拆解习题


习题九 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