胖哈勃杯第十三届CUIT校赛之re100
 
文章目录
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可能更快解决问题