逆向改出不死版扫雷
文章作者: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
上一篇: 妙解破解的原理
下一篇: 介绍几款“加密”软件的破解方法