本帖最后由 无瑕黑心肠 于 2017-2-15 14:05 编辑
前言:
上次破解的CS1.6在WIN7 x64下会崩溃的问题, 详情:http://www.52pojie.cn/thread-503166-1-1.html. 今天打开运行一下老是崩溃, 再次载入OD发现原来是破解还不够完美, 只是阻止了弹出填写CDK的窗口, 我还真是小看这CS1.6单机版了. 经过我的深层剖析, 它的校验比较多, 而且还会检测自身的指纹(不清楚MD5还是CRC32之类的). 废话不多说, 此文章比较长, 如果你耐心看完, 也许你能从中 GET 到更多技巧和破解思路!
正题:
上期的帖子破解CS1.6中的思路是在注册表操作"RegQueryValueExA"上下断, 而且将"test eax,eax"改为"test esp,esp"就能破解了. 事实是如此. 但是如果在"新建游戏" -> 点下"确定"的这一刻, 程序又会再次验证注册表的CDK, 如果CDK不正确, 会有很多坏情况:
CDK无效:
坏的CDK:
还有什么CDK太短, CDK太长, CDK字符非法(CDK不允许0(零)、O(欧)、1、U, 这四个字符)等等...
先不管这些坏情况, 知道它"新建游戏"会再次检测CDK, 就在第一次CDK检测后再往"RegQueryValueExA"这个API下断, 找到源头后发现是在一个模块文件"mp.dll"里面(文件在"\cstrike\dlls"目录下), 也就是说, 爆破又是存在重定位的, 而且经我的调试, 这个DLL在程序载入后是看不到的, 它是"新建游戏"时才动态加载的. 来看看它检测CDK的地方:
计算到这个检测点的"偏移"后立马用C32ASM爆破掉这三个跳转, 因为正确的CDK是走下面的retn的. 为什么要立马爆破掉? 因为这个DLL文件是动态加载的, "新建游戏"的一瞬间这个DLL就被加载而且把代码也跑了, 手慢到了这里下断是没用的, 而且注册表的"RegQueryValueExA"断点不能一直断着, 会影响破解时的流程. 所以马上爆破保存对接下来的调试会比较好.
爆破掉这里后心想肯定就能完美的运行CS1.6了, 但, 根据我的剧情, 这是不可能的. 因为游戏自身模块"cstrike"还有一个验证CDK的, 于是就找到这个地方:
不跳的话里面就是"受到挑战?"(实在不知道怎么拆解这英文), 如果跳的话就是"无效的身份验证类型", 这岔路看的我云里雾里的. 先把正确的CDK注册, 然后跑到这里会发现它是实现跳转的, 难道这个"无效的身份验证类型"是个幌子? 先不管是不是幌子, 既然正确CDK是这么走那么直接改JMP就能爆破这最后一个校验了.
但是正当我保存的时候, 意外就是这么突然:
无法定位? 程序一般不带重定位呀! 怎么还无法定位? 这让我疑惑不解, 记住这么爆破点的地址"01D1B419", 重新载入程序跳过来一看:
居然是空的? 我猜这里的代码是不是被程序压缩没解压? 于是在这里下了个内存写入断点, 果不其然:
一开始看到这个汇编代码我也懵了, 因为我也没接触过, 去百度一下它的作用是:"循环从ESI指向的内存区域复制数据到EDI处的内存区域,复制ECX次,每次是一个DWORD", 内存区域复制? 真是个棘手的问题, 我去找了很久找这个ESI指向的内存区域是不是在程序某个地方, 结果发现这个地方是动态的, 也是放弃了. 不过找到一个新的线索, 它写入的地方每次都是不一样的(不可能一个地方内存写入两次一样的东西吧, 这样没啥意义), 因此, 可以自己控制程序的逻辑, 判断它写入的地址是"爆破点"时就把"爆破点"的字节给它改了, 说干就干, 找一段空代码段, 然后将这个内存复制的代码改成"jmp 0140B8CA":
可以发现下面的那个跳转给nop掉了, 没事, 在空代码段补回来就行了. 具体的控制逻辑:
解释一下这几句的汇编代码的意思:
第一句: 还是那句内存复制的汇编代码
第二句: 比较当前复制的目的内存区域是不是爆破点的区域
第三句: 如果当前复制的目的内存区域是爆破点的区域就将"爆破点"的字节进行"爆破"(也就是"je"(74)改"jmp"(EB)), 如果不是就执行之前抹掉的那句jmp, 整个逻辑就这么简单.
爆破点的爆破字节原本是"682F74C0", 这是它进行内存复制时截取的, 由于数据储存在反过来的, 例如:"12345678", 那么在数据窗口看到的就是就是"78563412", 所以, 这个"682F74C0", 也要倒过来看, 也就是"C0742F68", 是不是很眼熟? 没错, "742F"就是爆破点的汇编字节码:
改成将74改成EB就成"jmp short 01D1B44A"了, 也就是上面的"第三句"的汇编的意思.
右键 -> 复制到可执行文件 -> 所有修改, 终于保存成功了.
高兴的还是太早了, 此时打开游戏居然报错了:
程序的自校验来了, 由于时间太晚了, 就不想继续跟自校验了. 有兴趣的朋友可以跟一下.
办法不是没用, 这期就再教大家内存补丁吧! 打开"KeyMake2.0", 其他 -> 制作内存补丁:
内存补丁里面修改的全是刚才那几句修改的汇编代码, 改完保存再运行CS1.6就真的完全免CDK了, 这次有图有真相:
附上爆破点和内存补丁以及成品:
DLL爆破点以及偏移C32ASM的地址:
// 爆破点一(模块:GameUI)
[原]09C52A4F 85C0 test eax,eax
[改]09C52A4F 85E4 test esp,esp
[模块首地址]09C31000 53 push ebx
[偏移]0x21A4F (C32ASM: 10022A4F)
// 爆破点二(模块:mp)
[原]0E0A5AF0 81EC 18020000 sub esp,0x218
[改]0E0A5AF0 C3 retn
[模块首地址]0E031000 53 push ebx
[偏移]0x74AF0 (C32ASM: 10075AF0)
内存补丁:
// 原始指令(014027F3)
F3A5FF2495
// 修改指令(014027F3)
E9D2900000
// 原始指令(014027F8)
08294001
// 修改指令(014027F8)
EBF9EBF7
// 原始指令(0140B8CA)
0000000000000000
// 修改指令(0140B8CA)
F3A5817D080010D0
// 原始指令(0140B8D2)
0000000000000000
// 修改指令(0140B8D2)
01750AC70518B4D1
// 原始指令(0140B8DA)
0000000000000000
// 修改指令(0140B8DA)
01C0EB2F683EFF24
// 原始指令(140B8E2)
0000000000
// 修改指令(140B8E2)
9508294001
成品: http://pan.baidu.com/s/1slMwKnb 密码:dsd2
总结:
废话我也不想叨叨一堆了, 这期里面有很多知识点是非常新手的, 但有些是半知不解的, 在这里我想说的是:"度娘是你很好的老师, 它总有意想不到的答案给你", 遇到不懂的问题多多百度. 这期主要将了一些破解思路、手写汇编控制程序流程、内存补丁的制作. 当然还参杂了其他的知识点等朋友们一一去了解和理解, 很感谢大家的阅贴. 我会一如既往的不断努力. 当然最近偏向的还是破解部分. 我不像大伙的帖子"非零基础者请勿看以下内容, 以免易怒粗口"啥的. 我这里欢迎所有人, 新手经过能学到东西, 当然有高手经过发现帖子有不好的地方和误解的地方还请大方的指出. 我一定会非常感谢.
|