本文是爆破。
aspack加的壳,脱壳,也是DELPHI所写,
运行程序,有提示程序被病毒修改,即有自校验,於是下bp CreateFileA
下断,逐步跟,发现後面调用GetFilesize取得文件大小,通过判断文件大小来比较,大於某个数值则认为文件被修改过。跳过这里即可。
正常运行了。於是下个按钮断点:
来到头部:
00488F20 . 55 PUSH EBP ; 按钮事件
00488F21 . 8BEC MOV EBP, ESP
//........省略部份
0048902A . 8B45 F0 MOV EAX, DWORD PTR SS:[EBP-0x10] ; 用户名
0048902D . 8D55 EC LEA EDX, DWORD PTR SS:[EBP-0x14]
00489030 . E8 3BFEFFFF CALL unpack.00488E70
00489035 . 8B45 EC MOV EAX, DWORD PTR SS:[EBP-0x14] ; ASCII "270018795"
00489038 . 8B55 F8 MOV EDX, DWORD PTR SS:[EBP-0x8] ; 假码
0048903B . E8 60ADF7FF CALL unpack.00403DA0 ; 字符串比较
00489040 0F85 56010000 JNZ unpack.0048919C
00489046 . B8 34924800 MOV EAX, unpack.00489234 ; 注册成功!请重新启动浪漫情书……
明码比较的,用由用户名和机器码算出真码,於是再和假码比较,相等则提示重启程序。算法没跟进去。
後面保存注册码:
004890AB . E8 A4ADF7FF CALL unpack.00403E54
004890B0 . 50 PUSH EAX ; |String
004890B1 . 68 58924800 PUSH unpack.00489258 ; |用户名
004890B6 . 68 60924800 PUSH unpack.00489260 ; |注册
004890BB . E8 34D2F7FF CALL <JMP.&kernel32.WritePrivateProfi>; \WritePrivateProfileStringA
004890C0 . 8D55 E8 LEA EDX, DWORD PTR SS:[EBP-0x18]
004890C3 . A1 B47A4A00 MOV EAX, DWORD PTR DS:[0x4A7AB4]
004890C8 . 8B00 MOV EAX, DWORD PTR DS:[EAX]
004890CA . E8 AD26FCFF CALL unpack.0044B77C
004890CF . 8B45 E8 MOV EAX, DWORD PTR SS:[EBP-0x18]
004890D2 . 8D55 EC LEA EDX, DWORD PTR SS:[EBP-0x14]
004890D5 . E8 06F2F7FF CALL unpack.004082E0
004890DA . 8D45 EC LEA EAX, DWORD PTR SS:[EBP-0x14]
004890DD . 8B15 E4784A00 MOV EDX, DWORD PTR DS:[0x4A78E4] ; unpack.004A89A0
004890E3 . 8B12 MOV EDX, DWORD PTR DS:[EDX]
004890E5 . 8B92 38060000 MOV EDX, DWORD PTR DS:[EDX+0x638]
004890EB . E8 A8ABF7FF CALL unpack.00403C98
004890F0 . 8B45 EC MOV EAX, DWORD PTR SS:[EBP-0x14]
004890F3 . E8 5CADF7FF CALL unpack.00403E54
004890F8 . 50 PUSH EAX
004890F9 . 8D55 F0 LEA EDX, DWORD PTR SS:[EBP-0x10]
004890FC . 8B45 FC MOV EAX, DWORD PTR SS:[EBP-0x4]
004890FF . 8B80 D0020000 MOV EAX, DWORD PTR DS:[EAX+0x2D0]
00489105 . E8 265BFAFF CALL unpack.0042EC30
0048910A . 8B45 F0 MOV EAX, DWORD PTR SS:[EBP-0x10]
0048910D . E8 42ADF7FF CALL unpack.00403E54
00489112 . 50 PUSH EAX ; |String
00489113 . 68 68924800 PUSH unpack.00489268 ; |注册码
00489118 . 68 60924800 PUSH unpack.00489260 ; |注册
0048911D . E8 D2D1F7FF CALL <JMP.&kernel32.WritePrivateProfi>; \写入INI文件
写入INI文件,於是重新运行程序,下个GetPrivateProfileStringA断点
0049B074 . 8B80 44060000 MOV EAX, DWORD PTR DS:[EAX+0x644] ; ini中的假码
0049B07A . E8 118CF6FF CALL unpack.00403C90
0049B07F . 83F8 06 CMP EAX, 0x6
0049B082 . 7D 24 JGE SHORT unpack.0049B0A8
0049B084 . 8B45 FC MOV EAX, DWORD PTR SS:[EBP-0x4]
0049B087 . 05 44060000 ADD EAX, 0x644
0049B08C . BA 10B94900 MOV EDX, unpack.0049B910 ; 试用用户
0049B091 . E8 D289F6FF CALL unpack.00403A68
0049B096 . 8B45 FC MOV EAX, DWORD PTR SS:[EBP-0x4]
0049B099 . 05 48060000 ADD EAX, 0x648
0049B09E . E8 7189F6FF CALL unpack.00403A14
0049B0A3 . E9 E1000000 JMP unpack.0049B189
0049B0A8 > 8D4D EC LEA ECX, DWORD PTR SS:[EBP-0x14]
0049B0AB . 8B45 FC MOV EAX, DWORD PTR SS:[EBP-0x4]
0049B0AE . 8B90 44060000 MOV EDX, DWORD PTR DS:[EAX+0x644]
0049B0B4 . 8B45 FC MOV EAX, DWORD PTR SS:[EBP-0x4]
0049B0B7 . E8 44ADFFFF CALL unpack.00495E00
0049B0BC . 8B45 EC MOV EAX, DWORD PTR SS:[EBP-0x14] ; 出现真码(ASCII "372037082")
0049B0BF . 8B55 FC MOV EDX, DWORD PTR SS:[EBP-0x4]
0049B0C2 . 8B92 48060000 MOV EDX, DWORD PTR DS:[EDX+0x648] ; 假码
0049B0C8 . E8 D38CF6FF CALL unpack.00403DA0 ; 字符串比较
0049B0CD 75 3F JNZ SHORT unpack.0049B10E
0049B0CF . 8B45 FC MOV EAX, DWORD PTR SS:[EBP-0x4]
0049B0D2 . 05 44060000 ADD EAX, 0x644
0049B0D7 . BA 10B94900 MOV EDX, unpack.0049B910 ; 试用用户
这里虽然有字符串,试用用户,但不要被它迷惑,因为不跳的话就不是一个合法用户
把这些都解决了,程序的注册菜单消失了。但用点击菜单,打印,转WORD那些都报一个错误,还有验证没搞定。於是下个菜单的死码:
菜单项改成:
74 ?? 8B ?? 8B ?? ?? FF ?? ??
如果用按钮死码,有可能断不到。
几个菜单的校验都是类似的,所以只举例某一个:
004A0108 . 55 PUSH EBP ; 菜单事件。
004A0109 . 8BEC MOV EBP, ESP
004A010B . 83C4 F8 ADD ESP, -0x8
004A010E . 53 PUSH EBX
004A010F . 56 PUSH ESI
004A0110 . 57 PUSH EDI
004A0111 . 8955 F8 MOV DWORD PTR SS:[EBP-0x8], EDX
004A0114 . 8945 FC MOV DWORD PTR SS:[EBP-0x4], EAX
004A0117 . 8B45 FC MOV EAX, DWORD PTR SS:[EBP-0x4]
004A011A . 80B8 84060000>CMP BYTE PTR DS:[EAX+0x684], 0x0 ; BYTE变量地址012B67F8为1表示已注册变量
004A0121 . 75 13 JNZ SHORT unpack.004A0136
004A0123 . 8B45 FC MOV EAX, DWORD PTR SS:[EBP-0x4]
004A0126 . 8B80 94060000 MOV EAX, DWORD PTR DS:[EAX+0x694]
004A012C . E8 1F19FBFF CALL unpack.00451A50
004A0131 . E9 D2000000 JMP unpack.004A0208
004A0136 > 8B45 FC MOV EAX, DWORD PTR SS:[EBP-0x4]
004A0139 . 8B80 E4030000 MOV EAX, DWORD PTR DS:[EAX+0x3E4]
004A013F . 8078 30 00 CMP BYTE PTR DS:[EAX+0x30], 0x0 ; BYTE变量地址012C4E68为1才是合法用户,否则出错
004A0143 . 75 33 JNZ SHORT unpack.004A0178
004A0145 . 8B45 FC MOV EAX, DWORD PTR SS:[EBP-0x4]
004A0148 . 8B80 44060000 MOV EAX, DWORD PTR DS:[EAX+0x644]
004A014E . BA 18024A00 MOV EDX, unpack.004A0218 ; 试用用户
004A0153 . E8 483CF6FF CALL unpack.00403DA0
004A0158 75 1E JNZ SHORT unpack.004A0178 ; 跳过就不出错
这里JNZ改JMP就OK了,测试正常。校验合部搞定。看来DELPHI程序得多些找来用用,弄多些死码有助PJ。