如何强制使用int$0x80而不是sysenter进行系统调用检测



我正在努力完成一个项目,该项目将ELF二进制文件转换为虚拟机,以提供一个进程自己的执行环境,类似于http://dune.scs.stanford.edu/.许多论文都说"我们检测系统调用……",但除了本文的代码检测vmx非根环0中的系统调用外,没有提供检测的详细信息。(因为进程将在此环中运行)。但由于他的论文中缺乏文件和提示,我无法掌握他的方法。相关代码如下

/*
 * macro to switch to G0 fs.base
 *
 * NOTE: clobbers %rax, %rdx, and %rcx
 */
    .macro SET_G0_FS_BASE
    movq    $0, %gs:IN_USERMODE
    movq    %gs:KFS_BASE, %rax
    movq    %gs:UFS_BASE, %rdx
    cmp %rax, %rdx
    je  1f
#if USE_RDWRGSFS
    wrfsbase %rax
#else
    movq    %rax, %rdx
    shrq    $32, %rdx
    movl    $MSR_FS_BASE, %ecx
    wrmsr
#endif /* USE_RDWRGSFS */
1:
    .endm  

__dune_syscall:
    /* handle system calls from G0 */
    testq $1, %gs:IN_USERMODE
    jnz 1f
    pushq   %r11
    popfq
    vmcall
    jmp *%rcx
1:
    /* first switch to the kernel stack */
    movq    %rsp, %gs:TMP
    movq    %gs:TRAP_STACK, %rsp
    /* now push the trap frame onto the stack */
    subq    $TF_END, %rsp
    movq    %rcx, RIP(%rsp)
    movq    %r11, RFLAGS(%rsp)
    movq    %r10, RCX(%rsp) /* fixup to standard 64-bit calling ABI */
    SAVE_REGS 0, 1
    movq    %gs:TMP, %rax
    movq    %rax, RSP(%rsp)
    /* then restore the CPL0 FS base address */
    SET_G0_FS_BASE
    /* then finally re-enable interrupts and jump to the handler */
    sti
    movq    %rsp, %rdi /* argument 0 */
    lea dune_syscall_handler, %rax
    call    *%rax
    /* next restore the CPL3 FS base address */
    SET_G3_FS_BASE
    /* then pop the trap frame off the stack */
    RESTORE_REGS 0, 1
    movq    RCX(%rsp), %r10
    movq    RFLAGS(%rsp), %r11
    movq    RIP(%rsp), %rcx
    /* switch to the user stack and return to ring 3 */
    movq    RSP(%rsp), %rsp
    sysretq
.globl __dune_syscall_end
__dune_syscall_end:
    nop

我的问题如下

1) 上面的代码是如何工作的?任何解释、指针或参考都将有助于

2) 在这种情况下,是否有其他方法可以检测系统调用?我认为调整vdso将是另一个解决方案。我能想到的是强制vmx非root中的syscall使用int 80h并挂接这个中断。请分享关于这次黑客攻击的任何建议。

我不会向您解释这段代码(需要更多,但我不能,因为git存储库仍然不可用)

但是,在vmx非root中检测系统调用依赖于本文第6页和第7页中的一些技巧。基本上,检测

  • syscall/sysret:您必须在EFER中禁用CSE位,这样任何使用syscall/ssysret的尝试都会导致您将截获的无效操作码异常
  • sysenter/sysexit:您必须将sysenter_CS_MSR保存在系统管理程序中的某个位置,然后用null值加载它,这样任何使用sysenter/ssysexit的操作都会导致您将捕获的一般保护异常

最新更新