Code:
' Detect QEMU.bas
' This program uses multiple detection methods for QEMU VM to increase accuracy.
' However, no single method is foolproof, as virtualization environments
' can be customized or masked by hackers.
#COMPILE EXE
#DIM ALL
#INCLUDE "Win32Api.inc"
%KEY_QUERY_VALUE = &H0001
%ERROR_SUCCESS = 0
'============================
FUNCTION PBMAIN () AS LONG
IF IsQEMU() THEN
? "Running inside a QEMU virtual machine."
ELSE
? "Not running inside a QEMU virtual machine."
END IF
END FUNCTION
'===============================
' Detects QEMU VM using several methods
FUNCTION IsQEMU() AS LONG
LOCAL hqeKey AS DWORD
LOCAL dwType AS DWORD
LOCAL dwData AS DWORD
LOCAL cbData AS DWORD
LOCAL qresult AS LONG
' Indicator for various QEMU types
LOCAL tmpQe AS LONG
tmpQe = 0
' Check for QEMU-specific registry key (System Manufacturer)
' HARDWARE\DESCRIPTION\System\BIOS
qresult = RegOpenKeyEx(%HKEY_LOCAL_MACHINE, hwBios, 0, %KEY_QUERY_VALUE, hqeKey)
IF qresult = %ERROR_SUCCESS THEN
cbData = 256
' SystemManufacturer
qresult = RegQueryValueEx(hqeKey, SysManf , 0, dwType, BYVAL VARPTR(dwData), cbData)
IF qresult = %ERROR_SUCCESS THEN
'QEMU
IF INSTR(UCASE$(PEEK$(VARPTR(dwData), cbData)), StQE) > 0 THEN
tmpQe = 1
END IF
END IF
RegCloseKey hqeKey
END IF
IF tmpQe > 0 THEN
IsQEMU = 1
EXIT FUNCTION
END IF
' Check for QEMU-specific driver (qxl.sys or virtio drivers)
' such as QXL video adapter or VirtIO devices
' C:\Windows\System32\drivers\qxl.sys and
' C:\Windows\System32\drivers\vioinput.sys
IF ISFILE(qxlS ) OR ISFILE(vioinp) THEN
tmpQe = 2
END IF
IF tmpQe > 0 THEN
IsQEMU = 1
EXIT FUNCTION
END IF
' Check for QEMU-specific hardware (QXL video or VirtIO devices)
' C:\Windows\System32\drivers\qxl.dll and
' C:\Windows\System32\drivers\viostor.sys
IF ISFILE(stQxl) OR ISFILE(stVio) THEN
tmpQe = 3
END IF
IF tmpQe > 0 THEN
IsQEMU = 1
EXIT FUNCTION
END IF
' Not running inside QEMU
IsQEMU = 0
END FUNCTION
' ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
' C:\Windows\System32\drivers\vioinput.sys
FUNCTION vioinp() AS STRING
' Text is 40 bytes excluding the terminating zero
#REGISTER NONE
LOCAL src AS DWORD
LOCAL dst AS DWORD
LOCAL outpt$
src = CODEPTR(datalabel)
outpt$ = NUL$(40)
dst = STRPTR(outpt$)
' -------------------
' copy data to string
' -------------------
! mov esi, src
! mov edi, dst
! mov ecx, 40
! rep movsb
src = CODEPTR(paddlabel)
' -----------------------------
' xor string data to unique pad
' -----------------------------
! mov esi, dst
! mov ebx, 40
! mov edi, src
! add esi, ebx
! add edi, ebx
! neg ebx
lbl0:
! movzx eax, BYTE PTR [edi+ebx]
! xor [esi+ebx], al
! add ebx, 1
! jz lbl1
! movzx eax, BYTE PTR [edi+ebx]
! xor [esi+ebx], al
! add ebx, 1
! jz lbl1
! movzx eax, BYTE PTR [edi+ebx]
! xor [esi+ebx], al
! add ebx, 1
! jz lbl1
! movzx eax, BYTE PTR [edi+ebx]
! xor [esi+ebx], al
! add ebx, 1
! jnz lbl0
lbl1:
FUNCTION = outpt$
EXIT FUNCTION
#ALIGN 4
datalabel:
! db 137,244,134,19,90,252,4,157,27,48,199,3,14,247,228,3
! db 175,250,190,186,216,209,84,46,134,104,244,174,243,136,210,100
! db 103,146,120,43,36,182,157,78,0
#ALIGN 4
paddlabel:
! db 202,206,218,68,51,146,96,242,108,67,155,80,119,132,144,102
! db 194,201,140,230,188,163,61,88,227,26,135,242,133,225,189,13
! db 9,226,13,95,10,197,228,61,0
END FUNCTION
' ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
' ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
' C:\Windows\System32\drivers\qxl.sys
FUNCTION qxlS() AS STRING
' Text is 35 bytes excluding the terminating zero
#REGISTER NONE
LOCAL src AS DWORD
LOCAL dst AS DWORD
LOCAL outpt$
src = CODEPTR(datalabel)
outpt$ = NUL$(35)
dst = STRPTR(outpt$)
' -------------------
' copy data to string
' -------------------
! mov esi, src
! mov edi, dst
! mov ecx, 35
! rep movsb
src = CODEPTR(paddlabel)
' -----------------------------
' xor string data to unique pad
' -----------------------------
! mov esi, dst
! mov ebx, 35
! mov edi, src
! add esi, ebx
! add edi, ebx
! neg ebx
lbl0:
! movzx eax, BYTE PTR [edi+ebx]
! xor [esi+ebx], al
! add ebx, 1
! jz lbl1
! movzx eax, BYTE PTR [edi+ebx]
! xor [esi+ebx], al
! add ebx, 1
! jz lbl1
! movzx eax, BYTE PTR [edi+ebx]
! xor [esi+ebx], al
! add ebx, 1
! jz lbl1
! movzx eax, BYTE PTR [edi+ebx]
! xor [esi+ebx], al
! add ebx, 1
! jnz lbl0
lbl1:
FUNCTION = outpt$
EXIT FUNCTION
#ALIGN 4
datalabel:
! db 39,193,199,194,34,252,156,45,109,153,235,30,232,30,74,199
! db 100,250,27,119,124,175,212,177,7,207,147,66,236,149,73,81
! db 143,69,39,0
#ALIGN 4
paddlabel:
! db 100,251,155,149,75,146,248,66,26,234,183,77,145,109,62,162
! db 9,201,41,43,24,221,189,199,98,189,224,30,157,237,37,127
! db 252,60,84,0
END FUNCTION
' ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
' ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
'C:\Windows\System32\drivers\qxl.dll
FUNCTION stQxl() AS STRING
' Text is 35 bytes excluding the terminating zero
#REGISTER NONE
LOCAL src AS DWORD
LOCAL dst AS DWORD
LOCAL outpt$
src = CODEPTR(datalabel)
outpt$ = NUL$(35)
dst = STRPTR(outpt$)
' -------------------
' copy data to string
' -------------------
! mov esi, src
! mov edi, dst
! mov ecx, 35
! rep movsb
src = CODEPTR(paddlabel)
' -----------------------------
' xor string data to unique pad
' -----------------------------
! mov esi, dst
! mov ebx, 35
! mov edi, src
! add esi, ebx
! add edi, ebx
! neg ebx
lbl0:
! movzx eax, BYTE PTR [edi+ebx]
! xor [esi+ebx], al
! add ebx, 1
! jz lbl1
! movzx eax, BYTE PTR [edi+ebx]
! xor [esi+ebx], al
! add ebx, 1
! jz lbl1
! movzx eax, BYTE PTR [edi+ebx]
! xor [esi+ebx], al
! add ebx, 1
! jz lbl1
! movzx eax, BYTE PTR [edi+ebx]
! xor [esi+ebx], al
! add ebx, 1
! jnz lbl0
lbl1:
FUNCTION = outpt$
EXIT FUNCTION
#ALIGN 4
datalabel:
! db 107,242,156,222,105,186,235,71,251,111,207,178,223,54,223,160
! db 48,66,192,5,85,78,114,228,105,10,125,30,253,8,13,29
! db 29,250,74,0
#ALIGN 4
paddlabel:
! db 40,200,192,137,0,212,143,40,140,28,147,225,166,69,171,197
! db 93,113,242,89,49,60,27,146,12,120,14,66,140,112,97,51
! db 121,150,38,0
END FUNCTION
' ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
' ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
' C:\Windows\System32\drivers\viostor.sys
FUNCTION stVio() AS STRING
' Text is 39 bytes excluding the terminating zero
#REGISTER NONE
LOCAL src AS DWORD
LOCAL dst AS DWORD
LOCAL outpt$
src = CODEPTR(datalabel)
outpt$ = NUL$(39)
dst = STRPTR(outpt$)
' -------------------
' copy data to string
' -------------------
! mov esi, src
! mov edi, dst
! mov ecx, 39
! rep movsb
src = CODEPTR(paddlabel)
' -----------------------------
' xor string data to unique pad
' -----------------------------
! mov esi, dst
! mov ebx, 39
! mov edi, src
! add esi, ebx
! add edi, ebx
! neg ebx
lbl0:
! movzx eax, BYTE PTR [edi+ebx]
! xor [esi+ebx], al
! add ebx, 1
! jz lbl1
! movzx eax, BYTE PTR [edi+ebx]
! xor [esi+ebx], al
! add ebx, 1
! jz lbl1
! movzx eax, BYTE PTR [edi+ebx]
! xor [esi+ebx], al
! add ebx, 1
! jz lbl1
! movzx eax, BYTE PTR [edi+ebx]
! xor [esi+ebx], al
! add ebx, 1
! jnz lbl0
lbl1:
FUNCTION = outpt$
EXIT FUNCTION
#ALIGN 4
datalabel:
! db 249,253,198,251,223,113,140,156,245,139,234,192,79,79,251,90
! db 10,141,82,54,82,155,166,16,138,158,122,123,208,158,228,122
! db 211,170,16,201,173,76,240,0
#ALIGN 4
paddlabel:
! db 186,199,154,172,182,31,232,243,130,248,182,147,54,60,143,63
! db 103,190,96,106,54,233,207,102,239,236,9,39,166,247,139,9
! db 167,197,98,231,222,53,131,0
END FUNCTION
' ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
' ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
' QEMU
FUNCTION StQE() AS STRING
#REGISTER NONE
LOCAL pstr AS DWORD
LOCAL a$
a$ = NUL$(4)
pstr = STRPTR(a$)
! mov esi, pstr
! mov BYTE PTR [esi+0], 81
! mov BYTE PTR [esi+2], 77
! mov BYTE PTR [esi+1], 69
! mov BYTE PTR [esi+3], 85
FUNCTION = a$
END FUNCTION
' ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
' ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
' SystemManufacturer
FUNCTION SysManf() AS STRING
#REGISTER NONE
LOCAL pstr AS DWORD
LOCAL a$
a$ = NUL$(18)
pstr = STRPTR(a$)
! mov esi, pstr
! mov BYTE PTR [esi+14], 117
! mov BYTE PTR [esi+5], 109
! mov BYTE PTR [esi+9], 117
! mov BYTE PTR [esi+16], 101
! mov BYTE PTR [esi+15], 114
! mov BYTE PTR [esi+17], 114
! mov BYTE PTR [esi+11], 97
! mov BYTE PTR [esi+8], 110
! mov BYTE PTR [esi+13], 116
! mov BYTE PTR [esi+3], 116
! mov BYTE PTR [esi+4], 101
! mov BYTE PTR [esi+2], 115
! mov BYTE PTR [esi+0], 83
! mov BYTE PTR [esi+1], 121
! mov BYTE PTR [esi+7], 97
! mov BYTE PTR [esi+12], 99
! mov BYTE PTR [esi+6], 77
! mov BYTE PTR [esi+10], 102
FUNCTION = a$
END FUNCTION
' ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
' ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
' HARDWARE\DESCRIPTION\System\BIOS
FUNCTION hwBios() AS STRING
#REGISTER NONE
LOCAL pstr AS DWORD
LOCAL a$
a$ = NUL$(32)
pstr = STRPTR(a$)
! mov esi, pstr
! mov BYTE PTR [esi+28], 66
! mov BYTE PTR [esi+29], 73
! mov BYTE PTR [esi+27], 92
! mov BYTE PTR [esi+17], 73
! mov BYTE PTR [esi+4], 87
! mov BYTE PTR [esi+30], 79
! mov BYTE PTR [esi+20], 92
! mov BYTE PTR [esi+16], 84
! mov BYTE PTR [esi+21], 83
! mov BYTE PTR [esi+25], 101
! mov BYTE PTR [esi+31], 83
! mov BYTE PTR [esi+12], 67
! mov BYTE PTR [esi+15], 80
! mov BYTE PTR [esi+22], 121
! mov BYTE PTR [esi+9], 68
! mov BYTE PTR [esi+1], 65
! mov BYTE PTR [esi+3], 68
! mov BYTE PTR [esi+6], 82
! mov BYTE PTR [esi+0], 72
! mov BYTE PTR [esi+18], 79
! mov BYTE PTR [esi+23], 115
! mov BYTE PTR [esi+11], 83
! mov BYTE PTR [esi+7], 69
! mov BYTE PTR [esi+19], 78
! mov BYTE PTR [esi+26], 109
! mov BYTE PTR [esi+8], 92
! mov BYTE PTR [esi+2], 82
! mov BYTE PTR [esi+5], 65
! mov BYTE PTR [esi+10], 69
! mov BYTE PTR [esi+13], 82
! mov BYTE PTR [esi+14], 73
! mov BYTE PTR [esi+24], 116
FUNCTION = a$
END FUNCTION
' ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