存在花指令,永真跳转,将选中部分nop掉
然后在main函数头处点p,生成函数,f5查看伪函数
int __cdecl main(int argc, const char **argv, const char **envp)
{
int i; // esi
int v4; // eax
char v6; // [esp+0h] [ebp-F8h]
char v7; // [esp+0h] [ebp-F8h]
char v8[100]; // [esp+Ch] [ebp-ECh]
__int128 v9; // [esp+70h] [ebp-88h]
int v10; // [esp+80h] [ebp-78h]
int v11; // [esp+84h] [ebp-74h]
int v12; // [esp+88h] [ebp-70h]
char v13; // [esp+8Ch] [ebp-6Ch]
char Arglist[100]; // [esp+90h] [ebp-68h] BYREF
sub_401020((char *)&Format, v6);
sub_401050("%s", (char)Arglist);
v10 = -171171450;
v11 = -669748952;
v12 = 1651994351;
v13 = -6;
v9 = xmmword_402170;
if ( strlen(Arglist) == 29 )
{
for ( i = 0; i < 29; ++i )
v8[i] = funcs_40117E[i % 5u](Arglist[i]);
v4 = 0;
while ( v8[v4] == *((_BYTE *)&v9 + v4) )
{
if ( ++v4 >= 29 )
{
sub_401020("Congratulations!!\n", v7);
return 0;
}
}
sub_401020("try again\n", v7);
}
else
{
sub_401020("wwwhhhaaattt???\n", v7);
}
return 0;
}
简单的加密
funcs_40117E中有5个函数,分别逆向一下
这里重点讲一下第五个函数
int __cdecl sub_4010B0(char a1)
{
return 2 * (a1 & 0x7F);
}
int __cdecl sub_4010C0(int a1)
{
return a1 ^ ((unsigned __int8)a1 ^ (unsigned __int8)~(_BYTE)a1) & 0x80;
}
先查看运算符的优先级:~大于&大于^
举个例子:
~00000000=11111111
11111111^00000000=11111111
11111111&任意数=任意数
所以第五个函数最终的意思是:
a1^0x80
EXP:
def f1(a1):
return a1 ^ 0x19
def f2(a1):
return a1 - 18
def f3(a1):
return a1 + 16
def f4(a1):
return (a1 >> 1) & 0xff
def f5(a1):
return a1 ^ 0x80
enc = [0x7F, 0x7E, 0x51, 0xCE, 0xFB, 0x4E, 0x7A, 0x24, 0xE8, 0xDF,
0x59, 0x71, 0x26, 0xCA, 0xE1, 0x6C, 0x86, 0x21, 0xCC, 0xF5, 0x28, 0x71, 0x14, 0xD8, 0xEF, 0x6E, 0x77, 0x62, 0xFA]
for i in range(len(enc)):
temp = i % 5
if temp == 0:
print(chr(f1(enc[i])), end='')
elif temp == 1:
print(chr(f2(enc[i])), end='')
elif temp == 2:
print(chr(f3(enc[i])), end='')
elif temp == 3:
print(chr(f4(enc[i])), end='')
else:
print(chr(f5(enc[i])), end='')
flag{Wh4t_@_6eaut1fu1_$lower}