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

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

文章总结: 本文详细分析了Frida框架中Module和Memory模块的JavaScriptAPI与底层C++实现的五层映射架构,包括接口定义层、绑定层、平台实现层、工厂模式层和应用集成层。文档提供了完整的函数对照表,展示了模块操作和内存管理功能的具体实现机制,并包含跨平台差异分析、性能优化建议和实战案例,为安全研究人员深入理解Frida内部机制和进行二进制分析提供技术参考。 综合评分: 82 文章分类: 二进制安全,逆向分析,安全工具,渗透测试,漏洞分析


cover_image

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

原创

haidragon haidragon

安全狗的自我修养

2026年4月5日 11:40 湖南

  • 官网:http://securitytech.cc

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

    文档概述

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

    五层架构模型分析

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

    Module模块主要接口:

    Memory模块主要接口:

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

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

    关键数据结构


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

#### Module实现 ( gummodule-*.c)

关键函数:

#### Memory实现 ( gummemory-*.c)

关键函数:

### 4. 工厂模式层 (Backend Factory)

#### Module工厂


#### Memory工厂


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

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

## 详细函数映射关系表

### Module模块映射表

| JavaScript Function | C++ Function | File Location | Description | | — | — | — | — | | Module.findBaseAddress() | gum_module_find_base_address() | gummodule-*.c | 查找模块基地址 | | Module.findExportByName() | gum_module_find_export_by_name() | gummodule-*.c | 查找导出符号地址 | | Module.enumerateExports() | gum_module_enumerate_exports() | gummodule-*.c | 枚举模块导出符号 | | Module.enumerateImports() | gum_module_enumerate_imports() | gummodule-*.c | 枚举模块导入符号 | | Module.enumerateSymbols() | gum_module_enumerate_symbols() | gummodule-*.c | 枚举模块所有符号 | | Module.getExports() | gum_module_enumerate_exports() | gummodule-*.c | 获取导出符号列表(同步) |

### Memory模块映射表

| JavaScript Function | C++ Function | File Location | Description | | — | — | — | — | | Memory.alloc() | gum_memory_alloc() | gummemory-*.c | 分配内存 | | Memory.free() | gum_memory_free() | gummemory-*.c | 释放内存 | | Memory.copy() | gum_memory_copy() | gummemory.c | 内存复制 | | Memory.protect() | gum_memory_protect() | gummemory-*.c | 修改内存保护属性 | | Memory.scan() | gum_memory_scan() | gummemory.c | 内存扫描(异步) | | Memory.scanSync() | gum_memory_scan_sync() | gummemory.c | 内存扫描(同步) |

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

### ExportDetails结构体内存布局


### ImportDetails结构体内存布局


### MemoryRange结构体内存布局


## 系统调用级执行流程追踪

### Module.findExportByName()执行流程

### Memory.scan()执行流程

## 跨平台差异与抽象机制

### Module实现差异

### Memory实现差异

### 抽象层设计


## 调试命令与安全实践

### GDB调试示例


### 性能优化建议

## 错误处理与边界情况

### 常见错误场景

### 最佳实践


## 攻击检测场景映射

### 可用于检测的场景

### 防御绕过技术

## 性能分析与优化

### 时间复杂度分析

### 内存使用分析

## 扩展功能与自定义实现

### 自定义模块解析


### 自定义内存工具


### 底层扩展点

## 版本兼容性与演进

### API变更历史

### 向后兼容性保证

## 实战案例分析

### 案例1: 动态API解析


### 案例2: 内存特征码扫描


### 案例3: 模块依赖分析


## 总结与最佳实践

Module和Memory模块是Frida中最核心的功能模块,提供了对目标进程二进制结构和内存空间的全面访问能力。理解其JS与C++的映射关系有助于:

