免費論壇 繁體 | 簡體
Sclub交友聊天~加入聊天室當版主
分享
返回列表 发帖

应用层勾子InLine HOOK

A、InLine HOOK 原理分析
    B、InLine HOOK 代码编写
        C、InLine HOOK 代码测试
        课时:33
       
在 021_绕过驱动保护 已经讲过一次 in line hook
_declspec(naked)
#pragma pack(1)  
//前5字节
77D507EA >    8BFF          MOV EDI,EDI
77D507EC  /.  55            PUSH EBP
77D507ED  |.  8BEC          MOV EBP,ESP

My_MessageBoxA地址 401020

============================================

笔记:
在21课时讲过内联HOOK,本课再继续深入讲解.用VC6新建代码inlineHook_test控制台程序,新建一个MessageBoxA,然后用另一个函数my_MessageBox进行参数与原函数相同.我们在OD里看一下这MessageBoxA函数,将前面几个字节改成JMP XXXXXX,先找到我们自己的函数地址是00401020,然后修改代码跳到这里.在OD中修改了代码之后出现了两次的HOOK成功,应该是有两个地方调用了代码.又修改后打印自己的地址信息,信息正确但是报错,我们需要加上恢复函数头部的代码,但是还是出错了,再加上一条_declspec(naked)生成干脆的汇编

// inlineHook_test.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "hook_test.h"

#include <windows.h>
_declspec(naked)  int My_MessageBox
             (
                           HWND hWnd,          // handle of owner window
                           LPCTSTR lpText,     // address of text in message box
                           LPCTSTR lpCaption,  // address of title of message box
                           UINT uType          // style of message box
                           )

{  
        __asm                                                 //恢复函数头部
        {    mov bx,bx                                //特征码定位
         PUSH EBP
         MOV EBP,ESP

        }
  printf("Hook Ok %x,%s,%s,%x \n",hWnd,lpText,lpCaption,uType);
  __asm
  {
          jmp oldMessageBoxA+5                //HOOK后又跳回
  }
  __asm pop ebp                                        //堆栈平衡
  __asm retn 0x10                                        //堆栈平衡
}

int main(int argc, char* argv[])
{   
    //        printf("Hello World!\n");
        MessageBoxA(NULL,"Hook Test Contect","hook",MB_OK);
        printf("End Process \n");
        getchar();
        return 0;
}

已经成功了,原理清楚后再用一下之前已经写好的hook_test.h


#include <windows.h>
typedef   int   (__stdcall *MessageBox_type)(
                                                                                         HWND hWnd,          // handle of owner window
                                                                                         LPCTSTR lpText,     // address of text in message box
                                                                                         LPCTSTR lpCaption,  // address of title of message box
                                                                                         UINT uType          // style of message box
                           ) ;
MessageBox_type old_MessageBoxA;

#pragma pack(1)  
typedef struct _JMPCODE
{
        BYTE jmp;
        DWORD addr;

}JMPCODE,*PJMPCODE;

_declspec(naked)
VOID __stdcall my_MessageBox(
                           HWND hWnd,          // handle of owner window
                           LPCTSTR lpText,     // address of text in message box
                           LPCTSTR lpCaption,  // address of title of message box
                           UINT uType          // style of message box
                           )
{
        // old_MessageBoxA(hWnd,"Hook ok",lpCaption,uType);
        __asm
        {
                PUSH EBP
                MOV EBP,ESP
        }
         printf("取得参数%x,%s,%s,%x\n",hWnd,lpText,lpCaption,uType);
         __asm
         {
                 mov ebx,old_MessageBoxA
             add ebx,5
                 jmp ebx
         }
          printf("hook Error\n");
}
VOID InLine_HookMessageBoxA()
{ JMPCODE jcode;
         //取得MessageBoxA函数当前地址
         HMODULE h=LoadLibraryA("user32.dll");
     old_MessageBoxA=(MessageBox_type)(GetProcAddress(h,"MessageBoxA"));
         //替换jmp指令
         jcode.jmp=0xe9;
         jcode.addr=(DWORD)(&my_MessageBox)-(DWORD)(&MessageBoxA)-5;//目的地址-当前地址-5 //跳到my
         old_MessageBoxA=&MessageBoxA;
         WriteProcessMemory(GetCurrentProcess(),&MessageBoxA,&jcode,sizeof(JMPCODE),NULL);
         CloseHandle(h);
}

int main(int argc, char* argv[])
{
         printf("Hello World!\n");
     InLine_HookMessageBoxA();
         MessageBoxA(NULL,"333","222",MB_OK);
         return 0;
}

代码过程:通过LoadLibrarA(“user32.dll”);来取得原有MessageBoxA函数地址,然后写入我们的HOOK代码, 通过公式计算执行到我们自己的函数处,执行完后再恢复原有函数.最后在OD里详细的看清HOOK流程.这种内联HOOK用于保护/盗密等,应用比较广泛.

返回列表