unidbg调用so文件

unidbg 是一个基于 unicorn 的逆向工具,可以在 pc 端直接调用Android和iOS中的 so 文件

1. unidbg下载地址:https://github.com/zhkl0228/u... unidbg调用so文件
文章图片

unidbg项目用Java编写,并且上面下载的是一个标准的maven项目,要确保电脑安装好JDK、maven

2.项目导入IDEA
先将zip文件解压,使用IDEA2021版本不知如何导入,这里使用为IDEA2018版本

【unidbg调用so文件】unidbg调用so文件
文章图片
unidbg调用so文件
文章图片
unidbg调用so文件
文章图片
unidbg调用so文件
文章图片

接下来一路next即可第一次导入此项目会自动下载一些jar包,和网速、maven服务器有关,耐心等待吧

3.unidbg测试
项目中的unidbg-android\src\test\java\com\bytedance\frameworks\core\encrypt路径中有一个TTEncrypt测试用例,直接执行其中的main方法

unidbg调用so文件
文章图片

控制台打印相关调用信息,说明项目导入成功

unidbg调用so文件
文章图片

4.运行自己的so文件 下边为个人简单的修改的一个案例,大部分都做有注释,可参考一下
package com.DU_APP; //当前文件的路径import com.github.unidbg.AndroidEmulator; import com.github.unidbg.Module; 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.StringObject; import com.github.unidbg.linux.android.dvm.VM; import com.github.unidbg.linux.android.dvm.array.ByteArray; import com.github.unidbg.memory.Memory; import java.io.File; import java.io.IOException; public class DU_sign {//类名要与文件名一致private final AndroidEmulator emulator; private final VM vm; private final Module module; private final DvmClass TTEncryptUtils; private final boolean logging; public DU_sign(boolean logging) { this.logging = logging; emulator = AndroidEmulatorBuilder.for32Bit().setProcessName("com.shizhuang.duapp").build(); // 创建模拟器实例,要模拟32位或者64位,在这里区分,包名可写、可不写、可随意写 final Memory memory = emulator.getMemory(); // 模拟器的内存操作接口 memory.setLibraryResolver(new AndroidResolver(23)); // 设置系统类库解 vm = emulator.createDalvikVM(); // 创建Android虚拟机 vm.setVerbose(logging); // 设置是否打印Jni调用细节 String so_path = ""; //要调用的so文件路径 DalvikModule dm = vm.loadLibrary(new File(so_path), false); // 加载libttEncrypt.so到unicorn虚拟内存,加载成功以后会默认调用init_array等函数 dm.callJNI_OnLoad(emulator); // 手动执行JNI_OnLoad函数 module = dm.getModule(); // 加载好的libttEncrypt.so对应为一个模块 TTEncryptUtils = vm.resolveClass("com/duapp/aesjni/AESEncrypt"); //将要调用的so文件在java层的哪一个类中被调用,类的路径 }//关闭模拟器 void destroy() throws IOException { emulator.close(); if (logging) { System.out.println("destroy"); } }public static void main(String[] args) throws Exception { DU_sign test = new DU_sign(false); //实例化当前类//要进行加密的字符串 String str1 = "abTest[{\"name\":\"search_equlheight_spu_strategy\",\"value\":\"0\"}]catId0hideAddProduct0limit20loginTokenoriginSearchfalsepage0platformandroidproductDetailVersionFlag1showHot1sortMode0sortType0timestamp1625715089920title手表typeId0uuidd812da2917d75f8ev4.71.0"; System.out.println(test.encodeByte(str1)); test.destroy(); //关闭模拟器 }public String encodeByte(String str1) { //需要加密的第二个字符串,不变 String byteString = "010110100010001010010010000011000111001011101010101000101110111010011010101101101010001000101100010110100010001010011010110011001111001011100010101000100100110010110010100010101011110010111100"; //定义参数的类型,传参(emulator,要调用的方法的smail写法,传参(注意参数类型,有几个参数传几个参数)) Object ret = TTEncryptUtils.callStaticJniMethodObject(emulator, "encodeByte([BLjava/lang/String; )Ljava/lang/String; ", //传参,这里需要两个字符串,所以就传入两个参数 new ByteArray(vm, str1.getBytes()), vm.addLocalObject(new StringObject(vm, byteString))); return ret.toString(); }}

    推荐阅读