unidbg
unidbg copied to clipboard
尝试模拟运行 libcovault-appsec.so 出现异常错误,Illegal JNI version: 0xffffffff
最近分析 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
前面的INFO提示的环境要完善
修复了环境提示的问题,依然还有错误,最后一个是 .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)
你好,目标内存不可写,我具体分析了一下,依然没有找到问题的根源,只能提供一种暂缓的办法:在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;
}