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 函数实现脱壳。

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

  • 相关阅读:
    Hadoop 学习笔记 (十) hadoop2.2.0 生产环境部署 HDFS HA Federation 含Yarn部署
    hadoop 2.x 安装包目录结构分析
    词聚类
    Hadoop 学习笔记 (十一) MapReduce 求平均成绩
    Hadoop 学习笔记 (十) MapReduce实现排序 全局变量
    Hadoop 学习笔记 (九) hadoop2.2.0 生产环境部署 HDFS HA部署方法
    Visual Studio Code 快捷键大全(Windows)
    Eclipse安装教程 ——史上最详细安装Java &Python教程说明
    jquery操作select(取值,设置选中)
    $.ajax 中的contentType
  • 原文地址:https://www.cnblogs.com/gm-201705/p/9864047.html
Copyright © 2011-2022 走看看