代码注入实例教程(续一)
如果你前面看过我写的
代码注入实例教程并且理解里面的做法,也成功地做了代码注入了,那么今天我们再来改进一下我们前一次的做法,这次做得更复杂点,也更完善点。
友情提醒:如果你完全不懂汇编,估计看了这些会很不明白,建议你先去补充一些必要的汇编知识,这个教程是写给那些有一定的汇编基础的人看的,看不懂的话自己去看汇编教程,我不想再浪费我的时间来说一些别人早已经写得非常清楚详细的汇编基础。
我们这次要来对前面的代码注入做两个方面的改进:
一,利用代码注入来锁定数值。
二,让CHANGE VALUE按钮和CHANGE POINTER按钮两个都同时把数值的新地址写到我们的指定位置。
前面已经说过的一些做法我就不再重复了,我现在只重点解释一些新的内容。
一,利用代码注入来锁定数值:
今天我们的做法仍然和前一次一样,只不过在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 - 50 push eax (1)
0045ff1c - 8b 05 40 ff 45 00 mov eax, [0045ff40] (2)
0045ff22 - c7 00 88 13 00 00 mov [eax], 00001388 (3)
0045ff28 - 58 pop eax (4)
----------------------------------------------------
0045ff29 - e9 a6 61 ff ff jmp 004560d4
其实除了新增加的四行代码,其他的四行和原来完全一样。就是转到这里来之后,我们先把地址放到我们指定的位置,然后恢复原始位置上被破坏的两行代码,接着,在跳回去之前,我们又加了些代码,其实就是要往那个保存数值的地址上写入我们指定的值(1388是十六进制数,就是十进制的5000),(3)这一行就是做这件事的,那么为什么还要(1),(2)和(4)呢?
这就涉及了汇编的规则了,我们要往一个地址写入数值,先要把这个地址放到寄存器,然后才能写入数值,这是汇编的规定。(其实我的汇编水平也不高,为什么会有这样要求等等,自己看教程。顺便说一下,我写的这些代码和我说的这些,也不一定是最正规的甚至不一定是正确的,一切以汇编教程和书本上的为准)。因此,才需要(2)这一步先把我们已经保存在0045FF40上的这个数值的地址先调入到EAX寄存器中。
那么,又为什么还要用到(1)和(4)这两行呢?因为我们在(2)和(3)的时候借用了EAX这个寄存器,由于这个寄存器原来里面有数值(天知道原来的数值是多少,还有原来的数值对程序来说有多重要!),所以我们要先把数值保留起来,然后我们开始使用EAX寄存器,使用完了之后,我们再把原来的数值放回到EAX,这样才不会破坏程序的正常运行,有借有还,再借不难嘛,嘿嘿。PUSH和POP这两个指令就是用来保存和恢复寄存器的数值的,PUSH的作用是把指定寄存器的值压到堆栈中,而POP则相反,是从堆栈中把数值恢复到指定的寄存器。有关PUSH和POP的用法请自行参看相关汇编教程。
所以,这一次我们这么修改,就是由原始位置(004560CF)处跳到我们的代码(0045FF10)处执行,先把放有数值地址的寄存器放到我们指定的位置上,然后恢复被我们破坏的两条指令,再然后(1)保存EAX的值,再(2)用EAX来调入我们保存的数值地址,然后我们(3)往数值地址写入我们指定的数字,然后(4)恢复EAX的值,最后是跳回原处执行后续的指令。
经过我们这么修改之后,现在按CHANGE VALUE按钮之后,除了0045FF40这里会保存数值的地址之外,TUT上的数字还会被我们改成5000,其实也就是数值被我们锁定在5000了。
上面只是用这个例子来说明代码注入实际上能做到的比我们想象的要多,只要你有足够的汇编水平,并且有一块足够大的内存空间给你放你的代码,事实上代码注入几乎可以做任何你想象得到的事。比如说大家熟悉的珊瑚虫版的QQ,在早期的版本其实就是用代码注入的方法直接把查IP的代码注入到QQ主程序里面的,想不到吧?
其实我都说了,上面这个只是扩展我们上次实例教程中所注入的代码的功能的一个例子,要锁定数值,可以做得更简单些,如果你看得懂汇编代码,知道哪一句是做什么的,就很容易用更简单的方法来锁定数值,其实在004560CF这一句:
004560CF mov [eax], edx
EDX里面就是你按CHANGE VALUE按钮之后产生的新数值,这一句就是把新数值放到数值的地址里。那么如果把这一句修改成mov [eax], 00001388,而不是把EDX放进去,这样不就行了?不过因为这个新代码比原来的代码长,直接在原始位置上修改会破坏后面的指令,所以不能直接在原始位置上修改,要在跳转到0045FF10之后再那里修改。如果是原来的指令比我们要修改的指令长,那么还可以直接在原始位置修改,连代码注入都不用!
所以,在0045ff10那里如果你改成这样:
0045ff10 - c7 00 88 13 00 00 mov [eax], 00001388
0045ff16 - 8b 45 fc mov eax, [ebp-04]
0045ff19 - e9 b6 61 ff ff jmp 004560d4
这样就是不用做任何外挂,直接在游戏中修改成无敌了!当然,别忘了004560CF仍然要改成JMP 0045FF10。
第一行是把原来按了CHANGE VALUE按钮之后写入新产生的数值,修改成写入固定的5000(1388),第二句仍然是恢复原始位置上被破坏的这条指令,第三行就是跳回去,就这样,简单吧?不过这个已经是超出这个教程的本意了,我们的重点是在研究代码注入,而不是在研究游戏修改,呵呵。
再说一遍,汇编教程里面能查到的内容,别再问我,自己去看,我不会再回复汇编教程里面已经说得清楚的东西。
> >