吾爱汇编

 找回密码
 立即注册

QQ登录

绑定QQ避免忘记帐号

查看: 10531|回复: 75

[原创逆向图文] 记一次win7下逆向扫雷到DLL(HOOK)注入

  [复制链接]
Follow丶Me 发表于 2018-10-8 22:24 | 显示全部楼层 |阅读模式

本帖最后由 Follow丶Me 于 2018-10-9 13:41 编辑

10.1国庆宅在家里,没事干就调戏了扫雷。

这是在Windows 7下的32位扫雷程序,有空在看看64位。
首先理清逆向思路:
    1.载入OD,下消息断点201 (后来发现此路不通....)
    2.后来枚举所有函数,发现了Rand这个有趣的东东,然后OD中 bp rand
    3.最后游戏结束的时候发现对话框,可以直接给 DialogBoxParamW下断

上面是我自己的开始的思路,当然有大神提供思路的,请留言,十分感谢。

第一步,当然是载入OD,bp rand
1.png

接着程序会断这里
2.png

之后OD会不停的断在这,我们在堆栈窗口找到上层CALL的调用地址,再搜索哪些地方调用了当前的CALL,每个调用的地方都F2
就会得出有8个地方调用了,把那个一直调用rand的断点的去掉,还有把bp rand那个断也去掉

3.png

去掉之后再点击格子,此时回到OD如当前图片的断点,去这个CALL的头部从上往下分析。
4.png

经过分析,得知当前CALL是一个“布雷函数”
[Asm] 纯文本查看 复制代码
mov  edi,edi                                              ;布雷函数
push  ebp                           
mov  ebp,esp                        
push  ecx                           
push  ecx                           
push  ebx                           
push  esi                           
push  edi                           
mov  esi,ecx                        
call  MineSweeper.0034D816                       ;全局变量到EAX
push  dword ptr ds:[esi+0x2C]                    ;push 5BB9B276 == push eax
mov  dword ptr ss:[ebp-0x08],eax               ;mov ecx, eax
call  MineSweeper.0034D821                       ;这个参数也就是eax 即为随机序列种子
push  0x00000010                    
call  MineSweeper.0034DCA7                       ;申请4个DWORD大小的空间(malloc)
pop  ecx                                                    ;变相的平衡堆栈 ecx = eax = 0x5BB9B276
test  eax,eax                                 
je  MineSweeper.003400F1            
push  0x00000010                                      ;初始化函数第一个参数0x10
mov  ecx,eax                                              ;ecx = 01FD6948  即为第一次申请的空间首地址
call  MineSweeper.0033F959                        ;上面四个参数初始化为:0x0 0x0 0x10 0x0
mov  dword ptr ss:[ebp-0x04],eax                ;ecx = eax 即为01FD6948
jmp  MineSweeper.003400F5           
and  dword ptr ss:[ebp-0x04],0x00000
mov  eax,dword ptr ds:[esi+0x08]               ;获取扫雷的行 rows
imul  eax,dword ptr ds:[esi+0x0C]               ;获取扫雷的列 eax = rows * columns -> 9+9 = 0x51
xor  edi,edi                                                ;i=0 edi置零 
test  eax,eax                       
jle  MineSweeper.0034014B           
mov  ecx,dword ptr ds:[esi+0x0C]               ;ecx = columns.....[esi]=3DC248
mov  eax,edi                                              ;eax = i
cdq                                 
 idiv  ecx                                                    ;此时ecx为columns   i/dwColumn=eax行号....edx列号
