V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
freeminder
V2EX  ›  Android

Android x86 模拟器上用 cydia substrate 注入 arm so

  •  
  •   freeminder · 2018-05-08 10:50:53 +08:00 · 10290 次点击
    这是一个创建于 2393 天前的主题,其中的信息可能已经有所发展或是发生改变。

    在研究一个应用的 so hook,之前在 arm 真机上已经用 substrate 实现了,所以我判断注入相关代码没有问题。
    在移植到模拟器环境中时,发现基于 x86 架构的模拟器在加载 App 内部的 arm 库时,使用了libhoudini。通过 hook libdvm 中 houdini 的 dlopen 方法拿到了 app arm so 的地址,并且通过MSFindSymbol找到了要 hook 的目标函数地址,但是使用MSHookFunction之后就会一直崩溃。log 里面显示的也是看不出来什么有用的信息。
    核心代码如下

    // target hook
    void fake_target()
    {
        // 这里只做简单的日志输出,logcat 没内容
    }
    
    // 原始的 houdini dlopen 句柄
    void* (*_hookDlopen)(const char *filename, int flag, bool* useHoudini);
    
    // houdini dlopen hook
    void* fake_hookDlopen(const char *filename, int flag, bool* useHoudini){
        void* handle = _hookDlopen(filename, flag, useHoudini);
        if(strstr(filename, "libAppArm.so")){
            void * target = MSFindSymbol(handle, "target_function");
            if (target != NULL){
                MSHookFunction(target, (void*)&fake_target);
            }
        }
        return handle;
    }
    // 初始化过程
    MSInitialize {
       MSImageRef image;
       image = MSGetImageByName("/system/lib/libdvm.so");
       if (image != NULL) {
         void * houdini = MSFindSymbol(image, "_ZN7houdini10hookDlopenEPKciPb");
         if (houdini != NULL){
             MSHookFunction(houdini, (void*)&fake_hookDlopen,(void **)&_hookDlopen);
         }
       }
     }
    
    • 在找到要 hook 的函数之后,进行 MSHookFunction 的过程在 arm 上已经测试过,上面的代码被我简化了
    • 各种 NULL 和非 NULL 的分支都加了 log,也被我简化了,比较确定的是 MSHookFunction 一旦调用必然崩溃
    • 猜测 MSHookFunction 会对原始地址、替换地址进行某些指令集相关的操作,libAppArm 中 MSFindSymbol 的结果是一个 arm 相关的地址,我用本地的函数应该是 x86 的,MSHookFunction 在转换的过程中指针操作异常了
    • cydia substrate 在模拟器上只能 link x86 的 so,所以我写的 module 也只能导出 x86 版本的 so。
    • 是不是关键在于把 hook 的某个环节变成 arm so,也用 libhoudini 加载就可以解决?这个路子完全没思路。

    请各路 v 友指点一二……

    2 条回复    2018-07-02 22:54:40 +08:00
    freeminder
        1
    freeminder  
    OP
       2018-05-10 15:02:33 +08:00
    自己解决了,思路就是 cydia module 只 hook libdvm 的 loadNativeCode, 在找到目标 lib 的时候 loadNativeCode 一个自己写好的 arm so。这个 arm so 的 JNI_ONLoad 包含了所有的 hook 逻辑,arm so 里面用的 cydia 和 findSymbol 来自 VirtualApp 的源码。module 编 x86 的,arm so 编 arm 的。就这样,收藏的回来点感谢吧。
    cainiaoniao
        2
    cainiaoniao  
       2018-07-02 22:54:40 +08:00
    您好,请问下我 hook loadNativeCode
    ```
    char *armsopath = "/system/lib/libarmso.so";

    bool MydvmLoadNativeCode(const char* pathName, void* classLoader,char** detail)
    {
    LOGI("MydvmLoadNativeCode %s",pathName);
    //if(strstr(pathName,"libcubehawk.so")>0)
    if(strstr(pathName,"libtestso.so")>0)
    {
    LOGI("load arm so %s",armsopath);
    bool bret = pOldFunc(pathName,classLoader,detail);
    pOldFunc(armsopath,classLoader,detail);
    return bret;
    }
    return pOldFunc(pathName,classLoader,detail);
    }
    ```
    是这样的错误提示
    D/houdini ( 127): [127] Open Native Library /system/lib/libarmso.so failed.

    请问下这是怎么回事呢
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1167 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 20ms · UTC 18:37 · PVG 02:37 · LAX 10:37 · JFK 13:37
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.