inline hook【001】

42 篇文章 1 订阅
11 篇文章 0 订阅

什么是inline hook呢?图像解释下:


程序本来是要调用左边的目标函数,但是,我们在有没源码的情况下,想要在调用这个函数的时候做点其他事情,就需要插进去我们的函数,这个实现方式就是inline hook

操作原理非常简单:

在程序调用目标函数时候,会找到该函数的地址(图里边的head  A),通过将这个头信息偷偷的替换:


通过jmp B跳到head B,调用我们的插入函数,这样只要被HOOK的程序调用目标函数,就一定会先调用我们的插入函数,(比如游戏中,人机对战,电脑偷偷调用某个行动的时候,我们把它的行为打印,甚至改变,来帮助我们实现我们的想法)。

但是不能影响原来函数的操作,我们在插入函数运行结束后,再将目标函数被去掉的头部还给它,然后在指回去:


然而,在驱动编程的时候,我们往往这样做:http://www.cnblogs.com/Safe3/archive/2008/10/20/1315381.html

HOOK:

	KIRQL Irql;
	//开始inline hook
	//关闭内存写保护
	_asm
	{
		push eax
			mov eax, cr0 
			mov CR0VALUE, eax 
			and eax, 0fffeffffh  
			mov cr0, eax
			pop eax
	}
	//提升IRQL中断级
	Irql=KeRaiseIrqlToDpcLevel();
	//函数开头五个字节写JMP 
	RtlCopyMemory((BYTE *)NtOpenProcess,JmpAddress,5);
	//恢复Irql中断级
	KeLowerIrql(Irql);
	//开启内存写保护
	__asm
	{       
		push eax
			mov eax, CR0VALUE 
			mov cr0, eax
			pop eax
	}

UnHook:

	//把五个字节再写回到原函数
	KIRQL Irql;
	//关闭写保护
	_asm
	{
		push eax
			mov eax, cr0 
			mov CR0VALUE, eax 
			and eax, 0fffeffffh  
			mov cr0, eax
			pop eax
	}
	//提升IRQL到Dpc
	Irql=KeRaiseIrqlToDpcLevel();
	RtlCopyMemory((BYTE *)NtOpenProcess,OriginalBytes,5);
	KeLowerIrql(Irql);
	//开启写保护
	__asm
	{       
		push eax
			mov eax, CR0VALUE 
			mov cr0, eax
			pop eax
	}



但是很多时候我们想要的是一个应用级别的dll,而不是内核级别的sys,可以这样: http://blog.sina.com.cn/s/blog_802a13bc0100qyol.html

同样想实现这个流程,但是在应用级别,没有权限调用cr0,应用级别,可以用这个来做:

HOOK:

void HookOn() 
{ 
	HANDLE hProc; 
	DWORD dwIdOld = GetCurrentProcessId(); // 得到所属进程的ID 
	// 得到所属进程的句柄 
	hProc = OpenProcess(PROCESS_ALL_ACCESS,0,dwIdOld); 
	// 修改所属进程中MessageBoxA的前5个字节的属性为可写 
	VirtualProtectEx(hProc,NtOpenProcess,5,PAGE_READWRITE,&dwIdOld); 
	// 将所属进程中MessageBoxA的前5个字节改为JMP 到MyMessageBoxA 
	WriteProcessMemory(hProc,NtOpenProcess,JmpAddress,5,0); //RtlCopyMemory((BYTE *)NtOpenProcess,JmpAddress,5);
	// 修改所属进程中MessageBoxA的前5个字节的属性为原来的属性 
	VirtualProtectEx(hProc,NtOpenProcess,5,dwIdOld,&dwIdOld); 
	bHook=true; 
} 
UnHook:

void HookOff() 
{ 
	HANDLE hProc; 
	DWORD dwIdOld = GetCurrentProcessId(); // 得到所属进程的ID 
	hProc = OpenProcess(PROCESS_ALL_ACCESS,0,dwIdOld); 
	VirtualProtectEx(hProc,NtOpenProcess,5,PAGE_READWRITE,&dwIdOld); 
	WriteProcessMemory(hProc,NtOpenProcess,OriginalBytes,5,0); //RtlCopyMemory((BYTE *)NtOpenProcess,OriginalBytes,5);
	VirtualProtectEx(hProc,NtOpenProcess,5,dwIdOld,&dwIdOld); 
	bHook = false; 
} 
有个比较赞的地方:拷贝一个函数体几个字节到指定空间

_asm 

pushad    //将EAX,ECX,EDX,EBX,ESP,EBP,ESI,EDI这8个指令压栈,保存现场
lea edi,OldMessageBoxACode  //edi存放的是想要将数据移动到的目标地址,也就是OldMessageBoxACode  
mov esi,fpMessageBoxA    //esi存放的是数据存放的源地址
cld  //cld是来控制重复移动时候的esi 和edi的递增方式。 cld是将方向标志位DF设置为0,每次rep循环的时候,esi和edi自动+1。   std是将方向标志位DF设置为1,每次rep循环的时候,esi和edi自动-1。
movsd  //移动字节数,movsd是DWORD,movsw是WORD,movsb是BYTE
movsb 
popad    //将EAX,ECX,EDX,EBX,ESP,EBP,ESI,EDI这8个指令弹出,还原现场


参考:http://blog.csdn.net/zhenyongyuan123/article/details/8364011

http://blog.csdn.net/flowshell/article/details/6094184

http://blog.csdn.net/feixiaoxing/article/details/7009911

接下来需要做的:

完整写一个实例。

如何将DLL注入到指定程序:http://blog.csdn.net/beanjoy/article/details/8497307

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值