From dcadee62385e0ae4018effb536fbe85db8b0f158 Mon Sep 17 00:00:00 2001 From: Nukem Date: Mon, 30 Mar 2015 22:06:16 -0400 Subject: [PATCH] Refactor reffind --- x64_dbg_dbg/_dbgfunctions.cpp | 16 +++-- x64_dbg_dbg/disasm_fast.cpp | 2 +- x64_dbg_dbg/reference.cpp | 131 ++++++++++++++++++++-------------- 3 files changed, 88 insertions(+), 61 deletions(-) diff --git a/x64_dbg_dbg/_dbgfunctions.cpp b/x64_dbg_dbg/_dbgfunctions.cpp index 69051a78..f18a804c 100644 --- a/x64_dbg_dbg/_dbgfunctions.cpp +++ b/x64_dbg_dbg/_dbgfunctions.cpp @@ -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(); } diff --git a/x64_dbg_dbg/disasm_fast.cpp b/x64_dbg_dbg/disasm_fast.cpp index 137f30fa..e1d8c7f7 100644 --- a/x64_dbg_dbg/disasm_fast.cpp +++ b/x64_dbg_dbg/disasm_fast.cpp @@ -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); } \ No newline at end of file diff --git a/x64_dbg_dbg/reference.cpp b/x64_dbg_dbg/reference.cpp index 5bd33a2f..15a5dac5 100644 --- a/x64_dbg_dbg/reference.cpp +++ b/x64_dbg_dbg/reference.cpp @@ -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, ®ionSize, 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 data(start_size, "reffind:data"); - if(!MemRead((void*)start_addr, data, start_size, 0)) + + // Allocate and read a buffer from the remote process + Memory 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; }