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

unidbg 入门(一)

戴瑞
2023-12-01

1 学习内容


1.1:调用native方法

        1.1 .1使用方法:callStaticJniMethodObject

        1.1.2 先new出对象再调用方法callJniMethodObject

1.2:传不同的参数:

        1.2.1  调用无参函数

       1.2.2  int类型参数

       1. 2.3  btye数组类型参数

        1.2.4  多个String类型的参数

       

2 代码如下


2.1:so文件在附件中,下载

2.2:安卓代码

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);
    /**
     * 获取uuid字符串
     * @param type
     * @return
     */
    public native String uuid(int type);

    /**
     * 加密
     *
     * @param msg  原始字符串
     * @param type 加密的方式
     * @return 加密后的数据
     */
    public native String encode(String msg, int type);
    /**
     * 解密
     *
     * @param msg  解密前的 字符串
     * @param type 解密的方式
     * @return 解密后的数据
     */
    public native String decode(String msg, int type);




    /**
     * A native method that is implemented by the 'native-lib' native library,
     * which is packaged with this application.
     */
    public native String stringFromJNI();

    /**
     * SHA1签名    --失败
     *
     * @param src
     * @return
     */
    public native String encodeBySHA1(byte[] src);

    /**
     * SHA224签名
     *
     * @param src
     * @return
     */
    public native String encodeBySHA224(byte[] src);

    /**
     * SHA384签名
     *
     * @param src
     * @return
     */
    public native String encodeBySHA256(byte[] src);

    /**
     * SHA256签名
     *
     * @param src
     * @return
     */
    public native String encodeBySHA384(byte[] src);

    /**
     * SHA512签名
     *
     * @param src
     * @return
     */
    public native String encodeBySHA512(byte[] src);

    /**
     * AES加密
     *
     * @param keys
     * @param src
     * @return
     */
    public native byte[] encodeByAES(byte[] keys, byte[] src);

    /**
     * AES解密
     *
     * @param keys
     * @param src
     * @return
     */
    public native byte[] decodeByAES(byte[] keys, byte[] src);

    /**
     * RSA公钥加密
     *
     * @param keys
     * @param src
     * @return
     */
    public native byte[] encodeByRSAPubKey(byte[] keys, byte[] src);

    /**
     * RSA私钥解密
     *
     * @param keys
     * @param src
     * @return
     */
    public native byte[] decodeByRSAPrivateKey(byte[] keys, byte[] src);

    /**
     * RSA私钥加密
     *
     * @param keys
     * @param src
     * @return
     */
    public native byte[] encodeByRSAPrivateKey(byte[] keys, byte[] src);

    /**
     * RSA公钥解密
     *
     * @param keys
     * @param src
     * @return
     */
    public native byte[] decodeByRSAPubKey(byte[] keys, byte[] src);

    /**
     * RSA私钥签名
     *
     * @param keys
     * @param src
     * @return
     */
    public native byte[] signByRSAPrivateKey(byte[] keys, byte[] src);

    /**
     * RSA公钥验证签名 (未测试)
     *
     * @param keys
     * @param src
     * @param sign
     * @return 1:验证成功
     */
    public native int verifyByRSAPubKey(byte[] keys, byte[] src, byte[] sign);

    /**
     * 异或加解密
     *
     * @param src
     * @return
     */
    public native byte[] xOr(byte[] src);

    /**
     * MD5编码
     *
     * @param src
     * @return 默认小写
     */
    public native String md5(byte[] src);


    /**
     * HmacSHA1签名
     *
     * @param context
     * @param src
     * @return
     */
    public native byte[] encodeByHmacSHA1(Context context, byte[] src);

    /**
     * 获取apk-sha1
     *
     * @param context
     * @return
     */
    public native String sha1OfApk(Context context);

    /**
     * 校验apk签名是否有效(未验证)
     *
     * @param context
     * @return
     */
    public native boolean verifySha1OfApk(Context context);


    /**
     * 字节测试用例
     * @param bytes
     * @return
     */
    public native byte[] byteTestFn(byte[] bytes) ;

}

2.3:unidbg实现代码

package com.jni4;

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 JniManagerUtil {

    private final AndroidEmulator emulator;

    private final DvmClass jniManagerUtil;
    private final VM vm;

    public JniManagerUtil() {
        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);
        DalvikModule dm = vm.loadLibrary(new File("unidbg-android/src/test/resources/jnitest4/libnative-lib.so"), false);
        jniManagerUtil = vm.resolveClass("com/example/jnitest4/jni/JniManager");
        dm.callJNI_OnLoad(emulator);
    }

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

    /**
     * 这里有个问题是使用callStaticJniMethodObject还是callJniMethodObject
     */
    public void stringFromJNI(){
        String methodStringFromJNI = "stringFromJNI()Ljava/lang/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 {
        JniManagerUtil jniManagerUtil = new JniManagerUtil();
        jniManagerUtil.stringFromJNI();
        jniManagerUtil.UUIDTest();
        jniManagerUtil.str2strTest();
        jniManagerUtil.encode();
        jniManagerUtil.encodeBySHA1();
        jniManagerUtil.destroy();
    }

}

 3 其他


   3.1:使用unidbg时的参数类型如何定义的,可以参考文章


 类似资料: