package com.ks; import com.github.unidbg.AndroidEmulator; import com.github.unidbg.Emulator; import com.github.unidbg.Module; import com.github.unidbg.file.FileResult; import com.github.unidbg.file.IOResolver; 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.api.AssetManager; import com.github.unidbg.linux.android.dvm.array.ArrayObject; import com.github.unidbg.linux.android.dvm.wrapper.DvmBoolean; import com.github.unidbg.linux.android.dvm.wrapper.DvmInteger; import com.github.unidbg.memory.Memory; import com.github.unidbg.virtualmodule.android.AndroidModule; import com.github.unidbg.virtualmodule.android.JniGraphics; import java.io.File; import java.io.FileNotFoundException; import java.util.ArrayList; import java.util.List; public class ks2 extends AbstractJni implements IOResolver{
@Override public FileResult resolve(Emulator emulator, String pathname, int oflags) {
System.out.println( "file open:" +pathname); return null ; } private final AndroidEmulator emulator; private final VM vm; private final Module module; ks2(){
emulator = AndroidEmulatorBuilder.for64Bit().build(); // 获取模拟器的内存操作接口 final Memory memory = emulator.getMemory(); // 设置系统类库解析 memory.setLibraryResolver( new AndroidResolver( 23 )); // 创建Android虚拟机,传入APK,Unidbg可以替我们做部分签名校验的工作 vm = emulator.createDalvikVM( new File( "unidbg-android/apks/ks/ks11.420.30984.apk" )); // 设置JNI vm.setJni( this ); // 打印日志 vm.setVerbose( true ); new JniGraphics(emulator, vm).register(memory); new AndroidModule(emulator, vm).register(memory); emulator.getSyscallHandler().addIOResolver( this ); //重定向io // 加载目标SO DalvikModule dm = vm.loadLibrary( "kwsgmain" , true ); // DalvikModule dm = vm.loadLibrary(new File("unidbg-android/apks/ks/libkwsgmain.so"), true); //获取本SO模块的句柄,后续需要用它 module = dm.getModule(); // 调用JNI OnLoad dm.callJNI_OnLoad(emulator); }; public void callByAddress(){
List<Object> list = new ArrayList<>( 4 ); list.add(vm.getJNIEnv()); // 第⼀个参数是env DvmObject<?> thiz = vm.resolveClass( "com/kuaishou/android/security/internal/dispatch/JNICLibrary" ).newObject( null ); list.add(vm.addLocalObject(thiz)); // 第⼆个参数,实例⽅法是jobject,静态⽅法是jclass,直接填0,⼀般⽤不到。 DvmObject<?> context = vm.resolveClass( "com/yxcorp/gifshow/App" ).newObject( null ); // context vm.addLocalObject(context); list.add( 10412 ); //参数1 StringObject appkey = new StringObject(vm, "d7b7d042-d4f2-4012-be60-d97ff2429c17" ); // SO⽂件有校验 vm.addLocalObject(appkey); DvmInteger intergetobj = DvmInteger.valueOf(vm, 0 ); vm.addLocalObject(intergetobj); list.add(vm.addLocalObject( new ArrayObject(intergetobj, appkey, intergetobj, intergetobj, context, intergetobj, intergetobj))); // 直接通过地址调⽤ Number numbers = module.callFunction(emulator, 0x41680 , list.toArray()); System.out.println( "numbers:" + numbers); DvmObject<?> object = vm.getObject(numbers.intValue()); String result = (String) object.getValue(); System.out.println( "result:" + result); }; @Override public DvmObject<?> callObjectMethodV(BaseVM vm, DvmObject<?> dvmObject, String signature, VaList vaList) {
switch (signature) {
case "com/yxcorp/gifshow/App->getPackageCodePath()Ljava/lang/String;" : {
return new StringObject(vm, "/data/app/com.smile.gifmaker-q14Fo0PSb77vTIOM1-iEqQ==/base.apk" ); } case "com/yxcorp/gifshow/App->getAssets()Landroid/content/res/AssetManager;" : {
return new AssetManager(vm, signature); } case "com/yxcorp/gifshow/App->getPackageName()Ljava/lang/String;" : {
return new StringObject(vm, "com.smile.gifmaker&
|