Chinaunix首页 | 论坛 | 博客
  • 博客访问: 181955
  • 博文数量: 57
  • 博客积分: 2215
  • 博客等级: 大尉
  • 技术积分: 635
  • 用 户 组: 普通用户
  • 注册时间: 2010-11-09 15:47
个人简介

非淡泊无以明志,非宁静无以致远

文章分类

全部博文(57)

文章存档

2013年(12)

2011年(15)

2010年(30)

我的朋友

分类:

2010-11-15 16:45:20

我接触游戏数据分析很久了,但不做外挂,就是感兴趣而已。现在没有保护的游戏越来越少了,不管游戏开发商采用的是知名的保护软件,还是自己开发的保护,都涉及到驱动。没办法,谁叫我喜欢分析数据了呢那就过保护吧!怎么过,没头绪。先学习一下内核编程吧。主要是内核HOOK。今天就学习一下InLine HOOK。

当然要有实例了,再看看前几天用工具过了保护的游戏。截取一小部分HOOK,如下图


就已NtOpenProcess为例吧,我们用windbg查看一下嘛~~~

这个实例结合《详谈内核三步走Inline 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那上面的代码我们
可以改成jmp xxxxxxxx,这里的XXXXXXX就是我们的HOOK函数jmp跳有近跳,和远跳。近跳就是以当前为基址,跳多少,XXXXXXX就是多少远跳就是。E9是近跳,那么跳的是偏移,EA是远跳那么跳的是绝对地址还有一种方法是
push xxxxxxxxx,
ret
xxxxxxx是我们的hook函数地址。ret的功能是
pop eip
那么push xxxxxxx后,又ret,把hook函数的地址放到了eip就等于去eip的地址执行指令,那么
就是执行hook函数了。顺便解释一下call:

CALL 等于

push eip

,jmp xxxxxxx

当HOOK未导出函数的时候这个就有用了,搜索E8,E8后面的ULONG就是当前位置与函数的偏移量。当前位置+偏移量+5就等于CALL函数的地址为什么要加5?因为是以下一条指令为基址计算,E8这条指令是5个字节,所以要+5
③不得不说的事 ------------------JMP偏移量的计算

这是我们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函数;参数,返回值和原函数是一样的。而功能就是执行原函数被修改的字节,在跳转到原函数。
由于是小菜鸟,在函数内部进行iline hook 还是没学会呢。主要是没想明白!先给一个hook函数开头的代码,实现禁止打开进程:

在DriverEntry中调用HookObReferceObjectByHandle函数在DriverUnLoad函数中调用UnHookObReferceObjectByHandle就可以了。

解释一下NTKERNELAPI这是在wdm.h中定义的一个宏,请看如下定义:


如何在函数中间进行HOOK还在学习之中,请等待.....

阅读(8572) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

upuplbj2015-03-04 00:28:21

请教一下,图片可以看吗?
谢谢!