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

Android平台Go语言二进制文件Hook框架及实现方案咨询

Android平台Go二进制文件的动态Hook方案

针对Android上的Go语言静态二进制,确实无法直接复用Frida对C++/ELF的常规Hook逻辑(比如Module.findExportByName),但有几种可行的动态Hook方案,满足你无需依赖IDA等逆向工具的需求:

1. 利用Frida结合Go符号表/内存特征扫描

如果目标Go二进制未剥离符号(编译时未加-s -w参数),可以直接通过Frida遍历进程符号表定位目标函数:

// Frida脚本:Hook time.Now()
const targetProc = Process.getModuleByName("your_go_binary_name");
// 遍历符号表查找time.Now
const timeNowSymbol = Process.enumerateSymbols(targetProc.name).find(sym => sym.name === "time.Now");

if (timeNowSymbol) {
    Interceptor.attach(timeNowSymbol.address, {
        onEnter: function(args) {
            console.log("[+] time.Now() 被调用");
        },
        onLeave: function(retVal) {
            // Go的time.Time是结构体,需按内存结构解析
            const timePtr = retVal.readPointer();
            console.log("[+] time.Now() 返回值地址:", timePtr);
        }
    });
} else {
    console.log("[-] 未找到time.Now符号,请检查二进制是否保留符号");
}

如果二进制已剥离符号,可以通过Go函数的特征指令扫描内存定位:Go函数开头通常会有访问TLS的指令(如MOVQ (TLS), CX),结合go tool nm提前获取的函数偏移(无需IDA),直接计算地址:

# 先用go tool nm获取time.Now的偏移
go tool nm your_go_binary_name | grep "time.Now"
# 输出类似:12345678 T time.Now

然后在Frida脚本中直接计算地址:

const moduleBase = Process.getModuleByName("your_go_binary_name").base;
const timeNowAddr = moduleBase.add(0x12345678); // 替换为实际偏移

Interceptor.attach(timeNowAddr, {
    onEnter: function(args) {
        console.log("[+] time.Now() 被Hook");
    }
});

2. 使用专门的Go动态Hook库(gohook)

gohook是一款针对Go语言的Hook库,支持动态替换Go函数实现,需交叉编译为Android共享库后注入目标进程:

步骤1:编写Hook逻辑(Go代码)

package main

import (
    "time"
    "github.com/rainycape/gohook"
)

// 自定义的time.Now替代函数
func fakeNow() time.Time {
    println("[Hooked] time.Now() 被调用,返回伪造时间")
    return time.Date(2024, 1, 1, 0, 0, 0, 0, time.UTC)
}

func main() {
    // Hook time.Now函数
    origNow := time.Now
    if err := gohook.Hook(origNow, fakeNow, nil); err != nil {
        panic(err)
    }
    defer gohook.Unhook(origNow)

    // 保持进程运行,维持Hook状态
    select{}
}

步骤2:交叉编译为Android共享库

# 针对arm64架构
GOOS=android GOARCH=arm64 go build -buildmode=c-shared -o libgohook.so main.go
# 针对arm32架构
GOOS=android GOARCH=arm go build -buildmode=c-shared -o libgohook.so main.go

步骤3:用Frida注入共享库

编写Frida注入脚本inject.js:

const libPath = "/data/local/tmp/libgohook.so"; // 上传到设备的路径
const module = Process.load(libPath);
console.log("[+] 注入Hook库成功");

执行注入:

frida -U -f com.your.go.app -l inject.js --no-pause

注意事项

  • Go的函数调用约定与C不同,处理参数/返回值时需注意内存结构(比如结构体返回会通过指针传递)。
  • 静态编译的Go二进制没有动态依赖,所有函数都在主模块中,需针对主进程二进制操作。
  • 若目标二进制开启了代码混淆,需结合内存特征或调试信息进一步定位函数。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 04:53:18