You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Frida hook基于Electron开发的Linux桌面应用FreeTube

关于Frida hook Electron应用FreeTube的问题

背景

我正在学习Frida,已经完成不少Android端应用hook的教程练习,觉得Frida是款强大的工具。现在需要hook基于Electron开发的Linux桌面应用FreeTube里ft-input.js文件中的handleClick函数,函数代码如下:

handleClick: function (e) {
  // No action if no input text
  if (!this.inputDataPresent) {
    return
  }

  this.searchState.showOptions = false
  this.searchState.selectedOption = -1
  this.searchState.keyboardSelectedOptionIndex = -1
  this.removeButtonSelectedIndex = -1
  this.$emit('input', this.inputData)
  this.$emit('click', this.inputData, { event: e })
},

但网上Electron应用hook的教程很少,Frida官方文档信息也有限。我尝试向FreeTube的渲染进程注入以下hook代码:

// hook.js
if (typeof document !== "undefined") {
    console.log("[Frida] Attached to renderer process");
} else {
    console.log("[Frida] Attached to main process or invalid context");
}

结果无法获取渲染进程上下文,document未定义,因此有以下疑问:

疑问

  • Frida能否hook基于Electron的PC应用?是否支持hook JavaScript?若不支持JS,是否也不支持Python?
  • 若支持hook JavaScript,应在哪个层级进行?渲染进程、V8引擎还是其他位置?
  • 恳请提供针对Electron应用的hook代码示例。

另外我找到一个Frida的issue,但里面没提到Python版hook的使用方法。我是Frida、JavaScript和Electron新手,如果思路有误,希望能指正。


解答

1. Frida对Electron应用及JS/Python的支持

Frida完全支持hook Electron应用,也支持hook JavaScript代码。Electron本质是基于Chromium和Node.js,Frida可以注入到Electron的各个进程(主进程、渲染进程)中,不管是用Frida的JS脚本还是Python绑定都可以实现hook。

2. 正确的hook层级

Electron应用分为主进程(Node.js环境)和渲染进程(Chromium的V8环境,同时支持浏览器API和Node.js API)。要hook你目标的handleClick函数(属于渲染进程里的前端组件逻辑),必须注入到渲染进程的V8上下文里。

你之前的脚本没获取到document,大概率是因为注入到了主进程,或者注入时机不对(渲染进程的V8上下文还没初始化完成)。

3. 代码示例

方法一:JS脚本直接hook渲染进程

首先,找到FreeTube的渲染进程PID,或者用进程名匹配注入:

# 注入到FreeTube的渲染进程,Linux下可以用进程名过滤
frida -n FreeTube -l hook.js

编写hook.js,确保注入到渲染进程的V8上下文,针对Vue组件的handleClick函数,可通过以下两种思路实现hook:

// 等待渲染进程上下文初始化
setTimeout(() => {
  if (typeof document !== 'undefined') {
    console.log('[Frida] 成功进入渲染进程上下文');
    
    // 方法1:拦截Vue组件的$emit,监听handleClick触发的事件
    const originalEmit = Vue.prototype.$emit;
    Vue.prototype.$emit = function(eventName, ...args) {
      if (eventName === 'click' && this.$options.name === 'ft-input') {
        console.log('[Frida] 捕获ft-input的handleClick事件');
        console.log('inputData:', args[0]);
        console.log('事件对象:', args[1]);
      }
      return originalEmit.call(this, eventName, ...args);
    };

    // 方法2:直接找到ft-input组件的handleClick方法
    const FtInputComponent = Vue.options.components['ft-input'];
    if (FtInputComponent) {
      const originalHandleClick = FtInputComponent.methods.handleClick;
      FtInputComponent.methods.handleClick = function(e) {
        console.log('[Frida] 直接hook到handleClick函数');
        console.log('inputDataPresent:', this.inputDataPresent);
        console.log('inputData:', this.inputData);
        // 调用原函数
        return originalHandleClick.call(this, e);
      };
    }
  } else {
    console.log('[Frida] 当前不在渲染进程上下文,可能注入到了主进程');
  }
}, 3000); // 延迟3秒等待页面加载完成

方法二:Python脚本实现hook

用Frida的Python绑定,可以更灵活地控制注入时机和进程选择:

import frida
import sys

def on_message(message, data):
    if message['type'] == 'send':
        print(f"[Frida] {message['payload']}")
    elif message['type'] == 'error':
        print(f"[Frida Error] {message['stack']}")

# 找到FreeTube的进程
session = frida.attach("FreeTube")

# 脚本内容,和JS版本逻辑一致
script_code = """
setTimeout(() => {
  if (typeof document !== 'undefined') {
    send('成功进入渲染进程上下文');
    
    // 拦截$emit来监控handleClick的触发
    const originalEmit = Vue.prototype.$emit;
    Vue.prototype.$emit = function(eventName, ...args) {
      if (eventName === 'click' && this.$options.name === 'ft-input') {
        send(`捕获ft-input的handleClick事件,inputData: ${args[0]}`);
      }
      return originalEmit.call(this, eventName, ...args);
    };
  } else {
    send('当前不在渲染进程上下文,请确认注入的是渲染进程');
  }
}, 3000);
"""

script = session.create_script(script_code)
script.on('message', on_message)
script.load()

print("按任意键退出...")
sys.stdin.read()
session.detach()

注意事项

  • 确保注入的是渲染进程:Electron应用会有多个进程,主进程和渲染进程,你可以用frida -n FreeTube --list查看所有进程,选择带有renderer标识的进程注入。
  • 注入时机:页面加载需要时间,所以用setTimeout延迟执行hook逻辑,或者监听DOMContentLoaded事件。
  • Vue组件的hook:如果组件是局部注册的,可能需要通过遍历document元素获取对应Vue实例(vm = document.querySelector('ft-input').__vue__),再hook它的handleClick方法。

内容的提问来源于stack exchange,提问作者dujiajun

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 11:42:13