1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187
|
#include <windows.h>
#include <string.h>
#define MakePtr(cast, ptr, addValue)(cast)((DWORD)(ptr)+(DWORD)(addValue))
DWORD GetModuleBaseFromWin32sHMod(HMODULE hMod); // Prototype(defined below)
PROC WINAPI HookImportedFunction(
HMODULE hFromModule, // Module to intercept calls from
PSTR pszFunctionModule, // Module to intercept calls to
PSTR pszFunctionName, // Function to intercept calls to
PROC pfnNewProc // New function(replaces old function)
)
{
PROC pfnOriginalProc;
PIMAGE_DOS_HEADER pDosHeader;
PIMAGE_NT_HEADERS pNTHeader;
PIMAGE_IMPORT_DESCRIPTOR pImportDesc;
PIMAGE_THUNK_DATA pThunk;
BOOL B;
DWORD dwOld, dw;
// DWORD *pdw1;
if(IsBadCodePtr(pfnNewProc)) // Verify that a valid pfn was passed
return 0;
// First, verify the the module and function names passed to use are valid
pfnOriginalProc = GetProcAddress(GetModuleHandle(pszFunctionModule),
pszFunctionName);
/* pdw1 =(DWORD*)pfnOriginalProc;
pfnOriginalProc =(PROC)*pdw1;*/
if(!pfnOriginalProc)
return 0;
if((GetVersion() & 0xC0000000) == 0x80000000)
pDosHeader = // Win32s
(PIMAGE_DOS_HEADER)GetModuleBaseFromWin32sHMod(hFromModule);
else
pDosHeader =(PIMAGE_DOS_HEADER)hFromModule; // other
// Tests to make sure we're looking at a module image(the 'MZ' header)
if(IsBadReadPtr(pDosHeader, sizeof(IMAGE_DOS_HEADER)))
return 0;
if(pDosHeader->e_magic != IMAGE_DOS_SIGNATURE)
return 0;
// The MZ header has a pointer to the PE header
pNTHeader = MakePtr(PIMAGE_NT_HEADERS, pDosHeader, pDosHeader->e_lfanew);
// More tests to make sure we're looking at a "PE" image
if(IsBadReadPtr(pNTHeader, sizeof(IMAGE_NT_HEADERS)))
return 0;
if(pNTHeader->Signature != IMAGE_NT_SIGNATURE)
return 0;
// We know have a valid pointer to the module's PE header. Now go
// get a pointer to its imports section
pImportDesc = MakePtr(PIMAGE_IMPORT_DESCRIPTOR, pDosHeader,
pNTHeader->OptionalHeader.
DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].
VirtualAddress);
// Bail out if the RVA of the imports section is 0(it doesn't exist)
if(pImportDesc == (PIMAGE_IMPORT_DESCRIPTOR) pNTHeader)
return 0;
// Iterate through the array of imported module descriptors, looking
// for the module whose name matches the pszFunctionModule parameter
while(pImportDesc->Name)
{
PSTR pszModName = MakePtr(PSTR, pDosHeader, pImportDesc->Name);
if(stricmp(pszModName, pszFunctionModule) == 0)
break;
pImportDesc++; // Advance to next imported module descriptor
}
// Bail out if we didn't find the import module descriptor for the
// specified module. pImportDesc->Name will be non-zero if we found it.
if(pImportDesc->Name == 0)
return 0;
// Get a pointer to the found module's import address table(IAT)
pThunk = MakePtr(PIMAGE_THUNK_DATA, pDosHeader, pImportDesc->FirstThunk);
// Blast through the table of import addresses, looking for the one
// that matches the address we got back from GetProcAddress above.
while(pThunk->u1.Function)
{
if((DWORD)pThunk->u1.Function == (DWORD)pfnOriginalProc)
{
// We found it! Overwrite the original address with the
// address of the interception function. Return the original
// address to the caller so that they can chain on to it.
//Problem persists in winXP... Not required in win98..
//DLL will simply unload if an unalowed byte was modified.
if(IsBadWritePtr(&pThunk->u1.Function, 4))
{
B = VirtualProtect(&pThunk->u1.Function, 4,
PAGE_EXECUTE_READWRITE, &dwOld);
pThunk->u1.Function =(DWORD)pfnNewProc;
B = VirtualProtect(&pThunk->u1.Function, 4,
dwOld, &dw);
}else
pThunk->u1.Function = (DWORD)pfnNewProc;
//pfnOriginalProc =(PROC)(DWORD)pdw1;
return pfnOriginalProc;
}
pThunk++; // Advance to next imported function address
}
return 0; // Function not found
}
typedef DWORD(__stdcall *XPROC) (DWORD);
// Converts an HMODULE under Win32s to a base address in memory
DWORD GetModuleBaseFromWin32sHMod(HMODULE hMod)
{
XPROC ImteFromHModule, BaseAddrFromImte;
HMODULE hModule;
DWORD imte;
hModule = GetModuleHandle("W32SKRNL.DLL");
if(!hModule)
return 0;
ImteFromHModule =(XPROC)GetProcAddress(hModule, "_ImteFromHModule@4");
if(!ImteFromHModule)
return 0;
BaseAddrFromImte =(XPROC)GetProcAddress(hModule, "_BaseAddrFromImte@4");
if(!BaseAddrFromImte)
return 0;
imte = ImteFromHModule((DWORD)hMod);
if(!imte)
return 0;
return BaseAddrFromImte(imte);
}
typedef int(WINAPI *LOADICONPROC) (HINSTANCE, LPCTSTR);
LOADICONPROC OriginalProc;
int WINAPI LoadIconH(HINSTANCE hInstance, LPCTSTR lpIconName)
{
int ret;
ret = OriginalProc(hInstance, "MYICON");
MessageBox(0, "LoadIcon called", "Hook", 0);
return ret;
}
DWORD WINAPI ThreadProc(LPVOID thParam)
{
OriginalProc = (LOADICONPROC)
HookImportedFunction(GetModuleHandle(0), "USER32.DLL", "LoadIconW",(PROC)LoadIconH);
if(!OriginalProc)
{
MessageBox(0, "Hook failed", "ERROR", 0);
return FALSE;
}
}
BOOL APIENTRY DllMain(HINSTANCE hModule, DWORD reason, LPVOID lpReserved)
{
HANDLE hThr;
if(reason != DLL_PROCESS_ATTACH) return FALSE;
hThr = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) ThreadProc, NULL, 0, NULL);
if(hThr == NULL) return FALSE;
else CloseHandle(hThr);
return TRUE;
} |
Partager