【frida】03 初识frida-node

本文介绍了如何在Node.js环境下安装和使用Frida-Node,通过创建脚本实现对MessageBoxA函数的钩子,捕获并显示其参数。作者提供了详细的步骤和示例,适合开发者进行动态分析和调试工作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

🛫 导读

需求

frida每次安装都需要配置python环境,想想都麻烦,今天来一个纯js的环境:frida-node。

开发环境

版本号描述
文章日期2024-03-13
操作系统Win11 - 22H222621.2715
git地址https://gitcode.net/kinghzking/MyOpen
代码相对路径course\frida\03_frida-node\foo
node -vv20.10.0
npm -v10.2.3
frida-node16.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的两个参数,效果如下图:
在这里插入图片描述

📖 参考资料

ps: 文章中内容仅用于技术交流,请勿用于违规违法行为。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

夜猫逐梦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值