主要介紹如何使用Cydia Substrate去hook native代碼薯鳍。本文是抄襲的,當作個人筆記挨措。
1.建立project挖滤,選擇No Activity;
2.在app-main下建立jni文件夾运嗜;
3.將cydia_substrate-r2下的substrate.h壶辜、libsubstrate.so和libsubstrate-dvm.so三個文件放入jni目錄中,這里要注意根據架構的不同担租,選擇x86或ARM目錄下的libsubstrate.so和libsubstrate-dvm.so
4.同樣在jni目錄下建立test.cy.cpp(一定要記得帶‘cy’)和Android.mk兩個文件砸民;
5.test.cy.cpp內容:
#include "substrate.h"
#include <dlfcn.h>
#include <android/log.h>
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, "HookGetSpeed", __VA_ARGS__)
#define LIB "/data/app-lib/com.shandagames.bop-1/libShellClient.so"
MSConfig(MSFilterExecutable,"/system/bin/app_process")
//MSConfig(MSFilterLibrary, "libdvm.so");
int (* old_getSpeed)(void);
int new_getSpeed(void * CCharacter){
LOGD("getSpeed %d",(&CCharacter + 28));
return 1;
}
int (* old_SpeedUp)(int);
int new_SpeedUp(int a2){
LOGD("a2 : %d",a2);
return old_SpeedUp(a2);
}
int (* old_SetScale)(int,float);
int new_SetScale(int result,float a2){
LOGD("result : %d",result);
LOGD("a2 : %d",a2);
*(float *)(result + 1136) = a2;
return result;
}
//通過so庫的絕對路徑和函數名,找到其函數的映射地址
void* lookup_symbol(char* libraryname,char* symbolname)
{
//獲取so庫的句柄
void *handle = dlopen(libraryname, RTLD_GLOBAL | RTLD_NOW);
if (handle != NULL){
LOGD("dlopen success");
void * symbol = dlsym(handle, symbolname);
if (symbol != NULL){
LOGD("dlsym %s success",symbolname);
return symbol;
}else{
LOGD("dl error: %s", dlerror());
return NULL;
}
}else{
LOGD("dlopen %s faile",libraryname);
return NULL;
}
}
MSInitialize
{
//獲取hook函數的地址,最好不要用下面MS提供的方法
void * symbol = lookup_symbol(LIB,"_ZN16CGameSceneClient8SetScaleEf");
if(symbol != NULL){
LOGD("symbol address is 0x%08X",&symbol);
//這里將舊函數的入口(參數一)指向hello(參數三),然后執(zhí)行新函數(參數二)
MSHookFunction(symbol, (void *)&new_SetScale, (void **)&old_SetScale);
LOGD("MSHookFunction finish");
}
}
使用官方提供的方法有時候不能獲取到symbol岭参。
6.Android.mk內容
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路徑
8.修改gradle.properties文件,末尾增加:
android.useDeprecatedNdk=true
9.修改app下的build.gradle文件
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:\MyCandy\app\src\main\jni>ndk-build APP_ABI=”x86″
11.模擬器安裝好com.saurik.substrate_0.9.4010.apk闽颇,運行,并給予Root權限寄锐;
注意在AndroidManifest.xml中添加權限:<uses-permission android:name=”cydia.permission.SUBSTRATE”/>
https://koz.io/android-substrate-c-hooking/
http://mybeibei.net/1051.html
http://www.cydiasubstrate.com/id/73e45fe5-4525-4de7-ac14-6016652cc1b8/
https://blog.csdn.net/jk38687587/article/details/51498062