1
0
Fork 0

DBG: fix buffer overflow and assert when tracing fxsave or invalid instructions

This commit is contained in:
Duncan Ogilvie 2018-10-10 15:34:33 +02:00
parent 22861d69e5
commit 25a67b778e
1 changed files with 15 additions and 9 deletions

View File

@ -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)
{