飘云阁

 找回密码
 加入我们

QQ登录

只需一步,快速开始

查看: 4322|回复: 7

[转贴] 新手逆向学习--Win7下64位扫雷逆向以及辅助制作

[复制链接]
  • TA的每日心情
    开心
    2023-3-19 17:58
  • 签到天数: 229 天

    [LV.7]常住居民III

    发表于 2018-2-1 08:09:36 | 显示全部楼层 |阅读模式
    本帖最后由 lchhome 于 2018-2-1 11:50 编辑

    之前逆过XP下的扫雷程序,感觉XP下的扫雷很简单,但是发现网上对于Win7下的扫雷逆向很少很少,于是就试着继续逆一下Win7下的扫雷。这一逆发现难度提升了不只一个等级啊,经过两天的努力,终于整个逆完了它的扫雷算法。
    首先在Win7下的扫雷不再是像XP一样在一开始就布置好雷区,这样我们就可以在一开始就读取雷区内存,比较坑的是win7下的扫雷是在你点击第一块儿方块时才开始布置雷区。这样我首先在rand函数下断点,发现有好多地方会调用rand函数,我把每个调用rand函数的地方下了断点,然后把一直在调用的rand函数的那几个函数断点给去掉,这样我们就找到了程序的突破口。
    不断退出当前调用,并在上层函数的call调用处下断点,直到找到了一个疑是算法入口的函数。

    跟进函数,又发现一个call,继续跟进


    我发现这个函数便是调用rand函数的地方,估计核心就在此了,开干


    我们要对每个call都倍加小心,需要都看一下,我们发现这里好像是一个申请数组空间并填充的操作


    经过多次循环后,发现数组填充完毕,之后观察一下申请的数组空间中存储的东西


    发现没有了00 01 09 0A四个值。因为我是点击的第一个方块,我们可以重新调试,点击其他方块试一下,发现这个数组会将点击方块周围的的9个值去掉(包括点击方块自己),这样我们就理解了,程序不会在第一次点击方块周围产生雷。
    这时候我们估计就对这个程序有了一点点理解了,在点击第一块儿方块的时候,程序开始申请内存。这里它会有一个结构体存储了随机雷数组已用大小和总空间,然后生成一个数组,并将各个雷进行编号存入数组中。之后rand函数产生的随机雷就在这些数组中产生。接下来验证我们的想法:
    跟进下一个call,发现这里申请数组空间,并存储随机出来的雷值




    继续单步,发现有个小循环比较有意思


    看一下rax存储了什么?


    这好像是存储了多个数组的首地址啊,正好我们现在设定了9x9的雷区,这里正好9个地址,我们再跟进去这些地址看一下


    这里+10处又存储了一个地址,继续观察,发现有个byte数组,存储了雷的状态,有雷就是1,无雷就是0


    这个时候我们就基本搞明白了这个Win7下扫雷是怎么布置的了。可是问题来了,最初的记录雷区各个数组的地址从哪得啊?我们逆着代码去溯源。我们发现这个值是rax+0x10处的存储的值,而rax是rsi+0x58处存储的值,这个rsi是rcx作为上层调用函数传过来的参,我们走出这个函数看看这个参数从哪里得到。


    我们找到了这样一个值,在FFCFAA38中存储了我们所想要的rsi的值。我们知道,这是一个全局变量,存储了rsi地址。但是这个值由于RSLR机制而导致每次地址不一样。我们有一种方法得到这个值,我们先看当前模块加载基地址,然后用FFCFAA38(全局变量地址)-FFC500000(当前模块加载地址)= AAA38(相对当前模块偏移)。这样我们可以用GetModuleHandle函数得到当前模块加载基地址,然后加上这个偏移AAA38就得到了全局变量地址。
    这样我们就有了得到数组地址的方法:
    Address = [[[[hModule+0xAAA38]+0x18]+0x58]+0x10]
    这时Address就是存储雷区数组的首地址,每个雷区地址+0x10处就是雷区列状态数组(byte)地址。
    其实,到这里我们也开始明白了,它所使用的应该是C++的vector,一个个push才产生这样的内存空间的,不得不说,这C++功力已经炉火存青了,各种数据结构弄得头都大了。
    找到了雷区布置数组就可以进行下一步动作了,我们通过计算鼠标坐标值来获得雷区格子,每个格子是17*17像素大小并加上1像素的边,所以每个格子大小为18像素,雷区边界为30像素。你问我这些怎么得到的?这些值肯定在某个内存存着,你可以下断点在GetCursorPos处,在你移动鼠标时会触发断点,然后跳出函数,发现下边有一个GetWindowRect函数,这个函数会传递窗口句柄,窗口句柄存储在一个全局内存中,我们可以得到这个窗口句柄。但是我用了更简单的方法,既然有窗口,我直接用工具测一下就知道每个格子大小了么。
    这样我们就得到了鼠标坐标转换格子的公式:
    int x = (xPos - 30) / 18;          //列
    int y = (yPos - 30) / 18;          //行
    最后,上辅助代码:
    到此,我们大功告成,需要注意的是每次要点击一下一个格子再注入动态库。不过,我的F12一键扫雷并没成功有人知道是怎么回事么?希望不吝赐教帮我解决一下,嘻嘻~~

    PYG19周年生日快乐!
  • TA的每日心情
    慵懒
    昨天 09:21
  • 签到天数: 2162 天

    [LV.Master]伴坛终老

    发表于 2018-2-1 11:06:22 | 显示全部楼层

    楼主,你的图一张都看不到
    哎。。。。。。
    PYG19周年生日快乐!
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    慵懒
    2019-3-24 14:20
  • 签到天数: 65 天

    [LV.6]常住居民II

    发表于 2018-2-1 13:12:02 | 显示全部楼层
    楼主,你的图一张都看不到
    PYG19周年生日快乐!
    回复 支持 反对

    使用道具 举报

  • TA的每日心情

    2020-2-25 11:45
  • 签到天数: 213 天

    [LV.7]常住居民III

    发表于 2018-2-4 15:45:42 | 显示全部楼层
    楼主,你的图一张都看不到
    PYG19周年生日快乐!
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    无聊
    2023-4-24 22:09
  • 签到天数: 35 天

    [LV.5]常住居民I

    发表于 2018-2-15 19:55:16 | 显示全部楼层
    #在这里快速回复#广播播音大师 5.1迷你破解版,不用注册,直接可以用了!
    PYG19周年生日快乐!
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    郁闷
    2022-2-20 20:31
  • 签到天数: 36 天

    [LV.5]常住居民I

    发表于 2019-4-13 20:03:05 | 显示全部楼层
    一张图片也看不到。。这个是为什么呢?
    PYG19周年生日快乐!
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2019-4-21 20:15
  • 签到天数: 2 天

    [LV.1]初来乍到

    发表于 2019-4-21 20:43:24 | 显示全部楼层
    图是别的地方的图吧,我们看不见 看不见
    PYG19周年生日快乐!
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 登录 | 加入我们

    本版积分规则

    快速回复 返回顶部 返回列表