Skip to content

Commit

Permalink
Dynarmic continue..........
Browse files Browse the repository at this point in the history
  • Loading branch information
WebDucerBlog committed Oct 12, 2020
1 parent 9fab83f commit be3aea9
Show file tree
Hide file tree
Showing 18 changed files with 133 additions and 39 deletions.
6 changes: 6 additions & 0 deletions unidbg-android/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@
<artifactId>unidbg-api</artifactId>
<version>0.8.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.github.zhkl0228</groupId>
<artifactId>unidbg-dynarmic</artifactId>
<version>0.8.0-SNAPSHOT</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>net.dongliu</groupId>
<artifactId>apk-parser</artifactId>
Expand Down
12 changes: 6 additions & 6 deletions unidbg-android/src/test/java/com/sun/jna/JniDispatch32.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ private static AndroidEmulator createARMEmulator() {
private final AndroidEmulator emulator;
private final Module module;

private final DvmClass Native;
private final DvmClass cNative;

private JniDispatch32() {
emulator = createARMEmulator();
Expand All @@ -51,7 +51,7 @@ private JniDispatch32() {
dm.callJNI_OnLoad(emulator);
module = dm.getModule();

Native = vm.resolveClass("com/sun/jna/Native");
cNative = vm.resolveClass("com/sun/jna/Native");

Symbol __system_property_get = module.findSymbolByName("__system_property_get", true);
MemoryBlock block = memory.malloc(0x10);
Expand Down Expand Up @@ -102,7 +102,7 @@ public HookStatus onCall(Emulator<?> emulator, long originFunction) {

long start = System.currentTimeMillis();
final int size = 0x20;
Number ret = Native.callStaticJniMethodLong(emulator, "malloc(J)J", size);
Number ret = cNative.callStaticJniMethodLong(emulator, "malloc(J)J", size);
Pointer pointer = UnidbgPointer.pointer(emulator, ret.intValue() & 0xffffffffL);
assert pointer != null;
pointer.setString(0, getClass().getName());
Expand All @@ -119,13 +119,13 @@ public void dbiCall(Emulator<?> emulator, RegisterContext ctx, HookEntryInfo inf
}
});

StringObject version = Native.callStaticJniMethodObject(emulator, "getNativeVersion()Ljava/lang/String;");
StringObject version = cNative.callStaticJniMethodObject(emulator, "getNativeVersion()Ljava/lang/String;");
System.out.println("getNativeVersion version=" + version.getValue() + ", offset=" + (System.currentTimeMillis() - start) + "ms");

StringObject checksum = Native.callStaticJniMethodObject(emulator, "getAPIChecksum()Ljava/lang/String;");
StringObject checksum = cNative.callStaticJniMethodObject(emulator, "getAPIChecksum()Ljava/lang/String;");
System.out.println("getAPIChecksum checksum=" + checksum.getValue() + ", offset=" + (System.currentTimeMillis() - start) + "ms");

ret = Native.callStaticJniMethodInt(emulator, "sizeof(I)I", 0);
ret = cNative.callStaticJniMethodInt(emulator, "sizeof(I)I", 0);
System.out.println("sizeof POINTER_SIZE=" + ret.intValue() + ", offset=" + (System.currentTimeMillis() - start) + "ms");
}

Expand Down
15 changes: 7 additions & 8 deletions unidbg-android/src/test/java/com/sun/jna/JniDispatch64.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import com.github.unidbg.*;
import com.github.unidbg.arm.HookStatus;
import com.github.unidbg.arm.context.RegisterContext;
import com.github.unidbg.debugger.DebuggerType;
import com.github.unidbg.hook.HookContext;
import com.github.unidbg.hook.ReplaceCallback;
import com.github.unidbg.hook.hookzz.Dobby;
Expand Down Expand Up @@ -38,7 +37,7 @@ private static AndroidEmulator createARMEmulator() {
private final AndroidEmulator emulator;
private final Module module;

private final DvmClass Native;
private final DvmClass cNative;

private JniDispatch64() {
emulator = createARMEmulator();
Expand All @@ -52,7 +51,7 @@ private JniDispatch64() {
dm.callJNI_OnLoad(emulator);
this.module = dm.getModule();

Native = vm.resolveClass("com/sun/jna/Native");
cNative = vm.resolveClass("com/sun/jna/Native");

Symbol __system_property_get = module.findSymbolByName("__system_property_get", true);
MemoryBlock block = memory.malloc(0x10);
Expand Down Expand Up @@ -102,7 +101,7 @@ public HookStatus onCall(Emulator<?> emulator, long originFunction) {

long start = System.currentTimeMillis();
final int size = 0x20;
Number ret = Native.callStaticJniMethodLong(emulator, "malloc(J)J", size);
Number ret = cNative.callStaticJniMethodLong(emulator, "malloc(J)J", size);
Pointer pointer = UnidbgPointer.pointer(emulator, ret.intValue() & 0xffffffffL);
assert pointer != null;
pointer.setString(0, getClass().getName());
Expand All @@ -119,14 +118,14 @@ public void dbiCall(Emulator<?> emulator, RegisterContext ctx, HookEntryInfo inf
}
});

StringObject version = Native.callStaticJniMethodObject(emulator, "getNativeVersion()Ljava/lang/String;");
StringObject version = cNative.callStaticJniMethodObject(emulator, "getNativeVersion()Ljava/lang/String;");
System.out.println("getNativeVersion version=" + version.getValue() + ", offset=" + (System.currentTimeMillis() - start) + "ms");

StringObject checksum = Native.callStaticJniMethodObject(emulator, "getAPIChecksum()Ljava/lang/String;");
StringObject checksum = cNative.callStaticJniMethodObject(emulator, "getAPIChecksum()Ljava/lang/String;");
System.out.println("getAPIChecksum checksum=" + checksum.getValue() + ", offset=" + (System.currentTimeMillis() - start) + "ms");

emulator.attach(DebuggerType.ANDROID_SERVER_V7);
ret = Native.callStaticJniMethodInt(emulator, "sizeof(I)I", 0);
// emulator.attach(DebuggerType.ANDROID_SERVER_V7);
ret = cNative.callStaticJniMethodInt(emulator, "sizeof(I)I", 0);
System.out.println("sizeof POINTER_SIZE=" + ret.intValue() + ", offset=" + (System.currentTimeMillis() - start) + "ms");
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ private static AndroidEmulator createARMEmulator() {
private final AndroidEmulator emulator;
private final VM vm;

private final DvmClass Utilities;
private final DvmClass cUtilities;

private Utilities32() {
emulator = createARMEmulator();
Expand All @@ -48,7 +48,7 @@ private Utilities32() {
DalvikModule dm = vm.loadLibrary(new File("unidbg-android/src/test/resources/example_binaries/armeabi-v7a/libtmessages.29.so"), false);
dm.callJNI_OnLoad(emulator);

Utilities = vm.resolveClass("org/telegram/messenger/Utilities");
cUtilities = vm.resolveClass("org/telegram/messenger/Utilities");
}

private void destroy() throws IOException {
Expand All @@ -71,7 +71,7 @@ private void aesCbcEncryptionByteArray() {
ByteArray data = new ByteArray(vm, new byte[16]);
byte[] key = new byte[32];
byte[] iv = new byte[16];
Utilities.callStaticJniMethod(emulator, "aesCbcEncryptionByteArray([B[B[BIIII)V", vm.addLocalObject(data),
cUtilities.callStaticJniMethod(emulator, "aesCbcEncryptionByteArray([B[B[BIIII)V", vm.addLocalObject(data),
vm.addLocalObject(new ByteArray(vm, key)),
vm.addLocalObject(new ByteArray(vm, iv)),
0, data.length(), 0, 0);
Expand All @@ -83,7 +83,7 @@ private void aesCtrDecryptionByteArray() {
ByteArray data = new ByteArray(vm, new byte[16]);
byte[] key = new byte[32];
byte[] iv = new byte[16];
Utilities.callStaticJniMethod(emulator, "aesCtrDecryptionByteArray([B[B[BIII)V", vm.addLocalObject(data),
cUtilities.callStaticJniMethod(emulator, "aesCtrDecryptionByteArray([B[B[BIII)V", vm.addLocalObject(data),
vm.addLocalObject(new ByteArray(vm, key)),
vm.addLocalObject(new ByteArray(vm, iv)),
0, data.length(), 0);
Expand All @@ -95,7 +95,7 @@ private void pbkdf2() {
byte[] password = "123456".getBytes();
byte[] salt = new byte[8];
ByteArray dst = new ByteArray(vm, new byte[64]);
Utilities.callStaticJniMethod(emulator, "pbkdf2([B[B[BI)V", vm.addLocalObject(new ByteArray(vm, password)),
cUtilities.callStaticJniMethod(emulator, "pbkdf2([B[B[BI)V", vm.addLocalObject(new ByteArray(vm, password)),
vm.addLocalObject(new ByteArray(vm, salt)),
vm.addLocalObject(dst), 100000);
Inspector.inspect(dst.getValue(), "pbkdf2 offset=" + (System.currentTimeMillis() - start) + "ms");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ private static AndroidEmulator createARMEmulator() {
private final AndroidEmulator emulator;
private final VM vm;

private final DvmClass Utilities;
private final DvmClass cUtilities;

private Utilities64() {
emulator = createARMEmulator();
Expand All @@ -48,7 +48,7 @@ private Utilities64() {
DalvikModule dm = vm.loadLibrary(new File("unidbg-android/src/test/resources/example_binaries/arm64-v8a/libtmessages.29.so"), true);
dm.callJNI_OnLoad(emulator);

Utilities = vm.resolveClass("org/telegram/messenger/Utilities");
cUtilities = vm.resolveClass("org/telegram/messenger/Utilities");
}

private void destroy() throws IOException {
Expand All @@ -71,7 +71,7 @@ private void aesCbcEncryptionByteArray() {
ByteArray data = new ByteArray(vm, new byte[16]);
byte[] key = new byte[32];
byte[] iv = new byte[16];
Utilities.callStaticJniMethod(emulator, "aesCbcEncryptionByteArray([B[B[BIIII)V", vm.addLocalObject(data),
cUtilities.callStaticJniMethod(emulator, "aesCbcEncryptionByteArray([B[B[BIIII)V", vm.addLocalObject(data),
vm.addLocalObject(new ByteArray(vm, key)),
vm.addLocalObject(new ByteArray(vm, iv)),
0, data.length(), 0, 0);
Expand All @@ -83,7 +83,7 @@ private void aesCtrDecryptionByteArray() {
ByteArray data = new ByteArray(vm, new byte[16]);
byte[] key = new byte[32];
byte[] iv = new byte[16];
Utilities.callStaticJniMethod(emulator, "aesCtrDecryptionByteArray([B[B[BIII)V", vm.addLocalObject(data),
cUtilities.callStaticJniMethod(emulator, "aesCtrDecryptionByteArray([B[B[BIII)V", vm.addLocalObject(data),
vm.addLocalObject(new ByteArray(vm, key)),
vm.addLocalObject(new ByteArray(vm, iv)),
0, data.length(), 0);
Expand All @@ -95,7 +95,7 @@ private void pbkdf2() {
byte[] password = "123456".getBytes();
byte[] salt = new byte[8];
ByteArray dst = new ByteArray(vm, new byte[64]);
Utilities.callStaticJniMethod(emulator, "pbkdf2([B[B[BI)V", vm.addLocalObject(new ByteArray(vm, password)),
cUtilities.callStaticJniMethod(emulator, "pbkdf2([B[B[BI)V", vm.addLocalObject(new ByteArray(vm, password)),
vm.addLocalObject(new ByteArray(vm, salt)),
vm.addLocalObject(dst), 100000);
Inspector.inspect(dst.getValue(), "pbkdf2 offset=" + (System.currentTimeMillis() - start) + "ms");
Expand Down
1 change: 1 addition & 0 deletions unidbg-android/src/test/resources/log4j.properties
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,4 @@ log4j.logger.com.github.unidbg.hook.xhook=INFO
log4j.logger.net.fornwall.jelf.AndroidRelocationIterator=INFO
log4j.logger.com.github.unidbg.AndroidRelocationTest=INFO
log4j.logger.com.github.unidbg.unix.file=INFO
log4j.logger.com.github.unidbg.arm.backend=INFO
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ public AbstractEmulator(boolean is64Bit, String processName, long svcBase, int s
throw new IllegalStateException("mkdirs failed: " + rootDir);
}
this.fileSystem = createFileSystem(rootDir);
this.backend = BackendFactory.createBackend(is64Bit);
this.backend = BackendFactory.createBackend(this, is64Bit);
this.processName = processName == null ? "unidbg" : processName;
this.registerContext = createRegisterContext(backend);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package com.github.unidbg.arm.backend;

import com.github.unidbg.Emulator;

public class BackendFactory {

public static Backend createBackend(boolean is64Bit) {
public static Backend createBackend(Emulator<?> emulator, boolean is64Bit) {
boolean useDynarmic = Boolean.parseBoolean(System.getProperty("use.dynarmic.backend"));
if (useDynarmic) {
Backend backend = DynarmicBackend.tryInitialize(is64Bit);
Backend backend = DynarmicBackend.tryInitialize(emulator, is64Bit);
if (backend != null) {
return backend;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.github.unidbg.arm.backend;

import com.github.unidbg.Emulator;
import com.github.unidbg.arm.backend.dynarmic.*;
import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
Expand All @@ -10,10 +11,10 @@ public abstract class DynarmicBackend implements Backend, DynarmicCallback {

private static final Log log = LogFactory.getLog(DynarmicBackend.class);

static DynarmicBackend tryInitialize(boolean is64Bit) {
static DynarmicBackend tryInitialize(Emulator<?> emulator, boolean is64Bit) {
try {
Dynarmic dynarmic = new Dynarmic(is64Bit);
return is64Bit ? new DynarmicBackend64(dynarmic) : new DynarmicBackend32(dynarmic);
return is64Bit ? new DynarmicBackend64(emulator, dynarmic) : new DynarmicBackend32(emulator, dynarmic);
} catch (Throwable throwable) {
if (log.isDebugEnabled()) {
log.debug("initialize dynarmic failed", throwable);
Expand All @@ -22,9 +23,11 @@ static DynarmicBackend tryInitialize(boolean is64Bit) {
}
}

protected final Emulator<?> emulator;
protected final Dynarmic dynarmic;

protected DynarmicBackend(Dynarmic dynarmic) {
protected DynarmicBackend(Emulator<?> emulator, Dynarmic dynarmic) {
this.emulator = emulator;
this.dynarmic = dynarmic;
this.dynarmic.setDynarmicCallback(this);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
package com.github.unidbg.arm.backend.dynarmic;

import com.github.unidbg.Emulator;
import com.github.unidbg.arm.backend.DynarmicBackend;
import unicorn.ArmConst;

public class DynarmicBackend32 extends DynarmicBackend {

public DynarmicBackend32(Dynarmic dynarmic) {
super(dynarmic);
public DynarmicBackend32(Emulator<?> emulator, Dynarmic dynarmic) {
super(emulator, dynarmic);
}

@Override
Expand All @@ -19,6 +20,11 @@ public void callSVC(long pc, int swi) {
throw new AbstractMethodError();
}

@Override
public boolean handleInterpreterFallback(long pc, int num_instructions) {
throw new AbstractMethodError();
}

@Override
public Number reg_read(int regId) {
switch (regId) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
package com.github.unidbg.arm.backend.dynarmic;

import capstone.Capstone;
import com.github.unidbg.Emulator;
import com.github.unidbg.arm.ARM;
import com.github.unidbg.arm.backend.DynarmicBackend;
import com.github.unidbg.utils.Inspector;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import unicorn.Arm64Const;
Expand All @@ -9,8 +13,8 @@ public class DynarmicBackend64 extends DynarmicBackend {

private static final Log log = LogFactory.getLog(DynarmicBackend64.class);

public DynarmicBackend64(Dynarmic dynarmic) {
super(dynarmic);
public DynarmicBackend64(Emulator<?> emulator, Dynarmic dynarmic) {
super(emulator, dynarmic);
}

protected long until;
Expand All @@ -21,6 +25,28 @@ public void emu_start(long begin, long until, long timeout, long count) {
super.emu_start(begin, until, timeout, count);
}

@Override
public boolean handleInterpreterFallback(long pc, int num_instructions) {
if (num_instructions != 1) {
return false;
}
byte[] code = mem_read(pc, 4);
Capstone.CsInsn ins = emulator.disassemble(pc, code, false, 1)[0];
if (log.isDebugEnabled()) {
log.debug(Inspector.inspectString(code, "handleInterpreterFallback pc=0x" + Long.toHexString(pc) + ", " + String.format("0x%08x: %s %s", ins.address, ins.mnemonic, ins.opStr)));
}

switch (ins.mnemonic) {
case "ic": {
// eg: ic ivau, x2
return true;
}
case "nop":
default:
return false;
}
}

@Override
public void callSVC(long pc, int swi) {
if (log.isDebugEnabled()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,9 @@ public interface DynarmicCallback {

void callSVC(long pc, int swi);

/**
* 返回<code>false</code>表示未处理的指令
*/
boolean handleInterpreterFallback(long pc, int num_instructions);

}
Loading

0 comments on commit be3aea9

Please sign in to comment.