文章总结: 本文档系统分析Frida框架中Tools模块(Console、Hexdump、Worker、Cloak、Profiler)的JavaScriptAPI与底层C/C++实现之间的五层架构映射关系,详细列出各模块函数对应表、内存布局及执行流程,并提供安全编程实践与实战案例(如内存扫描、性能监控),为安全研究人员深入理解Frida工具链实现原理和二次开发提供技术参考。 综合评分: 85 文章分类: 安全工具,二进制安全,逆向分析,安全开发,WEB安全
frida各模块js与cpp函数分析对照(八)
原创
haidragon haidragon
安全狗的自我修养
2026年4月5日 11:40 湖南
-
官网:http://securitytech.cc
Tools模块 JavaScript与底层C++函数映射关系分析
文档概述
本文档详细分析Frida中Console、Hexdump、Worker、Cloak、Profiler等工具模块的JavaScript API与其底层C/C++实现之间的映射关系,涵盖完整的五层架构模型分析。
五层架构模型分析
1. 接口定义层 (JavaScript API Layer)
Console模块主要接口:
Hexdump模块主要接口:
Worker模块主要接口:
Cloak模块主要接口:
Profiler模块主要接口:
其他工具接口:
2. 基础结构层 (GumJS Binding Layer)
在
subprojects/frida-gum/bindings/gumjs目录中,Tools模块的绑定实现在相关文件中。关键数据结构
### 3. 具体实现层 (Platform-specific Implementation)
#### Console实现 ( gumjs-console.c)
关键函数:
#### Hexdump实现 ( gumhexdump.c)
关键函数:
#### Worker实现 ( gumjs-worker.c)
关键函数:
#### Cloak实现 ( gumcloak.c)
关键函数:
#### Profiler实现 ( gumprofiler.c)
关键函数:
### 4. 工厂模式层 (Backend Factory)
#### 采样器工厂
#### 工作线程工厂
#### 控制台工厂
### 5. 应用集成层 (Integration with Frida Core)
Tools模块通过frida-core与上层应用集成,提供统一的API接口,并与事件系统、消息通道和线程管理深度集成。
## 详细函数映射关系表
### Console映射表
| JavaScript Function | C Function | File Location | Description |
| — | — | — | — |
| console.log() | gumjs_console_log() | gumjs-console.c | 发送日志消息 |
| console.warn() | gumjs_console_warn() | gumjs-console.c | 发送警告消息 |
| console.error() | gumjs_console_error() | gumjs-console.c | 发送错误消息 |
### Hexdump映射表
| JavaScript Function | C Function | File Location | Description |
| — | — | — | — |
| hexdump() | gum_hexdump_with_options() | gumhexdump.c | 生成内存十六进制转储 |
### Worker映射表
| JavaScript Constructor/Method | C Function | File Location | Description |
| — | — | — | — |
| newWorker() | gum_worker_new() | gumjs-worker.c | 创建工作线程 |
| worker.postMessage() | gum_worker_post_message() | gumjs-worker.c | 发送消息到工作线程 |
| worker.terminate() | gum_worker_terminate() | gumjs-worker.c | 终止工作线程 |
### Cloak映射表
| JavaScript Function | C Function | File Location | Description |
| — | — | — | — |
| Cloak.add() | gum_cloak_add() | gumcloak.c | 添加反调试隐藏规则 |
| Cloak.remove() | gum_cloak_remove() | gumcloak.c | 移除反调试隐藏规则 |
| Cloak.isApplied() | gum_cloak_is_applied() | gumcloak.c | 检查隐藏是否已应用 |
### Profiler映射表
| JavaScript Function | C Function | File Location | Description |
| — | — | — | — |
| Profiler.start() | gum_profiler_start() | gumprofiler.c | 开始性能剖析 |
| Profiler.stop() | gum_profiler_stop() | gumprofiler.c | 停止性能剖析 |
| Profiler.depth | gum_profiler_get_depth() | gumprofiler.c | 获取当前调用深度 |
## 内存布局与数据结构可视化
### GumConsole结构体内存布局
### GumWorker结构体内存布局
### GumHexdumpOptions结构体内存布局
### GumSampler结构体内存布局
## 系统调用级执行流程追踪
### console.log()执行流程
### hexdump()执行流程
### Worker.postMessage()执行流程
### Cloak.add()执行流程
### Profiler.start()执行流程
## 跨平台差异与抽象机制
### 平台特定实现
### 抽象层设计
## 调试命令与安全实践
### GDB调试示例
### 性能优化建议
### 安全考虑
## 错误处理与边界情况
### 常见错误场景
### 最佳实践
“javascript // 安全的控制台日志 function safeLog(…args) { try { // 过滤敏感信息 const safeArgs = args.map(arg => { if (typeof arg === ‘string’ && arg.includes(‘password’)) { return arg.replace(/password.?”/g, ‘password”:”**”‘); } return arg; });
} catch (e) { // 忽略日志错误,不影响主逻辑 } }
// 安全的内存转储 function safeHexdump(address, length = 256) { try { if (!address || address.isNull()) { throw new Error(‘Invalid address’); }
} catch (e) { console.error(‘Hexdump failed:’, e); return null; } }
// 安全的工作线程使用 function createSafeWorker(script) { try { const worker = new Worker(script);
} catch (e) { console.error(‘Failed to create worker:’, e); return null; } }
// 安全的性能剖析 function safeProfile(samplerType, durationMs = 1000) { try { let SamplerClass; switch (samplerType) { case ‘cycle’: SamplerClass = CycleSampler; break; case ‘wallclock’: SamplerClass = WallClockSampler; break; case ‘callcount’: SamplerClass = CallCountSampler; break; default: throw new Error(‘Unsupported sampler type’); }
} catch (e) { console.error(‘Profiling failed:’, e); } }
### 自定义内存分析工具
“javascript // 内存模式扫描工具 class MemoryScanner { constructor(baseAddress, size) { this.base = baseAddress; this.size = size; }
findPattern(pattern) { const matches = []; const scanResults = Memory.scanSync(this.base, this.size, pattern);
}
getContextAround(address, bytes = 16) { const start = address.sub(bytes / 2); const end = address.add(bytes / 2);
}
dumpRegion(name, address, length = 64) { console.log( ===${name}===); console.log(hexdump(address, { length: length, header: true })); console.log(‘==================’); } }
// 使用示例 const scanner = new MemoryScanner(Process.findModuleByName(‘libtarget.so’).base, 0x100000); const matches = scanner.findPattern(’48 89 ?? ?? ?? 48 8b’); matches.forEach(match => { console.log(‘Found pattern at:’, match.address); console.log(‘Context:’, match.context); });
### 底层扩展点
## 版本兼容性与演进
### API变更历史
### 向后兼容性保证
## 实战案例分析
### 案例1: 高级调试日志
“javascript // 实现带有调用栈的日志系统 function createStackLogger() { const originalLog = console.log;
console.log = function(…args) { try { // 获取调用栈 const stack = Thread.backtrace(Thread.backtrace(null, Backtracer.ACCURATE)) .map(DebugSymbol.fromAddress) .slice(1, 6) // 限制栈深度 .join(‘\n ‘);
}; }
// 启用栈日志 createStackLogger(); console.log(‘This message includes call stack!’);
### 案例3: 后台内存扫描
`javascript
// 使用Worker进行后台内存扫描
function backgroundMemoryScan(pattern, callback) {
const workerScript =const pattern = ‘${pattern}’; const base = ${Process.findModuleByName(‘libtarget.so’).base}; const size = ${0x100000};
`;
const worker = new Worker(workerScript);
worker.on(‘message’, (message) => { try { const results = JSON.parse(message); callback(null, results); } catch (e) { callback(e, null); } worker.terminate(); });
worker.on(‘error’, (error) => { callback(error, null); worker.terminate(); });
return worker; }
// 使用示例 backgroundMemoryScan(’48 89 ?? ?? ?? 48 8b’, (error, results) => { if (error) { console.error(‘Scan failed:’, error); } else { console.log(‘Found’, results.length, ‘matches’); results.forEach(addr => console.log(‘Match at:’, addr)); } });
### 案例5: 实时性能监控
“javascript // 实时性能监控面板 function createPerformanceDashboard() { const dashboard = { cpu: new CycleSampler(), memory: new MallocCountSampler(), calls: new CallCountSampler() };
// 开始监控 Object.values(dashboard).forEach(sampler => Profiler.start(sampler));
// 定期更新仪表板 const interval = setInterval(() => { console.clear(); console.log(‘=== Performance Dashboard ===’); console.log( CPUCycles:${dashboard.cpu.value}); console.log( MemoryAllocations:${dashboard.memory.value}); console.log( FunctionCalls:${dashboard.calls.value}); console.log(‘=============================’); }, 1000);
// 返回控制函数 return { stop: () => { clearInterval(interval); Object.values(dashboard).forEach(sampler => Profiler.stop()); console.log(‘Performance dashboard stopped’); }, getMetrics: () => ({ cpu: dashboard.cpu.value, memory: dashboard.memory.value, calls: dashboard.calls.value }) }; }
// 使用示例 const dashboard = createPerformanceDashboard();
// 5秒后停止 setTimeout(() => { dashboard.stop(); }, 5000);
c GUMJSDECLAREFUNCTION (gumjssend) GUMJSDECLAREFUNCTION (gumjssetincomingmessage_callback)
c struct _GumQuickMessageSink { JSValue callback; GumQuickCore * core; };
## 扩展功能:垃圾回收与内存管理
### Garbage Collection
Frida提供了手动触发垃圾回收的接口,用于在内存密集型操作后释放内存。
#### 接口定义层
#### 基础结构层
在 gumquickcore.c中声明:
#### 具体实现层
#### 使用场景
“javascript // 内存密集型操作后 for (let i = 0; i < 10000; i++) { // 创建大量临时对象 const data = Memory.alloc(1024); // … 处理数据 }
// 手动触发垃圾回收 gc();
console.log(‘Memory cleaned up’);
c GUMJSDECLAREFUNCTION (gumjssettimeout) GUMJSDECLAREFUNCTION (gumjssetinterval) GUMJSDECLAREFUNCTION (gumjscleartimer)
c struct _GumQuickScheduledCallback { gint id; gboolean repeat; JSValue func; GSource * source; GumQuickCore * core; };
// 调试通信问题 try { send({type: ‘debug’, message: ‘test’}); } catch (e) { console.error(‘Send failed:’, e.message); }
// 设置超时的接收 let received = false; recv((message) => { received = true; console.log(‘Received:’, message); }).wait(); // 阻塞等待
if (!received) { console.warn(‘No message received within timeout’); }
// 大量定时器的正确管理 const timers = [];
// 创建定时器时保存引用 const timer1 = setTimeout(() => { // 处理逻辑 }, 1000); timers.push(timer1);
const timer2 = setInterval(() => { // 处理逻辑 }, 5000); timers.push(timer2);
// 清理时取消所有定时器 function cleanup() { timers.forEach(timer => { clearTimeout(timer); clearInterval(timer); }); timers.length = 0;
}
// 监控通信性能 const startTime = Date.now(); send({type: ‘large_data’, data: largeArrayBuffer}); const sendTime = Date.now() – startTime;
console.log( Sendtook ${sendTime}ms);
// 监控GC影响 const heapBefore = Frida.heapSize; gc(); const heapAfter = Frida.heapSize; console.log( GC freed ${heapBefore-heapAfter}bytes); “`
-
QuickJS实现: 调用
JS_RunGC()触发垃圾回收 -
V8实现: 调用V8的垃圾回收API
-
gc()– 立即触发JavaScript引擎的垃圾回收 -
核心API保持稳定
-
新功能通过扩展方式添加
-
废弃的API会标记并提供迁移路径
-
Frida早期版本: 基本的Console和setTimeout支持
-
Frida 6.x: 添加Worker和Hexdump支持
-
Frida 8.x: 添加Cloak和Profiler支持
-
Frida 10.x: 完善跨平台支持和性能优化
-
Frida 12.x: 优化内存使用和错误处理
-
Frida 14.x: 改进Worker线程稳定性和Profiler准确性
-
可以通过修改
gumjs-console.c添加新的日志级别或格式 -
通过修改
gumhexdump.c添加新的内存转储格式 -
扩展Worker模块支持更多的消息类型和序列化格式
-
添加新的采样器类型支持更多的性能指标
-
Console错误:
-
消息通道断开:日志消息丢失
-
内存不足:无法分配消息缓冲区
-
格式化错误:复杂对象序列化失败
-
Hexdump错误:
-
无效地址:无法读取内存
-
权限不足:无法访问受保护内存
-
内存不足:无法分配输出缓冲区
-
Worker错误:
-
脚本语法错误:工作线程启动失败
-
消息序列化失败:无法发送复杂对象
-
线程创建失败:系统资源不足
-
Cloak错误:
-
规则冲突:多个隐藏规则相互干扰
-
系统调用拦截失败:无法完全隐藏
-
性能影响:隐藏机制导致性能下降
-
Console安全: 避免泄露敏感信息到日志
-
Worker安全: 注意工作线程的权限和隔离
-
Cloak安全: 理解反调试技术的局限性
-
Profiler安全: 注意性能剖析对目标应用的影响
-
Console优化:
-
避免频繁的日志输出影响性能
-
使用条件日志减少不必要的输出
-
批量处理日志消息
-
Worker优化:
-
重用工作线程避免频繁创建/销毁
-
使用适当的消息大小避免内存浪费
-
及时终止不再需要的工作线程
-
Profiler优化:
-
选择合适的采样器类型
-
控制采样频率避免过度开销
-
及时停止剖析避免内存泄漏
-
Console消息通道:
-
所有平台: 通过frida-core的统一消息通道
-
传输协议: 基于JSON的消息格式
-
异步处理: 非阻塞的消息发送
-
Hexdump内存访问:
-
Darwin: 使用Mach VM API进行安全内存读取
-
Linux: 使用信号处理捕获访问违规
-
Windows: 使用结构化异常处理(SEH)
-
Worker线程管理:
-
POSIX系统: 使用pthread API
-
Windows: 使用Windows线程API
-
统一抽象: 通过GLib的GThread封装
-
Cloak反调试技术:
-
Darwin: 隐藏dyld信息、修改进程信息
-
Linux: 隐藏/proc信息、修改ptrace检测
-
Android: 隐藏Java层信息、修改系统属性
-
拦截相关系统调用
-
修改内存保护属性
-
隐藏进程/线程信息
-
添加地址偏移
-
生成十六进制字节
-
生成ASCII字符表示
-
应用ANSI颜色(如果启用)
-
gum_profiler_start() -
gum_profiler_stop() -
gum_profiler_get_depth() -
采样器框架: 统一的采样器接口
-
性能计数: 各种性能指标的收集
-
调用栈跟踪: 函数调用深度和路径跟踪
-
gum_cloak_add() -
gum_cloak_remove() -
gum_cloak_is_applied() -
反调试隐藏: 隐藏Frida的存在痕迹
-
系统调用拦截: 拦截可能暴露Frida的系统调用
-
内存隐藏: 隐藏Frida相关的内存区域
-
gum_worker_new() -
gum_worker_post_message() -
gum_worker_terminate() -
线程管理: 创建和管理独立的工作线程
-
消息队列: 线程间消息传递机制
-
脚本执行: 在工作线程中执行JavaScript代码
-
gum_hexdump() -
gum_hexdump_with_options() -
内存读取: 安全的内存读取和错误处理
-
格式化输出: 支持多种输出格式(ANSI颜色、头部信息等)
-
缓冲区管理: 动态分配输出缓冲区
-
gumjs_console_log() -
gumjs_console_warn() -
gumjs_console_error() -
消息通道: 通过frida-core的消息通道发送日志消息
-
格式化处理: 支持多种数据类型的格式化输出
-
异步发送: 非阻塞的消息发送机制
-
setTimeout(callback,delay) -
clearTimeout(timerId) -
setImmediate(callback) -
clearImmediate(immediateId) -
Profiler.start() -
Profiler.stop() -
Profiler.depth -
Sampler相关接口: -
CycleSampler -
BusyCycleSampler -
WallClockSampler -
UserTimeSampler -
MallocCountSampler -
CallCountSampler -
Cloak.add(predicate) -
Cloak.remove(predicate) -
Cloak.isApplied() -
newWorker(script) -
worker.postMessage(message) -
worker.on('message',callback) -
worker.on('error',callback) -
worker.terminate() -
hexdump(target,options) -
options.offset -
options.length -
options.header -
options.ansi -
console.log(message) -
console.warn(message) -
console.error(message) -
console.info(message) -
console.debug(message)
-
### 性能监控 -
// 触发垃圾回收 -
gc(); -
### 内存泄漏预防 -
#### 具体实现层 -
-**GSource集成**:使用GLib的GSource机制实现跨平台定时器 -
-**事件循环**:定时器回调在JavaScript事件循环中执行 -
-**资源管理**:自动清理已取消或已完成的定时器 -
#### 详细函数映射表 -
|JavaScriptFunction| C Function|FileLocation|Description| -
|-------------------|------------|---------------|-------------| -
|setTimeout()|gumjssettimeout()|gumquickcore.c|设置一次性定时器| -
|setInterval()|gumjssetinterval()|gumquickcore.c|设置重复定时器| -
|clearTimeout()/clearInterval()|gumjscleartimer()|gumquickcore.c|清除定时器| -
## 扩展功能:简写API (Shorthand) -
### Shorthand APIs -
Frida提供了一些简写的全局函数,简化常见操作: -
#### 内存读写简写 -
虽然主要的内存操作通过Memory和NativePointer进行,但Frida也提供了一些便捷的全局函数: -
-**ptr(address)**-快速创建NativePointer -
-**NULL**-空指针常量 -
-**TRUE/FALSE**-布尔常量 -
#### 模块查找简写 -
-**Module.findExportByName(moduleName, symbolName)**-查找导出符号 -
-**Module.getBaseAddress(moduleName)**-获取模块基地址 -
这些简写API实际上是对相应模块方法的全局包装,提高了代码的可读性和编写效率。 -
## 跨平台差异与兼容性 -
### 通信机制差异 -
-**所有平台**:send()/recv()行为一致 -
-**性能差异**:不同平台的消息序列化性能可能略有差异 -
### 定时器精度 -
-**Unix/Linux/macOS**:基于GLibGSource,精度较高 -
-**Windows**:基于Windows定时器,精度受系统影响 -
-**Android**:受Linux内核定时器影响 -
### 垃圾回收行为 -
-**QuickJS**:增量标记清除GC,暂停时间短 -
-**V8**:分代GC,大内存应用性能更好 -
## 调试命令与安全实践 -
### 通信调试 -
关键数据结构: -
## 扩展功能:定时事件系统 -
### Timing Events -
Frida提供了标准的Web API定时器接口,用于异步任务调度。 -
#### 接口定义层 -
-**setTimeout(callback, delay, …args)**-延迟执行一次 -
-**setInterval(callback, delay, …args)**-重复执行 -
-**clearTimeout(timerId)**-取消setTimeout -
-**clearInterval(timerId)**-取消setInterval -
#### 基础结构层 -
在gumquickcore.c中实现: -
GUMJS_DECLARE_FUNCTION (gumjs_gc) -
#### 具体实现层 -
-**send实现**:将JavaScript对象序列化为JSON,通过frida-core的消息通道发送到主机 -
-**recv实现**:注册消息回调,在接收到主机消息时反序列化并调用JavaScript回调 -
#### 详细函数映射表 -
|JavaScriptFunction| C Function|FileLocation|Description| -
|-------------------|------------|---------------|-------------| -
|send()|gumjs_send()|gumquickcore.c|发送消息到主机| -
|recv()|gumjssetincomingmessagecallback()|gumquickcore.c|设置接收消息的回调| -
#### 实战案例:加密数据提取 -
``javascript -
// 注入脚本中 -
Interceptor.attach(targetFunction,{ -
onLeave:function(retval){ -
var decrypted = retval.readUtf8String(); -
// 发送解密数据到主机 -
send({ -
type:'decrypted_data', -
timestamp:Date.now(), -
data: decrypted -
}); -
} -
}); -
// 主机端 (Python) -
def on_message(message, data): -
if message['type']=='decrypted_data': -
print(f"Decrypted: {message['data']}") -
# 保存到文件或进一步处理 -
script.on('message', on消息) -
关键数据结构: -
## 总结与最佳实践 -
Tools模块为Frida提供了丰富的实用工具,从基础的日志输出到高级的性能剖析和反调试功能。理解其JS与C++的映射关系有助于: -
1.**高效调试**:利用Console和Hexdump进行高效的调试和分析 -
2.**性能优化**:使用Profiler和Sampler进行精确的性能监控 -
3.**安全增强**:通过Cloak模块增强反调试能力 -
4.**异步处理**:利用Worker模块进行后台任务处理 -
通过本文档的五层架构分析,开发者可以全面掌握Tools模块的工作原理和使用技巧,为各种动态分析任务提供强大的工具支持。 -
## 扩展功能:主机与注入进程通信机制 -
### Communication between Host and Injected Process -
Frida提供了强大的双向通信机制,允许注入的JavaScript代码与主机(Python/Node.js等)进行数据交换。 -
#### 接口定义层 (JavaScript API Layer) -
-**send(message, data)**-向主机发送消息 -
-message:可序列化的JavaScript对象(通常是包含type字段的对象) -
-data:可选的二进制数据(ArrayBuffer或NativePointer) -
-**recv(callback)**-接收来自主机的消息 -
-callback:处理接收到消息的回调函数 -
#### 基础结构层 (GumJS Binding Layer) -
在gumquickcore.c中实现: -
### 案例4: 反调试增强 -
``javascript -
// 使用Cloak模块增强反调试能力 -
function enhanceAntiDebug(){ -
if(!Cloak.isApplied()){ -
// 添加自定义隐藏规则 -
const hideFridaPredicate =Module.findExportByName(null,'some_function'); -
if(hideFridaPredicate){ -
Cloak.add(hideFridaPredicate); -
console.log('Custom anti-debug rule added'); -
} -
// 隐藏常见的Frida特征 -
const fridaFeatures =[ -
'frida-agent', -
'frida-server', -
'gum-js-loop', -
'gmain' -
]; -
fridaFeatures.forEach(feature =>{ -
try{ -
const featureAddr =Module.findExportByName(null, feature); -
if(featureAddr){ -
Cloak.add(featureAddr); -
} -
}catch(e){ -
// 忽略未找到的特征 -
} -
}); -
console.log('Anti-debug enhancement completed'); -
}else{ -
console.log('Cloak already applied'); -
} -
} -
enhanceAntiDebug(); -
const results =[]; -
Memory.scanSync(base, size, pattern).forEach(match =>{ -
results.push(match.address.toString()); -
}); -
postMessage(JSON.stringify(results)); -
### 案例2: 内存泄漏检测 -
``javascript -
// 使用MallocCountSampler检测内存泄漏 -
function detectMemoryLeaks(durationMs =10000){ -
const sampler =newMallocCountSampler(); -
const initialCount =0; -
Profiler.start(sampler); -
setTimeout(()=>{ -
const finalCount = sampler.value; -
Profiler.stop(); -
console.log(Memory allocations during ${durationMs}ms: ${finalCount – initialCount}); -
if(finalCount - initialCount >1000){ -
console.warn('Potential memory leak detected!'); -
// 进一步分析 -
const callCountSampler =newCallCountSampler(); -
Profiler.start(callCountSampler); -
setTimeout(()=>{ -
Profiler.stop(); -
console.log('Function calls during analysis:', callCountSampler.value); -
},1000); -
} -
}, durationMs); -
} -
detectMemoryLeaks(); -
// 输出带栈的日志 -
originalLog.call(console,...args,'\n Stack:', stack); -
}catch(e){ -
// 回退到普通日志 -
originalLog.call(console,...args); -
} -
### 自定义性能监控 -
``javascript -
// 高级性能监控器 -
classPerformanceMonitor{ -
constructor(){ -
this.samplers =newMap(); -
this.metrics =newMap(); -
} -
startMonitoring(metrics =['cpu','memory','calls']){ -
metrics.forEach(metric =>{ -
let sampler; -
switch(metric){ -
case'cpu': -
sampler =newCycleSampler(); -
break; -
case'memory': -
sampler =newMallocCountSampler(); -
break; -
case'calls': -
sampler =newCallCountSampler(); -
break; -
default: -
console.warn(Unknown metric: ${metric}); -
return; -
} -
this.samplers.set(metric, sampler); -
Profiler.start(sampler); -
}); -
console.log('Performance monitoring started for:',Array.from(this.samplers.keys())); -
} -
stopMonitoring(){ -
this.samplers.forEach((sampler, metric)=>{ -
Profiler.stop(); -
this.metrics.set(metric, sampler.value); -
}); -
this.samplers.clear(); -
console.log('Performance monitoring stopped'); -
} -
getMetrics(){ -
const currentMetrics ={}; -
// 获取当前采样器值 -
this.samplers.forEach((sampler, metric)=>{ -
currentMetrics[metric]= sampler.value; -
}); -
// 合并历史指标 -
this.metrics.forEach((value, metric)=>{ -
if(!currentMetrics.hasOwnProperty(metric)){ -
currentMetrics[metric]= value; -
} -
}); -
return currentMetrics; -
} -
report(){ -
const metrics =this.getMetrics(); -
console.log('Performance Report:'); -
Object.entries(metrics).forEach(([metric, value])=>{ -
console.log(${metric}: ${value}); -
}); -
} -
} -
// 使用示例 -
const monitor =newPerformanceMonitor(); -
monitor.startMonitoring(['cpu','calls']); -
// 执行一些操作 -
setTimeout(()=>{ -
monitor.report(); -
monitor.stopMonitoring(); -
},5000); -
try{ -
return hexdump(start,{ -
offset:0, -
length: bytes, -
header:false, -
ansi:false -
}); -
}catch(e){ -
return'Unable to read memory context'; -
} -
scanResults.forEach(match =>{ -
const context =this.getContextAround(match.address,32); -
matches.push({ -
address: match.address, -
context: context, -
hex: hexdump(match.address,{ length:16, ansi:false}) -
}); -
}); -
return matches; -
## 攻击检测场景映射 -
### 可用于检测的场景 -
-**反调试检测**:使用Cloak模块隐藏Frida存在 -
-**性能监控**:使用Profiler模块监控应用性能 -
-**内存分析**:使用Hexdump模块分析内存内容 -
-**异步处理**:使用Worker模块进行后台分析 -
### 防御绕过技术 -
-**日志过滤**:过滤可能暴露Frida的日志消息 -
-**内存加密**:加密敏感数据避免Hexdump泄露 -
-**多线程检测**:检测和规避Worker线程 -
-**性能混淆**:干扰Profiler的采样结果 -
## 性能分析与优化 -
### 时间复杂度分析 -
-**Console操作**: O(1),但涉及消息序列化和传输 -
-**Hexdump操作**: O(n),n为转储的字节数 -
-**Worker操作**: O(m),m为消息处理复杂度 -
-**Profiler操作**: O(1) per sample,采样频率影响总体开销 -
### 内存使用分析 -
-**Console**:每条消息需要分配临时缓冲区 -
-**Hexdump**:需要分配输出字符串缓冲区(约4x输入大小) -
-**Worker**:每个工作线程需要独立的JS引擎实例 -
-**Profiler**:采样器需要存储历史数据和统计信息 -
### 优化建议 -
-**Console**:批量发送日志消息,减少消息数量 -
-**Hexdump**:限制转储长度,避免大内存分配 -
-**Worker**:重用工作线程,避免频繁创建 -
-**Profiler**:选择低开销的采样器,控制采样频率 -
## 扩展功能与自定义实现 -
### 自定义日志系统 -
``javascript -
// 增强的日志系统 -
classEnhancedLogger{ -
constructor(prefix =''){ -
this.prefix = prefix; -
this.level ='info'; -
this.levels ={ -
debug:0, -
info:1, -
warn:2, -
error:3 -
}; -
} -
setLevel(level){ -
this.level = level; -
} -
log(level,...args){ -
if(this.levels[level]>=this.levels[this.level]){ -
const timestamp =newDate().toISOString(); -
const message =[${timestamp}] [${level.toUpperCase()}] ${this.prefix ? this.prefix + ‘: ‘ : ”}${args.join(‘ ‘)}; -
console.log(message); -
} -
} -
debug(...args){this.log('debug',...args);} -
info(...args){this.log('info',...args);} -
warn(...args){this.log('warn',...args);} -
error(...args){this.log('error',...args);} -
} -
// 使用示例 -
const logger =newEnhancedLogger('MyModule'); -
logger.setLevel('debug'); -
logger.info('Application started'); -
logger.debug('Debug information'); -
const sampler =newSamplerClass(); -
Profiler.start(sampler); -
setTimeout(()=>{ -
Profiler.stop(); -
console.log(Profiling results for ${samplerType}:, sampler.value); -
}, durationMs); -
worker.on('error',(error)=>{ -
console.error('Worker error:', error); -
}); -
worker.on('message',(message)=>{ -
try{ -
// 处理工作线程消息 -
handleMessage(message); -
}catch(e){ -
console.error('Message handling error:', e); -
} -
}); -
return worker; -
return hexdump(address,{ -
offset:0, -
length: length, -
header:true, -
ansi:false -
}); -
console.log(...safeArgs); -
# 在控制台消息发送处设置断点 -
(gdb)break gumjs_console_log -
# 查看消息内容 -
(gdb) info args -
(gdb) x/s $rdi # 查看消息字符串 -
# 在十六进制转储处设置断点 -
(gdb)break gum_hexdump_with_options -
(gdb) info registers -
(gdb) x/32bx $rdi # 查看目标内存内容 -
// 采样器抽象接口 -
struct_GumSampler -
{ -
GObject parent; -
GumSamplerType type; -
guint64 start_time; -
guint64 sample_count; -
void(* start)(GumSampler* self); -
void(* stop)(GumSampler* self); -
guint64 (* get_current_value)(GumSampler* self); -
void(* reset)(GumSampler* self); -
}; -
// 工作线程抽象接口 -
struct_GumWorker -
{ -
GObject parent; -
GThread* thread; -
GumWorkerMessageQueue* message_queue; -
gchar * script; -
gboolean is_terminated; -
gboolean (* post_message)(GumWorker* self,const gchar * message); -
void(* terminate)(GumWorker* self); -
gboolean (* is_alive)(GumWorker* self); -
}; -
JavaScript调用
Profiler.start(sampler)→ GumJS绑定层 -
调用
gum_profiler_start(sampler) -
初始化采样器状态
-
记录开始时间戳
-
设置采样间隔(如果适用)
-
开始收集性能数据
-
返回控制权给JavaScript
-
返回操作结果
-
JavaScript调用
Cloak.add(predicate)→ GumJS绑定层 -
调用
gum_cloak_add(predicate) -
验证predicate函数的有效性
-
将predicate添加到隐藏规则列表
-
如果隐藏尚未应用,应用所有规则:
-
JavaScript调用
worker.postMessage(message)→ GumJS绑定层 -
调用
gum_worker_post_message(worker,message) -
序列化消息内容为字符串
-
将消息添加到工作线程的消息队列
-
如果工作线程正在等待消息,唤醒它
-
返回控制权给JavaScript(异步操作)
-
返回格式化的字符串
-
JavaScript调用
hexdump(target,options)→ GumJS绑定层 -
调用
gum_hexdump_with_options(target,options) -
验证目标地址和长度的有效性
-
安全读取内存内容(处理访问违规)
-
根据选项格式化输出:
-
JavaScript调用
console.log(message)→ GumJS绑定层 -
调用
gumjs_console_log(message) -
格式化消息内容(处理多个参数和不同数据类型)
-
通过frida-core的消息通道发送消息
-
主机端接收消息并输出到控制台
-
返回控制权给JavaScript
-
+------------------+ -
| type (GumSamplerType)|->采样器类型 -
+------------------+ -
| start_time (guint64)|->开始时间戳 -
+------------------+ -
| sample_count (guint64)|->采样次数 -
+------------------+ -
| current_value (guint64)|->当前采样值 -
+------------------+ -
+------------------+ -
| offset (gssize)|->起始偏移量 -
+------------------+ -
| length (gsize)|->转储长度 -
+------------------+ -
| header (gboolean)|->是否显示头部 -
+------------------+ -
| ansi (gboolean)|->是否使用ANSI颜色 -
+------------------+ -
+------------------+ -
| thread (GThread*)|->工作线程句柄 -
+------------------+ -
| message_queue (GumWorkerMessageQueue*)|->消息队列 -
+------------------+ -
| script (char*)|->工作线程脚本内容 -
+------------------+ -
| is_terminated (gboolean)|->是否已终止 -
+------------------+ -
| mutex (GMutex)|->线程同步互斥锁 -
+------------------+ -
+------------------+ -
| script (GumScript*)|->脚本上下文引用 -
+------------------+ -
| message_handler (GumScriptMessageHandler)|->消息处理器回调 -
+------------------+ -
| message_data (gpointer)|->消息处理器用户数据 -
+------------------+ -
// GumConsole工厂 -
GumConsole* -
gum_console_new (GumScript* script); -
void -
gum_console_set_message_handler (GumConsole* console,GumScriptMessageHandler handler, gpointer data); -
// GumWorker工厂 -
GumWorker* -
gum_worker_new (const gchar * script); -
GumWorkerMessageQueue* -
gum_worker_message_queue_new (void); -
// GumSampler工厂 -
GumSampler* -
gum_cycle_sampler_new (void); -
GumSampler* -
gum_busy_cycle_sampler_new (void); -
GumSampler* -
gum_wall_clock_sampler_new (void); -
GumSampler* -
gum_user_time_sampler_new (void); -
GumSampler* -
gum_malloc_count_sampler_new (void); -
GumSampler* -
gum_call_count_sampler_new (void); -
// Console相关的结构 -
typedefstruct_GumConsoleApi{ -
void(* log)(const gchar * message); -
void(* warn)(const gchar * message); -
void(* error)(const gchar * message); -
void(* info)(const gchar * message); -
void(* debug)(const gchar * message); -
}GumConsoleApi; -
// Hexdump相关的结构 -
typedefstruct_GumHexdumpApi{ -
gchar *(* hexdump)(gconstpointer target,GumHexdumpOptions* options); -
}GumHexdumpApi; -
// Worker相关的结构 -
typedefstruct_GumWorkerApi{ -
GumWorker*(* new_worker)(const gchar * script); -
void(* post_message)(GumWorker* worker,const gchar * message); -
void(* terminate)(GumWorker* worker); -
}GumWorkerApi; -
// Cloak相关的结构 -
typedefstruct_GumCloakApi{ -
gboolean (* add)(GumAddress predicate); -
gboolean (* remove)(GumAddress predicate); -
gboolean (* is_applied)(void); -
}GumCloakApi; -
// Profiler相关的结构 -
typedefstruct_GumProfilerApi{ -
void(* start)(GumSampler* sampler); -
void(* stop)(void); -
gint (* get_depth)(void); -
}GumProfilerApi;
- 公众号:安全狗的自我修养
- vx:2207344074
- http://gitee.com/haidragon
- http://github.com/haidragon
- bilibili:haidragonx
#
#
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:安全狗的自我修养 haidragon haidragon《frida各模块js与cpp函数分析对照(八)》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。








评论