Inline Hook

// Test.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
#include <iostream>

#pragma comment(lib, "User32")

//int _tmain(int argc, _TCHAR* argv[])
//{
// return 0;
//}

DWORD head;//保存API返回地址
int nRet;
BYTE orig_code[5] = {0x90, 0x90, 0x90, 0x90, 0x90};//存放原始的指令
BYTE hook_code[5] = {0xe9, 0, 0, 0, 0};//存放跳转到MyMessageBoxA的指令
BYTE jmp_org_code[5] = {0xe9, 0, 0, 0, 0};//存放跳转到原起始地址后5字节的指令

int MyMessageBoxA(
        HWND hWnd,          // handle to owner window
        LPCTSTR lpText,     // text in message box
        LPCTSTR lpCaption,  // message box title
        UINT uType          // message box style
        );
int MyMessageBoxAA(
          HWND hWnd,          // handle to owner window
          LPCTSTR lpText,     // text in message box
          LPCTSTR lpCaption,  // message box title
          UINT uType          // message box style
        );
int MyFunc();
void Hook();
int jmp_back();

ULONG OldFuncAddr;
ULONG MyFuncAddr;
ULONG jmp_backAddr;

//在修改前几个字节时,注意:取出的指令为完整的


int main()
{
  Hook();

  int rt = MessageBoxA(NULL, "Hello World", "Title", MB_OK);
//  cout << rt << endl;//查看返回值是否已修改成功

  system("pause");

  return 0;
}

 


void Hook()
{
  DWORD dwOldProtect; 
  OldFuncAddr = (ULONG)MessageBoxA;

 // printf("OldFuncAddr is:%X/n",OldFuncAddr);

  // MyFuncAddr = MyMessageBoxA的实际地址  *(ULONG *)((BYTE *)MyMessageBoxA+1)为跳转偏移差  MyMessageBoxA为偏移 如果在Release模式下则少一个跳转

 // MyFuncAddr = *(ULONG *)((BYTE *)MyMessageBoxA+1) + (ULONG)MyMessageBoxA + 5;
    MyFuncAddr = (ULONG)MyMessageBoxA;

  // jmp_backAddr = jmp_back的实际地址
 // jmp_backAddr = *(ULONG *)((BYTE *)jmp_back+1) + (ULONG)jmp_back + 5;
  jmp_backAddr = (ULONG)jmp_back + 5;
    //修改内存为PAGE_EXECUTE_READWRITE
  VirtualProtect((LPVOID)jmp_backAddr, 10, PAGE_EXECUTE_READWRITE, &dwOldProtect);

  VirtualProtect((LPVOID)OldFuncAddr, 5, PAGE_EXECUTE_READWRITE, &dwOldProtect);
  //计算跳转地址
  *((ULONG*)(hook_code+1)) = (ULONG)MyFuncAddr - (ULONG)OldFuncAddr - 5;//填充跳转地址
 
  memcpy(orig_code,(BYTE *)OldFuncAddr, 5);

  memcpy((BYTE*)OldFuncAddr, hook_code, 5);//在原来的跳转地址处写上跳转至MyMessageBoxA地址
  //计算返回地址
  *((ULONG*)(jmp_org_code+1)) = (ULONG)OldFuncAddr - (ULONG)jmp_backAddr - 5;

  memcpy((BYTE *)jmp_backAddr, orig_code, 5);//原来MessageBox跳转指令

  memcpy((BYTE *)jmp_backAddr + 5, jmp_org_code, 5);//写跳回去的指令
}


__declspec(naked) int jmp_back()
{
  __asm
  {
    _emit 0x90
    _emit 0x90
    _emit 0x90
    _emit 0x90
    _emit 0x90
    _emit 0x90
    _emit 0x90
    _emit 0x90
    _emit 0x90
    _emit 0x90
  }
}


//MyMessageBoxA:在函数执行前进行自己的处理
__declspec(naked) int MyMessageBoxA(
                   HWND hWnd,          // handle to owner window
                   LPCTSTR lpText,     // text in message box
                   LPCTSTR lpCaption,  // message box title
                   UINT uType          // message box style
                  )
{  
  printf("MyMessageBoxA is called/r/n");
   __asm
  {
    pop head
    pop hWnd
    pop lpText
    pop lpCaption
    pop uType
  }
  MyFunc();////可以加入函数过程
  __asm
  {
    //压栈过程
    push uType
    push lpCaption
    push lpText
    push hWnd
    push head
    //跳回MessageBoxA入口点
    jmp jmp_back;
    ret;
  }
}

 

//MyMessageBoxA:在函数执行后进行自己的处理
__declspec(naked) int MyMessageBoxAA(
                  HWND hWnd,          // handle to owner window
                  LPCTSTR lpText,     // text in message box
                  LPCTSTR lpCaption,  // message box title
                  UINT uType          // message box style
                  )
{  
  printf("MyMessageBoxAA is called/r/n");
  __asm
  {
    pop head
    push offset s1;//返回地址为S1:
    //跳回MessageBoxA入口点
    jmp jmp_back;
    s1:    nop 
  }

  MyFunc();
 
  __asm
  {
    ;//将原返回地址压栈
    mov eax, 0;////演示:将返回结果改为0,也可由MyFunc返回
    push head
    ret;
  }
}

int MyFunc()
{
  printf("Hello World/r/n");
  return 1;
}

 

VS2010 Release编译运行!!

你可能感兴趣的:(api,user,null,System,byte,hook)