177 lines
6.4 KiB
C++
177 lines
6.4 KiB
C++
#include "addrinfo.h"
|
|
#include "debugger.h"
|
|
#include "console.h"
|
|
#include "memory.h"
|
|
#include "breakpoint.h"
|
|
#include "threading.h"
|
|
#include "symbolinfo.h"
|
|
#include "murmurhash.h"
|
|
#include "lz4\lz4file.h"
|
|
#include "patches.h"
|
|
#include "module.h"
|
|
#include "comment.h"
|
|
#include "label.h"
|
|
#include "bookmark.h"
|
|
#include "function.h"
|
|
#include "loop.h"
|
|
|
|
//database functions
|
|
void dbsave()
|
|
{
|
|
dprintf("saving database...");
|
|
DWORD ticks = GetTickCount();
|
|
JSON root = json_object();
|
|
commentcachesave(root);
|
|
labelcachesave(root);
|
|
bookmarkcachesave(root);
|
|
functioncachesave(root);
|
|
loopcachesave(root);
|
|
bpcachesave(root);
|
|
WString wdbpath = StringUtils::Utf8ToUtf16(dbpath);
|
|
if(json_object_size(root))
|
|
{
|
|
FILE* jsonFile = 0;
|
|
if(_wfopen_s(&jsonFile, wdbpath.c_str(), L"wb"))
|
|
{
|
|
dputs("failed to open database file for editing!");
|
|
json_decref(root); //free root
|
|
return;
|
|
}
|
|
if(json_dumpf(root, jsonFile, JSON_INDENT(4)) == -1)
|
|
{
|
|
dputs("couldn't write JSON to database file...");
|
|
json_decref(root); //free root
|
|
return;
|
|
}
|
|
fclose(jsonFile);
|
|
if(!settingboolget("Engine", "DisableCompression"))
|
|
LZ4_compress_fileW(wdbpath.c_str(), wdbpath.c_str());
|
|
}
|
|
else //remove database when nothing is in there
|
|
DeleteFileW(wdbpath.c_str());
|
|
dprintf("%ums\n", GetTickCount() - ticks);
|
|
json_decref(root); //free root
|
|
}
|
|
|
|
void dbload()
|
|
{
|
|
if(!FileExists(dbpath)) //no database to load
|
|
return;
|
|
dprintf("loading database...");
|
|
DWORD ticks = GetTickCount();
|
|
WString wdbpath = StringUtils::Utf8ToUtf16(dbpath);
|
|
bool compress = !settingboolget("Engine", "DisableCompression");
|
|
LZ4_STATUS status = LZ4_decompress_fileW(wdbpath.c_str(), wdbpath.c_str());
|
|
if(status != LZ4_SUCCESS && status != LZ4_INVALID_ARCHIVE && compress)
|
|
{
|
|
dputs("\ninvalid database file!");
|
|
return;
|
|
}
|
|
FILE* jsonFile = 0;
|
|
if(_wfopen_s(&jsonFile, wdbpath.c_str(), L"rb"))
|
|
{
|
|
dputs("\nfailed to open database file!");
|
|
return;
|
|
}
|
|
JSON root = json_loadf(jsonFile, 0, 0);
|
|
fclose(jsonFile);
|
|
if(status != LZ4_INVALID_ARCHIVE && compress)
|
|
LZ4_compress_fileW(wdbpath.c_str(), wdbpath.c_str());
|
|
if(!root)
|
|
{
|
|
dputs("\ninvalid database file (JSON)!");
|
|
return;
|
|
}
|
|
commentcacheload(root);
|
|
labelcacheload(root);
|
|
bookmarkcacheload(root);
|
|
functioncacheload(root);
|
|
loopcacheload(root);
|
|
bpcacheload(root);
|
|
json_decref(root); //free root
|
|
dprintf("%ums\n", GetTickCount() - ticks);
|
|
}
|
|
|
|
void dbclose()
|
|
{
|
|
dbsave();
|
|
commentclear();
|
|
labelclear();
|
|
bookmarkclear();
|
|
functionclear();
|
|
loopclear();
|
|
bpclear();
|
|
patchclear();
|
|
}
|
|
|
|
///api functions
|
|
bool apienumexports(uint base, EXPORTENUMCALLBACK cbEnum)
|
|
{
|
|
MEMORY_BASIC_INFORMATION mbi;
|
|
VirtualQueryEx(fdProcessInfo->hProcess, (const void*)base, &mbi, sizeof(mbi));
|
|
uint size = mbi.RegionSize;
|
|
Memory<void*> buffer(size, "apienumexports:buffer");
|
|
if(!memread(fdProcessInfo->hProcess, (const void*)base, buffer, size, 0))
|
|
return false;
|
|
IMAGE_NT_HEADERS* pnth = (IMAGE_NT_HEADERS*)((uint)buffer + GetPE32DataFromMappedFile((ULONG_PTR)buffer, 0, UE_PE_OFFSET));
|
|
uint export_dir_rva = pnth->OptionalHeader.DataDirectory[0].VirtualAddress;
|
|
uint export_dir_size = pnth->OptionalHeader.DataDirectory[0].Size;
|
|
IMAGE_EXPORT_DIRECTORY export_dir;
|
|
memset(&export_dir, 0, sizeof(export_dir));
|
|
memread(fdProcessInfo->hProcess, (const void*)(export_dir_rva + base), &export_dir, sizeof(export_dir), 0);
|
|
unsigned int NumberOfNames = export_dir.NumberOfNames;
|
|
if(!export_dir.NumberOfFunctions or !NumberOfNames) //no named exports
|
|
return false;
|
|
char modname[MAX_MODULE_SIZE] = "";
|
|
modnamefromaddr(base, modname, true);
|
|
uint original_name_va = export_dir.Name + base;
|
|
char original_name[deflen] = "";
|
|
memset(original_name, 0, sizeof(original_name));
|
|
memread(fdProcessInfo->hProcess, (const void*)original_name_va, original_name, deflen, 0);
|
|
char* AddrOfFunctions_va = (char*)(export_dir.AddressOfFunctions + base);
|
|
char* AddrOfNames_va = (char*)(export_dir.AddressOfNames + base);
|
|
char* AddrOfNameOrdinals_va = (char*)(export_dir.AddressOfNameOrdinals + base);
|
|
for(DWORD i = 0; i < NumberOfNames; i++)
|
|
{
|
|
DWORD curAddrOfName = 0;
|
|
memread(fdProcessInfo->hProcess, AddrOfNames_va + sizeof(DWORD)*i, &curAddrOfName, sizeof(DWORD), 0);
|
|
char* cur_name_va = (char*)(curAddrOfName + base);
|
|
char cur_name[deflen] = "";
|
|
memset(cur_name, 0, deflen);
|
|
memread(fdProcessInfo->hProcess, cur_name_va, cur_name, deflen, 0);
|
|
WORD curAddrOfNameOrdinals = 0;
|
|
memread(fdProcessInfo->hProcess, AddrOfNameOrdinals_va + sizeof(WORD)*i, &curAddrOfNameOrdinals, sizeof(WORD), 0);
|
|
DWORD curFunctionRva = 0;
|
|
memread(fdProcessInfo->hProcess, AddrOfFunctions_va + sizeof(DWORD)*curAddrOfNameOrdinals, &curFunctionRva, sizeof(DWORD), 0);
|
|
|
|
if(curFunctionRva >= export_dir_rva and curFunctionRva < export_dir_rva + export_dir_size)
|
|
{
|
|
char forwarded_api[deflen] = "";
|
|
memset(forwarded_api, 0, deflen);
|
|
memread(fdProcessInfo->hProcess, (void*)(curFunctionRva + base), forwarded_api, deflen, 0);
|
|
int len = (int)strlen(forwarded_api);
|
|
int j = 0;
|
|
while(forwarded_api[j] != '.' and j < len)
|
|
j++;
|
|
if(forwarded_api[j] == '.')
|
|
{
|
|
forwarded_api[j] = 0;
|
|
HINSTANCE hTempDll = LoadLibraryExA(forwarded_api, 0, DONT_RESOLVE_DLL_REFERENCES | LOAD_LIBRARY_AS_DATAFILE);
|
|
if(hTempDll)
|
|
{
|
|
uint local_addr = (uint)GetProcAddress(hTempDll, forwarded_api + j + 1);
|
|
if(local_addr)
|
|
{
|
|
uint remote_addr = ImporterGetRemoteAPIAddress(fdProcessInfo->hProcess, local_addr);
|
|
cbEnum(base, modname, cur_name, remote_addr);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
cbEnum(base, modname, cur_name, curFunctionRva + base);
|
|
}
|
|
}
|
|
return true;
|
|
} |