利用Cydia Substrate进行Android Native HOOK

简介
Cydia Substrate是一个很强大的工具,他提供了很便利的方法帮助你去hook so和java中的方法。
在本例中,出于学习的目的,我使用Cydia Substrate来hook每个进程的dvmLoadNativeCode函数,以达到监控加载so顺序的功能。

Cydia Substrate相关链接
使用指南: http://www.cydiasubstrate.com/inject/android/
SDK下载: http://www.cydiasubstrate.com/id/73e45fe5-4525-4de7-ac14-6016652cc1b8/
框架APK下载: http://www.cydiasubstrate.com/download/com.saurik.substrate.apk
本文demo代码:   https://github.com/mohuihui/CydiaSubstrateAndroidNativeHOOK

Hook模块编译指南
1. 创建一个android程序,如果没什么特殊需要,可以不创建activity(这个不是必须)。
利用Cydia Substrate进行Android Native HOOK_第1张图片

2.  将SDK下载到本地。目录结构是这样的:
利用Cydia Substrate进行Android Native HOOK_第2张图片

3. 在android工程中新建jni文件夹,然后加入相关的头文件substrate.h和库文件,例如我的工程只支持arm,那么就加入cydia_substrate\lib\armeabi下的两个so。目录结构如下:

利用Cydia Substrate进行Android Native HOOK_第3张图片

4. 在AndroidManifest.xml中注册cydia的自定义权限cydia.permission.SUBSTRATE。
另外,设置  android:hasCode 为 "false"
 android:installLocation 为 "internalOnly". 
如下所示

    
    
    

5. 编写Hook模块代码,即上面的test.cpp
#include 
#include "substrate.h"
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define TAG "HOOKTEST"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, TAG, __VA_ARGS__)
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, TAG, __VA_ARGS__)

MSConfig(MSFilterLibrary, "libdvm.so"); // 要hook的so库,后缀名即可。

bool (*_dvmLoadNativeCode)(char* pathName, void* classLoader, char** detail);

bool fake_dvmLoadNativeCode(char* soPath, void* classLoader, char** detail)
{
    LOGD("fake_dvmLoadNativeCode soPath:%s", soPath);
    return _dvmLoadNativeCode(soPath,classLoader,detail);
}

//Substrate entry point
MSInitialize{
    LOGD("Substrate initialized.");
    MSImageRef image;
    image = MSGetImageByName("/system/lib/libdvm.so"); // 此处要绝对路径
    if (image != NULL)
    {
        LOGD("dvm image: 0x%08X", (void*)image);
        void * dvmload = MSFindSymbol(image, "_Z17dvmLoadNativeCodePKcP6ObjectPPc");
        if(dvmload == NULL)
        {
            LOGD("error find dvmLoadNativeCode.");
        }
        else
        {
            MSHookFunction(dvmload,(void*)&fake_dvmLoadNativeCode,(void **)&_dvmLoadNativeCode);
            LOGD("hook dvmLoadNativeCode sucess.");
        }
    }
    else{
        LOGD("can not find libdvm.");
    }
}

6. 编写Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE    := substrate
LOCAL_SRC_FILES := libsubstrate.so
include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE    := substrate-dvm
LOCAL_SRC_FILES := libsubstrate-dvm.so
include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)
# 注意:此处substrate规定模块名必须以.cy结尾
LOCAL_MODULE    := test.cy 
LOCAL_SRC_FILES := test.cpp
LOCAL_LDLIBS := -llog
LOCAL_ARM_MODE := arm
LOCAL_LDLIBS += -L$(LOCAL_PATH) -lsubstrate-dvm -lsubstrate
include $(BUILD_SHARED_LIBRARY)

7. ndk-build之后会在android工程中生成libs目录,结构如下:
利用Cydia Substrate进行Android Native HOOK_第4张图片

8. build android工程即可生成hook模块的apk安装包。

使用指南
1. 下载 Cydia Substrate框架apk 并安装到手机上。
http://www.cydiasubstrate.com/download/com.saurik.substrate.apk
2. 安装在上面编译出来的 hook模块apk。此时, Cydia Substrate框架apk会提示你有新的模块可以使用
3. 打开框架apk,点击“Link Substrate Files”,之后点击“Restart System”就可以使用了。
4. Hook native demo运行之后,会打印每个程序加载so的情况,如下图:
利用Cydia Substrate进行Android Native HOOK_第5张图片

总结
本例就当是给大家使用 Cydia Substrate框架的抛砖引玉了,希望各路大神能写出更多更好的插件来方便后来人。
如果看了本篇文章还有不明白的,欢迎留言探讨交流。

源码
https://github.com/mohuihui/CydiaSubstrateAndroidNativeHOOK

你可能感兴趣的:(Android安全)