文章目录
  1. 1. 0x00 分析
  2. 2. 0x01 总结

100分的逆向题


0x00 分析

题目相关文件:https://github.com/Reshahar/BlogFile/tree/master/2017-cuit-re100

首先运行程序,让输入一个flag,随便输入一个退出了,查壳什么也没有,先拖到IDA中吧

int start()
{
char v1; // [sp+0h] [bp-100h]@1

print(aFIUFlag);
read(&v1, 256);
check(&v1);
return 0;
}

主函数很简单,总共也没有几个函数(这里函数重命名过了),主要看一下check

int __cdecl check(const char *input_str)
{
int result; // eax@5
signed int i; // [sp+8h] [bp-Ch]@2

if ( strlen(input_str) == 23 )
{
    calc((int)input_str);
    for ( i = 0; i < 23; ++i )
    {
    if ( input_str[i] != unk_403048[i] )
        return print(aFlagT__0);
    }
    result = print(aFlagT);
}
else
{
    result = print(aFlagT_);
}
return result;
}

主要就是将输入的字符串进行计算,然后和unk_403048地址的字符串比较,字符串的长度是23,看来主要就在calc函数里

int __cdecl calc(int input_str)
{
int result; // eax@3
unsigned int v2; // edx@3
signed int i; // [sp+18h] [bp-4h]@1

for ( i = 0; i < 23; ++i )
{
    *(_BYTE *)(i + input_str);
    *(_BYTE *)(i + input_str);
    *(_BYTE *)(i + input_str);
    *(_BYTE *)(i + input_str);
    *(_BYTE *)(i + input_str);
    *(_BYTE *)(i + input_str);
    *(_BYTE *)(i + input_str);
    *(_BYTE *)(i + input_str);
    *(_BYTE *)(i + input_str);
    *(_BYTE *)(i + input_str);
    *(_BYTE *)(i + input_str);
    *(_BYTE *)(i + input_str);
    *(_BYTE *)(i + input_str);
    *(_BYTE *)(i + input_str);
    *(_BYTE *)(i + input_str);
    *(_BYTE *)(i + input_str);
    *(_BYTE *)(i + input_str);
    *(_BYTE *)(i + input_str);
    *(_BYTE *)(i + input_str);
    *(_BYTE *)(i + input_str);
    *(_BYTE *)(i + input_str);
    *(_BYTE *)(i + input_str);
    *(_BYTE *)(i + input_str);
    *(_BYTE *)(i + input_str);
    *(_BYTE *)(i + input_str);
    *(_BYTE *)(i + input_str);
    *(_BYTE *)(i + input_str);
    *(_BYTE *)(i + input_str);
    *(_BYTE *)(i + input_str);
    *(_BYTE *)(i + input_str);
    *(_BYTE *)(i + input_str);
    *(_BYTE *)(i + input_str);
    *(_BYTE *)(i + input_str);
    *(_BYTE *)(i + input_str);
    *(_BYTE *)(i + input_str);
    *(_BYTE *)(i + input_str);
    *(_BYTE *)(i + input_str);
    *(_BYTE *)(i + input_str);
    *(_BYTE *)(i + input_str);
    *(_BYTE *)(i + input_str);
    *(_BYTE *)(i + input_str);
    *(_BYTE *)(i + input_str);
    *(_BYTE *)(i + input_str);
    *(_BYTE *)(i + input_str);
    *(_BYTE *)(i + input_str);
    *(_BYTE *)(i + input_str);
    *(_BYTE *)(i + input_str);
    *(_BYTE *)(i + input_str);
    *(_BYTE *)(i + input_str);
    *(_BYTE *)(i + input_str);
    *(_BYTE *)(i + input_str);
    *(_BYTE *)(i + input_str);
    *(_BYTE *)(i + input_str);
    *(_BYTE *)(i + input_str);
    *(_BYTE *)(i + input_str);
    *(_BYTE *)(i + input_str);
    *(_BYTE *)(i + input_str);
    *(_BYTE *)(i + input_str);
    *(_BYTE *)(i + input_str);
    *(_BYTE *)(i + input_str);
    *(_BYTE *)(i + input_str);
    *(_BYTE *)(i + input_str);
    *(_BYTE *)(i + input_str);
    *(_BYTE *)(i + input_str);
    *(_BYTE *)(i + input_str);
    *(_BYTE *)(i + input_str);
    *(_BYTE *)(i + input_str);
    *(_BYTE *)(i + input_str);
    *(_BYTE *)(i + input_str);
    *(_BYTE *)(i + input_str);
    *(_BYTE *)(i + input_str);
    *(_BYTE *)(i + input_str);
    *(_BYTE *)(i + input_str);
    *(_BYTE *)(i + input_str);
    *(_BYTE *)(i + input_str);
    *(_BYTE *)(i + input_str);
    *(_BYTE *)(i + input_str);
    *(_BYTE *)(i + input_str);
    *(_BYTE *)(i + input_str);
    *(_BYTE *)(i + input_str);
    *(_BYTE *)(i + input_str);
    *(_BYTE *)(i + input_str);
    *(_BYTE *)(i + input_str);
    *(_BYTE *)(i + input_str);
    *(_BYTE *)(i + input_str);
    *(_BYTE *)(i + input_str);
    *(_BYTE *)(i + input_str);
    *(_BYTE *)(i + input_str);
    *(_BYTE *)(i + input_str);
    *(_BYTE *)(i + input_str);
    *(_BYTE *)(i + input_str);
    *(_BYTE *)(i + input_str);
    v2 = ~(*(_BYTE *)(i + input_str) | 0xFFFFFFCE) | ~(~*(_BYTE *)(i + input_str) | 0x31);
    *(_BYTE *)(i + input_str);
    *(_BYTE *)(i + input_str) = ~(~(*(_BYTE *)(i + input_str) | 0xCE) | ~(~*(_BYTE *)(i + input_str) | 0x31));
    result = i + 1;
    }
    return result;
}

这个函数看着很长实际都是迷惑你,这里IDA很容易就能看出来,要是用OD完了,就算你很清醒,也会变得迷迷糊糊,主要就是通过最后一条语句进行计算,其他的都没有改变你输入的值

*(_BYTE *)(i + input_str) = ~(~(*(_BYTE *)(i + input_str) | 0xCE) | ~(~*(_BYTE *)(i + input_str) | 0x31));

这里我用python写的脚本,当然用c语言更好,脚本如下

list = [0x9D,0x97,0x8D,0xB5,0x84,0xBB,0xFB,0xBA,0x91,0x8C,0x90,0xBD,0xFD,0x91,0x80,0xFE,0xBC,0x91,0x8D,0xFE,0xAA,0xAB,0xB3]                     

flag = ''

for i in list:
    for j in range(20,128):
        y=~((~((j%256)|0xCE))|~((~(j%256))|0x31))
        if y == i:
            flag +=chr(j)
print flag

运行结果:

SYC{Ju5t_B^s3_N0r_C0de}

验证:

输入你的Flag:SYC{Ju5t_B^s3_N0r_C0de}
flag 就是这个!

0x01 总结

不一定要马上使用OD才好,IDA可能更快解决问题

文章目录
  1. 1. 0x00 分析
  2. 2. 0x01 总结