zoukankan      html  css  js  c++  java
  • Android Native Hook技术(二)

    Hook技术应用

    已经介绍了安卓 Native hook 原理,这里介绍 hook 技术的应用,及 Cyida Substrate 框架。

    分析某APP,发现其POST请求数据经过加密,我们希望还原其明文。经分析,加密是在so中的 Java_com_imohoo_jni_Main_abc() 函数内完成的。

    该函数通过 getkey() 和 getIV() 分别生成加密密钥与IV,然后使用AES加密请求数据。

    简单逻辑如下:

    v_iv = getIV((int)env, a5);
    v14 = getkey((int)v11, a5);
    --
    aes_key_setup(v14, &v_key, 128);
    --
    aes_encrypt_cbc((int)dec, size, (int)enc, (int)&v_key, 128, v_iv);
    

    分析 getIV() 与 getkey() 函数的实现,其经过强混淆,并且生成的key又经过 aes_key_setup() 函数变换。静态分析变换过程其使用了部分运行时动态修改的内存,静态分析出结果机率为0。

    但由上面代码执行流程,发现通过hook aes_encrypt_cbc() 函数,就能简单的拿到IV与加密key

    使用 Cydia Substrate 框架来完成这个任务,主要代码如下:

    #include <android/log.h>
    #include <substrate.h>
    #include <stdio.h>
    
    #define LOG_TAG "KEYHOOK"
    #define LOGI(...)  __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
    
    MSConfig(MSFilterExecutable, "/system/bin/app_process")
    
    void (*original_getnewkey) (char* in, int len, char *out, char *key, int key_len, char *iv);
    void replaced_getnewkey (char* in, int len, char *out, char *key, int key_len, char *iv) 
    {
            LOGI("ENC_KEY [%s]", key);
            LOGI("IV [%s]", iv);
            LOGI("PlainText [%s]", in);
            original_getnewkey(in, len, out, key, 128, iv);
    }
    
    void* lookup_symbol(char* libraryname, char* symbolname)
    {
            void *imagehandle = dlopen(libraryname, RTLD_GLOBAL | RTLD_NOW);
            if (imagehandle != NULL){
                    void * sym = dlsym(imagehandle, symbolname);
                    if (sym != NULL){
                            return sym;
                    }
                    else{
                            LOGI("(lookup_symbol) dlsym didn't work");
                            return NULL;
                    }
            }
            else{
                    LOGI("(lookup_symbol) dlerror: %s",dlerror());
                    return NULL;
            }
    }
    
    void cigi_hook(void *orig_fcn, void* new_fcn, void **orig_fcn_ptr)
    {
            MSHookFunction(orig_fcn, new_fcn, orig_fcn_ptr);
    }
    
    MSInitialize {
            LOGI("Cydia Init");
            void *getnewkey_t = lookup_symbol("/data/app-lib/com.imohoo.shanpao-1/libshanpao_jni.so", "aes_encrypt_cbc");
    
            cigi_hook(getnewkey_t, (void*)&replaced_getnewkey, (void**)&original_getnewkey);
    }
    

    代码显示了 hook 系统与应用 so 之间的区别,我们的 substrate 模块运行在 app_process 的上下文中,也就是 zygote 进程。所有的 Android 应用进程都由它 fork 而来,而这个进程中并没有加载 libshanpao_jni.so 这个库,因此直接查找 aes_encrypt_cbc 符号肯定是找不到的。

    我的解决办法是在 zygote 中使用 dlopen() 主动加载之。根据so加载原则,fork出的APP进程启动后,将会使用我们加载的 libshanpao_jni.so 库。

    这是一个有用的技巧。

    该 hook 框架的一个完整工程,参考 github 上的 DumpDex,该工程通过 hook 系统 dalvik 运行时 libdvm.so 的 _Z12dexFileParsePKhji 函数实现脱壳。

    如何自己创建这样一个工程,参考莫灰灰博客

  • 相关阅读:
    xampp 80端口被占用后这么办??解决了
    XAMPP配置基于虚拟目录、多域名的环境
    mysql 主从同步
    jquery插件
    Css绘制箭头实现代码
    Ubuntu下mount命令的好用处
    linux下IPTABLES配置详解
    java程序员网站
    1.Hibernate介绍
    1. Mybatis介绍
  • 原文地址:https://www.cnblogs.com/gm-201705/p/9864047.html
Copyright © 2011-2022 走看看