i春秋百度杯11月第3周WriteUp

这是i春秋百度杯11月份第三场,逆向专场,还加了三个杂项。
传送门:百度杯

1 Misc XX

给了一串字串:
LNalVNrhIO4ZnLqZnLpVsAqtXA4FZTEc+,开始试了下base,不对。后注意到题目XX,XXencode?找个在线的解码网站,直接就出flag了。

xxencode

在线网站:http://web.chacuo.net/charsetxxencode/ 这个网站访问不顺畅,再来个国外的:http://www.webutils.pl/XXencode

2 Misc 贝丝家族

这个题目说得很清楚,base,再看字串,MZWGCZ33MVZGQZLJL5STQOJTGRPWK4SVJ56Q====。4个=号,明显base32,py解之。

base32

3 Misc 敲击

这个对于做CTF的童鞋们应该很熟悉但不常见,暂且称之为键位编码或加密吧。我一个没玩过CTF的朋友问我这是什么,我说你用26键键盘打一遍就知道了。
结果:flag{xvzoc}
这题说明上也给了提示:方方格格,不断敲击

4 Reverse CrackMe01

这题不算难,但是真让人不省心啊,具体听我慢慢道来。

先试运行下,一个文本框,一个按键,错误不提示。

直接上ida,投石问路(真不知道ida被我说成这样,那些大神会怎么蔑视我)。

因为是GUI程序,所以就不从入口看了。直接shift+f12查看下string情况,可惜没有结果。

继续投石,查看导入函数,看看如GetWindowTextA/GetWindowTextW /GetDlgItemTextA/GetDlgItemTextW之类的,足了8个地方调用了GetWindowTextW

GetWindowTextW

粗略看了下,然而没什么卵用。又看了MessageBoxW,调用也很多,同样没什么用。

到这就该细想下了,没有MessageBox,没有GetText,也就有可能提示窗口是用winapi写的,取文本通过消息机制完成。那就找消息吧,不省心的地方出现了:

message

message

幸好天无绝人之路,从创建窗口出发,找到了DefWindowProcW。

顺便复制下这个函数的说明:DefWindowProc函数调用缺省的窗口过程来为应用程序没有处理的任何窗口消息提供缺省的处理。该函数确保每一个消息得到处理。

看看这个是不是我们要找的:

windowproc

这里面比较简单,除了本窗体绘制处理外还有个循环异或和文本的绘制,而文本绘制内容就是异或的结果。其中cnText内容为:

F0 04 DA 04 D7 04 D1 04 8C 04 FF 04 F5 04 FE 04
E3 04 F8 04 E7 04 FF 04 E3 04 E9 04 F0 04 F3 04
85 04 80 04 84 04 F2 04 F4 04 F3 04 00 00 00 00

从上面的情况来看,这个窗口很有可能就是弹窗,我们需要的弹窗,那这个文本十有八九有flag有关。可是我们不知道参与异或V6的值,其实这个简单,这是单字节循环异或,枚举就行。枚举前要处理下cnText,去除宽字节。结果如下:

cm1flag

5 Reverse CrackMe02

这题没怎么用ida,就是开始看了下导入函数,发现窗口文本获取函数GetDlgItemTextA只有一个地方调用,而且调用地方很是可疑。GetWindowTextA虽然也只有一个地方调用,但显然没用。
然后就直接上了OD,bpx GetDlgItemTextA下断,f9运行,输入点“checksn”,预期中断下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
004025F1 . 68 04010000 push 0x104 ; /Count = 104 (260.)
004025F6 . 50 push eax ; |Buffer = 00000020
004025F7 . 68 E8030000 push 0x3E8 ; |ControlID = 3E8 (1000.)
004025FC . FF73 20 push dword ptr ds:[ebx+0x20] ; |hWnd = 000609FA ('CrackMe',class='#32770')
004025FF . FF15 F0E34200 call dword ptr ds:[<&USER32.GetDlgItemTextA>] ; \GetDlgItemTextA
00402605 . 80BC24 480300>cmp byte ptr ss:[esp+0x348],0x0 ; 判断输入是否为空
0040260D . 0F84 61010000 je CrackMe0.00402774
00402613 . 8DB424 480300>lea esi,dword ptr ss:[esp+0x348]
0040261A . 8D9B 00000000 lea ebx,dword ptr ds:[ebx]
00402620 > 8D8424 500400>lea eax,dword ptr ss:[esp+0x450]
00402627 . 03C7 add eax,edi
00402629 . 50 push eax
0040262A . 68 68714300 push CrackMe0.00437168 ; %02x
0040262F . 56 push esi
00402630 . E8 DC400100 call CrackMe0.00416711 ; 将输入当作16进制值进栈
00402635 . 83C6 02 add esi,0x2
00402638 . 83C4 0C add esp,0xC
0040263B . 47 inc edi
0040263C . 803E 00 cmp byte ptr ds:[esi],0x0
0040263F .^ 75 DF jnz short CrackMe0.00402620
00402641 . 83EC 08 sub esp,0x8
00402644 . 8D9424 580400>lea edx,dword ptr ss:[esp+0x458] ; 输入16进制处理后地址
0040264B . 8D8C24 480200>lea ecx,dword ptr ss:[esp+0x248] ; 后续操作地址
00402652 . 57 push edi
00402653 . E8 38F2FFFF call CrackMe0.00401890 ; AES解密一次CBC 如果输入位数不对还有一次ECB

获取输入并检查是否为空,然后直接以16进制形式(未转换)进入栈区内存,地址为堆栈地址=0018F618,再进行AES解密,解密结果存放地址为堆栈地址=0018F400。再看看AES解密:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
00401890 /$ 55 push ebp
00401891 |. 8BEC mov ebp,esp
00401893 |. 83EC 08 sub esp,0x8
00401896 |. 8A45 08 mov al,byte ptr ss:[ebp+0x8] ; 输入长度/2,即16进制字节长度
00401899 |. 53 push ebx
0040189A |. 56 push esi ; CrackMe0.0043E810
0040189B |. 57 push edi
0040189C |. 24 0F and al,0xF ; 长度 and 0xf
0040189E |. 8955 F8 mov [local.2],edx ; 16进制
004018A1 |. 8BF9 mov edi,ecx
004018A3 |. 8845 FF mov byte ptr ss:[ebp-0x1],al
004018A6 |. 8BDA mov ebx,edx
004018A8 |. BE 10000000 mov esi,0x10
004018AD |. 2BDF sub ebx,edi
004018AF |. 90 nop
004018B0 |> 8A040B /mov al,byte ptr ds:[ebx+ecx] ; 16进制值转存 长度0x10
004018B3 |. 8D49 01 |lea ecx,dword ptr ds:[ecx+0x1]
004018B6 |. 8841 FF |mov byte ptr ds:[ecx-0x1],al
004018B9 |. 4E |dec esi ; CrackMe0.0043E810
004018BA |.^ 75 F4 \jnz short CrackMe0.004018B0
004018BC |. 33C0 xor eax,eax
004018BE |. 893D DC234400 mov dword ptr ds:[0x4423DC],edi ; 0x4423dc 存放转存16进制值的地址
004018C4 |. 3D 20E84300 cmp eax,CrackMe0.0043E820 ; 此地址存放密钥B1nGzL[4st-TeAm]
004018C9 |. 74 12 je short CrackMe0.004018DD
004018CB |. C705 90244400>mov dword ptr ds:[0x442490],CrackMe0.0043E820 ; 0x442490 取密钥放此地址
004018D5 |. E8 86F9FFFF call CrackMe0.00401260 ; 密钥扩展处理
004018DA |. 8B55 F8 mov edx,[local.2] ; 16进制输入
004018DD |> 8B45 08 mov eax,[arg.1] ; 长度
004018E0 |. BE 10E84300 mov esi,CrackMe0.0043E810 ; IV向量000102030405060708090A0B0C0D0E0F
004018E5 |. 8935 94244400 mov dword ptr ds:[0x442494],esi ; 0x442494 存放IV向量
004018EB |. 85C0 test eax,eax
004018ED |. 74 58 je short CrackMe0.00401947
004018EF |. 48 dec eax
004018F0 |. C1E8 04 shr eax,0x4
004018F3 |. 40 inc eax
004018F4 |. 8945 08 mov [arg.1],eax ; 分组解密
004018F7 |> 8BDA /mov ebx,edx
004018F9 |. 8BCF |mov ecx,edi
004018FB |. 2BDF |sub ebx,edi
004018FD |. BA 10000000 |mov edx,0x10
00401902 |> 8A0419 |/mov al,byte ptr ds:[ecx+ebx]
00401905 |. 8D49 01 ||lea ecx,dword ptr ds:[ecx+0x1]
00401908 |. 8841 FF ||mov byte ptr ds:[ecx-0x1],al
0040190B |. 4A ||dec edx
0040190C |.^ 75 F4 |\jnz short CrackMe0.00401902
0040190E |. 893D DC234400 |mov dword ptr ds:[0x4423DC],edi
00401914 |. E8 D7FDFFFF |call CrackMe0.004016F0 ; AES解密
00401919 |. 8BC7 |mov eax,edi
0040191B |. 2BF7 |sub esi,edi
0040191D |. BA 10000000 |mov edx,0x10
00401922 |> 8A0C06 |/mov cl,byte ptr ds:[esi+eax] ; 按字节与IV异或,得最终解密结果
00401925 |. 8D40 01 ||lea eax,dword ptr ds:[eax+0x1]
00401928 |. 3048 FF ||xor byte ptr ds:[eax-0x1],cl
0040192B |. 4A ||dec edx
0040192C |.^ 75 F4 |\jnz short CrackMe0.00401922
0040192E |. 8B55 F8 |mov edx,[local.2]
00401931 |. 83C7 10 |add edi,0x10
00401934 |. 8BF2 |mov esi,edx
00401936 |. 83C2 10 |add edx,0x10
00401939 |. FF4D 08 |dec [arg.1]
0040193C |. 8955 F8 |mov [local.2],edx
0040193F |.^ 75 B6 \jnz short CrackMe0.004018F7
00401941 |. 8935 94244400 mov dword ptr ds:[0x442494],esi ; CrackMe0.0043E810
00401947 |> 8A5D FF mov bl,byte ptr ss:[ebp-0x1]
0040194A |. 84DB test bl,bl
0040194C |. 74 38 je short CrackMe0.00401986 ; 如果长度不是16的倍数,其余会进行下面的ECB解密
0040194E |. 8BCF mov ecx,edi ; 如果输入是16位,进来就是8位,会生成32位
00401950 |. 2BD7 sub edx,edi
00401952 |. BE 10000000 mov esi,0x10
00401957 |> 8A0411 /mov al,byte ptr ds:[ecx+edx]
0040195A |. 8D49 01 |lea ecx,dword ptr ds:[ecx+0x1]
0040195D |. 8841 FF |mov byte ptr ds:[ecx-0x1],al
00401960 |. 4E |dec esi ; CrackMe0.0043E810
00401961 |.^ 75 F4 \jnz short CrackMe0.00401957
00401963 |. 0FB6CB movzx ecx,bl
00401966 |. B8 10000000 mov eax,0x10
0040196B |. 2BC1 sub eax,ecx
0040196D |. 50 push eax
0040196E |. 56 push esi ; CrackMe0.0043E810
0040196F |. 8D0439 lea eax,dword ptr ds:[ecx+edi]
00401972 |. 50 push eax
00401973 |. E8 48510100 call CrackMe0.00416AC0 ; memset
00401978 |. 83C4 0C add esp,0xC
0040197B |. 893D DC234400 mov dword ptr ds:[0x4423DC],edi
00401981 |. E8 6AFDFFFF call CrackMe0.004016F0
00401986 |> 5F pop edi
00401987 |. 5E pop esi ; CrackMe0.0043E810
00401988 |. 5B pop ebx
00401989 |. 8BE5 mov esp,ebp
0040198B |. 5D pop ebp
0040198C \. C3 retn

先进行AES分组解密,密钥为B1nGzL[4st-TeAm],IV向量16进制为000102030405060708090A0B0C0D0E0F,使用CBC模式。如果输入转成的16进制长度不是16的倍数,则分组觖密后剩下的会进行ECB模式的解密,密钥不变。
回去主流程,接着看。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
00402658 . 8D8C24 4C0200>lea ecx,dword ptr ss:[esp+0x24C] ; 解密后的结果地址
0040265F . 83C4 0C add esp,0xC
00402662 . 8D51 01 lea edx,dword ptr ds:[ecx+0x1]
00402665 > 8A01 mov al,byte ptr ds:[ecx]
00402667 . 41 inc ecx
00402668 . 84C0 test al,al
0040266A .^ 75 F9 jnz short CrackMe0.00402665
0040266C . 2BCA sub ecx,edx
0040266E . 8D9424 400200>lea edx,dword ptr ss:[esp+0x240]
00402675 . 51 push ecx
00402676 . 8D8C24 3C0100>lea ecx,dword ptr ss:[esp+0x13C]
0040267D . E8 0EF3FFFF call CrackMe0.00401990 ; base64解码 这个base强悍,不是用的查表,所以什么字符都能转
00402682 . 8DB424 3C0100>lea esi,dword ptr ss:[esp+0x13C]
00402689 . 83C4 04 add esp,0x4
0040268C . 8D4E 01 lea ecx,dword ptr ds:[esi+0x1]
0040268F . 90 nop
00402690 > 8A06 mov al,byte ptr ds:[esi]
00402692 . 46 inc esi ; CrackMe0.0043E810
00402693 . 84C0 test al,al
00402695 .^ 75 F9 jnz short CrackMe0.00402690
00402697 . 2BF1 sub esi,ecx
00402699 . 33FF xor edi,edi
0040269B . 85F6 test esi,esi ; CrackMe0.0043E810
0040269D . 0F8E 97000000 jle CrackMe0.0040273A
004026A3 . EB 0B jmp short CrackMe0.004026B0
004026A5 . 8DA424 000000>lea esp,dword ptr ss:[esp]
004026AC . 8D6424 00 lea esp,dword ptr ss:[esp]
004026B0 > 0FBE843C 3801>movsx eax,byte ptr ss:[esp+edi+0x138]
004026B8 . 83C0 CE add eax,-0x32 ; Switch (cases 32..53)
004026BB . 83F8 21 cmp eax,0x21
004026BE . 77 6A ja short CrackMe0.0040272A ; 死亡之跳
004026C0 . 0FB680 A02740>movzx eax,byte ptr ds:[eax+0x4027A0] ; 0:26e5 1:26ce 2:26fc 3:2713 4:272a
004026C7 .- FF2485 8C2740>jmp dword ptr ds:[eax*4+0x40278C] ; 2 8 Q S 错
004026CE > 0FBE843C 3901>movsx eax,byte ptr ss:[esp+edi+0x139] ; Case 38 ('8') of switch 004026B8
004026D6 . 8D4C24 10 lea ecx,dword ptr ss:[esp+0x10]
004026DA . 83E8 30 sub eax,0x30
004026DD . 50 push eax
004026DE . E8 2D010000 call CrackMe0.00402810 ; -3 dec 18f1d8 18f1d8 2-9 初始时18f1dc为1进入
004026E3 . EB 4A jmp short CrackMe0.0040272F
004026E5 > 0FBE843C 3901>movsx eax,byte ptr ss:[esp+edi+0x139] ; Case 32 ('2') of switch 004026B8
004026ED . 8D4C24 10 lea ecx,dword ptr ss:[esp+0x10]
004026F1 . 83E8 30 sub eax,0x30
004026F4 . 50 push eax
004026F5 . E8 66010000 call CrackMe0.00402860 ; 1d inc 18f1d8 0-7 初始时18f1dc为1进入
004026FA . EB 33 jmp short CrackMe0.0040272F
004026FC > 0FBE843C 3901>movsx eax,byte ptr ss:[esp+edi+0x139] ; Case 51 ('Q') of switch 004026B8
00402704 . 8D4C24 10 lea ecx,dword ptr ss:[esp+0x10]
00402708 . 83E8 30 sub eax,0x30
0040270B . 50 push eax
0040270C . E8 9F010000 call CrackMe0.004028B0 ; c dec 18f1dc 1-16 初始时18f1d8为0时进入
00402711 . EB 1C jmp short CrackMe0.0040272F
00402713 > 0FBE843C 3901>movsx eax,byte ptr ss:[esp+edi+0x139] ; Case 53 ('S') of switch 004026B8
0040271B . 8D4C24 10 lea ecx,dword ptr ss:[esp+0x10]
0040271F . 83E8 30 sub eax,0x30
00402722 . 50 push eax
00402723 . E8 D8010000 call CrackMe0.00402900 ; e inc 18f1dc count 0-15 初始时18f1d8为0时进入
00402728 . EB 05 jmp short CrackMe0.0040272F
0040272A C64424 1C 01 mov byte ptr ss:[esp+0x1C],0x1 ; default 死亡之选
0040272F > 83C7 02 add edi,0x2
00402732 . 3BFE cmp edi,esi ; CrackMe0.0043E810
00402734 .^ 0F8C 76FFFFFF jl CrackMe0.004026B0
0040273A > 807C24 1C 01 cmp byte ptr ss:[esp+0x1C],0x1
0040273F . 74 33 je short CrackMe0.00402774
00402741 . 80BC24 240100>cmp byte ptr ss:[esp+0x124],0x0
00402749 . 74 15 je short CrackMe0.00402760
0040274B . 8A4C24 18 mov cl,byte ptr ss:[esp+0x18] ; 必须为 0x2F
0040274F . 8D8424 240100>lea eax,dword ptr ss:[esp+0x124]
00402756 > 3008 xor byte ptr ds:[eax],cl
00402758 . 8D40 01 lea eax,dword ptr ds:[eax+0x1]
0040275B . 8038 00 cmp byte ptr ds:[eax],0x0
0040275E .^ 75 F6 jnz short CrackMe0.00402756
00402760 > 6A 00 push 0x0 ; /Style = MB_OK|MB_APPLMODAL
00402762 . 6A 00 push 0x0 ; |Title = NULL
00402764 . 8D8424 2C0100>lea eax,dword ptr ss:[esp+0x12C] ; |
0040276B . 50 push eax ; |Text = 00000023 ???
0040276C . 6A 00 push 0x0 ; |hOwner = NULL
0040276E . FF15 ECE34200 call dword ptr ds:[<&USER32.MessageBoxA>] ; \MessageBoxA
00402774 > 8B8C24 5C0500>mov ecx,dword ptr ss:[esp+0x55C]
0040277B . 5F pop edi
0040277C . 5E pop esi ; CrackMe0.0043E810
0040277D . 5B pop ebx
0040277E . 33CC xor ecx,esp
00402780 . E8 83370100 call CrackMe0.00415F08
00402785 . 8BE5 mov esp,ebp
00402787 . 5D pop ebp
00402788 . C3 retn

AES解密之后的字串再进行base64解码,地址00401990 ,然后然后取字串奇数位,检查其值不能大于’S’,再然后根据其-0x32的值查跳转表,实现swich选择。其原值必须为82QS中的一个,不然就是进入default,这是一条死亡之路。
switch中的call循环做完之后,在0040273A 检查0018F1E4 是否为1,为1就game over。

再检查堆栈0018F2EC处字串是否为空,即第一个字符不为0x0,为0x0则直接弹出弹窗,没有有用信息。再下面就是对0018F2EC处字串与一定值异或,最后在弹窗中显示。

于是又进行了异或的爆破,结果很容易挑选:The flag is right!。参与运算的定值为0x2f。

那这个0x2f是哪来的呢,这就要说说4个case中的call了。依据奇数位字符选择switch case,其右边的偶数位字符-0x30,结果进行累加,最后累加值就是0x2f。

case中的call就不看了。看了也是各种混乱,明白程序意图后再看比较清晰。4个case call的作用有些类似,都是以偶数位减-0x30的值为循环次数控制,循环比较内存指点地址处的值是否为0,如果不是就OVER。如果我们定内存显示宽度为16字节,具体内存取数情况为:8,2保特横向位置不变,纵向分别随着循环向上一格和向下一格;Q,S保持纵向位置不变,横向分别向左一格和向右一格。这似乎像是矩阵的行列操作。我们再看下取数处的内存,调整下内存视图看就很明白。

maze

看到这张图就明白了吧,C3为终点,另一端为起点,只要顺着0走就不会错,只要跟到此处,不难发现第一个switch选择必须为2,其它的顺路走就OK。但是整完发现,路径虽没错,可是0x2f的累加值才到0x2e,还差1。再看看S的case call,与其余三个有点不同:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
00402923 |. 385C08 0E |cmp byte ptr ds:[eax+ecx+0xE],bl ; bl为0
00402927 |. 75 12 |jnz short CrackMe0.0040293B
00402929 |. 46 |inc esi
0040292A |. 8D42 01 |lea eax,dword ptr ds:[edx+0x1]
0040292D |. 8941 04 |mov dword ptr ds:[ecx+0x4],eax
00402930 |. 3BF7 |cmp esi,edi
00402932 |.^ 7C E1 \jl short CrackMe0.00402915
00402934 |. 5B pop ebx
00402935 |. 5F pop edi
00402936 |. 5E pop esi
00402937 |. 5D pop ebp
00402938 |. C2 0400 retn 0x4
0040293B |> 84DB test bl,bl
0040293D |. 75 13 jnz short CrackMe0.00402952
0040293F |. 8B01 mov eax,dword ptr ds:[ecx]
00402941 |. C1E0 04 shl eax,0x4
00402944 |. 0341 04 add eax,dword ptr ds:[ecx+0x4]
00402947 |. 807C08 0E FF cmp byte ptr ds:[eax+ecx+0xE],0xFF
0040294C |. 74 04 je short CrackMe0.00402952
0040294E |. C641 0C 01 mov byte ptr ds:[ecx+0xC],0x1
00402952 |> 5B pop ebx
00402953 |> 5F pop edi
00402954 |. 5E pop esi
00402955 |. 5D pop ebp
00402956 \. C2 0400 retn 0x4

在00402923处,就是比较取值是否为0的,别的call检查失败直接置标志返回,这里跳到了0040293B,检查取数是否为0xFF,如果是直接返回,不置失败标记。正好到终点处右边为0xff,且S循环一次是右移一格,取数,所以最后加上S1即可。

最后把取得数base64编码再AES加密就可得到flag。

路径选择结果为27S281S182S327S287S323Q124S281S1,共32字节,base64后是44字节,填充到48字节进行AES加密。不知道为什么答案会给出填充到64字节,不懂。

此题多解原因是如果偶数为0x30,则不进行循环,0x2f累加值也为零,对最后的正确流程没有影响。所以是可以随意附加”20”、”80”、”Q0”、’S0”,从而产生多解。
最后附上加密脚本:

1
2
3
4
5
6
7
8
9
10
11
from Crypto.Cipher import AES
key = 'B1nGzL[4st-TeAm]'
iv = '\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F'
path = '27S281S182S327S287S323Q124S281S1'.encode('base64').strip()
m = path +'\x00'*4
cryptor = AES.new(key,AES.MODE_CBC,iv)
cryptortext = cryptor.encrypt(m)
print '==================================================='
print 'cryptortext:'+cryptortext.encode('hex')
print '==================================================='

6 Reverse CrackMe03

试运行下,Console程序,输入错误直接退出。
直接AD载入,查找字串,发现input your key:,直接下断,运行,断下,发现程序主要流程全在这一个函数里。心中忽然有种轻松的感觉。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
00E9117C |. 68 505EEA00 push CrackMe0.00EA5E50 ; %32s
00E91181 |. E8 A1020000 call CrackMe0.00E91427 ; 输入
00E91186 |. 8D8C24 9C0600>lea ecx,dword ptr ss:[esp+0x69C] ; b1ngzl
00E9118D |. 83C4 08 add esp,0x8
00E91190 |. 8D51 01 lea edx,dword ptr ds:[ecx+0x1]
00E91193 |> 8A01 /mov al,byte ptr ds:[ecx] ; 计算b1ngzl长度
00E91195 |. 41 |inc ecx
00E91196 |. 84C0 |test al,al
00E91198 |.^ 75 F9 \jnz short CrackMe0.00E91193
00E9119A |. 2BCA sub ecx,edx
00E9119C |. 8DBC24 A00600>lea edi,dword ptr ss:[esp+0x6A0]
00E911A3 |. 894C24 10 mov dword ptr ss:[esp+0x10],ecx
00E911A7 |. 8D57 01 lea edx,dword ptr ds:[edi+0x1] ; 取存放输入的地址
00E911AA |. 8D9B 00000000 lea ebx,dword ptr ds:[ebx]
00E911B0 |> 8A07 /mov al,byte ptr ds:[edi] ; 计算输入长度
00E911B2 |. 47 |inc edi
00E911B3 |. 84C0 |test al,al
00E911B5 |.^ 75 F9 \jnz short CrackMe0.00E911B0
00E911B7 |. 2BFA sub edi,edx
00E911B9 |. 897C24 14 mov dword ptr ss:[esp+0x14],edi
00E911BD |. 60 pushad
00E911BE |. 9C pushfd
00E911BF |. 8F4424 58 pop dword ptr ss:[esp+0x58] ; 初始化空间
00E911C3 |. 8F4424 50 pop dword ptr ss:[esp+0x50]
00E911C7 |. 8F4424 48 pop dword ptr ss:[esp+0x48]
00E911CB |. 8F4424 40 pop dword ptr ss:[esp+0x40]
00E911CF |. 8F4424 38 pop dword ptr ss:[esp+0x38]
00E911D3 |. 8F4424 30 pop dword ptr ss:[esp+0x30] ; CrackMe0.<ModuleEntryPoint>
00E911D7 |. 8F4424 28 pop dword ptr ss:[esp+0x28]
00E911DB |. 8F4424 20 pop dword ptr ss:[esp+0x20]
00E911DF |. 8F4424 18 pop dword ptr ss:[esp+0x18]
00E911E3 |. C74424 28 140>mov dword ptr ss:[esp+0x28],0x14
00E911EB |. FF7424 10 push dword ptr ss:[esp+0x10]
00E911EF |. FF7424 18 push dword ptr ss:[esp+0x18]
00E911F3 |. 8F4424 28 pop dword ptr ss:[esp+0x28]
00E911F7 |. 8F4424 20 pop dword ptr ss:[esp+0x20]
00E911FB |. 83F1 04 xor ecx,0x4 ; b1ngzl长度 6xor4 =-4
00E911FE |. 83F7 04 xor edi,0x4 ; 输入长度xor4
00E91201 |. 897C24 14 mov dword ptr ss:[esp+0x14],edi
00E91205 |. 8D41 FC lea eax,dword ptr ds:[ecx-0x4] ; 从此处开始的6句没必要存在
00E91208 |. 83F8 03 cmp eax,0x3
00E9120B |. 77 10 ja short CrackMe0.00E9121D
00E9120D |. 8D47 FC lea eax,dword ptr ds:[edi-0x4]
00E91210 |. 83F8 03 cmp eax,0x3
00E91213 |. 77 08 ja short CrackMe0.00E9121D
00E91215 |. 83CE FF or esi,-0x1
00E91218 |. E9 B8010000 jmp CrackMe0.00E913D5
00E9121D |> 8D4C24 3C lea ecx,dword ptr ss:[esp+0x3C]
00E91221 |. E8 FAFDFFFF call CrackMe0.00E91020 ; 用0xFEFEFEFE、0xEFEFEFEF、0xFFEEFFEE填充esp+0x3c地址4*5*81个字节
00E91226 |. 837C24 20 00 cmp dword ptr ss:[esp+0x20],0x0
00E9122B |. 7E 5F jle short CrackMe0.00E9128C
00E9122D |. 33FF xor edi,edi
00E9122F |. 90 nop
00E91230 |> 0FBEB43C 9406>/movsx esi,byte ptr ss:[esp+edi+0x694] ; 处理b1ngzl记byte为c c1=esi=c&0xf c2=ecx=c>>4&0xf
00E91238 |. 8BCE |mov ecx,esi ; c1为低四位 c2为高4位
00E9123A |. 83E6 0F |and esi,0xF
00E9123D |. C1F9 04 |sar ecx,0x4
00E91240 |. 83E1 0F |and ecx,0xF
00E91243 |. 83F9 09 |cmp ecx,0x9
00E91246 |. 76 0E |jbe short CrackMe0.00E91256 ; c2大于9要进行处理 -9
00E91248 |. B8 398EE338 |mov eax,0x38E38E39
00E9124D |. F7E1 |mul ecx
00E9124F |. D1EA |shr edx,1
00E91251 |. 6BC2 F7 |imul eax,edx,-0x9
00E91254 |. 03C8 |add ecx,eax
00E91256 |> 83FE 09 |cmp esi,0x9
00E91259 |. 76 0E |jbe short CrackMe0.00E91269 ; c1大于9要进行处理 -9
00E9125B |. B8 398EE338 |mov eax,0x38E38E39
00E91260 |. F7E6 |mul esi ; CrackMe0.<ModuleEntryPoint>
00E91262 |. D1EA |shr edx,1
00E91264 |. 6BC2 F7 |imul eax,edx,-0x9
00E91267 |. 03F0 |add esi,eax
00E91269 |> 8D04CE |lea eax,dword ptr ds:[esi+ecx*8] ; eax=c1+8*c2
00E9126C |. 894C24 30 |mov dword ptr ss:[esp+0x30],ecx ; c2
00E91270 |. 03C1 |add eax,ecx ; eax+c2 =c1+9*c2
00E91272 |. 897424 34 |mov dword ptr ss:[esp+0x34],esi ; c1
00E91276 |. 47 |inc edi
00E91277 |. 8D0480 |lea eax,dword ptr ds:[eax+eax*4] ; 5*(c1+9*c2)
00E9127A |. C74484 3C FFE>|mov dword ptr ss:[esp+eax*4+0x3C],0xEEFFEEFF ; 偏移为4*5*(c1+9*c2)+0x3c
00E91282 |. 3B7C24 20 |cmp edi,dword ptr ss:[esp+0x20] ; 循环6次
00E91286 |.^ 7C A8 \jl short CrackMe0.00E91230

