我正在尝试检测我的Windows是否在虚拟机上运行。我发现这个C代码被称为Joanna Rutkowska的红色药丸:
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。 我做错了吗?
答案 0 :(得分:3)
显然,示例代码正在尝试执行一系列机器指令,这些指令在某些虚拟机中的行为与在某些“真实硬件”上的行为不同。请注意,使用这种简单的方法可能无法检测到其他VM
代码无法执行的原因是在现代操作系统上,您无法执行数据部分。您需要专门将该段代码放入可执行部分,或将数据部分更改为可执行部分。
来自Joanna Rutkowska代码的实际作者:
注意:此程序将在具有PAX / X ^ W / grsecurity,保护的系统上失败(正如Brad Spengler所指出的那样),因为rpill变量未标记为可执行文件。为了使它在这样的系统中运行,应该使用mprotect()来标记具有PROT_EXEC属性的rpill。另一种解决方案是使用asm()关键字而不是类似shellcode的缓冲区。但是,这个程序应该被视为构建到您自己的shellcode中的骨架,而不是独立的生产类工具;)我的目标是使其尽可能简单和便携。这就是为什么我不使用asm()或mprotect(),因为它们是系统或编译器相关的。
答案 1 :(得分:0)
#include <windows.h>
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上构建的文件。