1
0
Fork 0

Refactor reffind

This commit is contained in:
Nukem 2015-03-30 22:06:16 -04:00
parent 7a1faba524
commit dcadee6238
3 changed files with 88 additions and 61 deletions

View File

@ -19,7 +19,7 @@ const DBGFUNCTIONS* dbgfunctionsget()
static bool _assembleatex(duint addr, const char* instruction, char* error, bool fillnop)
{
return assembleat(addr, instruction, 0, error, fillnop);
return assembleat(addr, instruction, nullptr, error, fillnop);
}
static bool _sectionfromaddr(duint addr, char* section)
@ -61,15 +61,18 @@ static bool _patchinrange(duint start, duint end)
if(start > end)
std::swap(start, end);
for(duint i = start; i < end + 1; i++)
if(_patchget(i))
return true;
for (duint i = start; i <= end; i++)
{
if (_patchget(i))
return true;
}
return false;
}
static bool _mempatch(duint va, const unsigned char* src, duint size)
{
return MemPatch((void*)va, (void*)src, size, 0);
return MemPatch((void*)va, (void*)src, size, nullptr);
}
static void _patchrestorerange(duint start, duint end)
@ -77,8 +80,9 @@ static void _patchrestorerange(duint start, duint end)
if (start > end)
std::swap(start, end);
for(duint i = start; i < end + 1; i++)
for(duint i = start; i <= end; i++)
PatchDelete(i, true);
GuiUpdatePatches();
}

View File

@ -117,7 +117,7 @@ bool disasmfast(unsigned char* data, uint addr, BASIC_INSTRUCTION_INFO* basicinf
bool disasmfast(uint addr, BASIC_INSTRUCTION_INFO* basicinfo)
{
unsigned int data[16];
if(!MemRead((void*)addr, data, sizeof(data), 0))
if(!MemRead((void*)addr, data, sizeof(data), nullptr))
return false;
return disasmfast((unsigned char*)data, addr, basicinfo);
}

View File

@ -6,81 +6,104 @@
int reffind(uint addr, uint size, CBREF cbRef, void* userinfo, bool silent, const char* name)
{
uint start_addr;
uint start_size;
uint base;
uint base_size;
base = MemFindBaseAddr(addr, &base_size, true);
if(!base or !base_size)
uint regionSize = 0;
uint regionBase = MemFindBaseAddr(addr, &regionSize, true);
// If the memory page wasn't found, fail
if(!regionBase || !regionSize)
{
if(!silent)
dputs("invalid memory page");
dprintf("Invalid memory page 0x%p", addr);
return 0;
}
if(!size) //assume the whole page
{
start_addr = base;
start_size = base_size;
// 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 - (addr - regionBase);
// Make sure the size fits in one page
scanStart = addr;
scanSize = min(size, maxsize);
}
else //custom boundaries
{
start_addr = addr;
uint maxsize = size - (start_addr - base);
if(size < maxsize) //check if the size fits in the page
start_size = size;
else
start_size = maxsize;
}
Memory<unsigned char*> data(start_size, "reffind:data");
if(!MemRead((void*)start_addr, data, start_size, 0))
// 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)
dputs("error reading memory");
dprintf("Error reading memory in reference search\n");
return 0;
}
DISASM disasm;
memset(&disasm, 0, sizeof(disasm));
// 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;
disasm.Archi = 64;
#endif // _WIN64
disasm.EIP = (UIntPtr)data;
disasm.VirtualAddr = (UInt64)start_addr;
uint i = 0;
BASIC_INSTRUCTION_INFO basicinfo;
REFINFO refinfo;
memset(&refinfo, 0, sizeof(REFINFO));
refinfo.userinfo = userinfo;
char fullName[deflen] = "";
char modname[MAX_MODULE_SIZE] = "";
if(ModNameFromAddr(start_addr, modname, true))
sprintf_s(fullName, "%s (%s)", name, modname);
else
sprintf_s(fullName, "%s (%p)", name, start_addr);
refinfo.name = fullName;
cbRef(0, 0, &refinfo); //allow initializing
while(i < start_size)
{
if(!(i % 0x1000))
disasm.EIP = (UIntPtr)data;
disasm.VirtualAddr = (UInt64)scanStart;
// Allow an "initialization" notice
REFINFO refInfo;
refInfo.refcount = 0;
refInfo.userinfo = userinfo;
refInfo.name = fullName;
cbRef(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)
{
double percent = (double)i / (double)start_size;
GuiReferenceSetProgress((int)(percent * 100));
float percent = (float)i / (float)scanSize;
GuiReferenceSetProgress((int)(percent * 100.0f));
}
// Disassemble the instruction
int len = Disasm(&disasm);
if(len != UNKNOWN_OPCODE)
{
BASIC_INSTRUCTION_INFO basicinfo;
fillbasicinfo(&disasm, &basicinfo);
basicinfo.size = len;
if(cbRef(&disasm, &basicinfo, &refinfo))
refinfo.refcount++;
if(cbRef(&disasm, &basicinfo, &refInfo))
refInfo.refcount++;
}
else
len = 1;
disasm.EIP += len;
disasm.VirtualAddr += len;
i += len;
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;
return refInfo.refcount;
}