BUUCTF Reverse SimpleRev Writeup
SimpleRev
这道题虽然网上已经有比较多的Writeup了,但是还是想自己写一下,加强一下学习效果🙂
查看main函数,外层就是输入d/D start,q/Q quit的代码实现:
核心是这个Decry函数:
*注1:*先提一嘴__readfsqword:这是一个栈保护机制,你可以在第15行和第69行看到它,如果这玩意改变了,那么return的异或值就不为0,就说明栈溢出了。总结一句话:这是程序的“防盗报警器”,如果只是逆向分析,可以完全忽略它。
关注最后的比对:text与str2。其中text是可以知道的。第22行join函数实现了key3与v9的拼接。其中key3的值是kills;v9的值在第19行,是hadow(选中按R将数值转换为字符,又因为是小端序,故取反)。所以text就是killshadow了。
我们也可以算出来key的值:key是由key1和src拼接而成。同上,我们可以得到key为ADSFKNDCLS。
注2:第27行的getchar()是为了“吃掉”上一步输入"d/D"留在缓冲区里的回车符,确保后面的 while 循环能真正等待用户输入 Flag。
注3:Str2显示的.bss:00000000002020A0 key db 80h dup(?)是啥意思?
- .bss: 这是内存的一个区域,专门存放全局变量或静态变量*。*
- db: 全称 Define Byte,意思是按“字节”为单位定义。
- 80h: 这是十六进制。转换为十进制是 128。
- dup(?): Duplicate 的缩写。意思是“重复”。
?表示初始值未知(通常在程序运行时才会被填入数据)。
通俗翻译: 程序在内存里申请了一块连续的空地,名字叫 key,大小是 128 个字节。它就像一个能装 128 个字符的空盒子。
第29~34行,
1 | for ( i = 0; i < v5; ++i ) |
这里是在将key从大写转为小写。
关注核心加密部分:
1 | while ( 1 ) |
读入v1,如果是回车就break;大写和小写字母的加密逻辑一致,都是:
其中 v1 是原始字符,str2[i] 是目标字符(即 “killshadow” 中的一位)。
为什么用 v3 % v5?
这是最困惑的地方。在密码学代码中,%(取模运算)通常用于循环遍历固定长度的序列。
- v3: 是一个计数器,它记录了当前用到了密钥的第几个字符。
- v5: 是密钥
key的长度(10)。 key[v3 % v5]: 这意味着如果你的 Flag 长度是 20,而密钥只有 10 位,当v3增加到 10 时,10 % 10 = 0,它会重新回到密钥的第 0 位开始计算。注4:因为前面遍历过(大写转小写),所以此时v3的初值已是10。
我们可以使用正向爆破的手段来得到flag,在这里贴一段网上的脚本:
1 | text = 'killshadow' |
得到flag:KLDQCUDFZO。
当然其实这里有一个问题,那就是如果小写字母和大写字母都满足的情况下,由于大写字母ascii码靠前,有break跳出循环,导致不会输出小写字母的这种情况。所以说其实flag也有别的可能。
- Title: BUUCTF Reverse SimpleRev Writeup
- Author: Realknow
- Created at : 2026-02-23 16:47:38
- Updated at : 2026-02-23 23:20:59
- Link: https://realknowtech.github.io/2026/02/23/BUUCTF-Reverse-SimpleRev-Writeup/
- License: This work is licensed under CC BY-NC-SA 4.0.