Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SignalTest. 对信号的初步测试修改 #389

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ public void hook(Backend backend, int intno, int swi, Object user) {
}

int NR = backend.reg_read(ArmConst.UC_ARM_REG_R7).intValue();
//System.out.println("发生系统低哦啊用:"+NR);
String syscall = null;
Throwable exception = null;
try {
Expand Down Expand Up @@ -175,7 +176,7 @@ public void hook(Backend backend, int intno, int swi, Object user) {
case 26:
backend.reg_write(ArmConst.UC_ARM_REG_R0, ptrace(emulator));
return;
case 20: // getpid
case 20: // getpid
backend.reg_write(ArmConst.UC_ARM_REG_R0, emulator.getPid());
return;
case 224: // gettid
Expand Down Expand Up @@ -330,6 +331,9 @@ public void hook(Backend backend, int intno, int swi, Object user) {
case 177:
backend.reg_write(ArmConst.UC_ARM_REG_R0, rt_sigtimedwait(emulator));
return;
case 178:
backend.reg_write(ArmConst.UC_ARM_REG_R0, rt_sigqueue(emulator));
return;
case 180:
backend.reg_write(ArmConst.UC_ARM_REG_R0, pread64(emulator));
return;
Expand Down Expand Up @@ -531,6 +535,7 @@ public void hook(Backend backend, int intno, int swi, Object user) {
}
}


private int mlock(Emulator<?> emulator) {
RegisterContext context = emulator.getContext();
Pointer addr = context.getPointerArg(0);
Expand Down Expand Up @@ -976,7 +981,7 @@ private int llseek(Backend backend, Emulator<?> emulator) {
int fd = backend.reg_read(ArmConst.UC_ARM_REG_R0).intValue();
long offset_high = backend.reg_read(ArmConst.UC_ARM_REG_R1).intValue() & 0xffffffffL;
long offset_low = backend.reg_read(ArmConst.UC_ARM_REG_R2).intValue() & 0xffffffffL;
long offset = (offset_high<<32) | offset_low;
long offset = (offset_high << 32) | offset_low;
Pointer result = UnidbgPointer.register(emulator, ArmConst.UC_ARM_REG_R3);
int whence = backend.reg_read(ArmConst.UC_ARM_REG_R4).intValue();
if (log.isDebugEnabled()) {
Expand Down Expand Up @@ -1240,7 +1245,7 @@ private int poll(Backend backend, Emulator<?> emulator) {
pollfd.setShort(6, (short) 0);
} else {
short revents = 0;
if((events & POLLOUT) != 0) {
if ((events & POLLOUT) != 0) {
revents = POLLOUT;
} else if ((events & POLLIN) != 0) {
revents = POLLIN;
Expand Down Expand Up @@ -1685,7 +1690,7 @@ private int munmap(Backend backend, Emulator<?> emulator) {
private static final int PR_SET_DUMPABLE = 4;
private static final int PR_SET_NAME = 15;
private static final int PR_GET_NAME = 16;
private static final int BIONIC_PR_SET_VMA = 0x53564d41;
private static final int BIONIC_PR_SET_VMA = 0x53564d41;
private static final int PR_SET_PTRACER = 0x59616d61;

private int prctl(Backend backend, Emulator<?> emulator) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,10 +143,10 @@ public void hook(Backend backend, int intno, int swi, Object user) {
case 62:
backend.reg_write(Arm64Const.UC_ARM64_REG_X0, lseek(emulator));
return;
case 172: // getpid
case 172: // getpid
backend.reg_write(Arm64Const.UC_ARM64_REG_X0, emulator.getPid());
return;
case 178: // gettid
case 178: // gettid
Task task = emulator.get(Task.TASK_KEY);
backend.reg_write(Arm64Const.UC_ARM64_REG_X0, task == null ? 0 : task.getId());
return;
Expand Down Expand Up @@ -249,6 +249,9 @@ public void hook(Backend backend, int intno, int swi, Object user) {
case 137:
backend.reg_write(Arm64Const.UC_ARM64_REG_X0, rt_sigtimedwait(emulator));
return;
case 138:
backend.reg_write(Arm64Const.UC_ARM64_REG_X0, rt_sigqueue(emulator));
return;
case 167:
backend.reg_write(Arm64Const.UC_ARM64_REG_X0, prctl(emulator));
return;
Expand Down Expand Up @@ -685,7 +688,7 @@ private int ppoll(Emulator<?> emulator) {
pollfd.setShort(6, (short) 0);
} else {
short revents = 0;
if((events & POLLOUT) != 0) {
if ((events & POLLOUT) != 0) {
revents = POLLOUT;
} else if ((events & POLLIN) != 0) {
revents = POLLIN;
Expand Down Expand Up @@ -1074,7 +1077,7 @@ private long mremap(Emulator<?> emulator) {

private static final int PR_SET_NAME = 15;
private static final int PR_SET_NO_NEW_PRIVS = 38;
private static final int BIONIC_PR_SET_VMA = 0x53564d41;
private static final int BIONIC_PR_SET_VMA = 0x53564d41;
private static final int PR_SET_PTRACER = 0x59616d61;

private int prctl(Emulator<?> emulator) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,7 @@ protected int rt_sigpending(Emulator<AndroidFileIO> emulator) {
return 0;
}


private static final int FUTEX_CMD_MASK = 0x7f;
private static final int FUTEX_PRIVATE_FLAG = 0x80;
private static final int MUTEX_SHARED_MASK = 0x2000;
Expand Down Expand Up @@ -359,6 +360,34 @@ protected int rt_sigtimedwait(Emulator<AndroidFileIO> emulator) {
return 0;
}

protected int rt_sigqueue(Emulator<AndroidFileIO> emulator) {
RegisterContext context = emulator.getContext();
int tgid = context.getIntArg(0);
int sig = context.getIntArg(1);
UnidbgPointer info = context.getPointerArg(2);
if (log.isDebugEnabled()) {
log.debug("rt_sigqueue tgid=" + tgid + ", sig=" + sig);
}
Task task = emulator.get(Task.TASK_KEY);
// 检查pid是有匹配进程存在
if (!(tgid == 0 || tgid == -1 || Math.abs(tgid) == emulator.getPid())) {
return -UnixEmulator.ESRCH;
}
// 检查进程是否存在, 无需发送信号
if (sig == 0) {
return 0;
}
if (sig < 0 || sig > 64) {
return -UnixEmulator.EINVAL;
}
if (task != null) {
SigAction sigAction = sigActionMap.get(sig);
//sigAction.sig_info = info;
return processSignal(emulator.getThreadDispatcher(), sig, task, sigAction, info);
}
throw new UnsupportedOperationException();
}

@Override
protected FileResult<AndroidFileIO> createFdDir(int oflags, String pathname) {
List<DirectoryFileIO.DirectoryEntry> list = new ArrayList<>();
Expand Down Expand Up @@ -486,7 +515,7 @@ final int select(int nfds, Pointer checkfds, Pointer clearfds, boolean checkRead
int count = 0;
for (int i = 0; i < nfds; i++) {
int mask = checkfds.getInt(i / 32);
if(((mask >> i) & 1) == 1) {
if (((mask >> i) & 1) == 1) {
AndroidFileIO io = fdMap.get(i);
if (!checkRead || io.canRead()) {
count++;
Expand Down Expand Up @@ -576,11 +605,13 @@ public MainTask createSignalHandlerTask(Emulator<?> emulator, int sig) {

@Override
protected int sigaction(Emulator<?> emulator, int signum, Pointer act, Pointer oldact) {
//TODO action参数解包 (64位有BUG, 暂定)
SigAction action = SigAction.create(emulator, act);
SigAction oldAction = SigAction.create(emulator, oldact);
if (log.isDebugEnabled()) {
log.debug("sigaction signum=" + signum + ", action=" + action + ", oldAction=" + oldAction);
}
// SIGKILL 和 SIGSTOP 不允许自定义处理
if (SIGKILL == signum || SIGSTOP == signum) {
if (oldAction != null) {
oldAction.sa_handler = UnidbgPointer.pointer(emulator, SIG_ERR);
Expand Down Expand Up @@ -611,20 +642,32 @@ protected int kill(Emulator<?> emulator) {
log.debug("kill pid=" + pid + ", sig=" + sig);
}
Task task = emulator.get(Task.TASK_KEY);
if (pid == 0 && sig > 0 && task != null) {
// 检查pid是有匹配进程存在
if (!(pid == 0 || pid == -1 || Math.abs(pid) == emulator.getPid())) {
emulator.getMemory().setErrno(UnixEmulator.ESRCH);
return UnixEmulator.ESRCH;
}
// 检查进程是否存在, 无需发送信号
if (sig == 0) {
return 0;
}
if (sig < 0 || sig > 64) {
return -UnixEmulator.EINVAL;
}
if (/*pid == 0 && */ task != null) {
SigAction action = sigActionMap.get(sig);
return processSignal(emulator.getThreadDispatcher(), sig, task, action);
return processSignal(emulator.getThreadDispatcher(), sig, task, action, null);
}
throw new UnsupportedOperationException("kill pid=" + pid + ", sig=" + sig + ", LR=" + context.getLRPointer());
}

private int processSignal(ThreadDispatcher threadDispatcher, int sig, Task task, SigAction action) {
private int processSignal(ThreadDispatcher threadDispatcher, int sig, Task task, SigAction action, Pointer sig_info) {
if (action != null) {
SignalOps signalOps = task.isMainThread() ? threadDispatcher : task;
SigSet sigMaskSet = signalOps.getSigMaskSet();
SigSet sigPendingSet = signalOps.getSigPendingSet();
if (sigMaskSet == null || !sigMaskSet.containsSigNumber(sig)) {
task.addSignalTask(new SignalTask(sig, action));
task.addSignalTask(new SignalTask(sig, action, sig_info));
throw new ThreadContextSwitchException().setReturnValue(0);
} else if (sigPendingSet != null) {
sigPendingSet.addSigNumber(sig);
Expand All @@ -648,6 +691,9 @@ protected int tgkill(Emulator<?> emulator) {
throw new ThreadContextSwitchException().setReturnValue(0);
}
}
if (sig < 0 || sig > 64) {
return -UnixEmulator.EINVAL;
}
return 0;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,23 @@
import com.github.unidbg.signal.SigSet;
import com.github.unidbg.signal.SignalOps;
import com.github.unidbg.signal.UnixSigSet;
import com.sun.jna.Pointer;
import unicorn.Arm64Const;
import unicorn.ArmConst;

public class SignalTask extends AbstractSignalTask {

private final SigAction action;
private Pointer sig_info;

public SignalTask(int signum, SigAction action) {
this(signum, action, null);
}

public SignalTask(int signum, SigAction action, Pointer sig_info) {
super(signum);
this.action = action;
this.sig_info = sig_info;
}

private UnidbgPointer stack;
Expand Down Expand Up @@ -48,24 +55,30 @@ private Number runHandler(AbstractEmulator<?> emulator) {
if (stack == null) {
stack = allocateStack(emulator);
}
if (action.needSigInfo() && infoBlock == null) {
if (action.needSigInfo() && infoBlock == null && sig_info == null) {
infoBlock = emulator.getMemory().malloc(128, true);
infoBlock.getPointer().setInt(0, signum);
sig_info = infoBlock.getPointer();
}
if (emulator.is32Bit()) {
backend.reg_write(ArmConst.UC_ARM_REG_SP, stack.peer);
backend.reg_write(ArmConst.UC_ARM_REG_R0, signum);
backend.reg_write(ArmConst.UC_ARM_REG_R1, infoBlock == null ? 0 : infoBlock.getPointer().peer); // siginfo_t *info
backend.reg_write(ArmConst.UC_ARM_REG_R1, sig_info == null ? 0 : ((UnidbgPointer) sig_info).toIntPeer() /*infoBlock == null ? 0 : infoBlock.getPointer().peer*/); // siginfo_t *info
backend.reg_write(ArmConst.UC_ARM_REG_R2, 0); // void *ucontext
backend.reg_write(ArmConst.UC_ARM_REG_LR, emulator.getReturnAddress());
} else {
backend.reg_write(Arm64Const.UC_ARM64_REG_SP, stack.peer);
backend.reg_write(Arm64Const.UC_ARM64_REG_X0, signum);
backend.reg_write(Arm64Const.UC_ARM64_REG_X1, infoBlock == null ? 0 : infoBlock.getPointer().peer); // siginfo_t *info
backend.reg_write(Arm64Const.UC_ARM64_REG_X1, sig_info == null ? 0 : ((UnidbgPointer) sig_info).toUIntPeer()); // siginfo_t *info
backend.reg_write(Arm64Const.UC_ARM64_REG_X2, 0); // void *ucontext
backend.reg_write(Arm64Const.UC_ARM64_REG_LR, emulator.getReturnAddress());
}
return emulator.emulate(UnidbgPointer.nativeValue(action.sa_handler), emulator.getReturnAddress());
long handler = UnidbgPointer.nativeValue(action.sa_handler);
// 如果handler忽略或缺省,直接返回
if (handler == 1 || handler == 0) {
return -1;
}
return emulator.emulate(handler, emulator.getReturnAddress());
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package com.github.unidbg.android;

import com.alibaba.fastjson.util.IOUtils;
import com.github.unidbg.AndroidEmulator;
import com.github.unidbg.Module;
import com.github.unidbg.linux.android.AndroidEmulatorBuilder;
import com.github.unidbg.linux.android.AndroidResolver;
import com.github.unidbg.memory.Memory;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;

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

public class Signal64BxlTest {

public static void main(String[] args) {
//Logger.getLogger(ARM32SyscallHandler.class).setLevel(Level.DEBUG);
Signal64BxlTest test = new Signal64BxlTest();
test.test();
test.destroy();
}

private void destroy() {
IOUtils.close(emulator);
}

private final AndroidEmulator emulator;
private final Module module;

private Signal64BxlTest() {
final File executable = new File("unidbg-android/src/test/native/bxl/example/arm64-v8a/build/ninja/signal64");
emulator = AndroidEmulatorBuilder
.for64Bit()
// .addBackendFactory(new DynarmicFactory(true))
// .addBackendFactory(new Unicorn2Factory(true))
.build();
Memory memory = emulator.getMemory();
emulator.getSyscallHandler().setVerbose(false);
emulator.getSyscallHandler().setEnableThreadDispatcher(true);
AndroidResolver resolver = new AndroidResolver(23);
memory.setLibraryResolver(resolver);

module = emulator.loadLibrary(executable, true);
}

private void test() {

Logger.getLogger("com.github.unidbg.linux.AndroidSyscallHandler").setLevel(Level.DEBUG);
emulator.emulateSignal(2);
emulator.emulateSignal(5);
int code = module.callEntry(emulator);

System.err.println("exit code: " + code + ", backend=" + emulator.getBackend());
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package com.github.unidbg.android;

import com.alibaba.fastjson.util.IOUtils;
import com.github.unidbg.AbstractEmulator;
import com.github.unidbg.AndroidEmulator;
import com.github.unidbg.Module;
import com.github.unidbg.arm.backend.DynarmicFactory;
import com.github.unidbg.arm.backend.Unicorn2Factory;
import com.github.unidbg.linux.ARM32SyscallHandler;
import com.github.unidbg.linux.android.AndroidEmulatorBuilder;
import com.github.unidbg.linux.android.AndroidResolver;
import com.github.unidbg.memory.Memory;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;


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

public class SignalBxlTest {

public static void main(String[] args) {
//Logger.getLogger(ARM32SyscallHandler.class).setLevel(Level.DEBUG);
SignalBxlTest test = new SignalBxlTest();
test.test();
test.destroy();
}

private void destroy() {
IOUtils.close(emulator);
}

private final AndroidEmulator emulator;
private final Module module;

private SignalBxlTest() {
final File executable = new File("unidbg-android/src/test/native/bxl/example/armeabi-v7a/build/ninja/signal");
emulator = AndroidEmulatorBuilder
.for32Bit()
// .addBackendFactory(new DynarmicFactory(true))
// .addBackendFactory(new Unicorn2Factory(true))
.build();
Memory memory = emulator.getMemory();
emulator.getSyscallHandler().setVerbose(false);
emulator.getSyscallHandler().setEnableThreadDispatcher(true);
AndroidResolver resolver = new AndroidResolver(23);
memory.setLibraryResolver(resolver);

module = emulator.loadLibrary(executable, true);
}

private void test() {
//emulator.traceCode(module.base, module.base+module.size);
Logger.getLogger("com.github.unidbg.linux.AndroidSyscallHandler").setLevel(Level.DEBUG);
emulator.emulateSignal(2);
emulator.emulateSignal(5);
int code = module.callEntry(emulator);

System.err.println("exit code: " + code + ", backend=" + emulator.getBackend());
}

}
Binary file not shown.
Loading