输入完成后,计算常量b1ngzl的长度,再计算输入长度,接着初始化一段栈空间,前面计算的两个长度xor 4。接着在00E91221调用call 00E91020(这个程序主流程很明晰,所以没关掉动态基址,见谅,后四位偏移应该是一样的),在内存中填充一大组数据,填充规则是写入5*9*9个dword,进行了9*9 81个循环,每次循环按规则写入5个dword,第一个dword始终填充0xFFEEFFEE,第二个dword在前9次循环填充0xEFEFEFEF,其它填充0xFEFEFEFE,第三个dword全部填充用0xFEFEFEFE,第四个dword在循环次数为9倍数+1(第一次也算)时填充0xEFEFEFEF,其它填充0xFEFEFEFE 。

然后按b1ngzl换算的偏移地址填充0xEEFFEEFF,共计填充6次,填充地址为00E91221处call操作的内存区域。

可以看下这个偏移计算4*5*(c1+9*c2)+0x3c,0x3c为指向刚才填充区域相对栈指针的偏移量,4是dword 4字节对齐,那5*(c1+9*c2)与前面5*9*9相对应的话,那9*c2就是纵坐标了,c1就是横坐标了。其实到这里已经很明显了,5*9*9实际上就是5个9*9的二维数组,这6次循环填充是操作第一个9*9数组。

大家也应该注意到00E9124600E91259的注释,这里做了处理防止数组越界。0x00–0xff,最终都会落在(9,9)范围内。处理过程中,比较第一个字符b,即0x62,那就在第一个数组a1[6][2]处填充0xEEFFEEFF。如果记5个数组分别为a1,a2,a3,a4,a5,0xFFEEFFEE为0,0xEEFFEEFF为1,0xEFEFEFEF为2,0xFEFEFEFE为3,则现在5个数组情况如下(实际上就是个矩阵嘛):

1
2
3
4
5
6
7
8
9
10
a1:
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 1 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 1 1 0 1 0 1 0
0 1 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
1
2
3
4
5
6
7
8
9
10
a2:
3 3 3 3 3 3 3 3 3
2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2
1
2
3
4
5
6
7
8
9
10
a3:
2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2
1
2
3
4
5
6
7
8
9
10
a4:
3 2 2 2 2 2 2 2 2
3 2 2 2 2 2 2 2 2
3 2 2 2 2 2 2 2 2
3 2 2 2 2 2 2 2 2
3 2 2 2 2 2 2 2 2
3 2 2 2 2 2 2 2 2
3 2 2 2 2 2 2 2 2
3 2 2 2 2 2 2 2 2
3 2 2 2 2 2 2 2 2
1
2
3
4
5
6
7
8
9
10
a5:
2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2

