引言
- 我是一名CTF萌新啊,做这么详细的WP,也是希望能够帮助像我一样的新手,如果大佬发现WP有问题可以评论,我会改进!
16 bit
- 这个官方文档写的比较详细,那我就仔细的讲一下过程
- 运行这个exe会发现运行不了,据官方WP所说,这个是16位的应⽤程序,是由汇编语⾔直接编写再编译的,现代操作系统⼀般都无法直接运行,但它还是⼆进制⽂件,ida可以分析,不过F5⼀键出伪代码就没法⽤了
方法1:观看反汇编
可以把汇编代码复制给ai,然后问一下它这段代码写的啥,这里就结合ai进行解释了
IDA不会用的可以看我的Week1

第1行:
mov ax, seg dsegseg dseg:dseg是程序中定义的一个数据段的名称。seg是一个操作符,它获取dseg这个段的段地址(段基址)。- 在实模式下,内存地址由
段地址:偏移地址组成。
mov ax, seg dseg:- 将数据段
dseg的段地址加载到 AX 寄存器中。 - AX 在这里作为临时中转寄存器。
- 将数据段
第2行:
mov ds, axmov ds, ax:- 将 AX 寄存器中的值(即
dseg的段地址)移动到 DS 寄存器。 - DS 是数据段寄存器,它定义了程序中数据访问的默认段。
- 将 AX 寄存器中的值(即
为什么不能直接
mov ds, seg dseg?- 在 x86 架构中,大多数指令不允许将立即数直接移动到段寄存器。
- 必须通过通用寄存器(如 AX)进行中转。
第3行:
assume ds:dsegassume:- 这是一个汇编器伪指令,不是 CPU 指令。
- 它不生成任何机器代码,只是给汇编器提供信息。

其实这一段不用看,因为下面又给覆盖了 :(
只是把sub和xor的位置颠倒了,所以这段和后面那段就一块讲了
sub是减法,xor是异或
cx是循环计数器,mov是赋值语法,0x17 = 23,也就是循环23次
loc_1000E:后面就是循环结构
1 | loc_1000E: |
- 再往下看
1 | mov byte_100A6, 24h ; '$' ; 在地址 66h 写入 '$' 终止符 |
- 下面那段也类似就不解释了,什么,你问我这个地址在哪看?把鼠标滚轮往下滚,你会得知答案
- 然后你已经看懂了汇编,就可以试着写一写python脚本来推算出flag,我不是很会,就用ai生成脚本了
1 | # decode_flag.py |
- 另外提一嘴,国内的ai真的不太好用,写脚本都是错的:p
方法2:配置Dosbox运行
- 不用看其他人配置Dosbox了,太麻烦,看我的精简版
- 从DOSBox, an x86 emulator with DOS下载

- 进去之后啥也不用点,等几秒就行,别点那老鼻子广告都是假的下载按钮

- 下载好之后,就随便安装个地方,我就安装在z盘了
- 然后打开Dosbox,你会发现不管你安装在哪个磁盘,默认进去就是z:/,没有关系,那只是他内部的磁盘罢了,利用mount c 你放exe文件夹的路径,来挂起这个文件夹当做内部磁盘c盘,如果你嫌麻烦,可以点击这个

- 在最下面填上


- 然后进入Dosbox,输入16bit.exe就行了

BabyJar
- 这个很简单,直接拖到jadx,查看反的java代码,看不懂喂给ai让它写脚本
- jadx下载Releases · skylot/jadx (github.com)
1 | import base64 |
TELF
- 依旧查壳,可以看Week1,由于大部分说过,所以省略些部分

- 可以看到有个UPX壳,我们去脱,发现脱不了壳

- 官方WP写的很清楚啊,我们去下个Winhex,吾爱破解就有,自行下载
- upx执行脱壳逻辑的时候,会先识别⼀下⽂件内部的upx标识,也就是”upx”这个字符串,upx只有识别到了它才能认识这个upx程序,从而执行脱壳。
- 反之,如果⼈为地修改这个upx标识,让upx⽆法识别出来,那么脱壳就会失败,这道题就是这样。只要把被修改的字符串改回去就⾏了

- 改一下

- 就成功了

- 丢到IDA,查看c语言伪代码
- 可以注意到,密钥是动态生成的,若需要得到密钥则需要动态调试,但本题是elf文件,动态调试需要远程挂linux(具体操作可以自行搜索学习)
- 有的师傅可能做过相关题⽬,觉得动态调试有点麻烦,因此直接在本地windows的编译器⾥⾯设置相同的种⼦,然后模拟出随机数列得到密钥,最后发现密钥不对
- 这是因为windows和linux两个系统对于随机数的⽣成逻辑不太⼀样,这个程序是在linux中运⾏的,所以在windows系统⽆法模拟出来正确的密钥顺序,必须要在linux中运⾏才可以得到正确的密钥
- 上面是我引用的官方的WP,很高深,学习到了:>
- 这里引用官方WP所给的脚本以及源代码
1 |
|
- 源代码
1 |
|
- 最后结果为

算术高手
- 把它丢进DIE中,可以看到它是pyinstaller打包的exe

- PyInstaller 是⼀个把 Python 脚本及其依赖打包成独立可执行文件(如 .exe),方便分发和运行的工具
- 也就是说这个exe文件里是一堆python代码和依赖文件,不是传统的二进制文件,所以说ida无法分析这个exe文件
- https://github.com/extremecoders-re/pyinstxtractor
- 下载这个工具,分离那些文件


- 下载
uncompyle6 pip install uncompyle6uncompyle6 -o . yourfile.pyc- 这个
.是生成文件在根目录 - 在生成的文件夹下打开cmd

- 然后就能找到.py

- 看到flag,并且这道题认真计算做的话也是得不到flag的,可以看看源代码
Shuffle!Shuffle!
- 直接丢进IDA,看下c语言伪代码

- 这两个地方可以双击点开,esc返回,看下函数
- 当你把那些信息喂给ai,它给你的脚本是几乎得不到答案的
- 看看这个官方WP的脚本吧
- ⽤了随机数打乱,随机种⼦固定,所以可以写代码模拟乱序的序列,然后恢复字符串的正确顺序,但实际上更推荐另⼀种方法:动态调试⼀个固定长度字符全不同的字符串,得到其加密结果,就能还原任意密文。
- 简单来说,就是我们可以先随便输入⼀个没有重复字符且长度和flag相等的字符串,得到它的乱序结果,然后和被乱序的flag进行对比,就能得到正确的flag
1 | enc='23-64bed6}-xm5300-{faGa34-0e04c2e7c2a78f39a4' # 待恢复的密⽂字符串 |
总结
- 这Reverse的题,我如果不看WP可能也只会做出来BabyJar那道题,有些东西确实是看不懂,只能慢慢学了,很多思路和脚本也不是很理解
- 本WP是基于官方WP更为详细的版本,只是我复现的过程,希望能帮助到你
- 题目需要到https://www.ctfplus.cn/自取
关于本文
由 GuQing 撰写,采用 CC BY-NC 4.0 许可协议。