赞
踩
idea
unidbg
记得电脑先安装好JDK,下载好idea后打开unidbg文件夹即可自动安装依赖。
如果需要永久激活idea的请私我。目前支持2023.1版本。
打开标记出的项目文件直接运行即可,然后正常打印出结果代表项目可以正常运行。
这个项目需要自己去创建的。
com.dta.lesson2.MainActivity
apk和so文件也会发到下面(用的是r0ysue-大数据安全入门课程里面的课件)。
注释已经非常详细写了
最终打印的会是两个调用方法输出的md5加密字符串。
package com.dta.lesson2; import com.github.unidbg.AndroidEmulator; import com.github.unidbg.LibraryResolver; import com.github.unidbg.arm.backend.DynarmicFactory; 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.DvmObject; import com.github.unidbg.linux.android.dvm.StringObject; import com.github.unidbg.linux.android.dvm.VM; import com.github.unidbg.linux.android.dvm.jni.ProxyDvmObject; import com.github.unidbg.memory.Memory; import com.github.unidbg.Module; import com.sun.jna.Pointer; import java.io.File; import java.util.ArrayList; import java.util.List; public class MainActivity { private final AndroidEmulator emulator; private final VM vm; private final Module module; private MainActivity() { // 创建模拟器实例,要模拟32位或者64位,在这里区分 emulator = AndroidEmulatorBuilder // 指定32位CPU .for32Bit() // 添加后端, 推荐使用Dynarmic,运行速度快,但是不支持某些新特性 .addBackendFactory(new DynarmicFactory(true)) // 指定进程名,推荐以安卓包名做进程名 // .setProcessName("") .build(); // 模拟器的内存操作接口 Memory memory = emulator.getMemory(); // 设置SDK版本 LibraryResolver resolver = new AndroidResolver(23); // 设置系统类库解析 memory.setLibraryResolver(resolver); // 创建Android虚拟机 vm = emulator.createDalvikVM(new File("D:\\unidbg-master\\unidbg-android\\src\\test\\java\\com\\dta\\lesson2\\app-debug.apk")); // 设置是否打印Jni调用细节 vm.setVerbose(false); // 加载libnative-lib.so到unicorn虚拟内存,加载成功以后会默认调用init_array等函数 DalvikModule dm = vm.loadLibrary(new File("D:\\unidbg-master\\unidbg-android\\src\\test\\java\\com\\dta\\lesson2\\libnative-lib.so"), false); //获取本SO模块的句柄,后续需要用它 module = dm.getModule(); // 调用JNI OnLoad dm.callJNI_OnLoad(emulator); } public void md5(){ /* 符号调用 创建项目要和包名一致, 因为unidbg会根据this的包名进行匹配JNI方法,所以this所属类的包名应该与目标函数相同(com.dta.lesson2) 例如这里this的包名是com.dta.lesson2,那么就相当于调用Java_com_dta_lesson2_md5(JNIEnv *env, jobject thiz, jstring str); */ DvmObject<?> obj = ProxyDvmObject.createObject(vm, this); String data = "dta"; DvmObject<?> result = obj.callJniMethodObject(emulator,"md5(Ljava/lang/String;)Ljava/lang/String;", data); String value = (String) result.getValue(); System.out.println("(symbol)md5 ====> result: " + value); } private void call_address() { /* 地址调用(虽然复杂,但是最好用) 这部分基本上固定写法,只需要改地址偏移和参数类型就行 在so文件里面方法的一般是Java_com_dta_lesson2_md5(JNIEnv *env, jobject thiz, jstring str); 所以下面要创建对应的参数, 基本为固定写法 */ Pointer jniEnv = vm.getJNIEnv(); DvmObject<?> obj = ProxyDvmObject.createObject(vm, this); // 如果要传入vm.addLocalObject,String只能这么写 StringObject data = new StringObject(vm, "dta"); List<Object> args = new ArrayList<>(); args.add(jniEnv); // 除了指针类型和Number类型都需要添加到vm(vm.addLocalObject)才能够在vm中操作该对象 args.add(vm.addLocalObject(obj)); args.add(vm.addLocalObject(data)); // 0x8E81是地址偏移(加过1的) Number numbers = module.callFunction(emulator, 0x8E81, args.toArray()); DvmObject<?> object = vm.getObject(numbers.intValue()); String value = (String) object.getValue(); System.out.println("(addr)md5 ====> result: " + value); } public static void main(String[] args) { MainActivity mainActivity = new MainActivity(); mainActivity.md5(); mainActivity.call_address(); } }
r0ysue-大数据安全入门课程
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。