先用die查了一下,32位无壳
直接打开ida
发现F5反编译不了了
代码也没有爆红
只能硬着头皮看了
发现了这段代码
中间的代码就是花指令,没什么意义,纯纯不给我F5的
全nop掉
在main函数按p重新生成函数
然后就能F5了
main函数代码如下
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 flag[100]; // [esp+90h] [ebp-68h] BYREF
print((char *)&Format, v6);
sub_401050("%s", (char)flag);
v10 = -171171450; //F5CC 2186
v11 = -669748952; //D814 7128
v12 = 1651994351; //6277 6EEF
v13 = -6; //FFFF FFFA
v9 = xmmword_402170;
if ( strlen(flag) == 29 )
{
for ( i = 0; i < 29; ++i )
v8[i] = funcs_40117E[i % 5u](flag[i]);/推测是函数指针,数组
v4 = 0;
while ( v8[v4] == *((_BYTE *)&v9 + v4) )
{
if ( ++v4 >= 29 )
{
print("Congratulations!!\n", v7);
return 0;
}
}
print("try again\n", v7);
}
else
{
print("wwwhhhaaattt???\n", v7);
}
return 0;
}
开始看代码,输入一个字符串,应该就是flag,改个名
v9直接双击xmmword_402170
shift+e提取数据
这才16字节,代码中用到了28字节
发现v9,v10,v11,v12,v13的地址其实是连着的
所以要使用到,v10,v11,v12,v13的部分(int 4字节)
还得是小端序
继续双击进入funcs_40117E
发现五个函数地址
双击第一个,sub_401080
F5一下
后面四个相同方法
然后得到五个函数
int __cdecl sub_401080(int a1)
{
return a1 ^ 0x19;
}
int __cdecl sub_401090(int a1)
{
return a1 + 18;
}
int __cdecl sub_4010A0(int a1)
{
return a1 - 16;
}
int __cdecl sub_4010B0(int a1)
{
return 2 * (a1 & 0x7F);
}
int __cdecl sub_4010C0(int a1)
{
return a1 ^ ((unsigned __int8)a1 ^ (unsigned __int8)~(_BYTE)a1) & 0x80;
/*化简一下 => a1 ^ (a1 ^ (~a1)) & 0x80;
=> a1 ^ 0xFF & 0x80
=> a1 ^ 0x80 */
}
先& 后^ 可以试验下,发现化简正确
最后完整解题脚本
#include<stdio.h>
#include<Windows.h>
char v8[] =
{
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,
};
int __cdecl sub_401080(int a1)
{
return a1 ^ 0x19;
}
int __cdecl sub_401090(int a1)
{
return a1 - 18;
}
int __cdecl sub_4010A0(int a1)
{
return a1 + 16;
}
int __cdecl sub_4010B0(int a1)
{
return (a1 >>1)&0x7f;
}
int __cdecl sub_4010C0(int a1)
{
//return a1 ^ ((unsigned __int8)a1 ^ (unsigned __int8)~(BYTE)a1) & 0x80;
return a1 ^ 0x80;
}
int main()
{
char flag[30];
int (_cdecl*fun[5])(int)= {sub_401080,sub_401090 ,sub_4010A0 ,sub_4010B0 ,sub_4010C0 };
for (int i = 0; i < 29; i++) {
flag[i] = fun[i % 5](v8[i]);
}
printf("%s", flag);
return 0;
}