20181020学习笔记——解决的第一个Reverse题目
解决的第一个Reverse题目
题目描述
题目给了一个名为rev1的文件,没有后缀。
文件的下载地址:
结题过程
第一次做Reverse题目,一脸蒙蔽,我首先尝试把后缀改为.exe,结果,不能运行。。。。可能不是Windows系统文件。
我转到虚拟机里,打开Linux系统,执行“file rev1”,结果,果然是Linux下的可执行文件,是ELF文件。
然后我在终端执行“./rev1”,结果拒绝访问。
修改权限,在终端执行“chmod 777 rev1”
再次执行“./rev1”,运行成功了,终端显示"Please input your flag:",随便输入,结果果然是wrong。
好吧,其实,上述步骤和解决这道题没有半毛钱关系,这是我在完全小白的情况下对此题的摸索,接下来进入正题。
Windows下逆向分析强有力的工具是OD+IDA,我之前的博客中提供了下载链接。题目提供的是ELF文件,是无法使用OD的,好在这道题仅仅使用IDA就可以了。
- 把文件拖入IDA中,执行ctrl+F5,得到程序的伪代码。
- 打开伪代码查看。伪代码的核心内容如下:
//这是main函数 __int64 __fastcall main(__int64 a1, char **a2, char **a3) { __int64 result; // [email protected] __int64 v4; // [email protected] char s; // [sp+0h] [bp-30h]@1 __int64 v6; // [sp+28h] [bp-8h]@1 v6 = *MK_FP(__FS__, 40LL); printf("Please input your flag:", a2, a3); __isoc99_scanf("%32s", &s); if ( strlen(&s) == 32 ) { if ( (unsigned int)sub_400686((__int64)&s) ) puts("Right!"); else puts("Wrong!"); result = 0LL; } else { puts("Wrong!"); result = 0LL; } v4 = *MK_FP(__FS__, 40LL) ^ v6; return result; } //main函数中调用的子函数 signed __int64 __fastcall sub_400686(__int64 a1) { signed int i; // [sp+Ch] [bp-Ch]@1 for ( i = 0; i <= 31; ++i ) { if ( (char)(*(_BYTE *)(i + a1) ^ byte_400818[i]) != i ) return 0LL; } return 1LL; } //定义的全局变量 _BYTE byte_400818[33] = { 102, 109, 99, 100, 127, 60, 54, 114, 87, 66, 100, 59, 123, 82, 124, 60, 102, 84, 96, 96, 39, 74, 73, 127, 113, 88, 82, 114, 125, 117, 42, 98, 0 }; // idb
分析得到,主函数中输入了一个长度为32的字符串,然后调用子函数对字符串进行处理(子函数返回一个判断),所以最关键的部分就是分析子函数到底干了啥。
-
我们来分析一下子函数到底干了啥。子函数的伪代码如下:
signed __int64 __fastcall sub_400686(__int64 a1) { signed int i; // [sp+Ch] [bp-Ch]@1 for ( i = 0; i <= 31; ++i ) { if ( (char)(*(_BYTE *)(i + a1) ^ byte_400818[i]) != i ) return 0LL; } return 1LL; }
定义了一个变量i(i用来控制循环),然后进入了一个for循环。观察for循环中if语句的条件,“^”是异或运算,(i+a1)实际上就是在从传入的字符串变量中一次取值(第1个字符、第2个字符、第3个字符......一直到第31个字符),取出来以后和byte_400818[i](是定义的全局变量)进行了异或运算,判断异或运算的结果,满足条件,则继续循环,不满足,则返回false。所以,每个字符的值怎么求呢?其实很简单,a^b = c,那么b^c =a,所以(a1+i)=byte_400818[i]^i。
-
最后编程求出flag就行了。
#include<stdio.h> int a[]={102,109,99,100,127,60,54,114,87,66,100,59,123,82,124,60,102,84,96,96,39,74,73,127,113,88,82,114,125,117,42,98,0}; void test(){ int i; for(i=0;i<32;i++){ printf("%c",a[i]^i); } printf("\n"); } int main(){ test(); return 0; }
flag{90u_Kn0w_r3vErs3__hiAHiah4}