尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

MIPS逆向工程入门:从babymips解析到实战技巧

MIPS逆向工程入门:从babymips解析到实战技巧 1. 逆向工程入门从babymips开始第一次接触逆向工程时我盯着那个名为babymips的CTF题目发了半小时呆。作为攻防世界(CTF比赛平台)中经典的逆向入门题它完美诠释了什么叫看似简单实则暗藏玄机。MIPS架构的逆向分析对于大多数从x86入门的逆向新手来说就像突然被扔到了异国他乡——指令集不同、寄存器用法不同、甚至连字节序都是反的。提示MIPS架构采用大端序存储而x86是小端序这是逆向分析时第一个需要注意的关键差异点。我清楚地记得第一次用IDA Pro打开babymips时的困惑那些$v0、$a0寄存器是什么为什么跳转指令长得这么奇怪lw和sw指令又在操作什么经过十几个小时的折腾和查阅资料终于搞明白这道题在考察逆向工程师最基础的三项能力静态分析工具的使用熟练度IDA/Ghidra对非x86架构的适应能力基础密码算法的识别与破解2. 环境搭建与工具链配置2.1 模拟器选择与配置分析MIPS架构程序首先需要合适的运行环境。我尝试过三种方案QEMU用户模式最轻量但调试功能有限qemu-mips -g 1234 ./babymipsQEMU系统模式需要下载Debian MIPS镜像约2GBqemu-system-mips -kernel vmlinux -hda debian.img -append root/dev/sda1Docker容器最推荐的方式快速部署且资源占用小FROM multiarch/debian-debootstrap:mips-jessie RUN apt-get update apt-get install -y gdb-multiarch实测发现第三种方案配合gef插件效果最佳。安装完成后需要特别注意# 设置qemu静态解释器路径 export QEMU_LD_PREFIX/usr/mips-linux-gnu # 使用gdb-multiarch连接 gdb-multiarch -q ./babymips -ex target remote :12342.2 逆向工具链配置静态分析推荐组合使用IDA Pro 7.7必须安装MIPS处理器模块Ghidra 10.1免费但反编译质量稍差Binwalk用于固件提取本题不需要动态调试必备插件GEF增强版GDB调试界面Pwndbg专为CTF优化的调试工具radare2命令行逆向瑞士军刀特别要注意IDA的MIPS处理器设置在Options-General中勾选Show full instruction设置Analysis-Processor options为mipsb大端模式启用Cross references中的Create function tails3. babymips题目深度解析3.1 初始文件分析拿到题目文件首先执行常规检查file babymips # 输出: ELF 32-bit MSB executable, MIPS, MIPS32 rel2 version 1 checksec --filebabymips # 结果: 无NX保护、无PIE、部分RELRO用IDA加载后立即注意到几个关键点入口函数start最终调用main地址0x00400740存在明显的字符串比较逻辑xref到Correct!发现可疑函数sub_4007F0包含大量算术运算3.2 核心算法逆向在地址0x00400884处发现关键比较lui $v0, 0x41 lw $v1, 0x28var_10($fp) lw $v0, 0x28var_14($fp) nop bne $v1, $v0, loc_4008C8通过交叉引用追踪发现输入验证流程用户输入被存入$s2寄存器经过sub_4007F0函数处理结果与硬编码值0x41比较重点分析sub_4007F0函数// 伪代码还原 int check(char* input) { int sum 0; for(int i0; i8; i) { sum (input[i] ^ 0x20) 0x10; } return sum 0x41; }3.3 密码学特征识别这个算法表现出典型的线性校验和特征每个字节独立处理无雪崩效应使用固定异或值0x20空格字符的ASCII累加和检查容易碰撞通过数学推导可建立方程Σ(input[i] ^ 0x20 0x10) 0x41 即 Σ(input[i]) 0x41 - 8*0x10 8*0x20 0xE1这意味着任何8字节输入只要ASCII码总和为225即可通过验证。例如aaaaaaae (97*7 101 225) ABCDEFGH (6566676869707172548) → 不符合4. 漏洞利用与Payload构造4.1 基础解法根据上述分析最简单的解法是print(a*7 chr(225-97*7)) # 输出: aaaaaaae但作为CTF题目通常需要更通用的解法脚本from z3 import * s Solver() inp [BitVec(fc_{i}, 8) for i in range(8)] for c in inp: s.add(c 0x20, c 0x7e) # 可打印字符 sum_val sum((c ^ 0x20) 0x10 for c in inp) s.add(sum_val 0x41) if s.check() sat: m s.model() print(.join([chr(m[c].as_long()) for c in inp])) # 可能输出: !\#$%(4.2 进阶技巧在实际比赛中还可以采用以下方法暴力破解由于密钥空间小8字节可打印字符from itertools import product for p in product(range(0x20,0x7f), repeat8): if sum((x^0x20)0x10 for x in p) 0x41: print(bytes(p)) break符号执行使用angr框架import angr p angr.Project(./babymips) state p.factory.entry_state() simgr p.factory.simulation_manager(state) simgr.explore(find0x4008B0) # Correct分支 print(simgr.found[0].posix.dumps(0))动态插桩使用QEMU模式下的PIN工具5. MIPS逆向的特殊技巧5.1 寄存器使用惯例MIPS架构有固定的寄存器用途寄存器别名用途$v0-$v1函数返回值$a0-$a3函数参数$t0-$t9临时寄存器$s0-$s7保存寄存器$gp全局指针$sp栈指针$ra返回地址在babymips中观察到$s2存储用户输入指针$v0常用于系统调用号$a0常作为printf参数5.2 延迟槽机制MIPS特有的分支延迟槽特性beq $a0, $a1, loc_400800 move $v0, $zero # 这条指令总会执行无论分支是否跳转延迟槽中的指令都会执行。逆向时容易误判执行流。5.3 常见指令速查指令等效C代码说明lwreg *addr加载字sw*addr reg存储字luireg imm 16加载高位立即数orireg immjalcall func跳转并链接jrreturn跳转寄存器sltreg (a b)设置条件6. 逆向工程学习路线建议通过babymips这道题我总结出逆向新手的进阶路径工具熟练阶段1-2周掌握IDA基本操作交叉引用(X)、重命名(N)、注释(:)熟悉GDB调试命令break、stepi、x/i、info registers学会使用Hex-Rays反编译器F5快捷键架构适应阶段按优先级x86 → ARM → MIPS → PowerPC32位 → 64位小端序 → 大端序算法识别训练常见加密算法特征AES的S盒、RC4的KSA等压缩算法特征zlib头、LZMA字典等编码特征Base64的填充、Hex的0x前缀CTF专项突破先从简单逆向题开始如攻防世界新手区逐步挑战复杂保护机制UPX壳、ollvm混淆等最后研究真实恶意软件样本我个人的练习方法是每天分析1个CTF题目1个真实世界软件的小功能。坚持三个月后再看babymips这类题目会觉得异常简单。逆向工程最关键的还是经验积累没有捷径可走。
返回列表