做得好,你完成了CE的教程了,再玩玩这个TUT并学习一下其他的扫描方法怎样工作的】
另外:
cheat engine教程-代码注入实例教程
转自http://hi.baidu.com/xgwk/blog/item/67fcab8622d8673b66096e6d.html
本教程由CCB原创,转载时请征得本人同意并注明。
代码注入(CODE INJECTION)是对付动态内存分配(DMA)游戏的常用方法。这个教程目的是想让你了解有关代码注入方面的相关知识,并以CE的TUTORIAL为实例来说明一下实际的操作。
选择CE的TUT来做实例是因为大家手头上基本上都有CE,并且TUT第六步使用的就是DMA,这样可以以最简单的方法让大家最快地接触和理解代码注入的 原理和实际操作。这个教程面向那些已经掌握了CE操作的人,特别是按TUT的要求做完CE的教程的,并且要有一定的汇编语言基础。如果你还不能熟悉CE的 操作,或者CE的教程你还没完成,或者你完全不懂汇编,可能很难看懂,请先去学些基础,学好了再来看这个教程。
我手头上用的是CE4.4,大家可能都在用5.2了吧,不过没关系,基本上都一样。好了,让我们开始吧!
第一步:
运行CE,运行TUT,然后输入密码098712直接进到第六步。
现在我们先来找TUT窗口上那个数值的地址,找到地址后,象原来做教程第六步一样,找到改写这个地址的指令。这一次,这条指令的所在内存地址对我们来说比 较重要,找到指令后要把它的地址记下来。然后,我们还是象做教程第六步一样找到指针,并把它以指针方式加到地址列表上,因为后面我们还要来看看我们做代码 注入的效果。
我这里找到的这条指令是:
004560CF MOV [eax], edx
这一步做的基本上就是CE教程里面的第六步,没什么特别的,只是指令的地址要记下来,因为后面还要用到。
第二步:
现在我们要为代码注入做些准备了。首先要做的就是找一个地方来放我们的代码,就是找一个CODE CAVE。在CE主菜单上点MEMORY VIEW,打开内存察看窗口。在内存察看窗口上点菜单:VIEW->MEMORY REGIONS,这个时候就会弹出一个MEMORY REGIONS(内存区域)的窗口,在这个窗口中我们可以看到TUT所使用的各个内存块。我们要找的地方应该是在某一个块的尾部,并且这个块应该是可读写 的,就是在这个内存区域窗口上看PROTECT那一栏应该是Read+Write的,这样才不会导致出错。
在内存区域窗口中,我们可以看到第三个区域00459000,PROTECT那一栏写的是Read+Write,看来这个块就是我们要找的了,再看看它下 面的一个块,是00460000,也就是说,我们找的00459000这个块,范围是从00459000-0045FFFF。那么我们就从它的尾部来找地 方。
现在关了内存区域这个窗口,回到内存察看这个窗口。我们在上半部点右键->GO TO ADDRESS,输入00460000,然后再往上翻。嗯,不错,这个位置全是00 00,基本上可以确定是我们可以用的地方了。然后我们还要规划一下,特别是我们不太确定我们要写入的代码有多少,所以尽量留多一点,以免破坏下一个块 (00460000),所以我们确定把代码放在0045FF10这里,另外我们要确定一个地址来放我们得到的数值的地址,就放在0045FF40吧。
这一步主要做的就是找地方放我们的代码,现在就基本确定了。
第三步:
这一步就要真正动手了,不过动手之前,要先看看原来的指令所在的位置那里(就是004560CF)后面的几条指令,并注意这些指令所在的地址。我这里看到的三条指令是这样的:
004560cf 89 10 mov [eax], edx
004560d1 8b 45 fc mov eax, [ebp-04]
004560d4 8b 80 10 03 00 00 mov eax, [eax+00000310]
我们要把这里改成一条JMP指令,由于一条JMP指令是五个字节,所以这里要破坏两条指令,注意如果被破坏的指令总字节数超过五字节,后面多余的要用NOP补上。
现在我们要先写好我们的代码,就是0045FF10那里的代码,这个次序不能搞错,不管我们是在CE中直接汇编还是以后用外挂写入机器码,都要注意这个次 序,因为如果在我们自己的代码没处理好之前就先改原始位置的代码,结果程序如果在这个时候刚好执行到那里的话,就会跳到我们还没准备好的这个位置来,结果 出现不可预料的结果,所以要先写好我们的代码再说。
现在,在内存察看窗口上半部点右键->GO TO ADDRESS,输入0045FF10,然后我们在0045FF10这一行上点右键->ASSEMBLE,然后输入我们的代码,输入完后CE会问, 我们输入的代码字节数和原来代码不兼容,是否要用NOP填掉,因为这里原来放的不是真正的代码,所以点NO就行了。输入一行完了之后再在下一行点右键- >ASSEMBLE输入下一行代码,。我们要输入的代码其实很简单:
mov [0045ff40], eax ---------->这一行是把当前EAX的值,也就是那个数值当前的地址放到我们的地址
mov [eax], edx ---------->这两行是恢复原始位置上被我们破坏了的原来的代码。
mov eax, [ebp-04] ---------->
jmp 004560d4 ---------->这一行是跳回去执行。
四行代码输入完了,0045FF10这个位置上的情况应该是这样的:
0045ff10 89 05 40 ff 45 00 mov [0045ff40], eax
0045ff16 89 10 mov [eax], edx
0045ff18 8b 45 fc mov eax, [ebp-04]
0045ff1b e9 b4 61 ff ff jmp 004560d4
现在回过头来改原始位置的代码,同样是右键->GO TO ADDRESS,再输入004560CF,再点右键->ASSEMBLE,把原始位置上那两条代码改成JMP,改了之后的情况如下:
004560cf e9 3c 9e 00 00 jmp 0045ff10
004560d4 8b 80 10 03 00 00 mov eax, [eax+00000310]
从上面总共六行代码,我们可以看出,当程序执行到004560CF时,是跳到0045FF10执行我们的代码,而我们的代码首先是把EAX的值放到我们指 定的内存地址0045FF40那里,然后就是恢复原始位置上被我们的JMP破坏掉的那两条代码。再然后是跳到原始位置我们那个JMP后面的一行代码去执 行。注意,如果我们先恢复原始位置上那两行代码,再把EAX放到我们所指定的位置的话,就有问题了,因为原始位置上那个第二行代码MOV eax, [ebp-04]已经破坏了EAX的值了。还有跳回去是要跳到JMP后面的一行,否则会造成死循环。
这一步就是代码注入的关键,该解释的上面应该都解释清楚了吧