RISC-V 架构
RISC-V 是一种开源的精简指令集架构(ISA),由加州大学伯克利分校于 2010 年发起,现由 RISC-V 国际基金会维护
基本特征
位数:RV32(32位)、RV64(64位)、RV128(未来扩展)。常用的是 RV32/64
字节序:默认为小端(Little-Endian),也允许大端(非主流)
指令格式:定长 16 位(压缩指令)或 32 位(标准指令)。编码极为规整,字段位置几乎固定
模块化指令集:
基础整数指令集(
I):加减、逻辑、移位、分支、访存、系统调用标准扩展:
M:乘除法A:原子操作F / D:单/双精度浮点C:压缩指令(16 位,提高代码密度)V:向量扩展(尚未完全冻结)
组合如 RV64IMAC 即为 64 位基础整数、乘除、原子、压缩指令
寄存器与调用约定
RISC-V 有 32 个通用寄存器(x0–x31),以及可选的浮点寄存器(f0–f31)。每个通用寄存器在 ABI 中有别名和用途
| 寄存器 | ABI 名称 | 用途 | 调用者/被调用者保存 |
|---|---|---|---|
| x0 | zero | 恒为 0 | - |
| x1 | ra | 返回地址 | 调用者保存 |
| x2 | sp | 栈指针 | 被调用者保存 |
| x3 | gp | 全局指针 | 被调用者保存 |
| x4 | tp | 线程指针 | 被调用者保存 |
| x5–x7 | t0–t2 | 临时寄存器 | 调用者保存 |
| x8 | s0 / fp | 帧指针(可用作 s0) | 被调用者保存 |
| x9 | s1 | 保存寄存器 | 被调用者保存 |
| x10–x11 | a0–a1 | 函数参数/返回值 | 调用者保存 |
| x12–x17 | a2–a7 | 函数参数 | 调用者保存 |
| x18–x27 | s2–s11 | 保存寄存器 | 被调用者保存 |
| x28–x31 | t3–t6 | 临时寄存器 | 调用者保存 |
指令格式与编码
RISC-V 的 32 位指令被分成 6 种基本格式(R、I、S、B、U、J),opcode 和 funct3/funct7 字段位置高度一致,反汇编时易于解析
R-type(寄存器-寄存器):
ADD rd, rs1, rs2I-type(寄存器-立即数):
ADDI rd, rs1, imm12S-type(存储):
SW rs2, offset(rs1)B-type(分支):
BEQ rs1, rs2, offsetU-type(上移立即数):
LUI rd, imm20、AUIPC rd, imm20(用于 PC 相对寻址)J-type(跳转):
JAL rd, offset
压缩指令(C 扩展):16 位指令,仅操作常用寄存器(x8–x15),由最低 2 位非 11 标识。C.ADDI4SPN, C.LW, C.J 等。反汇编工具会自动处理
实战案例
IoT(RISC-V 架构 + XOR)

IDA 逆向,根据流程图一步一步来

main 函数用途:
调用
scanf从标准输入读取字符串到全局缓冲区str调用
strlen获取输入长度若长度等于 20,则跳转到
loc_1018E进入处理逻辑;否则顺序执行
1 | main: |
loc_1018E 函数用途:
- 将局部变量
i置零,然后跳到loc_101F4
1 | loc_1018E: |
loc_101F4 函数用途:
从栈上重新加载
i,调用strlen获得长度 20,用bltu比较,若i < 20则跳回loc_10194(循环体),否则退出循环实现一个 20 次迭代的
for循环,用于逐字节处理输入字符串
1 | loc_101F4: |
该循环体对输入字符串 str 的每个字符 str[i] 进行如下操作:
读取
str[i]从
xor表中读取一个 32 位整数xor[i]计算
xor[i] ^ str[i]从
__DATA_BEGIN__表中读取expected[i]比较
xor[i] ^ str[i]与expected[i]
1 | loc_10194: |
提取 xor 表和 __DATA_BEGIN__ 的数据解密
1 | # 已知的 xor 表与 expected 表(32 位整数数组) |
最后得到 flag{XoR_I5_S0_Easy}