none
通过覆盖系统函数的地址来实现HOOK API 中的MessageBoxProxy函数哪里被使用了 ? RRS feed

  • 问题

  • //<br/>
    //write by Gxter<br/>
    //<br/>
    //通过覆盖系统函数的地址来实现HOOK API<br/>
    //<br/>
    #include "stdio.h"<br/>
    #include "windows.h"<br/>
    #include "tchar.h"<br/>
    <br/>
    // "崩溃函数绝对地址"指00401020<br/>
    BYTE addr_old[8] = {0};<br/>
    BYTE addr_new[8] = { 0xB8, 0x20, 0x10, 0x40, 0x00, 0xFF, 0xE0, 0x00 }; //第2,3,4,5是需要手工调整的(重要的步骤)<br/>
    DWORD pfnMsgBox=0; //API函数地址<br/>
    <br/>
    <br/>
    <strong>int WINAPI MessageBoxProxy(IN HWND hWnd, IN LPCSTR lpText, IN LPCSTR lpCaption, IN UINT uType)<br/>
    {<br/>
    	int ret = 0;<br/>
    <br/>
    	DWORD dwOldProtect;<br/>
    	MEMORY_BASIC_INFORMATION  mbi;<br/>
    	<br/>
    	printf("%08x\n", MessageBoxProxy);<br/>
    <br/>
    	::VirtualQuery((void *)pfnMsgBox, &mbi, sizeof(mbi));<br/>
    	::VirtualProtect((void *)pfnMsgBox, 8, PAGE_READWRITE, &dwOldProtect);<br/>
    	<br/>
    	// 写入原来的执行代码, 恢复<br/>
    	::WriteProcessMemory(::GetCurrentProcess(),<br/>
    		(void *)pfnMsgBox,<br/>
    		addr_old,<br/>
    		sizeof(DWORD)*2,<br/>
    		NULL);<br/>
    	<br/>
    	::VirtualProtect((void *)pfnMsgBox, 8, mbi.Protect, 0);<br/>
    	<br/>
    	ret=MessageBox(hWnd,"gxter","gxter",uType);<br/>
    	<br/>
    	return ret;<br/>
    }<br/>
    </strong>
    <br/>
    <br/>
    //----------------------------------------------程序入口<br/>
    int main()<br/>
    {<br/>
    	DWORD dwOldProtect;<br/>
    	MEMORY_BASIC_INFORMATION  mbi;<br/>
    	<br/>
    	MessageBox(NULL,_T("Hook Demo!"),_T("API Hook"),MB_ICONINFORMATION);<br/>
    	pfnMsgBox=(DWORD)GetProcAddress(GetModuleHandle(_T("user32.dll")),_T("MessageBoxA"));<br/>
    	printf("api 入口地址: %x\n",pfnMsgBox);<br/>
    	<br/>
    	<br/>
    	VirtualQuery( (void *)pfnMsgBox, &mbi, sizeof(mbi) );<br/>
    	//修改我们要改的地址的页属性,为可读可写<br/>
    	VirtualProtect( (void *)pfnMsgBox, 8, PAGE_READWRITE, &dwOldProtect);<br/>
    	<br/>
    	// 保存原来的执行代码<br/>
    	memcpy(addr_old, (void *)pfnMsgBox, 8);<br/>
    	<br/>
    	// 写入新的执行代码<br/>
    	WriteProcessMemory( GetCurrentProcess(),<br/>
    		(void *)pfnMsgBox,<br/>
        addr_new,<br/>
    		sizeof(DWORD)*2,<br/>
    		NULL);<br/>
    	//修改为原来的属性属性<br/>
    	VirtualProtect((void *)pfnMsgBox, 8, mbi.Protect, 0);<br/>
    	<br/>
    	//当调用这个函数的时候就跳到我的函数上面了<br/>
    	MessageBox(NULL,_T("Hook Demo!"),_T("API Hook"),MB_ICONINFORMATION);<br/>
    	<br/>
    	<br/>
    	getchar();<br/>
    	return 0;<br/>
    }<br/>
    
    
    上面的程序,我没有看到 函数 MessageBoxProxy 被使用了,但是把这个函数给注释掉,程序又出错,是什么原因呢  ?

    清钟沁桐
    2010年8月8日 6:57

答案

全部回复

  •  
     
    • 已标记为答案 vfdff 2010年8月9日 14:39
    • 已编辑 ID已删 2010年8月16日 5:24
    2010年8月8日 8:20
  • int WINAPI MessageBoxProxy(IN HWND hWnd, IN LPCSTR lpText, IN LPCSTR lpCaption, IN UINT uType)
    {
      int ret = 0;
    
      DWORD dwOldProtect;
      MEMORY_BASIC_INFORMATION  mbi;
    
      printf("%08x\n", MessageBoxProxy);
    
      ::VirtualQuery((void *)pfnMsgBox, &mbi, sizeof(mbi));
      ::VirtualProtect((void *)pfnMsgBox, 8, PAGE_READWRITE, &dwOldProtect);
    
      // 写入原来的执行代码, 恢复
      ::WriteProcessMemory(::GetCurrentProcess(), (void *)pfnMsgBox, addr_old, sizeof(DWORD)*2, NULL);
    	
      ::VirtualProtect((void *)pfnMsgBox, 8, mbi.Protect, 0);
    	
      ret=MessageBox(hWnd,"gxter","gxter",uType);
    	
      return ret;
    } 
    
    但是MessageBoxProxy函数内使用  printf("%08x\n", MessageBoxProxy);
    把地址显示出来时,却发现这个地址不是 00401020 ?
    清钟沁桐
    2010年8月9日 14:41
  • 不建议在Hook后的执行函数中恢复原函数然后跳转回去执行,很不稳定,多线程杯具死你

          可以直接把覆盖的指令在函数中实现,然后只需要跳回到被覆盖指令的下一条指令执行

    就算恢复,也推荐使用原子操作,WriteProcessMemory不用的好

    2010年8月9日 19:17