因为exe有重定位表,为了方便读者阅读分析代码,先用pe编辑工具把exe的重定位表地址rv清
0
程序中有很多检测,但检测到异常后,都会调用一个共同入口
0042E086
来处理,因此只要在
0042E086
处改一个字节ret直接返回就可以了
ida打开exe,从GetDlgItemTextA的参考入手找到读取输入的地方,并对后面的流程做个注释:
.text:
00435061
push
401h
; cchMax
.text:
00435066
lea eax, [ebp
+
String]
.text:
0043506C
push eax ; lpString
.text:
0043506D
push
3E9h
; nIDDlgItem
.text:
00435072
mov ecx, [ebp
+
hDlg]
.text:
00435075
push ecx ; hDlg
.text:
00435076
call ds:GetDlgItemTextA
/
/
读取输入
...
.text:
004350A6
lea eax, [ebp
+
var_C30]
.text:
004350AC
push eax
.text:
004350AD
push
400h
.text:
004350B2
lea ecx, [ebp
+
String]
.text:
004350B8
push ecx
.text:
004350B9
call sub_42D267
/
/
对输入做第一层base64解码
...
.text:
004350DE
lea eax, [ebp
+
var_1038]
.text:
004350E4
push eax
.text:
004350E5
push
400h
.text:
004350EA
lea ecx, [ebp
+
var_C30]
.text:
004350F0
push ecx
.text:
004350F1
call sub_42D267
/
/
对输入做第二层base64解码
.text:
004350F6
add esp,
0Ch
.text:
004350F9
push
400h
.text:
004350FE
lea eax, [ebp
+
var_1440]
.text:
00435104
push eax
.text:
00435105
lea ecx, [ebp
+
var_1038]
.text:
0043510B
push ecx
.text:
0043510C
call sub_42D96A
/
/
摩尔斯电码解码,空格分隔,
4
个字符转成一个小写字母
.text:
00435111
add esp,
0Ch
.text:
00435114
mov [ebp
+
var_144C],
3
.text:
0043511E
lea eax, [ebp
+
var_1474]
.text:
00435124
push eax
.text:
00435125
mov ecx, [ebp
+
var_144C]
.text:
0043512B
push ecx
.text:
0043512C
lea edx, [ebp
+
var_1038]
.text:
00435132
push edx
.text:
00435133
call sub_42DA78
/
/
计算前
3
个字符的
hash
.text:
00435138
add esp,
0Ch
.text:
0043513B
mov [ebp
+
var_1888],
0
.text:
00435145
jmp short loc_435156
.text:
00435147
loc_435147:
.text:
00435147
mov eax, [ebp
+
var_1888]
.text:
0043514D
add eax,
1
.text:
00435150
mov [ebp
+
var_1888], eax
.text:
00435156
loc_435156:
.text:
00435156
cmp
[ebp
+
var_1888],
20h
.text:
0043515D
jge short loc_43518B
.text:
0043515F
mov eax, [ebp
+
var_1888]
.text:
00435165
movzx ecx, [ebp
+
eax
+
var_1474]
.text:
0043516D
push ecx
.text:
0043516E
push offset a02x ;
"%02x"
.text:
00435173
mov edx, [ebp
+
var_1888]
.text:
00435179
lea eax, [ebp
+
edx
*
2
+
var_187C]
.text:
00435180
push eax
.text:
00435181
call sub_42DF05
/
/
hash
结果转成
16
进制字符串
.text:
00435186
add esp,
0Ch
.text:
00435189
jmp short loc_435147
.text:
0043518B
loc_43518B:
...
.text:
004351C0
sub esi, eax
.text:
004351C2
push esi
.text:
004351C3
lea eax, [ebp
+
var_187C]
.text:
004351C9
push eax
.text:
004351CA
call sub_42DB27
/
/
hash
串和输入的后
64
个字符比较
.text:
004351CF
add esp,
0Ch
.text:
004351D2
test eax, eax
.text:
004351D4
jnz short loc_435214
.text:
004351D6
call sub_42D0B4
.text:
004351DB
lea eax, [ebp
+
var_1440]
.text:
004351E1
push eax
.text:
004351E2
push offset unk_49B000
/
/
迷宫数据
.text:
004351E7
call sub_42D9AB
/
/
根据输入做迷宫寻路
.text:
004351EC
add esp,
8
.text:
004351EF
movzx ecx, al
.text:
004351F2
cmp
ecx,
1
.text:
004351F5
jnz short loc_435214
.text:
004351F7
mov esi, esp
.text:
004351F9
push
0
; uType
.text:
004351FB
push offset Caption ;
"CrackMe"
.text:
00435200
push offset Text ;
"ok"
.text:
00435205
push
0
; hWnd
.text:
00435207
call ds:MessageBoxA
.text:
0043520D
cmp
esi, esp
摩尔斯电码解码
4
个字符一组,空格是分隔符,空格前加
'/'
转义表示空格本身,每
4
个字符查表
0049B2A0
处的数据表,按顺序对应a~z:
.
-
*
*
-
...
-
.
-
.
-
..
*
.
*
*
*
..
-
.
-
-
.
*
....
..
*
*
.
-
-
-
-
.
-
*
.
-
..
-
-
*
*
-
.
*
*
-
-
-
*
.
-
-
.
-
-
.
-
.
-
.
*
...
*
-
*
*
*
..
-
*
...
-
.
-
-
*
-
..
-
-
.
-
-
-
-
..
大小是
10
*
10
的迷宫数据
49B000
,要求从左上角走到右上角,
0
是可走点,
1
是障碍,x是个暗桩导致死锁:
0
1
1
1
1
1
1
1
1
0
0
0
1
1
1
1
1
0
0
0
1
0
0
0
0
0
1
0
1
1
1
1
1
1
1
0
1
0
x
1
1
0
0
0
1
0
1
0
0
1
1
0
1
0
0
0
1
0
1
1
1
0
1
1
1
1
1
0
0
1
1
0
0
0
0
1
1
1
0
0
1
1
1
1
0
0
0
0
1
0
1
1
1
1
1
1
1
0
0
0
迷宫走法是:
z 下
l 右
q 上
p 左
所以解题流程就清楚了:把迷宫路线用zlqp四个字符表示出来(注意末尾带个空格表示结束):
zlzllllzzzppqppzzzlllzlllzllqqpqpqqqqqllq
然后转成摩尔斯编码:
-
-
.. .
-
..
-
-
.. .
-
.. .
-
.. .
-
.. .
-
..
-
-
..
-
-
..
-
-
.. .
-
-
. .
-
-
.
-
-
.
-
.
-
-
. .
-
-
.
-
-
..
-
-
..
-
-
.. .
-
.. .
-
.. .
-
..
-
-
.. .
-
.. .
-
.. .
-
..
-
-
.. .
-
.. .
-
..
-
-
.
-
-
-
.
-
.
-
-
.
-
-
.
-
.
-
-
.
-
-
.
-
-
-
.
-
-
-
.
-
-
-
.
-
-
-
.
-
.
-
.. .
-
..
-
-
.
-
/
做两层base64:
TFMwdUxpQXVMUzR1SUMwdExpNGdMaTB1TGlBdUxTNHVJQzR0TGk0Z0xpMHVMaUF0TFM0dUlDMHRMaTRnTFMwdUxpQXVMUzB1SUM0dExTNGdMUzB1TFNBdUxTMHVJQzR0TFM0Z0xTMHVMaUF0TFM0dUlDMHRMaTRnTGkwdUxpQXVMUzR1SUM0dExpNGdMUzB1TGlBdUxTNHVJQzR0TGk0Z0xpMHVMaUF0TFM0dUlDNHRMaTRnTGkwdUxpQXRMUzR0SUMwdExpMGdMaTB0TGlBdExTNHRJQzR0TFM0Z0xTMHVMU0F0TFM0dElDMHRMaTBnTFMwdUxTQXRMUzR0SUM0dExpNGdMaTB1TGlBdExTNHRMeUE
后面加上
hash
得到答案:
TFMwdUxpQXVMUzR1SUMwdExpNGdMaTB1TGlBdUxTNHVJQzR0TGk0Z0xpMHVMaUF0TFM0dUlDMHRMaTRnTFMwdUxpQXVMUzB1SUM0dExTNGdMUzB1TFNBdUxTMHVJQzR0TFM0Z0xTMHVMaUF0TFM0dUlDMHRMaTRnTGkwdUxpQXVMUzR1SUM0dExpNGdMUzB1TGlBdUxTNHVJQzR0TGk0Z0xpMHVMaUF0TFM0dUlDNHRMaTRnTGkwdUxpQXRMUzR0SUMwdExpMGdMaTB0TGlBdExTNHRJQzR0TFM0Z0xTMHVMU0F0TFM0dElDMHRMaTBnTFMwdUxTQXRMUzR0SUM0dExpNGdMaTB1TGlBdExTNHRMeUEb92a72497b685c31013347a7276f371f8cf91085ab8322009bfed2df41d94f94
实际情况是,题目中迷宫判断有bug,遇到空格就会结束,判为成功,所以利用空格可以构造出无数的解来,甚至自己不加空格,程序都会自动从内存中一直向后找到一个空格为止。