Inline Hook MessageBoxA

本文简单介绍一下Inline Hook,用MessageBoxA来做试验。

Inline Hook 其实就是jmp来jmp去。理解的了话就不难了。在开始代码之前,先说一下简单的Inline Hook的实现。

1,hook函数几个字节,一般是5个,因为5个才够写一个jmp指令。


2,保存好写jmp指令之前是5个字节,一般用数组来保存。

BYTE old_bytes[5] = {0x0};

3,去掉内存保护

VirtualProtect();

4,jmp去我们的函数,Address = MyFunction - OldFunction;

看(1.)E9 是jmp指令机器码,紧跟着后面的是Address = MyFunction - OldFunction;得到的差值。

5,保存写入跳转的地址的下一个地址。


在这里我选择用eax寄存器来寄放跳回去的地址,用汇编表示如下

__asm

{

mov eax,OldAddress

add eax,5

jmp eax

}

用一个8字节的数组存放上面汇编代码的机器码。

BYTE  jmp_back[8] = {0xb8,0x0,0x0,0x40,0x0,0xff,0xe0,0x0};


6,恢复内存保护

VirtualProtect();


以上是简单的Inline Hook,一般Inline Hook都是通过hook函数开头的5个字节,因为这样处理起来不会很麻烦。但是相对来说就很容易被工具检测到。下图是经典的Inline Hook后的函数样子。

hook之前



hook之后



Inline Hook 最大的问题就是堆栈平衡问题,处理好堆栈平衡之后,任你怎样hook都没问题。


以下是hook得很深的一个代码,就不多加说明了,有问题的看注释。

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

BYTE old_bytes[5] = {0x0};//保存被hook的5个字节
BYTE jmp_to[5] = {0xe9,0x0,0x0,0x0,0x0};//跳转到的地址
BYTE jmp_back[8] = { 0x0B8, 0x0, 0x0, 0x40, 0x0, 0x0FF, 0x0E0,0};//跳回原函数
DWORD OldAddress = 0;
//次函数主要作用是做跳板,申请出来一段空间,以待填入返回数据,然后跳回到原本MessageBoxA函数。
_declspec (naked) void jmp_to_old(HWND hWnd,LPCTSTR lpText,LPCTSTR lpCaption,UINT UType)
{	
	__asm
	{
			__emit 0x90
			__emit 0x90
			__emit 0x90
			__emit 0x90
			__emit 0x90
			__emit 0x90
			__emit 0x90
			__emit 0x90
			__emit 0x90
	}
}
//此函数是hook了之后,你想做神马事都可以的函数。最后那句jmp是跳到跳板函数,恢复原来MessageBoxA函数的堆栈平衡
_declspec (naked) void fun1(HWND hWnd,LPCTSTR lpText,LPCTSTR lpCaption,UINT UType)
{

	printf("hook success!\n");

	__asm
	{		
		jmp jmp_to_old
	}
}

int main(int argc, char* argv[])
{
	DWORD OldProtect; //内存保护类型

	OldAddress = (ULONG)MessageBoxA;//取地址
	memcpy(old_bytes,(PULONG)((ULONG)MessageBoxA+0x32),5);//保存被Hook的5个字节,这里是MessageBoxA+0x32的这样一个偏倚,挺深的了。
	*(PULONG)(jmp_to+1) = (ULONG)fun1 - (ULONG)(OldAddress+0x32+5);//跳转地址
	*(PULONG)(jmp_back+1) = (ULONG)(OldAddress+0x32+5);//跳转回来的地址

	VirtualProtect((PULONG)OldAddress,0x100,PAGE_EXECUTE_READWRITE,&OldProtect);
	memcpy((PULONG)((ULONG)OldAddress+0x32),jmp_to,5); //实现hookMessageBoxA。
	VirtualProtect((PULONG)OldAddress,0x100,OldProtect,NULL);

	VirtualProtect((PULONG)jmp_to_old,0x100,PAGE_EXECUTE_READWRITE,&OldProtect);
	memcpy((PULONG)jmp_to_old,old_bytes,5);//填写跳板函数,恢复MessageBoxA的堆栈平衡。
	memcpy((PULONG)((ULONG)jmp_to_old+5),jmp_back,8);//写入跳转。跳回到MessageBoxA,完美收尾。
	VirtualProtect((PULONG)jmp_to_old,0x100,OldProtect,&OldProtect);

	MessageBoxA(NULL,"second","",NULL);//检测是否已经被hook成功。

	return 0;
}

hook 之前



hook 之后



fun1 的情景。简单的输出hook success。



jmp_to_old 这个跳板函数的情景。恢复堆栈,跳回去。



最后的输出



以上是学习途中的一些笔记,如有错漏还望各位指出。

转载请标明出处:http://blog.csdn.net/z6470975

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值