1
0
Fork 0
x64dbg/x64_dbg_dbg/disasm_fast.cpp

129 lines
4.3 KiB
C++
Raw Normal View History

2014-09-14 22:28:23 +08:00
/**
@file disasm_fast.cpp
@brief Implements the disasm fast class.
*/
2014-06-10 21:56:42 +08:00
#include "disasm_fast.h"
2014-06-24 10:46:54 +08:00
#include "debugger.h"
#include "memory.h"
2014-06-10 21:56:42 +08:00
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));
2014-07-07 23:00:24 +08:00
//copy instruction text
2015-02-02 07:58:25 +08:00
strcpy_s(basicinfo->instruction, disasm->CompleteInstr);
2014-06-10 21:56:42 +08:00
//find immidiat
2014-08-05 07:06:59 +08:00
if(disasm->Instruction.BranchType == 0) //no branch
2014-06-10 21:56:42 +08:00
{
2014-08-05 07:06:59 +08:00
if((disasm->Argument1.ArgType & CONSTANT_TYPE) == CONSTANT_TYPE)
2014-06-10 21:56:42 +08:00
{
2014-08-05 07:06:59 +08:00
basicinfo->type |= TYPE_VALUE;
basicinfo->value.value = (ULONG_PTR)disasm->Instruction.Immediat;
basicinfo->value.size = argsize2memsize(disasm->Argument1.ArgSize);
2014-06-10 21:56:42 +08:00
}
2014-08-05 07:06:59 +08:00
else if((disasm->Argument2.ArgType & CONSTANT_TYPE) == CONSTANT_TYPE)
2014-06-10 21:56:42 +08:00
{
2014-08-05 07:06:59 +08:00
basicinfo->type |= TYPE_VALUE;
basicinfo->value.value = (ULONG_PTR)disasm->Instruction.Immediat;
basicinfo->value.size = argsize2memsize(disasm->Argument2.ArgSize);
2014-06-10 21:56:42 +08:00
}
}
else //branch
2014-06-24 10:46:54 +08:00
{
2014-08-05 07:06:59 +08:00
basicinfo->branch = true;
if(disasm->Instruction.BranchType == CallType)
basicinfo->call = true;
if(disasm->Instruction.BranchType == RetType)
basicinfo->branch = false;
2014-06-24 10:46:54 +08:00
}
2014-06-10 21:56:42 +08:00
//find memory displacement
if((disasm->Argument1.ArgType & MEMORY_TYPE) == MEMORY_TYPE)
2014-06-10 21:56:42 +08:00
{
if(disasm->Argument1.Memory.Displacement)
{
2014-08-05 07:06:59 +08:00
basicinfo->type |= TYPE_MEMORY;
basicinfo->memory.value = (ULONG_PTR)disasm->Argument1.Memory.Displacement;
2015-02-02 07:58:25 +08:00
strcpy_s(basicinfo->memory.mnemonic, disasm->Argument1.ArgMnemonic);
2014-06-10 21:56:42 +08:00
}
basicinfo->memory.size = argsize2memsize(disasm->Argument1.ArgSize);
}
if((disasm->Argument2.ArgType & MEMORY_TYPE) == MEMORY_TYPE)
{
if(disasm->Argument2.Memory.Displacement)
2014-06-10 21:56:42 +08:00
{
2014-08-05 07:06:59 +08:00
basicinfo->type |= TYPE_MEMORY;
basicinfo->memory.value = (ULONG_PTR)disasm->Argument2.Memory.Displacement;
2015-02-02 07:58:25 +08:00
strcpy_s(basicinfo->memory.mnemonic, disasm->Argument2.ArgMnemonic);
2014-06-10 21:56:42 +08:00
}
basicinfo->memory.size = argsize2memsize(disasm->Argument2.ArgSize);
2014-06-10 21:56:42 +08:00
}
//find address value
if(disasm->Instruction.BranchType && disasm->Instruction.AddrValue)
{
2014-08-05 07:06:59 +08:00
basicinfo->type |= TYPE_ADDR;
basicinfo->addr = (ULONG_PTR)disasm->Instruction.AddrValue;
2014-06-10 21:56:42 +08:00
}
//rip-relative (non-branch)
2014-08-05 07:06:59 +08:00
if(disasm->Instruction.BranchType == 0)
2014-06-10 21:56:42 +08:00
{
2014-08-05 07:06:59 +08:00
if((disasm->Argument1.ArgType & RELATIVE_) == RELATIVE_)
2014-06-10 21:56:42 +08:00
{
2014-08-05 07:06:59 +08:00
basicinfo->type |= TYPE_MEMORY;
basicinfo->memory.value = (ULONG_PTR)disasm->Instruction.AddrValue;
2015-02-02 07:58:25 +08:00
strcpy_s(basicinfo->memory.mnemonic, disasm->Argument1.ArgMnemonic);
2014-08-05 07:06:59 +08:00
basicinfo->memory.size = argsize2memsize(disasm->Argument1.ArgSize);
2014-06-10 21:56:42 +08:00
}
2014-08-05 07:06:59 +08:00
else if((disasm->Argument2.ArgType & RELATIVE_) == RELATIVE_)
2014-06-10 21:56:42 +08:00
{
2014-08-05 07:06:59 +08:00
basicinfo->type |= TYPE_MEMORY;
basicinfo->memory.value = (ULONG_PTR)disasm->Instruction.AddrValue;
2015-02-02 07:58:25 +08:00
strcpy_s(basicinfo->memory.mnemonic, disasm->Argument2.ArgMnemonic);
2014-08-05 07:06:59 +08:00
basicinfo->memory.size = argsize2memsize(disasm->Argument2.ArgSize);
2014-06-10 21:56:42 +08:00
}
}
}
2014-06-24 10:46:54 +08:00
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
2014-08-05 07:06:59 +08:00
disasm.Archi = 64;
2014-06-24 10:46:54 +08:00
#endif // _WIN64
2014-08-05 07:06:59 +08:00
disasm.EIP = (UIntPtr)data;
disasm.VirtualAddr = (UInt64)addr;
int len = Disasm(&disasm);
if(len == UNKNOWN_OPCODE)
2014-06-24 10:46:54 +08:00
return false;
fillbasicinfo(&disasm, basicinfo);
2014-08-05 07:06:59 +08:00
basicinfo->size = len;
2014-06-24 10:46:54 +08:00
return true;
}
bool disasmfast(uint addr, BASIC_INSTRUCTION_INFO* basicinfo)
{
unsigned int data[16];
2015-03-31 10:06:16 +08:00
if(!MemRead((void*)addr, data, sizeof(data), nullptr))
2014-06-24 10:46:54 +08:00
return false;
return disasmfast((unsigned char*)data, addr, basicinfo);
}