TMF 框架 Frida Hook 脚本逻辑深度解析

这份文档围绕TMF框架的Frida Hook脚本(tmf.js) 展开,是实操过程中对脚本开发、代码逻辑、Frida/Java/OkHttp技术细节的深度解析与问题探讨,核心聚焦tmf.js中Hook TMF框架sendShark方法、自定义回调、协议转发的实现逻辑,同时厘清了Frida操作Java对象、OkHttp发起请求的关键语法和底层原理,整体以实操疑问+逻辑拆解+技术解答的形式推进,核心内容提炼如下:

一、核心开发背景与脚本目标

基于Frida开发tmf.js脚本,实现对TMF框架的请求/响应拦截、篡改与转发,核心是Hook TMF框架的sendShark(请求发送核心方法)和ISharkCallBack2接口的onFinish(响应回调方法),并通过OkHttp将TMF私有协议的请求/响应转换为标准HTTP协议,绕过应用代理检测、实现数据抓包与调试,同时提供RPC接口供外部调用自定义发包。

二、TMF框架核心类与关键结构解析

  1. SharkHttpEntity :TMF框架的请求/响应实体类,核心字段包括params(请求元数据)和data(请求体/响应体原始字节流);其中params字段类型为SashimiHeader。

  2. SashimiHeader :TMF框架的请求/响应元数据容器类,封装了apiName(接口名)、header(请求/响应头,Map类型)、cookiesquery等核心参数,同时承载请求和响应元数据 ;实操中发现目标APP存在Protocol.MShark.SashimiHeaderProtocol.MTMFShark.SashimiHeader两个类,前者继承后者且结构/字段完全一致,为开发时的兼容处理提供了基础。

  3. ISharkCallBack2 :TMF框架的异步响应回调接口,必须实现onFinish方法,请求完成后框架会自动回调该方法并传入响应数据(SharkHttpEntity类型)。

三、tmf.js核心实现逻辑拆解

脚本整体遵循**「类初始化→自定义回调注册→Hook请求/响应→协议转换与转发→RPC导出」** 流程,核心模块及实操疑问解答如下:

(一)Java类与工具初始化

通过Java.use(类全限定名)获取TMF框架、Java基础类、OkHttp相关类的引用,为后续Hook和操作做准备,关键包括:

  • TMF相关:SharkClass(sendShark所属类)、SashimiHeader、SharkHttpEntity;

  • 基础工具:fastJson(序列化/反序列化)、StringClass(java.lang.String)、MapClass(java.util.Map);

  • OkHttp相关:OkHttpClient、Request、RequestBody、MediaType。

实操中发现预定义的PClass/PPClass(两个SashimiHeader类引用)为冗余代码 ,脚本实际通过Java.use(sharkHttpEnt.params.value.$className)动态获取类名,自动匹配真实的SashimiHeader类,因此错误的包名定义不影响执行。

(二)自定义响应回调类注册:MyHttpEntityCallback

通过Frida的Java.registerClass动态创建实现ISharkCallBack2接口的自定义类,核心作用是接管TMF框架的响应回调,获取响应数据并转发,关键细节:

  1. 类名规则:自定义全限定名(如com.owl.MyHttpEntityCallback)可随意定义,只需保证进程内唯一,避免与应用原有类冲突;

  2. 必实现方法 :因实现ISharkCallBack2接口,必须重写onFinish方法,框架请求完成后会自动触发;

  3. Frida特殊语法

    • $init:代表Java构造方法,用于初始化类的成员变量(如保存apiName,为后续区分接口做标记);

    • 方法需通过argumentTypes声明参数类型,无参则设为空数组;

    • 访问Java对象成员变量必须加.value(Frida封装的取值语法,类似C语言解引用指针,获取堆中实际值)。

(三)Hook核心方法:sendShark与onFinish

1. Hook sendShark(请求拦截)
  • 拦截APP调用TMF框架的请求发送方法,解析原始请求的apiName、header、body等参数;

  • 支持参数篡改:阻塞等待Python控制端(<tmf-killer.py>)的修改指令,替换参数后调用原始sendShark方法完成请求发送。

2. Hook onFinish(响应拦截)
  • 接管ISharkCallBack2的响应回调,解析TMF框架返回的响应数据(SharkHttpEntity类型);

  • 核心操作:将响应数据转换为标准HTTP格式,通过OkHttp转发,实现私有协议到HTTP的转换。

关键技术:Java.cast(对象, 目标类)------解决Frida跨语言(JS调用Java)的类型丢失问题,将Object类型的参数强制转换为目标类,才能正常访问其成员变量和方法。

(四)私有协议转标准HTTP:OkHttp转发实现

