题目
做法
下载压缩包,解压,把解压后的文件拖进Exeinfo PE进行分析
64位,无壳
扔进IDA(64位),找main函数
但是我们并没有发现main函数,那我们先按Shift+F12打开string窗口,一键找出所有的字符串,去寻找它的后门函数
我们从上往下看一遍,发现有些字符串带有flag,因为我们最后交的东西也是flag,所以我们重点关注一下
这里有三个带有flag的:
第2行的wrong flag
第4行的this is the right flag
第7行的input the flag
翻译一下就显而易见了
我们双击this is the right flag
然后直接按Ctrl+x
确定
然后按F5反编译成c语言
进入到主函数(一般是main,一般我们直接找到main,然后双击,再F5反汇编成c语言就可以了),分析代码
因为逆向需要猜像sub_1400111D1这种的实际表达意义是啥,因此我们从我们点进来的this is the right flag这行代码开始往上看(当然,也可以直接从最上面分析到最下面)
sub_1400111D1("this is the right flag!\n");
直观地可以看出sub_1400111D1表示的是print(经验之谈,一般这种有“”且是绿色的都是程序打印给你的东西)
if ( !strncmp(&Str1, Str2, v3) )
比较两个字符串的前 v3 个字符是否相同。如果相同,条件表达式的结果为真,程序会执行 if 语句块内的代码
到这里,我们知道了它的成立条件,我们直接去找str1和str2
往上继续看
sub_14001128F("%20s", &Str1);
我们不难猜出sub_14001128F表示的是类似于 scanf 的函数,表示用户的输入会存放到&str1
因此,我们的输入值要等于str2,就可以得到flag
继续往上看,找到有str2或者跟它有关联的东西
for ( j = 0; ; ++j )
{
v8 = j;
v2 = j_strlen(Str2);
if ( v8 > v2 )
break;
if ( Str2[j] == 111 )
Str2[j] = 48;
}
我们注意到这里有关于str2的东西,这是一个for循环
执行顺序总结
- 初始化 j = 0。
- 把 j 的值赋给 v8。
- 调用 j_strlen 函数计算 Str2 的长度并存储在 v2 中。
- 检查 v8 > v2 是否成立,若成立则跳出循环;若不成立则继续。
- 检查 Str2[j] 是否等于 111,若相等则将其替换为 48。
- j 自增 1。
- 重复步骤 2 - 6,直至满足循环终止条件。
了解大概后,补充一个小知识点——我们可以对111,48这些数字单击后按r将数字转换为字符,eg.
if ( Str2[j] == 'o' )
Str2[j] = '0';
分析完这段代码,再往上也没有关于str2的信息了,我们尝试双击一下str2看看会不会有啥惊喜
诶,我们看到一个{}括起来的字符串,有点像我们要提交的flag格式,然后想到上面要把o换成0
我们把它复制一下,把o换成0,然后再最前面加上flag
回到题目提交看看
Yes,成功解出!给自己的进步点个小赞吧!
更新
于2025.4.16