- 论坛徽章:
- 0
|
HOOK是一种WINDOWS下存在很久的技术了。 \nHOOK一般分两种1。HOOK MESSAGE 2。HOOK API 本问讨论的是HOOK API。(如果你是HOOK高手就不要看了) \n在最初学HOOK-API的时候通常都是通过覆盖地址和修改IAT的方法。\n通过这两种技术,我们基本都可以实现对本进程的API函数进行HOOK了。但是在高兴之余会有点遗憾,\n怎么才能HOOK其他进程的API函数呢?怎么才能对一个API函数进行全局的HOOK呢?\n下面是我的一个简单的“HOOK其他进程API函数”的实现。(对另一进程的MessageBoxA这个函数进行HOOK) \n\n其实里面的应用了两个技术\n1。远程线程注入 \n2。修改IAT,HOOK-API\n\n好了贴出代码如下:\n一共是3个文件\ninstall.c 注入程序 \nfundll.cpp DLL程序 \ntest.cpp 测试程序 \n\n\n//-------------------------install.c--------------------------\n//\n//write by Gxter\n//install.c\n\n#include \"windows.h\"\n#include \"tlhelp32.h\"\n\n#pragma comment(lib,\"th32.lib\" \n\nconst char *pkill=\"fundll.dll\"; //DLL文件的路径\n\n//这个路径很有意思,这个路径是相对于目标进程的,而不是自身进程。\n//所以要嘛写成绝对路径,要嘛写成相对于目标进程的相对路径。\n//如果写成相对于自身的路径就要麻烦了,本程序就找不到DLL文件了。 \n\nchar *prosess=\"test.exe\"; //要注入的进程名(目标进程名)\n\nint main()\n{\n HANDLE hSnap;\n HANDLE hkernel32; //被注入进程的句柄\n PROCESSENTRY32 pe; \n BOOL bNext;\n HANDLE hToken;\n TOKEN_PRIVILEGES tp;\n LUID Luid;\n LPVOID p;\n FARPROC pfn;\n\n if (!OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY,&hToken))\n {\n return 1;\n }\n\n if (!LookupPrivilegeValue(NULL,SE_DEBUG_NAME,&Luid))\n {\n return 1;\n }\n\n tp.PrivilegeCount = 1;\n tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;\n tp.Privileges[0].Luid = Luid;\n\n if (!AdjustTokenPrivileges(hToken,0,&tp,sizeof(TOKEN_PRIVILEGES),NULL,NULL))\n {\n return 1;\n }\n\n pe.dwSize = sizeof(pe);\n hSnap=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);\n bNext=Process32First(hSnap, &pe); \n while(bNext) \n {\n if(!stricmp(pe.szExeFile,prosess)) //--->>\n {\n hkernel32=OpenProcess(PROCESS_CREATE_THREAD|PROCESS_VM_WRITE|PROCESS_VM_OPERATION,1,pe.th32ProcessID);\n break;\n }\n bNext=Process32Next(hSnap, &pe); \n }\n\n CloseHandle(hSnap);\n\n\n\n p=VirtualAllocEx(hkernel32,NULL,strlen(pkill),MEM_COMMIT,PAGE_READWRITE);\n WriteProcessMemory(hkernel32,p,pkill,strlen(pkill),NULL);\n pfn=GetProcAddress(GetModuleHandle(\"kernel32.dll\" ,\"LoadLibraryA\" ;\n CreateRemoteThread(hkernel32,NULL,0,pfn,p,NULL,0); \n\n return 0;\n}\n\n\n//----------------------fundll.cpp-----------------------------\n//\n//write by Gxter\n//\n//fundll.cpp\n\n#include \"windows.h\"\n#include \"process.h\"\n#include \"tlhelp32.h\"\n#include \"stdio.h\"\n\n#pragma comment(lib,\"th32.lib\" \n\nPIMAGE_DOS_HEADER pDosHeader;\nPIMAGE_NT_HEADERS pNTHeaders;\nPIMAGE_OPTIONAL_HEADER pOptHeader;\nPIMAGE_IMPORT_DESCRIPTOR pImportDescriptor;\nPIMAGE_THUNK_DATA pThunkData;\nPIMAGE_IMPORT_BY_NAME pImportByName;\nHMODULE hMod;\n\n\n// 定义MessageBoxA函数原型\ntypedef int (WINAPI *PFNMESSAGEBOX)(HWND, LPCSTR, LPCSTR, UINT uType);\nint WINAPI MessageBoxProxy(IN HWND hWnd, IN LPCSTR lpText, IN LPCSTR lpCaption, IN UINT uType);\n\nint * addr = (int *)MessageBoxA; //保存函数的入口地址\nint * myaddr = (int *)MessageBoxProxy;\n\n\nvoid ThreadProc(void *param);//线程函数\n\n//-------------------------------------------------------主函数开始\n\nBOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved)\n{\n if(fdwReason==DLL_PROCESS_ATTACH) \n _beginthread(ThreadProc,0,NULL); \n\n return TRUE; \n}\n\n\n//结束进程的函数\n\nvoid ThreadProc(void *param)\n{\n //------------hook api----------------\n hMod = GetModuleHandle(NULL);\n\n pDosHeader = (PIMAGE_DOS_HEADER)hMod;\n pNTHeaders = (PIMAGE_NT_HEADERS)((BYTE *)hMod + pDosHeader->e_lfanew);\n pOptHeader = (PIMAGE_OPTIONAL_HEADER)&(pNTHeaders->OptionalHeader);\n\n pImportDescriptor = (PIMAGE_IMPORT_DESCRIPTOR)((BYTE *)hMod + pOptHeader->DataDirectory[1].VirtualAddress);\n\n while(pImportDescriptor->FirstThunk)\n {\n char * dllname = (char *)((BYTE *)hMod + pImportDescriptor->Name);\n\n pThunkData = (PIMAGE_THUNK_DATA)((BYTE *)hMod + pImportDescriptor->OriginalFirstThunk);\n\n int no = 1;\n while(pThunkData->u1.Function)\n {\n char * funname = (char *)((BYTE *)hMod + (DWORD)pThunkData->u1.AddressOfData + 2);\n PDWORD lpAddr = (DWORD *)((BYTE *)hMod + (DWORD)pImportDescriptor->FirstThunk) +(no-1);\n \n //修改内存的部分\n if((*lpAddr) == (int)addr)\n {\n //修改内存页的属性\n DWORD dwOLD;\n MEMORY_BASIC_INFORMATION mbi;\n VirtualQuery(lpAddr,&mbi,sizeof(mbi));\n VirtualProtect(lpAddr,sizeof(DWORD),PAGE_READWRITE,&dwOLD);\n \n WriteProcessMemory(GetCurrentProcess(), \n lpAddr, &myaddr, sizeof(DWORD), NULL);\n //恢复内存页的属性\n VirtualProtect(lpAddr,sizeof(DWORD),dwOLD,0);\n }\n //---------\n no++;\n pThunkData++;\n }\n\n pImportDescriptor++;\n }\n //-------------------HOOK END-----------------\n}\n\n//new messagebox function\nint WINAPI MessageBoxProxy(IN HWND hWnd, IN LPCSTR lpText, IN LPCSTR lpCaption, IN UINT uType)\n{\n return ((PFNMESSAGEBOX)addr)(NULL, \"gxter_test\", \"gxter_title\", 0);\n //这个地方可以写出对这个API函数的处理代码\n}\n\n\n//----------------------------test.cpp------------------------------------\n//\n//write by Gxter\n//test.cpp\n\n#include \"stdio.h\"\n#include \"windows.h\"\n\nint main()\n{\n printf(\"test---\n\" ;\n while(1)\n {\n getchar();\n MessageBoxA(NULL, \"原函数\", \"09HookDemo\", 0);\n }\n return 0;\n}\n\n测试过程:先运行TEST不要关闭(建立目标),再运行install(进行注入)。但要注意FUNDLL和TEST文件位置。 \n\n上面的代码进本上就实现了对其他进程的API进行HOOK了。\n但还有一个问题就是对“API函数进行全局的HOOK”。我的想法就是注入所有进程就可以实现了。\n只要简单的改一下上面的代码就可以实现了。 这好象有点像SetWindowsHookEx这个函数的的实现过程。\n以上就是我想法了,如果在什么地方有错误还请纠正。 \n\n\n参考资料:\n《WINDOWS 程序设计》\n《WINDOWS 核心编程》 \n\nBy Gxter\nhttp://www.safechina.net\nGxter@sogou.com |
|