1
0
mirror of https://github.com/DxWnd/DxWnd.reloaded synced 2024-12-30 09:25:35 +01:00
DxWnd.reloaded/dll/iatpatch.cpp

122 lines
4.1 KiB
C++
Raw Normal View History

#include <windows.h>
#include "dxwnd.h"
#include "dxwcore.hpp"
void *IATPatch(HMODULE module, DWORD ordinal, char *dll, void *apiproc, const char *apiname, void *hookproc)
{
PIMAGE_NT_HEADERS pnth;
PIMAGE_IMPORT_DESCRIPTOR pidesc;
DWORD base, rva;
PSTR impmodule;
PIMAGE_THUNK_DATA ptaddr;
PIMAGE_THUNK_DATA ptname;
PIMAGE_IMPORT_BY_NAME piname;
DWORD oldprotect;
void *org;
OutTraceH("IATPatch: module=%x ordinal=%x dll=%s\n", module, ordinal, dll);
base = (DWORD)module;
org = 0; // by default, ret = 0 => API not found
__try{
pnth = PIMAGE_NT_HEADERS(PBYTE(base) + PIMAGE_DOS_HEADER(base)->e_lfanew);
if(!pnth) {
OutTraceH("IATPatch: ERROR no PNTH at %d\n", __LINE__);
return 0;
}
rva = pnth->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
if(!rva) {
OutTraceH("IATPatch: ERROR no RVA at %d\n", __LINE__);
return 0;
}
pidesc = (PIMAGE_IMPORT_DESCRIPTOR)(base + rva);
while(pidesc->FirstThunk){
impmodule = (PSTR)(base + pidesc->Name);
//OutTraceH("IATPatch: analyze impmodule=%s\n", impmodule);
char *fname = impmodule;
for(; *fname; fname++); for(; !*fname; fname++);
if(!lstrcmpi(dll, impmodule)) {
OutTraceH("IATPatch: dll=%s found at %x\n", dll, impmodule);
ptaddr = (PIMAGE_THUNK_DATA)(base + (DWORD)pidesc->FirstThunk);
ptname = (pidesc->OriginalFirstThunk) ? (PIMAGE_THUNK_DATA)(base + (DWORD)pidesc->OriginalFirstThunk) : NULL;
while(ptaddr->u1.Function){
// OutTraceH("IATPatch: address=%x ptname=%x\n", ptaddr->u1.AddressOfData, ptname);
if (ptname){
// examining by function name
if(!IMAGE_SNAP_BY_ORDINAL(ptname->u1.Ordinal)){
piname = (PIMAGE_IMPORT_BY_NAME)(base + (DWORD)ptname->u1.AddressOfData);
OutTraceH("IATPatch: BYNAME ordinal=%x address=%x name=%s hint=%x\n", ptaddr->u1.Ordinal, ptaddr->u1.AddressOfData, (char *)piname->Name, piname->Hint);
if(!lstrcmpi(apiname, (char *)piname->Name)) break;
}
else{
if(ordinal && (IMAGE_ORDINAL32(ptname->u1.Ordinal) == ordinal)) { // skip unknow ordinal 0
OutTraceH("IATPatch: BYORD ordinal=%x addr=%x\n", ptname->u1.Ordinal, ptaddr->u1.Function);
//OutTraceH("IATPatch: BYORD GetProcAddress=%x\n", GetProcAddress(GetModuleHandle(dll), MAKEINTRESOURCE(IMAGE_ORDINAL32(ptname->u1.Ordinal))));
break;
}
}
}
else {
// OutTraceH("IATPatch: fname=%s\n", fname);
if(!lstrcmpi(apiname, fname)) {
OutTraceH("IATPatch: BYSCAN ordinal=%x address=%x name=%s\n", ptaddr->u1.Ordinal, ptaddr->u1.AddressOfData, fname);
break;
}
for(; *fname; fname++); for(; !*fname; fname++);
}
if (apiproc){
// examining by function addr
if(ptaddr->u1.Function == (DWORD)apiproc) break;
}
ptaddr ++;
if (ptname) ptname ++;
}
if(ptaddr->u1.Function) {
org = (void *)ptaddr->u1.Function;
if(org == hookproc) return 0; // already hooked
if(!VirtualProtect(&ptaddr->u1.Function, 4, PAGE_EXECUTE_READWRITE, &oldprotect)) {
OutTraceDW("IATPatch: VirtualProtect error %d at %d\n", GetLastError(), __LINE__);
return 0;
}
ptaddr->u1.Function = (DWORD)hookproc;
if(!VirtualProtect(&ptaddr->u1.Function, 4, oldprotect, &oldprotect)) {
OutTraceDW("IATPatch: VirtualProtect error %d at %d\n", GetLastError(), __LINE__);
return 0;
}
if (!FlushInstructionCache(GetCurrentProcess(), &ptaddr->u1.Function, 4)) {
OutTraceDW("IATPatch: FlushInstructionCache error %d at %d\n", GetLastError(), __LINE__);
return 0;
}
OutTraceH("IATPatch hook=%s address=%x->%x\n", apiname, org, hookproc);
return org;
}
}
pidesc ++;
}
if(!pidesc->FirstThunk) {
OutTraceH("IATPatch: PE unreferenced function %s:%s\n", dll, apiname);
return 0;
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
OutTraceH("IATPatch: EXCEPTION hook=%s:%s Hook Failed.\n", dll, apiname);
}
return org;
}
void *IATPatch(HMODULE module, char *dll, void *apiproc, const char *apiname, void *hookproc)
{
return IATPatch(module, 0, dll, apiproc, apiname, hookproc);
}