"Trapping" Windows 用户空间中进程自己的 sysenter 调用
"Trapping" a processes' own sysenter calls in userspace on Windows
我正在 Windows 中开发运行时非本机二进制翻译器,到目前为止,我已经能够 "trap" 中断(即 INT 0x99)OS 二进制文件我试图通过使用 Windows SEH 来处理无效中断的丑陋黑客来模拟;但只是因为系统调用向量与 Windows 中的不同,所以我可以通过执行以下操作来捕获这些 "soft" 异常:
static int __stdcall handler_cb(EXCEPTION_POINTERS* pes, ...)
{
if (pes->ExceptionRecord->ExceptionCode != EXCEPTION_ACCESS_VIOLATION)
return EXCEPTION_CONTINUE_SEARCH;
char* instruct = (char*) pes->ContextRecord->Eip;
if (!instruct)
handle_invalid_instruction(instruct);
switch (instruct[0])
{
case 0xcd: // INT
{
if (instruct[1] != 0x99) // INT 0x99
handle_invalid_instruction(instruct);
handle_syscall_translation();
...
}
...
default:
halt_and_catch_fire();
}
return EXCEPTION_SUCCESS;
}
效果很好(但很慢),问题是 Windows 首先尝试处理 instruction/interrupt,对于使用 sysenter/sysexit 的非本机二进制文件对于 int 0x99,非本机二进制文件中的一些 systenter 指令在执行时实际上是有效的 NT 内核调用本身,这意味着我的处理程序永远不会被调用,更糟的是; "host" OS 的状态也被泄露。 Windows中的"trap"sysenter指令有什么办法吗?我该怎么做?
据我所知,没有办法(从用户模式进程)“禁用”SYSENTER
,因此执行它会产生异常。 (我假设您的程序不会尝试 SYSEXIT
,因为只有 Ring 0 可以做到)。
我认为你唯一的选择就是像 VirtualBox 那样做,扫描无效指令,用非法操作码或类似的东西替换它们,你可以捕获并模拟它们。参见 10.4. Details about software virtualization。
To fix these performance and security issues, VirtualBox contains a Code Scanning and Analysis Manager (CSAM), which disassembles guest code, and the Patch Manager (PATM), which can replace it at runtime.
Before executing ring 0 code, CSAM scans it recursively to discover problematic instructions. PATM then performs in-situ patching, i.e. it replaces the instruction with a jump to hypervisor memory where an integrated code generator has placed a more suitable implementation. In reality, this is a very complex task as there are lots of odd situations to be discovered and handled correctly. So, with its current complexity, one could argue that PATM is an advanced in-situ recompiler.
我正在 Windows 中开发运行时非本机二进制翻译器,到目前为止,我已经能够 "trap" 中断(即 INT 0x99)OS 二进制文件我试图通过使用 Windows SEH 来处理无效中断的丑陋黑客来模拟;但只是因为系统调用向量与 Windows 中的不同,所以我可以通过执行以下操作来捕获这些 "soft" 异常:
static int __stdcall handler_cb(EXCEPTION_POINTERS* pes, ...)
{
if (pes->ExceptionRecord->ExceptionCode != EXCEPTION_ACCESS_VIOLATION)
return EXCEPTION_CONTINUE_SEARCH;
char* instruct = (char*) pes->ContextRecord->Eip;
if (!instruct)
handle_invalid_instruction(instruct);
switch (instruct[0])
{
case 0xcd: // INT
{
if (instruct[1] != 0x99) // INT 0x99
handle_invalid_instruction(instruct);
handle_syscall_translation();
...
}
...
default:
halt_and_catch_fire();
}
return EXCEPTION_SUCCESS;
}
效果很好(但很慢),问题是 Windows 首先尝试处理 instruction/interrupt,对于使用 sysenter/sysexit 的非本机二进制文件对于 int 0x99,非本机二进制文件中的一些 systenter 指令在执行时实际上是有效的 NT 内核调用本身,这意味着我的处理程序永远不会被调用,更糟的是; "host" OS 的状态也被泄露。 Windows中的"trap"sysenter指令有什么办法吗?我该怎么做?
据我所知,没有办法(从用户模式进程)“禁用”SYSENTER
,因此执行它会产生异常。 (我假设您的程序不会尝试 SYSEXIT
,因为只有 Ring 0 可以做到)。
我认为你唯一的选择就是像 VirtualBox 那样做,扫描无效指令,用非法操作码或类似的东西替换它们,你可以捕获并模拟它们。参见 10.4. Details about software virtualization。
To fix these performance and security issues, VirtualBox contains a Code Scanning and Analysis Manager (CSAM), which disassembles guest code, and the Patch Manager (PATM), which can replace it at runtime.
Before executing ring 0 code, CSAM scans it recursively to discover problematic instructions. PATM then performs in-situ patching, i.e. it replaces the instruction with a jump to hypervisor memory where an integrated code generator has placed a more suitable implementation. In reality, this is a very complex task as there are lots of odd situations to be discovered and handled correctly. So, with its current complexity, one could argue that PATM is an advanced in-situ recompiler.