打开运行,闪退。
拿去查壳,无壳,C++编译32位。
C++看着就烦,拿去OD调试。
F9运行一下,直接到达程序结束处,但总算看得到黑窗口有什么了。
?W?h?a?t h?a?p?p?e?n?
还有种方法可以不让它闪退。
就是在cmd运行程序,而不是直接打开程序。
这样就可以看到它的返回字符串且不闪退。
重新载入,右键->中文搜索引擎->智能搜索,看到很多有意义的字符串。
地址 反汇编 文本字符串
000F1043 mov eax,key.000F526C Unknown exception
000F115F mov eax,dword ptr ds:[0xF529C] emida
000F1164 movups xmm0,dqword ptr ds:[0xF528C] themidathemidathemida
000F116E movzx eax,word ptr ds:[0xF52A0] a
000F1179 movzx eax,word ptr ds:[0xF52B4] <.
000F1188 movups xmm0,dqword ptr ds:[0xF52A4] >----++++....<<<<.
000F1246 mov edx,key.000F52E4 ?W?h?a?t h?a?p?p?e?n?
000F133E mov edx,key.000F52FC |------------------------------|
000F1356 mov edx,key.000F5320 |==============================|
000F1373 mov edx,key.000F5320 |==============================|
000F1390 mov edx,key.000F5320 |==============================|
000F13AD mov edx,key.000F5344 \ /\ /\ /\ /\==============|
000F13CA mov edx,key.000F5368 \/ \/ \/ \/ \=============|
000F13E7 mov edx,key.000F538C |-------------|
000F1415 mov edx,key.000F53B0 Congrats You got it!
000F1421 mov edx,key.000F53C8 =W=r=o=n=g=K=e=y=
000F21F6 push key.000F53DC string too long
000F2587 push key.000F52B8 C:\Users\CSAW2016\haha\flag_dir\flag.txt
000F269C push key.000F53DC string too long
000F29A8 mov [local.8],key.000F5280 bad cast
000F2D38 mov [local.8],key.000F5280 bad cast
000F3415 call key.000F389D (Initial CPU selection)
000F37DE mov dword ptr ds:[ecx+0x4],key.000F5238 bad allocation
000F3817 mov dword ptr ds:[ecx+0x4],key.000F5254 bad array new length
因为有flag.txt路径,猜测这个程序是拿到key后读取flag.txt文件。
一个一个看字符串。
先看Whathappen
,上面有个跳转指令刚好跳过Whathappen
,在跳转指令下断点,运行,改一下ZF的值使跳转实现,再运行,终端显示=W=r=o=n=g=K=e=y=
。
000F123E |. /74 25 je short key.000F1265
000F1240 |. |8B0D C8500F00 mov ecx,dword ptr ds:[<&MSVCP140.std::cerr>] ; msvcp140.std::cerr
000F1246 |. BA E4520F00 mov edx,key.000F52E4 ; ?W?h?a?t h?a?p?p?e?n?
000F124B |. 68 502C0F00 push key.000F2C50
000F1250 |. E8 AB170000 call key.000F2A00
000F1255 |. 8BC8 mov ecx,eax
000F1257 |. FF15 98500F00 call dword ptr ds:[<&MSVCP140.std::basic>; msvcp140.std::basic_ostream >::operator<<
000F125D |. 6A FF push -0x1 ; /status = FFFFFFFF (-1.)
000F125F |. FF15 68510F00 call dword ptr ds:[<&api-ms-win-crt-runt>; \exit
000F1265 |> \8D55 AC lea edx,[local.21]
再看Congrats You got it!
,往上全都是call指令,直到遇到第一个跳转指令,下断点,运行。
发现程序停在了123E地址,也就是我们下的第一个断点处,改一下ZF值再运行,发现断在了第二个断点处,改ZF,运行,终端显示Congrats You got it!
。
如果是爆破的话,那这样改就可以达到破解程序的目的了。
可惜我们是要得到flag,那就需要逆向算法。
可知如果要到达Congrats You got it!
,先要经过Whathappen
那一个跳转指令。
在那条跳转指令往上看看有什么东西。
000F11A0 |> /8A4435 DC /mov al,byte ptr ss:[ebp+esi-0x24]
000F11A4 |. |8D4D 94 |lea ecx,[local.27]
000F11A7 |. |324435 C4 |xor al,byte ptr ss:[ebp+esi-0x3C]
000F11AB |. |04 16 |add al,0x16
000F11AD |. |8885 D8FEFFFF |mov byte ptr ss:[ebp-0x128],al
000F11B3 |. |FFB5 D8FEFFFF |push [local.74]
000F11B9 |. |6A 01 |push 0x1
000F11BB |. |E8 20100000 |call key.000F21E0
000F11C0 |. |46 |inc esi
000F11C1 |. |83FE 12 |cmp esi,0x12
000F11C4 |.^\7C DA \jl short key.000F11A0
000F11C6 |. 33F6 xor esi,esi
000F11C8 |. C745 D8 0F000000 mov [local.10],0xF
000F11CF |. 8975 D4 mov [local.11],esi
000F11D2 |. C645 C4 00 mov byte ptr ss:[ebp-0x3C],0x0
000F11D6 |. C645 FC 02 mov byte ptr ss:[ebp-0x4],0x2
000F11DA |. 8B7D A8 mov edi,[local.22]
000F11DD |. 8B5D 94 mov ebx,[local.27]
000F11E0 |> 83FF 10 /cmp edi,0x10
000F11E3 |. 8D45 94 |lea eax,[local.27]
000F11E6 |. 8D4D C4 |lea ecx,[local.15]
000F11E9 |. 0F43C3 |cmovnb eax,ebx
000F11EC |. 8A0430 |mov al,byte ptr ds:[eax+esi]
000F11EF |. 04 09 |add al,0x9
000F11F1 |. 8885 D8FEFFFF |mov byte ptr ss:[ebp-0x128],al
000F11F7 |. FFB5 D8FEFFFF |push [local.74]
000F11FD |. 6A 01 |push 0x1
000F11FF |. E8 DC0F0000 |call key.000F21E0
000F1204 |. 46 |inc esi
000F1205 |. 83FE 12 |cmp esi,0x12
000F1208 |.^ 7C D6 \jl short key.000F11E0
000F120A |. 68 B8000000 push 0xB8 ; /n = B8 (184.)
000F120F |. 8D85 DCFEFFFF lea eax,[local.73] ; |
000F1215 |. 6A 00 push 0x0 ; |c = 00
000F1217 |. 50 push eax ; |s = 00000070
000F1218 |. E8 ED2B0000 call ; \memset
000F121D |. 51 push ecx
000F121E |. 8D8D DCFEFFFF lea ecx,[local.73]
000F1224 |. E8 F7030000 call key.000F1620
000F1229 |. C645 FC 03 mov byte ptr ss:[ebp-0x4],0x3
000F122D |. 8B85 DCFEFFFF mov eax,[local.73] ; key.000F542C
000F1233 |. 8B40 04 mov eax,dword ptr ds:[eax+0x4]
000F1236 |. F68405 E8FEFF>test byte ptr ss:[ebp+eax-0x118],0x6
000F123E |. 74 25 je short key.000F1265
有两个循环,一个设置缓存函数,两个call指令。
在第一个循环内某条指令下断点,跑一下发现它会跑出一些字符串,存在ecx中。
在跳出循环的下一条指令下断点,F9运行,可以看到ecx存着循环跑完的字符串 `[^VZe`uYaY]`s^joY
第二个循环同样 *** 作,发现它需要用到第一个循环跑出来的字符串,直至循环跑完,字符串为idg_cni~bjbfi|gsxb
设置缓存空间函数没什么可利用的,跳过。
两个call指令执行完后的eax都是某个地址,不是返回值,也没什么好看的。
所以关键就是那两个循环。
没想到吧,flag就是idg_cni~bjbfi|gsxb
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)