🛫 导读
需求
frida每次安装都需要配置python环境,想想都麻烦,今天来一个纯js的环境:frida-node。
开发环境
版本号 | 描述 | |
---|---|---|
文章日期 | 2024-03-13 | |
操作系统 | Win11 - 22H2 | 22621.2715 |
git地址 | https://gitcode.net/kinghzking/MyOpen | |
代码相对路径 | course\frida\03_frida-node\foo | |
node -v | v20.10.0 | |
npm -v | 10.2.3 | |
frida-node | 16.2.1 | |
1️⃣ 安装
Frida 是一种强大的动态分析工具,它可以帮助安全研究人员、逆向工程师和开发者进行应用程序的动态分析和修改。而 Frida-Node 是 Frida 的 Node.js 绑定,它使得在 Node.js 环境中使用 Frida 变得更加方便。
node安装库,一如既往的简单,执行下面命令即可:
npm install frida
2️⃣ 创建一个 Frida-Node 脚本
注入js详解
注入的js详见代码注释,使用了下面几个函数:
- Module.findExportByName :获取MessageBoxA地址
- Interceptor.attach :执行hook
console.log("开始注入脚本");
// 获取MessageBoxA地址
const funcAddr = Module.findExportByName('user32.dll', 'MessageBoxA')
// hook MessageBoxA
Interceptor.attach(funcAddr, {
// 进入函数前打印第一个参数(从0开始计算,第0个参数为句柄)
onEnter(args) {
send("HOOK MessageBoxA args[1] = " + args[1].readAnsiString())
send("HOOK MessageBoxA args[2] = " + args[2].readAnsiString())
}
});
简单的将上面的代码封装为函数,直接返回字符串。
async function 获取注入脚本() {}
主逻辑
执行了下面几个逻辑:
- 获取进程ID
- 获取注入脚本
- 设置消息通知处理函数
- 剩下的就是固定模式:创建session、script;最后load脚本。
// node main.js MyTestMFC-vcpkg.exe
import frida from "frida";
// 消息通知处理函数
function onMessage(message, data) {
if (message.type === 'send') {
console.log('[*] ', message.payload);
} else if (message.type === 'error') {
console.error(message.stack);
}
}
async function 获取进程ID() {
let exeName = process.argv[2]
console.log("exeName:", exeName)
var device = await frida.getLocalDevice();
var processes = await device.enumerateProcesses(); // 尽量使用管理员权限执行脚本。
var pid = -1;
processes.forEach(async (p_) => {
// console.log(p_.name, p_.pid, p_);
if (p_.name == exeName) {
// 找到第一个就是
if (pid == -1) {
pid = p_.pid;
}
}
});
console.log("主进程 pid = " + pid);
return pid;
}
async function 获取注入脚本() {
return `
console.log("开始注入脚本");
// 获取MessageBoxA地址
const funcAddr = Module.findExportByName('user32.dll', 'MessageBoxA')
// hook MessageBoxA
Interceptor.attach(funcAddr, {
// 进入函数前打印第一个参数(从0开始计算,第0个参数为句柄)
onEnter(args) {
send("HOOK MessageBoxA args[1] = " + args[1].readAnsiString())
send("HOOK MessageBoxA args[2] = " + args[2].readAnsiString())
}
});
`
}
async function main() {
let jsSource = await 获取注入脚本()
const pid = await 获取进程ID();
if (pid == -1) {
return -1;
}
// 固定模式
let session = await frida.attach(pid);
let script = await session.createScript(jsSource);
script.message.connect(onMessage);
await script.load();
}
main().catch(error => {
console.error(error);
});
3️⃣ 效果
执行脚本
node ./course/frida/03_frida-node/foo/main.js MyTestMFC-vcpkg.exe
其中MyTestMFC-vcpkg.exe
为小编自己写的测试程序,该程序点击按钮的时候,弹出对话框。
执行脚本,hook成功后,显示下面内容,且不报错。
点击按钮,弹出对话框时,会打印MessageBoxA的两个参数,效果如下图:
📖 参考资料
- [frida] 00_简单介绍和使用 https://blog.csdn.net/kinghzking/article/details/123225580
- [frida] 01_食用指南(持续更新) https://blog.csdn.net/kinghzking/article/details/126849567
ps: 文章中内容仅用于技术交流,请勿用于违规违法行为。