unidbg icon indicating copy to clipboard operation
unidbg copied to clipboard

尝试模拟运行 libcovault-appsec.so 出现异常错误,Illegal JNI version: 0xffffffff

Open WanghongLin opened this issue 3 years ago • 3 comments

最近分析 Mir4 这个游戏,碰到了另一个 Android app 的保护方案,来自 AppSealing 的 libcovault-appsec.so,这应该是什么原因导致的?JNI_OnLoad 可以执行前面一小部分,后面就出现了这个异常。

遇到的错误如下

[08:54:07 932]  INFO [com.github.unidbg.linux.ARM64SyscallHandler] (ARM64SyscallHandler:1266) - openat dirfd=-100, pathname=/proc/5144/cmdline, oflags=0x0, mode=0
[08:54:07 935]  INFO [com.github.unidbg.linux.ARM64SyscallHandler] (ARM64SyscallHandler:570) - stat64 pathname=/data/local/tmp
[08:54:07 935]  INFO [com.github.unidbg.linux.ARM64SyscallHandler] (ARM64SyscallHandler:570) - stat64 pathname=/data/local
[08:54:08 034]  WARN [com.github.unidbg.AbstractEmulator] (AbstractEmulator:389) - emulate RX@0x40060ae8[libcovault-appsec.so]0x60ae8 exception sp=unidbg@0xbffff340, msg=unicorn.UnicornException: Write to write-protected memory (UC_ERR_WRITE_PROT), offset=5ms
Exception in thread "main" java.lang.IllegalStateException: Illegal JNI version: 0xffffffff
	at com.github.unidbg.linux.android.dvm.BaseVM.checkVersion(BaseVM.java:194)
	at com.github.unidbg.linux.android.dvm.DalvikModule.callJNI_OnLoad(DalvikModule.java:39)
	at com.inka.appsealing.CovaultAppSec.<init>(CovaultAppSec.java:33)
	at com.inka.appsealing.CovaultAppSec.main(CovaultAppSec.java:19)

示例代码

public class CovaultAppSec {

    private AndroidEmulator emulator;
    private VM dalvikVM;

    public static void main(String[] args) {
        CovaultAppSec covaultAppSec = new CovaultAppSec();
        covaultAppSec.destroy();
    }

    public CovaultAppSec() {
        emulator = AndroidEmulatorBuilder.for64Bit()
                .setProcessName("com.wemade.mir4global")
                .setRootDir(new File("target/rootfs")).build();
        emulator.getMemory().setLibraryResolver(new AndroidResolver(23));
        dalvikVM = emulator.createDalvikVM();
        dalvikVM.setVerbose(true);

        new AndroidModule(emulator, dalvikVM).register(emulator.getMemory());
        DalvikModule libraryModule = dalvikVM.loadLibrary(new File("unidbg-android/src/test/resources/example_binaries/arm64-v8a/libcovault-appsec.so"), true);
        libraryModule.callJNI_OnLoad(emulator);
    }

    void destroy() {
        try {
            if (emulator != null) {
                emulator.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

样本示例如下 libcovault-appsec.zip

WanghongLin avatar Sep 02 '21 01:09 WanghongLin

前面的INFO提示的环境要完善

zhkl0228 avatar Sep 02 '21 05:09 zhkl0228

修复了环境提示的问题,依然还有错误,最后一个是 .text 段无法写的错误?该如何解决这种问题?这个 so 用 IDA 静态分析,JNI_OnLoad 不是一个函数,有一些属于不是指令的字节序列。

[16:38:11 162]  WARN [com.github.unidbg.AbstractEmulator] (AbstractEmulator:389) - emulate RX@0x40060ae8[libcovault-appsec.so]0x60ae8 exception sp=unidbg@0xbffff340, msg=unicorn.UnicornException: Write to write-protected memory (UC_ERR_WRITE_PROT), offset=6ms
Exception in thread "main" java.lang.IllegalStateException: Illegal JNI version: 0xffffffff
	at com.github.unidbg.linux.android.dvm.BaseVM.checkVersion(BaseVM.java:194)
	at com.github.unidbg.linux.android.dvm.DalvikModule.callJNI_OnLoad(DalvikModule.java:39)
	at com.inka.appsealing.CovaultAppSec.<init>(CovaultAppSec.java:48)
	at com.inka.appsealing.CovaultAppSec.main(CovaultAppSec.java:24)

WanghongLin avatar Sep 02 '21 08:09 WanghongLin

你好,目标内存不可写,我具体分析了一下,依然没有找到问题的根源,只能提供一种暂缓的办法:在Unidbg的SO加载器逻辑中(src/main/java/com/github/unidbg/linux/AndroidElfLoader.java ),给LOAD segments rwx 权限。

for (int i = 0; i < elfFile.num_ph; i++) {
            ElfSegment ph = elfFile.getProgramHeader(i);
            switch (ph.type) {
                case ElfSegment.PT_LOAD:
                    int prot = get_segment_protection(ph.flags);
//                    if (prot == UnicornConst.UC_PROT_NONE) {
//                        prot = UnicornConst.UC_PROT_ALL;
//                    }
                    //  默认给rwx权限
                    prot = UnicornConst.UC_PROT_ALL;
                    final long begin = load_base + ph.virtual_address;

                    Alignment check = ARM.align(begin, ph.mem_size, Math.max(emulator.getPageAlign(), ph.alignment));
                    final int regionSize = regions.size();
                    MemRegion last = regionSize <= 0 ? null : regions.get(regionSize - 1);
                    MemRegion overall = null;
                    if (last != null && check.address >= last.begin && check.address < last.end) {
                        overall = last;
                    }
                    if (overall != null) {
                        long overallSize = overall.end - check.address;
                        backend.mem_protect(check.address, overallSize, overall.perms | prot);
                        if (ph.mem_size > overallSize) {
                            Alignment alignment = this.mem_map(begin + overallSize, ph.mem_size - overallSize, prot, libraryFile.getName(), Math.max(emulator.getPageAlign(), ph.alignment));
                            regions.add(new MemRegion(alignment.address, alignment.address + alignment.size, prot, libraryFile, ph.virtual_address));
                            if (lastAlignment != null) {
                                throw new UnsupportedOperationException();
                            }
                            lastAlignment = alignment;
                        }

Pr0214 avatar Sep 14 '21 05:09 Pr0214