非淡泊无以明志,非宁静无以致远
分类:
2010-11-15 16:45:20
我接触游戏数据分析很久了,但不做外挂,就是感兴趣而已。现在没有保护的游戏越来越少了,不管游戏开发商采用的是知名的保护软件,还是自己开发的保护,都涉及到驱动。没办法,谁叫我喜欢分析数据了呢那就过保护吧!怎么过,没头绪。先学习一下内核编程吧。主要是内核HOOK。今天就学习一下InLine HOOK。 当然要有实例了,再看看前几天用工具过了保护的游戏。截取一小部分HOOK,如下图
这个实例结合《详谈内核三步走Inline Hook实现》中对inline hook的解释,现在总结出InLine HOOK的流程图如下:
看一下没有被inline hook是的情况: 顺便说一句,inline hook 函数的地址是不会发生变化的,这有SSDT HOOK才会改变函数的地址。inline hook改变的只是函数内容,ssdt hook 改变的是函数地址,当然内容是自己的函数。目前流行和成熟的kernel inline hook技术就是修改内核函数的opcode,通过写入jmp或push ret等指令跳转到新的内核函数中,从而达到修改或过滤的功能。这些技术的共同点就是都会覆盖原有的指令,这样很容易在函数中通过查找jmp,push ret等指令来查出来,因此这种inline hook方式不够隐蔽。 我们在进行inline hook之前要明白一下几个关键点(学习别人来的): ①重中之重 -------------修改哪里 通过学习知道,修该函数的地方其实是任意的,通常是修改函数的入口处,其次是函数的中间也可以是函数的结尾。通常函数的开头是这样的:
通常都是修改这里的,但本文中提到的却是在函数中间。 ②实现手段 -------------怎么修改 我们改的目的是让原函数完成跳转。怎样完成跳转,最简单的无条件跳JMP那上面的代码我们 CALL 等于 push eip ,jmp xxxxxxx 当HOOK未导出函数的时候这个就有用了,搜索E8,E8后面的ULONG就是当前位置与函数的偏移量。当前位置+偏移量+5就等于CALL函数的地址为什么要加5?因为是以下一条指令为基址计算,E8这条指令是5个字节,所以要+5 这是我们inline hook初学者必须注意的一点。看一段代码(摘自:《详谈内核三步走Inline Hook实现》):
*(ULONG *)(JmpAddress+1)=(ULONG)DetourMyObReferenceObjectByHandle-((ULONG)ObReferenceObjectByHandle+5) 是为什么?为什么不是直接jmp DetourMyObReferenceObjectByHandle?之前说过了,jmp是E9的话是短跳,那么这个跳就是以当前为基址,跳转多少偏移。直接jmp DetourMyObReferenceObjectByHandle的话那就是跳转到jmp 当前+xxxxx去了,当然错了,那么我们正确计算这个便宜。原函数距离HOOK函数多远呢?那么就是HOOK函数-原函数。为什么原函数还要再加上5呢?是偏移这个xxxxxx,是下一条指令开始计算的。jmp xxxxxx这条指令占了5个字节,也就是JMP XXXXXXX这条指令和HOOK函数的距离是多少呢?那不就是HOOK函数-原函数-JMPXXXXXX指令长度吗?那就得出了那个5。 ④编写自己的Hook函数 HOOK函数就是我们自己写的替换原函数的函数。代理函数一般在HOOK函数里面调用,执行原函数功能的函数。代理函数一般声明为naked函数;参数,返回值和原函数是一样的。而功能就是执行原函数被修改的字节,在跳转到原函数。
在DriverEntry中调用HookObReferceObjectByHandle函数在DriverUnLoad函数中调用UnHookObReferceObjectByHandle就可以了。 解释一下NTKERNELAPI这是在wdm.h中定义的一个宏,请看如下定义: 如何在函数中间进行HOOK还在学习之中,请等待..... |