文章总结: 本文档详细分析Frida框架中CPU指令相关模块的JavaScriptAPI与底层C/C++实现之间的五层架构映射关系,涵盖Instruction、X86Writer、Arm64Writer等模块的函数对应表、内存布局和跨平台差异处理。核心发现包括完整的JS-C++函数映射关系、指令集架构抽象机制以及实战应用案例,为开发者提供底层动态代码分析和指令级控制的实用技术参考。 综合评分: 82 文章分类: 逆向分析,二进制安全,漏洞分析,安全工具,WEB安全
frida各模块js与cpp函数分析对照(七)
原创
haidragon haidragon
安全狗的自我修养
2026年4月5日 11:40 湖南
-
官网:http://securitytech.cc
CPU和Instruction模块 JavaScript与底层C++函数映射关系分析
文档概述
本文档详细分析Frida中CPU指令相关模块(包括Instruction、X86Writer、Arm64Writer等)的JavaScript API与其底层C/C++实现之间的映射关系,涵盖完整的五层架构模型分析。
五层架构模型分析
1. 接口定义层 (JavaScript API Layer)
CPU模块主要接口:
Instruction模块主要接口:
指令写入器模块:
主要接口包括:
枚举类型:
2. 基础结构层 (GumJS Binding Layer)
在
subprojects/frida-gum/bindings/gumjs目录中,CPU和Instruction模块的绑定实现在相关文件中。关键数据结构
### 3. 具体实现层 (Platform-specific Implementation)
#### Instruction实现 ( guminstruction.c)
关键函数:
#### 指令写入器实现
关键函数:
#### 指令重定位器实现
关键函数:
### 4. 工厂模式层 (Backend Factory)
#### 指令解析器工厂
#### 指令写入器工厂
#### 指令重定位器工厂
### 5. 应用集成层 (Integration with Frida Core)
CPU和Instruction模块通过frida-core与上层应用集成,为Interceptor、Stalker等高级功能提供底层支持,并与代码生成和动态插桩深度集成。
## 详细函数映射关系表
### Instruction映射表
| JavaScript Function | C Function | File Location | Description |
| — | — | — | — |
| Instruction.parse() | gum_instruction_parse() | guminstruction.c | 解析指定地址的指令 |
| instruction.address | gum_instruction_get_address() | guminstruction.c | 获取指令地址 |
| instruction.mnemonic | gum_instruction_get_mnemonic() | guminstruction.c | 获取助记符 |
| instruction.opStr | gum_instruction_get_op_str() | guminstruction.c | 获取操作数字符串 |
### X86Writer映射表
| JavaScript Constructor/Method | C Function | File Location | Description |
| — | — | — | — |
| newX86Writer() | gum_x86_writer_new() | gumx86writer.c | 创建x86指令写入器 |
| putCallAddressWithArguments() | gum_x86_writer_put_call_address_with_arguments() | gumx86writer.c | 生成函数调用指令 |
| putJmpAddress() | gum_x86_writer_put_jmp_address() | gumx86writer.c | 生成跳转指令 |
| flush() | gum_x86_writer_flush() | gumx86writer.c | 刷新写入器缓冲区 |
### Arm64Writer映射表
| JavaScript Constructor/Method | C Function | File Location | Description |
| — | — | — | — |
| newArm64Writer() | gum_arm64_writer_new() | gumarm64writer.c | 创建ARM64指令写入器 |
| putCallAddressWithArguments() | gum_arm64_writer_put_call_address_with_arguments() | gumarm64writer.c | 生成函数调用指令 |
| putBImm() | gum_arm64_writer_put_b_imm() | gumarm64writer.c | 生成分支指令 |
| flush() | gum_arm64_writer_flush() | gumarm64writer.c | 刷新写入器缓冲区 |
### Relocator映射表
| JavaScript Constructor/Method | C Function | File Location | Description |
| — | — | — | — |
| newX86Relocator() | gum_x86_relocator_new() | gumx86relocator.c | 创建x86指令重定位器 |
| readOne() | gum_x86_relocator_read_one() | gumx86relocator.c | 读取一条指令 |
| writeAll() | gum_x86_relocator_write_all() | gumx86relocator.c | 写入所有重定位指令 |
## 内存布局与数据结构可视化
### GumInstruction结构体内存布局
### GumX86Writer结构体内存布局
### GumArm64Writer结构体内存布局
### GumX86Relocator结构体内存布局
## 系统调用级执行流程追踪
### Instruction.parse()执行流程
### X86Writer.putCallAddressWithArguments()执行流程
### Arm64Writer.putBImm()执行流程
### X86Relocator.readOne()执行流程
## 跨平台差异与抽象机制
### 指令集架构差异
#### x86/x86_64架构特点
#### ARM/ARM64架构特点
#### MIPS架构特点
### ABI差异处理
### 抽象层设计
## 调试命令与安全实践
### GDB调试示例
### 性能优化建议
### 安全考虑
## 错误处理与边界情况
### 常见错误场景
### 最佳实践
## 攻击检测场景映射
### 可用于检测的场景
### 防御绕过技术
## 性能分析与优化
### 时间复杂度分析
### 内存使用分析
## 扩展功能与自定义实现
### 自定义指令分析工具
### 自定义代码生成器
### 底层扩展点
## 版本兼容性与演进
### API变更历史
### 向后兼容性保证
## 实战案例分析
### 案例1: 动态代码补丁
### 案例2: ROP链构建
### 案例3: ARM64函数Hook
### 案例4: 指令级别性能剖析
## 总结与最佳实践
CPU和Instruction模块是Frida最底层也是最强大的功能之一,提供了对机器指令级别的精确控制能力。理解其JS与C++的映射关系有助于:
通过本文档的五层架构分析,开发者可以全面掌握CPU和Instruction模块的工作原理和使用技巧,为底层动态分析任务提供坚实的基础。
-
核心API保持稳定
-
新功能通过扩展方式添加
-
废弃的API会标记并提供迁移路径
-
Frida早期版本: 基本的x86指令支持
-
Frida 6.x: 添加ARM和ARM64支持
-
Frida 8.x: 完善跨平台支持和性能优化
-
Frida 10.x: 添加MIPS支持和更多指令特性
-
Frida 12.x: 优化内存使用和错误处理
-
Frida 14.x: 改进指令解析准确性和性能
-
可以通过修改
guminstruction.c添加新的指令解析特性 -
通过修改
gumx86writer.c等文件添加新的指令生成原语 -
扩展指令重定位器支持更复杂的控制流模式
-
添加新的架构支持(如RISC-V、PowerPC等)
-
Instruction对象: 每个对象占用固定内存(包含字符串和数组)
-
Writer缓冲区: 需要预分配足够的代码缓冲区
-
Relocator缓冲区: 需要存储输入和输出指令信息
-
优化建议:
-
重用Instruction对象避免频繁分配
-
预估代码大小避免缓冲区重新分配
-
及时释放不再需要的对象
-
Instruction.parse(): O(1),单条指令解析
-
Writer操作: O(1),每条指令生成
-
Relocator操作: O(n),n为重定位的指令数量
-
批量操作: O(m),m为总指令数量
-
指令混淆: 使用等价但不同的指令序列
-
多态代码: 运行时动态生成不同的指令序列
-
加密指令: 加密存储指令,运行时解密执行
-
间接跳转: 使用间接跳转隐藏控制流
-
代码注入检测: 监控可执行内存的分配和修改
-
ROP链检测: 分析可疑的指令序列模式
-
Shellcode检测: 识别常见的shellcode特征
-
反调试检测: 检测指令级别的反调试技术
-
Instruction错误:
-
无效地址:无法读取指令字节
-
无效指令:遇到未定义的操作码
-
内存保护:无法访问受保护的内存区域
-
Writer错误:
-
缓冲区溢出:写入超出分配的代码缓冲区
-
无效地址:跳转目标超出指令范围
-
ABI不匹配:参数类型与ABI要求不符
-
Relocator错误:
-
指令边界:无法正确识别指令边界
-
自修改代码:重定位过程中代码被修改
-
复杂控制流:无法处理复杂的跳转模式
-
内存保护: 确保代码缓冲区具有可执行权限
-
地址验证: 验证跳转和调用目标地址的有效性
-
缓冲区溢出: 避免指令写入超出分配的缓冲区
-
异常处理: 正确处理无效指令和编码错误
-
指令缓存: 缓存常用的指令序列避免重复生成
-
批量写入: 减少flush()调用次数,批量生成指令
-
内存对齐: 确保代码缓冲区正确对齐以获得最佳性能
-
架构特定优化: 利用特定架构的优化指令
-
x86_64 System V ABI (Unix/Linux/macOS):
-
参数传递:整数%rdi, %rsi, %rdx, %rcx, %r8, %r9;浮点%xmm0-%xmm7
-
返回值:整数%rax,浮点%xmm0
-
栈对齐:16字节对齐
-
Microsoft x64 ABI (Windows):
-
参数传递:整数%rcx, %rdx, %r8, %r9;浮点%xmm0-%xmm3
-
影子空间:调用者为前4个参数预留32字节栈空间
-
栈对齐:16字节对齐
-
ARM64 AAPCS64 ABI:
-
参数传递:整数x0-x7,浮点v0-v7
-
返回值:整数x0,浮点v0
-
栈对齐:16字节对齐
-
固定长度指令: 32位固定长度
-
延迟槽: 分支指令后的延迟槽
-
加载/存储架构: 类似ARM的内存访问模式
-
流水线优化: 指令流水线设计考虑
-
固定长度指令: ARM64为32位固定长度
-
条件执行: ARM支持条件执行指令
-
加载/存储架构: 只有加载/存储指令访问内存
-
Thumb模式: ARM支持16/32位混合指令集
-
变长指令: 1-15字节不等
-
复杂寻址模式: 支持多种内存寻址方式
-
寄存器重命名: 现代CPU的寄存器重命名机制
-
指令前缀: 支持多种指令前缀(LOCK, REP, SEG等)
-
是否为跳转指令
-
是否为调用指令
-
是否有延迟槽(MIPS)
-
System V ABI: 前6个整数参数使用%rdi, %rsi, %rdx, %rcx, %r8, %r9
-
Microsoft x64 ABI: 前4个整数参数使用%rcx, %rdx, %r8, %r9
-
x86/x86_64: 使用Intel XED或Capstone反汇编引擎
-
ARM/ARM64: 使用自定义ARM指令解码器
-
MIPS: 使用自定义MIPS指令解码器
-
gum_x86_relocator_new() -
gum_x86_relocator_read_one() -
gum_x86_relocator_write_all() -
x86/x86_64:
gumx86relocator.c– x86指令重定位 -
ARM/ARM64:
gumarmrelocator.c,gumarm64relocator.c– ARM指令重定位 -
Thumb:
gumthumbrelocator.c– Thumb指令重定位 -
MIPS:
gummipsrelocator.c– MIPS指令重定位 -
gum_x86_writer_new() -
gum_x86_writer_put_call_address_with_arguments() -
gum_x86_writer_put_jmp_address() -
gum_x86_writer_flush() -
x86/x86_64:
gumx86writer.c– x86指令生成 -
ARM/ARM64:
gumarmwriter.c,gumarm64writer.c– ARM指令生成 -
Thumb:
gumthumbwriter.c– Thumb指令生成 -
MIPS:
gummipswriter.c– MIPS指令生成 -
gum_instruction_parse() -
gum_instruction_free() -
gum_instruction_get_address() -
gum_instruction_get_mnemonic() -
通用指令解析:
guminstruction.c– 跨平台指令解析框架 -
平台特定后端:
-
x86/x86_64:
gumx86reader.c– 基于Intel XED或Capstone -
ARM/ARM64:
gumarmreader.c,gumarm64reader.c– ARM指令解析 -
MIPS:
gummipsreader.c– MIPS指令解析 -
x86:
X86Register,X86OperandType,X86Group -
ARM:
ArmRegister,ArmOperandType,ArmGroup -
ARM64:
Arm64Register,Arm64OperandType,Arm64Group -
MIPS:
MipsRegister,MipsOperandType,MipsGroup -
newX86Writer(codeAddress[,options]) -
writer.putCallAddressWithArguments(func,argTypes,args) -
writer.putJmpAddress(address) -
writer.flush() -
writer.reset(codeAddress) -
X86/X86_64:
X86Writer,X86Relocator -
ARM/ARM64:
ArmWriter,ArmRelocator,Arm64Writer,Arm64Relocator -
Thumb:
ThumbWriter,ThumbRelocator -
MIPS:
MipsWriter,MipsRelocator -
Instruction.parse(target) -
Instruction.prototype.address -
Instruction.prototype.mnemonic -
Instruction.prototype.opStr -
Instruction.prototype.operands -
Instruction.prototype.regsRead -
Instruction.prototype.regsWritten -
Instruction.prototype.groups -
Instruction.prototype.next -
CPU.arch -
CPU.endian -
CPU.pointerSize
-
精确控制: 对目标进程的机器码进行精确的修改和生成
-
性能优化: 利用底层指令特性实现高性能的动态插桩
-
安全分析: 进行指令级别的安全检测和漏洞利用分析
-
逆向工程: 辅助复杂的二进制逆向工程任务
-
// 指令级别的性能剖析 -
function profileInstructions(targetFunc, durationMs =1000){ -
const instructionCounts =newMap(); -
const startTime =Date.now(); -
// Hook函数入口 -
Interceptor.attach(targetFunc,{ -
onEnter:function(args){ -
let currentAddr =this.context.pc; -
const endTime =Date.now()+10;// 最多分析10ms -
// 动态跟踪执行的指令 -
while(Date.now()< endTime){ -
try{ -
const instr =Instruction.parse(currentAddr); -
const key =${instr.mnemonic}:${instr.opStr}; -
instructionCounts.set(key,(instructionCounts.get(key)||0)+1); -
// 模拟执行(仅用于计数,不实际执行) -
currentAddr = currentAddr.add(instr.size); -
// 简单的控制流处理 -
if(instr.mnemonic.startsWith('ret')){ -
break;// 函数返回 -
}elseif(instr.mnemonic.startsWith('jmp')){ -
// 简化的跳转处理(实际需要更复杂的分析) -
break; -
} -
}catch(e){ -
break;// 遇到无效指令停止 -
} -
} -
} -
}); -
// 等待指定时间 -
setTimeout(()=>{ -
console.log('Instruction profiling results:'); -
const sorted =Array.from(instructionCounts.entries()) -
.sort((a, b)=> b[1]- a[1]) -
.slice(0,20);// 显示前20个 -
sorted.forEach(([instr, count])=>{ -
console.log(${count}: ${instr}); -
}); -
}, durationMs); -
} -
// ARM64特定的函数Hook实现 -
function hookArm64Function(targetFunc, hookFunc){ -
if(Process.arch !=='arm64'){ -
thrownewError('This function only works on ARM64'); -
} -
// 保存原始指令(ARM64指令为4字节) -
const originalInstrs = targetFunc.readByteArray(8);// 保存2条指令 -
// 分配trampoline内存 -
const trampolineSize =32; -
const trampoline =Memory.alloc(trampolineSize); -
Memory.protect(trampoline, trampolineSize,'rwx'); -
// 生成trampoline代码 -
const writer =newArm64Writer(trampoline); -
// 执行原始指令 -
writer.putBytes(originalInstrs); -
// 跳转回原函数(跳过被替换的指令) -
writer.putBImm(targetFunc.add(8)); -
writer.flush(); -
// 修改原函数为跳转到hook函数 -
const hookWriter =newArm64Writer(targetFunc); -
hookWriter.putLdrRegAddress('x17', hookFunc);// 加载hook函数地址到x17 -
hookWriter.putBrReg('x17');// 跳转到x17 -
hookWriter.flush(); -
console.log('ARM64 function hooked successfully'); -
return{ originalInstrs, trampoline }; -
} -
// 构建简单的ROP链 -
function buildROPChain(gadgets, finalTarget){ -
const chainSize = gadgets.length *Process.pointerSize +Process.pointerSize; -
const chain =Memory.alloc(chainSize); -
let currentPtr = chain; -
// 填充gadgets -
gadgets.forEach(gadgetAddr =>{ -
currentPtr.writePointer(gadgetAddr); -
currentPtr = currentPtr.add(Process.pointerSize); -
}); -
// 填充最终目标 -
currentPtr.writePointer(finalTarget); -
return chain; -
} -
// 查找有用的gadgets -
function findGadgets(moduleName, gadgetPattern){ -
const module =Process.findModuleByName(moduleName); -
const results =[]; -
Memory.scanSync(module.base, module.size, gadgetPattern).forEach(match =>{ -
try{ -
const instr =Instruction.parse(match.address); -
if(instr.mnemonic ==='ret'|| instr.mnemonic ==='pop'|| instr.mnemonic ==='add'){ -
results.push(match.address); -
} -
}catch(e){ -
// 忽略无效指令 -
} -
}); -
return results; -
} -
// 动态修补函数中的特定指令 -
function patchFunction(targetFunc, patchCallback){ -
// 解析函数入口指令 -
const firstInstr =Instruction.parse(targetFunc); -
console.log('Original instruction:', firstInstr.mnemonic, firstInstr.opStr); -
// 分配补丁代码内存 -
const patchSize =32;// 足够大的缓冲区 -
const patchCode =Memory.alloc(patchSize); -
Memory.protect(patchCode, patchSize,'rwx'); -
// 生成补丁代码 -
const writer =new X86Writer(patchCode); -
// 调用补丁回调函数 -
writer.putCallAddressWithArguments(patchCallback,['pointer'],[targetFunc]); -
// 跳转回原始函数(跳过被替换的指令) -
const returnAddr = targetFunc.add(firstInstr.size); -
writer.putJmpAddress(returnAddr); -
writer.flush(); -
// 修改原函数入口为跳转到补丁代码 -
const originalBytes = targetFunc.readByteArray(firstInstr.size); -
targetFunc.writeU8(0xE9);// JMP rel32 -
targetFunc.add(1).writeS32(patchCode.sub(targetFunc.add(5)).toInt32()); -
console.log('Function patched successfully'); -
return{ originalBytes, patchCode }; -
} -
// 高级代码生成器 -
classCodeGenerator{ -
constructor(codeAddress, arch =Process.arch){ -
this.arch = arch; -
this.writer =this.createWriter(codeAddress); -
this.labels =newMap(); -
this.fixups =[]; -
} -
createWriter(codeAddress){ -
switch(this.arch){ -
case'x64': -
returnnew X86Writer(codeAddress); -
case'arm64': -
returnnewArm64Writer(codeAddress); -
default: -
thrownewError(Unsupported architecture: ${this.arch}); -
} -
} -
defineLabel(name){ -
this.labels.set(name,this.writer.pc); -
} -
callFunction(func, args =[]){ -
this.writer.putCallAddressWithArguments(func, -
args.map(arg =>typeof arg ==='number'?'int':'pointer'), -
args); -
} -
jumpToLabel(labelName){ -
const labelAddr =this.labels.get(labelName); -
if(labelAddr){ -
this.writer.putJmpAddress(labelAddr); -
}else{ -
// 延迟修复 -
this.fixups.push({ type:'jmp', label: labelName, pos:this.writer.code }); -
this.writer.putJmpNearLabel();// 占位符 -
} -
} -
flush(){ -
// 应用延迟修复 -
this.fixups.forEach(fixup =>{ -
if(fixup.type ==='jmp'){ -
const target =this.labels.get(fixup.label); -
if(target){ -
// 重新定位跳转指令 -
this.relocateJump(fixup.pos, target); -
} -
} -
}); -
returnthis.writer.flush(); -
} -
relocateJump(jumpPos, target){ -
// 根据架构重新编码跳转指令 -
switch(this.arch){ -
case'x64': -
// x86相对跳转重定位 -
const offset = target.sub(jumpPos.add(5)).toInt32(); -
jumpPos.add(1).writeS32(offset); -
break; -
case'arm64': -
// ARM64 B指令重定位 -
const armOffset = target.sub(jumpPos.add(4)).toInt32(); -
const bInstr =0x14000000|((armOffset >>2)&0x3FFFFFF); -
jumpPos.writeU32(bInstr); -
break; -
} -
} -
} -
// 指令模式匹配 -
function findInstructionPattern(startAddr, endAddr, pattern){ -
const matches =[]; -
let currentAddr = startAddr; -
while(currentAddr.compare(endAddr)<0){ -
try{ -
const instr =Instruction.parse(currentAddr); -
if(instr.mnemonic === pattern.mnemonic && -
instr.opStr === pattern.opStr){ -
matches.push(instr); -
} -
currentAddr = currentAddr.add(instr.size); -
}catch(e){ -
// 跳过无效指令 -
currentAddr = currentAddr.add(1); -
} -
} -
return matches; -
} -
// 控制流图生成 -
function generateControlFlowGraph(startAddr, maxInstructions =1000){ -
const cfg =newMap(); -
const visited =newSet(); -
const queue =[startAddr]; -
while(queue.length >0&& visited.size < maxInstructions){ -
const addr = queue.shift(); -
if(visited.has(addr.toString()))continue; -
visited.add(addr.toString()); -
try{ -
const instr =Instruction.parse(addr); -
cfg.set(addr.toString(),{ -
address: addr, -
mnemonic: instr.mnemonic, -
opStr: instr.opStr, -
successors:[] -
}); -
// 分析控制流指令 -
if(instr.mnemonic.startsWith('j')|| instr.mnemonic ==='call'){ -
// 简化的跳转目标分析 -
const target = analyzeJumpTarget(instr, addr); -
if(target){ -
cfg.get(addr.toString()).successors.push(target); -
queue.push(target); -
} -
} -
// 继续下一条指令(非无条件跳转) -
if(!instr.mnemonic.startsWith('jmp')){ -
queue.push(addr.add(instr.size)); -
} -
}catch(e){ -
// 跳过无效指令 -
} -
} -
return cfg; -
} -
// 安全的指令解析 -
function safeParseInstruction(address){ -
try{ -
if(!address || address.isNull()){ -
thrownewError('Invalid address'); -
} -
const instruction =Instruction.parse(address); -
return instruction; -
}catch(e){ -
console.error('Failed to parse instruction:', e); -
returnnull; -
} -
} -
// 安全的指令写入 -
function safeWriteInstructions(codeAddress, size, writeFunc){ -
try{ -
// 分配可执行内存 -
const codePtr =Memory.alloc(size); -
Memory.protect(codePtr, size,'rwx'); -
// 创建写入器 -
const writer =new X86Writer(codePtr); -
// 执行写入操作 -
writeFunc(writer); -
// 刷新并返回 -
writer.flush(); -
return codePtr; -
}catch(e){ -
console.error('Failed to write instructions:', e); -
returnnull; -
} -
} -
// 安全的指令重定位 -
function safeRelocateInstructions(inputCode, inputSize, outputWriter){ -
try{ -
const relocator =new X86Relocator(inputCode, outputWriter); -
let instructionCount =0; -
while(!relocator.eoi()&& instructionCount <1000){// 防止无限循环 -
const instruction = relocator.readOne(); -
if(instruction){ -
// 处理指令重定位逻辑 -
relocator.writeAll(); -
instructionCount++; -
} -
} -
return instructionCount; -
}catch(e){ -
console.error('Failed to relocate instructions:', e); -
return0; -
} -
} -
# 在指令解析处设置断点 -
(gdb)break gum_instruction_parse -
# 查看指令解析过程 -
(gdb) info args -
(gdb) x/10i $rdi # 查看目标地址的指令 -
(gdb) print *(GumInstruction*)$rax -
# 在指令写入处设置断点 -
(gdb)break gum_x86_writer_put_call_address_with_arguments -
(gdb) info registers -
(gdb) x/20i $rdi # 查看写入器当前代码 -
// CPU架构抽象 -
typedefenum{ -
GUM_CPU_INVALID, -
GUM_CPU_IA32,// x86 32-bit -
GUM_CPU_X86_64,// x86 64-bit -
GUM_CPU_ARM,// ARM 32-bit -
GUM_CPU_ARM64,// ARM 64-bit -
GUM_CPU_MIPS // MIPS 32/64-bit -
}GumCpuType; -
// 指令写入器抽象 -
struct_GumInstructionWriter -
{ -
GObject parent; -
GumCpuType cpu_type; -
gpointer code; -
GumAddress pc; -
void(* put_call_address_with_arguments)(GumInstructionWriter* self,GumAddress func,const gchar ** arg_types, gsize arg_count,...); -
void(* put_jmp_address)(GumInstructionWriter* self,GumAddress address); -
gboolean (* flush)(GumInstructionWriter* self); -
void(* reset)(GumInstructionWriter* self, gpointer code_address); -
}; -
// 指令重定位器抽象 -
struct_GumRelocator -
{ -
GObject parent; -
GumCpuType cpu_type; -
gconstpointer input_start; -
gconstpointer input_cur; -
GumInstructionWriter* output; -
guint (* read_one)(GumRelocator* self,GumInstruction** instruction); -
gboolean (* eoi)(GumRelocator* self); -
void(* write_all)(GumRelocator* self); -
}; -
将指令信息存储在重定位器的内部缓冲区
-
更新输入位置指针
-
返回解析的指令对象
-
JavaScript调用
relocator.readOne()→ GumJS绑定层 -
调用
gum_x86_relocator_read_one(relocator,&instruction) -
从输入代码当前位置解析一条指令
-
分析指令类型和特性:
-
JavaScript调用
writer.putBImm(target)→ GumJS绑定层 -
调用
gum_arm64_writer_put_b_imm(writer,target) -
计算相对偏移:
offset=target-(current_pc+4) -
验证偏移是否在ARM64 B指令范围内(±128MB)
-
编码B指令:
0x14000000|((offset>>2)&0x3FFFFFF) -
将编码后的指令写入代码缓冲区
-
更新程序计数器
-
生成参数设置指令(mov, push等)
-
生成call指令
-
如果需要,生成栈清理指令
-
更新写入器的程序计数器
-
JavaScript调用
writer.putCallAddressWithArguments(func,argTypes,args)→ GumJS绑定层 -
调用
gum_x86_writer_put_call_address_with_arguments(writer,func,argTypes,args) -
根据ABI确定参数传递方式:
-
解析指令的各个组成部分(操作码、操作数、寄存器等)
-
创建GumInstruction结构体并填充信息
-
返回JavaScript Instruction对象
-
JavaScript调用
Instruction.parse(target)→ GumJS绑定层 -
调用
gum_instruction_parse(target) -
检测目标CPU架构
-
调用对应架构的指令解析器:
-
+------------------+ -
| input_start (gconstpointer)|->输入代码起始地址 -
+------------------+ -
| input_cur (gconstpointer)|->当前输入位置 -
+------------------+ -
| output (GumX86Writer*)|->输出写入器 -
+------------------+ -
| inpos (guint)|->输入缓冲区位置 -
+------------------+ -
| outpos (guint)|->输出缓冲区位置 -
+------------------+ -
| eoi (gboolean)|->是否到达输入末尾 -
+------------------+ -
| delay_slot_pending (gboolean)|->延迟槽待处理(MIPS) -
+------------------+ -
+------------------+ -
|base(GumCodeWriter)|->基础代码写入器 -
+------------------+ -
| code (guint32*)|->当前代码指针(32位对齐) -
+------------------+ -
| pc (GumAddress)|->当前程序计数器 -
+------------------+ -
| id_to_reg (GumArm64Reg[GUM_ARM64_REG_INVALID])|->寄存器ID映射 -
+------------------+ -
+------------------+ -
|base(GumCodeWriter)|->基础代码写入器 -
+------------------+ -
| target_cpu (GumCpuType)|->目标CPU类型 -
+------------------+ -
| target_abi (GumAbiType)|->目标ABI类型 -
+------------------+ -
| code (guint8*)|->当前代码指针 -
+------------------+ -
| pc (GumAddress)|->当前程序计数器 -
+------------------+ -
| id_to_reg (GumX86Reg[GUM_X86_REG_NONE])|->寄存器ID映射 -
+------------------+ -
+------------------+ -
| address (GumAddress)|->指令地址 -
+------------------+ -
| mnemonic (char*)|->助记符字符串 -
+------------------+ -
| op_str (char*)|->操作数字符串 -
+------------------+ -
| operands (GArray*)|->操作数数组 -
+------------------+ -
| regs_read (GArray*)|->读取的寄存器数组 -
+------------------+ -
| regs_written (GArray*)|->写入的寄存器数组 -
+------------------+ -
| groups (GArray*)|->指令组数组 -
+------------------+ -
| size (guint)|->指令大小(字节) -
+------------------+ -
// GumRelocator工厂 -
GumRelocator* -
gum_relocator_new (gconstpointer input_code,GumInstructionWriter* output); -
GumRelocator* -
gum_relocator_make_for_cpu (GumCpuType cpu_type, gconstpointer input_code,GumInstructionWriter* output); -
// GumInstructionWriter工厂 -
GumInstructionWriter* -
gum_instruction_writer_new (gpointer code_address); -
GumInstructionWriter* -
gum_instruction_writer_make_for_cpu (GumCpuType cpu_type, gpointer code_address); -
// 特定架构写入器 -
GumX86Writer* -
gum_x86_writer_new (gpointer code_address); -
GumArm64Writer* -
gum_arm64_writer_new (gpointer code_address); -
// GumInstruction工厂 -
GumInstruction* -
gum_instruction_parse (gpointer target); -
GumInstruction* -
gum_instruction_parse_at (gpointer target,GumCpuType cpu_type); -
// CPU类型检测 -
GumCpuType -
gum_cpu_detect (void); -
// Instruction相关的结构 -
typedefstruct_GumInstructionApi{ -
GumInstruction*(* parse)(gpointer target); -
void(* free)(GumInstruction* instruction); -
GumAddress(* get_address)(GumInstruction* instruction); -
const gchar *(* get_mnemonic)(GumInstruction* instruction); -
// ... 其他函数指针 -
}GumInstructionApi; -
// 指令写入器相关的结构 -
typedefstruct_GumInstructionWriterApi{ -
GumInstructionWriter*(* new_writer)(gpointer code_address); -
void(* put_call_address_with_arguments)(GumInstructionWriter* self,GumAddress func,const gchar ** arg_types, gsize arg_count,...); -
void(* put_jmp_address)(GumInstructionWriter* self,GumAddress address); -
gboolean (* flush)(GumInstructionWriter* self); -
void(* reset)(GumInstructionWriter* self, gpointer code_address); -
// ... 其他函数指针 -
}GumInstructionWriterApi; -
// 指令重定位器相关的结构 -
typedefstruct_GumRelocatorApi{ -
GumRelocator*(* new_relocator)(gconstpointer input_code,GumInstructionWriter* output); -
guint (* read_one)(GumRelocator* self,GumInstruction** instruction); -
gboolean (* eoi)(GumRelocator* self); -
void(* write_all)(GumRelocator* self); -
// ... 其他函数指针 -
}GumRelocatorApi;
- 公众号:安全狗的自我修养
- vx:2207344074
- http://gitee.com/haidragon
- http://github.com/haidragon
- bilibili:haidragonx
#
#
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:安全狗的自我修养 haidragon haidragon《frida各模块js与cpp函数分析对照(七)》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。









评论