本帖最后由 |流年灬一逝| 于 2012-7-26 09:20 编辑
前言
第一章
第二章
第三章
第四章
第五章
第六章
既然来了,就坚持读下去吧,认真读下去,一定会有收获的!
**********************************************************************************************
三、APIHook - 上 在学习了前面的两章Hook,大家应该已经对Hook由一个大致的了解了。 本章中,我们来学习一下APIHook。我们本章中的内容是要实现拦截MessageBoxA函数的调用,使他无效。 本章内容相对来说比较简单,也是给以后更深入的API Hook打下基础。 简单的来说,Hook一般包含一下几方面: 找到Hook地址 – 申请Hook代码储存空间 – 变更原地址,跳转到Hook代码储存空间执行 – 跳回原处执行相应代码 加红的这处,因为我们从原来的代码修改了jmp跳转,所以可能有一句或两句的代码无法执行,在我们Hook代码储存区里如果有需要的话,可以补充这两句代码。 那么APIHook也非常简单,它是针对程序调用API函数时候的一个Hook。 这时,程序执行到IAT表所指向的映射到程序中的API函数,我们通过获取IAT指定函数的地址,对这个地址进行Hook,就可以达到对API的Hook。 本章,我们将介绍如何对本程序中的函数调用进行Hook 学习这一章前,我们先认识几个API函数。 GetModuleHandle 获取库句柄 参数 lpModuleName 库名称,如 kernel32.dll
GetProcAddress 获取库函数地址 参数 hModule 库句柄 lpProcName 库函数名称
VirtualProtect 修改虚拟保护 参数 lpAddress 修改的虚拟保护区域首地址 dwSize 修改的虚拟保护长度 flNewProtect 新的虚拟保护 lpflOldProtect 保存旧的虚拟保护
我们要知道,程序的任何地方都可以调用API函数,所以我们不能Hook程序的某个地方,我们要Hook API函数的某个地方。一般情况下,我们都选择Hook API首地址的前5个字节。
图中,蓝色的区域是程序的某个位置,通过跳转、Call等指令,执行到红色的地方(API函数)。 我们可以用GetProcAddress函数来获取一个API函数的调用首地址。它的第一个参数需要一个库句柄,我们可以用GetModuleHandle函数来获取。 函数地址 = GetProcAddress( GetModuleHandle(库函数名称),函数名称) 这样就可以获取一个库中函数的地址。 接下来我们对它进行Hook:
(中间水印的地方是:函数地址 = API_GetProcAddress (模块句柄, “MessageBoxA”))
其中,{194,16,0}的汇编指令为 retn 0x10,也就是返回.当程序执行到这个信息框函数时,就返回。注:{16,0}是 参数的个数*4 后得到的字型数据 但是实际过程中,我们点击Hook按钮,对MessageBoxA进行Hook的时候,易程序会崩溃,这是由于我们对本程序的访问权限不足而导致的。 因为我们此时修改的是映射在我们程序中的库函数,属于程序的一部分,它对我们具有只读保护,我们想要对这段代码内存修改,就需要修改它的保护。 这也是我们今天的一个重要的API函数:VirtualProtect 修改之后的代码:
我们在获取了函数地址之后,将我们要修改的前3个字节的保护设置为PAGE_EXECUTE_READWRITE,也就是可读可写,这样,再进行写入;写入完毕后,修改它的保护为之前的(旧保护)。 我们再来看看效果: Hook之前的:
Hook之后:(无任何反应,说明我们的Hook成功了)
*****************************************************************************************
大家有什么疑问可以回帖提出来
代码:
code.rar
(1.62 KB, 下载次数: 342)
|