当前位置: 移动技术网 > 网络运营>安全>加解密 > 逆向改出不死版扫雷

逆向改出不死版扫雷

2018年04月19日  | 移动技术网网络运营  | 我要评论

文章作者:Fypher  摘自于邪恶八进制

上个学期搞过一段时间逆向,把windows的扫雷改成了个不死版的(纯属无聊消遣,呵呵)。
今晚睡不着,把当时的思路总结了一下写出来。

首先OD载入,来到此处:
复制内容到剪贴板
代码:
01003F90   . E8 5BE2FFFF   CALL winmine.010021F0                    ; winmine.010021F0
01003F95   . 8BF0          MOV ESI,EAX
01003F97   . 8975 84       MOV DWORD PTR SS:[EBP-7C],ESI
01003F9A   . 395D E4       CMP DWORD PTR SS:[EBP-1C],EBX
01003F9D   . 75 07         JNZ SHORT winmine.01003FA6
01003F9F   . 56            PUSH ESI                                 ; /status
01003FA0   . FF15 94110001 CALL DWORD PTR DS:[<&msvcrt.exit>]       ; exit
01003FA6   > FF15 9C110001 CALL DWORD PTR DS:[<&msvcrt._cexit>]     ; [msvcrt._cexit
由C运行期库的退出函数可知,winmine.010021F0应该是扫雷的main函数,跟入!

来到窗口注册的地方:
复制内容到剪贴板
代码:
0100228B |. 50            PUSH EAX                                 ; /pWndClass = 0007FED0
0100228C |. 897D D4       MOV DWORD PTR SS:[EBP-2C],EDI            ; |
0100228F |. 8975 D8       MOV DWORD PTR SS:[EBP-28],ESI            ; |
01002292 |. FF15 CC100001 CALL DWORD PTR DS:[<&USER32.RegisterClas>; RegisterClassW
这是RegisterClass的原型:ATOM RegisterClass( CONST WNDCLASS *lpWndClass);

其参数是指向WNDCLASS的指针。我们MSDN一下:
复制内容到剪贴板
代码:
typedef struct {
    UINT style;
    WNDPROC lpfnWndProc;
    int cbClsExtra;
    int cbWndExtra;
    HINSTANCE hInstance;
    HICON hIcon;
    HCURSOR hCursor;
    HBRUSH hbrBackground;
    LPCTSTR lpszMenuName;
    LPCTSTR lpszClassName;
} WNDCLASS, *PWNDCLASS;
呵呵,4~7字节就是窗口回调函数的地址!马上到0007FED0去看看:
复制内容到剪贴板
代码:
0007FED0 00 00 00 00 C9 1B 00 01 ....?.
嘿嘿~回调函数地址是0x01001BC9~跳过去看看回调函数吧。下面是一些比较有趣的消息处理case~:
复制内容到剪贴板
代码:
01001FDF |> 33FF          XOR EDI,EDI                              ; 左/中/右键弹起; Cases 202 (WM_LBUTTONUP),205 (WM_RBUTTONUP),208 (WM_MBUTTONUP) of switch 01001F5F
01001FE1 |. 393D 40510001 CMP DWORD PTR DS:[1005140],EDI
01001FE7 |. 0F84 BC010000 JE winmine.010021A9                      ; 如果是右键弹起(什么都不做,因为是在按下时画旗)
01001FED |> 893D 40510001 MOV DWORD PTR DS:[1005140],EDI
01001FF3 |. FF15 D8100001 CALL DWORD PTR DS:[<&USER32.ReleaseCaptu>; [ReleaseCapture
01001FF9 |. 841D 00500001 TEST BYTE PTR DS:[1005000],BL
01001FFF |. 0F84 B6000000 JE winmine.010020BB
01002005 |. E8 D7170000   CALL winmine.010037E1                    ; 处理左键
跟进去!毕竟我们最关心的是左键,如果点到了雷怎么办?嘿嘿~
复制内容到剪贴板
代码:
010038B1 |. E8 5CFCFFFF   CALL winmine.01003512
再跟!
复制内容到剪贴板
代码:
01003512 /$ 8B4424 08     MOV EAX,DWORD PTR SS:[ESP+8]
01003516 |. 53            PUSH EBX
01003517 |. 55            PUSH EBP
01003518 |. 56            PUSH ESI
01003519 |. 8B7424 10     MOV ESI,DWORD PTR SS:[ESP+10]            ; ESI中表示单击的格子在第几列
0100351D |. 8BC8          MOV ECX,EAX
0100351F |. C1E1 05       SHL ECX,5
01003522 |. 8D9431 405300>LEA EDX,DWORD PTR DS:[ECX+ESI+1005340]   ; EDX中存放的就是当前格子的内存地址!
01003529 |. F602 80       TEST BYTE PTR DS:[EDX],80
0100352C |. 57            PUSH EDI
0100352D |. 74 66         JE SHORT winmine.01003595                ; 如果是雷则不跳
0100352F |. 833D A4570001>CMP DWORD PTR DS:[10057A4],0             ; 中招!!
01003536 |. 75 50         JNZ SHORT winmine.01003588
……
01003588 |> 6A 4C         PUSH 4C
0100358A |. 50            PUSH EAX
0100358B |. 56            PUSH ESI
0100358C |. E8 1AF9FFFF   CALL winmine.01002EAB                    ; 挂~!
01003591 |. 6A 00         PUSH 0
01003593 |. EB 16         JMP SHORT winmine.010035AB
01003595 |> 50            PUSH EAX                                 ; /Arg2
01003596 |. 56            PUSH ESI                                 ; |Arg1
01003597 |. E8 E8FAFFFF   CALL winmine.01003084                    ; winmine.01003084 ;若不是雷,行列压栈,此call用来在打开的格子上写数字等等处理
0100359C |. A1 A4570001   MOV EAX,DWORD PTR DS:[10057A4]
010035A1 |. 3B05 A0570001 CMP EAX,DWORD PTR DS:[10057A0]
010035A7 |. 75 07         JNZ SHORT winmine.010035B0
010035A9 |. 6A 01         PUSH 1
010035AB |> E8 CCFEFFFF   CALL winmine.0100347C
010035B0 |> 5F            POP EDI
010035B1 |. 5E            POP ESI
010035B2 |. 5D            POP EBP
0100

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网