Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/154.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/60.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 红色药丸检测虚拟化_C++_C_Virtual Machine_Virtualization - Fatal编程技术网

C++ 红色药丸检测虚拟化

C++ 红色药丸检测虚拟化,c++,c,virtual-machine,virtualization,C++,C,Virtual Machine,Virtualization,我正在尝试检测我的Windows是否在虚拟机上运行。我发现了这个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)

我正在尝试检测我的Windows是否在虚拟机上运行。我发现了这个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。
我做错smth了吗?

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

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

来自代码的实际编写者:

注意:由于rpill变量未标记为可执行文件,因此此程序在具有PAX/X^W/grsecurity、protection(如Brad Spengler所指出)的系统上会失败。要使其在此类系统中运行,应使用mprotect()将rpill标记为PROT_EXEC属性。另一种解决方案是仅使用asm()关键字而不是像buffer这样的外壳代码。然而,这个程序应该被视为构建到您自己的外壳代码中的框架,而不是独立的生产类工具;)我的目标是使它尽可能简单和可移植。这就是为什么我没有使用asm()或mprotect(),因为它们依赖于系统或编译器

#包括
无符号字符m[2+4],rpill[]=“\x0f\x01\x0d\x00\x00\x00\x00\x03”;
int swallow_redpill()
{
无符号整型;
VirtualProtect(rpill,8页,执行页,读写页和旧页);
*((无符号*)&rpill[3])=(无符号)m;
((无效(*)和rpill)();
返回值(m[5]>0xd0)?1:0;
}

应该在Windows上执行此操作。如果您有x64计算机,请确保在Win32上运行它。

您尝试将
rpill
中的数据用作函数。但是,程序中的正常数据不应是可执行的,因此无法“调用”“。此外,如果您在64位系统上,地址大小为64位,该怎么办?
unsigned
类型等于
unsigned int
,在所有现代标准PC平台上都是32位类型,因此当您将
m
的地址“修补”到代码中时,它可能会被截断。@Someprogrammerdude这是否意味着这不是有效的方法?或者有什么方法可以使这个解决方案同时在x86和x64系统上工作?指针问题可以通过将程序构建为32位可执行文件轻松解决。但这并不能解决数据不可执行的问题,我也不知道如何解决这个问题。这种方法是十多年前发明的,非常适合当时的特定VMM—VMWare工作站和虚拟PC。这取决于VMM管理来宾内存的方式。它不适用于现代虚拟化技术(EPT和NPT,它们本身已经有近十年的历史了)?即使rpill在堆栈上不是全局的(所以在初始化的数据段中?),8也可能无法覆盖整个rpill+对齐,尽管我猜它跨越一个页面并使您陷入麻烦的可能性很小。