I'm currently exploring different integrations that can be done between Google App Script and Git. This is part of a bigger attempt to integrate Git data into my project management system. I'll post more on that later. GitHub supports a number of very nice sub-systems. One of them is the GitHub Issues ticket tracking system. It's fairly robust and comes with GitHub - which means it's highly integrated out-of-the-box. Integration with Google's App Script is done via the fetchURL command and JSON object manipulation. After a good bit of experimentation, I've settled on querying GitHub Issues with an "on open spreadsheet event" to avoid issues with Google's quota system. Essentially, Google prevents you from calling the fetchURL command more than X times (see the quota limits ) per day. That's not great if you have people actively working and changing data in a spreadsheet. Some of my other App Script routines are running thousands of times per d...
CubicDesign on delphi-talk.elists.org recently asked the question: "How do I know/detect if my software is running under Windows [or a virtual environment]?" Well, it turns out that it's a lot harder to tell than you would think. Apparently, the VM (VMware, Xen, Wine, etc.) doesn't really want you to be able to do this. At least not easily.
For VMware, there is a decent little C routine called jerry.c that does the trick. Jerry actually uses a simple communication channel that VMware left open. It's not 100% foolproof since the admin can change the channel, but that's not likely going to happen unless the system is specifically designed to be a honeypot. If you're running on a honeypot and still have a legitimate reason for detection, you could look at the much more complex scoopy implementation which inspects how the system is actually virtualized using the SIDT CPU instruction instead of a communication channel. Another reference (red pill) is here.
For Wine, there is a special dll entry called wine_nt_to_unix_file_name that they added to NTDLL.DLL. If you use LoadLibrary and GetProcAddress, you can determine if you are under Wine simply by the entry's presence or absence. Of course, if you specifically want to know what version of Wine you're on, you have to use NTDLL_wine_get_version but that function is only available in the bleeding edge version of wine. As an interesting side note, the Jerry test above actually returns true for VMware workstation under Wine. If you really have to know Wine vs VMware, make sure you test Wine first, otherwise you'll get a false positive.
For Xen, the most reliable method appears to be to use the WMI interface and get the Bios manufacturer's information. If it's Xen, then you are under some version of Xen. Since I don't have a Xen environment setup currently, I couldn't test this information. I am relying on information published here to make this assertion. At some point, I'll setup a Xen server and play with it.
For true VM's like Xen and Vmware, you can also test against the mac address. VMware uses 00-05-69 as the lead and Xen uses 00-16-3E. To see a list of all registered Mac addresses, go here. Keep in mind, that the VMM supports changing the MAC address so this is also easily defeated.
At any rate, here's some sample code that uses the described methods to detect VMware and Wine. Enjoy!
VMware:
Wine:
For VMware, there is a decent little C routine called jerry.c that does the trick. Jerry actually uses a simple communication channel that VMware left open. It's not 100% foolproof since the admin can change the channel, but that's not likely going to happen unless the system is specifically designed to be a honeypot. If you're running on a honeypot and still have a legitimate reason for detection, you could look at the much more complex scoopy implementation which inspects how the system is actually virtualized using the SIDT CPU instruction instead of a communication channel. Another reference (red pill) is here.
For Wine, there is a special dll entry called wine_nt_to_unix_file_name that they added to NTDLL.DLL. If you use LoadLibrary and GetProcAddress, you can determine if you are under Wine simply by the entry's presence or absence. Of course, if you specifically want to know what version of Wine you're on, you have to use NTDLL_wine_get_version but that function is only available in the bleeding edge version of wine. As an interesting side note, the Jerry test above actually returns true for VMware workstation under Wine. If you really have to know Wine vs VMware, make sure you test Wine first, otherwise you'll get a false positive.
For Xen, the most reliable method appears to be to use the WMI interface and get the Bios manufacturer's information. If it's Xen, then you are under some version of Xen. Since I don't have a Xen environment setup currently, I couldn't test this information. I am relying on information published here to make this assertion. At some point, I'll setup a Xen server and play with it.
For true VM's like Xen and Vmware, you can also test against the mac address. VMware uses 00-05-69 as the lead and Xen uses 00-16-3E. To see a list of all registered Mac addresses, go here. Keep in mind, that the VMM supports changing the MAC address so this is also easily defeated.
At any rate, here's some sample code that uses the described methods to detect VMware and Wine. Enjoy!
VMware:
//credit to chitchat@lycos.jp who discovered this method and
//checkvm + IDA Pro ;)
//converted from C source posted on www.trapkit.de
procedure TForm1.btnJerryClick(Sender: TObject);
var a, b:cardinal;
begin
a:=0;
try
asm
push eax
push ebx
push ecx
push edx
mov eax, 'VMXh'
mov ecx, 0Ah
mov dx, 'VX'
in eax, dx
mov a, ebx
mov b, ecx
pop edx
pop ecx
pop ebx
pop eax
end;
except on E:Exception do ShowMessage(E.Message);
end;
if a=$564D5868 then
begin
ShowMessage('In VMware');
case b of
1 : ShowMessage('Express');
2 : ShowMessage('ESX');
3 : ShowMessage('GSX');
4 : ShowMessage('Workstation');
else ShowMessage('Unknown version')
end;
end
else
ShowMessage('Native system');
end;
Wine:
function TForm1.IsRunningWine: boolean;
var hnd:THandle;
wine_get_version: function : pchar; {$IFDEF Win32} stdcall; {$ENDIF}
wine_unix2fn: procedure (p1:pointer; p2:pointer); {$IFDEF Win32} stdcall; {$ENDIF}
begin
result:=false;
hnd:=LoadLibrary('ntdll.dll');
if hnd>32 then
begin
wine_get_version:= GetProcAddress(hnd, 'wine_get_version');
wine_unix2fn:= GetProcAddress(hnd, 'wine_nt_to_unix_file_name');
if assigned(wine_get_version) or assigned(wine_unix2fn) then
result:=true;
FreeLibrary(hnd);
end;
end;
Comments
(**********************************
** Detect if your application **
** is running in Virtual Box. **
** **
** E0N 2008 **
**********************************)
function InVirtualBox:boolean;
var handle:THandle;
procinfo:ProcessEntry32;
begin
result:=false;
handle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
procinfo := sizeof(PROCESSENTRY32);
while(Process32Next(handle, procinfo)) do
begin
if POS("VBoxService.exe",procinfo.szExeFile)>0) then
begin
CloseHandle(handle);
result:=true;
exit;
end;
end;
CloseHandle(handle);
end;
Let me know if it works and I'll write it up as a normal blog entry. I've been trying to accumulate these detection methods in one place for ease of reference.
function RunningInsideVirtualBox: Boolean;
var
handle: THandle;
procinfo: ProcessEntry32;
begin
Result := False;
try
handle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
try
while(Process32Next(handle, procinfo)) do begin
if POS('VBoxService.exe', procinfo.szExeFile) > 0 then begin
Result := True;
Break;
end;
end;
finally
CloseHandle(handle);
end;
except
end;
end;