查壳
IDA打开
字符串打开就发现了明显的标志
int __cdecl main(int argc, const char **argv, const char **envp)
{
__int64 v3; // rbx
__int64 v4; // rax
char v5; // al
char *v6; // rcx
int v8[10]; // [rsp+20h] [rbp-19h]
char v9; // [rsp+48h] [rbp+Fh]
__int128 v10[3]; // [rsp+50h] [rbp+17h] BYREF
__int16 v11; // [rsp+80h] [rbp+47h]
v8[0] = 167640836;
v8[1] = 11596545;
v11 = 0;
v8[2] = -1376779008;
memset(v10, 0, sizeof(v10));
v3 = 0i64;
v8[3] = 85394951;
v8[4] = 402462699;
v8[5] = 32375274;
v8[6] = -100290070;
v8[7] = -1407778552;
v8[8] = -34995732;
v8[9] = 101123568;
v9 = -7;
sub_140001064("%50s");
v4 = -1i64;
do
++v4;
while ( *((_BYTE *)v10 + v4) );
if ( v4 == 41 )
{
while ( 1 )
{
v5 = (*((_BYTE *)v10 + v3) ^ 0x32) - 86;
*((_BYTE *)v10 + v3) = v5;
if ( *((_BYTE *)v8 + v3) != v5 )
break;
if ( ++v3 >= 41 )
{
v6 = "you are right!";
goto LABEL_8;
}
}
v6 = "wrong!";
LABEL_8:
sub_140001010(v6);
}
return 0;
}
从 right往回看,可以知道——答案应该是40个字符——v10要等于v8——v5通过v10有个不明的操作——v8已知
由已知到未知
但是我们又发现
v8是个10个元素组成的数组
但是要比较40次
那么说明 每个v8,我们要取4个字符
因为现在是在IDA里面(IDA里面是给机器看的),所以他是存在大小端的问题,我们要取的是数字的后面一个字节
(后面那个v5的不明操作,我们试一下就知道这是flag表示)
那么代码如下
v8 = [
167640836,
11596545,
-1376779008,
85394951,
402462699,
32375274,
-100290070,
-1407778552,
-34995732,
101123568,
]
flag=''
for i in range(len(v8)):
flag+=chr(((((v8[i]>>0)&0xff)+86)^0x32)%128)
flag+=chr(((((v8[i]>>8)&0xff)+86)^0x32)%128)
flag+=chr(((((v8[i]>>16)&0xff)+86)^0x32)%128)
flag+=chr(((((v8[i]>>24)&0xff)+86)^0x32)%128)##最后数据会大于128,所以保证下ASCII的范围
print(flag)