目录>>第7章
第7章 Visual Basic程序
第四节 拆解习题
习题九 chap7-09 需分析计算,难
SmartCheck
还剩最后一个 CrackMe 了。用 SmartCheck 运行它,输入 123456 并点击 OK.
** 确信 SmartCheck 是在 "Show Errors and Specific Events" 模式下(在菜单 VIEW 里)。
展开 Command1_click
你交将看到 :
Mid()
Asc()
Chr$()
这三个函数重复调用直到处理完我们输入的密码( 123456 )
例:
1) Mid(VARIANT:String"123456", long:1, VARIANT:Integer:1)
2) Asc(String:"1") returns Integer:49
3) Chr$(Integer:59)
解释 :
1) 得到第一个字符;
2) 将其转换为十进制;
3) 加 10 (十进制)并转换 Ascii 格式返回。
为什么我知道第三步这种规律?因为我分析了其它的 Chr$() 情况。
Ok. 我们知道我们输入的 KEY 被转换了,但是它们处理得很突然,一会儿就结束。
因此让我们点击最后一个 Chr$() ,并在菜单选择: "Show All Events"
在 2 行后,你将看到:
__vbaVarMove(VARIANT:String:";<=>?@",.....)...
这是输入的 123456 被转换后的 KEY
几行后,你将看到:
__vbaVarTstEq(VARIANT:String";<=>?@",VARIANT:Const String:"") returns...
这是与一常量字符串比较我们输入的己转换的 KEY.... 但是常量字符串并没显示出来!!现在让我们用 SOFTICE 。
注意: SmartCheck 里的这个函数 __vbaVarTstEq ,它是一普通的函数,因此我们用它设断。
在 SOFTICE 下设断: "bpx __vbaVarTstEq"
在你点击 OK 后,你将中断在 SOFTICE 。
在你继续之前,我要告诉你,需跟踪很长一段路程,你在每第一个 call 按 F8 进入,我在这里只列出一些重要的步骤。
Break due to BPX MSVBVM50!__vbaVarTstEq (ET=962.85 milliseconds)
MSVBVM50!__vbaVarTstEq
:xxxxB9A2 FF742408 PUSH DWORD PTR [ESP+08]
:xxxxB9A6 6A00 PUSH 00
:xxxxB9A8 E8E74AFFFF CALL xxxx0494
** 按 F8 进入这个 call
==========================================================================
:xxxx0494
:xxxx0494 55 PUSH EBP
:xxxx0495 8BEC MOV EBP,ESP
:xxxx0497 83EC44 SUB ESP,44
:xxxx049A 833D64F03F7B00 CMP DWORD PTR [xxxxF064],00
: __________ 省略一小部分 __________
:
:xxxx062F 8B550C MOV EDX,[EBP+0C]
:xxxx0632 FF7308 PUSH DWORD PTR [EBX+08]
:xxxx0635 FF7208 PUSH DWORD PTR [EDX+08]
:xxxx0638 FF7508 PUSH DWORD PTR [EBP+08]
:xxxx063B E8BC3FF0FF CALL 7B2F45FC
按 F8 进入这个 call
==========================================================================
:xxxx45FC 66837C240400 CMP WORD PTR [ESP+04],00
:xxxx4602 B800000000 MOV EAX,00000000
:xxxx4607 0F85D9F20500 JNZ 7B3538E6 (NO JUMP)
:xxxx460D FF74240C PUSH DWORD PTR [ESP+0C]
:xxxx4611 FF74240C PUSH DWORD PTR [ESP+0C]
:xxxx4615 50 PUSH EAX
:xxxx4616 E848EFFFFF CALL MSVBVM50!__vbaStrComp
** 按 F8 进入这个 call
==========================================================================
MSVBVM50!__vbaStrComp
:xxxx3564 8BEC MOV EBP,ESP
:xxxx3566 53 PUSH EBX
:xxxx3567 56 PUSH ESI
:xxxx3568 57 PUSH EDI
:xxxx3569 837D1000 CMP DWORD PTR [EBP+10],00
:xxxx356D BE00000000 MOV ESI,00000000
:xxxx3572 7406 JZ xxxx357A (NO JUMP)
:xxxx3574 8B4510 MOV EAX,[EBP+10] <-- d eax
:xxxx3577 8B70FC MOV ESI,[EAX-04] <-- esi = 0000000C
:xxxx357A 837D0C00 CMP DWORD PTR [EBP+0C],00
:xxxx357E BF00000000 MOV EDI,00000000
:xxxx3583 7406 JZ xxxx358B (NO JUMP)
:xxxx3585 8B4D0C MOV ECX,[EBP+0C] <-- d ecx
:xxxx3588 8B79FC MOV EDI,[ECX-04] <-- edi = 0000002A
:xxxx358B 3BFE CMP EDI,ESI
在通过这一步 :xxxx3574 ,你将看到寄存器窗口中的 eax 颜色改变了,键入: "d eax" 你将在 SOFTICE 的数据窗口看到:
:00510F70 3B 00 3C 00 3D 00 3E 00-3F 00 40 00 00 00 00 00 ;.<.=.>.?.@.....
:00510F80 00 00 00 00 00 00 00 00-00 00 00 00 14 00 00 A0 ................
注意 ;.<.=.>.?.@.
我们己在 SmartCheck 下己发现了它,它是我们输入的密码( key )转换后的形式。 <=>?@ 现在被转换成 widechar 格式: ;.<.=.>.?.@
如果你在 SOFTICE 下在走几行,你会看到: esi = 0000000C , c 是的 12 的十六进制。这是我们输入的密码的长度,注意此时密码转换为 widechar 格式,因此长度为 2*6=12.
如果你通过 :xxxx3585 ,你将看到 ecx 颜色改变。键入 "d ecx" ,在数据区内看到:
:00401A8C 6B 00 58 00 79 00 5E 00-72 00 4F 00 7C 00 2A 00 k.X.y.^.r.O.|.*.
:00401A9C 79 00 58 00 6F 00 2A 00-6D 00 5C 00 6B 00 4D 00 y.X.o.*.m.\.k.M.
:00401AAC 75 00 4F 00 6E 00 2A 00-2B 00 00 00 64 00 00 00 u.O.n.*.+...d...
再走几行你会发现 edi = 0000002A
2A 是 42 的十六进制,因此它的密码长度就是 21 ,此时从上面数据区里挑出 21 个字符(忽略 "." )
我们己知道输入的密码是如何转换的,因此我们反转这 21 个字符,具体如下:
1) Asc()
2) 以十进制减 10
3) Chr() 把结果转换为十六进制再变成 Ascii 码 .
|
sofice数据窗口 |
Asc() |
减10 |
Chr()
|
|
k |
107 |
97 |
a |
|
X |
88 |
78 |
N |
|
y |
121 |
111 |
o |
|
^ |
94 |
84 |
T |
|
r |
114 |
104 |
h |
|
O |
79 |
69 |
E |
|
| |
124 |
114 |
r |
|
* |
42 |
32 |
--(空格) |
|
y |
121 |
111 |
o |
|
X |
88 |
78 |
N |
|
o |
111 |
101 |
e |
|
* |
42 |
32 |
--(空格) |
|
m |
109 |
99 |
c |
|
\ |
92 |
82 |
R |
|
k |
107 |
97 |
a |
|
M |
77 |
67 |
C |
|
u |
117 |
107 |
k |
|
O |
79 |
69 |
E |
|
n |
110 |
100 |
d |
|
* |
42 |
32 |
--(空格) |
|
+ |
43 |
33 |
! |
正确的 Key: aNoThEr oNe cRaCkEd !
成功了,不要太高兴!!
讨论一下:在 CrackMe3, 你可用 __vbaStrComp 设断(它被调用),它可减少跟踪路程,但是开始谁知它被调用呢? SmartCheck 没告诉我们。 8)
看雪2000/2/22