我正在尝试检测我的 Windows 是否在虚拟机上运行。我找到了这个被称为 Joanna Rutkowska 的红色药丸的 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。 我做错了什么吗?
最佳答案
显然,示例代码试图执行一系列机器指令,这些机器指令在某些 虚拟机中的行为与在*某些“真实硬件上的行为不同。请注意,使用这种简单方法可能无法检测到其他虚拟机.
代码无法执行的原因是在现代操作系统上您无法执行数据部分。您需要专门将该段代码放入可执行部分,或将数据部分更改为可执行部分。
来自 Joanna Rutkowska代码的实际编写者:
NOTE: this program will fail on systems with PAX/X^W/grsecurity, protection (as it was pointed out by Brad Spengler) since the rpill variable is not marked as executable. To make it run in such systems, mprotect() should be used to mark rpill with PROT_EXEC attribute. Another solution would be to just use asm() keyword instead of shellcode-like buffer. However, this program should be rather considered as a skeleton to build into your own shellcode, rather then standalone production class tool;) My goal was to make it as simple and portable as possible. That's why I didn't use asm() nor mprotect() since they are system or compiler dependent.
关于c++ - Red Pill检测虚拟化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46267618/