Re小登对题目的基础理解

Re小登对题目的基础理解

一、学期总结

大一上的Re之旅不能说是砍瓜切菜,也可以说是惨不忍睹。凡Re题无有解出的,对汇编的陌生是最关键的,同时发现许多比赛的re配合着java与apk的逆向,更是对我这个小登施以暴击,所以我立下宏志,在这个寒假猛攻Re。

二、基础理解

光口头说说固然无用,所以放假以来,我仔细复盘了一遍Newstar CTF前三周的Re题,学了些网课,得到一些心得,记录下来。

以一道题来看一下逆向做题的常规步骤
例题为BUU的刮开有奖,题目描述如下

第一步 查壳

拿到题目先看一下文件格式和有无壳,有壳则脱壳,无壳就可以根据文件格式直接静态分析了。
使用工具:DetectItEasy 或者 exeinfo pe

PE文件,编译器和链接器这里能看出是什么语言编写编译的,如果有壳也会出现packer提示,指出是什么壳和壳的版本号。

第二步 查看题目文件

弹出一个图片,图片不能移动或修改

一般在这一步获取到题目是否输出字符串?有无提示?

比如:

第三步 静态分析

静态分析顾名思义就是看静态代码,分析逻辑

使用工具:IDA一把梭

shift + F12 看一下字符串:

https://bu.dusays.com/2025/01/20/678e5883d00e6.jpg

F5看一程序主体:

if ( a2 == 272 )
return 1;
if ( a2 != 273 )
return 0;
if ( (_WORD)a3 == 1001 )
{
memset(String, 0, 0xFFFFu);
GetDlgItemTextA(hDlg, 1000, String, 0xFFFF); //flag是我们输入的值,也就是String if ( strlen(String) == 8 )//String为8位
{
v7[0] = 90;
v7[1] = 74;
v8 = 83;
v9 = 69;
v10 = 67;
v11 = 97;
v12 = 78;
v13 = 72;
v14 = 51;
v15 = 110;
v16 = 103;
sub_4010F0(v7, 0, 10);
memset(v18, 0, 0xFFFFu);
v18[0] = String[5];
v18[2] = String[7];
v18[1] = String[6];
v4 = (const char *)sub_401000(v18, strlen(v18));
memset(v18, 0, 0xFFFFu);
v18[1] = String[3];
v18[0] = String[2];
v18[2] = String[4];
v5 = (const char *)sub_401000(v18, strlen(v18));
if ( String[0] == v7[0] + 34
&& String[1] == v10
&& 4 * String[2] - 141 == 3 * v8
&& String[3] / 4 == 2 * (v13 / 9)
&& !strcmp(v4, "ak1w")
&& !strcmp(v5, "V1Ax") )
{
MessageBoxA(hDlg, "U g3t 1T!", "@_@", 0);
}
}
return 0;
}
if ( (_WORD)a3 != 1 && (_WORD)a3 != 2 )
return 0;
EndDialog(hDlg, (unsigned __int16)a3);
return 1;
}

先看一下两个函数

**sub_4010F0 **

排序算法,最后会将

v7[0] = 90; 
v7[1] = 74;
v8 = 83;
v9 = 69;
v10 = 67;
v11 = 97;
v12 = 78;
v13 = 72;
v14 = 51;
v15 = 110;
v16 = 103;

进行一个从小到大的排序,变为

[51, 67, 69, 72, 74, 78, 83, 90, 97, 103, 110]

sub_401000

发现此处是base64加密

在主函数中可以很明显的找到成功提示”U g3t 1T!” ,那么上面的if就是判断是否成功的条件也就是

String[0] == v7[0] + 34 				//v7[0] = 51 String[0] = 85 = ’U’   
&& String[1] == v10 //String[1] = v10 = 74 = ’J’
&& 4 * String[2] - 141 == 3 * v8 //v8 = 69 String[2] = 87 = ’W’
&& String[3] / 4 == 2 * (v13 / 9) //v13 = 90 String[3] = ’P’
&& !strcmp(v4, "ak1w") //v4经过加密后要等于"ak1w" v4 = 'jMp'
&& !strcmp(v5, "V1Ax") //v5 = 'WP1'

一共8位,所以前4位为 UJWP,所以后面应该跟v5,再跟v4,即UJWP1jMp

这个题就做完啦~但是但是一般还会用到动调的!!

第四步 动态调试

动态调试时程序是运行的,我们通过观察程序运行的实时状态来获取数据或者分析程序逻辑

使用工具:OD (IDA也可以动调)

暂时还搞不定动调,希望在寒假过后可以掌握一些。

总结

发现Re的入门基础在于认真地、仔细地看IDA给的代码,一点点分析,相信剩下的一个月我会有所突破。