[原创]Android studio环境下Cydia android Native Hook测试
原文发表在:http://mybeibei.net/?p=1051
人比较笨,按照网上教程,断断续续折腾了5天4晚才最终搞定,期间无数次google,无数次翻看stackoverflow,各个android群询问,期间也得到了很多热心朋友的帮助,特别感谢“旗木、穿越地平线”、“kings0527”二位的耐心解答。
言归正传,部署步骤:
配置环境:
AS版本:Android Studio 1.5.1(之前用的1.3版本,各种问题,最终选择升级到1.5)
Cydia版本:com.saurik.substrate_0.9.4010.apk
Cydia框架:cydia_substrate-r2
NDK版本:android-ndk-r11
模拟器:海马玩0.9.0beta
1.建立project,选择No Activity;
然后在Mainfest.xml中增加substrate的调用权限:
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application>
<meta-data android:name="com.saurik.substrate.main"
android:value=".Main"/>
</application>
<uses-permission android:name="cydia.permission.SUBSTRATE"/>
</manifest>
2.在app-main下建立jni文件夹;

3.将cydia_substrate-r2下的substrate.h、libsubstrate.so和libsubstrate-dvm.so三个文件放入jni目录中,这里要注意根据架构的不同,选择x86或ARM目录下的libsubstrate.so和libsubstrate-dvm.so(我这里选择的是x86的)
4.同样在jni目录下建立test.cy.cpp(一定要记得带‘cy’)和Android.mk两个文件;
5.test.cy.cpp内容:
#include <jni.h>
#include "substrate.h"
#include <android/log.h>
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/types.h>
#include <string.h>
#include <sys/stat.h>
#define TAG "HOOKTEST"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, TAG, __VA_ARGS__)
MSConfig(MSFilterLibrary, "libdvm.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内容(之前打包后的apk里面只有libsubstrate-dvm.so,后来发现少写了中间这段):
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE:= substrate-dvm LOCAL_SRC_FILES := libsubstrate-dvm.so include $(PREBUILT_SHARED_LIBRARY) include $(CLEAR_VARS) LOCAL_MODULE:= substrate LOCAL_SRC_FILES := libsubstrate.so include $(PREBUILT_SHARED_LIBRARY) include $(CLEAR_VARS) LOCAL_MODULE := test.cy #生成的模块名 LOCAL_SRC_FILES := test.cy.cpp #源文件名 LOCAL_LDLIBS := -llog LOCAL_LDLIBS += -L$(LOCAL_PATH) -lsubstrate-dvm -lsubstrate include $(BUILD_SHARED_LIBRARY)
7.修改project下面的local.properties文件,末尾增加ndk路径,我的是:
ndk.dir=D\:\\android-ndk-r11
8.修改gradle.properties文件,末尾增加:
android.useDeprecatedNdk=true
9.修改app下的build.gradle文件(在这个文件上花费的时间最多,各种编译错误基本都是在这个设置上,顺便吐槽一下as各种版本对ndk的支持,简直让人崩溃!):
defaultConfig{}中增加ndk设置:
ndk{
moduleName "test.cy"
ldLibs "substrate"
ldLibs "substrate-dvm"
}因为要手动ndk-build,需要在android{}中增加jni和jniLibs路径说明:
sourceSets {
main {
jni.srcDirs = []
jniLibs.srcDirs = ['src/main/libs']
}
}
jni.srcDirs = [] 表示禁止as自动ndk编译,采用手动ndk-build
jniLibs.srcDirs = ['src/main/libs'] 表示经过ndk-build编译后的so路径
10.OK,接下来手动ndk-build吧,teminal下,进入到app/src/main/jni目录,因为是x86平台的编译,所以输入时需要带参数:
D:\MyTest\app\src\main\jni>ndk-build APP_ABI="x86"
11.OK,如果没报错,那么你的Project会刷新出libs和obj两个目录,libs目录正常应该是这样的:

12.模拟器安装好com.saurik.substrate_0.9.4010.apk,运行,并给予Root权限;
13.最后一步,build project,运行,打包后的apk应该是这样的:

14.看到hook log:

参考资料:
https://github.com/mohuihui/CydiaSubstrateAndroidNativeHOOK/
http://drops.wooyun.org/tips/8084
http://burningcodes.net/cydia-substrate-android-so-hook/
