re | [NPUCTF2020]BasicASM
这个题很神奇,给了一个.s文件和一个txt文件。
打开一看,txt文件是输出,.s文件是汇编代码,x86-64的汇编,完全不难,大概看看就知道干了些啥了,这里贴出分析:
1 00007FF7A8AC5A50 push rbp 2 00007FF7A8AC5A52 push rdi 3 00007FF7A8AC5A53 sub rsp,238h 4 00007FF7A8AC5A5A lea rbp,[rsp+20h] 5 00007FF7A8AC5A5F mov rdi,rsp 6 00007FF7A8AC5A62 mov ecx,8Eh 7 00007FF7A8AC5A67 mov eax,0CCCCCCCCh 8 00007FF7A8AC5A6C rep stos dword ptr [rdi] 9 00007FF7A8AC5A6E mov rax,qword ptr [__security_cookie (07FF7A8AD3018h)] 10 00007FF7A8AC5A75 xor rax,rbp 11 00007FF7A8AC5A78 mov qword ptr [rbp+208h],rax 12 00007FF7A8AC5A7F lea rcx,[__06A15900_ConsoleApplication@cpp (07FF7A8AD902Ah)] 13 00007FF7A8AC5A86 call __CheckForDebuggerJustMyCode (07FF7A8AC1122h) ;反调试 14 00007FF7A8AC5A8B lea rdx,[string "flag{this_is_a_fake_flag}" (07FF7A8ACF450h)] ;取假flag地址 15 00007FF7A8AC5A92 lea rcx,[flag] ; flag地址 16 00007FF7A8AC5A96 call std::basic_string<char,std::char_traits<char>,std::allocator<char> >::basic_string<char,std::char_traits<char>,std::allocator<char> > (07FF7A8AC15E1h) 17 ;创建字符串? 18 00007FF7A8AC5A9B nop 19 00007FF7A8AC5A9C mov dword ptr [p],0 20 00007FF7A8AC5AA3 mov dword ptr [rbp+64h],0 21 00007FF7A8AC5AAA jmp main+64h (07FF7A8AC5AB4h) ;跳到四行下 22 00007FF7A8AC5AAC mov eax,dword ptr [rbp+64h] 23 00007FF7A8AC5AAF inc eax 24 00007FF7A8AC5AB1 mov dword ptr [rbp+64h],eax 25 00007FF7A8AC5AB4 movsxd rax,dword ptr [rbp+64h] ;跳转到这里 取DWORD 26 00007FF7A8AC5AB8 mov qword ptr [rbp+1F8h],rax ; rbp+64h的DWORD --> rbp+1F8h的QWORD 27 00007FF7A8AC5ABF lea rcx,[flag] ;取flag地址 28 00007FF7A8AC5AC3 call std::basic_string<char,std::char_traits<char>,std::allocator<char> >::length (07FF7A8AC122Bh) 29 ;获取字符串长度 30 00007FF7A8AC5AC8 mov rcx,qword ptr [rbp+1F8h] ;rcx = QWORD[rbp+1F8h] 31 00007FF7A8AC5ACF cmp rcx,rax ; 比较长度 32 00007FF7A8AC5AD2 jae main+1B2h (07FF7A8AC5C02h) ;若大于等于 -> 跳转到倒数几行 33 00007FF7A8AC5AD8 mov eax,dword ptr [rbp+64h] 34 00007FF7A8AC5ADB and eax,1 ; 取奇数位 35 00007FF7A8AC5ADE cmp eax,1 36 00007FF7A8AC5AE1 jne main+126h (07FF7A8AC5B76h) ;不是奇数位就跳转 37 00007FF7A8AC5AE7 movsxd rax,dword ptr [rbp+64h] ;DWORD [rbp+64h] --> i --> flag[i] 38 00007FF7A8AC5AEB mov rdx,rax ;第二个参数 39 00007FF7A8AC5AEE lea rcx,[flag] 40 00007FF7A8AC5AF2 call std::basic_string<char,std::char_traits<char>,std::allocator<char> >::operator[] (07FF7A8AC1442h) 41 ;依次取flag 42 00007FF7A8AC5AF7 movsx eax,byte ptr [rax] ;将flag[i] 放进eax 43 00007FF7A8AC5AFA xor eax,42h ; flag[i] ^ 0x42 44 00007FF7A8AC5AFD mov dword ptr [p],eax ; 异或后的字符放进p 45 00007FF7A8AC5B00 mov dl,30h 46 00007FF7A8AC5B02 lea rcx,[rbp+144h] 47 00007FF7A8AC5B09 call std::setfill<char> (07FF7A8AC1046h) ;设置输出 48 00007FF7A8AC5B0E mov qword ptr [rbp+1F8h],rax 49 00007FF7A8AC5B15 mov edx,2 50 00007FF7A8AC5B1A lea rcx,[rbp+168h] 51 00007FF7A8AC5B21 call std::setw (07FF7A8AC10D2h) ;设置输出宽度 52 00007FF7A8AC5B26 mov qword ptr [rbp+200h],rax 53 00007FF7A8AC5B2D lea rdx,[std::hex (07FF7A8AC1488h)] ;输出16进制 54 00007FF7A8AC5B34 mov rcx,qword ptr [__imp_std::cout (07FF7A8AD71C0h)] 55 00007FF7A8AC5B3B call qword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (07FF7A8AD7160h)] 56 ;输出 57 00007FF7A8AC5B41 mov rcx,qword ptr [rbp+200h] 58 00007FF7A8AC5B48 mov rdx,rcx 59 00007FF7A8AC5B4B mov rcx,rax 60 00007FF7A8AC5B4E call std::operator<<<char,std::char_traits<char>,__int64> (07FF7A8AC12F8h) 61 00007FF7A8AC5B53 mov rcx,qword ptr [rbp+1F8h] 62 00007FF7A8AC5B5A mov rdx,rcx 63 00007FF7A8AC5B5D mov rcx,rax 64 00007FF7A8AC5B60 call std::operator<<<char,std::char_traits<char>,char> (07FF7A8AC11A4h) 65 00007FF7A8AC5B65 mov edx,dword ptr [p] 66 00007FF7A8AC5B68 mov rcx,rax 67 00007FF7A8AC5B6B call qword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (07FF7A8AD7158h)] 68 00007FF7A8AC5B71 jmp main+1ADh (07FF7A8AC5BFDh) ;跳回循环开头 69 00007FF7A8AC5B76 movsxd rax,dword ptr [rbp+64h] ;这里应该是偶数位 70 00007FF7A8AC5B7A mov rdx,rax 71 00007FF7A8AC5B7D lea rcx,[flag] 72 00007FF7A8AC5B81 call std::basic_string<char,std::char_traits<char>,std::allocator<char> >::operator[] (07FF7A8AC1442h) 73 00007FF7A8AC5B86 movsx eax,byte ptr [rax] 74 00007FF7A8AC5B89 mov dword ptr [p],eax 75 00007FF7A8AC5B8C mov dl,30h 76 00007FF7A8AC5B8E lea rcx,[rbp+194h] 77 00007FF7A8AC5B95 call std::setfill<char> (07FF7A8AC1046h) 78 00007FF7A8AC5B9A mov qword ptr [rbp+1F8h],rax 79 00007FF7A8AC5BA1 mov edx,2 80 00007FF7A8AC5BA6 lea rcx,[rbp+1B8h] 81 00007FF7A8AC5BAD call std::setw (07FF7A8AC10D2h) 82 00007FF7A8AC5BB2 mov qword ptr [rbp+200h],rax 83 00007FF7A8AC5BB9 lea rdx,[std::hex (07FF7A8AC1488h)] 84 00007FF7A8AC5BC0 mov rcx,qword ptr [__imp_std::cout (07FF7A8AD71C0h)] 85 00007FF7A8AC5BC7 call qword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (07FF7A8AD7160h)] 86 ;输出 87 00007FF7A8AC5BCD mov rcx,qword ptr [rbp+200h] 88 00007FF7A8AC5BD4 mov rdx,rcx 89 00007FF7A8AC5BD7 mov rcx,rax 90 00007FF7A8AC5BDA call std::operator<<<char,std::char_traits<char>,__int64> (07FF7A8AC12F8h) 91 00007FF7A8AC5BDF mov rcx,qword ptr [rbp+1F8h] 92 00007FF7A8AC5BE6 mov rdx,rcx 93 00007FF7A8AC5BE9 mov rcx,rax 94 00007FF7A8AC5BEC call std::operator<<<char,std::char_traits<char>,char> (07FF7A8AC11A4h) 95 00007FF7A8AC5BF1 mov edx,dword ptr [p] 96 00007FF7A8AC5BF4 mov rcx,rax 97 00007FF7A8AC5BF7 call qword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (07FF7A8AD7158h)] 98 00007FF7A8AC5BFD jmp main+5Ch (07FF7A8AC5AACh) 99 00007FF7A8AC5C02 mov dword ptr [rbp+1E4h],0 ;跳转到这里 100 00007FF7A8AC5C0C lea rcx,[flag] 101 00007FF7A8AC5C10 call std::basic_string<char,std::char_traits<char>,std::allocator<char> >::~basic_string<char,std::char_traits<char>,std::allocator<char> > (07FF7A8AC1302h) 102 00007FF7A8AC5C15 mov eax,dword ptr [rbp+1E4h] 103 00007FF7A8AC5C1B mov edi,eax 104 00007FF7A8AC5C1D lea rcx,[rbp-20h] 105 00007FF7A8AC5C21 lea rdx,[__xt_z+540h (07FF7A8ACEFE0h)] 106 00007FF7A8AC5C28 call _RTC_CheckStackVars (07FF7A8AC1596h) 107 00007FF7A8AC5C2D mov eax,edi 108 00007FF7A8AC5C2F mov rcx,qword ptr [rbp+208h] 109 00007FF7A8AC5C36 xor rcx,rbp 110 00007FF7A8AC5C39 call __security_check_cookie (07FF7A8AC1190h) 111 00007FF7A8AC5C3E lea rsp,[rbp+218h] 112 00007FF7A8AC5C45 pop rdi 113 00007FF7A8AC5C46 pop rbp 114 00007FF7A8AC5C47 ret
简单的说就是下标奇数做异或嘛,随便写个脚本好啦:
1 Python 3.7.3 (v3.7.3:ef4ec6ed12, Mar 25 2019, 21:26:53) [MSC v.1916 32 bit (Intel)] on win32 2 Type "help", "copyright", "credits" or "license" for more information. 3 >>> 4 >>> a = "662e61257b26301d7972751d6b2c6f355f3a38742d74341d61776d7d7d" 5 >>> b = bytes.fromhex(a) 6 >>> b 7 b'f.a%{&0\x1dyru\x1dk,o5_:8t-t4\x1dawm}}' 8 >>> flag = [] 9 >>> 10 >>> for i in range(len(b)): 11 ... if ((i & 1)-1) != 0: 12 ... flag.append(chr(b[i])) 13 ... else: 14 ... for j in range(33,127): 15 ... if j^0x42 == b[i]: 16 ... flag.append(chr(j)) 17 ... break 18 ... 19 >>> flag 20 ['f', 'l', 'a', 'g', '{', 'd', '0', '_', 'y', '0', 'u', '_', 'k', 'n', 'o', 'w', '_', 'x', '8', '6', '-', '6', '4', '_', 'a', '5', 'm', '?', '}'] 21 >>> "".join(flag) 22 'flag{d0_y0u_know_x86-64_a5m?}'
这种给汇编的题第一次见,很有意思,还好我不是只会f5,233333333333.
over.
本文来自博客园,作者:Mz1,转载请注明原文链接:https://www.cnblogs.com/Mz1-rc/p/14087970.html
如果有问题可以在下方评论或者email:mzi_mzi@163.com