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

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

文章总结: 本文档系统分析Frida框架中NativePointer、NativeFunction、NativeCallback、Int64/UInt64等Native数据类型的JavaScriptAPI与底层C/C++实现的五层映射架构,涵盖接口定义层、基础结构层、具体实现层、工厂模式层和应用集成层。通过详细函数映射表展示JS方法与C函数的对应关系,并提供跨平台差异处理、性能优化、安全实践及实战案例,为动态分析和二进制安全研究提供关键技术参考。 综合评分: 85 文章分类: 逆向分析,二进制安全,WEB安全,安全工具,安全开发


cover_image

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

原创

haidragon haidragon

安全狗的自我修养

2026年4月5日 11:40 湖南

  • 官网:http://securitytech.cc

    Native数据类型 JavaScript与底层C++函数映射关系分析

    文档概述

    本文档详细分析Frida中NativePointer、NativeFunction、NativeCallback、Int64、UInt64等Native数据类型的JavaScript API与其底层C/C++实现之间的映射关系,涵盖完整的五层架构模型分析。

    五层架构模型分析

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

    NativePointer主要接口:

    NativeFunction主要接口:

    NativeCallback主要接口:

    Int64/UInt64主要接口:

    ArrayBuffer主要接口:

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

    在 subprojects/frida-gum/bindings/gumjs目录中,Native数据类型的绑定实现在相关文件中。

    关键数据结构


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

#### NativePointer实现 ( gumjs-native-pointer.c)

#### NativeFunction实现 ( gumjs-native-function.c)

#### NativeCallback实现 ( gumjs-native-callback.c)

#### Int64/UInt64实现 ( gumjs-int64.cgumjs-uint64.c)

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

#### 类型系统工厂


#### 内存管理工厂


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

Native数据类型通过frida-core与上层应用集成,提供统一的API接口,并与QuickJS/V8引擎深度集成。

## 详细函数映射关系表

### NativePointer映射表

| JavaScript Method | C Function | File Location | Description | | — | — | — | — | | add() | gumjs_native_pointer_add() | gumjs-native-pointer.c | 指针加法运算 | | sub() | gumjs_native_pointer_sub() | gumjs-native-pointer.c | 指针减法运算 | | readU8() | gumjs_native_pointer_read_u8() | gumjs-native-pointer.c | 读取8位无符号整数 | | writeU8() | gumjs_native_pointer_write_u8() | gumjs-native-pointer.c | 写入8位无符号整数 | | readPointer() | gumjs_native_pointer_read_pointer() | gumjs-native-pointer.c | 读取指针值 | | writePointer() | gumjs_native_pointer_write_pointer() | gumjs-native-pointer.c | 写入指针值 |

### NativeFunction映射表

| JavaScript Constructor | C Function | File Location | Description | | — | — | — | — | | newNativeFunction() | gumjs_native_function_construct() | gumjs-native-function.c | 构造NativeFunction对象 | | Function call | gumjs_native_function_invoke() | gumjs-native-function.c | 调用原生函数 |

### NativeCallback映射表

| JavaScript Constructor | C Function | File Location | Description | | — | — | — | — | | newNativeCallback() | gumjs_native_callback_construct() | gumjs-native-callback.c | 构造NativeCallback对象 | | Callback invocation | gumjs_native_callback_on_invoke() | gumjs-native-callback.c | 处理回调调用 |

### Int64/UInt64映射表

| JavaScript Method | C Function | File Location | Description | | — | — | — | — | | newInt64() | gumjs_int64_construct() | gumjs-int64.c | 构造Int64对象 | | add() | gumjs_int64_add() | gumjs-int64.c | 64位整数加法 | | toString() | gumjs_int64_to_string() | gumjs-int64.c | 转换为字符串 | | newUInt64() | gumjs_uint64_construct() | gumjs-uint64.c | 构造UInt64对象 |

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

### GumNativePointer结构体内存布局


### GumNativeFunction结构体内存布局


### GumNativeCallback结构体内存布局


### GumInt64/GumUInt64结构体内存布局


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

### NativeFunction调用执行流程

### NativeCallback调用执行流程

### NativePointer内存读写流程

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

### ABI差异处理

### 指针大小差异

### 字节序处理

### 抽象层设计


## 调试命令与安全实践

### GDB调试示例


### 安全考虑

## 错误处理与边界情况

### 常见错误场景

### 最佳实践


## 攻击检测场景映射

### 可用于检测的场景

### 防御绕过技术

## 性能分析与优化

### 时间复杂度分析

### 内存使用分析

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

### 自定义NativeFunction包装器


### 自定义内存访问工具


### 底层扩展点

## 版本兼容性与演进

### API变更历史

### 向后兼容性保证

## 实战案例分析

### 案例1: Windows API调用


### 案例2: 回调函数注册


### 案例3: 内存数据分析


### 案例4: 64位地址处理


## 总结与最佳实践

Native数据类型是Frida连接JavaScript世界和原生代码世界的桥梁,提供了强大的底层操作能力。理解其JS与C++的映射关系有助于:

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

  • 核心API保持稳定

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

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

  • Frida早期版本: 基本的NativePointer和NativeFunction

  • Frida 8.x: 添加NativeCallback支持

  • Frida 10.x: 完善Int64/UInt64支持

  • Frida 12.x: 优化ABI处理和性能

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

  • 可以通过修改 gumjs-native-function.c添加新的ABI支持

  • 通过修改 gumjs-native-pointer.c添加新的内存操作原语

  • 扩展类型系统支持更多数据类型

  • NativeFunction: 每个实例占用固定内存,参数转换需要临时缓冲区

  • NativeCallback: 需要分配回调桩内存和上下文结构体

  • 优化建议: 重用NativeFunction实例,避免频繁创建

  • NativePointer操作: O(1),直接内存访问

  • NativeFunction调用: O(n),n为参数数量(参数转换开销)

  • NativeCallback调用: O(n),n为参数数量(双向转换开销)

  • Int64/UInt64操作: O(1),64位整数运算

  • 直接汇编: 绕过NativeFunction直接执行机器码

  • 内存加密: 隐藏NativePointer指向的数据

  • 动态代码生成: 运行时生成和执行代码

  • API调用监控: 通过NativeFunction监控关键API调用

  • 回调函数分析: 分析NativeCallback的使用模式

  • 内存访问模式: 监控NativePointer的内存访问行为

  • NativePointer错误:

  • 无效地址访问:段错误或访问违规

  • 地址对齐错误:某些平台要求对齐访问

  • 权限不足:无法读写受保护内存

  • NativeFunction错误:

  • 函数地址无效:调用失败

  • 参数类型不匹配:未定义行为

  • ABI不匹配:栈损坏或参数错误

  • NativeCallback错误:

  • JavaScript异常:需要正确处理和传播

  • 线程安全问题:多线程环境下回调冲突

  • 内存泄漏:回调对象未正确释放

  • 内存访问安全: NativePointer读写需要验证地址有效性

  • 类型安全: NativeFunction参数类型必须严格匹配

  • 回调安全: NativeCallback需要处理异常和线程安全

  • 小端序平台 (x86, x86_64, ARM): 直接内存访问

  • 大端序平台 (某些PowerPC, MIPS): 需要字节序转换

  • 64位平台: GumAddress = uint64_t

  • 32位平台: GumAddress = uint32_t

  • 统一接口: 通过GumAddress类型抽象

  • x86_64: System V ABI (Unix) vs Microsoft x64 ABI (Windows)

  • ARM64: AAPCS64调用约定

  • ARM: AAPCS调用约定

  • MIPS: O32/N32/N64 ABI

  • 64位整数运算

  • 与32位系统的兼容性处理

  • 字符串转换和格式化

  • 回调函数桩生成

  • JavaScript到C的参数转换

  • C到JavaScript的返回值转换

  • 线程安全处理

  • 函数调用约定处理

  • 参数类型转换

  • 返回值处理

  • ABI特定实现(不同平台的调用约定)

  • 指针算术运算实现

  • 内存读写操作实现

  • 与不同数据类型的转换

  • 标准JavaScript ArrayBuffer API

  • Frida扩展的内存读写功能

  • newInt64(value)

  • newUInt64(value)

  • 各种算术和位操作方法

  • 与NativePointer的相互转换

  • newNativeCallback(func,returnType,argTypes[,abi])

  • 返回可被原生代码调用的回调函数指针

  • newNativeFunction(address,returnType,argTypes[,options])

  • 调用函数实例执行原生函数

  • newNativePointer(value)

  • NativePointer.prototype.add(rhs)

  • NativePointer.prototype.sub(rhs)

  • NativePointer.prototype.and(mask)

  • NativePointer.prototype.or(mask)

  • NativePointer.prototype.xor(mask)

  • NativePointer.prototype.shl(shift)

  • NativePointer.prototype.shr(shift)

  • NativePointer.prototype.equals(rhs)

  • NativePointer.prototype.compare(rhs)

  • NativePointer.prototype.toInt32()

  • NativePointer.prototype.toString([radix])

  • NativePointer.prototype.readU8()readS8()readU16(), etc.

  1. 精确控制: 对原生函数和内存进行精确的控制和操作

  2. 性能优化: 避免不必要的类型转换和内存分配

  3. 安全分析: 利用Native数据类型进行深度的安全检测

  4. 跨平台开发: 理解不同平台的ABI差异和处理方式

  5. // 处理64位地址(在32位JS环境中)

  6. const largeAddress =newUInt64('0x123456789abcdef0');

  7. const ptr =newNativePointer(largeAddress);

  8. // 执行指针运算

  9. const offsetPtr = ptr.add(newUInt64('0x1000'));

  10. console.log('Offset pointer:', offsetPtr.toString(16));

  11. // 读取内存

  12. const value = offsetPtr.readU64();

  13. console.log('Memory value:', value.toString(16));

  14. // 分析结构体数据

  15. const structPtr =newNativePointer(0x12345678);

  16. // 读取结构体字段(假设结构体包含int32、指针、int64)

  17. const field1 = structPtr.readS32();// 第一个字段:32位整数

  18. const field2 = structPtr.add(4).readPointer();// 第二个字段:指针

  19. const field3 = structPtr.add(12).readS64();// 第三个字段:64位整数

  20. console.log('Struct fields:', field1, field2, field3.toString());

  21. // 注册信号处理回调

  22. const libc =Module.findBaseAddress('libc.so');

  23. const signalAddr =Module.findExportByName('libc.so','signal');

  24. if(signalAddr){

  25. const signalFunc =newNativeFunction(signalAddr,'pointer',['int','pointer']);

  26. // 创建信号处理回调

  27. const sigHandler =newNativeCallback(function(sig){

  28. console.log('Received signal:', sig);

  29. return0;

  30. },'int',['int']);

  31. // 注册SIGINT处理程序

  32. signalFunc(2, sigHandler);// SIGINT = 2

  33. }

  34. // 调用Windows MessageBox API

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

  36. const messageBoxAddr =Module.findExportByName('user32.dll','MessageBoxA');

  37. if(messageBoxAddr){

  38. constMessageBox=newNativeFunction(messageBoxAddr,'int',['pointer','pointer','pointer','int']);

  39. const caption =Memory.allocUtf8String('Frida Alert');

  40. const text =Memory.allocUtf8String('Hello from Frida!');

  41. // 调用MessageBox(0, "Hello from Frida!", "Frida Alert", 0)

  42. MessageBox(NULL, text, caption,0);

  43. }

  44. // 内存区域批量读取

  45. NativePointer.prototype.readArray =function(elementSize, count, readFunc){

  46. const results =[];

  47. let currentPtr =this;

  48. for(let i&nbsp;=0;&nbsp;i&nbsp;<&nbsp;count;&nbsp;i++){

  49. results.push(readFunc.call(currentPtr));

  50. currentPtr&nbsp;=&nbsp;currentPtr.add(elementSize);

  51. }

  52. return&nbsp;results;

  53. };

  54. // 带日志记录的NativeFunction

  55. function&nbsp;createLoggedNativeFunction(address,&nbsp;returnType,&nbsp;argTypes,&nbsp;name){

  56. const&nbsp;originalFunc&nbsp;=newNativeFunction(address,&nbsp;returnType,&nbsp;argTypes);

  57. returnfunction(...args){

  58. console.log(Calling ${name}with args:,&nbsp;args);

  59. const&nbsp;result&nbsp;=&nbsp;originalFunc(...args);

  60. console.log(${name} returned:,&nbsp;result);

  61. return&nbsp;result;

  62. };

  63. }

  64. // 安全的NativeFunction使用

  65. function&nbsp;createSafeNativeFunction(address,&nbsp;returnType,&nbsp;argTypes){

  66. try{

  67. // 验证地址有效性

  68. if(!address&nbsp;||&nbsp;address.isNull()){

  69. thrownewError('Invalid function address');

  70. }

  71. // 创建NativeFunction

  72. const&nbsp;func&nbsp;=newNativeFunction(address,&nbsp;returnType,&nbsp;argTypes);

  73. // 包装安全调用

  74. returnfunction(...args){

  75. try{

  76. return&nbsp;func(...args);

  77. }catch(e){

  78. console.error('Native function call failed:',&nbsp;e);

  79. returnnull;

  80. }

  81. };

  82. }catch(e){

  83. console.error('Failed to create NativeFunction:',&nbsp;e);

  84. returnnull;

  85. }

  86. }

  87. // 安全的NativePointer内存访问

  88. function&nbsp;safeReadMemory(ptr,&nbsp;size,&nbsp;readFunc){

  89. try{

  90. // 验证指针和大小

  91. if(!ptr&nbsp;||&nbsp;ptr.isNull()||&nbsp;size&nbsp;<=0){

  92. returnnull;

  93. }

  94. // 尝试读取内存

  95. return&nbsp;readFunc.call(ptr);

  96. }catch(e){

  97. console.error('Memory read failed:',&nbsp;e);

  98. returnnull;

  99. }

  100. }

  101. # 在NativeFunction调用处设置断点

  102. (gdb)break&nbsp;gumjs_native_function_invoke

  103. # 查看函数调用参数

  104. (gdb)&nbsp;info args

  105. (gdb)&nbsp;print&nbsp;*(GumNativeFunction*)$rdi

  106. (gdb)&nbsp;x/10gx&nbsp;$rsi &nbsp;# 查看参数数组

  107. # 在NativeCallback桩处设置断点

  108. (gdb)break&nbsp;gumjs_native_callback_on_invoke

  109. (gdb)&nbsp;info registers

  110. (gdb)&nbsp;x/20i&nbsp;$pc-20# 查看回调桩代码

  111. // ABI抽象接口

  112. typedefenum{

  113. GUM_ABI_UNIX,

  114. GUM_ABI_WINDOWS,

  115. GUM_ABI_IOS,

  116. // ... 其他ABI

  117. }GumAbiType;

  118. // 调用处理器抽象

  119. struct_GumCallHandler

  120. {

  121. GObject&nbsp;parent;

  122. gboolean&nbsp;(*&nbsp;prepare_call)(GumCallHandler*&nbsp;self,GumCpuContext*&nbsp;cpu_context,constGumArgument*&nbsp;args,&nbsp;gsize arg_count);

  123. gboolean&nbsp;(*&nbsp;perform_call)(GumCallHandler*&nbsp;self,GumCpuContext*&nbsp;cpu_context,&nbsp;gpointer function_address);

  124. gboolean&nbsp;(*&nbsp;handle_return)(GumCallHandler*&nbsp;self,GumCpuContext*&nbsp;cpu_context,GumReturnValue*&nbsp;return_value);

  125. };

  126. JavaScript调用 readU32()等方法

  127. 调用对应的 gumjs_native_pointer_read_u32()

  128. 验证指针有效性(地址对齐、可访问性)

  129. 执行内存读取操作

  130. 返回读取的值

  131. 原生代码调用回调函数指针

  132. 执行回调桩(trampoline)代码

  133. 保存CPU上下文

  134. 调用 gumjs_native_callback_on_invoke()

  135. 参数转换(C值 → JS值)

  136. 调用JavaScript回调函数

  137. 返回值转换(JS值 → C值)

  138. 恢复CPU上下文并返回

  139. JavaScript调用NativeFunction实例 → GumJS绑定层

  140. 调用 gumjs_native_function_invoke()

  141. 参数类型检查和转换(JS值 → C值)

  142. 根据ABI设置调用约定(寄存器/栈参数布局)

  143. 执行原生函数调用

  144. 返回值转换(C值 → JS值)

  145. 返回结果给JavaScript

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

  147. |&nbsp;value&nbsp;(gint64/guint64)|->64位整数值

  148. +------------------+

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

  150. |&nbsp;cpu_context&nbsp;(pointer)|->&nbsp;CPU上下文

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

  152. |&nbsp;callback&nbsp;(JSObjectRef)|->JavaScript回调函数引用

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

  154. |&nbsp;signature&nbsp;(pointer)|->函数签名信息

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

  156. |&nbsp;trampoline&nbsp;(gpointer)|->回调桩地址

  157. +------------------+

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

  159. |&nbsp;address&nbsp;(gpointer)|->原生函数地址

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

  161. |&nbsp;signature&nbsp;(pointer)|->函数签名信息

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

  163. |&nbsp;cpu_context&nbsp;(pointer)|->&nbsp;CPU上下文(用于调用)

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

  165. +------------------+

  166. |&nbsp;value&nbsp;(GumAddress)|->64位或32位地址值

  167. +------------------+

  168. // 回调函数内存管理

  169. GumCallbackManager*

  170. gum_callback_manager_new&nbsp;(void);

  171. // 函数调用上下文管理

  172. GumInvocationContext*

  173. gum_invocation_context_new&nbsp;(void);

  174. // GumTypeSignature用于描述函数签名

  175. GumTypeSignature*

  176. gum_type_signature_new&nbsp;(const&nbsp;gchar&nbsp;*&nbsp;return_type,const&nbsp;gchar&nbsp;**&nbsp;arg_types,&nbsp;gsize arg_count);

  177. // ABI特定的调用处理器

  178. GumCallHandler*

  179. gum_call_handler_new&nbsp;(GumTypeSignature*&nbsp;signature,GumAbiType&nbsp;abi);

  180. // NativePointer相关的结构

  181. typedefstruct_GumNativePointer{

  182. GumAddress&nbsp;value;

  183. }GumNativePointer;

  184. // NativeFunction相关的结构

  185. typedefstruct_GumNativeFunction{

  186. gpointer address;

  187. GumTypeSignature*&nbsp;signature;

  188. GumCpuContext*&nbsp;cpu_context;

  189. }GumNativeFunction;

  190. // NativeCallback相关的结构

  191. typedefstruct_GumNativeCallback{

  192. GumCpuContext*&nbsp;cpu_context;

  193. JSObjectRef&nbsp;callback;

  194. GumTypeSignature*&nbsp;signature;

  195. gpointer trampoline;

  196. }GumNativeCallback;

  197. // Int64/UInt64相关的结构

  198. typedefstruct_GumInt64{

  199. gint64 value;

  200. }GumInt64;

  201. typedefstruct_GumUInt64{

  202. guint64 value;

  203. }GumUInt64;

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

#

#


免责声明:

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

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

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

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

评论:0   参与:  0