1.代码分析
__int64 __fastcall sub_401CA0(signed int a1, __int64 *a2) { __int64 v2; // rsi __int64 v3; // rcx __int64 v4; // rdi __int64 v5; // rdx __int64 result; // rax __int64 v7; // rcx unsigned __int64 v8; // rt1 __int16 v9; // [rsp+16h] [rbp-1Ah] __int64 v10; // [rsp+18h] [rbp-18h] __int64 v11; // [rsp+20h] [rbp-10h] unsigned __int64 v12; // [rsp+28h] [rbp-8h] v12 = __readfsqword(0x28u); sub_401C2D(); if ( a1 <= 2 ) { v2 = *a2; sub_410890((unsigned __int64)"Use: %s <input_file> <output_file> "); sub_40FD60(0xFFFFFFFFLL, v2); } v10 = sub_41FC70(a2[1], "r"); // 读取文件 v11 = sub_41FC70(a2[2], "w+"); // 写入文件 while ( (unsigned int)sub_410A20(v10, (__int64)"%c", &v9) != -1 )// 将读取到的信息,一字节一字节存入v9 { v9 = 2 * (unsigned __int8)v9; LOBYTE(v9) = HIBYTE(v9) | v9; LOBYTE(v9) = ~(_BYTE)v9; sub_421B30((unsigned __int8)v9, v11, v11, v3);// 将变换后的信息存入文件 } sub_41F7C0(v10, "%c"); v4 = v11; sub_41F7C0(v11, "%c"); result = 0LL; v8 = __readfsqword(0x28u); v7 = v8 ^ v12; if ( v8 != v12 ) sub_45AF10(v4, "%c", v5, v7); return result; }
实际的信息变换就是
v9 = 2 * (unsigned __int8)v9; LOBYTE(v9) = HIBYTE(v9) | v9; LOBYTE(v9) = ~(_BYTE)v9;
因为每次读入一字节,变换后存入文件。因此我们只需要每次遍历0x00~0xFF,能够满足变换后与输出文件相同,则该数为原数。
2.脚本解密
# -*- coding:utf-8 -*- with open('C://Users//10245//Desktop//flag.enc','rb') as f: datas = f.read() for data in datas: for i in range(0,256): j = i * 2 lbyte = ((j & 0xFF00) >> 8) | j lbyte = (~lbyte)&0xFF hbyte = (~((j & 0xFF00) >> 8))&0xFF num = ((hbyte&0xF000)>>4)*pow(16,3) + (hbyte&0xF00)*pow(16,2) + ((lbyte&0xF0)>>4)*16 + (lbyte&0xF) if num == data: print (chr(i),end="")
# -*- coding:utf-8 -*- with open('C://Users//10245//Desktop//flag.enc','rb') as f: datas = f.read() for data in datas: for i in range(0,256): j = ~((i >> 7) | (2 * i))&0xff if j == data: print (chr(i),end="")
Congratulations!
I hope you liked this small challenge.
The flag you are looking for is F#{S1mpl3_encr1pt10n_f0und_0n_g1thub!}
3. get flag!
F#{S1mpl3_encr1pt10n_f0und_0n_g1thub!}