红药丸检测虚拟化

4

我正在尝试检测我的Windows是否运行在虚拟机中。我找到了这段被称为Joanna Rutkowska的Red Pill的C代码:

int swallow_redpill () 
{
  unsigned char m[2+4], rpill[] = "\x0f\x01\x0d\x00\x00\x00\x00\xc3";
  *((unsigned*)&rpill[3]) = (unsigned)m;
  ((void(*)())&rpill)();
  return (m[5]>0xd0) ? 1 : 0;
}

但是当我在我的VC++项目中运行它时,它在这一行失败:
  ((void(*)())&rpill)();

出现错误信息:执行位置0x003AFCE8时访问冲突。 我做错了什么吗?


1
您试图将rpill中的数据用作函数。然而,程序中的普通数据不应该是可执行的,因此它不能被“调用”。此外,如果您在一个64位系统上,地址的大小为64位呢?unsigned类型等同于unsigned int,在所有现代标准PC平台上都是32位类型,因此当您将m的地址“修补”到代码中时,可能会被截断。 - Some programmer dude
@Someprogrammerdude 这是不是意味着这个方法不起作用?还是有办法让这个解决方案在x86和x64系统上都能工作? - Kiramm
指针问题可以通过构建32位可执行文件轻松解决。但这并不能解决数据无法执行的问题,我不知道该如何解决。 - Some programmer dude
6
这种方法是十多年前发明的,非常特定于当时的某些虚拟机管理程序(VMWare Workstation和Virtual PC)。它依赖于虚拟机管理程序管理客户机内存的方式。它无法与现代虚拟化技术(EPT和NPT,它们自己也已经近十年历史)兼容。 - prl
3个回答

5
显然,示例代码试图执行一系列机器指令,在*一些*虚拟机内的行为与某些真实硬件上的行为不同。请注意,其他虚拟机可能无法用这种简单方法检测到。
代码不能执行的原因是,在现代操作系统中,您无法执行数据部分。您需要将那段代码明确地放入可执行部分,或者将数据部分更改为可执行。
来自Joanna Rutkowska,实际编写代码的人:
注意:在具有PAX / X ^ W / grsecurity保护系统(如Brad Spengler所指出的)中,此程序将失败,因为rpill变量未标记为可执行。要在这些系统中运行它,应使用mprotect()将rpill标记为PROT_EXEC属性。另一种解决方案是只使用asm()关键字而不是类似于shellcode的缓冲区。但是,这个程序应该被视为构建自己的shellcode的骨架,而不是独立的生产级工具;)我的目标是使它尽可能简单和便携。这就是为什么我没有使用asm()或mprotect(),因为它们是系统或编译器相关的。

1
#include <windows.h>

unsigned char m[2+4], rpill[] = "\x0f\x01\x0d\x00\x00\x00\x00\xc3";
int swallow_redpill () 
{
  unsigned int old;
  VirtualProtect(rpill, 8, PAGE_EXECUTE_READWRITE, &old);
  *((unsigned*)&rpill[3]) = (unsigned)m;
  ((void(*)())&rpill)();
  return (m[5]>0xd0) ? 1 : 0;
}

在Windows上,应该能解决问题。如果您的机器是x64,请确保运行Win32版本。


这个看起来不对:难道你不需要VirtualProtect rpill而不是old吗?即使rpill不是全局的(所以在初始化数据段中?),那么8也可能无法覆盖整个rpill +对齐,虽然我猜它跨越一页并遇到问题的机会很小。 - Rup

0
这是为x86手写的代码,没有考虑到现代编译器中常见的NX堆栈硬化机制。一个更具可移植性的代码,用于通过SIDT获取IDTR,在amd64上也能正常工作。
#include <stdio.h>

struct {
    unsigned short limit;
    unsigned long base;
} __attribute__((packed)) idtr;

int main() {
    asm("sidt %0" : "=m" (idtr));
    printf("%lx %x\n", idtr.base, idtr.limit);
    return 0;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接