GithubHelp home page GithubHelp logo

zhkl0228 / unidbg Goto Github PK

View Code? Open in Web Editor NEW
3.5K 100.0 897.0 575.88 MB

Allows you to emulate an Android native library, and an experimental iOS emulation

License: Apache License 2.0

Shell 0.54% Java 83.17% Batchfile 0.01% C 8.14% Objective-C 3.93% Makefile 0.02% C++ 1.71% Objective-C++ 1.27% Kaitai Struct 1.05% Swift 0.01% JavaScript 0.16%
android emulator unicorn capstone keystone debugger ios emulation dynarmic hypervisor

unidbg's Introduction

unidbg

Allows you to emulate an Android native library, and an experimental iOS emulation.

This is an educational project to learn more about the ELF/MachO file format and ARM assembly.

Use it at your own risk !

License

Simple tests under src/test directory





More tests

Features

  • Emulation of the JNI Invocation API so JNI_OnLoad can be called.
  • Support JavaVM, JNIEnv.
  • Emulation of syscalls instruction.
  • Support ARM32 and ARM64.
  • Inline hook, thanks to Dobby.
  • Android import hook, thanks to xHook.
  • iOS fishhook and substrate and whale hook.
  • unicorn backend support simple console debugger, gdb stub, instruction trace, memory read/write trace.
  • Support iOS objc and swift runtime.
  • Support dynarmic fast backend.
  • Support Apple M1 hypervisor, the fastest ARM64 backend.
  • Support Linux KVM backend with Raspberry Pi B4.

Thanks

One-time Donation

We accept donations via WeChatPay:

WeChat Pay

Stargazers over time

Stargazers over time

unidbg's People

Contributors

dependabot[bot] avatar hluwa avatar minghaolin2000 avatar noob7777777 avatar onlythen avatar pdwnnr3572 avatar pr0214 avatar satng avatar webducerblog avatar xiada avatar zhkl0228 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

unidbg's Issues

unidbg调试dy出错

@zhkl0228
我测试抖音时遇到奔溃日志:
unicorn.UnicornException: Invalid memory read (UC_ERR_READ_UNMAPPED)
at unicorn.Unicorn.emu_start(Native Method)
at cn.banny.unidbg.AbstractEmulator.emulate(AbstractEmulator.java:267)
at cn.banny.unidbg.AbstractEmulator.eFunc(AbstractEmulator.java:360)
at cn.banny.unidbg.arm.AbstractARMEmulator.eFunc(AbstractARMEmulator.java:201)
at cn.banny.unidbg.linux.LinuxModule.emulateFunction(LinuxModule.java:154)
at cn.banny.unidbg.linux.android.dvm.DvmClass.callStaticJniMethod(DvmClass.java:140)
at com.ss.sys.ces.CMSTest.sign(CMSTest.java:105)
at com.ss.sys.ces.CMSTest.main(CMSTest.java:75)
debugger break at: 0x40012a54

