我正在尝试完成将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 non root中的syscall使用int 80h
并挂钩此中断。请分享任何关于此黑客的建议。
答案 0 :(得分:0)
我不打算向你解释这段代码(需要的不仅仅是那些,但我可以因为git存储库仍然无法使用)
但是检测vmx non root中的系统调用依赖于你可以在paper,第6页和第7页中找到的一些技巧。 基本上,要检测