bug*_*gra 9 vmware 64-bit assembly detection visual-c++
我正在尝试开发一个应用程序,它检测程序是否在虚拟机内运行.
对于32位Windows,已经有方法下面的链接解释说: http://www.codeproject.com/Articles/9823/Detect-if-your-program-is-running-inside-a-Virtual
我正在尝试在64位Windows操作系统中调整有关Virtual PC和VMware检测的代码.对于VMware,代码可以在Windows XP 64位操作系统中成功检测到.但是当我在本机系统(Windows 7 64位操作系统)中运行程序时程序崩溃了.
我将代码放在.asm文件中,并使用ml64.exe文件定义自定义生成步骤.64位Windows的asm代码是:
IsInsideVM proc
push rdx
push rcx
push rbx
mov rax, 'VMXh'
mov rbx, 0 ; any value but not the MAGIC VALUE
mov rcx, 10 ; get VMWare version
mov rdx, 'VX' ; port number
in rax, dx ; read port
; on return EAX returns the VERSION
cmp rbx, 'VMXh'; is it a reply from VMWare?
setz al ; set return value
movzx rax,al
pop rbx
pop rcx
pop rdx
ret
IsInsideVM endp
Run Code Online (Sandbox Code Playgroud)
我将这部分称为cpp文件,如:
__try
{
returnValue = IsInsideVM();
}
__except(1)
{
returnValue = false;
}
Run Code Online (Sandbox Code Playgroud)
提前致谢.
乔安娜的旧红色药丸可能有效:invisiblethings.org 博客的随机备份页面:
吞下红色药丸或多或少相当于以下代码(在矩阵中返回非零):
Run Code Online (Sandbox Code Playgroud)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; }这段代码的核心实际上是SIDT指令(编码为0F010D[addr]),它将中断描述符表寄存器(IDTR)的内容存储在目标操作数中,目标操作数实际上是一个内存位置。SIDT指令的特殊和有趣之处在于,它可以在非特权模式(ring3)下执行,但它返回敏感寄存器的内容,由操作系统内部使用。
由于只有一个IDTR寄存器,但至少有两个操作系统同时运行(即主机和客户操作系统),因此VMM需要将客户的IDTR重新定位到安全的地方,以免与主机的IDTR发生冲突。不幸的是,VMM 无法知道来宾操作系统中运行的进程是否(以及何时)执行 SIDT 指令,因为它没有特权(并且不会生成异常)。这样进程就得到了IDT表的重定位地址。据观察,在 VMWare 上,IDT 的重定位地址位于地址 0xffXXXXXX,而在 Virtual PC 上则为 0xe8XXXXXX。这是在 VMWare Workstation 4 和 Virtual PC 2004 上进行测试的,两者都运行在 Windows XP 主机操作系统上。
注意:我自己还没有测试过它,但看起来它使用了非特权方法。如果它一开始不适用于 x64,一些调整可能会有所帮助。
另外,刚刚发现一个问题,其内容可能对您有帮助:Detecting VMM on linux
| 归档时间: |
|
| 查看次数: |
2718 次 |
| 最近记录: |