In converting some code like this:
http://www.delphi3000.com/articles/article%5F4135.asp?SK=
or this
http://www.codeproject.com/KB/system/VmDetect.aspx
or this
http://www.powerbasic.com/support/pbforums/showthread.php?t=24024
I do not understand much about how to handle exceptions at the OS level
This is the best article I've found so far:
http://www.jorgon.freeserve.co.uk/Except/Except.htm
and MSDN documents the OS functions here:
http://msdn.microsoft.com/en-us/library/aa363082(VS.85).aspx
The powerbasic code for example, works on Win XP an server 2003, but not on Server 2008 or win7, so first I need to understand more about how to implement a bullet proof exception handler. What is a good approaoh in the context of the VMware detection?
everything you're ask has been posted on this forum before, just search, the session handlin stuff probably be under SEH
Im sorry I am not sure what topics I should be looking for. I did a thorough search of this forum, but I am not clear what I am looking for.
under the search term you suggested SEH I found nothing with the SMF serarch engine, and three with google that seemed to b unrelated
http://www.masm32.com/board/index.php?PHPSESSID=c80cbbbf6e6cf2b30889977a426f07f9&action=printpage;topic=10925.0
http://www.masm32.com/board/index.php?PHPSESSID=63414a5b6ee6899dbcb9080c0ec4bcf3&action=printpage;topic=12183.0
http://www.masm32.com/board/index.php?PHPSESSID=c675bbbd7468cdc0c9aef478bf63fd63&action=printpage;topic=10848.0
I'm not trying to be lazy, i'm just not sure what I'm looking for. If you could give me just a little more to work with?
Quote from: MikeT on December 21, 2009, 01:47:07 AM
Im sorry I am not sure what topics I should be looking for. I did a thorough search of this forum, but I am not clear what I am looking for.
I'm also not quite sure if it is possible to detect VMware from a ring-3 Win32 application. But if it is possible, then the following code "should" work:
;--- detecting VMware
.386
.MODEL FLAT, stdcall
option casemap:none
GetStdHandle proto stdcall :DWORD
WriteConsoleA proto stdcall :DWORD, :DWORD, :DWORD, :DWORD, :DWORD
ExitProcess proto stdcall :DWORD
wvsprintfA proto stdcall :ptr, :ptr, :ptr
STD_OUTPUT_HANDLE equ -11
CONTEXT struct
dd ? ;context flags
dd 6 dup (?) ;DRx regs
db 112 dup (?) ;FP status
dd 4 dup (?) ;segment regs
rEdi dd ?
rEsi dd ?
rEbx dd ?
rEdx dd ?
rEcx dd ?
rEax dd ?
rEbp dd ?
rEip dd ?
SegCs dd ?
EFlags dd ?
rEsp dd ?
SegSs dd ?
CONTEXT ends
CStr macro text:VARARG
local x
.const
x db text,0
.code
exitm <offset x>
endm
.code
printf proc c uses ebx pszFormat:ptr byte, args:VARARG
local dwWritten:dword
local szText[256]:byte
invoke GetStdHandle, STD_OUTPUT_HANDLE
mov ebx, eax
invoke wvsprintfA, addr szText, pszFormat, addr args
lea ecx, dwWritten
invoke WriteConsoleA, ebx, addr szText, eax, ecx, 0
ret
align 4
printf endp
VMware proc
assume fs:nothing
xor edx,edx
push offset myexc
push fs:[edx]
mov fs:[edx],esp
mov eax, 564D5868h ;magic number (="VMXh")
mov cx, 000ah ;command number (000A=get VMware version)
xor ebx,ebx ;command specific parameter
mov dx, 5658h ;VMware IO port (="VX")
in eax,dx ;"returns" version number in EAX
donebrp:
cmp ebx, 564D5868h ;and magic number in EBX (="VMXh")
setz al
movzx eax,al
pop fs:[0]
add esp,4
ret
myexc:
mov eax, [esp+12] ;get context
mov [eax].CONTEXT.rEip, offset donebrp
xor eax, eax ;== _XCPT_CONTINUE_EXECUTION
retn
align 4
VMware endp
start:
invoke VMware
invoke printf, CStr("VMware()=%u",10), eax
invoke ExitProcess, 0
END start
It's possible to detect vmware in ring3, here's simple code to do it, along with easy SEH macro's, the title of the thread ironically is SEH
http://www.masm32.com/board/index.php?topic=11065.msg81886#msg81886
Cube,
Thats not bad looking SEH code, have you bothered to give it a hammering to see what it does and what it will handle ?
Here is another simple and very limited set of macros that I think will work for this, along with a test app.
;==============================================================================
LPEXCEPTION_POINTERS typedef ptr EXCEPTION_POINTERS
;-----------------------------------------------------------------
; This macro sets the top-level exception filter for the calling
; process to our try_filter procedure, so when an unhandled
; exception reaches the UnhandledExceptionFilter function, and
; the process is not being debugged, the function will call our
; procedure. The return_address parameter specifies the address
; of a label were execution will continue if an exception occurs.
; Use this macro to begin a guarded section of code.
;-----------------------------------------------------------------
try_begin macro return_address
push return_address
pop _exception_return_address_
invoke SetUnhandledExceptionFilter, try_filter
mov _previous_exception_filter_, eax
endm
;----------------------------------------------------------------
; This macro sets the top-level exception filter for the calling
; process to what it was before the try_begin macro changed it.
; Use this macro to end a guarded section of code.
;----------------------------------------------------------------
try_end macro
invoke SetUnhandledExceptionFilter, _previous_exception_filter_
endm
;==============================================================================
.data
_exception_return_address_ dd 0
_previous_exception_filter_ dd 0
exception_record EXCEPTION_RECORD <>
.code
;==============================================================================
;---------------------------------------------------
; This procedure is our top-level exception filter.
;---------------------------------------------------
try_filter proc lpexception_pointers:LPEXCEPTION_POINTERS
;--------------------------------------------------------------
; Copy the entire EXCEPTION_RECORD structure to global memory.
;--------------------------------------------------------------
mov edx, lpexception_pointers
mov ecx, [edx].EXCEPTION_POINTERS.pExceptionRecord
mov edx, offset exception_record
DISP=0
repeat (sizeof EXCEPTION_RECORD) / 4
mov eax, [ecx+DISP]
mov [edx+DISP], eax
DISP=DISP+4
endm
;------------------------------------------------------------------
; Modify the EIP member of the CONTEXT structure so execution will
; continue at the address passed to the try_begin macro, instead
; of continuing at the point of the exception (which would cause
; the exception to repeat).
;------------------------------------------------------------------
mov edx, lpexception_pointers
mov eax, [edx].EXCEPTION_POINTERS.ContextRecord
push _exception_return_address_
pop [eax].CONTEXT.regEip
;------------------------------------------------------------------------
; Returning EXCEPTION_CONTINUE_EXECUTION to the UnhandledExceptionFilter
; function will cause it to return and continue execution from the point
; specified in the EIP member of the CONTEXT structure.
;------------------------------------------------------------------------
return EXCEPTION_CONTINUE_EXECUTION
try_filter endp
;==============================================================================
;==============================================================================
include \masm32\include\masm32rt.inc
include try.asm
;==============================================================================
.data
.code
;==============================================================================
PEXCEPTION_RECORD typedef ptr EXCEPTION_RECORD
EXCEPTION_NONCONTINUABLE_EXCEPTION equ 0C0000025h
EXCEPTION_STACK_OVERFLOW equ 0C00000FDh
EXCEPTION_INVALID_DISPOSITION equ 0C0000026h
EXCEPTION_GUARD_PAGE equ 080000001h
EXCEPTION_INVALID_HANDLE equ 0C0000008h
ShowException proc uses ebx per:PEXCEPTION_RECORD
mov ebx, per
SWITCH [ebx].EXCEPTION_RECORD.ExceptionCode
CASE EXCEPTION_ACCESS_VIOLATION
print "EXCEPTION_ACCESS_VIOLATION"
CASE EXCEPTION_DATATYPE_MISALIGNMENT
print "EXCEPTION_DATATYPE_MISALIGNMENT"
CASE EXCEPTION_BREAKPOINT
print "EXCEPTION_BREAKPOINT"
CASE EXCEPTION_SINGLE_STEP
print "EXCEPTION_SINGLE_STEP"
CASE EXCEPTION_ARRAY_BOUNDS_EXCEEDED
print "EXCEPTION_ARRAY_BOUNDS_EXCEEDED"
CASE EXCEPTION_FLT_DENORMAL_OPERAND
print "EXCEPTION_FLT_DENORMAL_OPERAND"
CASE EXCEPTION_FLT_DIVIDE_BY_ZERO
print "EXCEPTION_FLT_DIVIDE_BY_ZERO"
CASE EXCEPTION_FLT_INEXACT_RESULT
print "EXCEPTION_FLT_INEXACT_RESULT"
CASE EXCEPTION_FLT_INVALID_OPERATION
print "EXCEPTION_FLT_INVALID_OPERATION"
CASE EXCEPTION_FLT_OVERFLOW
print "EXCEPTION_FLT_OVERFLOW"
CASE EXCEPTION_FLT_STACK_CHECK
print "EXCEPTION_FLT_STACK_CHECK"
CASE EXCEPTION_FLT_UNDERFLOW
print "EXCEPTION_FLT_UNDERFLOW"
CASE EXCEPTION_INT_DIVIDE_BY_ZERO
print "EXCEPTION_INT_DIVIDE_BY_ZERO"
CASE EXCEPTION_INT_OVERFLOW
print "EXCEPTION_INT_OVERFLOW"
CASE EXCEPTION_PRIV_INSTRUCTION
print "EXCEPTION_PRIV_INSTRUCTION"
CASE EXCEPTION_IN_PAGE_ERROR
print "EXCEPTION_IN_PAGE_ERROR"
CASE EXCEPTION_ILLEGAL_INSTRUCTION
print "EXCEPTION_ILLEGAL_INSTRUCTION"
CASE EXCEPTION_NONCONTINUABLE_EXCEPTION
print "EXCEPTION_NONCONTINUABLE_EXCEPTION"
CASE EXCEPTION_STACK_OVERFLOW
print "EXCEPTION_STACK_OVERFLOW"
CASE EXCEPTION_INVALID_DISPOSITION
print "EXCEPTION_INVALID_DISPOSITION"
CASE EXCEPTION_GUARD_PAGE
print "EXCEPTION_GUARD_PAGE"
CASE EXCEPTION_INVALID_HANDLE
print "EXCEPTION_INVALID_HANDLE"
DEFAULT
print "exception code "
print hex$([ebx].EXCEPTION_RECORD.ExceptionCode)
ENDSW
print " @ "
print hex$([ebx].EXCEPTION_RECORD.ExceptionAddress),"h",13,10
ret
ShowException endp
;==============================================================================
IsVMwarePresent proc
try_begin x
mov eax, 564D5868h
xor ebx, ebx
mov ecx, 0000000Ah
mov edx, 00005658h
in eax, dx
cmp ebx, 564D5868h
jne x
try_end
mov eax, 1
ret
x:
invoke ShowException, addr exception_record
try_end
xor eax, eax
ret
IsVMwarePresent endp
;==============================================================================
start:
;==============================================================================
try_begin x1
mov ecx, 1
xor edx, edx
try1:
div ecx
print "no exception",13,10
jmp @f
x1:
invoke ShowException, addr exception_record
print hex$(try1),"h",13,10
@@:
try_end
try_begin x2
xor ecx, ecx
xor edx, edx
try2:
div ecx
print "no exception",13,10
jmp @f
x2:
invoke ShowException, addr exception_record
print hex$(try2),"h",13,10
@@:
try_end
try_begin x3
xor eax, eax
try3:
mov eax, [eax]
print "no exception",13,10
jmp @f
x3:
invoke ShowException, addr exception_record
print hex$(try3),"h",13,10
@@:
try_end
try_begin x4
try4:
dd 0ffffffffh
print "no exception",13,10
jmp @f
x4:
invoke ShowException, addr exception_record
print hex$(try4),"h",13,10
@@:
try_end
try_begin x5
try5:
int 3
print "no exception",13,10
jmp @f
x5:
invoke ShowException, addr exception_record
print hex$(try5),"h",13,10
@@:
try_end
try_begin x6
try6:
invoke RaiseException, 1234h, 0, 0, 0
print "no exception",13,10,13,10
jmp @f
x6:
invoke ShowException, addr exception_record
print hex$(try6),"h",13,10,13,10
@@:
try_end
invoke IsVMwarePresent
print str$(eax),13,10,13,10
inkey "Press any key to exit..."
exit
;==============================================================================
end start
no exception
EXCEPTION_INT_DIVIDE_BY_ZERO @ 004013B5h
004013B5h
EXCEPTION_ACCESS_VIOLATION @ 00401421h
00401421h
EXCEPTION_ILLEGAL_INSTRUCTION @ 0040148Bh
0040148Bh
EXCEPTION_BREAKPOINT @ 004014F7h
004014F7h
exception code 00001234 @ 7C59BCB1h
00401560h
EXCEPTION_PRIV_INSTRUCTION @ 004012F4h
0
Quote from: hutch-- on December 21, 2009, 11:44:22 PM
Cube,
Thats not bad looking SEH code, have you bothered to give it a hammering to see what it does and what it will handle ?
I haven't used it extensively but as BlackVortex mentioned is doesn't change any registers, and the times I have used it i've had no problems.
maybe what Hutch meant was - has it been tested on a variety of OS's
i can only test it on XP
Mike was looking for something that will work on all windows OS's
the one he has doesn't work under server 2008 or win7
ill test on win7 real quick
update, tested both simotaniously, seems to work fine
update 2, works on windows xp pro x64 too
update 3, works on windows vista home
(http://img46.imageshack.us/img46/3259/27071549.jpg)
>the title of the thread ironically is SEH
Urgh... now I feel like an idiot. You are right. I was looking within the body of the search results which returned a lot of cloSEHandle etc.
Thank you for your patience. That says a lot. Thank you for that code. I am going to study it.
Michael,
Thanks for the example, I just copied and built it and it works perfectly.