当前位置: 首页 > 工具软件 > unidbg > 使用案例 >

andiord逆向之unidbg简单使用

程英资
2023-12-01

一、app中代码

package com.example.jnitest4.jni;

import android.content.Context;

public class JniManager {
    // Used to load the 'native-lib' library on application startup.
    static {
        System.loadLibrary("native-lib");
    }
    public native String str2str(String org,String append);
    public native String uuid(int type);
    public native String encode(String msg, int type);
    public native String decode(String msg, int type);
    public native String stringFromJNI();
    public native String encodeBySHA1(byte[] src);
    public native String encodeBySHA224(byte[] src);
    public native String encodeBySHA256(byte[] src);
    public native String encodeBySHA384(byte[] src);
    public native String encodeBySHA512(byte[] src);
    public native byte[] encodeByAES(byte[] keys, byte[] src);
    public native byte[] decodeByAES(byte[] keys, byte[] src);
    public native byte[] encodeByRSAPubKey(byte[] keys, byte[] src);
    public native byte[] decodeByRSAPrivateKey(byte[] keys, byte[] src);
    public native byte[] encodeByRSAPrivateKey(byte[] keys, byte[] src);
    public native byte[] decodeByRSAPubKey(byte[] keys, byte[] src);
    public native byte[] signByRSAPrivateKey(byte[] keys, byte[] src);
    public native int verifyByRSAPubKey(byte[] keys, byte[] src, byte[] sign);
    public native byte[] xOr(byte[] src);
    public native String md5(byte[] src);
    public native byte[] encodeByHmacSHA1(Context context, byte[] src);
    public native String sha1OfApk(Context context);
    public native boolean verifySha1OfApk(Context context);
    public native byte[] byteTestFn(byte[] bytes) ;

}

二、unidbg的代码调用

package com.bytedance.frameworks.core.encrypt;

import com.github.unidbg.AndroidEmulator;
import com.github.unidbg.linux.android.AndroidEmulatorBuilder;
import com.github.unidbg.linux.android.AndroidResolver;
import com.github.unidbg.linux.android.dvm.DalvikModule;
import com.github.unidbg.linux.android.dvm.DvmClass;
import com.github.unidbg.linux.android.dvm.DvmObject;
import com.github.unidbg.linux.android.dvm.VM;
import com.github.unidbg.linux.android.dvm.jni.ProxyClassFactory;
import com.github.unidbg.memory.Memory;

import java.io.File;
import java.io.IOException;

public class Test {

    private final AndroidEmulator emulator;

    private final DvmClass jniManagerUtil;
    private final VM vm;

    public Test() {
        emulator = AndroidEmulatorBuilder.for64Bit()
                .setProcessName("com.example.jnitest4")
                .build();
        Memory memory = emulator.getMemory();
        memory.setLibraryResolver(new AndroidResolver(23));
        vm = emulator.createDalvikVM();
        vm.setDvmClassFactory(new ProxyClassFactory());
        vm.setVerbose(false);                                // 加载so的路径
        DalvikModule dm = vm.loadLibrary(new File("unidbg-android/src/test/resources/MySo/libnative-lib.so"), false);
        jniManagerUtil = vm.resolveClass("com/example/jnitest4/jni/JniManager");   // app中JniManager类的路径
        dm.callJNI_OnLoad(emulator);
    }

    public void destroy() throws IOException {
        emulator.close();
    }

    /**
     * 这里有个问题是使用callStaticJniMethodObject还是callJniMethodObject
     */
    public void stringFromJNI(){
        String methodStringFromJNI = "stringFromJNI()Ljava/lang/String;";     // stringFromJNI()为类的函数 返回类型String

        DvmObject<?> strRc =  jniManagerUtil.callStaticJniMethodObject(emulator, methodStringFromJNI);
        System.out.println("stringFromJNI返回值:"+strRc.getValue());
    }

    /**
     * 这个例子的重点是参数是int类型,对应的参数类型标识为I
     */
    public void UUIDTest(){
        String methodStringFromJNI = "uuid(I)Ljava/lang/String;";
        int paramInt = 15;
        DvmObject<?> strRc =  jniManagerUtil.callStaticJniMethodObject(emulator, methodStringFromJNI,paramInt);
        System.out.println("UUIDTest返回值:"+strRc.getValue());
    }

    //    public native String str2str(String org,String append);
    public void str2strTest(){
        String methodStringFromJNI = "str2str(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;";
        String paramString0 = "hello ";
        String paramString1 = "mr wang";
        DvmObject<?> strRc =  jniManagerUtil.callStaticJniMethodObject(emulator, methodStringFromJNI,paramString0,paramString1);
        System.out.println("str2strTest返回值:"+strRc.getValue());
    }

    public void encode(){
        String methodStringFromJNI = "encode(Ljava/lang/String;I;)Ljava/lang/String;";
        String paramString0 = "hello ";
        int paramString1 = 20;
        DvmObject<?> strRc =  jniManagerUtil.callStaticJniMethodObject(emulator, methodStringFromJNI,paramString0,paramString1);
        System.out.println("encode返回值:"+strRc.getValue());
    }

    /**
     * 学习重点:
     *  1:这里重点是参数是byte数组,学习byte数组如何传参。
     *  2:调用方法采用先new一个对象,然后再调用非静态方法来调用。
     */
    public void encodeBySHA1(){
        String methodStringFromJNI = "encodeBySHA1(B[;)Ljava/lang/String;";
        String paramString0 = "99999 ";
//  方法1
//        DvmObject<?> strRc =  jniManagerUtil.callStaticJniMethodObject(emulator, methodStringFromJNI,paramString0.getBytes());
//   方法2:
        DvmObject<?> strRc =  jniManagerUtil.newObject(null).callJniMethodObject(emulator, methodStringFromJNI,paramString0.getBytes());
        System.out.println("encodeBySHA1返回值:"+strRc.getValue());
    }



    public static void main(String[] args) throws Exception {
        Test jniManagerUtil = new Test();
        jniManagerUtil.stringFromJNI();
        jniManagerUtil.UUIDTest();
        jniManagerUtil.str2strTest();
        jniManagerUtil.encode();
        jniManagerUtil.encodeBySHA1();
        jniManagerUtil.destroy();
    }

}

 类似资料: