1
0
Fork 0
x64dbg/x64_dbg_dbg/reference.cpp

119 lines
2.8 KiB
C++

/**
@file reference.cpp
@brief Implements the reference class.
*/
#include "reference.h"
#include "debugger.h"
#include "memory.h"
#include "console.h"
#include "module.h"
int RefFind(uint Address, uint Size, CBREF Callback, void* UserData, bool Silent, const char* Name)
{
uint regionSize = 0;
uint regionBase = MemFindBaseAddr(Address, &regionSize, true);
// If the memory page wasn't found, fail
if(!regionBase || !regionSize)
{
if(!Silent)
dprintf("Invalid memory page 0x%p", Address);
return 0;
}
// Assume the entire range is used
uint scanStart = regionBase;
uint scanSize = regionSize;
// Otherwise use custom boundaries if size was supplied
if (Size)
{
uint maxsize = Size - (Address - regionBase);
// Make sure the size fits in one page
scanStart = Address;
scanSize = min(Size, maxsize);
}
// Allocate and read a buffer from the remote process
Memory<unsigned char*> data(scanSize, "reffind:data");
if(!MemRead((PVOID)scanStart, data, scanSize, nullptr))
{
if(!Silent)
dprintf("Error reading memory in reference search\n");
return 0;
}
// Determine the full module name
char fullName[deflen];
char moduleName[MAX_MODULE_SIZE];
if (ModNameFromAddr(scanStart, moduleName, true))
sprintf_s(fullName, "%s (%s)", Name, moduleName);
else
sprintf_s(fullName, "%s (%p)", Name, scanStart);
// Initialize the disassembler
DISASM disasm;
memset(&disasm, 0, sizeof(disasm));
#ifdef _WIN64
disasm.Archi = 64;
#endif // _WIN64
disasm.EIP = (UIntPtr)data;
disasm.VirtualAddr = (UInt64)scanStart;
// Allow an "initialization" notice
REFINFO refInfo;
refInfo.refcount = 0;
refInfo.userinfo = UserData;
refInfo.name = fullName;
Callback(0, 0, &refInfo);
//concurrency::parallel_for(uint(0), scanSize, [&](uint i)
for (uint i = 0; i < scanSize;)
{
// Print the progress every 4096 bytes
if((i % 0x1000) == 0)
{
// Percent = (current / total) * 100
// Integer = floor(percent)
float percent = floor(((float)i / (float)scanSize) * 100.0f);
GuiReferenceSetProgress((int)percent);
}
// Disassemble the instruction
int len = Disasm(&disasm);
if(len != UNKNOWN_OPCODE)
{
BASIC_INSTRUCTION_INFO basicinfo;
fillbasicinfo(&disasm, &basicinfo);
basicinfo.size = len;
if(Callback(&disasm, &basicinfo, &refInfo))
refInfo.refcount++;
}
else
{
// Invalid instruction detected, so just skip the byte
len = 1;
}
disasm.EIP += len;
disasm.VirtualAddr += len;
i += len;
}
GuiReferenceSetProgress(100);
GuiReferenceReloadData();
return refInfo.refcount;
}