r0=0x0 r1=0x414e1111 r2=0x574598f8, r3=0x0 r4=0xf72315d4 r5=0x18353522 r6=0x574598f7 r7=0xd7977dd5 sb=0x61cad990 sl=0x414e1112 fp=0x1 ip=0x0 sp=0xbfffe160 lr=0x61cad990 pc=0x40012a54 cpsr: N=0, Z=1, C=1, V=0, T=1, mode=0b10000
=> [ libcms.so][0x12a55][ 01 9b ]*0x40012a54:*ldr r3, [sp, #4]
[ libcms.so] [0x12a57] [ 03 93 ] 0x40012a56: str r3, [sp, #0xc]
[ libcms.so] [0x12a59] [ 03 9b ] 0x40012a58: ldr r3, [sp, #0xc]
[ libcms.so] [0x12a5b] [ 1b 78 ] 0x40012a5a: ldrb r3, [r3]
[ libcms.so] [0x12a5d] [ 00 2b ] 0x40012a5c: cmp r3, #0
[ libcms.so] [0x12a5f] [ 23 46 ] 0x40012a5e: mov r3, r4
[ libcms.so] [0x12a61] [ 04 bf ] 0x40012a60: itt eq
[ libcms.so] [0x12a63] [ 43 f2 22 53 ] 0x40012a62: movweq r3, #0x3522
[ libcms.so] [0x12a67] [ c1 f6 35 03 ] 0x40012a66: movteq r3, #0x1835
[ libcms.so] [0x12a6b] [ 21 e0 ] 0x40012a6a: b #0x40012ab0
CMSTest.zip
这个是我的测试代码
其实问题跟这个https://github.com/zhkl0228/unidbg/issues/21的作者是一样的,debug单步调试文件读取应该是没有问题的,但是最后还是出现了这样的错误报告,希望能得到大佬的答复,谢谢

Object...调用问题

jin方法
public static native Object native(int param, Object... args);

android调用
String key = "123";
String val = "test";
int type = 7;
String code = "";
native(1, new Object[]{val, key, code})

请问unidbg应该如何调用呢
目前写到这里不知道什么写了
native.callStaticJniMethod(emulator,"native(I[Ljava/lang/Object;)Ljava/lang/Object;",1,??)

测试某个so出现dvmObject=null, dvmClass=null的情况

在调用_CallObjectMethodV的时候,DvmObject dvmObject = getObject(object.peer);拿到的东西是空的,求大佬帮忙看看是什么情况。
具体报错如下:
``
unicorn.UnicornException: dvmObject=null, dvmClass=null, jmethodID=unicorn@0x318b4ca9
at cn.banny.unidbg.linux.android.dvm.DalvikVM$19.handle(DalvikVM.java:308)
at cn.banny.unidbg.linux.ARMSyscallHandler.hook(ARMSyscallHandler.java:90)
at unicorn.Unicorn.invokeInterruptCallbacks(Unicorn.java:123)
at unicorn.Unicorn.emu_start(Native Method)
at cn.banny.unidbg.AbstractEmulator.emulate(AbstractEmulator.java:267)
at cn.banny.unidbg.AbstractEmulator.eFunc(AbstractEmulator.java:360)
at cn.banny.unidbg.arm.AbstractARMEmulator.eFunc(AbstractARMEmulator.java:201)
at cn.banny.unidbg.linux.LinuxModule.emulateFunction(LinuxModule.java:154)
at cn.banny.unidbg.linux.android.dvm.DvmClass.callStaticJniMethod(DvmClass.java:140)
at com.ss.sys.ces.CMS.sign(CMS.java:101)
at com.ss.sys.ces.CMS.main(CMS.java:77)
debugger break at: 0xfffe01b4

r0=0xfffe0920 r1=0xbffff7c4 r2=0x318b4ca9, r3=0xbfffef14 r4=0xb377e5e8 r5=0xfffe0920 r6=0x50bb0e8 r7=0xabf69add r8=0xc148d653 r9=0xfffe0920 r10=0x6fe75f6e fp=0xc148d654 ip=0xfffe01b0 sp=0xbfffef00 lr=0x40011af5 pc=0xfffe01b4 cpsr: N=0, Z=1, C=1, V=0, T=0, mode=0b10000
[ libcms.so] [0x11ad7] [ fc 44 ] 0x40011ad6: add ip, pc
[ libcms.so] [0x11ad9] [ dc f8 00 c0 ] 0x40011ad8: ldr.w ip, [ip]
[ libcms.so] [0x11add] [ dc f8 00 c0 ] 0x40011adc: ldr.w ip, [ip]
[ libcms.so] [0x11ae1] [ 05 93 ] 0x40011ae0: str r3, [sp, #0x14]
[ libcms.so] [0x11ae3] [ 05 ab ] 0x40011ae2: add r3, sp, #0x14
[ libcms.so] [0x11ae5] [ cd f8 08 c0 ] 0x40011ae4: str.w ip, [sp, #8]
[ libcms.so] [0x11ae9] [ 01 93 ] 0x40011ae8: str r3, [sp, #4]
[ libcms.so] [0x11aeb] [ d0 f8 00 c0 ] 0x40011aea: ldr.w ip, [r0]
[ libcms.so] [0x11aef] [ dc f8 8c c0 ] 0x40011aee: ldr.w ip, [ip, #0x8c]
[ libcms.so] [0x11af3] [ e0 47 ] 0x40011af2: blx ip
[ 0xfffe01b0] [0x001b0] [ 12 01 00 ef ] 0xfffe01b0: svc #0x112
=> [ 0xfffe01b4][0x001b4]*[ 1e ff 2f e1 ]*0xfffe01b4:*bx lr
[ 0xfffe01b8] [0x001b8] [ 00 00 00 00 ] 0xfffe01b8: andeq r0, r0, r0
[ 0xfffe01bc] [0x001bc] [ 00 00 00 00 ] 0xfffe01bc: andeq r0, r0, r0
[ 0xfffe01c0] [0x001c0] [ 13 01 00 ef ] 0xfffe01c0: svc #0x113
[ 0xfffe01c4] [0x001c4] [ 1e ff 2f e1 ] 0xfffe01c4: bx lr
[ 0xfffe01c8] [0x001c8] [ 00 00 00 00 ] 0xfffe01c8: andeq r0, r0, r0
[ 0xfffe01cc] [0x001cc] [ 00 00 00 00 ] 0xfffe01cc: andeq r0, r0, r0
[ 0xfffe01d0] [0x001d0] [ 14 01 00 ef ] 0xfffe01d0: svc #0x114
[ 0xfffe01d4] [0x001d4] [ 1e ff 2f e1 ] 0xfffe01d4: bx lr
[ 0xfffe01d8] [0x001d8] [ 00 00 00 00 ] 0xfffe01d8: andeq r0, r0, r0
``

附件:
upload.zip

660.apk是dy的apk

执行NewGlobalRefs报空指针错误

你好,zhkl0228 ,我在调用so初始化时候,在执行newGlobalRefs 报空指针错误,能帮忙看看么
[17:12:54 108] DEBUG [cn.banny.emulator.linux.ARMSyscallHandler] (ARMSyscallHandler:433) - handleInterrupt intno=2, NR=-1073743908, svcNumber=0x106, PC=unicorn@0xfffe007c, syscall=null
java.lang.NullPointerException
at cn.banny.emulator.linux.android.dvm.DalvikVM$7.handle(DalvikVM.java:112)
at cn.banny.emulator.linux.ARMSyscallHandler.hook(ARMSyscallHandler.java:71)
at unicorn.Unicorn.invokeInterruptCallbacks(Unicorn.java:123)
at unicorn.Unicorn.emu_start(Native Method)
at cn.banny.emulator.AbstractEmulator.emulate(AbstractEmulator.java:197)
at cn.banny.emulator.AbstractEmulator.eFunc(AbstractEmulator.java:283)
at cn.banny.emulator.arm.AbstractARMEmulator.eFunc(AbstractARMEmulator.java:191)
at cn.banny.emulator.linux.LinuxModule.emulateFunction(LinuxModule.java:154)
at cn.banny.emulator.linux.android.dvm.DvmClass.callStaticJniMethod(DvmClass.java:144)
at com.xingin.xhs.Shield.(Shield.java:73)
at com.xingin.xhs.Shield.main(Shield.java:120)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)

运行Utilities64 报错 所有test都报错 idea win64

[17:11:26 957] WARN [cn.banny.unidbg.AbstractEmulator] (AbstractEmulator:271) - emulate unicorn@0x40a19a74[libc.so]0x1aa74 failed: sp=unicorn@0xbffff7b8, offset=3ms
unicorn.UnicornException: Invalid memory read (UC_ERR_READ_UNMAPPED)
at unicorn.Unicorn.emu_start(Native Method)
at cn.banny.unidbg.AbstractEmulator.emulate(AbstractEmulator.java:267)
at cn.banny.unidbg.AbstractEmulator.eFunc(AbstractEmulator.java:360)
at cn.banny.unidbg.arm.AbstractARM64Emulator.eInit(AbstractARM64Emulator.java:202)
at cn.banny.unidbg.linux.AbsoluteInitFunction.call(AbsoluteInitFunction.java:33)
at cn.banny.unidbg.linux.LinuxModule.callInitFunction(LinuxModule.java:46)
at cn.banny.unidbg.linux.AndroidElfLoader.loadInternal(AndroidElfLoader.java:171)
at cn.banny.unidbg.linux.AndroidElfLoader.loadInternal(AndroidElfLoader.java:30)
at cn.banny.unidbg.spi.AbstractLoader.load(AbstractLoader.java:211)
at cn.banny.unidbg.linux.android.dvm.BaseVM.loadLibrary(BaseVM.java:249)
at org.telegram.messenger.Utilities64.(Utilities64.java:39)
at org.telegram.messenger.Utilities64.main(Utilities64.java:51)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)

抖音的有测试过么?

[17:28:09 783]  WARN [cn.banny.unidbg.linux.ARMSyscallHandler] (ARMSyscallHandler:346) - handleInterrupt intno=2, NR=1467298506, svcNumber=0x122, PC=unicorn@0xfffe015c, syscall=null
java.lang.AbstractMethodError: java/security/cert/CertificateFactory->getInstance(Ljava/lang/String;)Ljava/security/cert/CertificateFactory;
	at cn.banny.unidbg.linux.android.dvm.AbstractJni.callStaticObjectMethodV(AbstractJni.java:183)
	at cn.banny.unidbg.linux.android.dvm.DvmMethod.callStaticObjectMethodV(DvmMethod.java:35)
	at cn.banny.unidbg.linux.android.dvm.DalvikVM$35.handle(DalvikVM.java:626)
	at cn.banny.unidbg.linux.ARMSyscallHandler.hook(ARMSyscallHandler.java:69)
	at unicorn.Unicorn.invokeInterruptCallbacks(Unicorn.java:123)
	at unicorn.Unicorn.emu_start(Native Method)
	at cn.banny.unidbg.AbstractEmulator.emulate(AbstractEmulator.java:204)
	at cn.banny.unidbg.AbstractEmulator.eFunc(AbstractEmulator.java:290)
	at cn.banny.unidbg.arm.AbstractARMEmulator.eFunc(AbstractARMEmulator.java:193)
	at cn.banny.unidbg.linux.LinuxModule.emulateFunction(LinuxModule.java:154)
	at cn.banny.unidbg.linux.android.dvm.DvmObject.callJniMethod(DvmObject.java:43)

像这种应该这么解决

找不到getSharedPreferences

QQ截图20190810202643
QQ截图20190810202840
如图,看上去Application里找不到getSharedPreferences这个方法。目前Application里调试看到只有getPackageManager和getPackageInfo。在哪里加上请指教

jni的一部分方法可以调用,一部分调用失败一般是什么原因?


public class AwemeEncryptTest extends AbstractJni implements IOResolver {

    private static LibraryResolver createLibraryResolver() {
        return new AndroidResolver(23);
    }

    private static ARMEmulator createARMEmulator() {
        return new AndroidARMEmulator("com.ss.android");
    }

    private final ARMEmulator emulator;
    private final VM vm;
    private final Module module;

    private final DvmClass UserInfo;

    private AwemeEncryptTest() throws IOException {
        emulator = createARMEmulator();
        final Memory memory = emulator.getMemory();
        memory.setLibraryResolver(createLibraryResolver());
        memory.setCallInitFunction();

        vm = emulator.createDalvikVM(null);
        DalvikModule dm = vm.loadLibrary(new File("src/test/resources/example_binaries/libcms.so"), false);
        vm.setJni(this);
        dm.callJNI_OnLoad(emulator);
        module = dm.getModule();

        UserInfo = vm.resolveClass("com/ss/android/common/applog/UserInfo");
    }
    private void destroy() throws IOException {
        emulator.close();
        System.out.println("module=" + module);
        System.out.println("== destroy ===");
    }
    public static void main(String[] args) throws Exception {
        AwemeEncryptTest test = new AwemeEncryptTest();
        test.sign();
        test.destroy();
    }

    private void sign() {
        int appId = 1128;
        UserInfo.callStaticJniMethod(emulator, "setAppId(I)V", appId);
        long hash;
        StringObject obj ;
        Number ret;
        String key = "a3668f0afac72ca3f6c1697d29e0e1bb1fef4ab0285319b95ac39fa42c38d05f";
        UserInfo.callStaticJniMethod(emulator, "initUser(Ljava/lang/String;)I", new StringObject(vm, key));
//        System.out.println(obj.getValue());

        ret = UserInfo.callStaticJniMethod(emulator, "getS()Ljava/lang/String;");
        hash = ret.intValue() & 0xffffffffL;
        obj = vm.getObject(hash);
        System.out.println(obj.getValue());

        UserInfo.callStaticJniMethod(emulator, "getType()I");


        int timeStamp = 1559629512;
        String deviceId = "53039791462";
        String url = "https://aweme-eagle.snssdk.com/aweme/v1/feed/?os_api=26&device_type=MHA-AL00&ssmix=a&manifest_version_code=380&dpi=480&uuid=865296034887289&js_sdk_version=1.5.4&need_relieve_aweme=0&min_cursor=0&req_from=&count=6&app_name=aweme&max_cursor=0&version_name=3.8.0&pull_type=1&ac=wifi&app_type=normal&update_version_code=3802&channel=update&type=0&_rticket=1545468521415&is_cold_start=0&device_platform=android&iid=54915619827&volume=0.0&longitude=120.388862&version_code=380&openudid=3a6f6cdf79dc8965&device_id=53039791462&latitude=36.090072&resolution=1080*1808&device_brand=HUAWEI&language=zh&os_version=8.0.0&filter_warn=0&aid=1128&mcc_mnc=46000&ts=1559629512";
        ret = UserInfo.callStaticJniMethod(emulator, "getUserInfo(ILjava/lang/String;[Ljava/lang/String;)Ljava/lang/String;",
                timeStamp,new StringObject(vm,url),null,new StringObject(vm,deviceId));
        hash = ret.intValue() & 0xffffffffL;
        obj = vm.getObject(hash);
        vm.deleteLocalRefs();
//        System.out.println(obj.getValue());
        Number[] numbers = module.callFunction(emulator, 0x19c5d,vm.getJNIEnv(),0x363E7561,timeStamp,url,null,deviceId);
        Unicorn unicorn = emulator.getUnicorn();
        long address = numbers[0].intValue() & 0xffffffffL;
        System.out.println("eFunc length is: " + numbers[0].intValue());
        System.out.println("ret=" + ARM.readCString(unicorn, address));
    }


    @Override
    public FileIO resolve(File workDir, String pathname, int oflags) {
        if (("proc/" + emulator.getPid() + "/status").equals(pathname)) {
            return new ByteArrayFileIO(oflags, pathname, "TracerPid:\t0\n".getBytes());
        }
        return null;
    }
}

这个是so文件
libcms.zip

getS 和 getType能得到返回值
其他就是NullPointerException

调用libcms 的leviathan方法时,程序输出警告

警告内容:
cn.banny.unidbg.linux.ARMSyscallHandler hook
handleInterrupt intno=2, NR=345, svcNumber=0x0, PC=unicorn@0x4022a65c[libcms.so]0x2a65c, syscall=null

根据提示, 去到相关类的hook方法. 发现是345没有定义.
请问345对应的实现函数如何定义?
请问345对应的函数是lds吗?

关于gdbserver调试查看内存的问题

想请问下具体gdbserver的问题,我使用gdbserver在ida上进行动态调试,但是发现在hexview里面只能看到so的内存信息,rebase后就只能看到0x40000000 - 0x400EF560之间的内存信息,想问一下作者怎样才能看到别的地方的内存信息?能在unidbg看还是ida里面看,我在unidbg里面想用mr0这样的是看不见的。
image

关于 cn.banny.unidbg.file.AbstractFileIO.ioctl(AbstractFileIO.java:66) 的异常

作者你好,在调试的时候遇到一个异常

  >>> r0=0x4 r1=0x8912 r2=0xbfffea84, r3=0xd358ee20 r4=0xd358ee20 r5=0xa994c780 r6=0xbfffea88 r7=0x36 r9=0xe896a2b1 r10=0x5970fe23 fp=0x427a336e ip=0xbfffea18 sp=0xbfffea08 lr=0x400245c1 pc=0x4002a65c cpsr: N=0, Z=1, C=1, V=0, T=0, mode=0b10000
[14:04:04 455] DEBUG [cn.banny.unidbg.linux.ARMSyscallHandler] (ARMSyscallHandler:1646) - ioctl fd=4, request=0x8912, argp=0xbfffea84
[14:05:01 084]  WARN [cn.banny.unidbg.linux.ARMSyscallHandler] (ARMSyscallHandler:377) - handleInterrupt intno=2, NR=54, svcNumber=0x0, PC=unicorn@0x4002a65c[libcms.so]0x2a65c, syscall=null
java.lang.AbstractMethodError: cn.banny.unidbg.unix.file.UdpSocket: request=0x8912, argp=0xbfffea84
	at cn.banny.unidbg.file.AbstractFileIO.ioctl(AbstractFileIO.java:66)
	at cn.banny.unidbg.linux.ARMSyscallHandler.ioctl(ARMSyscallHandler.java:1658)
	at cn.banny.unidbg.linux.ARMSyscallHandler.hook(ARMSyscallHandler.java:162)
	at unicorn.Unicorn.invokeInterruptCallbacks(Unicorn.java:123)
	at unicorn.Unicorn.emu_start(Native Method)
	at cn.banny.unidbg.AbstractEmulator.emulate(AbstractEmulator.java:267)
	at cn.banny.unidbg.AbstractEmulator.eFunc(AbstractEmulator.java:360)
	at cn.banny.unidbg.arm.AbstractARMEmulator.eFunc(AbstractARMEmulator.java:201)
	at cn.banny.unidbg.linux.LinuxModule.emulateFunction(LinuxModule.java:154)
	at cn.banny.unidbg.linux.android.dvm.DvmClass.callStaticJniMethod(DvmClass.java:140)

我debug看的时候发现fd=4的时候,fdMap->"", 然后调用 file.ioctl(emulator, request, argp);就出现异常了,
image
具体异常信息:
image

关于调试问题

作者你好~
在调用之前使用emulator.attach(DebuggerType.GDB_SERVER);
可以进行动态调试么?具体操作应该怎么做,

override callObjectMethodV

@OverRide
public DvmObject callObjectMethodV(BaseVM vm, DvmObject dvmObject, String signature, VaList vaList) {
switch (signature){
case "java/lang/Thread->getStackTrace()[Ljava/lang/StackTraceElement;":
return ????
}
return super.callObjectMethodV(vm, dvmObject, signature, vaList);
}

signature为“java/lang/Thread->getStackTrace()[Ljava/lang/StackTraceElement;”时返回值应该怎么写呢?如何返回object的数组?

native方法调用返回值是int,调用后如何拿到返回值呢?

Number ret = TTEncryptUtils.callStaticJniMethod(emulator, "init(Landroid/content/Context;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;II)I"
, vm.addLocalObject(context),
vm.addLocalObject(new StringObject(vm, "1.1")),
vm.addLocalObject(new StringObject(vm, "")),
vm.addLocalObject(new StringObject(vm, "")),
vm.addLocalObject(new StringObject(vm, "")),
vm.addLocalObject(new StringObject(vm, "./")),
vm.addLocalObject(new StringObject(vm, "./")),
0, 2
);

如上,init 方法调用返回值是int类型,我这边调用后如何拿到返回值呢?

关于 “svcMemory.registerSvc” 执行过程中存在NULL错误的问题请教

大神你好,遇到了一个问题,在调用_CallObjectMethodV的时候,DvmObject dvmObject = getObject(object.peer),返回值为空;这个问题前面有个兄弟遇到过了,你给的解决方案是根据具体的context传入具体的内容,但是我这里不用传context,而且函数的签名是直接从so中复制出来的,应该不会出错,鉴于没有很好的参考性,所以来请教大神了。

值得一提的是,在调用其他的native接口的时候比如getKey,是可以直接得到结果的;但是在调用SM2的一个解密接口时,就会出现上述的错误,而且这个so的函数签名好像是混淆过的,希望大神抽空帮我看看,有劳了!

附件:
TestPag.zip

open文件夹时 报错

附上示例

public class DemoTest extends AbstractJni implements IOResolver {

    private static LibraryResolver createLibraryResolver() {
        return new AndroidResolver(23);
    }

    private static ARMEmulator createARMEmulator() {
        return new AndroidARMEmulator("zzz.me.unidbg_d");
    }

    private final ARMEmulator emulator;
    private final VM vm;
    private final Module module;

    private final DvmClass MainActivity;

    private DemoTest() throws IOException {
        emulator = createARMEmulator();
        emulator.getSyscallHandler().addIOResolver(this);
        final Memory memory = emulator.getMemory();
        memory.setLibraryResolver(createLibraryResolver());
        memory.setCallInitFunction();

        vm = emulator.createDalvikVM(new File("src/test/resources/app/app-debug.apk"));
        DalvikModule dm = vm.loadLibrary("native-lib", false);
        dm.callJNI_OnLoad(emulator);
        module = dm.getModule();

        MainActivity = vm.resolveClass("zzz.me.unidbg_d.MainActivity".replace(".", "/"));
    }

    public static void main(String[] args) throws Exception {
        DemoTest test = new DemoTest();

        test.test();

        test.destroy();
    }

    private void destroy() throws IOException {
        emulator.close();
        System.out.println("destroy module=" + module);
    }

    private void test() {
        vm.setJni(this);
        IWhale whale = Whale.getInstance(emulator);

        final Symbol compress;
        try {
            compress = emulator.getMemory().findModule("libz.so").findSymbolByName("compress");
            if (compress != null) {
                whale.WInlineHookFunction(compress, new ReplaceCallback() {
                    @Override
                    public HookStatus onCall(Emulator emulator, long originFunction) {

                        RegisterContext context = emulator.getContext();

                        Pointer dest = context.getPointerArg(0);
                        Pointer destLen = context.getPointerArg(1);
                        Pointer src = context.getPointerArg(2);
                        long srcLen = context.getLongArg(3);

                        String src_Compress = new String(src.getByteArray(0, (int) srcLen));


                        System.out.println("Let's compress: " + src_Compress);
                        return HookStatus.RET(emulator, originFunction);
                    }
                });
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        Number ret = MainActivity.callStaticJniMethod(emulator, "stringFromJNI()Ljava/lang/String;");
        long hash = ret.intValue() & 0xffffffffL;
        StringObject obj = vm.getObject(hash);
        vm.deleteLocalRefs();
        System.err.println(obj.getValue());
    }


    @Override
    public FileIO resolve(File workDir, String pathname, int oflags) {
        return null;
    }
}

cpp代码:

#include <jni.h>
#include <string>
#include <zlib.h>
#include <fcntl.h>
#include <cstring>

#ifndef NELEM
# define NELEM(x) ((int) (sizeof(x) / sizeof((x)[0])))
#endif

const char *className = "zzz/me/unidbg_d/MainActivity";     // the jni class

jstring stringFromJNI(JNIEnv *env, jobject /* this */) {

    Byte compr[200];
    uLongf destLen = sizeof(compr) / sizeof(compr[0]);
    const char* hello = "12345678901234567890123456789012345678901234567890";
    uLong len = strlen(hello) + 1;

    if(compress(compr, &destLen, (const Bytef*)hello, len) == Z_OK) {
        int fd = open("/proc", O_RDONLY);
        if(fd == -1) {
            printf("打开失败\n");
        }
        close(fd);
    }
    printf("打开Proc\n");
    return env->NewStringUTF(hello);
}

/**
 * name:      stringFromJni
 * signature: ()Ljava/lang/String;
 * fnPtr:     stringFromJni
 *
 * jni.h struct JNINativeMethod
 */
static const JNINativeMethod sMethods[] = {                                  // jni methods table
        {"stringFromJNI", "()Ljava/lang/String;", (void *) stringFromJNI},
};

JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *) {
    JNIEnv *env;
    if (vm->GetEnv(reinterpret_cast<void **>(&env), JNI_VERSION_1_6) != JNI_OK) {
        return JNI_EVERSION;
    } //if

    jclass clazz = env->FindClass(className);              // find the jni class
    if (clazz == NULL) {
        return JNI_ERR;
    }

    if (env->RegisterNatives(clazz, sMethods, NELEM(sMethods)) < 0) {      //register jni methods
        return JNI_ERR;
    }

    return JNI_VERSION_1_6;
}

报错日志:

java.lang.IllegalStateException: java.io.FileNotFoundException: /tmp/proc (是一个目录)
	at cn.banny.unidbg.linux.android.AndroidResolver.resolve(AndroidResolver.java:143)
	at cn.banny.unidbg.unix.UnixSyscallHandler.resolve(UnixSyscallHandler.java:55)
	at cn.banny.unidbg.unix.UnixSyscallHandler.open(UnixSyscallHandler.java:146)
	at cn.banny.unidbg.linux.ARMSyscallHandler.openat(ARMSyscallHandler.java:1542)
	at cn.banny.unidbg.linux.ARMSyscallHandler.hook(ARMSyscallHandler.java:340)
	at unicorn.Unicorn.invokeInterruptCallbacks(Unicorn.java:123)
	at unicorn.Unicorn.emu_start(Native Method)
	at cn.banny.unidbg.AbstractEmulator.emulate(AbstractEmulator.java:267)
	at cn.banny.unidbg.AbstractEmulator.eFunc(AbstractEmulator.java:360)
	at cn.banny.unidbg.arm.AbstractARMEmulator.eFunc(AbstractARMEmulator.java:201)
	at cn.banny.unidbg.linux.LinuxModule.emulateFunction(LinuxModule.java:154)
	at cn.banny.unidbg.linux.android.dvm.DvmClass.callStaticJniMethod(DvmClass.java:140)
	at zzz.me.unidbg_d.DemoTest.test(DemoTest.java:102)
	at zzz.me.unidbg_d.DemoTest.main(DemoTest.java:61)
Caused by: java.io.FileNotFoundException: /tmp/proc (是一个目录)
	at java.io.FileOutputStream.open0(Native Method)
	at java.io.FileOutputStream.open(FileOutputStream.java:270)
	at java.io.FileOutputStream.<init>(FileOutputStream.java:213)
	at java.io.FileOutputStream.<init>(FileOutputStream.java:162)
	at cn.banny.unidbg.linux.android.AndroidResolver.resolve(AndroidResolver.java:139)
	... 13 more

附上app:

app.zip

Linux服务器上初始化unicorn失败

在Windows环境运行正常,将项目部署到linux服务器上,一开始报找不到unicorn_java,在将linux64的so设置入服务器的java.path后,出现另一个错误Could not initialize class unicorn.Unicorn,发现是在下面new Unicorn中进入jar后报了错,请问作者这个是什么原因:

public AbstractEmulator(int unicorn_arch, int unicorn_mode, String processName) {
super();

    this.unicorn = new Unicorn(unicorn_arch, unicorn_mode);
    this.processName = processName == null ? "unidbg" : processName;
    this.registerContext = createRegisterContext(unicorn);

    this.readHook = new TraceMemoryHook();
    this.writeHook = new TraceMemoryHook();
    this.codeHook = new AssemblyCodeDumper(this);

    String name = ManagementFactory.getRuntimeMXBean().getName();
    String pid = name.split("@")[0];
    this.pid = Integer.parseInt(pid);

    POINTER_SIZE.set(getPointerSize());
}

执行到方法:AbstractJni.newObjectV 时,找不到对应的函数签名类型

具体的报错为:

newObjectV signature:java/lang/String->([BLjava/lang/String;)V
[19:51:27 721] WARN [cn.banny.unidbg.linux.ARMSyscallHandler] (ARMSyscallHandler:384) - handleInterrupt intno=2, NR=-2083121372, svcNumber=0x10d, PC=unicorn@0xfffe0164, syscall=null
java.lang.AbstractMethodError: java/lang/String->([BLjava/lang/String;)V
at cn.banny.unidbg.linux.android.dvm.AbstractJni.newObjectV(AbstractJni.java:346)
at cn.banny.unidbg.linux.android.dvm.DvmMethod.newObjectV(DvmMethod.java:177)
at cn.banny.unidbg.linux.android.dvm.DalvikVM$14.handle(DalvikVM.java:218)
at cn.banny.unidbg.linux.ARMSyscallHandler.hook(ARMSyscallHandler.java:92)
at unicorn.Unicorn.invokeInterruptCallbacks(Unicorn.java:123)
at unicorn.Unicorn.emu_start(Native Method)
at cn.banny.unidbg.AbstractEmulator.emulate(AbstractEmulator.java:267)
at cn.banny.unidbg.AbstractEmulator.eFunc(AbstractEmulator.java:360)
at cn.banny.unidbg.arm.AbstractARMEmulator.eFunc(AbstractARMEmulator.java:201)
at cn.banny.unidbg.linux.LinuxModule.emulateFunction(LinuxModule.java:154)
at cn.banny.unidbg.linux.android.dvm.DvmClass.callStaticJniMethod(DvmClass.java:140)
at cn.passguard.PassGuardEncrypt.sig_1init(PassGuardEncrypt.java:170)
at cn.passguard.PassGuardEncrypt.main(PassGuardEncrypt.java:71)

涉及到的方法原型:
@OverRide
public DvmObject newObjectV(BaseVM vm, DvmClass dvmClass, String signature, VaList vaList) {
System.out.println("newObjectV signature:" + signature);
if ("java/io/ByteArrayInputStream->([B)V".equals(signature)) {
ByteArray array = vaList.getObject(0);
return new DvmObject<>(vm.resolveClass("java/io/ByteArrayInputStream"), new ByteArrayInputStream(array.value));
}
throw new AbstractMethodError(signature);
}

结果:
当sugbature为java/lang/String->([BLjava/lang/String;)V的时候,直接抛出异常,我应该怎么续写该类型的返回值?求大神解答。

附件:
TestPag.zip

Substrate64Test 运行会进入到调试器里

Substrate64Test运行会有如下结果,这是意料中的吗?

`
/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/bin/java -Djava.library.path=prebuilt/osx64 -Djna.library.path=prebuilt/osx64 "-javaagent:/Applications/IntelliJ IDEA.app/Contents/lib/idea_rt.jar=50969:/Applications/IntelliJ IDEA.app/Contents/bin" -Dfile.encoding=UTF-8 -classpath /Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/charsets.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/deploy.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/ext/cldrdata.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/ext/dnsns.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/ext/jaccess.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/ext/jfxrt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/ext/localedata.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/ext/nashorn.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/ext/sunec.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/ext/sunjce_provider.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/ext/sunpkcs11.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/ext/zipfs.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/javaws.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/jce.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/jfr.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/jfxswt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/jsse.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/management-agent.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/plugin.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/resources.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/rt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/lib/ant-javafx.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/lib/dt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/lib/javafx-mx.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/lib/jconsole.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/lib/packager.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/lib/sa-jdi.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/lib/tools.jar:/Users/admin/Project/GitProject/emulator/target/test-classes:/Users/admin/Project/GitProject/emulator/target/classes:/Users/admin/.m2/repository/org/unicorn-engine/unicorn/1.0.1/unicorn-1.0.1.jar:/Users/admin/.m2/repository/net/java/dev/jna/jna/4.5.2/jna-4.5.2.jar:/Users/admin/.m2/repository/org/capstone-engine/capstone/3.0.5/capstone-3.0.5.jar:/Users/admin/.m2/repository/keystone/java-bindings/0.9.1-2/java-bindings-0.9.1-2.jar:/Users/admin/.m2/repository/net/java/dev/jna/jna-platform/4.5.1/jna-platform-4.5.1.jar:/Users/admin/.m2/repository/cn/banny/utils/0.0.8/utils-0.0.8.jar:/Users/admin/.m2/repository/commons-io/commons-io/2.4/commons-io-2.4.jar:/Users/admin/.m2/repository/commons-logging/commons-logging/1.1.3/commons-logging-1.1.3.jar:/Users/admin/.m2/repository/net/dongliu/apk-parser/2.6.4/apk-parser-2.6.4.jar:/Users/admin/.m2/repository/io/kaitai/kaitai-struct-runtime/0.8/kaitai-struct-runtime-0.8.jar:/Users/admin/.m2/repository/log4j/log4j/1.2.17/log4j-1.2.17.jar:/Users/admin/.m2/repository/junit/junit/3.8.2/junit-3.8.2.jar:/Users/admin/.m2/repository/commons-codec/commons-codec/1.11/commons-codec-1.11.jar cn.banny.unidbg.ios.Substrate64Test
objc[67023]: Class JavaLaunchHelper is implemented in both /Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/bin/java (0x10867e4c0) and /Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/libinstrument.dylib (0x10870a4e0). One of the two will be used. Which one is undefined.
[15:45:05 544] DEBUG [cn.banny.unidbg.AbstractEmulator] (AbstractEmulator:265) - emulate unicorn@0x10021fb30[libSystem.B.dylib]0x3b30 started sp=unicorn@0xfbfffef50
[15:45:05 578] INFO [cn.banny.unidbg.ios.ARM64SyscallHandler] (ARM64SyscallHandler:672) - sysctl CTL_KERN action=59, namelen=2, buffer=unicorn@0xfbfffeed0, bufferSize=unicorn@0xfbfffeec8, set0=null, set1=0
[15:45:05 579] INFO [cn.banny.unidbg.ios.ARM64SyscallHandler] (ARM64SyscallHandler:272) - pthread_set_self=unicorn@0x100578380[libsystem_pthread.dylib]0x8380
unicorn.UnicornException: Write to write-protected memory (UC_ERR_WRITE_PROT)
at unicorn.Unicorn.emu_start(Native Method)
at cn.banny.unidbg.AbstractEmulator.emulate(AbstractEmulator.java:267)
at cn.banny.unidbg.AbstractEmulator.eFunc(AbstractEmulator.java:360)
at cn.banny.unidbg.arm.AbstractARM64Emulator.eFunc(AbstractARM64Emulator.java:190)
at cn.banny.unidbg.ios.MachOModuleInit.callModInit(MachOModuleInit.java:65)
at cn.banny.unidbg.ios.MachOModuleInit.call(MachOModuleInit.java:47)
at cn.banny.unidbg.ios.MachOModule.callInitFunction(MachOModule.java:187)
at cn.banny.unidbg.ios.MachOLoader.loadInternal(MachOLoader.java:152)
at cn.banny.unidbg.ios.MachOLoader.loadInternalPhase(MachOLoader.java:220)
at cn.banny.unidbg.ios.MachOLoader.loadInternalPhase(MachOLoader.java:190)
at cn.banny.unidbg.ios.MachOLoader.loadInternalPhase(MachOLoader.java:165)
at cn.banny.unidbg.ios.MachOLoader.loadInternal(MachOLoader.java:135)
at cn.banny.unidbg.ios.MachOLoader.loadInternal(MachOLoader.java:131)
at cn.banny.unidbg.spi.AbstractLoader.load(AbstractLoader.java:204)
at cn.banny.unidbg.spi.AbstractLoader.load(AbstractLoader.java:194)
at cn.banny.unidbg.arm.AbstractARM64Emulator.loadLibrary(AbstractARM64Emulator.java:111)
at cn.banny.unidbg.ios.Substrate64Test.testMS(Substrate64Test.java:47)
at cn.banny.unidbg.ios.Substrate64Test.main(Substrate64Test.java:163)
debugger break at: 0x100016094

x0=0x1000370b8 x1=0x1005c3d5d x2=0x0, x3=0xfbfffebd8 x4=0x2060 x5=0x1 x6=0x716e6f69736e65 x7=0x0 x8=0x1000370c0 x9=0x1000370b8 x10=0x10000 x11=0x0 x12=0x0 x13=0x0 x14=0xffffffff x15=0xffffffe7 x16=0x0 x17=0x4059000000000000 x18=0x0 x19=0x1005a4608 x20=0x1005c3d5d x21=0x1005c7f48 x22=0x1005c7f58 x23=0x1001ce480 x24=0x100701320 x25=0x0 x26=0x1000284e0 x27=0x0 x28=0xfffffffffffffffb fp=0xfbfffec40
lr=0x10001608c
sp=0xfbfffec20
pc=0x100016094
nzcv: N=0, Z=1, C=0, V=0, T=0, mode=0b0
=> [ libobjc.A.dylib][0x000006094]*[ a8 1e 40 b9 ]*0x100016094:*ldr w8, [x21, #0x1c]
[ libobjc.A.dylib] [0x000006098] [ 08 05 00 11 ] 0x100016098: add w8, w8, #1
[ libobjc.A.dylib] [0x00000609c] [ a8 1e 00 b9 ] 0x10001609c: str w8, [x21, #0x1c]
[ libobjc.A.dylib] [0x0000060a0] [ 08 20 00 91 ] 0x1000160a0: add x8, x0, #8
[ libobjc.A.dylib] [0x0000060a4] [ 14 4c 00 a9 ] 0x1000160a4: stp x20, x19, [x0]
[ libobjc.A.dylib] [0x0000060a8] [ c0 0d 00 90 ] 0x1000160a8: adrp x0, #0x1001ce000
[ libobjc.A.dylib] [0x0000060ac] [ 00 20 0a 91 ] 0x1000160ac: add x0, x0, #0x288
[ libobjc.A.dylib] [0x0000060b0] [ f6 57 c1 a8 ] 0x1000160b0: ldp x22, x21, [sp], #0x10
[ libobjc.A.dylib] [0x0000060b4] [ f4 4f c1 a8 ] 0x1000160b4: ldp x20, x19, [sp], #0x10
[ libobjc.A.dylib] [0x0000060b8] [ fd 7b c1 a8 ] 0x1000160b8: ldp x29, x30, [sp], #0x10

`

测试dy遇到的情况

你好,在测试dy的时候又遇到一个问题,下面是一些错误日志和截图,请问这是什么情况?

>-----------------------------------------------------------------------------<
[11:19:19 654]GetByteArrayRegion array=ByteArray{value=[B@153f5a29}, start=0, length=17, buf=unicorn@0x402cd030, md5=1b5de627b4a25553baf1f72af9afb96d, hex=31313a32323a33333a34343a35353a3636
size: 17
0000: 31 31 3A 32 32 3A 33 33 3A 34 34 3A 35 35 3A 36    11:22:33:44:55:6
0010: 36                                                 6
^-----------------------------------------------------------------------------^
[11:19:19 655] DEBUG [cn.banny.unidbg.linux.android.dvm.DalvikVM] (DalvikVM$9:143) - DeleteLocalRef object=unicorn@0xfffe0920
[11:19:19 656] DEBUG [cn.banny.unidbg.linux.android.dvm.DalvikVM] (DalvikVM$9:143) - DeleteLocalRef object=unicorn@0xfffe0920
[11:19:19 656] DEBUG [cn.banny.unidbg.linux.android.dvm.DalvikVM] (DalvikVM$9:143) - DeleteLocalRef object=unicorn@0xfffe0920
[11:19:19 656] DEBUG [cn.banny.unidbg.linux.android.dvm.DalvikVM] (DalvikVM$9:143) - DeleteLocalRef object=unicorn@0xfffe0920
>>> r0=0x1200011 r1=0x0 r2=0x0, r3=0x0 r4=0xbffffc08 r5=0x4fbb09ad r6=0x9bd8bb44 r7=0x78 r9=0xac98b1ca r10=0xbfffeec8 fp=0x1bba0160 ip=0xbfffec90 sp=0xbfffec80 lr=0x401092b5 pc=0x401075ec cpsr: N=0, Z=0, C=1, V=0, T=0, mode=0b10000
[11:19:19 659]  WARN [cn.banny.unidbg.linux.ARMSyscallHandler] (ARMSyscallHandler:377) - handleInterrupt intno=2, NR=120, svcNumber=0x0, PC=unicorn@0x401075ec[libc.so]0x175ec, syscall=null
java.lang.NullPointerException
	at cn.banny.unidbg.linux.ARMSyscallHandler.hook(ARMSyscallHandler.java:201)
	at unicorn.Unicorn.invokeInterruptCallbacks(Unicorn.java:123)
	at unicorn.Unicorn.emu_start(Native Method)
	at cn.banny.unidbg.AbstractEmulator.emulate(AbstractEmulator.java:267)
	at cn.banny.unidbg.AbstractEmulator.eFunc(AbstractEmulator.java:360)
	at cn.banny.unidbg.arm.AbstractARMEmulator.eFunc(AbstractARMEmulator.java:201)
	at cn.banny.unidbg.linux.LinuxModule.emulateFunction(LinuxModule.java:154)
	at cn.banny.unidbg.linux.android.dvm.DvmClass.callStaticJniMethod(DvmClass.java:140)

image

读取完/proc/self/maps后r0寄存器为0xffffffff

今天跑一下dy720版本的meta的时候,发现系统调用read了/proc/self/maps这个文件后,r0=0xffffffff r1=0x0 r2=0xffffffff, r3=0x0 r4=0x6991e777 r5=0x98,r0直接变成了0xffffffff,我看这个文件读取了好几次,前面都没问题,下面就出问题了。
报错日志:
image

不清楚是什么错误,大佬有空帮手看看!
测试用例相关文件:
test.zip

Invalid memory fetch (UC_ERR_FETCH_UNMAPPED)的问题

调试dy的时候遇到这个问题

[22:02:51 972] DEBUG [cn.banny.unidbg.linux.android.dvm.DalvikVM] (DalvikVM$77:1361) - ExceptionCheck jthrowable=null
[22:02:51 972] DEBUG [cn.banny.unidbg.linux.android.dvm.DalvikVM] (DalvikVM$15:228) - GetObjectClass object=unicorn@0x24e5a4e0, dvmObject=DvmObject{value=META-INF/FUNNYGAL.RSA}
[22:02:51 972] DEBUG [cn.banny.unidbg.linux.android.dvm.DalvikVM] (DalvikVM$77:1361) - ExceptionCheck jthrowable=null
[22:02:52 028] DEBUG [cn.banny.unidbg.linux.android.dvm.DalvikVM] (DalvikVM$17:265) - GetMethodID class=unicorn@0x147c6f7e, methodName=getSize, args=()J
[22:02:52 028] DEBUG [cn.banny.unidbg.linux.android.dvm.DvmClass] (DvmClass:53) - getMethodID name=java/util/zip/ZipEntry->getSize()J, hash=0xb1d720e2
unicorn.UnicornException: Invalid memory fetch (UC_ERR_FETCH_UNMAPPED)
	at unicorn.Unicorn.emu_start(Native Method)
	at cn.banny.unidbg.AbstractEmulator.emulate(AbstractEmulator.java:267)
	at cn.banny.unidbg.AbstractEmulator.eFunc(AbstractEmulator.java:360)
	at cn.banny.unidbg.arm.AbstractARMEmulator.eFunc(AbstractARMEmulator.java:201)
	at cn.banny.unidbg.linux.LinuxModule.emulateFunction(LinuxModule.java:154)
	at cn.banny.unidbg.linux.android.dvm.DvmClass.callStaticJniMethod(DvmClass.java:140)
	at com.ss.sys.ces.CMS.sign(CMS.java:122)
	at com.ss.sys.ces.CMS.main(CMS.java:90)
debugger break at: 0xd4
>>> r0=0xfffe0920 r1=0x24e5a4e0 r2=0xb1d720e2, r3=0xbfffe144 r4=0xfffe0920 r5=0xfffe0190 r6=0x24e5a4e0 r7=0xbfffe178 r8=0x5039de18 r9=0x147c6f7e r10=0xe6e59a17 fp=0xbfffe2d4 ip=0xd4 sp=0xbfffe130 lr=0x4001a8cd pc=0xd4 cpsr: N=0, Z=1, C=1, V=0, T=0, mode=0b10000

想问一下作者大大怎么解决

运行报Invalid memory fetch (UC_ERR_FETCH_UNMAPPED)错误

你好,我在调用一个so时报Invalid memory fetch (UC_ERR_FETCH_UNMAPPED)的错误,具体错误如下:
image
libdexshell.so有个依赖库libandroid.so,我尝试过把libandroid.so放到相关目录下,结果引发的错误更多了。现在在调用callJNI_OnLoad就会报Invalid memory fetch (UC_ERR_FETCH_UNMAPPED)的错误,请问这个问题要怎么解决呢?代码如下:
package com.dexshell.protect;

import cn.banny.auxiliary.Inspector;
import cn.banny.emulator.Module;
import cn.banny.emulator.Symbol;
import cn.banny.emulator.arm.ARMEmulator;
import cn.banny.emulator.file.FileIO;
import cn.banny.emulator.file.IOResolver;
import cn.banny.emulator.linux.android.AndroidARMEmulator;
import cn.banny.emulator.linux.android.AndroidResolver;
import cn.banny.emulator.linux.android.dvm.*;
import cn.banny.emulator.memory.Memory;

import java.io.File;
import java.io.IOException;

public class DexShellUtil extends AbstractJni implements IOResolver {

private static final String APP_PACKAGE_NAME = "com.zz.yzzj.aligames";

private final ARMEmulator emulator;
private final VM vm;


private static final String APK_PATH = "src/test/resources/app/yzzj.apk";

private final Module module;

private final DvmClass DexShell;

private DexShellUtil() throws IOException {
	emulator = new AndroidARMEmulator(APP_PACKAGE_NAME);
    emulator.getSyscallHandler().addIOResolver(this);
    System.out.println("== init ===");

    final Memory memory = emulator.getMemory();
    memory.setLibraryResolver(new AndroidResolver(19));
    memory.setCallInitFunction();

    vm = emulator.createDalvikVM(new File(APK_PATH));
    vm.setJni(this);
    DalvikModule dm = vm.loadLibrary("dexshell", false);
    dm.callJNI_OnLoad(emulator);
    module = dm.getModule();

    DexShell = vm.resolveClass("com/dexshell/protect/DexShell");
    
}

private void destroy() throws IOException {
	emulator.close();
    System.out.println("module=" + module);
    System.out.println("== destroy ===");
}

public static void main(String[] args) throws Exception {
	DexShellUtil test = new DexShellUtil();

    test.Decrypt();

    test.destroy();
}

private void Decrypt() throws IOException {
	
	Symbol aeskey = module.findSymbolByName("aes_key");
	System.out.println("aeskey address = " + aeskey.getAddress());
	System.out.println("base address = " + module.base);
	Inspector.inspect(aeskey.createPointer(emulator).getByteArray(0, 32), "aes_key");
	
	byte[] aes_key = aeskey.createPointer(emulator).getByteArray(0, 32);

	ByteArray result = new ByteArray(new byte[128]);
	
	
	Symbol AES_set_decrypt_key = module.findSymbolByName("AES_set_decrypt_key");
    System.out.println("address = " + AES_set_decrypt_key.getAddress());
    System.out.println("base = " + module.base);
    Number ret = module.callFunction(emulator, AES_set_decrypt_key.getAddress(), aes_key, 128, vm.addLocalObject(result))[0];
    
    Inspector.inspect(result.getValue(), "AES_set_decrypt_key ret=" + ret);


}

@Override
public FileIO resolve(File workDir, String pathname, int oflags) {
    return null;
}

}
测试的apk的链接是http://www.9game.cn/game/downs_530641_2.html
麻烦看看这个问题。谢谢!

java.lang.UnsatisfiedLinkError: Unable to load library 'capstone'

设置-Djava.library.path=prebuilt/osx64
执行报错:
Exception in thread "main" java.lang.UnsatisfiedLinkError: Unable to load library 'capstone': Native library (darwin/libcapstone.dylib) not found in resource path ([file:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/charsets.jar, file:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/deploy.jar, file:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/ext/cldrdata.jar, file:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/ext/dnsns.jar, file:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/ext/jaccess.jar, file:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/ext/jfxrt.jar, file:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/ext/localedata.jar, file:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/ext/nashorn.jar, file:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/ext/sunec.jar, file:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/ext/sunjce_provider.jar, file:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/ext/sunpkcs11.jar, file:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/ext/zipfs.jar, file:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/javaws.jar, file:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/jce.jar, file:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/jfr.jar, file:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/jfxswt.jar, file:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/jsse.jar, file:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/management-agent.jar, file:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/plugin.jar, file:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/resources.jar, file:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/rt.jar, file:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/lib/ant-javafx.jar, file:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/lib/dt.jar, file:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/lib/javafx-mx.jar, file:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/lib/jconsole.jar, file:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/lib/packager.jar, file:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/lib/sa-jdi.jar, file:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/lib/tools.jar, file:/Users/chengwei/workspace/java/unidbg_bak/target/test-classes/, file:/Users/chengwei/workspace/java/unidbg_bak/target/classes/, file:/Users/chengwei/.m2/repository/org/unicorn-engine/unicorn/1.0.1/unicorn-1.0.1.jar, file:/Users/chengwei/.m2/repository/org/capstone-engine/capstone/3.0.5/capstone-3.0.5.jar, file:/Users/chengwei/.m2/repository/keystone/java-bindings/0.9.1-2/java-bindings-0.9.1-2.jar, file:/Users/chengwei/.m2/repository/net/java/dev/jna/jna-platform/4.5.1/jna-platform-4.5.1.jar, file:/Users/chengwei/.m2/repository/cn/banny/utils/0.0.8/utils-0.0.8.jar, file:/Users/chengwei/.m2/repository/net/java/dev/jna/jna/4.5.2/jna-4.5.2.jar, file:/Users/chengwei/.m2/repository/commons-io/commons-io/2.4/commons-io-2.4.jar, file:/Users/chengwei/.m2/repository/commons-logging/commons-logging/1.1.3/commons-logging-1.1.3.jar, file:/Users/chengwei/.m2/repository/net/dongliu/apk-parser/2.6.4/apk-parser-2.6.4.jar, file:/Users/chengwei/.m2/repository/io/kaitai/kaitai-struct-runtime/0.8/kaitai-struct-runtime-0.8.jar, file:/Users/chengwei/.m2/repository/log4j/log4j/1.2.17/log4j-1.2.17.jar, file:/Users/chengwei/.m2/repository/junit/junit/3.8.2/junit-3.8.2.jar, file:/Users/chengwei/.m2/repository/commons-codec/commons-codec/1.11/commons-codec-1.11.jar])
at com.sun.jna.NativeLibrary.loadLibrary(NativeLibrary.java:303)
at com.sun.jna.NativeLibrary.getInstance(NativeLibrary.java:427)
at com.sun.jna.Library$Handler.(Library.java:179)
at com.sun.jna.Native.loadLibrary(Native.java:569)
at com.sun.jna.Native.loadLibrary(Native.java:544)
at capstone.Capstone.(Capstone.java:438)
at cn.banny.unidbg.arm.AbstractARMEmulator.(AbstractARMEmulator.java:70)
at cn.banny.unidbg.linux.android.AndroidARMEmulator.(AndroidARMEmulator.java:38)
at com.meituan.android.common.candy.CandyJni.createARMEmulator(CandyJni.java:41)
at com.meituan.android.common.candy.CandyJni.(CandyJni.java:55)
at com.meituan.android.common.candy.CandyJni.main(CandyJni.java:81)

jni的一部分方法可以调用,一部分调用失败

public class EncryptionJni extends AbstractJni implements IOResolver {
private static final String APP_PACKAGE_NAME = "com.sankuai.meituan.takeoutnew";

private static LibraryResolver createLibraryResolver() {
return new AndroidResolver(19);
}

private static ARMEmulator createARMEmulator() {
return new AndroidARMEmulator(APP_PACKAGE_NAME);
}

private final ARMEmulator emulator;
private final VM vm;

private final DvmClass clazz;

private static final String INSTALL_PATH = "/data/app/com.sankuai.meituan.takeoutnew-1.apk";
private static final String APK_PATH = "src/main/resources/app/7.8.4.70804.apk";

private final Module module;

public EncryptionJni() throws IOException {
emulator = createARMEmulator();
emulator.getSyscallHandler().addIOResolver(this);
System.out.println("== init ===");

final Memory memory = emulator.getMemory();
memory.setLibraryResolver(createLibraryResolver());
memory.setCallInitFunction();

vm = emulator.createDalvikVM(new File(APK_PATH));
DalvikModule dm = vm.loadLibrary("mtguard", false);
Logger.getLogger("cn.banny.unidbg.AbstractEmulator").setLevel(Level.ERROR);
dm.callJNI_OnLoad(emulator);
module = dm.getModule();

clazz = vm.resolveClass("com.meituan.android.common.encryption.EncryptionJni".replace(".", "/"));

memory.runLastThread(TimeUnit.SECONDS.toMicros(10));

}

private void destroy() throws IOException {
emulator.close();
System.out.println("module=" + module);
System.out.println("== destroy ===");
}

public static void main(String[] args) throws Exception {
EncryptionJni encryptionJni = new EncryptionJni();
String readString = "FHVl2ldQ8PhMY5elqWg+4Z/T8e1mq7zSaLP0sIJIieUfTAkx+0MktwQrw4/g1Tslxi+XgmK8lP7x" +
"PF9d8EVHfIHkmoQZDpA2msU5YW49HHppoyj8BocOqxmCGcIKEYgBv+GEWiRVpc8cbwPyNoRvog==";
byte[] decryptAES = encryptionJni.encyptDataAES2(java.util.Base64.getDecoder().decode(readString), "aesKey".getBytes(), 0);
System.out.println(new String(decryptAES, Charset.forName("UTF-8")));
}

public byte[] encyptDataAES2(byte[] bArr, byte[] bArr2, int i) {

DvmObject context = vm.resolveClass("android/content/Context").newObject(null);
long start = System.currentTimeMillis();
Number ret = clazz.callStaticJniMethod(emulator, "encyptDataAES2(Ljava/lang/Object;[B[BI)[B",
        context,
        vm.addLocalObject(new ByteArray(bArr)),
        vm.addLocalObject(new ByteArray(bArr2)),
        i
);
long hash = ret.intValue() & 0xffffffffL;
ByteArray obj = vm.getObject(hash);
vm.deleteLocalRefs();
Inspector.inspect(Base64.decodeBase64(obj.getValue()), "encyptDataAES2 = " + new String(obj.getValue()) + ", offset=" + (System.currentTimeMillis() - start) + "ms");

try {
    destroy();
} catch (IOException e) {
    e.printStackTrace();
}
return obj.getValue();

}

@OverRide
public FileIO resolve(File workDir, String pathname, int oflags) {
if ("/proc/self/cmdline".equals(pathname)) {
return new ByteArrayFileIO(oflags, pathname, APP_PACKAGE_NAME.getBytes());
}
if (INSTALL_PATH.equals(pathname)) {
return new SimpleFileIO(oflags, new File(APK_PATH), pathname);
}
if ("/data/misc/zoneinfo/tzdata".equals(pathname)) {
return new SimpleFileIO(oflags, new File("src/main/resources/android/sdk19/system/usr/share/zoneinfo/tzdata"), pathname);
}
return null;
}
@OverRide
public DvmObject callObjectMethod(BaseVM vm, DvmObject dvmObject, String signature, VarArg varArg) {
if ("android/content/Context->getPackageCodePath()Ljava/lang/String;".equals(signature)) {
return new StringObject(vm, INSTALL_PATH);
}

return super.callObjectMethod(vm, dvmObject, signature, varArg);

}

出现Exception in thread "main" java.lang.NullPointerException
at com.meituan.android.common.encryption.EncryptionJni.encyptDataAES2(EncryptionJni.java:98)
at com.meituan.android.common.encryption.EncryptionJni.main(EncryptionJni.java:80)

再现UC_ERR_WRITE_UNMAPPED错误

在另一个项目中,导入so后执行,会出现

emulate:unicorn@0x4059b68d[libc.so]0x1668d started sp=unicorn@0xbffff7d4, timeout:3600000000
emulate RuntimeException:unicorn@0x4059b68d[libc.so]0x1668d started sp=unicorn@0xbffff710
[15:25:12 392] WARN [cn.banny.unidbg.AbstractEmulator] (AbstractEmulator:274) - emulate unicorn@0x4059b68d[libc.so]0x1668d failed: sp=unicorn@0xbffff710, offset=36ms
unicorn.UnicornException: Invalid memory write (UC_ERR_WRITE_UNMAPPED)
at unicorn.Unicorn.emu_start(Native Method)
at cn.banny.unidbg.AbstractEmulator.emulate(AbstractEmulator.java:269)
at cn.banny.unidbg.AbstractEmulator.eFunc(AbstractEmulator.java:363)
at cn.banny.unidbg.arm.AbstractARMEmulator.eInit(AbstractARMEmulator.java:213)
at cn.banny.unidbg.linux.AbsoluteInitFunction.call(AbsoluteInitFunction.java:33)
at cn.banny.unidbg.linux.LinuxModule.callInitFunction(LinuxModule.java:46)
at cn.banny.unidbg.linux.AndroidElfLoader.loadInternal(AndroidElfLoader.java:171)
at cn.banny.unidbg.linux.AndroidElfLoader.loadInternal(AndroidElfLoader.java:30)
at cn.banny.unidbg.spi.AbstractLoader.load(AbstractLoader.java:211)
at cn.banny.unidbg.linux.android.dvm.BaseVM.loadLibrary(BaseVM.java:254)
at com.zyqb.ZyqbEncrypt.(ZyqbEncrypt.java:38)
at com.zyqb.ZyqbEncrypt.main(ZyqbEncrypt.java:51)
emulate:unicorn@0x4003276b[libcsiipowerenter.so]0x3276b started sp=unicorn@0xbffff7d4, timeout:3600000000
emulate RuntimeException:unicorn@0x4003276b[libcsiipowerenter.so]0x3276b started sp=unicorn@0xbffff7d4
[15:25:12 400] WARN [cn.banny.unidbg.AbstractEmulator] (AbstractEmulator:284) - emulate unicorn@0x4003276b[libcsiipowerenter.so]0x3276b exception sp=unicorn@0xbffff7d4, msg=Invalid
memory read (UC_ERR_READ_UNMAPPED), offset=1ms
MacValue ret:-1
destroy

同样的工程,执行其他的两个so完全没有问题,唯独这个出现这种情况,没有什么思路,这大概又是什么问题呢?

demo.zip

调用JNI函数出现 UC_ERR_FETCH_UNMAPPED

[14:07:15 632]  WARN [cn.banny.unidbg.AbstractEmulator] (AbstractEmulator:281) - emulate unicorn@0x40002909[libmpaas_crypto.so]0x2909 exception sp=unicorn@0xbffff758, msg=Invalid memory fetch (UC_ERR_FETCH_UNMAPPED), offset=109ms
debugger break at: 0x2b0
>>> r0=0xfffe0930 r1=0x3 r2=0xb66, r3=0x0 r4=0xfffe0930 r5=0x2b0 r6=0xbffff780 r7=0xbffff78c r8=0x0 r9=0xfb2c38 r10=0x8048020 fp=0xbffff798 ip=0xfffe04c0 sp=0xbffff758 lr=0x40002a03 pc=0x2b0 cpsr: N=0, Z=0, C=1, V=0, T=0, mode=0b10000
unicorn.UnicornException: Invalid memory read (UC_ERR_READ_UNMAPPED)
	at unicorn.Unicorn.mem_read(Native Method)
	at cn.banny.unidbg.arm.AbstractARMEmulator.disassemble(AbstractARMEmulator.java:175)
	at cn.banny.unidbg.arm.AbstractARMDebugger.disassemble(AbstractARMDebugger.java:250)
	at cn.banny.unidbg.arm.SimpleARMDebugger.loop(SimpleARMDebugger.java:34)
	at cn.banny.unidbg.arm.AbstractARMDebugger.debug(AbstractARMDebugger.java:178)
	at cn.banny.unidbg.AbstractEmulator.emulate(AbstractEmulator.java:282)
	at cn.banny.unidbg.AbstractEmulator.eFunc(AbstractEmulator.java:361)
	at cn.banny.unidbg.arm.AbstractARMEmulator.eFunc(AbstractARMEmulator.java:201)
	at cn.banny.unidbg.linux.LinuxModule.emulateFunction(LinuxModule.java:154)
	at cn.banny.unidbg.linux.android.dvm.DvmObject.callJniMethod(DvmObject.java:48)
	at test.MpaasCryptoClient.encode(MpaasCryptoClient.java:93)
	at test.MpaasCryptoClient.main(MpaasCryptoClient.java:40)

单步调发现是在调用 openssl 的 EC_POINT_mul函数报错的
麻烦作者大神看看什么原因
png

issue.zip

调用快手so时报错 Invalid memory fetch (UC_ERR_FETCH_UNMAPPED)

你好,我觉得CandyJni类应该是比较完善可以处理各种so调用的示例,我参照这个类写出了调用快手libcore.so的逻辑,但是运行时出现了错误Invalid memory fetch (UC_ERR_FETCH_UNMAPPED)。
image
下面是我的代码,求教如何解决这个错误?
package com.kuaishou;

import java.io.File;
import java.io.IOException;

import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Hex;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;

import cn.banny.emulator.LibraryResolver;
import cn.banny.emulator.Module;
import cn.banny.emulator.arm.ARMEmulator;
import cn.banny.emulator.file.FileIO;
import cn.banny.emulator.file.IOResolver;
import cn.banny.emulator.linux.android.AndroidARMEmulator;
import cn.banny.emulator.linux.android.AndroidResolver;
import cn.banny.emulator.linux.android.dvm.AbstractJni;
import cn.banny.emulator.linux.android.dvm.ArrayObject;
import cn.banny.emulator.linux.android.dvm.BaseVM;
import cn.banny.emulator.linux.android.dvm.ByteArray;
import cn.banny.emulator.linux.android.dvm.DalvikModule;
import cn.banny.emulator.linux.android.dvm.DvmClass;
import cn.banny.emulator.linux.android.dvm.DvmObject;
import cn.banny.emulator.linux.android.dvm.StringObject;
import cn.banny.emulator.linux.android.dvm.VM;
import cn.banny.emulator.linux.android.dvm.VarArg;
import cn.banny.emulator.linux.file.ByteArrayFileIO;
import cn.banny.emulator.linux.file.SimpleFileIO;
import cn.banny.emulator.memory.Memory;

public class KuaishouSign extends AbstractJni implements IOResolver {

private static final String APP_PACKAGE_NAME = "com.smile.gifmaker";

private static LibraryResolver createLibraryResolver() {
    return new AndroidResolver(23);
}

private static ARMEmulator createARMEmulator() {
    return new AndroidARMEmulator(APP_PACKAGE_NAME);
}

private final ARMEmulator emulator;
private final VM vm;

private final DvmClass CPUJni;

private static final String INSTALL_PATH = "/data/app/kuaishou.apk";
private static final String APK_PATH = "src/test/resources/app/kuaishou6.2.3.8614.apk";

private final Module module;

private KuaishouSign() throws IOException {
    emulator = createARMEmulator();
    emulator.getSyscallHandler().addIOResolver(this);
    System.out.println("== init ===");

    final Memory memory = emulator.getMemory();
    memory.setLibraryResolver(createLibraryResolver());
    memory.setCallInitFunction();

    vm = emulator.createDalvikVM(new File(APK_PATH));
    DalvikModule dm = vm.loadLibrary("core", false);
    dm.callJNI_OnLoad(emulator);
    module = dm.getModule();

    CPUJni = vm.resolveClass("com/yxcorp/gifshow/util/CPU");

    // memory.runLastThread();

    try {
        this.signature = Hex.decodeHex("3082027f308201e8a00302010202044d691bb8300d06092a864886f70d0101050500308182310b300906035504061302434e3110300e060355040813074265696a696e673110300e060355040713074265696a696e6731243022060355040a131b53616e6b75616920546563686e6f6c6f677920436f2e204c74642e31143012060355040b130b6d65697475616e2e636f6d311330110603550403130a4348454e204c69616e673020170d3131303232363135323634385a180f32313131303230323135323634385a308182310b300906035504061302434e3110300e060355040813074265696a696e673110300e060355040713074265696a696e6731243022060355040a131b53616e6b75616920546563686e6f6c6f677920436f2e204c74642e31143012060355040b130b6d65697475616e2e636f6d311330110603550403130a4348454e204c69616e6730819f300d06092a864886f70d010101050003818d0030818902818100ba09b72ceec15a04d9b91d66ba2226b50254e78e3d59f67e6f61f042c647f017ebc87999548a244d4059d1d8724e79f71cef456f71ac06e3ec128964746e6f140b75a23841fa1bae3690dcdab0cf46fb54b5e6af4b61a1777523f8190137d18dd3572f49dca940f6ad2b59d8e7c39ab6284a937be31ba4f920bfa99b31496d750203010001300d06092a864886f70d01010505000381810048a9df9ea307bacbf3214317d03e6a658a34d53a14cfdaa71ab5c05ce9204131ebed264005bcc42bc2c0c86e8f8e00594099f6ef62394dee051a712006fdeedfe17255d38280158d9a1b8d4056cc3dab49d9821b9d7a15c1d79237a0112cc80f3d86f444779fde38f7430d0f0c6bb5fba307eafc1e601c43c0222fdd00ad22f8".toCharArray());
    } catch (DecoderException e) {
        throw new IllegalStateException(e);
    }
}

private void destroy() throws IOException {
    emulator.close();
    System.out.println("module=" + module);
    System.out.println("== destroy ===");
}

public static void main(String[] args) throws Exception {
    KuaishouSign test = new KuaishouSign();
    test.sign();
    test.destroy();
}

private final byte[] signature;

private void sign() {
    vm.setJni(this);
    Logger.getLogger("cn.banny.emulator.AbstractEmulator").setLevel(Level.DEBUG);
    String str = "app=0appver=6.2.3.8614c=ALI_CPD,17client_key=3c2cd3f3contactData=7A9IqsDstz815+zxGyC1+XgougsArgtFUPBRYcRwUhcjwTsafJBmYnLZgLc5l4g7sjINLj0nrXFq1CCsFHteQSpac+959kD0yYEJyGzukSqMQGayQCue397jX98gp0NPU26waWGh+JWMaYnZG/F1Sg==country_code=CNdid=ANDROID_9fb7792f6142ea63did_gt=1553767215144ftt=hotfix_ver=isp=iuid=iv=5okP62w8Yl7WHiG6kpf=ANDROID_PHONEkpn=KUAISHOUlanguage=zh-cnlat=40.054041lon=116.298517max_memory=192mod=LGE(Nexus 5)net=WIFIoc=ALI_CPD,17os=androidsys=ANDROID_6.0.1token=f68245ccc1344489894f963248cc3501-1082592150ud=1082592150ver=6.2";

    DvmObject context = vm.resolveClass("android/content/Context").newObject(null);
    long start = System.currentTimeMillis();
    Number ret = CPUJni.callStaticJniMethod(emulator, "getClock(Ljava/lang/Object;[BI)Ljava/lang/String;",
            context,
            vm.addLocalObject(new ByteArray(str.getBytes())), 23);
    long hash = ret.intValue() & 0xffffffffL;
    StringObject obj = vm.getObject(hash);
    vm.deleteLocalRefs();
    System.out.println(obj.getValue());
}

@Override
public FileIO resolve(File workDir, String pathname, int oflags) {
    if ("/proc/self/cmdline".equals(pathname)) {
        return new ByteArrayFileIO(oflags, pathname, APP_PACKAGE_NAME.getBytes());
    }
    if (INSTALL_PATH.equals(pathname)) {
        return new SimpleFileIO(oflags, new File(APK_PATH), pathname);
    }
    if ("/data/misc/zoneinfo/tzdata".equals(pathname)) {
        return new SimpleFileIO(oflags, new File("src/main/resources/android/sdk19/system/usr/share/zoneinfo/tzdata"), pathname);
    }
    return null;
}

@Override
public DvmObject callObjectMethod(BaseVM vm, DvmObject dvmObject, String signature, String methodName, String args, VarArg varArg) {
    switch (signature) {
        case "android/content/Context->getPackageManager()Landroid/content/pm/PackageManager;":
            return new DvmObject<Object>(vm.resolveClass("android/content/pm/PackageManager"), null);
        case "android/content/Context->getPackageName()Ljava/lang/String;":
            return new StringObject(vm, APP_PACKAGE_NAME);
        case "android/content/pm/PackageManager->getPackageInfo(Ljava/lang/String;I)Landroid/content/pm/PackageInfo;":
            StringObject packageName = varArg.getObject(0);
            int flags = varArg.getInt(1);
            System.err.println("getPackageInfo packageName=" + packageName.getValue() + ", flags=" + flags);
            return vm.resolveClass("android/content/pm/PackageInfo").newObject(packageName.getValue());
        case "android/content/Context->getPackageCodePath()Ljava/lang/String;":
            return new StringObject(vm, INSTALL_PATH);
        case "android/content/pm/Signature->toByteArray()[B":
            return new ByteArray(this.signature);
    }

    return super.callObjectMethod(vm, dvmObject, signature, methodName, args, varArg);
}

@Override
public DvmObject getObjectField(VM vm, DvmObject dvmObject, String signature) {
    if ("android/content/pm/PackageInfo->signatures:[Landroid/content/pm/Signature;".equals(signature)) {
        String packageName = (String) dvmObject.getValue();
        System.err.println("PackageInfo signatures packageName=" + packageName);
        DvmObject sig = vm.resolveClass("android/content/pm/Signature").newObject(null);
        return new ArrayObject(sig);
    }

    return super.getObjectField(vm, dvmObject, signature);
}

}

如何给jni传递bitmap对象?

我要调用一个so内的方法,参数中有一个bitmap对象
但是java中似乎没有createBitmap的方法。有没有办法自定义传递这样的参数过去?

当我测试抖音时报错

在我测试抖音时,遇到如下崩溃日志:
getString pointer=unicorn@0xbfffe22c, size=14, encoding=UTF-8, ret=/system/bin/su
fstatat64 dirfd=-100, pathname=\system\bin\su, statbuf=unicorn@0xbfffe1c4, flags=0
[21:42:48 095] WARN [cn.banny.unidbg.linux.ARMSyscallHandler] (ARMSyscallHandler:1446) - fstatat64 dirfd=-100, pathname=\system\bin\su, statbuf=unicorn@0xbfffe1c4, flags=0
memory failed: address=0x0, size=1, value=0x0, user=null
unicorn.UnicornException: Invalid memory read (UC_ERR_READ_UNMAPPED)
at unicorn.Unicorn.emu_start(Native Method)
at cn.banny.unidbg.AbstractEmulator.emulate(AbstractEmulator.java:237)
at cn.banny.unidbg.AbstractEmulator.eFunc(AbstractEmulator.java:328)
at cn.banny.unidbg.arm.AbstractARMEmulator.eFunc(AbstractARMEmulator.java:201)
at cn.banny.unidbg.linux.LinuxModule.emulateFunction(LinuxModule.java:154)
at cn.banny.unidbg.linux.android.dvm.DvmClass.callStaticJniMethod(DvmClass.java:141)
at com.bytedance.frameworks.core.encrypt.cms.sign(cms.java:108)
at com.bytedance.frameworks.core.encrypt.cms.main(cms.java:96)
debugger break at: 0x40012a54

r0=0x0 r1=0x414e1111 r2=0x574598f8, r3=0x0 r4=0xf72315d4 r5=0x18353522 r6=0x574598f7 r7=0xd7977dd5 sb=0x61cad990 sl=0x414e1112 fp=0x1 ip=0x0 sp=0xbfffe160 lr=0x61cad990 pc=0x40012a54 cpsr: N=0, Z=1, C=1, V=0, T=1, mode=0b10000
=> [ libcms.so][0x12a55][ 01 9b ]*0x40012a54:*ldr r3, [sp, #4]
[ libcms.so] [0x12a57] [ 03 93 ] 0x40012a56: str r3, [sp, #0xc]
[ libcms.so] [0x12a59] [ 03 9b ] 0x40012a58: ldr r3, [sp, #0xc]
[ libcms.so] [0x12a5b] [ 1b 78 ] 0x40012a5a: ldrb r3, [r3]
[ libcms.so] [0x12a5d] [ 00 2b ] 0x40012a5c: cmp r3, #0
[ libcms.so] [0x12a5f] [ 23 46 ] 0x40012a5e: mov r3, r4
[ libcms.so] [0x12a61] [ 04 bf ] 0x40012a60: itt eq
[ libcms.so] [0x12a63] [ 43 f2 22 53 ] 0x40012a62: movweq r3, #0x3522
[ libcms.so] [0x12a67] [ c1 f6 35 03 ] 0x40012a66: movteq r3, #0x1835
[ libcms.so] [0x12a6b] [ 21 e0 ] 0x40012a6a: b #0x40012ab0

我的测试代码如下:
package com.bytedance.frameworks.core.encrypt;

import cn.banny.auxiliary.Inspector;
import cn.banny.unidbg.LibraryResolver;
import cn.banny.unidbg.Module;
import cn.banny.unidbg.arm.ARMEmulator;
import cn.banny.unidbg.linux.android.AndroidARMEmulator;
import cn.banny.unidbg.linux.android.AndroidResolver;
import cn.banny.unidbg.linux.android.dvm.DalvikModule;
import cn.banny.unidbg.linux.android.dvm.DvmClass;
import cn.banny.unidbg.linux.android.dvm.VM;
import cn.banny.unidbg.memory.Memory;

import java.io.File;
import java.io.IOException;

import cn.banny.unidbg.file.FileIO;
import cn.banny.unidbg.file.IOResolver;

import cn.banny.unidbg.linux.android.dvm.*;
import cn.banny.unidbg.linux.android.dvm.api.SystemService;
import cn.banny.unidbg.linux.file.ByteArrayFileIO;
import cn.banny.unidbg.linux.file.SimpleFileIO;

import org.apache.log4j.Level;
import org.apache.log4j.Logger;

import java.io.;
import java.net.
;

public class cms extends AbstractJni implements IOResolver {

private static final int WSG_CODE_OK = 0;

private static final String APP_PACKAGE_NAME = "com.ss.android.ugc.aweme";

private final ARMEmulator emulator;
private final VM vm;
private final DvmClass cmsDVM;
private final DvmClass userinfoDVM;
private final DvmClass tongdunDVM;

private static final String APK_PATH = "src/test/resources/app/660.apk";

private final Module module;

private cms() throws IOException {
    Logger.getLogger("cn.banny.unidbg.AbstractEmulator").setLevel(Level.DEBUG);
    emulator = new AndroidARMEmulator(APP_PACKAGE_NAME);
    emulator.getSyscallHandler().addIOResolver(this);
    System.out.println("== init ===");

    final Memory memory = emulator.getMemory();
    memory.setLibraryResolver(new AndroidResolver(23));
    memory.setCallInitFunction();

    vm = emulator.createDalvikVM(new File(APK_PATH));


    vm.setJni(this);
    DalvikModule dm = vm.loadLibrary("cms", false);

    dm.callJNI_OnLoad(emulator);
    module = dm.getModule();

    cmsDVM = vm.resolveClass("com/ss/sys/ces/a");
    userinfoDVM = vm.resolveClass("com/ss/android/common/applog/UserInfo");
    tongdunDVM = vm.resolveClass("com/ss/sys/secuni/b/c");

// IHookZz hookZz = HookZz.getInstance(emulator);
// hookZz.replace(module.base + 0x000733A0 + 1, new ReplaceCallback() {
// @OverRide
// public HookStatus onCall(Emulator emulator, long originFunction) {
// long currentTimeMillis = System.currentTimeMillis();
// EditableArm32RegisterContext context = emulator.getContext();
// context.setR1((int) currentTimeMillis);
// return HookStatus.LR(emulator, (int) (currentTimeMillis >> 32));
// }
// });

// emulator.attach().debug(emulator);
}

private void destroy() throws IOException {
    emulator.close();
    System.out.println("module=" + module);
    System.out.println("== destroy ===");
}

public static void main(String[] args) throws Exception {
    cms test = new cms();
    test.sign();
    test.destroy();
}

private void sign() {

    userinfoDVM.callStaticJniMethod(emulator, "setAppId(I)V", 1128);
    Number i = userinfoDVM.callStaticJniMethod(emulator, "initUser(Ljava/lang/String;)I", vm.addLocalObject(new StringObject(vm, "a3668f0afac72ca3f6c1697d29e0e1bb1fef4ab0285319b95ac39fa42c38d05f")));
    System.out.println("initUser ret: " + i.intValue());

// Number ret = cmsDVM.callStaticJniMethod(emulator, "e([B)[B",
// vm.addLocalObject(new ByteArray("888888888".getBytes())));
DvmObject context = vm.resolveClass("android/content/Context").newObject(null);
Number ret = tongdunDVM.callStaticJniMethod(emulator, "n0(Landroid/content/Context;)[B", vm.addLocalObject(context));
long hash = ret.intValue() & 0xffffffffL;
ByteArray array = vm.getObject(hash);

    Inspector.inspect(array.getValue(), "n0 ret=" + ret + ", offset=" + (System.currentTimeMillis()) + "ms");
    vm.deleteLocalRefs();
}

private static final String INSTALL_PATH = "/data/app/com.ss.android.ugc.aweme-1.apk";

@Override
public FileIO resolve(File workDir, String pathname, int oflags) {
    System.out.println("pathname: " + pathname);
    //System.out.println("workdir: " + workDir.getAbsolutePath());
    if (("proc/" + emulator.getPid() + "/status").equals(pathname)) {
        return new ByteArrayFileIO(oflags, pathname, "TracerPid:\t0\n".getBytes());
    }
    else if("/proc/meminfo".equals(pathname))
    {
        return new SimpleFileIO(oflags, new File("src/main/resources/meminfo"), pathname);
    }
    else if("/proc/self/status".equals(pathname))
    {
        return new ByteArrayFileIO(oflags, pathname, "TracerPid:\t0\n".getBytes());
    }

    return null;
}

@Override
public DvmObject callStaticObjectMethod(BaseVM vm, DvmClass dvmClass, String signature, VarArg varArg) {
    if ("java/lang/System->getProperty(Ljava/lang/String;)Ljava/lang/String;".equals(signature)) {
        StringObject string = varArg.getObject(0);
        return new StringObject(vm, System.getProperty(string.getValue()));
    }

    return super.callStaticObjectMethod(vm, dvmClass, signature, varArg);
}

public DvmObject callObjectMethodV(BaseVM vm, DvmObject dvmObject, String signature, VaList vaList) {
    System.out.println("CallObjectMethodV       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~: " + signature);
    if ("Landroid/app/Application->getPackageManager()Landroid/content/pm/PackageManager;".equals(signature)) {
        return vm.resolveClass("Landroid/content/pm/PackageManager;").newObject(null);
    }
    else if ("java/lang/String->getBytes(Ljava/lang/String;)[B".equals(signature)) {
        StringObject string = (StringObject) dvmObject;
        StringObject encoding = vaList.getObject(0);
        System.err.println("string=" + string.getValue() + ", encoding=" + encoding.getValue());
        try {
            return new ByteArray(string.getValue().getBytes(encoding.getValue()));
        } catch (UnsupportedEncodingException e) {
            throw new IllegalStateException(e);
        }
    } else if ("android/content/Context->getFilesDir()Ljava/io/File;".equals(signature)) {
        return vm.resolveClass("Ljava/io/File;").newObject(null);
    } else if ("Ljava/io/File;->getAbsolutePath()Ljava/lang/String;".equals(signature)) {
        return new StringObject(vm, "/data/data/com.ss.android.ugc.aweme/files");
    }else if ("android/telephony/TelephonyManager->getDeviceId()Ljava/lang/String;".equals(signature))
    {
        return new StringObject(vm, "123456789123456");
    }
    else if ("android/content/Context->getContentResolver()Landroid/content/ContentResolver;".equals(signature))
    {
        return vm.resolveClass("android/content/ContentResolver").newObject(null);
    }
    else if ("android/content/ContentResolver->call(Landroid/net/Uri;Ljava/lang/String;Ljava/lang/String;Landroid/os/Bundle;)Landroid/os/Bundle;".equals(signature))
    {
        return vm.resolveClass("android/os/Bundle").newObject(null);
    }
    else if ("android/os/Bundle->getString(Ljava/lang/String;)Ljava/lang/String;".equals(signature))
    {
        return new StringObject(vm, "112233448855");
    }
    else if ("android/content/Context->getPackageManager()Landroid/content/pm/PackageManager;".equals(signature))
    {
        return vm.resolveClass("android/content/pm/PackageManager").newObject(null);
    }
    else if ("android/content/Context->getPackageName()Ljava/lang/String;".equals(signature))
    {
        return new StringObject(vm, "com.ss.android.ugc.aweme");
    }
    else {
        StringObject serviceName = vaList.getObject(0);
        return new SystemService(vm, serviceName.getValue());
    }

}

public int getStaticIntField(BaseVM vm, DvmClass dvmClass, String signature) {
    if ("android/os/Build$VERSION->SDK_INT:I".equals(signature)) {
        return 21;
    }
    return -1;
}

public DvmObject getObjectField(BaseVM vm, DvmObject dvmObject, String signature) {
    if ("Landroid/content/pm/ApplicationInfo;->sourceDir:Ljava/lang/String;".equals(signature)) {
        return new StringObject(vm, APK_PATH);
    }
    return null;
}

public int callIntMethodV(BaseVM vm, DvmObject dvmObject, String signature, VaList vaList) {
    if ("android/content/Context->checkSelfPermission(Ljava/lang/String;)I".equals(signature)) {
        System.out.println("checkSelfPermission: " + vaList.getObject(0));
        return 0;
    }
    return 0;
}

public DvmObject callStaticObjectMethodV(BaseVM vm, DvmClass dvmClass, String signature, VaList vaList) {
    if ("java/security/cert/CertificateFactory->getInstance(Ljava/lang/String;)Ljava/security/cert/CertificateFactory;".equals(signature)) {

        return vm.resolveClass("java/security/cert/CertificateFactory").newObject(null);
    } else if ("java/security/cert/CertificateFactory->generateCertificate(Ljava/io/InputStream;)Ljava/security/cert/Certificate".equals(signature)) {
        return vm.resolveClass("java/security/cert/Certificate").newObject(null);
    } else if ("android/net/Uri->parse(Ljava/lang/String;)Landroid/net/Uri;".equals(signature)) {
        return vm.resolveClass("android/net/Uri").newObject(null);
    }

    return null;
}

public boolean callStaticBooleanMethodV(BaseVM vm, DvmClass dvmClass, String signature, VaList vaList) {
    if (signature.equals("android/os/Debug->isDebuggerConnected()Z"))
        return false;
    return false;
}

public DvmObject newObjectV(BaseVM vm, DvmClass dvmClass, String signature, VaList vaList) {
    switch (signature) {
        case "java/io/ByteArrayInputStream-><init>([B)V": {
            return vm.resolveClass("java/io/ByteArrayInputStream").newObject(vaList);
        }
    }
    return null;
}


@Override
public DvmObject callObjectMethod(BaseVM vm, DvmObject dvmObject, String signature, VarArg varArg) {
    System.out.println("signature: " + signature);
    switch (signature) {
        case "android/content/Context->getSharedPreferences(Ljava/lang/String;I)Landroid/content/SharedPreferences;":
            return vm.resolveClass("android/content/SharedPreferences").newObject(null);
        case "android/content/SharedPreferences->getString(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;": {
            StringObject name = varArg.getObject(0);
            StringObject defValue = varArg.getObject(1);
            System.err.println("android/content/SharedPreferences->getString name=" + name.getValue() + ", defValue=" + defValue.getValue());
            if ("wsg_conf".equals(name.getValue())) {
                return new StringObject(vm, "mZUzsjDkxAqS/YFujbRrX3j/7jhZYgh8GHHqMzMdK9hXjXJ0lBEDsIFuKTfF48ps5gvaplUOkcmLNP5/FEmaqO4oUAad1HzDTQBZobDMeFpub20K+axGeu7PBZ+TztfPdVpMgVfmuHc7/axEHlZFBxadprthaQQtBfjzn2pf7Bp3RcreGaqnfO+QwENoQnpVo8Jj1CFy9vUnD8UDq4nO5S2ivoecc+g1luF9lLs5+4j1uCPK4QjSNhWp2HODbohlx01+uXQpMW1HVc0hjvEk/c8oKxFSJkqo8yZTpJ0Fg4lGc7f8znArzH1X6WanJIfA6O/XR/aUdAoAx9jHcC3QJM2kyM/F/aZB/7I0n5hWWwptaZfWf1nVxQMJrRzZ/X5bPEPCh+1czaeYVwZgEMfgLqo+yfGY8j0exLyd5vQnG4bIAV61X9P03+MXe4M67XmFaS0SsK3PuOYF5ht5I906QqXbcJcjF2YlkvnIC1UAJ70+MSKBLZErujU1GOBnPLLCyBt3PdzBNuwTVchZFPPcKYG7ZR5YEzpTNdxcu06Q8frtapYUus8rS7fHTbvUebdoR3oYDbe6hvzQX9E0Kq2YXOoByfy03I0/hSLW1GP+XYr2UIljf+9DaQxuZ4Qqk3p/PKh1QKlPL+bqC2jZhb1wLP4Vcg+unx/+diKBQsxVdW//J77vfUjj/1icJGrjbxHSUa4PB/YtfMFDfcPUAUOLvRWYyimyE3tvBUUs/RoFKMMFrvrzwIV9B+3oT/L292xdxa4U65DVHR1vULHWgxqW4HXOI9wBxh3GP5F9ZUDAHGjMQqjzaeV/w5LyscAJpsYpCWk9CTI4ixHpk5AvKRNNvq3z/SPZGPy+J0GkUbqT+gTsFyI370Levy3WHXoJxFZ3t2mgsyY1VS8rdbIh8rX5jdq0iGfIVw6D5pqRuhyz5Sgzoc45MJQCcXEniCrr5v4BkAafMybg7uRedFbqza1l1w==");
            }
        }
        case "android/content/Context->getPackageCodePath()Ljava/lang/String;":
            return new StringObject(vm, INSTALL_PATH);
        case "android/content/Context->getSystemService(Ljava/lang/String;)Ljava/lang/Object;":
            StringObject serviceName = varArg.getObject(0);
            System.err.println("android/content/Context->getSystemService name=" + serviceName);
            return new SystemService(vm, serviceName.getValue());
        case "android/telephony/TelephonyManager->getDeviceId()Ljava/lang/String;":
            return new StringObject(vm, "353490069873368");
        case "java/net/URL->openConnection(Ljava/net/Proxy;)Ljava/net/URLConnection;":
            Proxy proxy = (Proxy) varArg.getObject(0).getValue();
            URL url = (URL) dvmObject.getValue();
            try {
                return vm.resolveClass("java/net/HttpURLConnection").newObject(url.openConnection(proxy));
            } catch (IOException e) {
                throw new IllegalStateException(e);
            }
        case "java/net/HttpURLConnection->getOutputStream()Ljava/io/OutputStream;": {
            HttpURLConnection connection = (HttpURLConnection) dvmObject.getValue();
            try {
                return vm.resolveClass("java/io/OutputStream").newObject(connection.getOutputStream());
            } catch (IOException e) {
                throw new IllegalStateException(e);
            }
        }
        case "java/lang/String->getBytes()[B": {
            String str = (String) dvmObject.getValue();
            System.err.println("java/lang/String->getBytes str=" + str);
            return new ByteArray(str.getBytes());
        }
        case "java/net/HttpURLConnection->getInputStream()Ljava/io/InputStream;": {
            HttpURLConnection connection = (HttpURLConnection) dvmObject.getValue();
            try {
                return vm.resolveClass("java/io/InputStream").newObject(connection.getInputStream());
            } catch (IOException e) {
                throw new IllegalStateException(e);
            }
        }
        case "java/io/BufferedReader->readLine()Ljava/lang/String;": {
            BufferedReader reader = (BufferedReader) dvmObject.getValue();
            try {
                String line = reader.readLine();
                if (line != null) {
                    System.err.println("java/io/BufferedReader->readLine " + line);
                }
                return line == null ? null : new StringObject(vm, line);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        case "android/content/SharedPreferences->edit()Landroid/content/SharedPreferences$Editor;": {
            return vm.resolveClass("android/content/SharedPreferences$Editor").newObject(null);
        }
        case "android/content/SharedPreferences$Editor->putString(Ljava/lang/String;Ljava/lang/String;)Landroid/content/SharedPreferences$Editor;": {
            StringObject name = varArg.getObject(0);
            StringObject value = varArg.getObject(1);
            System.err.println("android/content/SharedPreferences$Editor->putString name=" + name.getValue() + ", value=" + value.getValue());
            return dvmObject;
        }
    }
    return super.callObjectMethod(vm, dvmObject, signature, varArg);
}

@Override
public DvmObject newObject(BaseVM vm, DvmClass dvmClass, String signature, VarArg varArg) {
    System.out.println("signature: " + signature);
    switch (signature) {
        case "java/net/URL-><init>(Ljava/lang/String;)V":
            StringObject url = varArg.getObject(0);
            System.err.println("open URL: " + url.getValue());
            try {
                return vm.resolveClass("java/net/URL").newObject(new URL(url.getValue()));
            } catch (MalformedURLException e) {
                throw new IllegalStateException(e);
            }
        case "java/io/InputStreamReader-><init>(Ljava/io/InputStream;)V": {
            InputStream inputStream = (InputStream) varArg.getObject(0).getValue();
            return vm.resolveClass("java/io/InputStreamReader").newObject(new InputStreamReader(inputStream));
        }
        case "java/io/BufferedReader-><init>(Ljava/io/Reader;)V": {
            Reader reader = (Reader) varArg.getObject(0).getValue();
            return vm.resolveClass("java/io/BufferedReader").newObject(new BufferedReader(reader));
        }
    }

    return super.newObject(vm, dvmClass, signature, varArg);
}

@Override
public DvmObject getStaticObjectField(BaseVM vm, DvmClass dvmClass, String signature) {
    System.out.println("signature: " + signature);
    if ("java/net/Proxy->NO_PROXY:Ljava/net/Proxy;".equals(signature)) {
        return vm.resolveClass("java/net/Proxy").newObject(Proxy.NO_PROXY);
    }

    return super.getStaticObjectField(vm, dvmClass, signature);
}

@Override
public void callVoidMethod(BaseVM vm, DvmObject dvmObject, String signature, VarArg varArg) {
    System.out.println("signature: " + signature);
    switch (signature) {
        case "java/net/HttpURLConnection->setRequestMethod(Ljava/lang/String;)V": {
            HttpURLConnection connection = (HttpURLConnection) dvmObject.getValue();
            StringObject method = varArg.getObject(0);
            System.err.println("java/net/HttpURLConnection->setRequestMethod method=" + method.getValue());
            try {
                connection.setRequestMethod(method.getValue());
            } catch (ProtocolException e) {
                throw new IllegalStateException(e);
            }
            return;
        }
        case "java/net/HttpURLConnection->setConnectTimeout(I)V": {
            HttpURLConnection connection = (HttpURLConnection) dvmObject.getValue();
            int timeout = varArg.getInt(0);
            System.err.println("java/net/HttpURLConnection->setConnectTimeout timeout=" + timeout);
            connection.setConnectTimeout(timeout);
            return;
        }
        case "java/net/HttpURLConnection->setRequestProperty(Ljava/lang/String;Ljava/lang/String;)V": {
            HttpURLConnection connection = (HttpURLConnection) dvmObject.getValue();
            StringObject key = varArg.getObject(0);
            StringObject value = varArg.getObject(1);
            System.err.println("java/net/HttpURLConnection->setRequestProperty key=" + key.getValue() + ", value=" + value.getValue());
            connection.setRequestProperty(key.getValue(), value.getValue());
            return;
        }
        case "java/net/HttpURLConnection->setDoOutput(Z)V": {
            HttpURLConnection connection = (HttpURLConnection) dvmObject.getValue();
            int doOutput = varArg.getInt(0);
            System.err.println("java/net/HttpURLConnection->setDoOutput: " + doOutput);
            connection.setDoOutput(doOutput != 0);
            return;
        }
        case "java/io/OutputStream->write([B)V": {
            OutputStream outputStream = (OutputStream) dvmObject.getValue();
            ByteArray array = varArg.getObject(0);
            try {
                outputStream.write(array.getValue());
            } catch (IOException e) {
                throw new IllegalStateException(e);
            }
            return;
        }
        case "java/io/OutputStream->close()V": {
            OutputStream outputStream = (OutputStream) dvmObject.getValue();
            try {
                outputStream.close();
            } catch (IOException e) {
                throw new IllegalStateException(e);
            }
            return;
        }
        case "java/net/HttpURLConnection->connect()V": {
            HttpURLConnection connection = (HttpURLConnection) dvmObject.getValue();
            try {
                connection.connect();
            } catch (IOException e) {
                throw new IllegalStateException(e);
            }
            return;
        }
        case "java/io/InputStream->close()V": {
            InputStream inputStream = (InputStream) dvmObject.getValue();
            try {
                inputStream.close();
                return;
            } catch (IOException e) {
                throw new IllegalStateException(e);
            }
        }
        case "java/io/BufferedReader->close()V": {
            BufferedReader reader = (BufferedReader) dvmObject.getValue();
            try {
                reader.close();
                return;
            } catch (IOException e) {
                throw new IllegalStateException(e);
            }
        }
        case "java/net/HttpURLConnection->disconnect()V": {
            HttpURLConnection connection = (HttpURLConnection) dvmObject.getValue();
            connection.disconnect();
            return;
        }
    }

    super.callVoidMethod(vm, dvmObject, signature, varArg);
}

@Override
public int callIntMethod(BaseVM vm, DvmObject dvmObject, String signature, VarArg varArg) {
    System.out.println("signature: " + signature);
    if ("java/net/HttpURLConnection->getResponseCode()I".equals(signature)) {
        HttpURLConnection connection = (HttpURLConnection) dvmObject.getValue();
        try {
            return connection.getResponseCode();
        } catch (IOException e) {
            throw new IllegalStateException(e);
        }
    }

    return super.callIntMethod(vm, dvmObject, signature, varArg);
}

@Override
public boolean callBooleanMethod(BaseVM vm, DvmObject dvmObject, String signature, VarArg varArg) {
    System.out.println("signature: " + signature);
    if ("android/content/SharedPreferences$Editor->commit()Z".equals(signature)) {
        return true;
    }

    return super.callBooleanMethod(vm, dvmObject, signature, varArg);
}

}

libcms.zip

多线程支持

经过测试,so中pthread_create不执行,有计划解决吗

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.