媒介
关于指针找法,多种多样,此中最为“著名”的就是“跟踪法”。它通过跟踪关键数据,来找到各级指针和偏移,从而得到最终数据。此法固然基础正确(熟练的话,不管对找CALL还是找关键代码都很有帮助),但其均匀服从可能只能归于到O(n^2)的级别了。对于新手来说,一定的成就感是激发学习兴趣的一定催化剂。如果练习的目的层层递进,刚好“合适”,那最好不过。但大多数环境下,新手都只是对自己喜欢的目的感兴趣,而一般环境下使用“跟踪法”的效果大多是失败的。失败次数过多,对于大部分人来说,是劝退的直接原因。若想对新手友好,就必须改变使它的服从和难度都一定比例的降落。这里就不得不说到人造指针,它通过找到关键代码,读取关键地点,而获得关键数据。但就目前大多数相关教程来说,只应用到最基础的条理:改变获取。而对于像普通指针一样,加载即获取的性质是不具备的,如许每第一次更改数据还需人为“修改”一次,使得交互性打了折扣(大家都想“所见即所用”,不是吗?)
本文就人造指针举行进一步拓展,使获取指针方式更加高效
PS:
本文所有技术资料仅供研究,不鼓励任何盗版商用行为
欢迎文明转载,请注明出处 御坂00001号
本文所有红色标志处,为理论核心,也就是其它说再多,最后还是归结于如许的一句话
知识预备
我把人造指针分为两个阶段:基础和提升,下面为示区分,以 人造指针-基础 和 人造指针-提升 命名,而它们的共同之处就以 人造指针 表现
首先,我们来说说人造指针-基础的基础概念和其适用范围
人造指针-基础:找到关键代码,读取关键地点,而获得关键数据
适用范围:一种方式一次调用
暂停一下,这里所谓的“一种方式一次调用”是指啥呢?是如许的,当我们使用CE对数据举行找什么访问或找什么写入时,对于关键代码的 调用次数 是存在不同环境的,下面逐一列出它的类型以及分析
1. 一种方式一次调用:即关键代码所在的CALL,只用来访问或写入一类数据,而且一次动作(使某数据变化的行为)只触发一次。好比植物大战僵尸里的阳光增减的关键代码,它只在阳光改变时调用,且只调用一次
2. 一种方式多次调用:即关键代码所在的CALL,只用来访问或写入一类数据,但一次动作触发多次。好比魔兽争霸3冰封王座里的物品栏数量增减的关键代码,它只在某个物品栏数量改变时调用,但它会循环遍历6个物品栏,如果这个时候读取,就只能获取最后一个地点
3. 多种方式一次调用:即关键代码所在的CALL,被用来访问或写入多类数据,而且触发多次。假如生命值/魔法值/力量/灵敏度/智力等的增减代码都共用一个函数,则相关量改变时,它最终会调用多次
4. 多种方式多次调用:即关键代码所在的CALL,被用来访问或写入多类数据,而且触发多次。一般出现在 持续不断 的访问的关键代码中
暂停一下,这里提示一下,CE工具提供的反汇编功能很强大,尤其自动汇编和访问改写为最,但这里访问改写框中代码的计数只表现改数据的访问修改的次数,并不代表它的关键代码只实行那么多次。这里恰好与上面的几个类型印证。而我们这次的核心就是利用好访问改写功能,辅助以自动汇编。嗯。。。你想变得更加强大吗?我觉得可以试试深入明白访问改写或自动汇编(包罗代码注入\AOB注入\API Hook\代码重定位\Lua函数调用)的原理,看CE源码。。。
如上,我们可以轻易得到一个结论:人造指针-基础 只应用到第一种环境或第二种环境。这对于至少凌驾一半的游戏是没用的,好比魔兽争霸3冰封王座中的生命值/魔法值,如果只应用 人造指针-基础 的知识,由于其关键代码属于 多次方式多次调用 的类型,它的第一个困难就是无法下断跟踪,因为多种方式,所以恰好是你需要的环境的概率为1/N。又因为多次调用,这个概率就变为1/N^2。如果这个时候它持续不断,这个概率就变为1/OO(无穷小,不考虑叠加性,可以认为为0)。因此,这个时候我们需要搬出 人造指针-提升 的基础概念及方法
人造指针-提升:找到关键代码,设置条件断点,获取寄存器状态,分析关键寄存器含义,利用多重特性而获得唯一的环境
适用范围:上述四种环境(欢迎后来者继续补充,对人造指针举行拓展,使其无限接近普通指针所具有的特性:加载即所得)
使用方法:附近分析法
暂停一下,给出附近分析法的一个简朴分析:即对访问改写的关键代码,利用其寄存器状态、栈状态、特殊值等,通过自动汇编获得数据的动态基址,从而获得最终数据。具体看实战分析来体会
人造指针的实质还是CE的访问写入功能与自动汇编功能的结合。人造指针-基础只是简朴的结合两者,只能用于访问次数少或非持续数据。而人造指针-提升则把寄存器状态和栈的状态乃至其它特殊值加入进来,使得应用范围扩展到任意可被访问或写入的数据(好比当关键代码被持续访问时,可以人造指针-提升来获取即时的指针。也就是说,人造指针-提升的技术力还只能够使持续访问的代码来获得普通指针的特性,但对于非持续的暂时还需要条件触发它。但这里我有个建议:我们可以把非持续的作为被持续加载的一个子程序,从而获得普通指针的特性)
实战分析
逻辑分析
首先,我们来分析快速制作
数据捕捉:对于修建而言,它的耗费金币\耗费木材\耗费时间等数据应该是在一起或相隔不远的。这里我们假设它的金币和木材是靠近的,对它举行字节数组搜刮。可以得到目的数据
动作分析:很简朴,就是一般的访问触发
接着,我们来分析快速研发
数据捕捉:对于科技而言,这里是不能像上面直接捕捉到实际数据的。因此我们需要间接联想:这个数据可以被谁访问或修改了谁?这里提示一下:CE数据分析的本质,还是与具体游戏动作有关。因此不论是直接的修改还是间接的访问都需要对应的动作接洽 这里,很轻易联想到,研发某个科技,我们的金币木材会发生改变,这个时候目的数据必然需要被访问。因此耗费金币\耗费木材可以通过跟踪此关键代码向上跟踪到
动作分析:同快速制作
上述对比,可知当直接搜刮数据(一般是4字节,然后浮点,最后字节数组、字符串)不到时,可以联想某动作与数据的关系,是访问还是修改。因为游戏动作不是孤立的,所以数据也不是孤立的。直接不行,就间接或逆向思考或换个角度等
CE分析
分析一:快速制作
首先,我们如图搜刮,得到目的数据
接着,我们如图查找什么访问/改写,得到关键代码,并可分析(下断,发现它只在制作时调用)得到它属于 一种方式一次调用 的类型
接着,分析寄存器状态,获取关键寄存器含义
接着,分析栈状态,获取栈中相关值
接着,利用寄存器状态\栈状态等多重特性,编写自动汇编脚本
[Asm] 纯文本查看 复制代码[ENABLE]//code from here to '[DISABLE]' will be used to enable the cheatalloc(newmem,2048)label(returnhere)label(code)label(exit)alloc(BLE,4)registersymbol(BLE)alloc(KSSC,4)registersymbol(KSSC)newmem:cmp [Game.dll+ACBDD8],0 //包管在创建界面,脚本可运行je codecmp ecx,Game.dll+ACB2B4jne codemov [BLE],ebxmov ebx,[Game.dll+ACBDD8]mov ebx,[ebx+3F4]cmp ebx,0 //包管在载入地图界面,脚本可运行je recovermov ebx,[ebx+238]cmp ebx,0je recovermov ebx,[ebx+1F4]cmp edi,ebx //一重特性jne recovercmp [esp],edx //二重特性jne recovercmp [esp+14],edi //三重特性jne recoveralter:mov [KSSC],eax //获取制作时间的动态基址mov eax,1 //使制作时间为1jmp end0recover:mov ebx,[BLE]code:mov eax,[eax+18]end0:pop ecxret exit:jmp returnhere"Game.dll"+29C2DE:jmp newmemreturnhere: [DISABLE]//code from here till the end of the code will be used to disable the cheatdealloc(newmem)dealloc(BLE,4)unregistersymbol(BLE)dealloc(KSSC)unregistersymbol(KSSC)"Game.dll"+29C2DE:mov eax,[eax+18]pop ecxret //Alt: db 8B 40 18 59 C3
最后,效果如下
分析二:快速研发
首先,我们如图搜刮,得不到目的数据(搜到的值修改无效果)
接着,我们间接联想,查找金币\木材增减的关键代码
接着,向上跟踪增减量
接着,跟进金币\木材减少的CALL
接着,跟进金币获得CALL
接着,可以发现,在这个CALL实行后,EAX便等于我们所要寻找的值,但可以很轻易知道,这个CALL是一个体系函数,查一下atoi函数,可以知道它起把字符串转化为整数的作用,第一个参数为常字符指针
接着,分析CALL前面的Push,跳到EDX处,可以看到字符串形式的耗费金币值。因此我们现在可以知道耗费金币\耗费木材\耗费时间是以字符串形式存储的,所以我们第一步是搜不到的
接着,得到目的数据后,通过查找什么访问,可以获得关键代码。这里可以像分析逐一样继续分析。这里下一个条件断点
接着,分析寄存器状态\栈状态,获取栈中相关值
接着,利用寄存器状态\栈状态等多重特性,编写自动汇编脚本
[Asm] 纯文本查看 复制代码[ENABLE]//code from here to '[DISABLE]' will be used to enable the cheatalloc(newmem,2048)label(returnhere)label(code)label(exit)alloc(BLA,4)alloc(BLBA,4)registersymbol(BLBA)alloc(KSYF,4)registersymbol(KSYF)newmem: //this is allocated memory, you have read,write,execute access//place your code herecmp [Game.dll+ACBDD8],0je codemov [BLA],ecxmov ecx,[Game.dll+ACBDD8]mov ecx,[ecx+3F4]cmp ecx,0je recmp ebp,0je remov ecx,[ecx+238]cmp [esp+3C],ecx //一重特性jne realt:mov ecx,[esp-4]mov [KSYF],ecx //获取研发时间的动态基址mov eax,1 //使研发时间为1re:mov ecx,[BLA]code:mov [esi+30],eaxmov eax,ediexit:jmp returnhere"Game.dll"+4CBE9E:jmp newmemreturnhere: [DISABLE]//code from here till the end of the code will be used to disable the cheatdealloc(newmem)dealloc(BLA)dealloc(BLBA)unregistersymbol(BLBA)dealloc(KSYF)unregistersymbol(KSYF)"Game.dll"+4CBE9E:mov [esi+30],eaxmov eax,edi//Alt: db 89 46 30 8B C7
最后,效果如下
最后总结
知识总结
1. 对访问写入功能的环境分为4类:1/1 1/N N/1 N/N
2. 追加种类2类:持续 非持续
上述两类可以自由组合,好比1/1持续、N/N持续等
3. 使用方法:附近分析法
附近分析法的实质:利用访问写入功能获取 关键代码访问目的数据时的状态,来获得唯一的环境。这里需要区分的是:CE的访问写入记录的是关键代码实行后的状态,而下断点记录的是关键代码实行前的状态
4. 下简朴条件断点的方法:先找什么访问写入获得动态基址,然后在关键代码处先下断再设置条件。好比EAX==0x0
<font face="Trebuchet MS"><font size="3"><strong><font size="4"><font size="3"><font color="Red"><font color="Black"> 5. 加多重特性是为了获得唯一环境,一般来说加特性数环境:1/1 |