/*
;配置文件格式
[hook_1]
dll=kernel32.dll fun=GetModuleHandleA min_addr=0x1000000 max_addr=0x2000000
*/
#include <tchar.h> #include <windows.h> #include <stdio.h> #define MAX_HOOK_FUNCTION 100 typedef struct _HOOK_FUNCTION_LIST { TCHAR szDllName[MAX_PATH]; // dll 路径 CHAR szFunctionName[MAX_PATH]; // 函数名 ULONG PointerToCode; // 函数入口 BYTE cOrgCode[5]; // 函数入口的原始 5 个字节 BYTE cNewCode[5]; // 函数入口 hooked 5 个字节 // 当返回地址在下面两个值之间,就 pause ULONG uMinReturnAddr; // 返回地址的最小值 ULONG uMaxReturnAddr; // 返回地址的最大值 } HOOK_FUNCTION_LIST, *PHOOK_FUNCTION_LIST; HMODULE __hModule; // 模块实例 CHAR __szFullPath[MAX_PATH]; // 当前模块的完整路径 CHAR __szMsgText[0x100]; // 弹出消息的文本 HOOK_FUNCTION_LIST __HookFunctionList[MAX_HOOK_FUNCTION]; CRITICAL_SECTION __LockMessageBox; HANDLE __hCurProcess; ULONG __uTlsIndex; #define _MY_STACK_SIZE 0x1000 // 应该够用了 VOID ClearHookFunctionList() { } // 不进行堆栈溢出检查 PULONG GetMyStackBase() { PULONG pStack = (PULONG)TlsGetValue(__uTlsIndex); if ( pStack == NULL ) { pStack = (PULONG)VirtualAllocEx(__hCurProcess, NULL, _MY_STACK_SIZE * sizeof (ULONG), MEM_COMMIT, PAGE_READWRITE); ULONG uStackTop = _MY_STACK_SIZE - 1; pStack[uStackTop] = uStackTop; TlsSetValue(__uTlsIndex, pStack); } return pStack; } ULONG& GetMyStackTop() { PULONG pStack = GetMyStackBase(); return pStack[_MY_STACK_SIZE - 1]; } ULONG PUSH_VALUE(ULONG uValue) { PULONG pStack = GetMyStackBase(); ULONG& uStackTop = GetMyStackTop(); return (pStack[--uStackTop] = uValue); } ULONG POP_VALUE() { PULONG pStack = GetMyStackBase(); ULONG& uStackTop = GetMyStackTop(); return pStack[uStackTop++]; } VOID __cdecl /*禁止平栈*/ _pLeave_ProxyFunction(ULONG uDummyValue) { ULONG uReturnAddr = POP_VALUE(); ULONG CalledFunction = POP_VALUE(); PULONG pCurStack = &uDummyValue; pCurStack[2] = uReturnAddr; // 利用压入的值,改为返回到原始 code PHOOK_FUNCTION_LIST pHfl = __HookFunctionList; for ( int i = 0; i < MAX_HOOK_FUNCTION; i++ ) { if ( CalledFunction == pHfl->PointerToCode ) { DWORD dwTemp; WriteProcessMemory(__hCurProcess, (PVOID)CalledFunction, pHfl->cNewCode, 5, &dwTemp); // 重新 hook break; } pHfl++; } } ULONGLONG __declspec(naked) Leave_ProxyFunction() { __asm { push -1 // dummy value push eax push edx call _pLeave_ProxyFunction pop edx pop eax ret } } VOID __fastcall Enter_ProxyFunction( PULONG pCurStack /* ecx 指向进入这个函数时的堆栈指针 */ ) { /* pCurStack[0] = Function Address pCurStack[1] = Return Address */ const ULONG CalledFunction = pCurStack[0]; ULONG& uReturnAddr = pCurStack[1]; PUSH_VALUE(CalledFunction); PUSH_VALUE(uReturnAddr); PHOOK_FUNCTION_LIST pHfl = __HookFunctionList; for ( int i = 0; i < MAX_HOOK_FUNCTION; i++ ) { if ( CalledFunction == pHfl->PointerToCode ) { DWORD dwTemp; WriteProcessMemory(__hCurProcess, (PVOID)CalledFunction, pHfl->cOrgCode, 5, &dwTemp); // 恢复被 hooked 函数 } if ( (pHfl->uMinReturnAddr < uReturnAddr) && (uReturnAddr < pHfl->uMaxReturnAddr) ) { EnterCriticalSection(&__LockMessageBox); wsprintf(__szMsgText, "函数 %s.%s 调用,返回地址是: 0x%08X!/n 祝你 Dump 成功!", pHfl->szDllName, pHfl->szFunctionName, uReturnAddr); MessageBox(NULL, __szMsgText, _T("提示"), MB_ICONSTOP | MB_DEFAULT_DESKTOP_ONLY); LeaveCriticalSection(&__LockMessageBox); break; } pHfl++; } uReturnAddr = (ULONG)Leave_ProxyFunction; // 修改返回地址 } ULONG __declspec(naked) ProxyFunction() { __asm { sub dword ptr [esp], 5 // 得到函数入口地址 mov ecx, esp // 栈顶送入 Enter_ProxyFunction 参数 call Enter_ProxyFunction ret // 转到原始函数 } } ULONG HexStringTo(PCTSTR pszString) { ULONG uResult = 0; while ( *pszString != 0 ) { TCHAR c = *pszString; uResult <<= 4; if ( c >= _T('a') && c <= ('f') ) { uResult += c - _T('a') + 10; } else if ( c >= _T('A') && c <= ('F') ) { uResult += c - _T('A') + 10; } else if ( c >= _T('0') && c <= _T('9') ) { uResult += c - _T('0'); } else { uResult = 0; } pszString++; } return uResult; } VOID Initialize() { __uTlsIndex = TlsAlloc(); __hCurProcess = GetCurrentProcess(); InitializeCriticalSection(&__LockMessageBox); // // 获取配置文件路径 TCHAR szCfgPath[MAX_PATH]; _tcsncpy(szCfgPath, __szFullPath, MAX_PATH); PTSTR p = _tcsrchr(szCfgPath, _T('.')); if ( p != NULL ) { _tcscpy(p, _T(".ini")); } // // 重配置文件中读取数据,初始化 hook function list PHOOK_FUNCTION_LIST pHfl = __HookFunctionList; memset(pHfl, 0, sizeof (pHfl)); for ( int i = 0; i < MAX_HOOK_FUNCTION; i++ ) { TCHAR szMinAddr[50]; TCHAR szMaxAddr[50]; TCHAR szAppName[MAX_PATH]; wsprintf(szAppName, _T("hook_%d"), i + 1); if ( GetPrivateProfileString(szAppName, _T("dll"), _T(""), pHfl->szDllName, MAX_PATH, szCfgPath) == 0 || GetPrivateProfileString(szAppName, _T("fun"), _T(""), pHfl->szFunctionName, MAX_PATH, szCfgPath) == 0 || GetPrivateProfileString(szAppName, _T("min_addr"), _T(""), szMinAddr, MAX_PATH, szCfgPath) == 0 || GetPrivateProfileString(szAppName, _T("max_addr"), _T(""), szMaxAddr, MAX_PATH, szCfgPath) == 0 ) { break; } pHfl->uMinReturnAddr = HexStringTo(szMinAddr); pHfl->uMaxReturnAddr = HexStringTo(szMaxAddr); pHfl++; } // // 被 hook 的函数最好不要有下列 api, 并且不支持 fastcall // LoadLibrary // GetProcAddress // WriteProcessMemory // EnterCriticalSection // LeaveCriticalSection // MessageBox // wsprintf pHfl = __HookFunctionList; for ( int j = 0; j < MAX_HOOK_FUNCTION; j++ ) { HMODULE hModule = LoadLibrary(pHfl->szDllName); if ( hModule != NULL ) { pHfl->PointerToCode = (ULONG)GetProcAddress(hModule, pHfl->szFunctionName); if ( pHfl->PointerToCode != NULL ) { DWORD dwTemp; // call xxxx pHfl->cNewCode[0] = 0xe8; *(PULONG32)(pHfl->cNewCode + 1) = (ULONG)ProxyFunction - (pHfl->PointerToCode + 5); ReadProcessMemory(__hCurProcess, (PVOID)pHfl->PointerToCode, pHfl->cOrgCode, 5, &dwTemp); WriteProcessMemory(__hCurProcess, (PVOID)pHfl->PointerToCode, pHfl->cNewCode, 5, &dwTemp); pHfl++; } } } } VOID UnInitialize() { DeleteCriticalSection(&__LockMessageBox); } BOOL WINAPI DllMain(HMODULE hModule, DWORD dwReason, LPVOID p) { if ( dwReason == DLL_PROCESS_ATTACH ) { __hModule = hModule; GetModuleFileName(hModule, __szFullPath, MAX_PATH); // __asm int 3 Initialize(); } else if ( dwReason == DLL_PROCESS_DETACH ) { UnInitialize(); } return TRUE; } |
dump 使用小工具设计
最新推荐文章于 2024-08-10 08:27:46 发布