re-mips

Installation
Run `npx skills add "https://github.com/dslsdzc/rev-skills" --skill "re-mips"` to install this skill, then follow its SKILL.md instructions for my next request.

Paste this into Claude Code, Cursor, or any agent that can run commands.

What this skill does
What it does: - Reads and understands programs written for MIPS processors - Explains how MIPS instructions work differently from other processors - Handles both big-endian and little-endian MIPS programs - Finds and analyzes web servers and programs inside router firmware - Explains special MIPS features like delayed slots and how functions call each other When to use it: - When you are studying a router or embedded device program - When you have a MIPS program from firmware and need to understand what it does - When you need to know if a program uses big-endian or little-endian byte order - When you are analyzing programs that run on MIPS processors
SKILL.mdShow the author's original SKILL.md (not in English)
---
name: re-mips
description: >
  MIPS 架构逆向与路由器固件分析方法论:延迟槽、$gp 调用约定、大小端判断、httpd 定位。
  触发词:MIPS、mipsel、路由器固件、嵌入式、延迟槽、big-endian、大端、小端、httpd、busybox
---

# MIPS 架构逆向(路由器固件)

## 何时使用 / 何时不用

- 用:MIPS 架构 ELF 样本/恶意软件(路由器、嵌入式设备固件中解出的可执行文件)
- 用:路由器固件内程序(web 后端、服务、工具类二进制)的逻辑分析
- 用:MIPS 大端(mips)/小端(mipsel)任意端序的二进制
- 不用:ARM / x86 等其他架构(通用底座 [[re-binary-core]],本技能只补 MIPS 特有语义)
- 不用:只需解包固件看内容(走 [[re-fw-extract]])
- 不用:只需分析文件系统/配置(走 [[re-fw-rootfs]])
- 不用:需要整体运行固件(走 [[re-fw-emulate]])

## 工具准备

所有工具先验证再使用。静态分析可免沙箱;qemu-user 动态执行默认沙箱 + 网络隔离([[platform-tips]] 最高原则)。

### 反编译器(Ghidra / IDA 任选其一)

- Ghidra(内置 MIPS 处理器模块,mips / mipsel / mips64 / mips64el 变体齐全):
  - Linux: 官方 release 包(需 JDK);部分发行版仓库有 `apt install ghidra` / `pacman -S ghidra`
  - macOS: `brew install --cask ghidra`;Windows: 官方 zip
  - 验证: `analyzeHeadless -help`(headless 模式)或 GUI 导入 MIPS ELF
- IDA:商业版含 MIPS 模块;Freeware 版架构支持范围以官方页面为准
- 导入时确认处理器变体与端序正确(mips 大端 / mipsel 小端),选错全部错位

### binwalk / unblob —— 固件与内嵌文件扫描

- 同 [[re-fw-extract]] 工具准备:`pip install binwalk`(推荐)或发行版包;unblob: `pip install unblob`
- 验证: `binwalk --version`、`unblob --version`

### readelf / file —— 架构与字节序确认(binutils)

- Linux: binutils 自带(`apt install binutils` 等);macOS: `brew install binutils` 或 LLVM 系 readelf;Windows: WSL 内
- 验证: `readelf --version`

### qemu-user —— MIPS 用户态仿真(动态验证)

- Linux: `apt install qemu-user` / `dnf install qemu-user` / `pacman -S qemu-user`
- macOS: `brew install qemu`(含用户态);Windows/WSL: WSL 内 Linux 版
- 大小端是独立二进制:`qemu-mips`(大端)/ `qemu-mipsel`(小端),64 位为 `qemu-mips64` / `qemu-mips64el`
- 验证: `qemu-mips --version`、`qemu-mipsel --version`

### python3

- Linux: `apt install python3` / `dnf install python3` / `pacman -S python`
- macOS: 自带;Windows: 官方安装器
- 验证: `python3 --version`

## 操作步骤

按顺序执行,每步结果存档;步骤 5(动态执行)默认沙箱。

1. **前置:固件提取与架构确认**:
   - 固件整体文件 → [[re-fw-extract]] 解包;解出的文件系统 → [[re-fw-rootfs]];解出的 ELF 继续本步骤
   - 架构确认:
     ```sh
     file target.elf               # 是否 MIPS + 端序提示
     readelf -h target.elf         # Machine=MIPS;Data=big-endian/little-endian
     readelf -A target.elf | head  # 子版本/ABI 附加信息
     ```
   - `file` 输出含 "MIPS" 才进入本技能流程;非 MIPS 转 [[re-binary-core]] 通用底座

2. **字节序判断(大端 / 小端)**:
   - `file` 输出 MSB → 大端(处理器变体 mips);LSB → 小端(mipsel)
   - `readelf -h` 的 Data 字段直接给出端序;e_flags 含 ABI 信息(o32 / n32 / n64)
   - strings 可读性验证:大端数据在小端视角下字节反转(如魔数 `hsqs` 反序出现)
   - 确认后导入反编译器选对变体,后续 $gp、跳转目标、字符串偏移全程按该端序——端序选错则数据、指令、地址全部错位

3. **反编译注意(MIPS 特有语义)**:
   - **延迟槽(硬件特性)**:分支/跳转指令后紧跟的一条指令无条件执行(无论跳转与否,先执行再转移控制);`beq` / `bne` / `j` / `jal` 后常见汇编器填充的 nop 或有用的指令;手读代码时把该指令同时计入跳转两路;补丁时分支后必须处理延迟槽(填 nop 或等价指令);MIPS32r6 起取消延迟槽(r6 代码无此问题)
   - **调用约定**:$a0-$a3 传前 4 个参数(多余参数栈传)、$v0 返回值、$ra 返回地址(`jal` 自动写入)、$s0-$s7 被调用者保存、$t0-$t9 调用者保存;PIC 间接调用模式 `jalr $t9`($t9 载入被调函数地址,函数开头常重载 $gp)
   - **$gp 与 .got**:$gp(r28)一般指向 .got 中间(常见 .got+0x7FF0,±32KB 偏移覆盖整个 GOT);数据访问形如 `lw $t0, off($gp)` / `addiu $t0, $gp, off`;函数序言常见 `lui gp, %hi(...)` + `addiu gp, gp, %lo(...)` 重设 $gp
   - **-mlong-calls 跳板**:`j` / `jal` 立即数跳转只覆盖同 256MB 段(26 位地址左移 2 位),跨段调用由编译期生成 stub 跳板(先加载地址再 `jalr`);看到成片 `lui + addiu + jalr` 三指令序列多为跳板,不要当业务逻辑
   - 反编译器(如 Ghidra)默认处理延迟槽与 GOT 引用,但剥离符号/静态链时 $gp 值需手工确认(见坑 3)

4. **路由器固件专项**:
   - **web 后端 httpd 定位**:rootfs 中找 httpd 系程序(httpd / mini_httpd / boa / lighttpd 及厂商改名版本)与 web 目录(www / htdocs / cgi-bin);字符串搜 "GET " / "HTTP/1" / 响应头字符串定位主请求循环
   - **认证绕过 / 命令注入模式**:搜 `system(` / `popen(` / `exec` 调用点 → 回溯参数来源是否为 URL 参数或 CGI 字段;认证常见缺陷是后端信任可客户端控制的字段(cookie、Referer、固定口令)或硬编码口令比对
   - **busybox 集成命令识别**:busybox 多合一——多个 applet 共用同一 main,按 argv[0] 分发;定位方式:可运行时 `busybox --list`,静态时找符号表中 applet 表(`applet_names`);单二进制内多 applet 逻辑,避免误判"一个函数处理一切"
   - **配置与密码哈希提取**:/etc/passwd、/etc/shadow、/etc/config 配置目录(开源路由系统常见)与 web 备份配置;密码哈希常见 `$1$`(MD5-crypt)、`$5$` / `$6$`(SHA-crypt)及自定义格式;备份配置常 base64 / gzip / 自定义打包(衔接 [[re-fw-rootfs]] 与 [[re-crypto-id]])

5. **动态验证(沙箱)**:
   - 默认沙箱原则:qemu-user 跑 MIPS 程序前先进 [[re-sandbox]](网络隔离 + 快照)
   - ```sh
     qemu-mips -L <rootfs路径> ./target           # 大端;小端用 qemu-mipsel
     qemu-mips -L <rootfs路径> -strace ./target   # 系统调用跟踪
     qemu-mips -L <rootfs路径> -E <ENV=val> ./target
     ```
   - `-L` 指定 rootfs 作为动态加载器/库来源(MIPS 程序常依赖固件内 libc 与配置)
   - 动态只作行为验证(文件/网络/配置读取),主逻辑以静态为主

## 跨域联合

- [[re-firmware]]:固件类样本网关路径(re-firmware → re-fw-extract → re-fw-rootfs → 本技能)
- [[re-fw-extract]] / [[re-fw-rootfs]]:固件解包与文件系统/配置分析前置
- [[re-binary-core]]:MIPS ELF 通用初勘/反编译/调试底座([[re-ghidra]]、[[re-gdb]] 等子技能照常使用)
- [[re-vuln]]:web 认证绕过/命令注入的漏洞确认与利用验证
- [[re-sandbox]]:一切动态执行强制前置([[platform-tips]] 默认沙箱原则)
- 配套:[[re-emulation]](无 qemu 场景用 Unicorn 模拟执行 MIPS 指令)、[[re-fw-emulate]](需要整体启动固件)、[[re-crypto-keys]](配置/固件中硬编码密钥)、[[re-patching]](延迟槽感知的字节补丁)

## 常见坑与陷阱

- **延迟槽执行流错位**:现象——手读分支处逻辑对不上,紧跟分支的指令"看似不该执行"却改变了状态;原因——MIPS 硬件特性:分支/跳转后紧跟的一条指令无条件执行后才转移控制(MIPS32r6 起取消);对策——读代码把延迟槽指令同时计入跳转两路,补丁分支后补 nop/等价指令;依赖反编译器输出时核对延迟槽指令的还原位置
- **大小端判断错 → 全部乱码**:现象——字符串、立即数、地址全乱,反编译面目全非;原因——MIPS 大小端并存(路由器固件多为大端,也有小端),读错端序后 4 字节整字全部错位;对策——`file`(MSB/LSB)+ `readelf -h` Data 字段 + strings 可读性三重确认,导入工具选对 mips / mipsel 变体
- **无重定位信息时 $gp 基址只能猜**:现象——`lw $t0, off($gp)` 指向不明、GOT 引用解不出;原因——剥离符号/静态链后重定位丢失,$gp 值(常见 .got+0x7FF0)需自行确认;对策——在 `_start` / crt0 序言的 `lui gp` + `addiu gp` 处计算实际 gp 值并在反编译器中标注;无符号时按 .got 段基址推算
- **路由器固件非标准头/多层压缩**:现象——binwalk 解不出或解出物不是文件系统,web 后端找不到;原因——厂商自定义头 + 多层压缩/嵌套打包(同 [[re-fw-extract]] 常见坑);对策——hexdump 手工查魔数、跳过头部偏移 dd 切分、逐层 file 确认后再分析
- **反编译工具对伪指令处理差异**:现象——同一函数不同反编译器输出差异大,li / la / move 展开不一致;原因——MIPS 汇编器展开伪指令方式多样(li 拆 lui+ori 等),工具按各自规则还原;对策——以机器码语义为准,跨工具对照,关键逻辑(延迟槽/跳板/GP 引用)回指令级核实
- **busybox 单二进制多 applet 误判**:现象——一个二进制里逻辑"什么都干",找不到入口;原因——busybox 按 argv[0] 分发 applet,全部逻辑共用一个 main;对策——`busybox --list` 或符号表 applet 表(`applet_names`)定位具体 applet,以对应子命令入口为分析起点

Mirrored from the author's public source. Install counts from the open skills registry.

The systems behind these skills get built for partners every week.

Partner with us