红色药丸检测虚拟化

Red Pill detect virtualization

本文关键字:虚拟化 检测 红色      更新时间:2023-10-16

我正在尝试检测我的窗口是否在虚拟机上运行。我找到了这个C代码,该代码被称为Joanna Rutkowska的红色药丸:

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

但是当我在VC 项目中运行它时,它会在线失败

  ((void(*)())&rpill)();

带有消息:访问违规执行位置0x003AFCE8。我做错了吗?

显然,示例代码正在尝试执行一系列机器指令,这些指令在某些虚拟机内与 *某些"真实硬件"中的行为不同。请注意,其他VMS可能无法通过这种简单的方法检测到。

代码无法执行的原因是,在现代OS上,您无法执行数据部分。您需要将该代码专门放入可执行的部分中,或更改数据部分才能执行。

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

注意:由于RPILL变量不能标记为可执行文件,因此该程序将在具有PAX/X^w/grsecurity,Protection,Protection(正如Brad Spengler指出)的系统失败。为了使其在此类系统中运行,应使用mprotect()用Prot_Exec属性标记RPILL。另一个解决方案是仅使用ASM()关键字而不是类似壳牌的缓冲区。但是,该程序应被视为构成自己的ShellCode的骨骼,而不是独立的生产类工具;)我的目标是使其尽可能简单和便携。这就是为什么我不使用ASM()和mprotect(),因为它们是系统或编译器依赖性的。

#include <windows.h>
unsigned char m[2+4], rpill[] = "x0fx01x0dx00x00x00x00xc3";
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上运行它。