好友
阅读权限25
听众
最后登录1970-1-1
|
镇北看雪
发表于 2020-5-8 20:48
本帖最后由 镇北看雪 于 2020-5-9 08:40 编辑
最近在学习hook技术与DLL注入技术,所以就做了个扫雷辅助来练习一下顺便和大家分享一下。
(觉得不错记得pf,快升级了哦)
——————————————————————————————————————————————
- 先用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:[0x1005164],0x0 此地址处的内存的值将被设置为0,意味着游戏将结束。
我们返回上层函数(栈中对应函数右击反汇编跟随),发现主要逻辑。在关键跳转处下断点,再次运行程序并使踩到雷时程序停在此关键判断处。
当跳转执行时就会跳到使 内存0x01005164 值为0的代码处(表示踩到了雷,游戏结束)。而此跳转要想不执行需要内存0x010057a4地址处的值为0,
我们在数据窗口中查看此地址处值为3,正好为我们已经消除的方格。(意思是如果是第一次点击,那么即使踩到雷也不爆)所以我们知道了为什么我们第一次点击永远不会踩到雷 的原因了。
我们继续往上看此处代码,我们发现je 01003595代码可以跳过使内存0x01005164 值为0的代码(表示踩到了雷,游戏结束),意思就是我们没有踩到雷。
分析此处代码:其是将0x1005340 + esi + ecx 内存处的值与0x80进行与运算,如果等于0表示没有踩到雷。
[Asm] 纯文本查看 复制代码 01003512 /$ 8B4424 08 mov eax,dword ptr ss:[esp+0x8]
01003516 |. 53 push ebx
01003517 |. 55 push ebp
01003518 |. 56 push esi
01003519 |. 8B7424 10 mov esi,dword ptr ss:[esp+0x10]
0100351D |. 8BC8 mov ecx,eax
0100351F |. C1E1 05 shl ecx,0x5
01003522 |. 8D9431 405300>lea edx,dword ptr ds:[ecx+esi+0x1005340]
01003529 |. F602 80 test byte ptr ds:[edx],0x80
0100352C |. 57 push edi
0100352D |. 74 66 je X01003595 ; winmine.01003595
0100352F |. 833D A4570001>cmp dword ptr ds:[0x10057A4],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 == [0x100511c], eax == [0x1005118]
我们重新运行,在数据窗口中中搜索这两处地址,并设置内存写入断点。
并点击方块。程序会停止,此处应该是两处地址初始化代码。
继续执行,程序在一个函数中再次断下。发现参数1(arg.1) == [0x01005118],参数2(arg.2 ) == [0x0100511c].
我们回溯到上层函数看参数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
|
免费评分
-
查看全部评分
|
发帖前要善用【论坛搜索】功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。 |
|
|
|
|