我们再接着往下看。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
00E91288 |. 8B7C24 14 mov edi,dword ptr ss:[esp+0x14] ; 输入长度xor 4的值
00E9128C |> 33C0 xor eax,eax
00E9128E |. 894424 10 mov dword ptr ss:[esp+0x10],eax
00E91292 |. 85FF test edi,edi
00E91294 |. 0F8E C0000000 jle CrackMe0.00E9135A
00E9129A |. 8D9B 00000000 lea ebx,dword ptr ds:[ebx]
00E912A0 |> 8A8404 A00600>/mov al,byte ptr ss:[esp+eax+0x6A0] ; 开始处理输入
00E912A7 |. 0FBEF0 |movsx esi,al
00E912AA |. 8BCE |mov ecx,esi ; CrackMe0.<ModuleEntryPoint>
00E912AC |. 83E6 0F |and esi,0xF
00E912AF |. C1F9 04 |sar ecx,0x4
00E912B2 |. 83E1 0F |and ecx,0xF
00E912B5 |. 83F9 09 |cmp ecx,0x9
00E912B8 |. 76 0E |jbe short CrackMe0.00E912C8
00E912BA |. B8 398EE338 |mov eax,0x38E38E39
00E912BF |. F7E1 |mul ecx
00E912C1 |. D1EA |shr edx,1
00E912C3 |. 6BC2 F7 |imul eax,edx,-0x9
00E912C6 |. 03C8 |add ecx,eax
00E912C8 |> 83FE 09 |cmp esi,0x9
00E912CB |. 76 0E |jbe short CrackMe0.00E912DB
00E912CD |. B8 398EE338 |mov eax,0x38E38E39
00E912D2 |. F7E6 |mul esi ; CrackMe0.<ModuleEntryPoint>
00E912D4 |. D1EA |shr edx,1
00E912D6 |. 6BC2 F7 |imul eax,edx,-0x9
00E912D9 |. 03F0 |add esi,eax
00E912DB |> 8D14CE |lea edx,dword ptr ds:[esi+ecx*8]
00E912DE |. 03D1 |add edx,ecx
00E912E0 |. 8D0C92 |lea ecx,dword ptr ds:[edx+edx*4]
00E912E3 |. 817C8C 40 FEF>|cmp dword ptr ss:[esp+ecx*4+0x40],0xFEFEFEFE ; off ecx*4+0x4
00E912EB |. 74 0B |je short CrackMe0.00E912F8
00E912ED |. 8D0492 |lea eax,dword ptr ds:[edx+edx*4]
00E912F0 |. 817484 88 111>|xor dword ptr ss:[esp+eax*4-0x78],0x11111111 ; off ecx*4-0xb4
00E912F8 |> 817C8C 44 FEF>|cmp dword ptr ss:[esp+ecx*4+0x44],0xFEFEFEFE ; off ecx*4+8 0xEEFFEEFF^0xFFEEFFEE=0x11111111
00E91300 |. 74 13 |je short CrackMe0.00E91315
00E91302 |. 8D0492 |lea eax,dword ptr ds:[edx+edx*4]
00E91305 |. 8B4484 88 |mov eax,dword ptr ss:[esp+eax*4-0x78]
00E91309 |. 35 11111111 |xor eax,0x11111111
00E9130E |. 89848C F00000>|mov dword ptr ss:[esp+ecx*4+0xF0],eax ; off ecx*4+0xb4
00E91315 |> 817C8C 48 FEF>|cmp dword ptr ss:[esp+ecx*4+0x48],0xFEFEFEFE ; off ecx*4+0xc
00E9131D |. 74 10 |je short CrackMe0.00E9132F
00E9131F |. 8D0492 |lea eax,dword ptr ds:[edx+edx*4]
00E91322 |. 8B4484 88 |mov eax,dword ptr ss:[esp+eax*4-0x78]
00E91326 |. 35 11111111 |xor eax,0x11111111
00E9132B |. 89448C 28 |mov dword ptr ss:[esp+ecx*4+0x28],eax ; off ecx*4-0x14
00E9132F |> 817C8C 4C FEF>|cmp dword ptr ss:[esp+ecx*4+0x4C],0xFEFEFEFE ; off ecx*4+0x10
00E91337 |. 74 10 |je short CrackMe0.00E91349
00E91339 |. 8D0492 |lea eax,dword ptr ds:[edx+edx*4]
00E9133C |. 8B4484 88 |mov eax,dword ptr ss:[esp+eax*4-0x78]
00E91340 |. 35 11111111 |xor eax,0x11111111
00E91345 |. 89448C 50 |mov dword ptr ss:[esp+ecx*4+0x50],eax ; off ecx*4+14
00E91349 |> 8B4424 10 |mov eax,dword ptr ss:[esp+0x10]
00E9134D |. 40 |inc eax
00E9134E |. 894424 10 |mov dword ptr ss:[esp+0x10],eax
00E91352 |. 3BC7 |cmp eax,edi
00E91354 |.^ 0F8C 46FFFFFF \jl CrackMe0.00E912A0
00E9135A |> 8D8424 C80000>lea eax,dword ptr ss:[esp+0xC8]
00E91361 |. BA 09000000 mov edx,0x9
00E91366 |. 33F6 xor esi,esi ; CrackMe0.<ModuleEntryPoint>
00E91368 |. EB 06 jmp short CrackMe0.00E91370
00E9136A | 8D9B 00000000 lea ebx,dword ptr ds:[ebx]
00E91370 |> 8B88 74FFFFFF /mov ecx,dword ptr ds:[eax-0x8C]
00E91376 |. 8D80 B4000000 |lea eax,dword ptr ds:[eax+0xB4]
00E9137C |. 0388 D4FEFFFF |add ecx,dword ptr ds:[eax-0x12C]
00E91382 |. 0388 E8FEFFFF |add ecx,dword ptr ds:[eax-0x118]
00E91388 |. 0388 FCFEFFFF |add ecx,dword ptr ds:[eax-0x104]
00E9138E |. 0388 10FFFFFF |add ecx,dword ptr ds:[eax-0xF0]
00E91394 |. 0388 24FFFFFF |add ecx,dword ptr ds:[eax-0xDC]
00E9139A |. 0388 38FFFFFF |add ecx,dword ptr ds:[eax-0xC8]
00E913A0 |. 0388 60FFFFFF |add ecx,dword ptr ds:[eax-0xA0]
00E913A6 |. 0388 4CFFFFFF |add ecx,dword ptr ds:[eax-0xB4]
00E913AC |. 03F1 |add esi,ecx
00E913AE |. 4A |dec edx
00E913AF |.^ 75 BF \jnz short CrackMe0.00E91370
00E913B1 |. 81FE 4DFC9CFC cmp esi,0xFC9CFC4D
00E913B7 |. 75 1A jnz short CrackMe0.00E913D3 ; 不能跳
00E913B9 |. 68 585EEA00 push CrackMe0.00EA5E58 ; This Flag is right!\r\n
00E913BE |. E8 DB020000 call CrackMe0.00E9169E
00E913C3 |. 83C4 04 add esp,0x4
00E913C6 |. 68 705EEA00 push CrackMe0.00EA5E70 ; pause
00E913CB |. E8 C4010000 call CrackMe0.00E91594

开始先是一个输入处理的循环,前半部分和上一段的代码一样,就是根据输入的字符定位数组元素位置,这里注意下,循环次数为输入长度与4异或的值。

再看下面的数据操作。在00E912E3、00E912F8、00E91315、00E9132F处的比较,实际上是分别是后面四个数组相应坐标的元素与定值比较。

ecx就是数组坐标,上面已经说过了。*4是dword 4字节对齐,如果不考虑对齐 ecx*4+4实际上就是ecx+1,ecx是定位a1[x][y],那ecx+1就是a2[x][y],因为数据存放是5*9*9,81个循环每次写入5组数据,上面已经提前伏笔了。所以00E912A000E91354就是循环根据输入字符0xHL(H表示高4位数值,L表示低4位数值),检查a2[H][L]a3[H][L]a4[H][L]a5[H][L]处的值是否为0xFEFEFEFE,即上面数组中的3,如果不是,则将a1相应位置的值进行异或。

