一打开只有3个函数还以为是有壳,一查没有,确实是3个
第1个是start,给401000传个a1作为将来输入flag加密后的对比值:密文。这里c代码没有对a1的说明,32位系统中第1参数就是ebp的值,这里就是4010E4开始的37字节。
.text:004010DF public start
.text:004010DF start proc near
.text:004010DF E8 1C FF FF FF call sub_401000
.text:004010DF
.text:004010DF start endp
.text:004010DF
.text:004010DF ; ---------------------------------------------------------------------------
.text:004010E4 AF db 0AFh
.text:004010E5 AA db 0AAh
.text:004010E6 AD db 0ADh
第2函数只是传递下参数和主程序,加密在后边
// positive sp value has been detected, the output may be wrong!
BOOL __usercall sub_401000@<eax>(int a1@<ebp>)
{
int v1; // eax
int v3; // [esp-14h] [ebp-14h]
HANDLE StdHandle; // [esp-10h] [ebp-10h]
HANDLE v5; // [esp-Ch] [ebp-Ch]
int v6; // [esp-8h] [ebp-8h] BYREF
int v7; // [esp-4h] [ebp-4h]
v1 = v7;
v7 = a1;
v3 = v1;
StdHandle = GetStdHandle(0xFFFFFFF6);
v5 = GetStdHandle(0xFFFFFFF5);
WriteFile(v5, aYouCrushedThat, 0x43u, (LPDWORD)&v6, 0);
ReadFile(StdHandle, byte_402159, 0x32u, (LPDWORD)&v6, 0);
if ( sub_401084((int)&v6, v3, byte_402159, v6) )
return WriteFile(v5, aYouAreSuccess, 0x11u, (LPDWORD)&v6, 0);
else
return WriteFile(v5, aYouAreFailure, 0x11u, (LPDWORD)&v6, 0);
}
第3个是加密过程
int __usercall sub_401084@<eax>(int result@<eax>, int a2, char *input, int a4)
{
__int16 v4; // bx
int v5; // ecx
_BYTE *v7; // edi
char v8; // al
unsigned int v9; // kr00_4
char v10; // al
char v11; // cf
__int16 v12; // ax
bool v13; // zf
_BYTE *v14; // edi
int v15; // [esp+0h] [ebp-Ch]
v4 = 0;
v5 = 37;
if ( a4 >= 37 )
{
v7 = (_BYTE *)(a2 + 36);
while ( 1 )
{
LOWORD(result) = 455;
v15 = result;
v8 = *input++;
v9 = __readeflags();
v10 = v15 ^ v8; // 输入值与result异或再加1248 与a3反向比较
__writeeflags(v9);
v12 = (unsigned __int8)(__ROL1__(1, v4 & 3) + v11 + v10);// v11 //cf位:运算是否产生进位 ROL左转后CF等于结果的最低bit,就是2341H的1。CF通常是进位标志,但根据具体指令有不同的意义,像ROL中不存在进位,就用作指示其他的情况。
v4 += v12;
v13 = *v7 == (unsigned __int8)v12;
v14 = v7 + 1;
if ( !v13 )
LOWORD(v5) = 0;
result = v15;
if ( !v5 )
break;
v7 = v14 - 2; // 取前一字节
if ( !--v5 )
return result;
}
}
return 0;
}
这里除了v11以外都好理解,将输入值与455异或后加上1左移0-3位再加上v11就得到密文(反向)
这里v11是cf位,这个是进位标记,在rol时表示右位,所以这里__rol1__(1,n)是1。
解密就简单了
cipher = bytes.fromhex('AFAAADEBAEAAECA4BAAFAEAA8AC0A7B0BC9ABAA5A5BAAFB89DB8F9AE9DABB4BCB6B3909AA8')[::-1]
flag = [0]*37
v4 = 0
for i in range(37):
flag[i] = ((cipher[i] - (1<<(v4&3)) - 1)^455)&0xff
v4 +=cipher[i]
print(bytes(flag))
#a_Little_b1t_harder_plez@flare-on.com
#flag{a_Little_b1t_harder_plez@flare-on.com}