frida各模块js与cpp函数分析对照(一)

admin 2026-04-10 03:25:08 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 本文详细分析Frida框架中Process模块的JavaScriptAPI与底层C/C++实现的五层映射架构,涵盖接口定义层、绑定层、平台实现层、工厂模式层和应用集成层。关键发现包括Process.enumerateModules()等核心函数与gumprocessenumerate_modules()等原生函数的对应关系,以及Darwin/Linux平台的差异化实现机制。文档提供内存布局可视化、系统调用追踪流程、性能优化建议及实战案例,为安全研究人员深入理解Frida架构、进行进程内存分析和安全检测提供技术参考。 综合评分: 85 文章分类: 安全工具,逆向分析,渗透测试,代码审计,二进制安全


cover_image

frida各模块js与cpp函数分析对照(一)

原创

haidragon haidragon

安全狗的自我修养

2026年4月5日 11:40 湖南

官网:http://securitytech.cc

#

Process模块 JavaScript与底层C++函数映射关系分析

文档概述

本文档详细分析Frida中Process模块的JavaScript API与其底层C/C++实现之间的映射关系,涵盖完整的五层架构模型分析。

五层架构模型分析

1. 接口定义层 (JavaScript API Layer)

Process模块提供的主要JavaScript接口包括:

  • Process.arch
  • Process.platform
  • Process.pageSize
  • Process.pointerSize
  • Process.setExceptionHandler(callback)
  • Process.getCurrentThreadId()
  • Process.enumerateModules()
  • Process.enumerateRanges(protection)
  • Process.enumerateMallocRanges()
  • Process.findModuleByName(name)
  • Process.getModuleByAddress(address)
  • Process.queryMemory(address)

2. 基础结构层 (GumJS Binding Layer)

在 subprojects/frida-gum/bindings/gumjs目录中,Process模块的绑定实现在相关文件中。

关键数据结构

1. // GumScriptBackend中的Process相关结构
2. typedefstruct_GumProcessApi{
3. // 枚举模块的回调函数定义
4. gboolean (* enumerate_modules)(GumFoundModuleFunc func, gpointer user_data);
5. gboolean (* enumerate_ranges)(const gchar * protection,GumFoundRangeFunc func, gpointer user_data);
6. // ... 其他函数指针
7. }GumProcessApi;

3. 具体实现层 (Platform-specific Implementation)

不同平台的具体实现在 subprojects/frida-gum/gum/backend-*目录中。

Darwin平台实现 ( gumprocess-darwin.c)

  • gum_process_enumerate_modules()
  • gum_process_enumerate_ranges()
  • gum_process_find_module_by_name()
  • gum_process_query_memory()

Linux/Android平台实现 ( gumprocess-linux.c)

  • 类似的函数实现,但使用不同的系统调用

4. 工厂模式层 (Backend Factory)

通过工厂模式创建不同平台的Process实现:

1. // gum_process_backend_create()
2. GumProcessBackend*
3. gum_process_backend_create (void)
4. {
5. #ifdef HAVE_DARWIN
6. return gum_darwin_process_backend_new ();
7. #elif defined(HAVE_LINUX)
8. return gum_linux_process_backend_new ();
9. // ... 其他平台
10. #endif
11. }

5. 应用集成层 (Integration with Frida Core)

Process模块通过frida-core与上层应用集成,提供统一的API接口。

详细函数映射关系表

| JavaScript Function | C++ Function | File Location | Description | | — | — | — | — | | Process.enumerateModules() | gum_process_enumerate_modules() | gumprocess-*.c | 枚举进程中加载的所有模块 | | Process.enumerateRanges() | gum_process_enumerate_ranges() | gumprocess-*.c | 枚举指定保护属性的内存范围 | | Process.findModuleByName() | gum_process_find_module_by_name() | gumprocess-*.c | 根据模块名查找模块信息 | | Process.getModuleByAddress() | gum_process_get_module_by_address() | gumprocess-*.c | 根据地址查找所属模块 | | Process.queryMemory() | gum_process_query_memory() | gumprocess-*.c | 查询指定地址的内存信息 | | Process.getCurrentThreadId() | gum_process_get_current_thread_id() | gumprocess-*.c | 获取当前线程ID |

内存布局与数据结构可视化

ModuleInfo结构体内存布局

1. +------------------+
2. | name (char*)|->模块名称字符串
3. +------------------+
4. |base(GumAddress)|->模块基地址
5. +------------------+
6. | size (gsize)|->模块大小
7. +------------------+
8. | path (char*)|->模块完整路径
9. +------------------+

RangeInfo结构体内存布局

1. +------------------+
2. |base(GumAddress)|->内存范围起始地址
3. +------------------+
4. | size (gsize)|->内存范围大小
5. +------------------+
6. | protection (int)|->内存保护属性
7. +------------------+

系统调用级执行流程追踪

Process.enumerateModules()执行流程

  1. JavaScript调用 → GumJS绑定层
  2. 调用 gum_process_enumerate_modules()
  3. 平台特定实现(Darwin: _dyld_image_count()_dyld_get_image_name()等)
  4. 回调函数逐个处理每个模块
  5. 结果转换为JavaScript对象返回

