hook基础讲解-转发分享的,希望对大家有用。
不死不休的一条不归路。。。。这几所有天看了一下学习资料,补充知识来解决自己遇到的问题(易游验证更换KEY打补丁无效),小生大牛说hook掉所有接口地址,从此我就走上了不归路,睡觉前拿手机学习,路上看,下班看,我就不信不能解决我的问题,内心呐喊不止。。。。。。这是搞到的教程,链接:http://pan.baidu.com/s/1o8o1pGI 密码:n6ja还有一个是从度娘上找到的,链接:http://pan.baidu.com/s/1jInn2iq 密码:id7r(绝对适合新手看,如果不了解汇编,当我没说)网上还有其他教程,大家自己搜搜看看
0、hook简介
简介:Hook是一个针对程序执行过程中挂钩技术。它主要用来拦截一些数据,并对这些数据进行处理,此时,程序转到我们的Hook代码,我们拥有整个程序的执行权限,我们可以选择跳过此处,也可以选择修改数据,或者出错退出程序等等。
系统应用范围:Hook技术应用非常广泛,可以应用在客户层(程序),也可以应用在硬件层(内核),本专题针对客户层进行介绍。
外部和内部:我们一般用Hook主要是用在外部程序,来监视一个程序的某个动作是否满足我们的条件。也可以用在本程序,这种作用我们以后介绍。
Hook的种类: Hook主要是用在拦截这方面,那么最重要的就是API了。也就是APIHook。也可以是拦截程序API执行过程。
前提:
学习Hook,你需要有一点汇编基础(为了能看懂本专题中的一些例子和图示)。
工具我们统一使用OllyDBG、易语言、API伴侣(可选)。在这里我使用吾爱破解版本的OllyDBG,下载地址:http://115.com/file/c44d0s9xAPI伴侣可以使用钟少敏写的易用API伴侣,下载地址:http://115.com/file/e6dje67n
1、HOOK原理
有学过PE文件的朋友可能都会这样一个感染文件的方法:
1、 新建一个区段。2、 把代码放入这个区段里。3、 在原始代码入口前,增加一条指令,jmp到这个区段中。4、 执行完整个区段之后,在区段的末尾,jmp回到原始代码的入口。
这样就完成了一个程序的Hook,我们可以直接在程序入口添加一个Hook,弹出信息框,选确定方可进入程序,选否则退出程序。其实这也就是一个hook,不过这样的Hook并不实用。因为我们并不是想控制程序的运行与否,而是控制程序执行过程而达到我们的一些目的。
我们来用OD写第一个Hook。下面是一个Windows窗口程序,我们在_启动子程序下写如下代码:
2、远程Hook
上一节我们知道了怎样在OllyDBG中Hook修改一个数据,然后转存。这节课我们主要学习一下远程修改指定进程的代码来达到我们Hook的目的。其实这节课也就是编写程序来实现OD中的修改代码的操作。这节课我们需要学习几个API函数。1、OpenProcess 打开一个进程,返回进程句柄2、WriteProcessMemory 在一个进程中写入数据3、CloseHandle 关闭一个内核对象4、ReadProcessMemory 读取进程数据5、VirtualAllocEx 在目标进程中申请一段内存空间(存放Hook代码)6、VirtualFreeEx 在目标进程中释放申请的内存空间因为是要动态修改程序代码,所以这节课的原程序有所改变,是一个静态编译的Windows窗口程序。
3、APIHook 上
本章,我们将介绍如何对本程序中的函数调用进行Hook学习这一章前,我们先认识几个API函数。GetModuleHandle 获取库句柄参数lpModuleName 库名称,如 kernel32.dll
GetProcAddress 获取库函数地址参数hModule 库句柄lpProcName 库函数名称
VirtualProtect 修改虚拟保护参数lpAddress 修改的虚拟保护区域首地址dwSize 修改的虚拟保护长度flNewProtect 新的虚拟保护lpflOldProtect 保存旧的虚拟保护
我们要知道,程序的任何地方都可以调用API函数,所以我们不能Hook程序的某个地方,我们要Hook API函数的某个地方。一般情况下,我们都选择Hook API首地址的前5个字节。
4、APIHOOK 中
首先,使用LoadLibrary 函数载入动态链接库,获取动态链接库的句柄。其次判断句柄是否为0,如果为零则重新载入一下。接着就是取库函数地址了。取好之后,修改内存保护属性为可读可写,接着就是重点了,为了照顾新手朋友,我会逐一分析。原字节 = 指针到字节集 (函数地址, 5)这句代码保存了API函数的前5个字节。新字节 = { 233 } + 到字节集 (到整数 (新函数地址 - (函数地址 + 5)))这句代码是计算跳转到 新函数地址 这个参数子程序处的机器码。写到内存 (新字节, 函数地址, 5)修改API入口前5字节原字节 = 原字节 + { 233, 0, 0, 0, 0 }今天的重点内容,把原字节和{ 233, 0, 0, 0, 0 }并加,
原地址 = _取指针_字节集 (原字节, 原字节, 0)写到内存 (到整数 (函数地址 + 5 - (原地址 + 10)), 原地址 + 6, 4)
先是取出 原字节 变量的数据指针,接着从原地址 + 6的地方,也就是{ 233, 0, 0, 0, 0 }的 {0, 0, 0, 0 }这个地方开始写入数据,内容是从{ 233, 0, 0, 0, 0 } 这条指令(jmp xxxxxx)跳转到API函数后5个字节的距离。函数地址 + 5 ,这就是API函数的后5个字节的地址;原地址 + 10 就是 原字节 变量的后10个字节,也就是计算机器码跳转的地方,把他们两个相减,就算出了距离。接着写入这个 原字节 变量中,就完整的实现了这个API函数:执行API函数的前5个字节 -> 跳转到API函数的后5个字节处执行我们再来看下 暂停 和 继续 方法:5、APIHook - 下
我们在启动窗口创建完毕后Hook send函数。其他的如同上一章的一样,主要是修改代码变量做了一些改变。首先 修改代码 初始化为 {201,88} 转换为汇编指令也就是leavepop eax,我们知道 leave也就是mov esp,ebppop ebp,所以,这两句也就是把call压入的下一条代码指针弹出到eax里.接着再加上函数指针前5个字节,最后加上{255,224} 汇编指令jmp eax.也就是跳转到call压入的下一条代码指针处。接着取New_Send 函数的真实地址,新代码为 call 新函数地址 这里我们用到call了,没有使用上一章的jmp指令,因为call是在堆栈中压入下一条指令的地址,所以这一点对我们来说方便很多。最后修改函数前5个字节,取到修改代码的指针。接着就是我们的New_send函数了:
6、APIHOOK_扩展7、Windows消息Hook8、拦截API返回值(完结)
我们这一章还是实例,内容相信大家也已经知道了,那么我们拦截API函数返回值有何用处呢?首先,我们针对一些恶意程序,比如像全局消息钩子,是使用像SetWindowsHookEx一类的函数来实现的,它返回的是一个钩子句柄,一样的,如果大家希望不要让某个程序使用OpenProcess函数打开自己的进程,就需要hook获取 OpenProcess函数的返回值,然后CloseHandle使这个进程操作句柄无效。当然这是我们用户层所使用的方法,实际上,OpenProcess是在内核中调用NtOpenProcess函数的,这里我们不讨论它。
那么我们如何下手呢?
我们知道,程序的任何地方都有可能调用指定的API函数,也就是不可能Hook程序的某个部分,那么只好从API来下手了,我们在考虑在API头部来实现,程序Call这个API,会把从程序调用API的某个地方的下一条代码压入堆栈,我们获取它,再对它Hook也可以完成,但是我们这样做太麻烦了——首先要保存被修改的代码,其次还要计算被毁坏的代码。所以,这种方法是不可取的。我们再考虑从API的返回代码,也就是ret xx 来下手。
修改返回代码->手写一段汇编,保存寄存器等->跳转到Hook子程序区->进行处理->返回到保存的API的返回代码(ret xxxx)进行返回。
sorry,忘记说解压密码了,那个我还是传到网盘上吧,坚决不再伟大的52里面放别的地址http://pan.baidu.com/s/1nuDV27f 嗯。hook学习过,问一下你有api伴侣是么?我一直找没找到... 麻烦给个api伴侣吧。最近我在用msdnlibrary,英文的,看的累死了,谢谢楼主 这是乐易的教程,谢谢楼主 好全面,学习了,谢谢楼主的劳动 牛逼牛逼 已收到。谢谢 机智的我已经发现密码了
转载的资料不错。
页:
[1]
2