当前位置: 首页 > news >正文

Frida:配置自动补全 in VSCode

1. 前言

编写 frida JavaScript 脚本是一件 very 普遍的事情在 Android Reverse 中。为了方便编写,配置相关的环境使其能够自动补全是很关键的,即通过类名就能够获取该类的所有对外接口信息,这是面向对象编程的核心优势,可惜我没有对象。

首先我们还是要有一个信仰,相信这是能够配置好的,这个原因很简单,因为 frida 的控制台中就给出了相应的补全操作,只是因为操作不方便我才要去 VSCode 中配置。
在这里插入图片描述

2. 配置

In C/C++ 中我们只需要 #include 相应的头文件就能够达到在编写源码时的自动补全了,后续的补全操作都是由 MicrosoftIntelliSense 组件完成的。

同样的在 JavaScript 中包含相应的 .ts (TypeScript)文件就能够达到这样的效果。当然 .ts 绝对不是用来干这个的,只是我找到的 frida-gum 的相关文件是 .ts 的。相应的下载地址在这 @types/frida-gum。我下载的是 19.0.0 版本的,对应的 frida-17.2.* 这个版本的 APIfrida-16.1.0 是不同的,配置的时候需要找到对应版本的 index.d.ts 文件。

安装 node.js 后可以直接使用其附带的 npm 进行下载。After 下载,@types/frida-gum 目录下的 index.d.ts 复制到 Frida JavaScript 目录下即可。在文件开头添加下面的代码进行包含即可。

/// <reference path="./frida.d.ts" />

当然如果不 want 下载 node.js 可以直接从网页端产看代码,然后全选,复制到文件中保存,这里我要吐槽一下 npm 管理了,代码都展示出来了却不提供下载的接口。

完成包含后就可以在 VSCode 使用 Frida 的自动补全了。
在这里插入图片描述

3. API 变化

frida-17.2.5frida-16.1.0API 是不一样的,这里我只能说我亲身体会到的一个例子,这个 Bug 我找了好久,修完之后 I just wanna say sun your mum frida

下面的代码是 frida-16.1.0 以及很多网上教程中常用的用来 Hook Android 加载库时的操作。但在 frida-17.2.5 中这样的操作是不行的。

Module.findExportByName(null, "dlopen");

当输入上述 JavaScript 之后会在得到这样的报错信息,出现这样错误的原因是 frida-17.2.5 中没有相应的 API 实现。
在这里插入图片描述
When 我去查看相应的 API 描述 in @type/frida-gum-19.0.0 时,发现在 Module 中只有一个 findExportByName 的实现,而其参数列表只接受一个参数,并且函数没有 static 关键字修饰,必须要实例化之后才能使用。
在这里插入图片描述

While in @type/frida-gum-15.2.0 中则是另一种情况,在其 Module 中有两个 findExportByName 的实现,并且其中一个使用 static 关键字修饰,即不需要实例化也能使用。这就是代码 Module.findExportByName(null, "dlopen") 为什么在 frida-16.1.0 中能够正常使用的原因。
在这里插入图片描述

4. Some Code

这部分是我用来记录自己写的 JavaScript 代码的位置,主要是给自己以后查阅。使用的是 frida-17.2.5。包括:查找 API 函数输出调用栈颜色字

