-
-
[原创]看雪2016 第四题 CrackMe逆向分析
-
发表于: 2016-11-9 16:46 2717
-
OD加载crackme,Ctrl+N 查找GetDlgItemTextA来到
00401474 |. 68 00020000 push 200 ; /Count = 200 (512.)
00401479 |. 8D85 FCFDFFFF lea eax, dword ptr [ebp-204] ; |
0040147F |. 50 push eax ; |Buffer
00401480 |. 68 E8030000 push 3E8 ; |ControlID = 3E8 (1000.)
00401485 |. 56 push esi ; |hWnd
00401486 |. FF15 04D14000 call dword ptr [<&USER32.GetDlgItemTe>; \GetDlgItemTextA
0040148C |. 83F8 1E cmp eax, 1E
0040148F |. 75 25 jnz short 004014B6
00401491 |. 8BD0 mov edx, eax
00401493 |. 8D8D FCFDFFFF lea ecx, dword ptr [ebp-204]
00401499 |. E8 62FBFFFF call 00401000
0040149E |. 83F8 01 cmp eax, 1
004014A1 |. 75 13 jnz short 004014B6
004014A3 |. 6A 00 push 0 ; /Style = MB_OK|MB_APPLMODAL
004014A5 |. 68 80374100 push 00413780 ; |Title = "information"
004014AA |. 68 8C374100 push 0041378C ; |Text = ""D7,"",A2,"",B2,"岢晒",A6,""
004014AF |. 56 push esi ; |hOwner
004014B0 |. FF15 00D14000 call dword ptr [<&USER32.MessageBoxA>>; \MessageBoxA
004014B6 |> 8B4D FC mov ecx, dword ptr [ebp-4] ; Default case of switch 0040143A
明显 00401499 |. E8 62FBFFFF call 00401000 为注册函数,且返回1表示成功。
继续分析发现
0042FCD9 F7D3 not ebx
0042FCDB 4B dec ebx
0042FCDC 66:F7D3 not bx
0042FCDF 66:81EB D165 sub bx, 65D1
0042FCE4 0FB646 FF movzx eax, byte ptr [esi-1]
0042FCE8 4E dec esi
0042FCE9 2AC3 sub al, bl
0042FCEB F6D0 not al
0042FCED 04 57 add al, 57
0042FCEF FEC8 dec al
0042FCF1 2C 3E sub al, 3E
0042FCF3 FF3485 DDF84200 push dword ptr [eax*4+42F8DD]
0042FCFA C3 retn
这个是vm_loop 作者使用了虚拟机。好吧,这里先不分析了。
对输入内容下硬件断点,来到 MD5
004014F0 /$ 55 push ebp ; md5_update
004014F1 |. 8BEC mov ebp, esp
004014F3 |. 83EC 0C sub esp, 0C
004014F6 |. 53 push ebx
004014F7 |. 8B5D 08 mov ebx, dword ptr [ebp+8]
004014FA |. 56 push esi
004014FB |. 57 push edi
PEID工具也可确认是MD5
MD5 :: 00000B37 :: 00401737
The reference is above.
SHA-512/384 [mixing] :: 00010198 :: 00411998
The reference is above.
I1 =
0019F6A0 32 32 32 32 32 32 32 00 00 00 00 00 00 00 00 00 2222222.........
输入数据为 前7个字符
通过vm_loop 找到handler表
0042F8DD 70 4A ED 20 AA F1 42 00 BD F1 42 00 D6 F1 42 00 pJ?B.今B.竹B.
0042F8ED 06 F2 42 00 31 F2 42 00 5C F2 42 00 7F F2 42 00 駼.1駼.\駼.駼.
0042F8FD A2 F2 42 00 BE F2 42 00 E5 F2 42 00 FE F2 42 00 ⅡB.掘B.弪B.B.
0042F90D 16 F3 42 00 3C F3 42 00 54 F3 42 00 7A F3 42 00 驜.<驜.T驜.z驜.
0042F91D A3 F3 42 00 CF F3 42 00 00 F4 42 00 34 F4 42 00 sB.象B..鬊.4鬊.
0042F92D 41 F4 42 00 72 F4 42 00 85 F4 42 00 A2 F4 42 00 A鬊.r鬊.咊B.ⅣB.
0042F93D BA F4 42 00 DE F4 42 00 F6 F4 42 00 1C F5 42 00 呼B.摁B.鲷B.魾.
0042F94D 4A F5 42 00 63 F5 42 00 88 F5 42 00 AD F5 42 00 J魾.c魾.堳B.B.
0042F95D C5 F5 42 00 DC F5 42 00 01 F6 42 00 23 F6 42 00 捧B.荃B.鯞.#鯞.
依次查看可找到 vm_exit
0042F76F 8BE5 mov esp, ebp ; vm_exit
0042F771 5F pop edi
0042F772 5E pop esi
0042F773 5D pop ebp
0042F774 5B pop ebx
0042F775 5A pop edx
0042F776 59 pop ecx
0042F777 58 pop eax
0042F778 9D popfd
0042F779 C3 retn
几次断点后来到
0040115E 8B8D 2CFCFFFF mov ecx, dword ptr [ebp-3D4]
00401164 8B41 17 mov eax, dword ptr [ecx+17]
00401167 0F1041 07 movups xmm0, dqword ptr [ecx+7]
0040116B 8945 E0 mov dword ptr [ebp-20], eax
0040116E 0FB741 1B movzx eax, word ptr [ecx+1B]
00401172 66:8945 E4 mov word ptr [ebp-1C], ax
00401176 0FB641 1D movzx eax, byte ptr [ecx+1D]
0040117A 33C9 xor ecx, ecx
0040117C 0F1145 D0 movups dqword ptr [ebp-30], xmm0
00401180 8845 E6 mov byte ptr [ebp-1A], al
00401183 8A440D D0 mov al, byte ptr [ebp+ecx-30]
00401187 32840D 14FCFF>xor al, byte ptr [ebp+ecx-3EC]
0040118E 88840D E8FBFF>mov byte ptr [ebp+ecx-418], al
00401195 83F9 17 cmp ecx, 17
00401198 0F83 68020000 jnb 00401406
0040119E C6440D D0 00 mov byte ptr [ebp+ecx-30], 0
004011A3 C6840D 14FCFF>mov byte ptr [ebp+ecx-3EC], 0
004011AB 41 inc ecx
004011AC 83F9 17 cmp ecx, 17
004011AF ^ 7C D2 jl short 00401183
发现这里是
I2=
0019F6E0 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 2222222222222222
0019F6F0 32 32 32 32 32 32 32 2222222
y2=
0019F324 44 AD 5C CC 12 90 73 8D 47 81 E3 89 84 9C DF F9 D璡?恠岹併墑溸?
0019F334 47 6A B6 9E 11 30 27 Gj稙0'.
I2= I2^y2 对输入进行异或操作。
004011C0 8A840D 90FDFF>mov al, byte ptr [ebp+ecx-270]
004011C7 32840D E8FBFF>xor al, byte ptr [ebp+ecx-418]
004011CE 88440D D0 mov byte ptr [ebp+ecx-30], al
004011D2 83F9 17 cmp ecx, 17
004011D5 0F83 2B020000 jnb 00401406
004011DB C6840D E8FBFF>mov byte ptr [ebp+ecx-418], 0
004011E3 C6840D 90FDFF>mov byte ptr [ebp+ecx-270], 0
004011EB 41 inc ecx
004011EC 83F9 17 cmp ecx, 17
004011EF ^ 7C CF jl short 004011C0
y1 = MD5(I1)^I2
0019F4A0 79 D8 86 01 01 86 EB 60 E3 61 1C D4 A5 D0 BC AE y貑嗠`鉧豫屑?
0019F4B0 79 D8 86 01 01 86 EB y貑嗠..
上面是 I2与MD5后的结果异或。为了达到23字节所以循环取值了一下。
004011F1 B9 40000000 mov ecx, 40
004011F6 8DBD 90FCFFFF lea edi, dword ptr [ebp-370]
004011FC BE 98374100 mov esi, 00413798
00401201 33C0 xor eax, eax
00401203 F3:A5 rep movs dword ptr es:[edi], dword ptr [esi]
00401205 B9 40000000 mov ecx, 40
0040120A 8985 30FCFFFF mov dword ptr [ebp-3D0], eax
00401210 BE 98384100 mov esi, 00413898
00401215 8DBD 90FEFFFF lea edi, dword ptr [ebp-170]
0040121B F3:A5 rep movs dword ptr es:[edi], dword ptr [esi]
0040121D 33C9 xor ecx, ecx
复制 2个 256字节的数据,通过下面的分析 这里应该是迷宫(16X16 )数据(被加密的)分别记t1和t2
0040121F 898D 2CFCFFFF mov dword ptr [ebp-3D4], ecx
00401225 > 8A4C0D D0 mov cl, byte ptr [ebp+ecx-30]
00401229 . 0FB6C9 movzx ecx, cl
0040122C . C785 0CFCFFFF>mov dword ptr [ebp-3F4], 6
00401236 . 898D 00FCFFFF mov dword ptr [ebp-400], ecx
0040123C 0F1F4000 dd crackme.00401F0F
00401240 > 8BD1 mov edx, ecx
00401242 . 8985 10FCFFFF mov dword ptr [ebp-3F0], eax
00401248 . 8A8D 0CFCFFFF mov cl, byte ptr [ebp-3F4] ; cl == 6
0040124E . D3EA shr edx, cl
00401250 . 83E2 03 and edx, 3
00401253 . FF2495 0C1440>jmp dword ptr [edx*4+40140C] ; jmp[y&0x03]??
0040125A > 83E8 10 sub eax, 10
0040125D . EB 09 jmp short 00401268
0040125F > 40 inc eax
00401260 . EB 06 jmp short 00401268
00401262 > 83C0 10 add eax, 10
00401265 . EB 01 jmp short 00401268
00401267 > 48 dec eax
00401268 > 8985 30FCFFFF mov dword ptr [ebp-3D0], eax
这里应该是计算走迷宫的步骤,每2bit代表一个方向
eax = 0
0=eax-10
1=eax+1
2=eax+10
3=eax-1
00401283 . 25 0F000080 and eax, 8000000F
00401288 . 79 05 jns short 0040128F
0040128A . 48 dec eax ; <0
0040128B . 83C8 F0 or eax, FFFFFFF0
0040128E . 40 inc eax
0040128F > 8985 04FCFFFF mov dword ptr [ebp-3FC], eax
00401295 .- E9 DBB10300 jmp 0043C475
这里进虚拟机,先不管他
退出虚拟机后来到这里
004012B5 ? 8B8D 08FCFFFF mov ecx, dword ptr [ebp-3F8]
004012BB ? 8D95 90FEFFFF lea edx, dword ptr [ebp-170]
004012C1 ? 8B85 04FCFFFF mov eax, dword ptr [ebp-3FC]
004012C7 ? C1E1 04 shl ecx, 4
004012CA . 03C1 add eax, ecx
004012CC . 03D0 add edx, eax
004012CE > 8995 04FCFFFF mov dword ptr [ebp-3FC], edx
004012D4 . 8A8C05 90FCFF>mov cl, byte ptr [ebp+eax-370]
004012DB . 8AC1 mov al, cl
004012DD . 888D 37FCFFFF mov byte ptr [ebp-3C9], cl
004012E3 . C0C8 02 ror al, 2
004012E6 . 0FB6C8 movzx ecx, al
004012E9 . 0FB602 movzx eax, byte ptr [edx]
004012EC . 33C8 xor ecx, eax
004012EE . 83F9 30 cmp ecx, 30
004012F1 . 0F84 E2000000 je 004013D9
004012F7 . 83F9 20 cmp ecx, 20
004012FA . 0F84 D9000000 je 004013D9
00401300 . 83F9 58 cmp ecx, 58
00401303 . 0F84 E5000000 je 004013EE
上面是走迷宫的算法,包含迷宫解密算法如下:
t3[i] = ror(t1[i], 2) xor t2[i]
0x00CFF878 43 30 30 30 30 31 31 31 31 31 31 31 31 30 30 30 C000011111111000
0x00CFF888 31 30 30 30 30 31 30 30 30 30 30 30 31 30 30 30 1000010000001000
0x00CFF898 31 30 30 30 30 31 30 31 31 31 31 31 31 30 30 30 1000010111111000
0x00CFF8A8 31 31 31 31 30 31 30 31 30 30 30 30 30 30 30 30 1111010100000000
0x00CFF8B8 30 30 30 31 30 31 30 31 31 31 31 31 31 31 31 30 0001010111111110
0x00CFF8C8 30 30 30 31 30 31 30 30 30 30 30 30 30 30 31 30 0001010000000010
0x00CFF8D8 30 31 31 31 30 31 30 30 30 30 30 30 30 30 31 30 0111010000000010
0x00CFF8E8 30 31 30 30 30 31 30 31 31 31 30 30 30 30 31 30 0100010111000010
0x00CFF8F8 30 31 30 30 30 31 30 31 30 31 30 30 30 30 31 30 0100010101000010
0x00CFF908 30 31 30 30 30 31 30 31 30 31 30 30 30 30 31 30 0100010101000010
0x00CFF918 30 31 30 30 30 31 31 31 30 31 30 30 30 30 31 30 0100011101000010
0x00CFF928 30 31 30 30 30 30 30 30 30 31 30 30 30 30 31 30 0100000001000010
0x00CFF938 30 31 30 30 30 30 30 30 30 31 30 31 31 31 31 30 0100000001011110
0x00CFF948 30 31 31 31 31 31 31 31 30 31 30 31 30 30 30 30 0111111101010000
0x00CFF958 30 30 30 30 30 30 30 31 30 31 30 31 30 30 30 30 0000000101010000
0x00CFF968 30 30 30 30 30 30 30 31 31 31 30 31 31 58 30 30 0000000111011X00
这句是关键 00401300 . 83F9 58 cmp ecx, 58
也就是迷宫出口,30或20 表示出错(迷宫没走对)
写程序计算走法
输出为:
x1=
A9 5A BE AA A5 55 A5 00 00 FA BC 00 00 15 55 AF FE 95 55 AA AA FE A5
至此可得出公式
I2 = MD5(I1)^x1^y2;
由于I1和I2未知,所以需要枚举一下,条件是 I1和I2必须为可见字符,程序如下:
输出如下:
sn=033a5449NE6t,iMft0mVbhJmFDdx'=
sn=0c1e344e9]%GH`"@cgE$o.811\wKC4
sn=10f3797.;Q <?n+URr@:}D)z3Pr04:
sn=15701ad;LYskzk(5Zv2"Z9NoDX!gq?
sn=1ddb354cZ,66,{~2?qAS*VJ7R-d:'/
sn=377bca1$Jn7,jj{t-):Wjk~pBoe a>
sn=3ae70c1jnLmECpHr*WLGU(S>fM?IH$
sn=7ab0f24je685qmF4Vo:v\~c>m7j9z9
sn=8187e32jMQe 4ugy YUxED1>EP7,?!
00401474 |. 68 00020000 push 200 ; /Count = 200 (512.)
00401479 |. 8D85 FCFDFFFF lea eax, dword ptr [ebp-204] ; |
0040147F |. 50 push eax ; |Buffer
00401480 |. 68 E8030000 push 3E8 ; |ControlID = 3E8 (1000.)
00401485 |. 56 push esi ; |hWnd
00401486 |. FF15 04D14000 call dword ptr [<&USER32.GetDlgItemTe>; \GetDlgItemTextA
0040148C |. 83F8 1E cmp eax, 1E
0040148F |. 75 25 jnz short 004014B6
00401491 |. 8BD0 mov edx, eax
00401493 |. 8D8D FCFDFFFF lea ecx, dword ptr [ebp-204]
00401499 |. E8 62FBFFFF call 00401000
0040149E |. 83F8 01 cmp eax, 1
004014A1 |. 75 13 jnz short 004014B6
004014A3 |. 6A 00 push 0 ; /Style = MB_OK|MB_APPLMODAL
004014A5 |. 68 80374100 push 00413780 ; |Title = "information"
004014AA |. 68 8C374100 push 0041378C ; |Text = ""D7,"",A2,"",B2,"岢晒",A6,""
004014AF |. 56 push esi ; |hOwner
004014B0 |. FF15 00D14000 call dword ptr [<&USER32.MessageBoxA>>; \MessageBoxA
004014B6 |> 8B4D FC mov ecx, dword ptr [ebp-4] ; Default case of switch 0040143A
明显 00401499 |. E8 62FBFFFF call 00401000 为注册函数,且返回1表示成功。
继续分析发现
0042FCD9 F7D3 not ebx
0042FCDB 4B dec ebx
0042FCDC 66:F7D3 not bx
0042FCDF 66:81EB D165 sub bx, 65D1
0042FCE4 0FB646 FF movzx eax, byte ptr [esi-1]
0042FCE8 4E dec esi
0042FCE9 2AC3 sub al, bl
0042FCEB F6D0 not al
0042FCED 04 57 add al, 57
0042FCEF FEC8 dec al
0042FCF1 2C 3E sub al, 3E
0042FCF3 FF3485 DDF84200 push dword ptr [eax*4+42F8DD]
0042FCFA C3 retn
这个是vm_loop 作者使用了虚拟机。好吧,这里先不分析了。
对输入内容下硬件断点,来到 MD5
004014F0 /$ 55 push ebp ; md5_update
004014F1 |. 8BEC mov ebp, esp
004014F3 |. 83EC 0C sub esp, 0C
004014F6 |. 53 push ebx
004014F7 |. 8B5D 08 mov ebx, dword ptr [ebp+8]
004014FA |. 56 push esi
004014FB |. 57 push edi
PEID工具也可确认是MD5
MD5 :: 00000B37 :: 00401737
The reference is above.
SHA-512/384 [mixing] :: 00010198 :: 00411998
The reference is above.
I1 =
0019F6A0 32 32 32 32 32 32 32 00 00 00 00 00 00 00 00 00 2222222.........
输入数据为 前7个字符
通过vm_loop 找到handler表
0042F8DD 70 4A ED 20 AA F1 42 00 BD F1 42 00 D6 F1 42 00 pJ?B.今B.竹B.
0042F8ED 06 F2 42 00 31 F2 42 00 5C F2 42 00 7F F2 42 00 駼.1駼.\駼.駼.
0042F8FD A2 F2 42 00 BE F2 42 00 E5 F2 42 00 FE F2 42 00 ⅡB.掘B.弪B.B.
0042F90D 16 F3 42 00 3C F3 42 00 54 F3 42 00 7A F3 42 00 驜.<驜.T驜.z驜.
0042F91D A3 F3 42 00 CF F3 42 00 00 F4 42 00 34 F4 42 00 sB.象B..鬊.4鬊.
0042F92D 41 F4 42 00 72 F4 42 00 85 F4 42 00 A2 F4 42 00 A鬊.r鬊.咊B.ⅣB.
0042F93D BA F4 42 00 DE F4 42 00 F6 F4 42 00 1C F5 42 00 呼B.摁B.鲷B.魾.
0042F94D 4A F5 42 00 63 F5 42 00 88 F5 42 00 AD F5 42 00 J魾.c魾.堳B.B.
0042F95D C5 F5 42 00 DC F5 42 00 01 F6 42 00 23 F6 42 00 捧B.荃B.鯞.#鯞.
依次查看可找到 vm_exit
0042F76F 8BE5 mov esp, ebp ; vm_exit
0042F771 5F pop edi
0042F772 5E pop esi
0042F773 5D pop ebp
0042F774 5B pop ebx
0042F775 5A pop edx
0042F776 59 pop ecx
0042F777 58 pop eax
0042F778 9D popfd
0042F779 C3 retn
几次断点后来到
0040115E 8B8D 2CFCFFFF mov ecx, dword ptr [ebp-3D4]
00401164 8B41 17 mov eax, dword ptr [ecx+17]
00401167 0F1041 07 movups xmm0, dqword ptr [ecx+7]
0040116B 8945 E0 mov dword ptr [ebp-20], eax
0040116E 0FB741 1B movzx eax, word ptr [ecx+1B]
00401172 66:8945 E4 mov word ptr [ebp-1C], ax
00401176 0FB641 1D movzx eax, byte ptr [ecx+1D]
0040117A 33C9 xor ecx, ecx
0040117C 0F1145 D0 movups dqword ptr [ebp-30], xmm0
00401180 8845 E6 mov byte ptr [ebp-1A], al
00401183 8A440D D0 mov al, byte ptr [ebp+ecx-30]
00401187 32840D 14FCFF>xor al, byte ptr [ebp+ecx-3EC]
0040118E 88840D E8FBFF>mov byte ptr [ebp+ecx-418], al
00401195 83F9 17 cmp ecx, 17
00401198 0F83 68020000 jnb 00401406
0040119E C6440D D0 00 mov byte ptr [ebp+ecx-30], 0
004011A3 C6840D 14FCFF>mov byte ptr [ebp+ecx-3EC], 0
004011AB 41 inc ecx
004011AC 83F9 17 cmp ecx, 17
004011AF ^ 7C D2 jl short 00401183
发现这里是
I2=
0019F6E0 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 2222222222222222
0019F6F0 32 32 32 32 32 32 32 2222222
y2=
0019F324 44 AD 5C CC 12 90 73 8D 47 81 E3 89 84 9C DF F9 D璡?恠岹併墑溸?
0019F334 47 6A B6 9E 11 30 27 Gj稙0'.
I2= I2^y2 对输入进行异或操作。
004011C0 8A840D 90FDFF>mov al, byte ptr [ebp+ecx-270]
004011C7 32840D E8FBFF>xor al, byte ptr [ebp+ecx-418]
004011CE 88440D D0 mov byte ptr [ebp+ecx-30], al
004011D2 83F9 17 cmp ecx, 17
004011D5 0F83 2B020000 jnb 00401406
004011DB C6840D E8FBFF>mov byte ptr [ebp+ecx-418], 0
004011E3 C6840D 90FDFF>mov byte ptr [ebp+ecx-270], 0
004011EB 41 inc ecx
004011EC 83F9 17 cmp ecx, 17
004011EF ^ 7C CF jl short 004011C0
y1 = MD5(I1)^I2
0019F4A0 79 D8 86 01 01 86 EB 60 E3 61 1C D4 A5 D0 BC AE y貑嗠`鉧豫屑?
0019F4B0 79 D8 86 01 01 86 EB y貑嗠..
上面是 I2与MD5后的结果异或。为了达到23字节所以循环取值了一下。
004011F1 B9 40000000 mov ecx, 40
004011F6 8DBD 90FCFFFF lea edi, dword ptr [ebp-370]
004011FC BE 98374100 mov esi, 00413798
00401201 33C0 xor eax, eax
00401203 F3:A5 rep movs dword ptr es:[edi], dword ptr [esi]
00401205 B9 40000000 mov ecx, 40
0040120A 8985 30FCFFFF mov dword ptr [ebp-3D0], eax
00401210 BE 98384100 mov esi, 00413898
00401215 8DBD 90FEFFFF lea edi, dword ptr [ebp-170]
0040121B F3:A5 rep movs dword ptr es:[edi], dword ptr [esi]
0040121D 33C9 xor ecx, ecx
复制 2个 256字节的数据,通过下面的分析 这里应该是迷宫(16X16 )数据(被加密的)分别记t1和t2
0040121F 898D 2CFCFFFF mov dword ptr [ebp-3D4], ecx
00401225 > 8A4C0D D0 mov cl, byte ptr [ebp+ecx-30]
00401229 . 0FB6C9 movzx ecx, cl
0040122C . C785 0CFCFFFF>mov dword ptr [ebp-3F4], 6
00401236 . 898D 00FCFFFF mov dword ptr [ebp-400], ecx
0040123C 0F1F4000 dd crackme.00401F0F
00401240 > 8BD1 mov edx, ecx
00401242 . 8985 10FCFFFF mov dword ptr [ebp-3F0], eax
00401248 . 8A8D 0CFCFFFF mov cl, byte ptr [ebp-3F4] ; cl == 6
0040124E . D3EA shr edx, cl
00401250 . 83E2 03 and edx, 3
00401253 . FF2495 0C1440>jmp dword ptr [edx*4+40140C] ; jmp[y&0x03]??
0040125A > 83E8 10 sub eax, 10
0040125D . EB 09 jmp short 00401268
0040125F > 40 inc eax
00401260 . EB 06 jmp short 00401268
00401262 > 83C0 10 add eax, 10
00401265 . EB 01 jmp short 00401268
00401267 > 48 dec eax
00401268 > 8985 30FCFFFF mov dword ptr [ebp-3D0], eax
这里应该是计算走迷宫的步骤,每2bit代表一个方向
eax = 0
0=eax-10
1=eax+1
2=eax+10
3=eax-1
00401283 . 25 0F000080 and eax, 8000000F
00401288 . 79 05 jns short 0040128F
0040128A . 48 dec eax ; <0
0040128B . 83C8 F0 or eax, FFFFFFF0
0040128E . 40 inc eax
0040128F > 8985 04FCFFFF mov dword ptr [ebp-3FC], eax
00401295 .- E9 DBB10300 jmp 0043C475
这里进虚拟机,先不管他
退出虚拟机后来到这里
004012B5 ? 8B8D 08FCFFFF mov ecx, dword ptr [ebp-3F8]
004012BB ? 8D95 90FEFFFF lea edx, dword ptr [ebp-170]
004012C1 ? 8B85 04FCFFFF mov eax, dword ptr [ebp-3FC]
004012C7 ? C1E1 04 shl ecx, 4
004012CA . 03C1 add eax, ecx
004012CC . 03D0 add edx, eax
004012CE > 8995 04FCFFFF mov dword ptr [ebp-3FC], edx
004012D4 . 8A8C05 90FCFF>mov cl, byte ptr [ebp+eax-370]
004012DB . 8AC1 mov al, cl
004012DD . 888D 37FCFFFF mov byte ptr [ebp-3C9], cl
004012E3 . C0C8 02 ror al, 2
004012E6 . 0FB6C8 movzx ecx, al
004012E9 . 0FB602 movzx eax, byte ptr [edx]
004012EC . 33C8 xor ecx, eax
004012EE . 83F9 30 cmp ecx, 30
004012F1 . 0F84 E2000000 je 004013D9
004012F7 . 83F9 20 cmp ecx, 20
004012FA . 0F84 D9000000 je 004013D9
00401300 . 83F9 58 cmp ecx, 58
00401303 . 0F84 E5000000 je 004013EE
上面是走迷宫的算法,包含迷宫解密算法如下:
t3[i] = ror(t1[i], 2) xor t2[i]
0x00CFF878 43 30 30 30 30 31 31 31 31 31 31 31 31 30 30 30 C000011111111000
0x00CFF888 31 30 30 30 30 31 30 30 30 30 30 30 31 30 30 30 1000010000001000
0x00CFF898 31 30 30 30 30 31 30 31 31 31 31 31 31 30 30 30 1000010111111000
0x00CFF8A8 31 31 31 31 30 31 30 31 30 30 30 30 30 30 30 30 1111010100000000
0x00CFF8B8 30 30 30 31 30 31 30 31 31 31 31 31 31 31 31 30 0001010111111110
0x00CFF8C8 30 30 30 31 30 31 30 30 30 30 30 30 30 30 31 30 0001010000000010
0x00CFF8D8 30 31 31 31 30 31 30 30 30 30 30 30 30 30 31 30 0111010000000010
0x00CFF8E8 30 31 30 30 30 31 30 31 31 31 30 30 30 30 31 30 0100010111000010
0x00CFF8F8 30 31 30 30 30 31 30 31 30 31 30 30 30 30 31 30 0100010101000010
0x00CFF908 30 31 30 30 30 31 30 31 30 31 30 30 30 30 31 30 0100010101000010
0x00CFF918 30 31 30 30 30 31 31 31 30 31 30 30 30 30 31 30 0100011101000010
0x00CFF928 30 31 30 30 30 30 30 30 30 31 30 30 30 30 31 30 0100000001000010
0x00CFF938 30 31 30 30 30 30 30 30 30 31 30 31 31 31 31 30 0100000001011110
0x00CFF948 30 31 31 31 31 31 31 31 30 31 30 31 30 30 30 30 0111111101010000
0x00CFF958 30 30 30 30 30 30 30 31 30 31 30 31 30 30 30 30 0000000101010000
0x00CFF968 30 30 30 30 30 30 30 31 31 31 30 31 31 58 30 30 0000000111011X00
这句是关键 00401300 . 83F9 58 cmp ecx, 58
也就是迷宫出口,30或20 表示出错(迷宫没走对)
写程序计算走法
int i = 0; int j = 0; unsigned char cch = 0; int m = 6; ctx xx[] = { { 16, 2 }, { 1, 1 }, { -1, 3}, { -16, 0 } }; while (t3[i] != 0x58) { for (int k = 0; k < 4; k++) { int v = i + xx[k].n; if (v < 0 || v > 255) continue; if (j != v && ((t3[v] == 0x31) || (t3[v] == 0x58))) { j = i; i = v; cch |= ((xx[k].bit & 0x03) << m); if (m == 0) { printf("%02X ", cch); cch = 0; m = 8; } m -= 2; break; } } } printf("%02X ", cch);
输出为:
x1=
A9 5A BE AA A5 55 A5 00 00 FA BC 00 00 15 55 AF FE 95 55 AA AA FE A5
至此可得出公式
I2 = MD5(I1)^x1^y2;
由于I1和I2未知,所以需要枚举一下,条件是 I1和I2必须为可见字符,程序如下:
static int check(unsigned char *i2) { for (int i = 0; i < 23; i++) { if (i2[i] < ' ') return -1; if (i2[i] > 0x7e) return -1; } return 0; } int main(void) { unsigned char y1[23] = {}; unsigned char x1[] = { 0xA9, 0x5A, 0xBE, 0xAA, 0xA5, 0x55, 0xA5, 0x00, 0x00, 0xFA, 0xBC, 0x00, 0x00, 0x15, 0x55, 0xAF, 0xFE, 0x95, 0x55, 0xAA, 0xAA, 0xFE, 0xA5 }; unsigned char y2[] = { 0x44, 0xAD, 0x5C, 0xCC, 0x12, 0x90, 0x73, 0x8D, 0x47, 0x81, 0xE3, 0x89, 0x84, 0x9C, 0xDF, 0xF9, 0x47, 0x6A, 0xB6, 0x9E, 0x11, 0x30, 0x27 }; for (int i = 0; i < 23; i++) { y1[i] = x1[i] ^ y2[i]; } char I1[8] = { "0000000" }; unsigned char i1[32] = { 0 }; unsigned char I2[32] = { 0 }; for (int i = 0; i <= 0xFFFFFFF; i++) { sprintf(I1, "%07x", i); zmd5_init(&md); zmd5_update(&md, I1, 7); zmd5_final(&md, i1); *(int *)&i1[0x10] = *(int*)&i1[0]; *(int *)&i1[0x14] = *(int*)&i1[4]; for (int k = 0; k < 23; k++) { I2[k] = i1[k] ^ y1[k]; // 简化为 y1 = x1^y2 } if (check(I2) == 0) { printf("sn=%s%s\n", I1, I2); } } printf("\n"); printf(" ok.\n"); return 0; }
输出如下:
sn=033a5449NE6t,iMft0mVbhJmFDdx'=
sn=0c1e344e9]%GH`"@cgE$o.811\wKC4
sn=10f3797.;Q <?n+URr@:}D)z3Pr04:
sn=15701ad;LYskzk(5Zv2"Z9NoDX!gq?
sn=1ddb354cZ,66,{~2?qAS*VJ7R-d:'/
sn=377bca1$Jn7,jj{t-):Wjk~pBoe a>
sn=3ae70c1jnLmECpHr*WLGU(S>fM?IH$
sn=7ab0f24je685qmF4Vo:v\~c>m7j9z9
sn=8187e32jMQe 4ugy YUxED1>EP7,?!
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
赞赏
他的文章
- [原创]C++类成员指针调用 4321
- [原创]VMP3.2授权分析 53966
- [原创]看雪CTF2017 第十二题分析 5080
- [原创]看雪CTF2017 第十一题分析 6218
- [原创]看雪CTF2017 第十题分析 5834
看原图
赞赏
雪币:
留言: