LoongArch指令编码拆解:手把手教你读懂龙芯汇编的‘密码本’

张开发
2026/4/19 9:44:40 15 分钟阅读

分享文章

LoongArch指令编码拆解:手把手教你读懂龙芯汇编的‘密码本’
LoongArch指令编码拆解手把手教你读懂龙芯汇编的‘密码本’在二进制分析的黑暗森林里每一条机器指令都是带着面具的舞者。当你在龙芯平台上用调试器打断点看到那一串0x28800024时是否好奇过这组十六进制数字如何对应到人类可读的ld.w $r4, $r0, 0本文将带你像密码学家破译恩尼格玛机那样逐比特解析LoongArch指令的加密逻辑。1. 龙芯指令集的密码学特征龙芯架构的指令编码像精心设计的摩尔斯电码每个比特位都有严格语义。与x86的变长指令不同LoongArch采用32位定长编码这种规整性让逆向工程变得像解九宫格——只要掌握规律再复杂的指令也能拆解。典型的LoongArch指令包含三个关键域操作码域31-24位决定指令类型相当于密码本的目录页操作数域23-0位包含寄存器编号或立即数如同密码正文功能码特定位置细化指令行为类似密码的校验位例如在add.w $r12, $r13, $r14这条指令中| 31-24 | 23-18 | 17-12 | 11-6 | 5-0 | |-----------------------------------| | 操作码 | r13 | r14 | 功能码 | r12 |这种布局使得通过机器码反推汇编指令成为可能。我们来看个实际案例当你在调试器看到0x002a9834时先转换为二进制00000000 00101010 10011000 00110100按域切割31-26位000000→ 主操作码25-22位0000→ 子操作码21-15位1010101→ 源寄存器1r2114-8位0011000→ 源寄存器2r247-0位00110100→ 功能码目的寄存器通过查表可知这是条addu16i.d $r12, $r21, 0x18指令其中立即数藏在特定比特位。2. 九大指令格式深度解析龙芯架构的指令可分为9种编码格式每种都是不同的密码本结构。我们重点分析最常用的三种2.1 3R型指令寄存器间的数学游戏这是最基础的算术指令格式典型代表是add.w、sub.d等。其二进制结构像俄罗斯方块[ opcode ][ rj ][ rk ][ sa ][ rd ] 6 bits 5 bits 5 bits 3 bits 5 bits实战案例解码0x002c3033二进制展开000000 00010 11000 00110 00000 110011按格式解析opcode000000对应ALU操作rj00010r2rk11000r24sa000无移位rd110011r3查功能码表确认这是sll.w $r3, $r2, $r24提示龙芯的寄存器编号从低位开始存放这种设计让指令解码器可以优先提取寄存器号提升解码效率。2.2 I12型指令立即数的艺术这类指令包含12位立即数常用于内存访问。以ld.w为例[ opcode ][ rj ][ rd ][ immediate ] 6 bits 5 bits 5 bits 12 bits特殊之处在于立即数采用符号扩展支持负数偏移。例如解码0x28c00024二进制001010 00110 00000 00000 00000 100100解析opcode001010load指令rj00110r6rd00000r0实际忽略immediate000000001001000x24最终对应ld.w $r4, $r6, 36注意立即数要×42.3 I26型指令长跳转的桥梁这是龙芯最特殊的指令格式26位立即数支持大范围跳转[ opcode ][ immediate ] 6 bits 26 bits典型代表是b指令。解码0x5400000c二进制010101 000000000000000000001100立即数需要左移2位0x30计算跳转地址PC 0x303. 逆向工程实战技巧3.1 离线解码三板斧在没有调试器的情况下可以这样手动解析十六进制转二进制echo obase2; ibase16; 28800024 | bc制作位域切割模板def decode_3r(insn): opcode (insn 26) 0x3f rj (insn 15) 0x1f rk (insn 10) 0x1f rd insn 0x1f return (opcode, rj, rk, rd)使用官方编码手册 [龙芯架构参考手册]中提供了完整的操作码映射表例如操作码指令类型功能码范围0x00ALU0x00-0x3F0x28Load0x00-0x073.2 常见指令速查表为方便逆向工作建议保存这些高频指令特征机器码前缀指令类型示例0x28加载指令ld.w0x29存储指令st.w0x00算术运算add.w0x54条件跳转beqz4. 高级解码技术4.1 向量指令解析龙芯的SIMD指令采用特殊编码例如vadd.b指令[ 111011 ][ rj ][ rk ][ vd ][ 000 ][ 000101 ] 6 bits 5 bits 5 bits 5 bits 3 bits 6 bits解码要点操作码前导位总是111功能码决定具体操作加/减/乘等向量寄存器编号从vr0到vr314.2 自动化解码脚本使用Capstone引擎可以快速构建解码工具from capstone import * md Cs(CS_ARCH_LOONGARCH, CS_MODE_LOONGARCH64) for insn in md.disasm(b\x28\x80\x00\x24, 0x1000): print(f{insn.address:x}: {insn.mnemonic} {insn.op_str})输出示例1000: ld.w $r4, $r0, 0在实际漏洞分析中我曾遇到过一个有趣的案例某段加密算法的关键指令0x0380000d被误判为nop实际是movgr2fr.d $f13, $r0这个发现直接导致算法逆向成功。

更多文章