红丸检测虚拟化

我试图检测我的Windows是否在虚拟机上运行。 我发现这个C代码被称为Joanna Rutkowska的Red Pill:

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)(); 

with message:访问冲突执行位置0x003AFCE8。 我做错了吗?

显然,示例代码试图执行一系列机器指令,这些指令在某些虚拟机中的行为与在某些“真实硬件”上的行为不同。请注意,使用这种简单方法可能无法检测到其他VM。

代码无法执行的原因是,在现代操作系统上,您无法执行数据部分。 您需要专门将该段代码放入可执行部分,或将数据部分更改为可执行部分。

来自Joanna Rutkowska的代码的实际作者:

注意:此程序将在具有PAX / X ^ W / grsecurity,保护的系统上失败(正如Brad Spengler所指出的那样),因为rpill变量未标记为可执行文件。 为了使它在这样的系统中运行,应该使用mprotect()来标记具有PROT_EXEC属性的rpill。 另一个解决方案是使用asm()关键字而不是类似shellcode的缓冲区。 但是,这个程序应该被视为构建到您自己的shellcode中的骨架,而不是独立的生产类工具;)我的目标是使其尽可能简单和便携。 这就是为什么我不使用asm()或mprotect(),因为它们是系统或编译器相关的。

 #include  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上运行它。