vm壳编写中如何解决异常处理机制?

我正在开发一款类似于VMProtect的代码虚拟化保护壳,我现在已经写好了虚拟指令集,进入退出虚拟机和虚拟指令的分发执行。但现在不知道如何去处理诸如seh和veh这些异常处理机制,请问处理这些异常处理的基本思想是什么?我的理解是找到每个seh或veh的异常处理handler,然后也对这些handler进行一遍vm虚拟化,最后就为它们构建一段进入虚拟机的stub引导代码。请问可以这样理解吗?还是说应该是要在虚拟机中完全模拟这些异常处理机制?

【以下回答由 GPT 生成】

在编写虚拟机壳时,解决异常处理机制的基本思想是将异常处理机制完全模拟在虚拟机中。你的理解是正确的,需要找到每个SEH或VEH的异常处理handler,并为它们构建一段进入虚拟机的引导代码。

以下是解决异常处理机制的一般步骤:

  1. 获取当前进程的异常链表:通过访问FS段寄存器(或GS段寄存器,在x64架构上)上的偏移量,可以获得线程本地存储区(TLS)内存块的起始地址。然后从TLS内存块中获取异常链表的起始地址。

csharp // C# 示例代码 IntPtr tebBaseAddress = NtGetCurrentTeb(); IntPtr exceptionList = tebBaseAddress + EXCEPTION_LIST_OFFSET;

  1. 遍历异常链表找到异常处理handler:从异常链表的起始地址开始,遍历链表直到找到有效的异常处理handler。对于SEH,从FS段寄存器所指向的线程本地存储区中获取异常链表的头节点。链表的每个节点包含了异常处理handler的地址。

```csharp // C# 示例代码 IntPtr currentEntry = exceptionList; while (currentEntry != IntPtr.Zero) { IntPtr exceptionHandler = ReadIntPtr(currentEntry + EXCEPTION_HANDLER_OFFSET); // 处理异常处理handler // ...

   currentEntry = ReadIntPtr(currentEntry + LIST_ENTRY_FLink_OFFSET);

} ```

  1. 对每个异常处理handler进行虚拟化:对于每个异常处理handler,将其进行虚拟化。使用你已经编写的虚拟指令集和执行逻辑,构建一段进入虚拟机的引导代码,并将其替换原有的异常处理handler。

csharp // C# 示例代码 byte[] bootstrapCode = ConstructBootstrapCode(); WriteToMemory(exceptionHandler, bootstrapCode);

  1. 退出虚拟机时恢复异常处理机制:在退出虚拟机时,需要将已经虚拟化的异常处理handler恢复为原来的方法。通过调用相关API函数将异常处理handler还原回原始的地址。

以上是一般的解决方案,但实际情况可能会更复杂,取决于具体的编程语言、平台和虚拟化技术。在实际解决问题时,可能需要更多的细节和代码来适应特定的环境和要求。

希望这些信息能对你有帮助!如果你有任何进一步的问题,请随时提问。


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^