美文网首页android进阶版
借鸡生蛋之SandHook的使用(一)

借鸡生蛋之SandHook的使用(一)

作者: fenfei331 | 来源:发表于2020-12-23 21:15 被阅读0次

    一、目标

    不管是通过rpc调用签名还是模拟执行,都有一个小小的问题,那就是没有在真机环境下直接调用so来算签名来的快。

    所以我们今天的目标是尝试在Android系统下直接调用目标App的so文件来做签名。

    二、步骤

    先从一个假想的例子说起

    extern "C" JNIEXPORT jstring JNICALL
    Java_com_fenfei_loadso_MainActivity_stringFromJNI(
            JNIEnv* env,
            jobject obj) {
    
        jclass cls = env->GetObjectClass(obj);
        jmethodID mid = env->GetMethodID(cls, "getPackageManager",
                                         "()Landroid/content/pm/PackageManager;");
    
        mid = env->GetMethodID(cls, "getPackageName", "()Ljava/lang/String;");//
        jstring packageName = (jstring) env->CallObjectMethod(obj, mid);
    
        const char* str;
        str = env->GetStringUTFChars(packageName, NULL);
        env->ReleaseStringUTFChars(packageName, str);
    
        std::string strRc = "ok";
        if( strcmp(str,"com.fenfei.demo") != 0){
            strRc = "OMG";
        }
    
    
        return env->NewStringUTF(strRc.c_str());
    }
    

    这个so在它的 stringFromJNI 的函数中获取了当前包名,判断是自己的包名就返回 OK,如果不是就返回 OMG

    我们直接load这so,调用它的 stringFromJNI 函数,毫不意外,它的返回值是 OMG

    omg.png

    SandHook的使用

    那么要让它返回正确的 OK,有如下几种方法:

    1、 getPackageName函数恰好是可以重写的,那么重写 MainActivity 类的 getPackageName 函数直接返回 "com.fenfei.demo"
    2、 Hook Native层 strcmp 函数,把比较的返回值改写成成功
    3、Hook Java层 getPackageName 函数,来返回 "com.fenfei.demo"

    今天我们使用最后一种方法,Hook Java层 getPackageName。

    本次用的Hook库是 SandHook

    导入SandHook库

    在 app/build.gradle 中增加 implementation 'com.swift.sandhook:hooklib:4.2.1'

    增加MyApp类,初始化SandHook

    import android.app.Application;
    
    public class MyApp extends Application {
    
        @Override
        public void onCreate() {
            super.onCreate();
    
            try {
                SandHook.addHookClass(
                        MainActivityHooker.class);
            } catch (HookErrorException e) {
                e.printStackTrace();
            }
    
        }
    }
    

    记得在 AndroidManifest.xml 中增加 android:name=".MyApp"

    增加MainActivityHooker类,Hook getPackageName函数

    @HookClass(ContextWrapper.class)
    public class MainActivityHooker {
    
        @HookMethodBackup("getPackageName")
        static Method onGetPackageNameBackup;
    
        @HookMethod("getPackageName")
        public static String onGetPackageName(@ThisObject ContextWrapper thiz) throws Throwable {
            String strPkg = (String)SandHook.callOriginByBackup(onGetPackageNameBackup, thiz);
     
            if (thiz.getClass().equals(MainActivity.class)){
                Log.e("MainActivityHooker", thiz + "hooked getPackageName success rc= com.fenfei.demo");
                return "com.fenfei.demo";
            }else{
                return strPkg;
            }
     
        }
    }
    

    好了,这次so就以为自己还是运行在com.fenfei.demo之下正常的返回 OK

    ok.png

    https://github.com/fenfei331/SandHookDemo

    三、总结

    借鸡生蛋要了解鸡的心理,让它以为还在自己家,它可能东看看西看看,这时候千万要小心把周围都模拟出来。然后它才会乖乖的下蛋。

    相关文章

      网友评论

        本文标题:借鸡生蛋之SandHook的使用(一)

        本文链接:https://www.haomeiwen.com/subject/nuwunktx.html