2017/4/22inlinehook学习


http://www.cnblogs.com/zhangdongsheng/archive/2013/04/08/3007154.html

学习这部分,不要被复杂的Windows编程类型所困扰

首先说明大概原理,我们既然要hook某一个函数P,让其首先执行我们的函数Q就是达到这样一个过程的话,本来是P,现在我们让它先P->Q->P那么只要修改P的前几行指令,让其跳转到我们的Q函数地址上,一般采用的是JMP指令,也看到有人说可以用push ret 和call的。

         那么我们为什么一般会修改进程的前5个字节呢,这是根据需求得到的,就是我们要jmp的时候,一般是jmp(0xe9)加上一个四字节偏移,正好是5个字节的内容。所以要修改前5个字节。

         那么下一个问题,加入P的地址是&P,Q的地址是&Q,好像直接jmp &Q-&P就好了但是要注意jmp的时候是使得EIP的值增加,跳转到增加后的EIP指针的位置执行,而EIP指向的并不是我们正在执行的jmp的地址,或者说不是已经被修改了的P的人口处的地址,而是它的下一条指令。下一条指令显然距离入口5个字节。所以jmp的是&Q-&P-5。所以我们修改被覆盖的函数的地址的时候,要修改它的前5个字节为jmp &Q-&P-5,数值要提前计算出来再写进去。

         需要注意的是,在执行完我们自己的函数以后,要加上已经被覆盖的原来的函数的5个字节的指令,使得他们能够继续执行,好像什么都没有发生一样。然后至于我们的函数想要做什么,那就全凭自己控制了!

         最后一个,也是困扰了我好久的一个难题,就是,如何修改人家函数的指令。。。我总不能直接把内存条打开手写进去吧。。。

         在大神的源码里发现了这个神奇地函数:

BOOL WriteProcessMemory(

HANDLE hProcess,

LPVOID lpBaseAddress,

LPVOID lpBuffer,

DWORD nSize,

LPDWORD lpNumberOfBytesWritten

);

         所以windows的API真是功能强大啊,了解了一下几个参数的作用,以后备用:

         hProcess,就是打开的进程句柄,要写入某个进程的内存

         IpBaseAddress,指向要写入的地址开始处的指针,要hook某函数,就填写函数运行时.text段的地址,要hook其他进程的什么地方就随便填写啦!

         lpBuffer,要写入内存地址空间的内容的缓冲区的指针。

         nSize就是要写入函数地址的内容的大小。类型是整型。

         lpNumberOfBytesWritten最后一个是一个整型指针,看意思是指向的是写入的字节数,,好像就是前一个参数的指针,大神的源码里把这个设为了NULL。

附上大神链接和源码,以备后面的学习:http://www.cnblogs.com/zhangdongsheng/archive/2013/04/08/3007154.html

// hook_blog_writer.cpp : 定义控制台应用程序的入口点。
//
#include <stdafx.h>
#include <windows.h>
#include <stdio.h>

typedef int (WINAPI
	*MessageBox_type) (
		__in_opt HWND hWnd,
		__in_opt LPCSTR lpText,
		__in_opt LPCSTR lpCaption,
		__in UINT uType);	

MessageBox_type RealMessageBox = MessageBoxA;

//我们自己的MessageBox,每调用MessageBox都要跳到myMessageBox来处理
_declspec(naked)  void WINAPI
myMessageBox(
	__in_opt HWND hWnd,
	__in_opt LPCSTR lpText,
	__in_opt LPCSTR lpCaption,
	__in UINT uType)
{
	__asm
	{
		PUSH ebp
		mov ebp, esp

		/*
		vs2010 debug 编译后的代码由于要cmp esi esp来比较堆栈。
		所以这里在调用非__asm函数前push一下esi
		*/
		push esi
	}
	//下面打印MessageBox参数
	printf("hwnd:%8X lpText:%s lpCaption:%s,uType:%8X", hWnd, lpText, lpCaption, uType);

	__asm
	{
		/*
		vs2010 debug 编译后的代码由于要cmp esi esp来比较堆栈。
		所以这里在调用非__asm函数前push一下esi
		*/
		pop esi

		mov ebx, RealMessageBox
		add ebx, 5
		jmp ebx
	}
}


#pragma pack(1)
typedef struct _JMPCODE
{
	BYTE jmp;
	DWORD addr;
}JMPCODE, *PJMPCODE;

VOID HookMessageBoxA()
{
	JMPCODE jcode;
	jcode.jmp = 0xe9;//jmp
	jcode.addr = (DWORD)myMessageBox - (DWORD)RealMessageBox - 5;

	RealMessageBox = MessageBoxA;
	::WriteProcessMemory(GetCurrentProcess(), MessageBoxA, &jcode, sizeof(JMPCODE), NULL);
}

int _tmain(int argc, TCHAR* argv[])
{
	HookMessageBoxA();  //hook操作
	::MessageBoxA(NULL, "hook test", "tip", MB_OK); //执行api MessageBox
	return 0;
}




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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值