内存查询流程

  1. JavaScript调用 Process.queryMemory(address)
  2. 调用 gum_process_query_memory(address)
  3. Darwin平台:使用 vm_region_64()系统调用
  4. Linux平台:解析 /proc/self/maps
  5. 返回内存区域信息

跨平台差异与抽象机制

Darwin vs Linux实现差异

  • Darwin: 使用Mach-O相关的API和 vm_region系列函数
  • Linux: 解析 /proc文件系统和ELF相关API
  • Windows: 使用PEB和VirtualQuery系列函数

抽象层设计

通过统一的函数指针表和工厂模式,隐藏平台差异:

1. struct_GumProcessBackend
2. {
3. GObject parent;

5. /* Platform-specific methods */
6. gboolean (* enumerate_modules)(GumProcessBackend* self,GumFoundModuleFunc func, gpointer user_data);
7. gboolean (* enumerate_ranges)(GumProcessBackend* self,const gchar * protection,GumFoundRangeFunc func, gpointer user_data);
8. // ... 其他方法
9. };

调试命令与安全实践

GDB调试示例

1. # 在gum_process_enumerate_modules处设置断点
2. (gdb)break gum_process_enumerate_modules
3. # 查看模块枚举过程
4. (gdb) info registers
5. (gdb) x/10s $rdi  # 查看模块名称

性能优化建议

  • 避免频繁调用 enumerateModules(),可缓存结果
  • 使用适当的过滤条件减少 enumerateRanges()的开销
  • 注意内存泄漏,及时释放大对象

错误处理与边界情况

常见错误场景

  • 无效地址查询:返回null或抛出异常
  • 权限不足:某些内存区域无法访问
  • 并发修改:模块列表在枚举过程中可能变化

最佳实践

1. // 安全的模块枚举
2. try{
3. const modules =Process.enumerateModules();
4. modules.forEach(module =>{
5. console.log(`${module.name}: ${module.base}- ${module.base.add(module.size)}`);
6. });
7. }catch(e){
8. console.error('Failed to enumerate modules:', e);
9. }

攻击检测场景映射

可用于检测的场景

  • 模块注入检测: 监控异常模块加载
  • 内存扫描: 检测可疑的内存区域
  • 完整性验证: 验证关键模块的基地址和大小

防御绕过技术

  • 直接系统调用: 绕过Frida的hook
  • 内存加密: 隐藏恶意代码
  • 反调试技术: 检测调试器存在

性能分析与优化

时间复杂度分析

  • enumerateModules(): O(n),n为模块数量
  • enumerateRanges(): O(m),m为内存段数量
  • findModuleByName(): O(n),需要遍历所有模块

内存使用分析

  • 每次调用都会分配临时结构体
  • 大量模块时内存占用显著
  • 建议分批处理或使用流式API

扩展功能与自定义实现

自定义模块枚举

1. // 扩展Process模块功能
2. Process.myCustomEnumerateModules =function(filter){
3. returnProcess.enumerateModules().filter(module =>{
4. return module.name.includes(filter);
5. });
6. };

底层扩展点

  • 可以通过修改 gumprocess-*.c添加新的平台特定功能
  • 通过扩展GumProcessBackend结构体添加新方法

版本兼容性与演进

API变更历史

  • Frida 10.x: 引入统一的Process API
  • Frida 12.x: 添加内存查询功能
  • Frida 14.x: 优化性能和错误处理

向后兼容性保证

  • 核心API保持稳定
  • 新功能通过扩展方式添加
  • 废弃的API会标记并提供迁移路径

实战案例分析

案例1: 动态库依赖分析

1. // 分析应用的动态库依赖
2. const mainModule =Process.findModuleByName(null);
3. console.log('Main module:', mainModule);

5. // 查找所有包含"ssl"的模块
6. const sslModules =Process.enumerateModules()
7. .filter(mod => mod.name.toLowerCase().includes('ssl'));
8. console.log('SSL modules:', sslModules);

案例2: 内存保护分析

1. // 分析可执行内存区域
2. const executableRanges =Process.enumerateRanges('---x');
3. executableRanges.forEach(range =>{
4. console.log(`Executable range: ${range.base}- ${range.base.add(range.size)}`);
5. });

总结与最佳实践

Process模块是Frida中最基础也是最重要的模块之一,提供了对目标进程的全面控制能力。理解其JS与C++的映射关系有助于:

  1. 深入理解Frida架构: 掌握从JS到原生代码的完整调用链
  2. 性能优化: 避免不必要的开销,合理使用API
  3. 安全分析: 利用Process模块进行深入的安全检测
  4. 自定义扩展: 基于现有架构开发新的功能

通过本文档的五层架构分析,开发者可以全面掌握Process模块的工作原理和使用技巧。

  • 公众号:安全狗的自我修养
  • vx:2207344074
  • http://gitee.com/haidragon
  • http://github.com/haidragon
  • bilibili:haidragonx

#

#


免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:安全狗的自我修养 haidragon haidragon《frida各模块js与cpp函数分析对照(一)》

ClaudeCode源码编程思想 网络安全文章

ClaudeCode源码编程思想

文章总结: 该书系统解析ClaudeCode代理系统的设计思想与工程实现,核心将其视为终端内的长期运行Agent运行时而非简单CLI工具。重点阐述会话状态机模型
评论:0   参与:  0