Android studio 3.0 (CMake)编写cydia脚本hook native

在anndroid studio 2.2 后,用它编写native代码只支持用CMake进行,然后我正在准备用Cydia Substrate 来 hook native代码的时候,发现网上没有用CMake方法来编写cydia脚本的,然后就只有自己动手了,下面用一个小案例记一下大致流程,也方便后来的朋友。

创建一个目标程序

1. 用android studio创建一个ndk程序,这里很简单,我们在创建的时候选择include c++ support即可,后面流程就和普通程序一样,然后等待它创建完成,完成后的目录结构如下:

目录结构
注:你们的cpp文件夹里cpp文件的名字可能不是这个,这没影响,我这个是我自己创建的

2.我们修改一下native-lib.cpp里面的代码,方便后面hook,native-lib.cpp中代码如下:
//
// Created by Blinger on 2018/7/3.
//
#include <jni.h>
#include <string>
//加上extern "C"是因为c++11后的编译器为了方便重载,会更改函数名,加上这个就不会,方便后面hook,不然还得用IDA PRO打开so文件查找,如果是自己创建的.c文件就不用
extern "C"
{
    char *getHello(void) {
    return "hello native";
}
//函数名记得做相应的修改
JNIEXPORT jstring JNICALL Java_blinger_com_dumpdex_MainActivity_getFromNativeString(
        JNIEnv *env,
        jobject jobject1) {
    return env->NewStringUTF(getHello());
}
}



3.编译运行

目标程序写好了,接下来就写我们的cydia脚本了

Cydia脚本编写

1.和传统JNI一样,先下载cydia sdkapk文件

SDK文件

2.新建一个NDK项目,步骤同上
3.将cydia sdk的两个.so放入libs文件夹相应的ABI目录中,没有ABI路径的话就自己建一个吧,然后在cpp文件夹中创建include文件夹,将sdk的头文件放进去,最后生成的目录如下

目录结构
注:路径也不一定要像我这样配置,如果改了,后面的配置文件也要做相应的改变

4.编写cydia脚本,内容如下,并将其后缀改为.cy.cpp,如上图最后一行:
#include <jni.h>
#include <android/log.h>
#include "include/substrate.h"

#define LOG(...) __android_log_print(ANDROID_LOG_DEBUG,"blinger",__VA_ARGS__)
extern "C"
//这是HOOK程序的写法,像hook livdvm.so应该这样写:MSConfig(MSFilterLibrary, "libdvm.so");  

MSConfig(MSFilterExecutable,"/system/bin/app_process")
//旧的函数地址,为了保留就函数入口,有时候会用到,当然我们这个例子简单,就不用了
char * (* getFromNativeString) (void);

char * newhello(void)
{
    return "hello better tomorrow";
}

//通过so库的绝对路径和函数名,找到其函数的映射地址 
void * lookup_symbol(char* libraryname,char* symbolname)
{
    void *handle = dlopen(libraryname,RTLD_GLOBAL | RTLD_NOW);

    if(handle != NULL){
        void *symbol = dlsym(handle,symbolname);

        if(symbol != NULL){
            return symbol;
        } else{
            LOG("dl error: %s",dlerror());
            return NULL;
        }
    } else{
        return NULL;
    }
}

MSInitialize
{
    //文件路径记得改为自己的路径
    void *symbol = lookup_symbol("/data/data/blinger.com.dumpdex/lib/libhello.so","getHello");
    //这里将旧函数的入口(参数一)指向hello(参数三),然后执行新函数(参数二)
    MSHookFunction(symbol,(void *)&newhello,(void **)&getFromNativeString);
};

这里注意一下,记得修改MainActivity里面的内容,将native相关的删掉,不然等会编译肯定是会报错的

5.配置CMakeLists文件,这也是最重要的一步,文件内容如下:
# For more information about using CMake with Android Studio, read the
# documentation: https://d.android.com/studio/projects/add-native-code.html

# Sets the minimum version of CMake required to build the native library.

cmake_minimum_required(VERSION 3.4.1)

add_library( # 这里记得改为脚本相应的名字.
             native-lib.cy

             # Sets the library as a shared library.
             SHARED

             # 改为相应的路径
             src/main/cpp/native-lib.cy.cpp )
# sdk头文件路径
include_directories(src/main/cpp/include/substrate)

#在添加第三方库进项目时,所添加的东西包括add_library与set_target_properties与在target_link_libraries添加相应的文件名,如果sdk文件放置的目录和我不一致,记得添加为自己的
#添加三方库名的时候记得把lib前缀去掉,比如:libtest.so,就应该写为test,但输入路径的时候不变,其他CMakeLists的配置方法就不多说了,可以去官网查阅
add_library(substrate SHARED IMPORTED)
set_target_properties(substrate
    PROPERTIES IMPORTED_LOCATION
    ${CMAKE_SOURCE_DIR}/libs/${ANDROID_ABI}/libsubstrate.so)

add_library(substrate-dvm SHARED IMPORTED)
set_target_properties(substrate-dvm
    PROPERTIES IMPORTED_LOCATION
    ${CMAKE_SOURCE_DIR}/libs/${ANDROID_ABI}/libsubstrate-dvm.so)

find_library( # Sets the name of the path variable.
              log-lib

              # Specifies the name of the NDK library that
              # you want CMake to locate.
              log )
#特别注意,记得在这里添加你说添加的三方库
target_link_libraries( # Specifies the target library.
                       native-lib.cy

                       # Links the target library to the log library
                       # included in the NDK.
                       substrate
                       substrate-dvm
                       ${log-lib} )
6.在模块的build.gradle添加配置文件,添加到android版块中,内容如下(这里如果你的sdk文件放到了其他地方,应该做相应的修改):
sourceSets.main {
        jni.srcDirs = [] // This prevents the auto generation of Android.mk
        jniLibs.srcDir 'libs'
    }
7.修改AndroidManifest.xml文件,在相应的地方做修改就行,内容如下:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    android:installLocation="internalOnly">
    <application android:hasCode="false">
    </application>

    <uses-permission android:name="cydia.permission.SUBSTRATE"/>
</manifest>
8.编译运行,记得先安装cydia的apk,给了root权限后重启,再安装cydia脚本后重启,如果打开我们的脚本apk可能会闪退,但这没影响,hook成功就行

说了这么多,是不是感觉比传统的JNI方法方便了许多,主要是修改CMakeLists中的内容,其他都和传统的JNI方法差不多。在我看了还是比传统方法好很多,不知道各位看官怎么看待。有什么问题就留言吧。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值