20211028gfsj_re_key
时间:2023-05-18 02:07:00
打开操作,闪回。拿去查壳,无壳,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?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?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 ov 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