使用Delphi 64位检测虚拟化环境?
如何为64位Delphi应用程序做到这一点使用Delphi 64位检测虚拟化环境?,delphi,assembly,virtual-machine,x86-64,vmware,Delphi,Assembly,Virtual Machine,X86 64,Vmware,如何为64位Delphi应用程序做到这一点 如果我尝试将其编译为64位,则会收到消息“不支持的语言功能:ASM”和“操作数大小不匹配”。我知道您需要将asm代码与pascal代码分开,并且寄存器不同,但不知道如何做?最后,我将此解决方案用于32/64位 // VMware detection as described by Elias Bachaalany function IsInsideVMware: Boolean; begin Result := True; try a
如果我尝试将其编译为64位,则会收到消息“不支持的语言功能:ASM”和“操作数大小不匹配”。我知道您需要将asm代码与pascal代码分开,并且寄存器不同,但不知道如何做?最后,我将此解决方案用于32/64位
// VMware detection as described by Elias Bachaalany
function IsInsideVMware: Boolean;
begin
Result := True;
try
asm
push edx;
push ecx;
push ebx;
mov eax, 'VMXh';
mov ebx, 0;
mov ecx, 10;
mov edx, 'VX';
in eax, dx;
cmp ebx, 'VMXh';
setz [Result];
pop ebx;
pop ecx;
pop edx;
end;
except
Result := False;
end;
end;
function IsRunningUnderHyperV: BOOL; stdcall;
var
VMBranding: array[0..12] of AnsiChar;
begin
asm
mov eax, $40000000;
cpuid;
mov dword ptr [VMBranding+0], ebx; // Get the VM branding string
mov dword ptr [VMBranding+4], ecx;
mov dword ptr [VMBranding+8], edx;
end;
VMBranding[12] := #0;
Result := CompareText(String(VMBranding), 'Microsoft Hv') = 0;
end;
至于检测64位的其他VM品牌,我使用了以下代码:
代码被更新为以x64位运行和编译,并检测虚拟机品牌。您读过Delphi的文档了吗?为什么需要检测虚拟化?是的。更改代码以消除“未移植的语言功能:ASM”,并解决了它,但现在有“E2116操作码和操作数的无效组合”。寄存器需要更改为64位,但不知道使用哪一个?您不能在用户模式下的中使用。当使用
eax=1执行cpuid
时,所有VMM将设置ecx
的位31。该位在物理机器上为零,在准虚拟化虚拟机上为1。您可以执行一些检查,但所有检查都很容易规避。我只知道一个简单有效的方法,但没有理由不希望用户在虚拟机中运行程序。虚拟机无处不在,即使用户不知道!唯一不想在虚拟机中运行的程序是恶意软件,因此它们无法通过自动沙盒进行分析。“如果用户可以在虚拟机中注册程序,那么他可以复制多次”,那么您需要修改您的许可方案。除了vmware和hyperV之外,还有许多虚拟机监控程序。。。
var
LFlag: Cardinal;
//================================= VMWare =====================================
procedure TryVMWare;
{$IFDEF CPUX86}
asm
push eax
push ebx
push ecx
push edx
mov eax, 'VMXh'
mov ecx, 0Ah
mov dx, 'VX'
in eax, dx
mov LFlag, ebx
pop edx
pop ecx
pop ebx
pop eax
end;
{$ENDIF CPUX86}
{$IFDEF CPUX64}
asm
push rax
push rbx
push rcx
push rdx
mov eax, 'VMXh'
mov ecx, 0Ah
mov dx, 'VX'
in eax, dx
mov LFlag, ebx
pop rdx
pop rcx
pop rbx
pop rax
end;
{$ENDIF CPUX64}
function IsInsideVMware: Boolean;
begin
LFlag := 0;
try
TryVMWare;
except
end;
Result := LFlag = $564D5868;
end;