再看看这5个异或都操作a1的什么位置。ecx*4-0xb4去除字节对齐干扰除以4,就是ecx-0x2d,后面的0x2d十进制是45,排除其它四个数组干扰除以5就是9,也就是a1[H][L]-9,换成数组坐标是a1[H-1][L],其它三个分别是a1[H+1][L]a1[H][L-1]a1[H][L+1],从图上看是a1[H][L]的上下左右,分别使用a2[H][L]a3[H][L]a4[H][L]a5[H][L]元素作改写开关。具体操作内容是a1[H-1][L]与0x11111111异或,在数组a1里实际上就是0,1翻转,而其余三个位置则是翻转a1[H-1][L]的值。而比较检查,可以对照上面后四个数组的情况,很容易就看出来当a1[H][L]落在第一行时,a1[H-1][L]是不操作的,因为越界了;a1[H][L]落在第一列时a1[H][L-1]是不操作的。这个我就看不懂了,为什么不相应检查落在最右侧的情况,所以如果落在最右侧,那操作a1[H][L+1]变成操作a1[H+1][0]。最下侧就没有必要检查了,因为我们输入的字符到不了那里,同样顶端的检测也是没有必要的,因为我们的输入也定位不到那。

00E9135A到00E913B7就是将第一个数组中的数值按dword相加,所以溢出是不管的,总和与0xFC9CFC4D比较,为真则提示This Flag is right!

按照这个条件,我们很容易就能把第一个数组中的0xEEFFEEFF和0xFFEEFFEE的个数算出来。来个小爆破吧。

1
2
3
4
5
6
7
8
a1 = 0xEEFFEEFF
a2 = 0xFFEEFFEE
sum = 0
for i in range(82):
sum = (a1*i+a2*(81-i))&0xFFFFFFFF
if sum == 0xFC9CFC4D:
print '0xEEFFEEFF real count:',i
return i

结果是唯一的,0xEEFFEEFF的个数是15。所以只要保证经过输入处理后,a1中1的数目为15就成功。我们看看输入之前a1的情况已经在上面列出。输入的处理仔细想下,其实如果a1[H][L]不落在最右侧,那4个检查条件是不受影响的,那每次操作数值翻转是1:3的关系,输入处理之前已经有了6个1,再来9个1就行。如果a1[H][L]的上下左右都为0,那在此位置进行两次翻转,其结果就是:

1
2
3
x 0 x
1 x 1
x 1 x

来三次就ok了。

9*9的空间很大,很容易就可以找到很多3个翻转结果0 1为1:3关系。但是,但是,但是啊,这是6次循环,循环次数为输入字符长度xor 4。6 xor 4 =2。那后4次取值就越界了。所以我们要找到输入长度xor 4后小于输入长度,并且异或后结果为偶数的。为什么要是偶数,自己想吧,该说的我已经全说了啊。又是脚本小跑下,找了两个比较小的数12,14,异或后值为8,10。当然这些不是必要条件,只是其中一种比较简单的解法而已。比如:

4477vvvv1234

12位输入,8次循环操作,如果定位点上方为0,每两次同位置的操作翻转结果0 1为1:3关系。三个位置就是9个1,注意不要影响到开始的6个1,所以是15个1,完全符合条件。后面4位根本不参加运算,所以随便填。两个地方都可以多解,数量非常巨大的多解。

上面一段说的偶数啊、同位置操作两次啊,这些是为了最简单寻找答案,看下面这些也行

4477T1111111
uJKK111123=1234

为了这个题,我把算法都还原了,反正已经写了,贴出来给大家看看。把各部分写成了函数调用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
def cal_num(): #爆0xEEFFEEFF个数
a1 = 0xEEFFEEFF
a2 = 0xFFEEFFEE
sum = 0
for i in range(82):
sum = (a1*i+a2*(81-i))&0xFFFFFFFF
if sum == 0xFC9CFC4D:
print '0xEEFFEEFF real count:',i
return i
def create_table(): #5*9*9初始列表
l = []
for i in range(9):
for j in xrange(9):
l.append(0xFFEEFFEE)
if i == 0:
l.append(0xFEFEFEFE)
else:
l.append(0xEFEFEFEF)
l.append( 0xEFEFEFEF)
if j == 0:
l.append(0xFEFEFEFE)
else:
l.append(0xEFEFEFEF)
l.append( 0xEFEFEFEF)
print '0xFEFEFEFE Pos:',
indx = 0
for i in range(l.count(0xFEFEFEFE)):
indx = l.index(0xFEFEFEFE,indx)
print indx,
indx +=1
print '\n'
return l
def hl(s): #坐标
bh = (s>>4&0xf)%9
bl = (s&0xf)%9
return 5*(bh*9+bl)
def cal_1(table): #a1 初次循环改写
b = 'b1ngzl'
off_b = []
for i in range(len(b)):
inx = hl(ord(b[i]))
off_b.append(inx)
table[inx] = 0xEEFFEEFF
print '0xEEFFEEFF Pos:',off_b
def cal_2(table,str,num): #使用str改写a1
count = len(str)
for i in range(count):
idx = hl(int(str[i]))
if table[idx+1] != 0xFEFEFEFE:
table[idx-45] = table[idx-45]^0x11111111
if table[idx+2] != 0xFEFEFEFE:
table[idx+45] = table[idx-45]^0x11111111
if table[idx+3] != 0xFEFEFEFE:
table[idx-5] = table[idx-45]^0x11111111
if table[idx+4] != 0xFEFEFEFE:
table[idx+5] = table[idx-45]^0x11111111
if table.count(0xEEFFEEFF) == num: #为15,cal_num()计算结果
print "The flag is right!"
else:
print "Wrong!!!"
if __name__ == '__main__':
num = cal_num()
table_l = create_table()
cal_1(table_l)
flag = raw_input('input the flag:')
count = len(flag) ^ 4
cal_2(table_l,list(flag[:count]),num)

不对之处,请多多指教。

×

纯属好玩

扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

文章目录
  1. 1. 1 Misc XX
  2. 2. 2 Misc 贝丝家族
  3. 3. 3 Misc 敲击
  4. 4. 4 Reverse CrackMe01
  5. 5. 5 Reverse CrackMe02
  6. 6. 6 Reverse CrackMe03
,