frida:
function printApplication(){ Java.perform(function (){ var BaseApplication = Java.use("com/izuiyou/common/base/BaseApplication"); var application = BaseApplication.getAppContext(); console.log(application); })}
unidbg:
package com.jniunidbg.part5;import com.github.unidbg.Emulator;import com.github.unidbg.arm.context.RegisterContext;import com.github.unidbg.debugger.BreakPointCallback;import com.github.unidbg.hook.hookzz.*;import com.github.unidbg.linux.android.dvm.AbstractJni;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.*;import com.github.unidbg.linux.android.dvm.array.ByteArray;import com.github.unidbg.memory.Memory;import com.github.unidbg.memory.MemoryBlock;import com.github.unidbg.pointer.UnidbgPointer;import com.github.unidbg.utils.Inspector;import com.sun.jna.Pointer;import java.io.File;import java.nio.charset.StandardCharsets;public class zuiyou extends AbstractJni{ private final AndroidEmulator emulator; private final VM vm; private final Module module; private final DvmClass NativeClass; zuiyou() { emulator = AndroidEmulatorBuilder.for32Bit().build(); // 创建模拟器实例 final Memory memory = emulator.getMemory(); // 模拟器的内存操作接口 memory.setLibraryResolver(new AndroidResolver(23)); // 设置系统类库解析 vm = emulator.createDalvikVM(new File("unidbg-android/src/test/resources/lession2/part5/zuiyou/right573.apk")); // 创建Android虚拟机 DalvikModule dm = vm.loadLibrary("net_crypto", true); // 加载so到虚拟内存 module = dm.getModule(); //获取本SO模块的句柄 vm.setJni(this); vm.setVerbose(true); dm.callJNI_OnLoad(emulator); NativeClass = vm.resolveClass("com/izuiyou/network/NetCrypto");// emulator.traceRead(0x40358000,0x40358000+7); emulator.traceRead(0xbffff54cL,0xbffff54cL+0x7L); emulator.traceRead(0xbffff63cL,0xbffff63cL+0x7L); }; public void callInit(){ String methodSign = "native_init()V"; NativeClass.callStaticJniMethodObject(emulator, methodSign); } private void callSign(){ String methodSign = "sign(Ljava/lang/String;[B)Ljava/lang/String;"; StringObject ret = NativeClass.callStaticJniMethodObject(emulator, methodSign, "12345", "lilac".getBytes(StandardCharsets.UTF_8)); System.out.println(ret); }; public static void main(String[] args) throws Exception { zuiyou test = new zuiyou(); test.hookMemcpy(); test.HookMemcmp(); test.callInit(); test.callSign(); } public void hookMemcpy(){// void *memcpy(void *str1, const void *str2, size_t n)// str1 -- 指向用于存储复制内容的目标数组,类型强制转换为 void* 指针。// str2 -- 指向要复制的数据源,类型强制转换为 void* 指针。// n -- 要被复制的字节数。 emulator.attach().addBreakPoint(module.findSymbolByName("memcpy").getAddress(), new BreakPointCallback() { // onEnter @Override public boolean onHit(Emulator> emulator, long address) { RegisterContext registerContext = emulator.getContext(); UnidbgPointer str1 = registerContext.getPointerArg(0); UnidbgPointer str2 = registerContext.getPointerArg(1); int length = registerContext.getIntArg(2); Inspector.inspect(str2.getByteArray(0, length), "要复制的数据源"); System.out.println("复制到的地方:"+str1.toString()); return true; } }); } // hook C 库函数 // int memcmp(const void *str1, const void *str2, size_t n)) 把存储区 str1 和存储区 str2 的前 n 个字节进行比较。 public void HookMemcmp(){ emulator.attach().addBreakPoint(module.findSymbolByName("memcmp").getAddress(), new BreakPointCallback() { @Override public boolean onHit(Emulator> emulator, long address) { System.out.println("call memcmp 作比较"); RegisterContext registerContext = emulator.getContext(); UnidbgPointer arg1 = registerContext.getPointerArg(0); UnidbgPointer arg2 = registerContext.getPointerArg(1); int size = registerContext.getIntArg(2); Inspector.inspect(arg1.getByteArray(0, size), "arg1"); Inspector.inspect(arg2.getByteArray(0, size), "arg2"); if(arg1.getString(0).equals("Context")){ emulator.attach().debug(); } return true; } }); } @Override public DvmObject> callStaticObjectMethodV(BaseVM vm, DvmClass dvmClass, String signature, VaList vaList) { switch (signature) { // cn.xiaochuankeji.tieba.AppController@1793a3b case "com/izuiyou/common/base/BaseApplication->getAppContext()Landroid/content/Context;":{ return vm.resolveClass("android/content/Context").newObject(null); } } return super.callStaticObjectMethodV(vm, dvmClass, signature, vaList); } @Override public DvmObject> callObjectMethodV(BaseVM vm, DvmObject> dvmObject, String signature, VaList vaList) { switch (signature){ case "android/content/Context->getClass()Ljava/lang/Class;":{ return dvmObject.getObjectType(); } // OK case "java/lang/Class->getSimpleName()Ljava/lang/String;":{ return new StringObject(vm, "Context"); } case "android/content/Context->getFilesDir()Ljava/io/File;":{ return vm.resolveClass("java/io/File").newObject(signature); } case "java/io/File->getAbsolutePath()Ljava/lang/String;":{ String tag = dvmObject.getValue().toString(); if(tag.equals("android/content/Context->getFilesDir()Ljava/io/File;")){ return new StringObject(vm, "/data/data/"+vm.getPackageName()+"/files"); } } } return super.callObjectMethodV(vm, dvmObject, signature, vaList); } @Override public boolean callStaticBooleanMethodV(BaseVM vm, DvmClass dvmClass, String signature, VaList vaList) { switch (signature){ case "android/os/Debug->isDebuggerConnected()Z":{ return false; } } return super.callStaticBooleanMethodV(vm, dvmClass, signature, vaList); } @Override public int callStaticIntMethodV(BaseVM vm, DvmClass dvmClass, String signature, VaList vaList) { switch (signature){ case "android/os/Process->myPid()I":{ return emulator.getPid(); } } return super.callStaticIntMethodV(vm, dvmClass, signature, vaList); }}
来源地址:https://blog.csdn.net/weixin_38927522/article/details/128083182