/// <reference path="./frida.d.ts" />
const CMD_RED = "\x1b[31m";
const CMD_GREEN = "\x1b[32m";
const CMD_YELLOW = "\x1b[33m";
const CMD_BLUE = "\x1b[34m";
const CMD_MAGENTA = "\x1b[35m";
const CMD_CYAN = "\x1b[36m";
const CMD_WHITE = "\x1b[37m";
// Store original console.log
const originalLog = console.log;
// Override console.log
console.log = function(...args) {originalLog(args, CMD_WHITE);
};console.log(CMD_GREEN + "[+] Enter Hook");/*** get a export function by its name* @param {string} strName : the function you want to hook* @returns {fnPoint} : the address of the function*/
function FindExportByName(strName) {var fn = null;const Modules = Process.enumerateModules();for(let i = 0; i < Modules.length; i++) {fn = Modules[i].getExportByName(strName);if(fn) {console.log(`In Module : ${Modules[i].name}, Address is : ${fn}`);break;}};return fn;
}/*** print out a thread calling stack * @param {context} Context : the context of current Thread, can be obtained in Interceptor.attach() callback*/
function TraceStack(Context) {try {const backtrace = Thread.backtrace(Context, Backtracer.ACCURATE).map(DebugSymbol.fromAddress).map(sym => sym.name + CMD_YELLOW +'[' + sym.moduleName + ']');console.log(CMD_YELLOW + 'Backtrace:');backtrace.forEach((frame, i) => console.log(CMD_GREEN + "\t" + `${i}: ${frame}`));}catch(e) {console.log(CMD_RED + "\tStack trace unavailable");console.log(CMD_RED + `\t${e}`);}console.log(CMD_GREEN + "End Trace");
}// record which lib are loaded
var setLoged = new Set(["libstats_jni.so"]);
/*** if the module isn't record in setLoged, then print it.* @param {string} libPath : the module name that is loaded* @returns : if the first that load it return 1 else return 0.*/
function LogLib(libPath) {if(libPath && !setLoged.has(libPath)) {setLoged.add(libPath);console.log(CMD_CYAN + `Load Module : ${libPath}`);return 1;}return 0;//console.log(CMD_RED + `00: ${this}`);
}function TraceModuleLoad() {var fnOpen = FindExportByName("android_dlopen_ext");if(fnOpen) {var bThere = 0;var libPath;Interceptor.attach(fnOpen, {onEnter(args) {libPath = args[0].readCString();bThere = LogLib(libPath);//Thread.sleep(10);if(bThere) {TraceStack(this.context);}},onLeave(retval) {}})console.log("Complete dlopen hook install");}
}
// get all the load module when apk start
TraceModuleLoad();console.log(CMD_YELLOW + "[-] Hook Installed");
http://www.dtcms.com/a/265460.html

相关文章:

  • 搭建VirtualBox-6+vagrant_2+docker+mysql5.7的步骤
  • 客户案例 | 某新能源车企依托Atlassian工具链+龙智定制开发服务,打造符合ASPICE标准的研发管理体系
  • 云原生系统DOCKER中容器系统搭建
  • Python字符与ASCII转换方法
  • Ubuntu Gnome 安装和卸载 WhiteSur-gtk-theme 类 Mac 主题的正确方法
  • vue2+elementui使用compressorjs压缩上传的图片
  • Euler2203安装.NetCore6.0环境操作步骤
  • python安装虚拟环境
  • Python 物联网(IoT)与边缘计算开发实战(1)
  • 优雅草蜻蜓R实时音视频会议系统云原生私有化部署方案深度解析-优雅草卓伊凡|贝贝|clam|麻子|夜辰
  • Docker 容器资源限制
  • 9.Docker的容器数据卷使用(挂载)
  • ATE FT ChangeKit学习总结-20250630
  • 网络的封包与拆包
  • 基于Java的企业项目管理与协作系统设计与实现
  • Dataset Distillation by Matching Training Trajectories(2203.11932)
  • Eclipse主题拓展
  • mysql索引的底层原理是什么?如何回答?
  • Go语言的sync.Once和sync.Cond
  • Redis 源码 tar 包安装 Redis 哨兵模式(Sentinel)
  • Go调度器的抢占机制:从协作式到异步抢占的演进之路|Go语言进阶(7)
  • 价值实证:数字化转型标杆案例深度解析
  • 网络地址与子网划分:一次性搞清 CIDR、VLSM 和子网掩码
  • 分类树查询性能优化:从 2 秒到 0.1 秒的技术蜕变之路
  • 如何在 IDEA 中设置类路径
  • 探索具身智能新高度——机器人在数据收集与学习策略中的优势和机会
  • Objective-C UI事件处理全解析
  • c++中的绑定器
  • 如何使用AI改进论文写作 ---- 引言篇(2)
  • 设计模式系列(10):结构型模式 - 桥接模式(Bridge)