【发布时间】:2017-09-17 18:42:03
【问题描述】:
我正在尝试检测我的 Windows 是否在虚拟机上运行。我发现了这个被称为 Joanna Rutkowska's 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。 我做错了吗?
【问题讨论】:
-
您尝试将
rpill中的数据用作函数。但是,程序中的普通数据不应该是可执行的,所以它不能被“调用”。此外,如果您在地址大小为 64 位的 64 位系统上怎么办?unsigned类型等于unsigned int,在所有现代标准 PC 平台上都是 32 位类型,因此当您将其“修补”到代码中时,m的地址可能会被截断。 -
@Someprogrammerdude 是否意味着这不是工作方法?或者有什么方法可以让这个解决方案同时在 x86 和 x64 系统上运行?
-
指针问题可以通过将程序构建为 32 位可执行文件来轻松解决。但这并不能解决数据不可执行的问题,我不知道如何解决。
-
这种方法是十多年前发明的,并且非常适用于当时的特定 VMM——VMWare 工作站和虚拟 PC。这取决于 VMM 管理客户内存的方式。它不适用于现代虚拟化技术(EPT 和 NPT,它们本身已有近十年的历史)。
标签: c++ c virtual-machine virtualization