1
0
Fork 0

DBG: use std::map to save the memory pages so sections will have their original size in memory (very slow now, will be fixed)

This commit is contained in:
Mr. eXoDia 2014-07-08 19:55:45 +02:00
parent b932ac8a09
commit c3a832fc0e
9 changed files with 197 additions and 172 deletions

View File

@ -119,4 +119,5 @@ void dbgfunctionsinit()
_dbgfunctions.ModPathFromAddr=_modpathfromaddr;
_dbgfunctions.ModPathFromName=_modpathfromname;
_dbgfunctions.DisasmFast=disasmfast;
_dbgfunctions.MemUpdateMap=memupdatemap;
}

View File

@ -26,6 +26,7 @@ typedef int (*PATCHFILE)(DBGPATCHINFO* patchlist, int count, const char* szFileN
typedef int (*MODPATHFROMADDR)(duint addr, char* path, int size);
typedef int (*MODPATHFROMNAME)(const char* modname, char* path, int size);
typedef bool (*DISASMFAST)(unsigned char* data, duint addr, BASIC_INSTRUCTION_INFO* basicinfo);
typedef void (*MEMUPDATEMAP)(HANDLE hProcess);
struct DBGFUNCTIONS
{
@ -46,6 +47,7 @@ struct DBGFUNCTIONS
MODPATHFROMADDR ModPathFromAddr;
MODPATHFROMNAME ModPathFromName;
DISASMFAST DisasmFast;
MEMUPDATEMAP MemUpdateMap;
};
#ifdef BUILD_DBG

View File

@ -18,7 +18,7 @@
extern "C" DLL_EXPORT duint _dbg_memfindbaseaddr(duint addr, duint* size)
{
return memfindbaseaddr(fdProcessInfo->hProcess, addr, size);
return memfindbaseaddr(addr, size);
}
extern "C" DLL_EXPORT bool _dbg_memread(duint addr, unsigned char* dest, duint size, duint* read)
@ -33,157 +33,16 @@ extern "C" DLL_EXPORT bool _dbg_memwrite(duint addr, const unsigned char* src, d
extern "C" DLL_EXPORT bool _dbg_memmap(MEMMAP* memmap)
{
int pagecount=(int)memoryPages.size();
memset(memmap, 0, sizeof(MEMMAP));
MEMORY_BASIC_INFORMATION mbi;
SIZE_T numBytes;
uint MyAddress=0, newAddress=0;
uint curAllocationBase=0;
bool bListAllPages = false; //TODO: settings for this
std::vector<MEMPAGE> pageVector;
do
{
numBytes=VirtualQueryEx(fdProcessInfo->hProcess, (LPCVOID)MyAddress, &mbi, sizeof(mbi));
if(mbi.State==MEM_COMMIT)
{
if(bListAllPages || curAllocationBase!=(uint)mbi.AllocationBase) //only list allocation bases
{
curAllocationBase=(uint)mbi.AllocationBase;
MEMPAGE curPage;
*curPage.info=0;
modnamefromaddr(MyAddress, curPage.info, true);
memcpy(&curPage.mbi, &mbi, sizeof(mbi));
pageVector.push_back(curPage);
}
else
pageVector.at(pageVector.size()-1).mbi.RegionSize+=mbi.RegionSize;
}
newAddress=(uint)mbi.BaseAddress+mbi.RegionSize;
if(newAddress<=MyAddress)
numBytes=0;
else
MyAddress=newAddress;
}
while(numBytes);
int pagecount;
//filter executable sections
if(bListAllPages)
{
pagecount=(int)pageVector.size();
char curMod[MAX_MODULE_SIZE]="";
for(int i=pagecount-1,curIdx=0; i>-1; i--)
{
if(pageVector.at(i).info[0]) //there is a module
{
if(!scmp(curMod, pageVector.at(i).info)) //mod is not the current mod
{
strcpy(curMod, pageVector.at(i).info);
curIdx=i;
}
else //current mod
{
pageVector.at(curIdx).mbi.RegionSize+=pageVector.at(i).mbi.RegionSize;
pageVector.erase(pageVector.begin()+i);
curIdx--; //the index changes when you remove an entry
}
}
}
}
//process file sections
pagecount=(int)pageVector.size();
char curMod[MAX_MODULE_SIZE]="";
for(int i=pagecount-1; i>-1; i--)
{
if(pageVector.at(i).info[0]) //there is a module
{
if(!scmp(curMod, pageVector.at(i).info)) //mod is not the current mod
{
strcpy(curMod, pageVector.at(i).info);
HMODULE hMod=(HMODULE)modbasefromname(curMod);
if(!hMod)
continue;
char curModPath[MAX_PATH]="";
if(!GetModuleFileNameExA(fdProcessInfo->hProcess, hMod, curModPath, MAX_PATH))
continue;
ULONG_PTR SectionNumber=GetPE32Data(curModPath, 0, UE_SECTIONNUMBER);
MEMPAGE newPage;
pageVector.erase(pageVector.begin()+i); //remove the SizeOfImage page
for(int j=SectionNumber-1; j>-1; j--)
{
memset(&newPage, 0, sizeof(MEMPAGE));
VirtualQueryEx(fdProcessInfo->hProcess, (LPCVOID)((uint)hMod+GetPE32Data(curModPath, j, UE_SECTIONVIRTUALOFFSET)), &newPage.mbi, sizeof(MEMORY_BASIC_INFORMATION));
uint SectionSize=GetPE32Data(curModPath, j, UE_SECTIONVIRTUALSIZE);
if(SectionSize%PAGE_SIZE) //unaligned page size
SectionSize+=PAGE_SIZE-(SectionSize%PAGE_SIZE); //fix this
if(SectionSize)
newPage.mbi.RegionSize=SectionSize;
const char* SectionName=(const char*)GetPE32Data(curModPath, j, UE_SECTIONNAME);
if(!SectionName)
SectionName="";
int len=(int)strlen(SectionName);
int escape_count=0;
for(int k=0; k<len; k++)
if(SectionName[k]=='\\' or SectionName[k]=='\"' or !isprint(SectionName[k]))
escape_count++;
char* SectionNameEscaped=(char*)emalloc(len+escape_count*3+1, "_dbg_memmap:SectionNameEscaped");
memset(SectionNameEscaped, 0, len+escape_count*3+1);
for(int k=0,l=0; k<len; k++)
{
switch(SectionName[k])
{
case '\t':
l+=sprintf(SectionNameEscaped+l, "\\t");
break;
case '\f':
l+=sprintf(SectionNameEscaped+l, "\\f");
break;
case '\v':
l+=sprintf(SectionNameEscaped+l, "\\v");
break;
case '\n':
l+=sprintf(SectionNameEscaped+l, "\\n");
break;
case '\r':
l+=sprintf(SectionNameEscaped+l, "\\r");
break;
case '\\':
l+=sprintf(SectionNameEscaped+l, "\\\\");
break;
case '\"':
l+=sprintf(SectionNameEscaped+l, "\\\"");
break;
default:
if(!isprint(SectionName[k])) //unknown unprintable character
l+=sprintf(SectionNameEscaped+l, "\\x%.2X", SectionName[k]);
else
l+=sprintf(SectionNameEscaped+l, "%c", SectionName[k]);
break;
}
}
sprintf(newPage.info, " \"%s\"", SectionNameEscaped);
efree(SectionNameEscaped, "_dbg_memmap:SectionNameEscaped");
pageVector.insert(pageVector.begin()+i, newPage);
}
memset(&newPage, 0, sizeof(MEMPAGE));
VirtualQueryEx(fdProcessInfo->hProcess, (LPCVOID)hMod, &newPage.mbi, sizeof(MEMORY_BASIC_INFORMATION));
strcpy(newPage.info, curMod);
pageVector.insert(pageVector.begin()+i, newPage);
}
}
}
//process vector
memmap->count=pagecount=(int)pageVector.size();
memmap->count=pagecount;
if(!pagecount)
return true;
memmap->page=(MEMPAGE*)BridgeAlloc(sizeof(MEMPAGE)*pagecount);
memset(memmap->page, 0, sizeof(MEMPAGE)*pagecount);
for(int i=0; i<pagecount; i++)
memcpy(&memmap->page[i], &pageVector.at(i), sizeof(MEMPAGE));
int j=0;
for(MemoryMap::iterator i=memoryPages.begin(); i!=memoryPages.end(); ++i,j++)
memcpy(&memmap->page[j], &i->second, sizeof(MEMPAGE));
return true;
}

View File

@ -182,6 +182,7 @@ void DebugUpdateGui(uint disasm_addr, bool stack)
{
if(!memisvalidreadptr(fdProcessInfo->hProcess, disasm_addr))
return;
memupdatemap(fdProcessInfo->hProcess); //update memory map
uint cip=GetContextData(UE_CIP);
GuiDisasmAt(disasm_addr, cip);
if(stack)
@ -325,7 +326,7 @@ static void cbMemoryBreakpoint(void* ExceptionAddress)
{
uint cip=GetContextData(UE_CIP);
uint size;
uint base=memfindbaseaddr(fdProcessInfo->hProcess, (uint)ExceptionAddress, &size);
uint base=memfindbaseaddr((uint)ExceptionAddress, &size);
BREAKPOINT bp;
BRIDGEBP pluginBp;
PLUG_CB_BREAKPOINT bpInfo;
@ -465,7 +466,7 @@ static bool cbSetModuleBreakpoints(const BREAKPOINT* bp)
case BPMEMORY:
{
uint size=0;
memfindbaseaddr(fdProcessInfo->hProcess, bp->addr, &size);
memfindbaseaddr(bp->addr, &size);
bool restore=false;
if(!bp->singleshoot)
restore=true;
@ -726,7 +727,7 @@ static void cbSystemBreakpoint(void* ExceptionData)
dputs("system breakpoint reached!");
bSkipExceptions=false; //we are not skipping first-chance exceptions
uint cip=GetContextData(UE_CIP);
GuiDumpAt(memfindbaseaddr(fdProcessInfo->hProcess, cip, 0)); //dump somewhere
GuiDumpAt(memfindbaseaddr(cip, 0)); //dump somewhere
//plugin callbacks
PLUG_CB_SYSTEMBREAKPOINT callbackInfo;
@ -1654,7 +1655,7 @@ CMDRESULT cbDebugSetMemoryBpx(int argc, char* argv[])
}
}
uint size=0;
uint base=memfindbaseaddr(fdProcessInfo->hProcess, addr, &size);
uint base=memfindbaseaddr(addr, &size);
bool singleshoot=false;
if(!restore)
singleshoot=true;
@ -1678,7 +1679,7 @@ static bool cbDeleteAllMemoryBreakpoints(const BREAKPOINT* bp)
if(!bp->enabled)
return true;
uint size;
memfindbaseaddr(fdProcessInfo->hProcess, bp->addr, &size);
memfindbaseaddr(bp->addr, &size);
if(!bpdel(bp->addr, BPMEMORY) or !RemoveMemoryBPX(bp->addr, size))
{
dprintf("delete memory breakpoint failed: "fhex"\n", bp->addr);
@ -1707,7 +1708,7 @@ CMDRESULT cbDebugDeleteMemoryBreakpoint(int argc, char* argv[])
if(bpget(0, BPMEMORY, arg1, &found)) //found a breakpoint with name
{
uint size;
memfindbaseaddr(fdProcessInfo->hProcess, found.addr, &size);
memfindbaseaddr(found.addr, &size);
if(!bpdel(found.addr, BPMEMORY) or !RemoveMemoryBPX(found.addr, size))
{
dprintf("delete memory breakpoint failed: "fhex"\n", found.addr);
@ -1722,7 +1723,7 @@ CMDRESULT cbDebugDeleteMemoryBreakpoint(int argc, char* argv[])
return STATUS_ERROR;
}
uint size;
memfindbaseaddr(fdProcessInfo->hProcess, found.addr, &size);
memfindbaseaddr(found.addr, &size);
if(!bpdel(found.addr, BPMEMORY) or !RemoveMemoryBPX(found.addr, size))
{
dprintf("delete memory breakpoint failed: "fhex"\n", found.addr);
@ -1942,7 +1943,7 @@ CMDRESULT cbDebugMemset(int argc, char* argv[])
}
else
{
uint base=memfindbaseaddr(fdProcessInfo->hProcess, addr, &size);
uint base=memfindbaseaddr(addr, &size);
if(!base)
{
dputs("invalid address specified");
@ -1962,7 +1963,7 @@ CMDRESULT cbDebugMemset(int argc, char* argv[])
CMDRESULT cbBenchmark(int argc, char* argv[])
{
uint addr=memfindbaseaddr(fdProcessInfo->hProcess, GetContextData(UE_CIP), 0);
uint addr=memfindbaseaddr(GetContextData(UE_CIP), 0);
DWORD ticks=GetTickCount();
char comment[MAX_COMMENT_SIZE]="";
for(uint i=addr; i<addr+100000; i++)
@ -2214,7 +2215,7 @@ CMDRESULT cbDebugStackDump(int argc, char* argv[])
}
duint csp=GetContextData(UE_CSP);
duint size=0;
duint base=memfindbaseaddr(fdProcessInfo->hProcess, csp, &size);
duint base=memfindbaseaddr(csp, &size);
if(base && addr>=base && addr<(base+size))
GuiStackDumpAt(addr, csp);
else

View File

@ -1004,7 +1004,7 @@ CMDRESULT cbInstrFind(int argc, char* argv[])
if(pattern[len-1]=='#')
pattern[len-1]='\0';
uint size=0;
uint base=memfindbaseaddr(fdProcessInfo->hProcess, addr, &size);
uint base=memfindbaseaddr(addr, &size);
if(!base)
{
dprintf("invalid memory address "fhex"!\n", addr);
@ -1058,7 +1058,7 @@ CMDRESULT cbInstrFindAll(int argc, char* argv[])
if(pattern[len-1]=='#')
pattern[len-1]='\0';
uint size=0;
uint base=memfindbaseaddr(fdProcessInfo->hProcess, addr, &size);
uint base=memfindbaseaddr(addr, &size);
if(!base)
{
dprintf("invalid memory address "fhex"!\n", addr);

View File

@ -1,29 +1,185 @@
#include "memory.h"
#include "debugger.h"
#include "patches.h"
#include "console.h"
uint memfindbaseaddr(HANDLE hProcess, uint addr, uint* size)
MemoryMap memoryPages;
void memupdatemap(HANDLE hProcess)
{
DWORD ticks=GetTickCount();
MEMORY_BASIC_INFORMATION mbi;
SIZE_T numBytes;
uint MyAddress=0, newAddress=0;
uint curAllocationBase=0;
bool bListAllPages = false; //TODO: settings for this
std::vector<MEMPAGE> pageVector;
do
{
numBytes=VirtualQueryEx(hProcess, (LPCVOID)MyAddress, &mbi, sizeof(mbi));
newAddress=(uint)mbi.BaseAddress+mbi.RegionSize;
if(mbi.State==MEM_COMMIT and addr<newAddress and addr>=MyAddress)
if(mbi.State==MEM_COMMIT)
{
if(size)
*size=mbi.RegionSize;
return (uint)mbi.BaseAddress;
if(bListAllPages || curAllocationBase!=(uint)mbi.AllocationBase) //only list allocation bases
{
curAllocationBase=(uint)mbi.AllocationBase;
MEMPAGE curPage;
*curPage.info=0;
modnamefromaddr(MyAddress, curPage.info, true);
memcpy(&curPage.mbi, &mbi, sizeof(mbi));
pageVector.push_back(curPage);
}
else
pageVector.at(pageVector.size()-1).mbi.RegionSize+=mbi.RegionSize;
}
newAddress=(uint)mbi.BaseAddress+mbi.RegionSize;
if(newAddress<=MyAddress)
numBytes=0;
else
MyAddress=newAddress;
}
while(numBytes);
return 0;
dprintf("memupdatemap[1], %ums\n", GetTickCount()-ticks);
ticks=GetTickCount();
int pagecount;
//filter executable sections
if(bListAllPages)
{
pagecount=(int)pageVector.size();
char curMod[MAX_MODULE_SIZE]="";
for(int i=pagecount-1,curIdx=0; i>-1; i--)
{
if(pageVector.at(i).info[0]) //there is a module
{
if(!scmp(curMod, pageVector.at(i).info)) //mod is not the current mod
{
strcpy(curMod, pageVector.at(i).info);
curIdx=i;
}
else //current mod
{
pageVector.at(curIdx).mbi.RegionSize+=pageVector.at(i).mbi.RegionSize;
pageVector.erase(pageVector.begin()+i);
curIdx--; //the index changes when you remove an entry
}
}
}
}
dprintf("memupdatemap[2], %ums\n", GetTickCount()-ticks);
ticks=GetTickCount();
//process file sections
pagecount=(int)pageVector.size();
char curMod[MAX_MODULE_SIZE]="";
for(int i=pagecount-1; i>-1; i--)
{
if(pageVector.at(i).info[0]) //there is a module
{
if(!scmp(curMod, pageVector.at(i).info)) //mod is not the current mod
{
strcpy(curMod, pageVector.at(i).info);
HMODULE hMod=(HMODULE)modbasefromname(curMod);
if(!hMod)
continue;
char curModPath[MAX_PATH]="";
if(!GetModuleFileNameExA(hProcess, hMod, curModPath, MAX_PATH))
continue;
int SectionNumber=(int)GetPE32Data(curModPath, 0, UE_SECTIONNUMBER);
MEMPAGE newPage;
pageVector.erase(pageVector.begin()+i); //remove the SizeOfImage page
for(int j=SectionNumber-1; j>-1; j--)
{
memset(&newPage, 0, sizeof(MEMPAGE));
VirtualQueryEx(hProcess, (LPCVOID)((uint)hMod+GetPE32Data(curModPath, j, UE_SECTIONVIRTUALOFFSET)), &newPage.mbi, sizeof(MEMORY_BASIC_INFORMATION));
uint SectionSize=GetPE32Data(curModPath, j, UE_SECTIONVIRTUALSIZE);
if(SectionSize%PAGE_SIZE) //unaligned page size
SectionSize+=PAGE_SIZE-(SectionSize%PAGE_SIZE); //fix this
if(SectionSize)
newPage.mbi.RegionSize=SectionSize;
const char* SectionName=(const char*)GetPE32Data(curModPath, j, UE_SECTIONNAME);
if(!SectionName)
SectionName="";
int len=(int)strlen(SectionName);
int escape_count=0;
for(int k=0; k<len; k++)
if(SectionName[k]=='\\' or SectionName[k]=='\"' or !isprint(SectionName[k]))
escape_count++;
char* SectionNameEscaped=(char*)emalloc(len+escape_count*3+1, "_dbg_memmap:SectionNameEscaped");
memset(SectionNameEscaped, 0, len+escape_count*3+1);
for(int k=0,l=0; k<len; k++)
{
switch(SectionName[k])
{
case '\t':
l+=sprintf(SectionNameEscaped+l, "\\t");
break;
case '\f':
l+=sprintf(SectionNameEscaped+l, "\\f");
break;
case '\v':
l+=sprintf(SectionNameEscaped+l, "\\v");
break;
case '\n':
l+=sprintf(SectionNameEscaped+l, "\\n");
break;
case '\r':
l+=sprintf(SectionNameEscaped+l, "\\r");
break;
case '\\':
l+=sprintf(SectionNameEscaped+l, "\\\\");
break;
case '\"':
l+=sprintf(SectionNameEscaped+l, "\\\"");
break;
default:
if(!isprint(SectionName[k])) //unknown unprintable character
l+=sprintf(SectionNameEscaped+l, "\\x%.2X", SectionName[k]);
else
l+=sprintf(SectionNameEscaped+l, "%c", SectionName[k]);
break;
}
}
sprintf(newPage.info, " \"%s\"", SectionNameEscaped);
efree(SectionNameEscaped, "_dbg_memmap:SectionNameEscaped");
pageVector.insert(pageVector.begin()+i, newPage);
}
memset(&newPage, 0, sizeof(MEMPAGE));
VirtualQueryEx(hProcess, (LPCVOID)hMod, &newPage.mbi, sizeof(MEMORY_BASIC_INFORMATION));
strcpy(newPage.info, curMod);
pageVector.insert(pageVector.begin()+i, newPage);
}
}
}
dprintf("memupdatemap[3], %ums\n", GetTickCount()-ticks);
ticks=GetTickCount();
pagecount=(int)pageVector.size();
memoryPages.clear();
for(int i=0; i<pagecount; i++)
{
const MEMPAGE & curPage = pageVector.at(i);
uint start=(uint)curPage.mbi.BaseAddress;
uint size=curPage.mbi.RegionSize;
memoryPages.insert(std::make_pair(std::make_pair(start, start+size-1), curPage));
}
dprintf("memupdatemap[4], %ums\n", GetTickCount()-ticks);
}
uint memfindbaseaddr(uint addr, uint* size)
{
MemoryMap::iterator found=memoryPages.find(std::make_pair(addr, addr));
if(found==memoryPages.end())
return 0;
if(size)
*size=found->second.mbi.RegionSize;
return found->first.first;
}
bool memread(HANDLE hProcess, const void* lpBaseAddress, void* lpBuffer, SIZE_T nSize, SIZE_T* lpNumberOfBytesRead)

View File

@ -2,9 +2,14 @@
#define _MEMORY_H
#include "_global.h"
#include "addrinfo.h"
#define PAGE_SIZE 0x1000 //TODO: better stuff here
typedef std::map<Range, MEMPAGE, RangeCompare> MemoryMap;
extern MemoryMap memoryPages;
struct PATTERNNIBBLE
{
unsigned char n;
@ -16,7 +21,8 @@ struct PATTERNBYTE
PATTERNNIBBLE n[2];
};
uint memfindbaseaddr(HANDLE hProcess, uint addr, uint* size);
void memupdatemap(HANDLE hProcess);
uint memfindbaseaddr(uint addr, uint* size);
bool memread(HANDLE hProcess, const void* lpBaseAddress, void* lpBuffer, SIZE_T nSize, SIZE_T* lpNumberOfBytesRead);
bool memwrite(HANDLE hProcess, void* lpBaseAddress, const void* lpBuffer, SIZE_T nSize, SIZE_T* lpNumberOfBytesWritten);
bool mempatch(HANDLE hProcess, void* lpBaseAddress, const void* lpBuffer, SIZE_T nSize, SIZE_T* lpNumberOfBytesWritten);

View File

@ -9,7 +9,7 @@ int reffind(uint addr, uint size, CBREF cbRef, void* userinfo, bool silent)
uint start_size;
uint base;
uint base_size;
base=memfindbaseaddr(fdProcessInfo->hProcess, addr, &base_size);
base=memfindbaseaddr(addr, &base_size);
if(!base or !base_size)
{
if(!silent)

View File

@ -15,13 +15,13 @@ bool stackcommentget(uint addr, STACK_COMMENT* comment)
return false;
uint size=0;
uint base=memfindbaseaddr(fdProcessInfo->hProcess, data, &size);
uint base=memfindbaseaddr(data, &size);
uint readStart=data-16*4;
if(readStart<base)
readStart=base;
unsigned char disasmData[256];
memread(fdProcessInfo->hProcess, (const void*)readStart, disasmData, sizeof(disasmData), 0);
unsigned int prev=disasmback(disasmData, 0, sizeof(disasmData), data-readStart, 1);
uint prev=disasmback(disasmData, 0, sizeof(disasmData), data-readStart, 1);
uint previousInstr=readStart+prev;
DISASM disasm;
disasm.Options=NoformatNumeral;