Window扫雷逆向破解与外挂教程
本帖最后由 镇北看雪 于 2020-5-9 08:40 编辑最近在学习hook技术与DLL注入技术,所以就做了个扫雷辅助来练习一下顺便和大家分享一下。
(觉得不错记得pf,快升级了哦)
——————————————————————————————————————————————
[*]工具:CE,OD
[*]破解思路:
[*]先用CE打开程序,想要破解掉扫雷的计时需要找到时间存储到内存的什么地方。
利用CE我们找到时间存在0x0100579C ,如果我们要想改变时间只需改变此内存地址下的值即可。
2.我们用OD打开程序,由0x0100579C 存放时间的内存入手。我们在od的数据窗口搜索此内存地址,此时没有开始游戏其值为0。
我们再此地址处设置内存写入断点,然后运行程序。(我们知道只要没有踩到雷子,时间值会一直增加的,我们需要知道其值增加处的逻辑)
3.运行程序后点击任意一个方块,游戏开始后程序暂停。我们发现这里是游戏计时的初始化逻辑,
当时间内存值加1后,通过SetTimer()设置一个计时器, 每一秒发送一条WM_TIME消息来达到计时的目的。
4.我们继续运行程序,程序又暂停下来了。这里就应该是时间值增加处的逻辑了。
此处逻辑为:当 0x01005164内存处的值不为0 或者 时间没有超过999时,时间值加1。
时间没有超过999时,时间加1我们可以理解。但是0x01005164 的值不为0时,时间值加1是什么意思呢?
我们知道当我们踩到雷游戏结束时,时间会停止。那意思是不是0x01005164的值为1表示游戏是否结束呢?我们验证一下。
5. 为了验证0x01005164 处的值为0表示我们踩到雷子游戏结束,我们需要在数据窗口跟踪此地址的值。
因为我们才点击一个方块,所以不可能踩到雷子。此时此地址处值为1,我们先取消时间内存处的内存写入断点继续运行程序,并点击方块知道踩到雷子为止。
当踩到雷子游戏结束时,我们发现0x01005164 地址处的值变成了0,所以我们的猜想是正确的。
6.现在我们在0x01005164地址处下内存写入断点,重新运行程序。不断点击方块当踩到雷子时,程序暂停。
我们发现 暂停处指令为:and dword ptr ds:,0x0 此地址处的内存的值将被设置为0,意味着游戏将结束。
我们返回上层函数(栈中对应函数右击反汇编跟随),发现主要逻辑。在关键跳转处下断点,再次运行程序并使踩到雷时程序停在此关键判断处。
当跳转执行时就会跳到使 内存0x01005164 值为0的代码处(表示踩到了雷,游戏结束)。而此跳转要想不执行需要内存0x010057a4地址处的值为0,
我们在数据窗口中查看此地址处值为3,正好为我们已经消除的方格。(意思是如果是第一次点击,那么即使踩到雷也不爆)所以我们知道了为什么我们第一次点击永远不会踩到雷的原因了。
我们继续往上看此处代码,我们发现je 01003595代码可以跳过使内存0x01005164 值为0的代码(表示踩到了雷,游戏结束),意思就是我们没有踩到雷。
分析此处代码:其是将0x1005340 + esi + ecx 内存处的值与0x80进行与运算,如果等于0表示没有踩到雷。
01003512/$8B4424 08 mov eax,dword ptr ss:
01003516|.53 push ebx
01003517|.55 push ebp
01003518|.56 push esi
01003519|.8B7424 10 mov esi,dword ptr ss:
0100351D|.8BC8 mov ecx,eax
0100351F|.C1E1 05 shl ecx,0x5
01003522|.8D9431 405300>lea edx,dword ptr ds:
01003529|.F602 80 test byte ptr ds:,0x80
0100352C|.57 push edi
0100352D|.74 66 je X01003595 ;winmine.01003595
0100352F|.833D A4570001>cmp dword ptr ds:,0x0
01003536|.75 50 jnz X01003588 ;winmine.01003588
7.我们在关键判断处下断点,重新运行程序并在数据窗口中搜索0x1005340。
重新运行程序后,点击一个方格。当程序停在此断点时,我们看到对应0x1005340 + esi + ecx 内存处的值为0 ,其与0x80与运算的值为0。
跳转将会执行,所以表示此次点击处无雷。
我们需要知道esi与ecx是怎么计算得来的,我们发现 ecx与esi都是由两个参数计算得到的,那这俩个参数代表什么意思呢?
我们在反汇编窗口中查看上一层函数后,在函数入口下断点。然后重新运行程序,并点击方格。程序停在此处发现两个参数分别是eax, ecx。
我们继续往上层函数回溯。发现到达了消息回调函数处。
我们发现其相应的是鼠标左键松开,我们先在对应函数入口下断点,然后重新运行程序,点击方块来到此断点处。 F7进入此函数分析ecx与eax怎么产生的。
F7进入此函数后F8向下单步我们发现ecx == ,eax ==
我们重新运行,在数据窗口中中搜索这两处地址,并设置内存写入断点。
并点击方块。程序会停止,此处应该是两处地址初始化代码。
继续执行,程序在一个函数中再次断下。发现参数1(arg.1) == ,参数2(arg.2 ) == .
我们回溯到上层函数看参数1,和参数2是怎么产生的。
发现参数1和参数2的算法。我们在函数入口下断点。
我们重新运行程序,点击方块后程序停在此处。可以看到参数1和参数2的算法,arg.4是消息回调函数的参数4(lParam).
因为此处是点击鼠标左键的消息,所以参数4表示鼠标点击的坐标,我们可以得知,参数1和参数2实际是我们点击方格在坐标。
致辞我们可以得知0x1005340 + esi + ecx 的esi与ecx是由我们点击方格行和列产生的,所以0x1005340地址处就是和方格一一对应的。
0x10应该表示墙,但是当其值为0x80时才表示无雷,为什么好多都是0x0f和0x8f呢?(说明在判断之前还进行了判断。)我们在第一个方格处设置内存写入断点。
第一个方格对应的内存地址为0x10005361.然后我们重新运行程序,并点击第一个方格。程序暂停
因为只有0x1005361地址处的值为0x80才表示无雷,我们由此处算法可得:当对应方块原始的值为0xf时经过运算会使其地址处值为0x80,如果原始值为0x8f则经过运算后会使其地址处值为0。
所以我们得:如果方块对应的地址处的值为0xf则表示此处无雷。如果为0x8f则表示有雷。
程序分析完了:下面就是外挂破解思路,很简单。
F3一键通关思路:
我们通过判断对应地址是否为0xf(是否无雷),决定是否向程序发送单击消息。
F4清零时间:
直接改变对应时间内存的值为0
效果:
下面是游戏链接,和外挂dll文件以及源程序,以及我自己写的dll注入工具。(全部都打包了)
dll注入成功,按F3一键通关,F4清零时间
链接:https://pan.baidu.com/s/1j0o7geZyUmOEO0VbXU-xEg
提取码:jrng
我的提示这个 打不开 没想到扫雷都有外挂了{:1_886:} 楼主,网盘文件失效了。能否重发一下?另外期待你的DLL注入器的编写教程 啥都能分享的非常透彻,新的例子可以参照一下自己尝试研究了 细水流长 发表于 2020-5-8 21:02
将je 01003595 这段nop掉是不是也可以呢?表示即使踩到了雷也不会结束
玩法多了,主要看你想怎么玩。这里直接nop不可以,因为下面还有一处跳转 扫雷也要教程呀,哈哈 有文字教程真好,先收藏,改天抽时间学习! 谢谢楼主分享 楼主威武
{:1_893:}