DBG: patchfile now works
This commit is contained in:
parent
c64d6766c2
commit
d9907a9fc8
|
|
@ -54,6 +54,7 @@ BRIDGE_IMPEXP int BridgeGetDbgVersion();
|
|||
#define MAX_SCRIPT_LINE_SIZE 2048
|
||||
#define MAX_THREAD_NAME_SIZE 256
|
||||
#define MAX_STRING_SIZE 512
|
||||
#define MAX_ERROR_SIZE 512
|
||||
|
||||
#define TYPE_VALUE 1
|
||||
#define TYPE_MEMORY 2
|
||||
|
|
|
|||
|
|
@ -86,6 +86,16 @@ static bool _patchrestore(duint addr)
|
|||
return patchdel(addr, true);
|
||||
}
|
||||
|
||||
static int _modpathfromaddr(duint addr, char* path, int size)
|
||||
{
|
||||
return GetModuleFileNameExA(fdProcessInfo->hProcess, (HMODULE)modbasefromaddr(addr), path, size);
|
||||
}
|
||||
|
||||
static int _modpathfromname(const char* modname, char* path, int size)
|
||||
{
|
||||
return _modpathfromaddr(modbasefromname(modname), path, size);
|
||||
}
|
||||
|
||||
void dbgfunctionsinit()
|
||||
{
|
||||
_dbgfunctions.AssembleAtEx=assembleat;
|
||||
|
|
@ -102,4 +112,6 @@ void dbgfunctionsinit()
|
|||
_dbgfunctions.PatchEnum=(PATCHENUM)patchenum;
|
||||
_dbgfunctions.PatchRestore=_patchrestore;
|
||||
_dbgfunctions.PatchFile=(PATCHFILE)patchfile;
|
||||
_dbgfunctions.ModPathFromAddr=_modpathfromaddr;
|
||||
_dbgfunctions.ModPathFromName=_modpathfromname;
|
||||
}
|
||||
|
|
@ -22,7 +22,9 @@ typedef bool (*MEMPATCH)(duint va, const unsigned char* src, duint size);
|
|||
typedef void (*PATCHRESTORERANGE)(duint start, duint end);
|
||||
typedef bool (*PATCHENUM)(DBGPATCHINFO* patchlist, size_t* cbsize);
|
||||
typedef bool (*PATCHRESTORE)(duint addr);
|
||||
typedef bool (*PATCHFILE)(DBGPATCHINFO* patchlist, int count, const char* szFileName);
|
||||
typedef int (*PATCHFILE)(DBGPATCHINFO* patchlist, int count, const char* szFileName, char* error);
|
||||
typedef int (*MODPATHFROMADDR)(duint addr, char* path, int size);
|
||||
typedef int (*MODPATHFROMNAME)(const char* modname, char* path, int size);
|
||||
|
||||
struct DBGFUNCTIONS
|
||||
{
|
||||
|
|
@ -40,6 +42,8 @@ struct DBGFUNCTIONS
|
|||
PATCHENUM PatchEnum;
|
||||
PATCHRESTORE PatchRestore;
|
||||
PATCHFILE PatchFile;
|
||||
MODPATHFROMADDR ModPathFromAddr;
|
||||
MODPATHFROMNAME ModPathFromName;
|
||||
};
|
||||
|
||||
#ifdef BUILD_DBG
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
#include "addrinfo.h"
|
||||
#include "memory.h"
|
||||
#include "debugger.h"
|
||||
#include "console.h"
|
||||
|
||||
PatchesInfo patches;
|
||||
|
||||
|
|
@ -127,7 +128,68 @@ bool patchenum(PATCHINFO* patcheslist, size_t* cbsize)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool patchfile(const PATCHINFO* patchlist, int count, const char* szFileName)
|
||||
int patchfile(const PATCHINFO* patchlist, int count, const char* szFileName, char* error)
|
||||
{
|
||||
return true;
|
||||
if(!count)
|
||||
{
|
||||
if(error)
|
||||
strcpy(error, "no patches to apply");
|
||||
return -1;
|
||||
}
|
||||
char modname[MAX_MODULE_SIZE]="";
|
||||
strcpy(modname, patchlist[0].mod);
|
||||
//check if all patches are in the same module
|
||||
for(int i=0; i<count; i++)
|
||||
if(_stricmp(patchlist[i].mod, modname))
|
||||
{
|
||||
if(error)
|
||||
sprintf(error, "not all patches are in module %s", modname);
|
||||
return -1;
|
||||
}
|
||||
uint modbase=modbasefromname(modname);
|
||||
if(!modbase) //module not loaded
|
||||
{
|
||||
if(error)
|
||||
sprintf(error, "failed to get base of module %s", modname);
|
||||
return -1;
|
||||
}
|
||||
char szOriginalName[MAX_PATH]="";
|
||||
if(!GetModuleFileNameExA(fdProcessInfo->hProcess, (HMODULE)modbase, szOriginalName, MAX_PATH))
|
||||
{
|
||||
if(error)
|
||||
sprintf(error, "failed to get module path of module %s", modname);
|
||||
return -1;
|
||||
}
|
||||
if(!CopyFileA(szOriginalName, szFileName, false))
|
||||
{
|
||||
if(error)
|
||||
strcpy(error, "failed to make a copy of the original file (patch target is in use?)");
|
||||
return -1;
|
||||
}
|
||||
HANDLE FileHandle;
|
||||
DWORD LoadedSize;
|
||||
HANDLE FileMap;
|
||||
ULONG_PTR FileMapVA;
|
||||
if(StaticFileLoad((char*)szFileName, UE_ACCESS_ALL, false, &FileHandle, &LoadedSize, &FileMap, &FileMapVA))
|
||||
{
|
||||
int patched=0;
|
||||
for(int i=0; i<count; i++)
|
||||
{
|
||||
unsigned char* ptr = (unsigned char*)ConvertVAtoFileOffsetEx(FileMapVA, LoadedSize, modbase, patchlist[i].addr, false, true);
|
||||
if(!ptr) //skip patches that do not have a raw address
|
||||
continue;
|
||||
dprintf("patch%.4d|%s[%.8X]:%.2X/%.2X->%.2X\n", i+1, modname, ptr-FileMapVA, *ptr, patchlist[i].oldbyte, patchlist[i].newbyte);
|
||||
*ptr=patchlist[i].newbyte;
|
||||
patched++;
|
||||
}
|
||||
if(!StaticFileUnload((char*)szFileName, true, FileHandle, LoadedSize, FileMap, FileMapVA))
|
||||
{
|
||||
if(error)
|
||||
strcpy(error, "StaticFileUnload failed");
|
||||
return -1;
|
||||
}
|
||||
return patched;
|
||||
}
|
||||
strcpy(error, "StaticFileLoad failed");
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -18,6 +18,6 @@ bool patchdel(uint addr, bool restore);
|
|||
void patchdelrange(uint start, uint end, bool restore);
|
||||
void patchclear(const char* mod);
|
||||
bool patchenum(PATCHINFO* patchlist, size_t* cbsize);
|
||||
bool patchfile(const PATCHINFO* patchlist, int count, const char* szFileName);
|
||||
int patchfile(const PATCHINFO* patchlist, int count, const char* szFileName, char* error);
|
||||
|
||||
#endif //_PATCHES_H
|
||||
Loading…
Reference in New Issue