首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

(急)关于API HOOK(ntdll.dll)的有关问题

2012-04-27 
(急急急!)关于API HOOK(ntdll.dll)的问题我想做的功能是阻止机器休眠、待机、睡眠,已经发了一个帖子http://t

(急急急!)关于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的代码,

C/C++ code
#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();

[解决办法]
设置全局钩子 屏蔽关机 可以么?

热点排行