xor  ecx,ecx                                               ;ecx置零
sub  edx,dword ptr ss:[ebp+0x08]               ;sub 0,0 鼠标点击的列号
sub  eax,dword ptr ss:[ebp+0x0C]               ;sub 0,0 鼠标点击的行号
test  edx,edx                                              ;列号!!!
setnl  cl                                                     ;根据列号是否正负,取绝对值
lea  ecx,dword ptr ds:[ecx+ecx-0x01]
imul  ecx,edx                       
cmp  ecx,0x01                       
jnle  MineSweeper.00340136                        ;第一个差值绝对值<=1,判断第二个差值
xor  ecx,ecx                                                ;ecx置零
test  eax,eax                                               ;行号!!!
setnl  cl                                                      ;根据行号是否正负,取绝对值
lea  ecx,dword ptr ds:[ecx+ecx-0x01]
imul  ecx,eax                       
cmp  ecx,0x01                       
jle  MineSweeper.0034013F                           ;第二个差值绝对值>=1 
mov  ecx,dword ptr ss:[ebp-0x04]    
push  edi                           
call  MineSweeper.00355A51          
mov  eax,dword ptr ds:[esi+0x08]                  ;行数
imul  eax,dword ptr ds:[esi+0x0C]                  ;列数   -> 行数 * 列数 = 0x51
inc  edi                                                         ;i++
cmp  edi,eax                                                 ;判断是否布满81个格子
jl  MineSweeper.00340102                              ;没有布满就继续
push  0x00000010                    
call  MineSweeper.0034DCA7                          ;第二次4个DWORD大小的申请空间
pop  ecx                                                       ;变相平衡堆栈 ecx = 0x10
test  eax,eax                       
je  MineSweeper.00340165                             ;可能是申请失败时的操作
push  dword ptr ds:[esi+0x04]                        ;雷数入栈
mov  ecx,eax                                                ;ecx为第二次申请的首地址
call  MineSweeper.0033F959                           ;第二次申请空间初始化 0x0,0x0,0xA,0x0
 mov  edi,eax                                                 ;edi 为第二次申请的首地址
jmp  MineSweeper.00340196                          ;无条件跳
xor  edi,edi                        
jmp  MineSweeper.00340196           
mov  eax,dword ptr ss:[ebp-0x04]                  ;eax = 第一次申请的首地址
mov  eax,dword ptr ds:[eax]                          ;eax = 0x4D = 77
test  eax,eax                       
jbe  MineSweeper.0034019D                          ;判断雷是否布完了
dec  eax                            
push  eax                                                     ;循环从0x4D 开始减一   入栈
push  0x00000000                    
call  MineSweeper.0034D7F3                          ;rand函数 随机数是:0-0x4C之间 即0-76之间
mov  ebx,eax                                                ;ebx = 雷的随机数
mov  eax,dword ptr ss:[ebp-0x04]                  ;第一个申请的首地址
mov  eax,dword ptr ds:[eax+0x0C]                 ;eax = 0436F980
push  dword ptr ds:[eax+ebx*4]                    ;找到随机布局中放雷的位置
mov  ecx,edi                                                 ;ecx = 第二个申请的首地址
call  MineSweeper.00355A51                          ;将数据保存到第二个申请空间里
mov  ecx,dword ptr ss:[ebp-0x04]                   ;ecx第一个申请的首地址
push  ebx                           
call  MineSweeper.0034EC9E          
mov  eax,dword ptr ds:[edi]                            ;eax的值是存放布雷数
cmp  eax,dword ptr ds:[esi+0x04]                   ;判断雷数
jne  MineSweeper.00340169                            ;雷数=第二次申请空间的第一个属性值 
xor  ecx,ecx                        
cmp  dword ptr ds:[edi],ecx         
jbe  MineSweeper.003401C4           
mov  eax,dword ptr ds:[edi+0x0C]                 ;获取存雷数组的地址
mov  eax,dword ptr ds:[eax+ecx*4]               ;取第i(ecx)个雷的位置数
mov  ebx,dword ptr ds:[esi+0x0C]                 ;扫雷初始化数据中第四个属性是列数
cdq                                 
idiv  ebx                                                      ;雷的位置数 / 列数 = 真实布雷的地址(EAX行号,EDX列号)
mov  ebx,dword ptr ds:[esi+0x44]                 ;[esi+0x44]地址表
mov  ebx,dword ptr ds:[ebx+0x0C]                ;[[esi+0x44]+0xc] 第二层地址表
inc  ecx                                                       ;i++
mov  edx,dword ptr ds:[ebx+edx*4]   
mov  edx,dword ptr ds:[edx+0x0C]                ;根据雷所在列号取第edx(列号)个地址
mov  byte ptr ds:[eax+edx],0x01                   ;为雷时,填充0x1
cmp  ecx,dword ptr ds:[edi]                           ;判断是否布完了
jc  MineSweeper.003401A3                            ;布雷完毕
push  0x00000001                    
mov  ecx,edi                        
call  MineSweeper.0033FC96                          ;free
mov  ecx,dword ptr ss:[ebp-0x04]     
pop  edi                            
pop  esi                            
pop  ebx                            
test  ecx,ecx                       
je  MineSweeper.003401DE            
push  0x00000001                    
call  MineSweeper.0033FC96                            ;free
push  dword ptr ss:[ebp-0x08]       
call  MineSweeper.0034D821          
leave                               
retn  0x0008                        


这还没完,在堆栈窗口找到向上2层的CALL那个才是左键点击的CALL

[Asm] 纯文本查看 复制代码
mov  edi,edi                                                                                  ;左键单击函数
push  ebp                                     
mov  ebp,esp                                  
mov  eax,dword ptr ds:[MineSweeper.003A68B4]                              ;这玩意就是基址
push  ebx                                     
push  esi                                     
mov  esi,dword ptr ss:[ebp+0x08]              
push  edi                                     
mov  byte ptr ds:[eax+0x000000C5],0x01        
push  dword ptr ds:[esi+0x1C]                                                         ;这个是y 坐标
mov  edi,ecx                                  
push  dword ptr ds:[esi+0x18]                                                         ;这个是x 坐标
mov  ecx,dword ptr ds:[MineSweeper.003A68B4]                               ;this 指针
xor  bl,bl                                    
call  MineSweeper.00341418                                                            ;判断单击的是不是雷,传X,Y坐标
test  eax,eax                                                                                   ;比较返回值
jnle  MineSweeper.00346FF1                    
mov  dword ptr ds:[edi+0x0000009C],esi        
inc  bl                                       
jmp  MineSweeper.00346FF9                     
push  eax                                     
mov  ecx,edi                                  
call  MineSweeper.00346BCD                                                            ;后续CALL
mov  byte ptr ds:[edi+0x000000AC],0x01        
pop  edi                                      
pop  esi                                      
mov  al,bl                                    
pop  ebx                                      
pop  ebp                                      
etn  0x0004                                  


再分析一下这个CALL里面“主要”做了什么:call  MineSweeper.00341418 --> 判断单击的是不是雷,传X,Y坐标
[Asm] 纯文本查看 复制代码
mov  edi,edi                                  
push  ebp                                     
mov  ebp,esp                                  
ecx,dword ptr ds:[ecx+0x10]                      ;this指针偏移+0x10(第5个属性地址)
pop  ebp                                      
jmp  MineSweeper.00340C50                      ;无条件跳

mov  edi,edi                                  
push  ebp                                     
mov  ebp,esp                                  
push  ecx                                                  ;this->第5个属性地址
push  ebx                                     
mov  ebx,dword ptr ss:[ebp+0x08]              ;x坐标
push  esi                                                   ;[esi+0x1C] = 存放x,y坐标的地址
mov  esi,ecx                                              ;此时esi=ecx=this指针->第5个属性地址
mov  eax,dword ptr ds:[esi+0x40]               ;this->某个对象
mov  eax,dword ptr ds:[eax+0x0C]              ;某个对象->属性
mov  eax,dword ptr ds:[eax+ebx*4]            ;ebx = x坐标
mov  eax,dword ptr ds:[eax+0x0C]              ;这个eax指向的地址就是存储[color=#666]所有列状态的地址表[/color]
push  edi                                     
mov  edi,dword ptr ss:[ebp+0x0C]               ;y 坐标
mov  eax,dword ptr ds:[eax+edi*4]             ;edi = y坐标
xor  ecx,ecx                                  
mov  dword ptr ss:[ebp-0x04],ecx              
cmp  eax,0x09                                           ;未点击
je  MineSweeper.00340C95                      
cmp  eax,0x0B                                           ;问号
je  MineSweeper.00340C95                      
mov  eax,dword ptr ds:[MineSweeper.003A68B4]  
cmp  byte ptr ds:[eax+0x18],cl                
je  MineSweeper.00340CE5                      
push  ecx                                     
push  ecx                                     
push  ecx                                     
call  MineSweeper.003505E9                    
xor  ecx,ecx                                  
jmp  MineSweeper.00340CE5                     
cmp  dword ptr ds:[esi+0x18],ecx                ;this->第七属性
jne  MineSweeper.00340CBA                        ;判断是否第一次鼠标点击
push  edi                                     
push  ebx                                     
mov  ecx,esi                                  
call  MineSweeper.003400BB                       ;布雷CALL
push  0x00000000                              
push  edi                                     
push  ebx                                     
push  0x00000000                              
push  edi                                     
push  ebx                                     
mov  ecx,esi                                  
call  MineSweeper.00340A42                    
mov  dword ptr ds:[esi+0x24],ebx              
mov  dword ptr ds:[esi+0x28],edi              
jmp  MineSweeper.00340CDD                     
mov  eax,dword ptr ds:[esi+0x44]              
mov  eax,dword ptr ds:[eax+0x0C]              
mov  eax,dword ptr ds:[eax+ebx*4]            ;这个ecx里面就是存储[color=#666]所有列有雷的地址表    [/color]
mov  eax,dword ptr ds:[eax+0x0C]              
cmp  byte ptr ds:[edi+eax],cl                      ;判断是否为雷 [edi+eax]->edi=行  eax=地址偏移 cl=0(cl值不变)
je  MineSweeper.00340CD0                         ;不为雷跳转



最后分析得出:
真实基址 = 扫雷起始地址 + 0x868B4(RVA)

格子数据 = [[[[[[[真实基址] + 0x10] + 0x40] + 0x0C] + 4 * X坐标] + 0x0C]+ 4 * Y坐标]
取值范围:1~8数字  9未开 10旗 11问号  12空



雷数据 = [[[[[[[真实基址] + 0x10] + 0x44] + 0x0C] + 4 * X坐标] + 0x0C] + Y坐标]


esi = [[真实基址] + 0x10]
[esi + 0x04] = 雷数

[esi + 0x08] = 行数

[esi + 0x0C] = 列数

[esi + 0x18] = 鼠标左键单机次数
第一次单机时:
列号:[esi + 0x24]
行号:[esi + 0x28]


这就是鼠标左键CALL分析了,至于右键CALL提供思路:在第一块数据方格中下硬件写入断点
然后回溯跟踪 直到返回2次后,就是我们要找的CALL



OK...............................分析到这就结束了。


具体实现核心代码:
游客,如果您要查看本帖隐藏内容请回复


附上超级难度下秒杀图:
5.png



下载完成后把后缀名改一下,另外我用的是VS2015写的。

Projects003.7z (950.37 KB, 下载次数: 21) Projects002.7z (1 MB, 下载次数: 26) Projects001.7z (1 MB, 下载次数: 26)





评分

参与人数 35威望 +1 HB +93 THX +19 收起 理由
longge188 + 1 [吾爱汇编论坛52HB.COM]-吃水不忘打井人,给个评分懂感恩!
虚心学习 + 1 [吾爱汇编论坛52HB.COM]-软件反汇编逆向分析,软件安全必不可少!
temp + 1
李卓吾 + 1
消逝的过去 + 1
冷亦飞 + 1
沉默的承诺 + 1
三月十六 + 1
芜湖哈 + 1
l278785481 + 1
车太震 + 1 + 1 [吾爱汇编论坛52HB.COM]-感谢楼主热心分享,小小评分不成敬意!
在天一方 + 2 [吾爱汇编论坛52HB.COM]-学破解防破解,知进攻懂防守!
fjgh + 2 + 1 [吾爱汇编论坛52HB.COM]-学破解防破解,知进攻懂防守!
liugu0hai + 1 + 1 [吾爱汇编论坛52HB.COM]-软件反汇编逆向分析,软件安全必不可少!
口水鸡 + 1 [吾爱汇编论坛52HB.COM]-软件反汇编逆向分析,软件安全必不可少!
hetao8003200 + 1
zxjzzh + 2 [吾爱汇编论坛52HB.COM]-学破解防破解,知进攻懂防守!
XiaoWeiSec + 1 [吾爱汇编论坛52HB.COM]-吃水不忘打井人,给个评分懂感恩!
kll545012 + 1 [吾爱汇编论坛52HB.COM]-软件反汇编逆向分析,软件安全必不可少!
成丰羽 + 1 [吾爱汇编论坛52HB.COM]-感谢楼主热心分享,小小评分不成敬意!
越宝 + 1
beijita520 + 1
2473262754 + 1 + 1
baky1223 + 1 + 1 [吾爱汇编论坛52HB.COM]-吃水不忘打井人,给个评分懂感恩!
bnjzzheng + 1 [吾爱汇编论坛52HB.COM]-吃水不忘打井人,给个评分懂感恩!
zhangz + 1 + 1
w18665346 + 1 + 1 [快捷评语] - 评分=感恩!简单却充满爱!感谢您的作品!
liumeng + 1 [快捷评语] - 评分=感恩!简单却充满爱!感谢您的作品!
千江月8 + 1 + 1 学习了很多
warhome + 1 + 1 [快捷评语] - 吃水不忘打井人,给个评分懂感恩!
wangxp + 1 + 1 [快捷评语] - 评分=感恩!简单却充满爱!感谢您的作品!
Oneness神 + 2 + 1 [快捷评语] - 评分=感恩!简单却充满爱!感谢您的作品!
耶稣 + 6 + 1 [快捷评语] - 2018,狗年发发发,狗年旺旺旺!
李沉舟 + 6 + 1 [快捷评语] - 2018,狗年发发发,狗年旺旺旺!
Shark恒 + 1 + 50 + 1 [快捷评语] - 评分=感恩!简单却充满爱!感谢您的作品!

查看全部评分

吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
Shark恒 发表于 2018-10-9 13:04 | 显示全部楼层
吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
slmlq123 发表于 2018-10-16 14:10 | 显示全部楼层

学习一下
吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
hc777 发表于 2018-10-16 16:43 | 显示全部楼层
吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
菜刀 发表于 2018-10-28 12:43 | 显示全部楼层

前来学习了
吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
woaizhoulu 发表于 2018-10-28 19:58 | 显示全部楼层
吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
abc1 发表于 2018-11-3 00:18 | 显示全部楼层

思路比较特别,调试还太不太懂
吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
493688702 发表于 2018-11-3 09:41 | 显示全部楼层

互相学习
共同进步
支持恒大
吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
TAOGE5387 发表于 2018-11-3 09:41 | 显示全部楼层

好好学习天天向上
吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
lcdxsun 发表于 2018-11-19 08:29 | 显示全部楼层

这个是win7自带的  还是网上下的独立版本的 扫雷游戏

评分

参与人数 1HB +1 收起 理由
梯云纵 + 1

查看全部评分

吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

警告:本站严惩灌水回复,尊重自己从尊重他人开始!

1层
2层
3层
4层
5层
6层
7层
8层
9层
10层

免责声明

吾爱汇编(www.52hb.com)所讨论的技术及相关工具仅限用于研究学习,皆在提高软件产品的安全性,严禁用于不良动机。任何个人、团体、组织不得将其用于非法目的,否则,一切后果自行承担。吾爱汇编不承担任何因为技术滥用所产生的连带责任。吾爱汇编内容源于网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑中彻底删除。如有侵权请邮件或微信与我们联系处理。

站长邮箱:SharkHeng@sina.com
站长QQ:1140549900


QQ|RSS|手机版|小黑屋|帮助|吾爱汇编 ( 京公网安备11011502005403号 , 京ICP备20003498号-6 )|网站地图

Powered by Discuz!

吾爱汇编 www.52hb.com

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