129 lines
4.3 KiB
C++
129 lines
4.3 KiB
C++
/**
|
|
@file disasm_fast.cpp
|
|
|
|
@brief Implements the disasm fast class.
|
|
*/
|
|
|
|
#include "disasm_fast.h"
|
|
#include "debugger.h"
|
|
#include "memory.h"
|
|
|
|
static MEMORY_SIZE argsize2memsize(int argsize)
|
|
{
|
|
switch(argsize)
|
|
{
|
|
case 8:
|
|
return size_byte;
|
|
case 16:
|
|
return size_word;
|
|
case 32:
|
|
return size_dword;
|
|
case 64:
|
|
return size_qword;
|
|
}
|
|
return size_byte;
|
|
}
|
|
|
|
void fillbasicinfo(DISASM* disasm, BASIC_INSTRUCTION_INFO* basicinfo)
|
|
{
|
|
//zero basicinfo
|
|
memset(basicinfo, 0, sizeof(BASIC_INSTRUCTION_INFO));
|
|
//copy instruction text
|
|
strcpy_s(basicinfo->instruction, disasm->CompleteInstr);
|
|
//find immidiat
|
|
if(disasm->Instruction.BranchType == 0) //no branch
|
|
{
|
|
if((disasm->Argument1.ArgType & CONSTANT_TYPE) == CONSTANT_TYPE)
|
|
{
|
|
basicinfo->type |= TYPE_VALUE;
|
|
basicinfo->value.value = (ULONG_PTR)disasm->Instruction.Immediat;
|
|
basicinfo->value.size = argsize2memsize(disasm->Argument1.ArgSize);
|
|
}
|
|
else if((disasm->Argument2.ArgType & CONSTANT_TYPE) == CONSTANT_TYPE)
|
|
{
|
|
basicinfo->type |= TYPE_VALUE;
|
|
basicinfo->value.value = (ULONG_PTR)disasm->Instruction.Immediat;
|
|
basicinfo->value.size = argsize2memsize(disasm->Argument2.ArgSize);
|
|
}
|
|
}
|
|
else //branch
|
|
{
|
|
basicinfo->branch = true;
|
|
if(disasm->Instruction.BranchType == CallType)
|
|
basicinfo->call = true;
|
|
if(disasm->Instruction.BranchType == RetType)
|
|
basicinfo->branch = false;
|
|
}
|
|
//find memory displacement
|
|
if((disasm->Argument1.ArgType & MEMORY_TYPE) == MEMORY_TYPE)
|
|
{
|
|
if(disasm->Argument1.Memory.Displacement)
|
|
{
|
|
basicinfo->type |= TYPE_MEMORY;
|
|
basicinfo->memory.value = (ULONG_PTR)disasm->Argument1.Memory.Displacement;
|
|
strcpy_s(basicinfo->memory.mnemonic, disasm->Argument1.ArgMnemonic);
|
|
}
|
|
basicinfo->memory.size = argsize2memsize(disasm->Argument1.ArgSize);
|
|
}
|
|
if((disasm->Argument2.ArgType & MEMORY_TYPE) == MEMORY_TYPE)
|
|
{
|
|
if(disasm->Argument2.Memory.Displacement)
|
|
{
|
|
basicinfo->type |= TYPE_MEMORY;
|
|
basicinfo->memory.value = (ULONG_PTR)disasm->Argument2.Memory.Displacement;
|
|
strcpy_s(basicinfo->memory.mnemonic, disasm->Argument2.ArgMnemonic);
|
|
}
|
|
basicinfo->memory.size = argsize2memsize(disasm->Argument2.ArgSize);
|
|
}
|
|
//find address value
|
|
if(disasm->Instruction.BranchType && disasm->Instruction.AddrValue)
|
|
{
|
|
basicinfo->type |= TYPE_ADDR;
|
|
basicinfo->addr = (ULONG_PTR)disasm->Instruction.AddrValue;
|
|
}
|
|
//rip-relative (non-branch)
|
|
if(disasm->Instruction.BranchType == 0)
|
|
{
|
|
if((disasm->Argument1.ArgType & RELATIVE_) == RELATIVE_)
|
|
{
|
|
basicinfo->type |= TYPE_MEMORY;
|
|
basicinfo->memory.value = (ULONG_PTR)disasm->Instruction.AddrValue;
|
|
strcpy_s(basicinfo->memory.mnemonic, disasm->Argument1.ArgMnemonic);
|
|
basicinfo->memory.size = argsize2memsize(disasm->Argument1.ArgSize);
|
|
}
|
|
else if((disasm->Argument2.ArgType & RELATIVE_) == RELATIVE_)
|
|
{
|
|
basicinfo->type |= TYPE_MEMORY;
|
|
basicinfo->memory.value = (ULONG_PTR)disasm->Instruction.AddrValue;
|
|
strcpy_s(basicinfo->memory.mnemonic, disasm->Argument2.ArgMnemonic);
|
|
basicinfo->memory.size = argsize2memsize(disasm->Argument2.ArgSize);
|
|
}
|
|
}
|
|
}
|
|
|
|
bool disasmfast(unsigned char* data, uint addr, BASIC_INSTRUCTION_INFO* basicinfo)
|
|
{
|
|
if(!data or !basicinfo)
|
|
return false;
|
|
DISASM disasm;
|
|
memset(&disasm, 0, sizeof(disasm));
|
|
#ifdef _WIN64
|
|
disasm.Archi = 64;
|
|
#endif // _WIN64
|
|
disasm.EIP = (UIntPtr)data;
|
|
disasm.VirtualAddr = (UInt64)addr;
|
|
int len = Disasm(&disasm);
|
|
if(len == UNKNOWN_OPCODE)
|
|
return false;
|
|
fillbasicinfo(&disasm, basicinfo);
|
|
basicinfo->size = len;
|
|
return true;
|
|
}
|
|
|
|
bool disasmfast(uint addr, BASIC_INSTRUCTION_INFO* basicinfo)
|
|
{
|
|
unsigned int data[16];
|
|
if(!MemRead((void*)addr, data, sizeof(data), nullptr))
|
|
return false;
|
|
return disasmfast((unsigned char*)data, addr, basicinfo);
|
|
} |