(急急急!)关于API HOOK(ntdll.dll)的问题
我想做的功能是阻止机器休眠、待机、睡眠,已经发了一个帖子http://topic.csdn.net/u/20110325/11/e3a033e2-0a76-4096-a553-6aa6c7b152d0.html,因为要支持VISTA和WIN7,所以WM_POWERBROADCAST不能解决问题了,有两位大师已经指出了道路:API HOOK,要HOOK的是ntdll里的NtSetSystemPowerState,网上有一份代码可以HOok到user32.dll的Messagebox,但不能hook到ntdll里的函数,请问是否有大师能帮个忙搞定这个HOOK,急啊,拜托了!
注:下面是网上能HOOK Messagebox的代码,
#include <stdio.h> #include <windows.h> #pragma comment(lib,"Dbghelp.lib") #pragma comment(lib,"User32.lib") typedef int (__stdcall *OLD_MessageBox)( HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption,UINT uType ); OLD_MessageBox g_procOldMessageBox = NULL; int __stdcall HOOK_MessageBox( HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption,UINT uType) { printf("%s\t%d\r\n",__FUNCTION__,__LINE__); if (NULL != g_procOldMessageBox) return g_procOldMessageBox(hWnd,lpText,"不好意思,hook到了!",uType); else return MessageBox(hWnd,lpText,lpCaption,uType); ; } int replace_IAT(const char *pDllName,const char *pApiName,bool bReplace) { HANDLE hProcess = ::GetModuleHandle (NULL); DWORD dwSize = 0; PIMAGE_IMPORT_DESCRIPTOR pImageImport = (PIMAGE_IMPORT_DESCRIPTOR)ImageDirectoryEntryToData(hProcess,TRUE, IMAGE_DIRECTORY_ENTRY_IMPORT,&dwSize); if (NULL == pImageImport) return 1; PIMAGE_IMPORT_BY_NAME pImageImportByName = NULL; PIMAGE_THUNK_DATA pImageThunkOriginal = NULL; PIMAGE_THUNK_DATA pImageThunkReal = NULL; while (pImageImport->Name) { if (0 == strcmpi((char*)((PBYTE)hProcess+pImageImport->Name),pDllName)) { break; } ++pImageImport; } if (! pImageImport->Name) return 2; pImageThunkOriginal = (PIMAGE_THUNK_DATA)((PBYTE)hProcess+pImageImport->OriginalFirstThunk ); pImageThunkReal = (PIMAGE_THUNK_DATA)((PBYTE)hProcess+pImageImport->FirstThunk ); while (pImageThunkOriginal->u1.Function) { if ((pImageThunkOriginal->u1 .Ordinal & IMAGE_ORDINAL_FLAG) != IMAGE_ORDINAL_FLAG) { pImageImportByName = (PIMAGE_IMPORT_BY_NAME)((PBYTE)hProcess+pImageThunkOriginal->u1 .AddressOfData ); if (0 == strcmpi(pApiName,(char*)pImageImportByName->Name)) { MEMORY_BASIC_INFORMATION mbi_thunk; VirtualQuery(pImageThunkReal, &mbi_thunk, sizeof(MEMORY_BASIC_INFORMATION)); VirtualProtect(mbi_thunk.BaseAddress,mbi_thunk.RegionSize, PAGE_READWRITE, &mbi_thunk.Protect); if (true == bReplace) { g_procOldMessageBox =(OLD_MessageBox) pImageThunkReal->u1.Function; pImageThunkReal->u1.Function = (DWORD)HOOK_MessageBox; } else pImageThunkReal->u1.Function = (DWORD)g_procOldMessageBox; DWORD dwOldProtect; VirtualProtect(mbi_thunk.BaseAddress, mbi_thunk.RegionSize, mbi_thunk.Protect, &dwOldProtect); break; } } ++pImageThunkOriginal; ++pImageThunkReal; } return 0; } int main() { replace_IAT("User32.dll","MessageBoxA",true); MessageBox(NULL,"EnumIAT User32.dll MessageBoxA true;","",MB_OK); replace_IAT("User32.dll","MessageBoxA",false); MessageBox(NULL,"EnumIAT User32.dll MessageBoxA false;","",MB_OK); return getchar(); }
HANDLE hProcess = ::GetModuleHandle (NULL); 这个定义总不能 打开自己的进程来更改别人的进程吧???
我是这样实现的, 将一个木马动态库注入到目标进程中去, 然后在木马库中 获取目标进程的句柄,更改保护权限, 用过一个字节指针pA指向 messagebox, 用另一个字节指针pB指向MyMessageBox,
然后计算这两个指针所对应地址的相对偏移量dwOffset,
再次更改pA的内容,即改为 0xE9 + dwOffset ; 一共5个字节
这时候只要目标程序调用 messagebox就会跑到 myMesssageBox中
但是没完, 这里不知道为什么崩溃,,可能是淸栈问题,还没研究出来。 所以在MyMessageBox中再次把messageBox地址改回来, return MessageBox();
[解决办法]
设置全局钩子 屏蔽关机 可以么?