将解析到的TMF请求/响应数据,通过OkHttp重新构造标准HTTP请求发送,绕过应用代理检测,核心步骤与语法:

  1. OkHttp核心三要素:OkHttpClient(请求执行者)、Request$Builder(请求构造器)、RequestBody(请求体封装);

  2. 建造者模式 :OkHttpClient和Request均通过内部类$Builder构建,链式配置参数后调用build()生成实例,解决复杂对象的创建问题;

  3. 关键配置

    • MediaType:指定请求体MIME类型(如application/json),等效于HTTP的Content-Type头,告诉服务端数据格式;

    • RequestBody.create:将TMF的data字节流封装为OkHttp可识别的请求体;

  4. 转发逻辑 :在自定义回调的onFinish方法中,解析响应的apiName、header、body,拼接为JSON格式,通过OkHttp发送到指定地址,实现响应数据的转发。

(五)RPC接口导出

封装自定义的sendShark方法,通过rpc.exports导出为RPC接口,供Python控制端(<tmf-killer.py>)调用,实现PC端控制移动端发送自定义TMF请求,形成完整的请求/响应闭环。

四、Frida操作Java的核心语法与底层原理

  1. Java.use :入参为类的全限定名(包名+类名),获取Java类的引用,支持类、接口、静态内部类;

  2. Java.registerClass :Frida动态创建Java类,必填name(类名)和methods(方法定义),可选implements(实现的接口)和fields(成员变量);

  3. Java.cast:强制类型转换,解决JS调用Java的类型丢失问题,仅当需要访问对象的成员/方法时使用;

  4. .value:Frida访问Java对象成员变量的专属语法,获取堆中实际值,否则仅拿到对象引用;

  5. $new() :Frida中创建Java对象的方法,等效于Java的new关键字;

  6. $className:Frida中获取Java对象所属类的全限定名的属性;

  7. 静态内部类访问 :通过外部类$内部类的形式获取,如OkHttpClient$Builder

五、OkHttp核心使用原理

  1. 核心角色:OkHttpClient是请求"引擎",负责底层网络连接、超时、重试;Request是请求"蓝图",定义URL、方法、头、体;

  2. 建造者模式 :通过Builder类链式配置参数,避免多构造器的冗余,最终通过build()生成可执行实例;

  3. POST请求关键:必须封装RequestBody并指定MediaType,否则服务端无法解析请求体;

  4. 请求执行 :通过OkHttpClient.newCall(Request).execute()发送同步请求,获取响应数据。

六、实操关键问题与解决方案

  1. 两个SashimiHeader类的兼容:目标APP同时存在两个包下的SashimiHeader,且结构一致,脚本通过动态获取类名实现自动匹配,无需手动区分;

  2. 代理检测绕过:不依赖系统代理设置,通过OkHttp直接构造HTTP请求发送到指定地址,在代码层面绕过应用的代理检测逻辑;

  3. 冗余代码清理:删除未被引用的PClass/PPClass,简化代码结构,提升可读性;

  4. 代码可读性优化:规范变量命名(见名知意)、统一日志格式、按功能分层、抽离公共代码(如解析SharkHttpEntity的方法)。

七、整体联动逻辑

tmf.js并非独立运行,而是与Python控制端(<tmf-killer.py>)、Burp形成**「移动端拦截→PC端转发→Burp修改→PC端返回→移动端篡改」** 的闭环:

  1. tmf.js拦截TMF请求/响应,通过Frida的send()将数据发送到Python端;

  2. Python端将数据转发到Burp,供用户可视化修改参数;

  3. Python端将Burp修改后的参数通过script.post()返回给tmf.js;

  4. tmf.js接收修改指令,篡改请求/响应后执行原始方法,完成全链路控制;

  5. 同时支持外部调用Python端的HTTP服务,触发tmf.js的RPC接口,实现自定义TMF发包。

(注:文档部分内容可能由 AI 生成)

相关推荐
wearegogog1231 小时前
基于SIFT、DoG与RANSAC的全景图像拼接MATLAB实现
开发语言·matlab
逍遥德2 小时前
如何学编程之理论篇.03.如何做数据库表结构设计?
开发语言·数据库·性能优化·代码规范·代码复审
froginwe112 小时前
TCP/IP 邮件
开发语言
Ivanqhz2 小时前
数据流分析的核心格(Lattice)系统
开发语言·javascript·后端·python·算法·蓝桥杯·rust
键盘鼓手苏苏2 小时前
Flutter for OpenHarmony 实战:Flutter Rust Bridge — 极致计算性能方案
开发语言·后端·flutter·华为·rust·json·harmonyos
he___H2 小时前
jvm41-47回
java·开发语言·jvm
csdn2015_2 小时前
MybatisPlus LambdaQueryChainWrapper 联合查询
开发语言·windows·python
骑猪撞地球QAQ2 小时前
Java在导出excel时中添加图片导出
java·开发语言·excel
悦悦子a啊2 小时前
CSS 知识点
开发语言·前端·css