DBG: fix buffer overflow and assert when tracing fxsave or invalid instructions
This commit is contained in:
parent
22861d69e5
commit
25a67b778e
|
|
@ -199,8 +199,10 @@ void TraceRecordManager::TraceExecute(duint address, duint size)
|
|||
}
|
||||
}
|
||||
|
||||
//See https://www.felixcloutier.com/x86/FXSAVE.html, max 512 bytes
|
||||
#define memoryContentSize 512
|
||||
|
||||
static void HandleCapstoneOperand(const Zydis & cp, int opindex, DISASM_ARGTYPE* argType, duint* value, unsigned char* memoryContent, unsigned char* memorySize)
|
||||
static void HandleCapstoneOperand(const Zydis & cp, int opindex, DISASM_ARGTYPE* argType, duint* value, unsigned char memoryContent[memoryContentSize], unsigned char* memorySize)
|
||||
{
|
||||
*value = cp.ResolveOpValue(opindex, [&cp](ZydisRegister reg)
|
||||
{
|
||||
|
|
@ -231,7 +233,7 @@ static void HandleCapstoneOperand(const Zydis & cp, int opindex, DISASM_ARGTYPE*
|
|||
*value += ThreadGetLocalBase(ThreadGetId(hActiveThread));
|
||||
}
|
||||
*memorySize = op.size / 8;
|
||||
if(DbgMemIsValidReadPtr(*value))
|
||||
if(*memorySize <= memoryContentSize && DbgMemIsValidReadPtr(*value))
|
||||
{
|
||||
MemRead(*value, memoryContent, max(op.size / 8, sizeof(duint)));
|
||||
}
|
||||
|
|
@ -253,23 +255,27 @@ void TraceRecordManager::TraceExecuteRecord(const Zydis & newInstruction)
|
|||
REGDUMPWORD newContext;
|
||||
//DISASM_INSTR newInstruction;
|
||||
DWORD newThreadId;
|
||||
duint newMemory[32];
|
||||
duint newMemoryAddress[32];
|
||||
duint oldMemory[32];
|
||||
const size_t memoryArrayCount = 32;
|
||||
duint newMemory[memoryArrayCount];
|
||||
duint newMemoryAddress[memoryArrayCount];
|
||||
duint oldMemory[memoryArrayCount];
|
||||
unsigned char newMemoryArrayCount = 0;
|
||||
DbgGetRegDumpEx(&newContext.registers, sizeof(REGDUMP));
|
||||
newThreadId = ThreadGetId(hActiveThread);
|
||||
// Don't try to resolve memory values for lea and nop instructions
|
||||
if(!(newInstruction.IsNop() || newInstruction.GetId() == ZYDIS_MNEMONIC_LEA))
|
||||
// Don't try to resolve memory values for invalid/lea/nop instructions
|
||||
if(newInstruction.Success() && !newInstruction.IsNop() && newInstruction.GetId() != ZYDIS_MNEMONIC_LEA)
|
||||
{
|
||||
DISASM_ARGTYPE argType;
|
||||
duint value;
|
||||
unsigned char memoryContent[128];
|
||||
unsigned char memoryContent[memoryContentSize];
|
||||
unsigned char memorySize;
|
||||
for(int i = 0; i < newInstruction.OpCount(); i++)
|
||||
{
|
||||
memset(memoryContent, 0, sizeof(memoryContent));
|
||||
HandleCapstoneOperand(newInstruction, i, &argType, &value, memoryContent, &memorySize);
|
||||
// check for overflow of the memory buffer
|
||||
if(newMemoryArrayCount * sizeof(duint) + memorySize > memoryArrayCount * sizeof(duint))
|
||||
continue;
|
||||
// TODO: Implicit memory access by push and pop instructions
|
||||
// TODO: Support memory value of ??? for invalid memory access
|
||||
if(argType == arg_memory)
|
||||
|
|
@ -305,7 +311,7 @@ void TraceRecordManager::TraceExecuteRecord(const Zydis & newInstruction)
|
|||
newMemoryArrayCount++;
|
||||
}
|
||||
//TODO: PUSHAD/POPAD
|
||||
assert(newMemoryArrayCount < 32);
|
||||
assert(newMemoryArrayCount < memoryArrayCount);
|
||||
}
|
||||
if(rtPrevInstAvailable)
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue