TC官方合作论坛

 找回密码
 立即注册
查看: 291|回复: 3
打印 上一主题 下一主题

[教程] [源码]扫雷内存call分析过程+tc源码

[复制链接]
跳转到指定楼层
楼主
发表于 2018-4-18 23:08:04 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式

马上加入TC

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
[ 本帖最后由 minews 于 2018-4-18 23:24 编辑 ]\n\nXP版扫雷 内存call分析过程和TC源代码第一次发帖排版有点乱,将就着看
这个排版真是醉了 文档直接放word文档里面了
[hide]分析雷的数据的思路1.开局的时候初始化雷的位置肯定会读取地图的宽高,找到宽高的地址后下硬件断点;2.开局的时候随机布雷,可能会调用随机函数,对rand函数下断我们用第二种方法输入bp rand 按回车
点击开局按钮程序断下来了

反汇编窗口中跟随 010036A6 |> \5B            pop ebx                                ;  winmine.01003946010036A7 |.  A3 34530001   mov dword ptr ds:[0x1005334],eax010036AC |.  890D 38530001 mov dword ptr ds:[0x1005338],ecx010036B2 |.  E8 1EF8FFFF   call winmine.01002ED5010036B7 |.  A1 A4560001   mov eax,dword ptr ds:[0x10056A4]        ;  总雷数010036BC |.  893D 60510001 mov dword ptr ds:[0x1005160],edi010036C2 |.  A3 30530001   mov dword ptr ds:[0x1005330],eax010036C7 |>  FF35 34530001 push dword ptr ds:[0x1005334]           ;  穿棋盘宽度010036CD |.  E8 6E020000   call winmine.01003940                   ;  rand函数010036D2 |.  FF35 38530001 push dword ptr ds:[0x1005338]           ;  传入棋盘高度010036D8 |.  8BF0          mov esi,eax010036DA |.  46            inc esi                                ;  user32.PtInRect010036DB |.  E8 60020000   call winmine.01003940                   ;  rand函数010036E0 |.  40            inc eax010036E1 |.  8BC8          mov ecx,eax010036E3 |.  C1E1 05       shl ecx,0x5010036E6 |.  F68431 405300>test byte ptr ds:[ecx+esi+0x1005340],0x8>; [y+x+0x1005340]&0x80!=0就是雷010036EE |.^ 75 D7         jnz short winmine.010036C7              ;  本格已经是雷跳转重新放雷010036F0 |.  C1E0 05       shl eax,0x5010036F3 |.  8D8430 405300>lea eax,dword ptr ds:[eax+esi+0x1005340]  
简单的分析可以得知这个就是初始化放雷的函数过程
用伪代码可以表示为while(总雷数==0)        x=取随机数(1,格子宽)       y=取随机数(1,格子高)       if(是否为雷(x,y)==真)       else             设置为雷(x,y)             总雷数=总雷数-1       Endend

//[(y+1)<<5+(x+1)+0x1005340]&0x80 !=0  则横坐标x,纵坐标y处是雷
function getType(x, y)//为真是雷    x = x + 1    y = y + 1    y = 位左移(y, 5)    var addr = y + x + #1005340    addr = strformat("%x", addr)    var type = dm.ReadInt(hwnd, addr, 2)    return 位与(type, #80) != 0end

跟踪挖雷call思路挖雷是在点鼠标的时候触发的,于是在windowproc函数里面的分支去找windowproc类似于tc里面的消息路由里面对各种windows消息做处理观察游戏可以发现鼠标左键按下去的时候并不会触发挖雷,只有鼠标左键弹起的时候才会触发所以直接找 WM_LBUTTONUP =0x202 这个消息的对应处理即可 01001FDF  |> \33FF          xor edi,edi                              ;  Cases 202 (WM_LBUTTONUP),205(WM_RBUTTONUP),208 (WM_MBUTTONUP) of switch 01001F5F01001FE1  |. 393D 40510001 cmp dword ptr ds:[0x1005140],edi01001FE7  |. 0F84 BC010000 je winmine.010021A901001FED  |> 893D 40510001 mov dword ptr ds:[0x1005140],edi01001FF3  |. FF15 D8100001 call dword ptr ds:[<&USER32.ReleaseCaptu>;[ReleaseCapture01001FF9  |. 841D 00500001 test byte ptr ds:[0x1005000],bl01001FFF  |. 0F84 B6000000 je winmine.010020BB01002005  |.  E8D7170000   call winmine.010037E10100200A  |.  E99A010000   jmp winmine.010021A90100200F  |> 393D 48510001 cmp dword ptr ds:[0x1005148],edi         ; Case 204 (WM_RBUTTONDOWN) of switch 01001F5F01002015  |.^ 0F85 69FFFFFF jnz winmine.01001F84
可以看到一共只有2个call  第一个是系统函数ReleaseCapture,所以肯定在第二个call里面 现在对  call 010037E1   这一句下断单步跟踪进入

010037E1  /$  A1 18510001  mov eax,dword ptr ds:[0x1005118]010037E6  |. 85C0          test eax,eax010037E8  |. 0F8E C8000000 jle winmine.010038B6010037EE  |.  8B0D1C510001 mov ecx,dword ptr ds:[0x100511C]010037F4  |. 85C9          test ecx,ecx010037F6  |. 0F8E BA000000 jle winmine.010038B6010037FC  |. 3B05 34530001 cmp eax,dword ptr ds:[0x1005334]01003802  |. 0F8F AE000000 jg winmine.010038B601003808  |. 3B0D 38530001 cmp ecx,dword ptr ds:[0x1005338]0100380E  |. 0F8F A2000000 jg winmine.010038B601003814  |. 53            push ebx01003815  |. 33DB          xor ebx,ebx01003817  |. 43            inc ebx01003818  |. 833D A4570001>cmp dword ptr ds:[0x10057A4],0x00100381F  |.  754A         jnz short winmine.0100386B01003821  |. 833D 9C570001>cmp dword ptr ds:[0x100579C],0x001003828  |.  7541         jnz short winmine.0100386B0100382A  |. 53            push ebx0100382B  |.  E8BD000000   call winmine.010038ED01003830  |. FF05 9C570001 inc dword ptr ds:[0x100579C]01003836  |.  E87AF0FFFF   call winmine.010028B50100383B  |.  6A00         push 0x0                                 ; /Timerproc =NULL0100383D  |.  68E8030000   push 0x3E8                               ; |Timeout =1000. ms01003842  |. 53            push ebx                                 ; |TimerID =0x401003843  |. FF35 245B0001 push dword ptr ds:[0x1005B24]            ; |hWnd = 001E2BFA ('扫雷',class='扫雷')01003849  |. 891D 64510001 mov dword ptr ds:[0x1005164],ebx         ; |0100384F  |. FF15 B4100001 call dword ptr ds:[<&USER32.SetTimer>]   ; \SetTimer01003855  |. 85C0          test eax,eax01003857  |.  7507         jnz short winmine.0100386001003859  |.  6A04         push 0x40100385B  |.  E8F0000000   call winmine.0100395001003860  |> A1 18510001   mov eax,dword ptrds:[0x1005118]01003865  |. 8B0D 1C510001 mov ecx,dword ptr ds:[0x100511C]0100386B  |> 841D 00500001 test byte ptr ds:[0x1005000],bl01003871  |. 5B            pop ebx                                  ;  winmine.0100394601003872  |.  7510         jnz short winmine.0100388401003874  |.  6AFE         push -0x201003876  |. 59            pop ecx                                  ;  winmine.0100394601003877  |. 8BC1          mov eax,ecx01003879  |. 890D 1C510001 mov dword ptr ds:[0x100511C],ecx0100387F  |.  A318510001   mov dword ptrds:[0x1005118],eax01003884  |> 833D 44510001>cmp dword ptr ds:[0x1005144],0x00100388B  |.  7409         je short winmine.010038960100388D  |. 51            push ecx0100388E  |. 50            push eax0100388F  |.  E823FDFFFF   call winmine.010035B701003894  |.  EB20         jmp short winmine.010038B601003896  |> 8BD1          mov edx,ecx01003898  |. C1E2 05       shl edx,0x50100389B  |. 8A9402 405300>mov dl,byte ptr ds:[edx+eax+0x1005340]010038A2  |. F6C2 40       test dl,0x40010038A5  |.  750F         jnz short winmine.010038B6010038A7  |.  80E2 1F      and dl,0x1F010038AA  |. 80FA 0E       cmp dl,0xE010038AD  |.  7407         je short winmine.010038B6010038AF  |. 51            push ecx010038B0  |. 50            push eax010038B1  |.  E85CFCFFFF   call winmine.01003512010038B6  |> FF35 60510001 push dword ptr ds:[0x1005160]010038BC  |.  E852F0FFFF   call winmine.01002913010038C1  \. C3            retn
整理为tc代码functionmineByPos(x, y)//挖雷call    dm.AsmClear()    dm.AsmAdd("push 0x" &strformat("%x", (y + 1)))    dm.AsmAdd("push 0x" &strformat("%x", (x + 1)))    dm.AsmAdd("call 01003512")    dm.AsmCall(hwnd, 1)end    标记call同理找鼠标右键按下消息分析代码整理为tc代码如下function mark(x, y)//标记call   dm.AsmClear()   dm.AsmAdd("push 0x" & strformat("%x", (y + 1)))   dm.AsmAdd("push 0x" & strformat("%x", (x + 1)))   dm.AsmAdd("call 0100374F")   dm.AsmCall(hwnd, 1)end[/hide]

1.jpg (51.19 KB, 下载次数: 0)

1.jpg

2.jpg (11.67 KB, 下载次数: 1)

2.jpg

3.jpg (112.92 KB, 下载次数: 1)

3.jpg

MineCracker.zip

4.57 KB, 下载次数: 8

售价: 1 个金币  [记录]

源代码

XP版扫雷 内存call分析过程.docx

18.33 KB, 下载次数: 106

回复

使用道具 举报

沙发
发表于 2018-4-26 09:51:46 | 只看该作者
XP版的太简单了
回复 支持 反对

使用道具 举报

板凳
发表于 2018-4-26 09:55:45 | 只看该作者
01003860    A1 18510001     mov     eax, dword ptr [1005118]
01003865    8B0D 1C510001   mov     ecx, dword ptr [100511C]
0100386B    841D 00500001   test    byte ptr [1005000], bl
01003871    5B              pop     ebx
01003872    75 10           jnz     short 01003884
01003874    6A FE           push    -2
01003876    59              pop     ecx
01003877    8BC1            mov     eax, ecx
01003879    890D 1C510001   mov     dword ptr [100511C], ecx
0100387F    A3 18510001     mov     dword ptr [1005118], eax
01003884    833D 44510001 0>cmp     dword ptr [1005144], 0
0100388B    74 09           je      short 01003896
0100388D    51              push    ecx
0100388E    50              push    eax
0100388F    E8 23FDFFFF     call    010035B7
01003894    EB 20           jmp     short 010038B6
01003896    8BD1            mov     edx, ecx
01003898    C1E2 05         shl     edx, 5
0100389B    8A9402 40530001 mov     dl, byte ptr [edx+eax+1005340]
010038A2    F6C2 40         test    dl, 40
010038A5    75 0F           jnz     short 010038B6
010038A7    80E2 1F         and     dl, 1F
010038AA    80FA 0E         cmp     dl, 0E
010038AD    74 07           je      short 010038B6
010038AF    51              push    ecx                              ; 行数
010038B0    50              push    eax                              ; 列数
010038B1    E8 5CFCFFFF     call    01003512  //左键点击call


01002174    8B45 14         mov     eax, dword ptr [ebp+14]
01002177    C1E8 10         shr     eax, 10
0100217A    83E8 27         sub     eax, 27
0100217D    C1F8 04         sar     eax, 4
01002180    50              push    eax                              ; 右键点击行数
01002181    0FB745 14       movzx   eax, word ptr [ebp+14]
01002185    83C0 04         add     eax, 4
01002188    C1F8 04         sar     eax, 4
0100218B    50              push    eax                              ; 右键点击列数
0100218C    E8 BE150000     call    0100374F

回复 支持 反对

使用道具 举报

地板
发表于 2018-4-26 09:59:06 | 只看该作者
这个是win 7版的
变量 线程ID
变量 冬去春来 = com("dm.dmsoft")
功能 执行()
    变量 游戏句柄 = 窗口查找("扫雷")
    变量 入口地址 = 冬去春来.FindData(游戏句柄, "00000000-7fffffff", "E8 B5 05 00 00 E9 4D FD FF FF")
    变量 左键点击 = "00" & 字符串格式化("%x", 转整型(入口地址, 1) - 52343)
    变量 右键点击 = "00" & 字符串格式化("%x", 转整型(入口地址, 1) - 57833)
    变量 游戏基址 = "00" & 字符串格式化("%x", 转整型(入口地址, 1) + 362533)//游戏每次启动基址会变化,这里用的入口地址定位
    变量 游戏行数 = 冬去春来.ReadInt(游戏句柄, "[[" & 游戏基址 & "]+10]+8", 0)
    变量 游戏列数 = 冬去春来.ReadInt(游戏句柄, "[[" & 游戏基址 & "]+10]+c", 0)//判断游戏行列数
    遍历(变量 i = 0; i < 游戏列数; i++)
        等待(10)
        遍历(变量 j = 0; j < 游戏行数; j++)
            等待(10)
            变量 列数下标 = 字符串格式化("%x", 4 * i)
            变量 行数下标 = 字符串格式化("%x", 4 * j)
            变量 列数下标1 = "0x" & 字符串格式化("%x", i)
            变量 行数下标1 = "0x" & 字符串格式化("%x", j)
            变量 是否点开 = 冬去春来.ReadInt(游戏句柄, "[[[[[[[" & 游戏基址 & "]+c]+24]+40]+c]+" & 列数下标 & "]+c]+" & 行数下标 & "", 0)
            如果(是否点开 == 9)//9未翻开10问号11旗子
                变量 是否有雷 = 冬去春来.ReadInt(游戏句柄, "[[[[[[" & 游戏基址 & "]+10]+44]+c]+" & 列数下标 & "]+c]+" & 行数下标1 & "", 2)
                如果(是否有雷 == 1)//1有雷,0没雷
                    冬去春来.AsmClear()
                    冬去春来.AsmAdd("push " & 行数下标1 & "")
                    冬去春来.AsmAdd("mov eax,[" & 游戏基址 & "]")
                    冬去春来.AsmAdd("mov ecx,[eax+0c]")
                    冬去春来.AsmAdd("mov esi,ecx")
                    冬去春来.AsmAdd("push " & 列数下标1 & "")
                    冬去春来.AsmAdd("mov ecx,[esi+24]")
                    冬去春来.AsmAdd("mov eax," & 右键点击 & "")
                    冬去春来.AsmAdd("call eax")
                    冬去春来.AsmCall(游戏句柄, 1)
                否则
                    冬去春来.AsmClear()
                    冬去春来.AsmAdd("push " & 行数下标1 & "")
                    冬去春来.AsmAdd("mov eax,[" & 游戏基址 & "]")
                    冬去春来.AsmAdd("mov ecx,[eax+0c]")
                    冬去春来.AsmAdd("mov edi,ecx")
                    冬去春来.AsmAdd("push " & 列数下标1 & "")
                    冬去春来.AsmAdd("mov ecx,[" & 游戏基址 & "]")
                    冬去春来.AsmAdd("mov eax," & 左键点击 & "")
                    冬去春来.AsmAdd("call eax")
                    冬去春来.AsmCall(游戏句柄, 1)
                结束
            结束
        结束
    结束
结束
功能 启动_热键()
    线程ID = 线程开启("执行", "")
结束
功能 终止_热键()
    线程关闭(线程ID)
结束
功能 win7扫雷_初始化()
    注册插件("rc:dm.dll", 真)
结束
回复 支持 反对

使用道具 举报

*滑动验证:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

站长推荐上一条 /2 下一条

关闭

小黑屋|TC官方合作论坛 (苏ICP备18043773号

GMT+8, 2025-9-17 05:40 , Processed in 0.136465 second(s), 26 queries .

Powered by 海安天坑软件科技有限公司

© 2001-2013 Comsenz Inc.

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