Я пытаюсь выполнить проект, который переводит двоичный файл ELF в виртуальную машину, чтобы обеспечить процесс собственной среды выполнения, аналогичный http://dune.scs.stanford.edu/. Многие работы говорят «мы обнаруживаем системный вызов ....», но не указали подробности обнаружения, кроме этой статьи, код которой обнаруживает syscall в vmx non root ring 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
будет другим решением. Что я могу сказать, чтобы заставить syscall в vmx non root использовать int 80h
и перехватить это прерывание. Пожалуйста, поделитесь любым предложением для этого взлома.
I гавань» t еще не прочитал весь вопрос, но да, построение ядра для экспорта заглушки 'int 0x80' в' vdso', а не 'sysenter', должно быть полностью прозрачным для glibc. Вы изучали механизм 'strace (1)' использует для отслеживания системных вызовов? Я не уверен, как он работает под капотом, но я знаю, что он основан на системном вызове 'ptrace (2)', который позволяет 'gdb' управлять другим процессом для одношаговой. Существует также 'ltrace (1)', который использует взломы shared-lib для отслеживания всех вызовов функций в shared libs. –