;--- Win64 console application with exception handler. ;--- this variant can be assembled by both JWasm and ML64. ;--- assemble: jwasm -c Win64_5m.asm ;--- ml64 -c Win64_5m.asm ;--- link: link /subsystem:console /Libpath:\WinInc\Lib64 Win64_5m.obj option casemap:none includelib exit proto printf proto ;--- CStr(): macro function to simplify defining a string CStr macro Text:VARARG local szText .const szText db Text,0 .code exitm endm EXCEPTION_MAXIMUM_PARAMETERS EQU 15 DWORD64 typedef QWORD EXCEPTION_RECORD64 struct ExceptionCode DWORD ? ExceptionFlags DWORD ? ExceptionRecord DWORD64 ? ExceptionAddress DWORD64 ? NumberParameters DWORD ? __unusedAlignment DWORD ? ExceptionInformation DWORD64 EXCEPTION_MAXIMUM_PARAMETERS dup (?) EXCEPTION_RECORD64 ends M128 struct Low_ QWORD ? High_ QWORD ? M128 ends LEGACY_SAVE_AREA struct ControlWord WORD ? Reserved0 WORD ? StatusWord WORD ? Reserved1 WORD ? TagWord WORD ? Reserved2 WORD ? ErrorOffset DWORD ? ErrorSelector WORD ? ErrorOpcode WORD ? DataOffset DWORD ? DataSelector WORD ? Reserved3 WORD ? FloatRegisters BYTE 8*10 dup (?) LEGACY_SAVE_AREA ends CONTEXT struct P1Home DWORD64 ? P2Home DWORD64 ? P3Home DWORD64 ? P4Home DWORD64 ? P5Home DWORD64 ? P6Home DWORD64 ? ContextFlags DWORD ? MxCsr DWORD ? SegCs WORD ? SegDs WORD ? SegEs WORD ? SegFs WORD ? SegGs WORD ? SegSs WORD ? EFlags DWORD ? Dr0_ DWORD64 ? Dr1_ DWORD64 ? Dr2_ DWORD64 ? Dr3_ DWORD64 ? Dr6_ DWORD64 ? Dr7_ DWORD64 ? Rax_ DWORD64 ? Rcx_ DWORD64 ? Rdx_ DWORD64 ? Rbx_ DWORD64 ? Rsp_ DWORD64 ? Rbp_ DWORD64 ? Rsi_ DWORD64 ? Rdi_ DWORD64 ? R8_ DWORD64 ? R9_ DWORD64 ? R10_ DWORD64 ? R11_ DWORD64 ? R12_ DWORD64 ? R13_ DWORD64 ? R14_ DWORD64 ? R15_ DWORD64 ? Rip_ DWORD64 ? Xmm0_ M128 <> Xmm1_ M128 <> Xmm2_ M128 <> Xmm3_ M128 <> Xmm4_ M128 <> Xmm5_ M128 <> Xmm6_ M128 <> Xmm7_ M128 <> Xmm8_ M128 <> Xmm9_ M128 <> Xmm10_ M128 <> Xmm11_ M128 <> Xmm12_ M128 <> Xmm13_ M128 <> Xmm14_ M128 <> Xmm15_ M128 <> FltSave LEGACY_SAVE_AREA <> Fill DWORD ? DebugControl DWORD64 ? LastBranchToRip DWORD64 ? LastBranchFromRip DWORD64 ? LastExceptionToRip DWORD64 ? LastExceptionFromRip DWORD64 ? Fill1 DWORD64 ? CONTEXT ends .CODE exchdl proc pRecord:ptr, ulframe:qword, pContext:ptr, x4:ptr sub rsp,28h add qword ptr [r8].CONTEXT.Rip_, 1 ;1=size of "in EAX, DX" opcode mov edx, [rcx].EXCEPTION_RECORD64.ExceptionCode mov rcx, CStr("exception code: %X",10) call printf mov eax, 0 ;0=continue execution? add rsp,28h ret exchdl endp VMwareInstalled proc FRAME:exchdl push rbx .pushreg rbx .endprolog mov eax, 0564D5868h mov ebx, 08685D465h mov ecx, 10 mov dx, 05658h in eax, dx cmp ebx, 564D5868h setz al movzx eax,al add rsp,0 pop rbx ret VMwareInstalled endp main proc FRAME sub rsp,28h .allocstack 28h .endprolog mov rcx, CStr("Testing VMware presence",10) call printf call VMwareInstalled lea rcx, CStr("running in VMware",10) and eax, eax jnz @F lea rcx, CStr("NOT running in VMware",10) @@: call printf add rsp,28h ret main endp mainCRTStartup proc sub rsp,28h call main mov ecx,eax call exit mainCRTStartup endp END