Thursday, 6 August 2009

Saber si nuestra aplicación se ejecuta dentro de una máquina virtual

En éste post, os muestro el código de Nico Bendlin para saber si nuestra aplicación se está ejecutando dentro de una máquina virtual o no. El código es bastante simple pero está en ensamblador. Si nos fijamos en el código podemos ver que se utiliza la instrucción "IN" para escribir en un puerto concreto. Ésta función solo la utilizan las máquinas virtuales, por lo tanto el programa intenta utilizar la instrucción, si puede valida que está dentro de la máquina virtual en otro caso no. He encontrado varios métodos por la red uno de ellos en CodeProject, con una muy buena explicación del funcionamiento del método. La mayoría suelen funcionar, pero como comentan ellos, ésto solo són funciones demo, sin ninguna validación por parte de los fabricantes de máquinas virtuales. En los dos métodos que os pondré a continuación se utiliza la misma función "IN" para saber si estamos dentro o no, pero otro día puede cambiar la funcionalidad y puede que no nos sirvan los métodos.

unit VMWare;

interface

uses
    Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
    Dialogs, StdCtrls;

type
    TForm3 = class(TForm)
        Button1: TButton;
        Edit1: TEdit;
        Button2: TButton;
        Edit2: TEdit;
        procedure Button1Click(Sender: TObject);
        procedure Button2Click(Sender: TObject);
    private
        { Private declarations }
    public
        { Public declarations }
    end;

var
    Form3: TForm3;

function IsInsideVMWare: Boolean;
function IsVMwarePresent(): LongBool; stdcall;

implementation

{$R *.dfm}

procedure TForm3.Button1Click(Sender: TObject);
begin
    Edit1.text := 'No';
    if IsVMwarePresent then
        Edit1.text := 'Yes';
end;

procedure TForm3.Button2Click(Sender: TObject);
begin
    Edit2.text := 'No';
    if IsInsideVMWare then
        Edit2.text := 'Yes';
end;

function IsVMwarePresent(): LongBool; stdcall;
begin
    Result := False;
{$IFDEF CPU386}
    try
        asm
            mov     eax, 564D5868h
            mov     ebx, 00000000h
            mov     ecx, 0000000Ah
            mov     edx, 00005658h
            in      eax, dx
            cmp     ebx, 564D5868h
            jne     @@exit
            mov     Result, True
    @@exit:
        end;
    except
        Result := False;
    end;
{$ENDIF}
end;

function IsInsideVMWare: Boolean;
var
    rc: Boolean;
begin
    rc := False;
    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   [rc]
          pop    ebx
          pop    ecx
          pop    edx
        end;
    except
        on EPrivilege do
            rc := False;
    end;
    Result := rc;
end;

end.

Si ejecutamos el programa y estamos dentro de una máquia virtual, podemos realizar el test:



  • Enlaces de interés:
Sítio de descargas de Nico Bendlin.
VMWare Torry's 1.
VMWare Torry's 2.
Detect if your program is running inside Virtual Machine.

0 comments:

Post a Comment