通过本文档的五层架构分析,开发者可以全面掌握Module和Memory模块的工作原理和使用技巧,为复杂的动态分析任务提供坚实的基础。

  • 核心API保持稳定

  • 新功能通过扩展方式添加

  • 废弃的API会标记并提供迁移路径

  • Frida早期版本: 基本的模块和内存操作

  • Frida 10.x: 添加完整的符号枚举功能

  • Frida 12.x: 优化内存扫描性能,添加异步API

  • Frida 14.x: 改进跨平台兼容性和错误处理

  • 可以通过修改 gummodule-*.c添加新的模块解析功能

  • 通过修改 gummemory-*.c添加新的内存操作原语

  • 扩展GumModule和GumMemory结构体添加新方法

  • Module操作: 符号枚举会为每个符号分配ExportDetails结构体

  • Memory操作: 扫描会分配临时缓冲区和结果数组

  • 优化建议: 使用流式API避免一次性加载大量数据

  • Module操作:

  • findExportByName(): O(n),n为导出符号数量

  • enumerateExports(): O(n),需要遍历所有导出符号

  • getExports(): O(n),同上但返回完整列表

  • Memory操作:

  • alloc()/free(): O(1),系统调用开销

  • scan(): O(size/pattern_length),线性扫描

  • protect(): O(1),系统调用开销

  • 直接系统调用: 绕过Module API直接解析二进制

  • 内存加密: 隐藏恶意代码和数据

  • 动态加载: 运行时加载和解析模块

  • API Hook检测: 监控关键导出函数的地址变化

  • 内存扫描检测: 检测可疑的内存扫描行为

  • 模块完整性验证: 验证关键模块的导出表完整性

  • Module错误:

  • 模块不存在:返回null

  • 符号不存在:返回null

  • 权限不足:无法读取模块信息

  • Memory错误:

  • 无效地址:访问违规

  • 内存不足:分配失败

  • 保护冲突:无法修改保护属性

  • Module缓存: 缓存常用的模块和符号查找结果

  • Memory批量操作: 避免频繁的小内存分配

  • 扫描优化: 使用更精确的模式减少扫描范围

  • Darwin: 使用 mach_vm_allocate()、 mach_vm_deallocate()、 mach_vm_protect()

  • Linux: 使用 mmap()、 munmap()、 mprotect()

  • Windows: 使用 VirtualAlloc()、 VirtualFree()、 VirtualProtect()

  • Darwin (Mach-O):

  • 使用 _dyld_get_image_header()获取镜像头

  • 解析LCSYMTAB、LCDYSYMTAB等加载命令

  • 支持懒绑定和非懒绑定符号

  • Linux (ELF):

  • 解析程序头表(PT_DYNAMIC)

  • 处理.dynsym、.dynstr段

  • 支持PLT/GOT机制

  • Windows (PE):

  • 解析IMAGENTHEADERS

  • 处理导出目录表

  • 支持转发器(forwarder)功能

  • Darwin: 解析Mach-O的LC_SYMTAB加载命令

  • Linux: 解析ELF的.dynamic段和符号表

  • Windows: 解析PE的导出表

  • gum_memory_alloc()

  • gum_memory_free()

  • gum_memory_copy()

  • gum_memory_protect()

  • gum_memory_scan()

  • 通用实现gummemory.c – 跨平台内存操作

  • Darwin特定gummemory-darwin.c – 使用Mach VM API

  • Linux特定gummemory-linux.c – 使用mmap/mprotect

  • gum_module_find_base_address()

  • gum_module_find_export_by_name()

  • gum_module_enumerate_exports()

  • gum_module_enumerate_imports()

  • gum_module_enumerate_symbols()

  • Darwingummodule-darwin.c – 使用Mach-O解析

  • Linuxgummodule-linux.c – 使用ELF解析

  • Windowsgummodule-windows.c – 使用PE解析

  • Memory.alloc(size)

  • Memory.copy(dst,src,n)

  • Memory.dup(address,size)

  • Memory.protect(address,size,protection)

  • Memory.scan(address,size,pattern,callbacks)

  • Memory.scanSync(address,size,pattern)

  • Memory.allocUtf8String(str)

  • Memory.allocAnsiString(str)

  • Memory.allocUtf16String(str)

  • Module.load(name)

  • Module.ensureInitialized(name)

  • Module.findBaseAddress(name)

  • Module.findExportByName(module,symbol)

  • Module.getExports()

  • Module.getImports()

  • Module.getSymbolByName(module,symbol)

  • Module.enumerateExports(module)

  • Module.enumerateImports(module)

  • Module.enumerateSymbols(module)

  • Module.enumerateRanges(module,protection)

  1. 二进制分析: 深入理解目标应用的模块结构和依赖关系

  2. 内存操作: 精确控制和监控目标进程的内存使用

  3. API Hook: 基于符号信息实现精准的函数Hook

  4. 安全检测: 利用模块和内存信息进行深度安全分析

  5. // 分析模块的导入依赖

  6. function analyzeModuleImports(moduleName){

  7. console.log(Analyzing imports for ${moduleName}:);

  8. Module.enumerateImports(moduleName,{

  9. onMatch:function(importDetails){

  10. console.log(  ${importDetails.name} from ${importDetails.module});

  11. },

  12. onComplete:function(){

  13. console.log('Import analysis completed');

  14. }

  15. });

  16. }

  17. analyzeModuleImports('libcrypto.so');

  18. // 扫描内存中的特定字节序列

  19. const pattern ='48 89 ?? ?? ?? 48 8b ?? ?? ?? ?? ??';

  20. const base =Module.findBaseAddress('libtarget.so');

  21. const size =0x100000;// 1MB扫描范围

  22. Memory.scan(base, size, pattern,{

  23. onMatch:function(address, size){

  24. console.log('Found pattern at:', address);

  25. // 进一步分析找到的地址

  26. },

  27. onError:function(reason){

  28. console.error('Scan error:', reason);

  29. },

  30. onComplete:function(){

  31. console.log('Scan completed');

  32. }

  33. });

  34. // 动态解析和调用Windows API

  35. const kernel32 =Module.findBaseAddress('kernel32.dll');

  36. const loadLibraryAddr =Module.findExportByName('kernel32.dll','LoadLibraryA');

  37. if(loadLibraryAddr){

  38. constLoadLibrary=newNativeFunction(loadLibraryAddr,'pointer',['pointer']);

  39. const libName =Memory.allocUtf8String('user32.dll');

  40. const user32Handle =LoadLibrary(libName);

  41. console.log('Loaded user32.dll:', user32Handle);

  42. }

  43. // 内存区域保护监控

  44. Memory.monitorProtectionChanges =function(address, size, callback){

  45. const originalProtection =Memory.queryProtection(address);

  46. // 定期检查保护属性变化

  47. const interval = setInterval(()=>{

  48. const currentProtection =Memory.queryProtection(address);

  49. if(currentProtection !== originalProtection){

  50. callback(address, originalProtection, currentProtection);

  51. clearInterval(interval);

  52. }

  53. },100);

  54. return interval;

  55. };

  56. // 扩展Module模块功能

  57. Module.findImportByName =function(moduleName, importName){

  58. let result =null;

  59. Module.enumerateImports(moduleName,{

  60. onMatch:function(importDetails){

  61. if(importDetails.name === importName){

  62. result = importDetails;

  63. return'stop';

  64. }

  65. },

  66. onComplete:function(){}

  67. });

  68. return result;

  69. };

  70. // 安全的模块操作

  71. function safeFindExport(moduleName, symbolName){

  72. try{

  73. const base =Module.findBaseAddress(moduleName);

  74. if(!base){

  75. console.warn(Module ${moduleName} not found);

  76. returnnull;

  77. }

  78. const address =Module.findExportByName(moduleName, symbolName);

  79. if(!address){

  80. console.warn(Symbol ${symbolName} not found in ${moduleName});

  81. returnnull;

  82. }

  83. return address;

  84. }catch(e){

  85. console.error('Module operation failed:', e);

  86. returnnull;

  87. }

  88. }

  89. // 安全的内存操作

  90. function safeMemoryScan(address, size, pattern){

  91. try{

  92. const results =[];

  93. Memory.scanSync(address, size, pattern).forEach(match =>{

  94. results.push(match.address);

  95. });

  96. return results;

  97. }catch(e){

  98. console.error('Memory scan failed:', e);

  99. return[];

  100. }

  101. }

  102. # 在模块符号查找处设置断点

  103. (gdb)break gum_module_find_export_by_name

  104. # 查看符号查找过程

  105. (gdb) info args

  106. (gdb) x/s $rsi  # 查看符号名称

  107. (gdb) print/x $rax  # 查看返回地址

  108. # 在内存分配处设置断点

  109. (gdb)break gum_memory_alloc

  110. (gdb) info registers

  111. (gdb) x/10gx $rax  # 查看分配的内存

  112. // Module抽象接口

  113. struct_GumModule

  114. {

  115. GObject parent;

  116. GumAddress(* find_base_address)(GumModule* self,const gchar * name);

  117. gpointer (* find_export_by_name)(GumModule* self,const gchar * module_name,const gchar * symbol_name);

  118. gboolean (* enumerate_exports)(GumModule* self,const gchar * module_name,GumFoundExportFunc func, gpointer user_data);

  119. // ... 其他方法

  120. };

  121. // Memory抽象接口

  122. struct_GumMemory

  123. {

  124. GObject parent;

  125. gpointer (* alloc)(GumMemory* self, gsize size);

  126. void(* free)(GumMemory* self, gpointer mem);

  127. void(* copy)(GumMemory* self, gpointer dst, gconstpointer src, gsize n);

  128. gboolean (* protect)(GumMemory* self, gpointer address, gsize size,GumPageProtection prot);

  129. // ... 其他方法

  130. };

  131. JavaScript调用 Memory.scan(address,size,pattern,callbacks)

  132. 调用 gum_memory_scan(address,size,pattern,callbacks)

  133. 创建扫描上下文和工作线程

  134. 工作线程逐块扫描内存

  135. 匹配模式时调用onMatch回调

  136. 扫描完成后调用onComplete回调

  137. 在符号表中查找匹配的符号名

  138. 返回符号的虚拟地址

  139. JavaScript调用 → GumJS绑定层

  140. 调用 gum_module_find_export_by_name(moduleName,symbolName)

  141. 平台特定实现:

  142. +------------------+

  143. |base(GumAddress)|->内存范围起始地址

  144. +------------------+

  145. | size (gsize)|->内存范围大小

  146. +------------------+

  147. +------------------+

  148. | type (int)|->导入类型

  149. +------------------+

  150. | name (char*)|->导入符号名称

  151. +------------------+

  152. |module(char*)|->导入自哪个模块

  153. +------------------+

  154. | address (GumAddress)|-> IAT中的地址

  155. +------------------+

  156. +------------------+

  157. | type (int)|->导出类型(函数/变量)

  158. +------------------+

  159. | name (char*)|->符号名称

  160. +------------------+

  161. | address (GumAddress)|->符号地址

  162. +------------------+

  163. |module(char*)|->所属模块名称

  164. +------------------+

  165. // gum_memory_backend_create()

  166. GumMemoryBackend*

  167. gum_memory_backend_create (void)

  168. {

  169. #ifdef HAVE_DARWIN

  170. return gum_darwin_memory_backend_new ();

  171. #elif defined(HAVE_LINUX)

  172. return gum_linux_memory_backend_new ();

  173. // ... 其他平台

  174. #endif

  175. }

  176. // gum_module_facade_create()

  177. GumModuleFacade*

  178. gum_module_facade_create (void)

  179. {

  180. return g_object_new (GUM_TYPE_MODULE_FACADE, NULL);

  181. }

  182. // Module相关的API结构

  183. typedefstruct_GumModuleApi{

  184. GumAddress(* find_base_address)(const gchar * module_name);

  185. gpointer (* find_export_by_name)(const gchar * module_name,const gchar * symbol_name);

  186. gboolean (* enumerate_exports)(const gchar * module_name,GumFoundExportFunc func, gpointer user_data);

  187. // ... 其他函数指针

  188. }GumModuleApi;

  189. // Memory相关的API结构

  190. typedefstruct_GumMemoryApi{

  191. gpointer (* alloc)(gsize size);

  192. void(* free)(gpointer mem);

  193. void(* copy)(gpointer dst, gconstpointer src, gsize n);

  194. gboolean (* protect)(gpointer address, gsize size,GumPageProtection prot);

  195. // ... 其他函数指针

  196. }GumMemoryApi;

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

#

#


免责声明:

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

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

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

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

评论:0   参与:  0