- 监控so文件加载成功
- 动态注册方法
package com.github.unidbg.android; import com.github.unidbg.AndroidEmulator; import com.github.unidbg.Emulator; import com.github.unidbg.LibraryResolver; import com.github.unidbg.Module; import com.github.unidbg.ModuleListener; import com.github.unidbg.Symbol; import com.github.unidbg.arm.HookStatus; import com.github.unidbg.arm.backend.DynarmicFactory; import com.github.unidbg.hook.ReplaceCallback; import com.github.unidbg.hook.xhook.IxHook; import com.github.unidbg.linux.android.AndroidEmulatorBuilder; import com.github.unidbg.linux.android.AndroidResolver; import com.github.unidbg.linux.android.XHookImpl; 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.linux.android.dvm.jni.ProxyClassFactory; import com.github.unidbg.memory.Memory; import com.github.unidbg.utils.Inspector; import javax.crypto.Cipher; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.DESedeKeySpec; import javax.crypto.spec.IvParameterSpec; import java.io.File; import java.io.IOException; public class QDReaderJni implements ModuleListener { private static final int SDK = 23; private static LibraryResolver createLibraryResolver() { return new AndroidResolver(SDK); } private static AndroidEmulator createARMEmulator() { return AndroidEmulatorBuilder.for32Bit() .setProcessName("a.d.c") .addBackendFactory(new DynarmicFactory(true)) .build(); } private final AndroidEmulator emulator; private final VM vm; private final DvmClass d; private QDReaderJni() { // 创建模拟器 emulator = createARMEmulator(); // 获取内存对象 final Memory memory = emulator.getMemory(); // 设置AndroidResolver memory.setLibraryResolver(createLibraryResolver()); // 重点: 设置模块加载监听 memory.addModuleListener(this); // 使用模拟器创建虚拟机 vm = emulator.createDalvikVM(); vm.setDvmClassFactory(new ProxyClassFactory()); // 设置是否打印Jni调用细节 vm.setVerbose(true); // 加载so文件 DalvikModule dm = vm.loadLibrary(new File("unidbg-android/src/test/resources/example_binaries/armeabi-v7a/libd-lib.so"), false); // 手动调用JNI_OnLoad方法 dm.callJNI_onLoad(emulator); // 模拟类a.d d = vm.resolveClass("a/d"); } private void destroy() throws IOException { emulator.close(); System.out.println("destroy"); } public static void main(String[] args) throws Exception { // 初始化类 QDReaderJni test = new QDReaderJni(); //调用方法c test.c(); test.destroy(); } @Override public void onLoaded(Emulator> emulator, Module module) { // 监控so文件加载完成后调用的方法 if ("libcrypto.so".equals(module.name)) { Symbol DES_set_key = module.findSymbolByName("DES_set_key", false); Symbol DES_set_key_unchecked = module.findSymbolByName("DES_set_key_unchecked", false); if (DES_set_key_unchecked == null && DES_set_key != null) { // 注册DES_set_key_unchecked module.registerSymbol("DES_set_key_unchecked", DES_set_key.getAddress()); } } } private void c() throws Exception { // 注册hook方法,对libd-lib.so里的free进行hook IxHook xHook = XHookImpl.getInstance(emulator); xHook.register("libd-lib.so", "free", new ReplaceCallback() { @Override public HookStatus onCall(Emulator> emulator, long originFunction) { return HookStatus.LR(emulator, 0); } }); xHook.refresh(); final String data = "359250054370919||1551086094"; long start = System.currentTimeMillis(); // emulator.traceCode(); // 模拟调用jni方法boolean c(String) ByteArray array = d.callStaticJniMethodObject(emulator, "c(Ljava/lang/String;)[B", new StringObject(vm, data)); // 打印返回结果 Inspector.inspect(array.getValue(), "c offset=" + (System.currentTimeMillis() - start) + "ms"); final String key = "sewxf03hhz3ew9qcCXMHiDMk"; final String iv = "sh331nt1"; // 加密和解密 Cipher cipher = Cipher.getInstance("DESede/CBC/PKCS5Padding"); DESedeKeySpec keySpec = new DESedeKeySpec(key.getBytes()); SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DESede"); SecretKey secretKey = keyFactory.generateSecret(keySpec); cipher.init(Cipher.ENCRYPT_MODE, secretKey, new IvParameterSpec(iv.getBytes())); byte[] encrypted = cipher.doFinal(data.getBytes()); // 打印加密后的二进制字节信息 Inspector.inspect(encrypted, "Encrypted"); cipher.init(Cipher.DECRYPT_MODE, secretKey, new IvParameterSpec(iv.getBytes())); byte[] decrypted = cipher.doFinal(array.getValue()); // 打印解密后的二进制字节信息 Inspector.inspect(decrypted, "Decrypted"); } }备注
1:动态监测so文件加载成功需要实现接口ModuleListener,并注册自己
2:动态注册符号,需要使用方法
module.registerSymbol
3 在线arm汇编指令与HEX转换网站:https://armconverter.com/
其他有问题请留言,一起进步。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)