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

如何用Frida钩子CURLNetRequest结构体的user与password成员

Frida钩子C++结构体成员获取username和password

问题背景

用户基于RhodeMobile构建的应用,需要通过Frida钩子librhodes.so中CURLNetRequest类下两个结构体的user、password等成员,但当前代码仅能获取到AuthMethod值,需调整实现逻辑。

目标C++代码片段

class CURLNetRequest : public CNetRequestBase
{
    DEFINE_LOGCLASS;
    
    struct ProxySettings
    {
        void initFromConfig();
        
        String  host;
        int     port;
        String  username;
        String  password;
    };

    struct AuthSettings
    {
        AuthSettings( AuthMethod m, const String& u, const String& p )
        : method(m)
        , user(u)
        , password(p)
        {}

        const AuthMethod method;
        const String user;
        const String password;
    };
...

当前Frida代码

const some_func_pointer = Module.getExportByName('librhodes.so', '_ZN3rho3net14CURLNetRequest10CURLHolder11set_optionsEPKcRKNSt6__ndk112basic_stringIcNS5_11char_traitsIcEENS5_9allocatorIcEEEESD_PNS0_11IRhoSessionEPNS_9HashtableISB_SB_EERKNS1_13ProxySettingsERKNS1_12AuthSettingsE');
const some_func = new NativeFunction(some_func_pointer, "void", ["int", "pointer"]);
Interceptor.replace(some_func_pointer, new NativeCallback(function (size, data) {
  console.log(size)
  console.log(data.readUtf8String())
  some_func(size, data);
}, "void", ["int", "pointer"]));

解决方案

核心问题是函数签名不匹配和结构体成员内存偏移计算错误,以下是修正后的实现:

1. 修正函数参数签名

原函数的demangled名称对应的参数列表需严格匹配,64位架构下参数类型定义如下(32位需将指针长度改为4字节):

const some_func = new NativeFunction(some_func_pointer, 'void', [
  'pointer',    // const char*
  'pointer',    // std::string&
  'pointer',    // std::string&
  'pointer',    // IRhoSession*
  'pointer',    // Hashtable&
  'pointer',    // ProxySettings&
  'pointer'     // AuthSettings&
]);

2. 编写字符串读取辅助函数

Rhodes中String对应NDK的std::__ndk1::basic_string,内部布局为[data_ptr, size, capacity],封装读取逻辑:

function readStdString(strPtr) {
  const dataPtr = strPtr.readPointer();
  return dataPtr ? dataPtr.readUtf8String() : '';
}

3. 钩子函数读取结构体成员

根据结构体内存对齐规则,计算成员偏移并读取:

Interceptor.replace(some_func_pointer, new NativeCallback(function (url, str1, str2, session, hashtable, proxySettings, authSettings) {
  // 读取AuthSettings成员(64位架构示例)
  const authMethod = authSettings.readInt();
  const userStrPtr = authSettings.add(8);    // 偏移8字节到user成员
  const passwordStrPtr = authSettings.add(24); // 偏移24字节到password成员
  
  console.log(`AuthMethod: ${authMethod}`);
  console.log(`Username: ${readStdString(userStrPtr)}`);
  console.log(`Password: ${readStdString(passwordStrPtr)}`);

  // 读取ProxySettings成员(64位架构示例)
  const proxyHostPtr = proxySettings.readPointer();
  const proxyPort = proxySettings.add(8).readInt();
  const proxyUserPtr = proxySettings.add(16);
  const proxyPassPtr = proxySettings.add(32);
  
  console.log(`Proxy Host: ${readStdString(proxyHostPtr)}`);
  console.log(`Proxy Port: ${proxyPort}`);
  console.log(`Proxy Username: ${readStdString(proxyUserPtr)}`);
  console.log(`Proxy Password: ${readStdString(proxyPassPtr)}`);

  // 调用原函数
  some_func(url, str1, str2, session, hashtable, proxySettings, authSettings);
}, 'void', [
  'pointer', 'pointer', 'pointer', 'pointer', 'pointer', 'pointer', 'pointer'
]));

4. 32位架构适配

若为32位ARM,指针长度为4字节,结构体偏移需调整:

  • AuthSettings:method占4字节,user偏移4字节,password偏移16字节
  • ProxySettings:host偏移0,port偏移4,username偏移16,password偏移28

注意事项

  • 结构体偏移需结合反编译librhodes.so的结果确认,不同编译器的对齐规则可能导致偏移变化
  • 若Rhodes使用自定义String类,需根据其内部布局修改readStdString函数逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 19:57:35