- [Duke's Virus Labs #10] - [Page 18] -

墠 win32api c  hardware break point
(c) by Voodoo/SMF


ਢ  ⥡ ⥫, "⥫" ;) .  ⮩     
 墠 㭪権 KERNEL32.dll c  hardware break point. ᫥ 
⮣   "⢀७"  ⠫  १  ६ ,  
  ࠧ.    襭 ⮩ ஡. : 
᪠ ᨬ   㤥 ᪠  ᪠ 㦭  䠩. 
   ⥩訬,   ⮣ 易⥫쭮 ⠢ 
१. ன: 墠뢠 win32api 㭪樨 ࠡ  䠩    
६ 㦭  䠩. 筮   㭪権  ⠡ ⮢  
᢮.  ⮬  ஡: ண  ᯮ   㭪樨,   
뢠  १ GetProcAddress.  室 墠뢠 GetProcAddress, 
஫஢  । 㭪権,   墠뢠,  ⠢ 
᢮ . 墠뢠    㭪樨 ୥  ।⢥ 
 . ਬ,  
                     push  NewMyFunction
                     ret
 ⮬ ᫥ ࠭  樨,   ⠪  믮 .  
ࠧ襭   KERNEL32.dll  ᯮ VirtualAllocEx.  NT  
⮤  ਣ.  9-   ஡: VirtualAllocEx   
    KERNEL32.dll,  ᫨  ய  ring0, 
 " ய   ᮢ". 
 ᫨   i486 [1] ,   ⪭    "।⢠ ⫠".  
   :  " 80386  i486 ⫨  
।⢥   ஬ । ⫠. .... 
  ....
   ⫠ ন ஫ 窨    . 
 饬,   ஫쭮 窮  ,  ᯮ짮 ண 
ணࠬ  ᮡ 砩 ⫠. ⠭ ஫쭮 窨  
 ᯥ稢 ॣ 믮     ."
   ᮡ  ⫠ 뢠 int 1. ࠡ 
  ring3 쬠 ஡筮. Int 1  뢠   蠣 ⫠ 
ணࠬ. 
    ࠡ  砩 ⫠   ring3. 
 ⮣ ᯮ SEH [2].    ⫠ ⥬ 
। ࠢ SEH-  ⮪  맢  砩 ⫠,
c  ⥪⮬    ᪫祭 EXCEPTION_SINGLE_STEP.     
ॡ - ࠡ  ᪫祭.
  ࠧ, ⮡ 墠, ᪠ CreateFileA,  㦭 ந 
᢮ SEH,  㧨  DR0  CreateFileA,  DR7 ⠭  RW0,
LEN0  0, L0  1     맮 :).   SEH    
⮪   HBP (hardware break point) 㤥 ࠡ   ⥪ 
 ⮪. .. ᫨ 㭪 CreateFileA 뢠   ⪨,   
 祣  . 室   樨  墠 
CreateThread. 墠⨢ CreateThread   塞  ⪨   襩 
ணࠬ,  ࠨ SEH  ⠭ HBPs,  ⢥ 
ࠬ ⮪ (lpParameter) ।  ⪨,   뫠 
᪠.  稢  ࠬ  ணࠬ ⤠ 㤠 ࠢ.  
뫮  ४⭥ ।  㪠⥫   : 
 dd  AddressOfNewThread 
 dd  OdlLpParameter
  ⥬ ⠭   ஥ 祭 lpParameter.
       ᫥ ࠡ⪥ EXCEPTION_SINGLE_STEP ᫥  HBP  
""  蠣 ० 믮 ணࠬ, ⠭  EFLAGS  TF=1. 
᫥ 믮   ᭮ ⠭ HBP.  室  
।饭 横.
 ⪮ ⮣ ⮤   ⢮ ॣ஢ ⫠: DR0-DR3.
 ⠪  ⮤ ࠡ⠥  win95  win2k, ..  win32 ᮢ⨬.
 ᥣ ⮣   室  䠩 seh_tr.asm
PS.
  ࠪ⨪, ⮤  .   ᫥ ⮣  , 
墠⨢ ࠡ稪, ⤠ ࠢ ண,  ⠭ ᢮ 
ࠡ稪.  ࠡ稪  祭 㦥   ⭮襭   :(. 
  ।    .  ய稢 calc.exe,   맮 
CreateThread  ᪫祭 (0x80000004) ஥ 㦠 . ⫠ 
,   ࠡ稪 室  3-. .. ⮡  ⮤ ࠡ⠫, 
室  "".   ""?     ।⮨ .
      ⮤ HBP  ᯮ짮   - ⫠,  - ⨪.

. :
[1]   .. ਣ쥢  
"ய i486. ⥪  ணࠬ஢ ( 4- )" 
      1
[2]  http://members.xoom.com/Iczel/Exceptionhandling.html
     http://members.xoom.com/Iczel/files/SEHinASM.zip


===== begin seh_tr.asm =====
; tasm    /m3 /ml seh_tr,,;
; tlink32 /Tpe /aa seh_tr,seh_tr,,import32.lib
                             .386p
                             .model  flat
             include  context.inc ; ᠭ  CONTEXT
             include  wvoodoo.inc ; ᠭ - ⠭  ᯮ⮢
             include  debug32.inc ; ᠭ - ⠭
             include exeption.inc ; -//-
                             .data
                  kernelmane db "KERNEL32.dll",0
               @CreateFileA  db "CreateFileA",0
               @CreateThread db "CreateThread",0
                    FileName db "qwerty.obj",0

                  FileNameis db "File name is : ",0
              @ErrSkip       db "Skip error",0
                       @by   db "Bce ...",0
@EXCEPTION_ACCESS_VIOLATION  db "EXCEPTION_ACCESS_VIOLATION",0
@EXCEPTION_SINGLE_STEP       db "EXCEPTION_SINGLE_STEP",0
@EXCEPTION_BREAKPOINT        db "EXCEPTION_BREAKPOINT",0
                    RegEAX   db 'EAX = '
                    @RegEAX  db 'XXXXXXXXh',0

             @LpCreateFileA  dd ?
             @LpCreateThread dd ?
                  KillThread dd 0
               include hexlib.inc   ;
             include displayc.inc   ; 㠫  CONTEXT
        .code
starts:
           push offset kernelmane      ; 稬  㭪権  ४⮢
           call GetModuleHandleA       ;
           push eax                    ;
           push offset @CreateFileA    ;
           push eax                    ;
           call GetProcAddress         ;
           call NTor9X                 ; ४   ᨬ  .
           mov  @LpCreateFileA,eax     ;
           pop eax                     ;
           push offset @CreateThread   ;
           push eax                    ;
           call GetProcAddress         ;
           call NTor9X                 ;
           mov  @LpCreateThread,eax    ;

           push offset SkipError       ; ன ࠡ稪 訡 
           push    dword ptr fs:[0]    ;  xor eax,eax
           mov     fs:[0],esp          ;  mov [eax],eax
                                       
           call SetMySEH               ; ⢥ 墠 㭪権
    
                                       ; ᪠ 楤  䠩a 
				       ;    MessageBox-, 
           call CreatF                 ;    EIP  DR0.

           xor eax,eax                 ; 塞 䫠 襭 ⮪.
           mov KillThread,eax          ;

           mov [eax],eax               ; ਬ 訡,  ࠡ⠥ SkipError.

           push ecx                    ;  ⮪ CreateF  ࠬ஬ 0x12345678.
           push esp                    ;
           push 0                      ;
           push 12345678h              ;
           push offset CreatF          ;
           push 0                      ;
           push 0                      ;
           call CreateThread           ;  ᪮ MessageBox c ࠬ஬ ⮪ CreateF.
           pop ecx                     ;

           WaitThread:                 ;  襭 ⮪.
           mov eax,KillThread          ;
           or eax,eax                  ;
           jz WaitThread               ;
MdExit:
           push 0                      ;    ...
           push offset @by             ;
           push offset @by             ;
           push 0                      ;
           call MessageBoxA            ;
                                       ;
           push 0                      ;
           call ExitProcess            ;
;------------------------------------------------------------------------
; ४   ᨬ  .
;  9x-ax ᫥ GetProcAddress('KERNEL32.dll','CreateFileA') eax  㪠뢠  ᫥騩  :
;    push  offsett CreateFileA
;    jmp XXXXX
;   㦭 ⮫쪮 offset CreateFileA , .. ᫨  ⠭ 
; HBP    ,(  ⠭  SoftIce-o)    
; ⮭ 맮, ࠩ ⥫쭮 ;).
;
NTor9X:
           cmp byte ptr [eax],068h
           jne NTKernel1
           mov eax,[eax+1]
           NTKernel1:
           ret
;------------------------------------------------------------------------

SetMySEHThread:
           mov ebx,[ebp+12] ;    ࠬ ⮪
           jmp  SetMySEH+1
SetMySEH:  pop ebx

           push offset TraceProc
           push    dword ptr fs:[0]
           mov     fs:[0],esp
           xor eax,eax
excep1:    mov eax,[eax]
nEXTdEBUG:
           push offset RetPrevSEH ; ४ 室  "襣" ⮪
           push ebx
           ret
;------------------------------------------------------------------------
;  襭 ⮪  ret  ୥,   ࠡ稪 SEH 
;  멤  ⮪.
RetPrevSEH:
           xor edx,edx               
           pop dword ptr fs:[edx]    
           pop edx                   
           ret                       
;------------------------------------------------------------------------
; ⨥  ⨥ 䠩. 
CreatF:
           push 0
           push FILE_ATTRIBUTE_ARCHIVE
           push OPEN_EXISTING
           push 0
           push FILE_SHARE_READ
           push GENERIC_READ
           push offset FileName
           call CreateFileA
           push eax
           call CloseHandle

           push 0
           push FILE_ATTRIBUTE_ARCHIVE
           push OPEN_EXISTING
           push 0
           push FILE_SHARE_READ
           push GENERIC_READ
           push offset FileName
           call CreateFileA
           push eax
           call CloseHandle

           mov eax,1
           mov KillThread,eax
           ret
;------------------------------------------------------------------------
;  ࠡ稪 ᪫祭
  TraceProc:
            push edi
            push esi
            mov edi,[esp+4+8]      ; EXEPTION_STURC
            mov esi,[esp+0ch+8]    ; eax=Lp2CONTEXT
            pusha
            mov eax,[edi]
            cmp eax,EXCEPTION_ACCESS_VIOLATION
            ; ᫨  EXCEPTION_ACCESS_VIOLATION ᬮਬ 
            jne NextExc1
            mov eax,[esi+@_EIP]
            cmp eax,offset excep1
            ; ᫨  "" 訡 ⤠ ࠢ ஬ ࠡ稪.
            jne NextExcSys

            mov ebp,offset @EXCEPTION_ACCESS_VIOLATION
            call DisplayCONTEXT
            
            mov eax,offset   nEXTdEBUG        ;  訡
            mov [esi+@_EIP],eax               ;

            call SetHardwareBreakPoints

            jmp ExcepEnd                     ; 蠥 ᪫祭.

 NextExc1:  cmp eax,EXCEPTION_SINGLE_STEP
            jne NextExc2

            mov ebp,offset @EXCEPTION_SINGLE_STEP
            call DisplayCONTEXT

            mov eax,[esi+@_EIP]
            cmp eax,@LpCreateThread
            ; ᫨ EIP=CreateThread  ࠡ 맮 CreateThread
            je HookCreateThread

            cmp eax,@LpCreateFileA
            ; ᫨ (EIP<>CreateFileA)&(EIP<>CreateThread) ⠭ HBP
            jne SetHardwareBP

            mov eax,[esi+@_ESP] ; 㦠 㪠⥫ ⥪  㭪樨 CreateFileA
            add eax,4
            push 0
            push offset FileNameis
            push dword ptr [eax] ; 饭   뢠 䠩.
            push 0
            call MessageBoxA     ;  .

SkipHBP:
            xor eax,eax          ; ⪫砥  HBPs
            mov [esi+@_DR7],eax  ;

            mov [esi+@_DR6],eax  ; ⪠ DR6
            ; 砥 ० 蠣 ⫠.
            or dword ptr [esi+@EFlags],100h ; set TF

            jmp ExcepEnd

SetHardwareBP:
            call SetHardwareBreakPoints
            jmp ExcepEnd

; 墠稪  CreateThread
HookCreateThread:
            mov eax,[esi+@_ESP] ; 㦠 㪠⥫ ⥪  㭪樨  CreateThread
            add eax,12
            push eax
            mov eax,[eax]       ;  ⮪.
            call EAX2HEX
            mov edi,offset @RegEAX
            call EBXEDX2STR
            push 0
            push offset @CreateThread
            push offset  RegEAX
            push 0
            call MessageBoxA   ;  .
            ; ⢥  ࠬ 㤥   ⮪.
            pop eax            
            mov edx,[eax]      
            mov [eax+4],edx    
            ; ⢥    ⮪ 㤥 SetMySEHThread.
            mov edx,offset SetMySEHThread
            mov [eax],edx            ; New Thread address
            
            jmp SkipHBP
;  ࠡ稪 int 3
 NextExc2:  cmp eax, EXCEPTION_BREAKPOINT
            jne NextExcSys
            mov ebp,offset @EXCEPTION_BREAKPOINT
            call DisplayCONTEXT
            dec eax
            jnz Exit2Md
            inc dword ptr [esi+@_EIP]
; 襭 ᪫祭
ExcepEnd:   popa
            pop esi
            pop edi
            xor eax,eax
            ret
; । ࠢ   楯窥 SEH
NextExcSys: popa
            pop esi
            pop edi
            xor eax,eax
            inc eax
            ret
;------------------------------------------------------------------------
Exit2Md:    mov eax,offset MdExit
            mov [esi+@_EIP],eax
            jmp ExcepEnd
;------------------------------------------------------------------------
SkipError:
            push edi
            push esi
            mov edi,[esp+4+8] ; EXEPTION_STURC
            mov esi,[esp+0ch+8]    ; eax=Lp2CONTEXT
            pusha
            mov ebp,offset @ErrSkip
            call DisplayCONTEXT
            mov eax,[edi]
            cmp eax,EXCEPTION_ACCESS_VIOLATION
            jne NextExcSys
            inc dword ptr [esi+@_EIP]
            inc dword ptr [esi+@_EIP]
            jmp ExcepEnd
;-----------------------------------------------------------------
SetHardwareBreakPoints:
            mov eax,@LpCreateFileA            ;㦠 ॣ DR0
            mov [esi+@_DR0],eax

            mov eax,@LpCreateThread           ;㦠 ॣ DR1
            mov [esi+@_DR1],eax

            xor eax,eax
            inc eax
            or eax,Dr7BPX1L
            mov [esi+@_DR7],eax              ; 㦠 ॣ DR7
            ret
end    starts
===== end   seh_tr.asm =====

===== begin context.inc =====
;
FLOATING_SAVE_AREA		STRUC
ControlWord		DD		?
StatusWord		DD		?
TagWord	                DD		?
ErrorOffset		DD		?
ErrorSelector		DD		?
DataOffset		DD		?
DataSelector		DD		?
RegisterArea		DB 	80 DUP (?)
Cr0NpxState		DD		?
FLOATING_SAVE_AREA		ENDS

_CONTEXT		STRUC
@ContextFlags   equ             0
ContextFlags	DD      	?

@_Dr0           EQU             4
_Dr0		DD		?

@_Dr1           EQU             8
_Dr1		DD		?

@_Dr2           EQU             12
_Dr2    	DD              ?

@_Dr3           EQU             16
_Dr3		DD		?

@_Dr6           EQU             20
_Dr6		DD		?

@_Dr7           EQU             24
_Dr7		DD		?

@FloatSave      EQU             28
FloatSave       FLOATING_SAVE_AREA <>
@_Gs            EQU            08ch
_Gs		DD		?

@_Fs            EQU             90h
_Fs		DD		?

@_Es            EQU             94h
_Es		DD		?

@_Ds            EQU             98h
_Ds		DD		?

@_Edi           EQU             9ch
_Edi		DD		?

@_Esi           equ             0A0h
_Esi		DD		?

@_Ebx           EQu             0a4h
_Ebx		DD		?

@_Edx           equ             0a8h
_Edx		DD		?

@_Ecx           equ             0ach
_Ecx		DD		?

@_Eax           equ             0b0h
_Eax		DD		?

@_Ebp           equ             0b4h
_Ebp		DD		?

@_Eip           equ             0b8h
_Eip		DD		?

@_Cs            equ            0bch
_Cs		DD		?

@EFlags         equ             0c0h
EFlags		DD		?

@_Esp           equ             0c4h
_Esp		DD		?

@_Ss            equ             0c8h
_Ss		DD		?
_CONTEXT		ENDS
===== end   context.inc =====

===== begin debug32.inc =====
Dr7BPX0L EQU 0000000000000000000000000000001b
Dr7BPX0G EQU 0000000000000000000000000000010b
Dr7BPX1L EQU 0000000000000000000000000000100b
Dr7BPX1G EQU 0000000000000000000000000001000b
Dr7BPX2L EQU 0000000000000000000000000010000b
Dr7BPX2G EQU 0000000000000000000000000100000b
Dr7BPX3L EQU 0000000000000000000000001000000b
Dr7BPX3G EQU 0000000000000000000000010000000b
===== end   debug32.inc =====

===== begin dislplayc.inc =====
            MSG1 db 'ContextFlag='
ContextFlag      db 'XXXXXXXX',0ah,0dh
                 db 'EAX = '
            rEAX db 'XXXXXXXX',0ah,0dh
                 db 'EBX = '
            rEBX db 'XXXXXXXX',0ah,0dh
                 db 'ECX = '
            rECX db 'XXXXXXXX',0ah,0dh
                 db 'EDX = '
            rEDX db 'XXXXXXXX',0ah,0dh
                 db 'ESI = '
            rESI db 'XXXXXXXX',0ah,0dh
                 db 'EDI = '
            rEDI db 'XXXXXXXX',0ah,0dh
                 db 'EBP = '
            rEBP db 'XXXXXXXX',0ah,0dh
                 db 'ESP = '
            rESP db 'XXXXXXXX',0ah,0dh
                 db 'EIP = '
            rEIP db 'XXXXXXXX',0ah,0dh
                 db 'DR0 = '
            rDR0 db 'XXXXXXXX',0ah,0dh
                 db 'DR1 = '
            rDR1 db 'XXXXXXXX',0ah,0dh
                 db 'DR2 = '
            rDR2 db 'XXXXXXXX',0ah,0dh
                 db 'DR3 = '
            rDR3 db 'XXXXXXXX',0ah,0dh
                 db 'DR6 = '
            rDR6 db 'XXXXXXXX',0ah,0dh
                 db 'DR7 = '
            rDR7 db 'XXXXXXXX',0ah,0dh
                 db 'CS = '
             rCS db 'XXXXXXXX',0ah,0dh
                 db 'DS = '
            rDS db 'XXXXXXXX',0ah,0dh
                 db 'ES = '
            rES db 'XXXXXXXX',0ah,0dh
                 db 'FS = '
            rFS db 'XXXXXXXX',0ah,0dh
                 db 'GS = '
            rGS db 'XXXXXXXX',0ah,0dh
                 db 'SS = '
            rSS db 'XXXXXXXX',0ah,0dh
                 db 'Command : '
         Command db '                                    ',0
;--------------------
; in : esi=LpCONTEXT
DisplayCONTEXT:
       push edi
       mov eax,[esi+@ContextFlags]
       call EAX2HEX
       mov edi,offset ContextFlag
       call EBXEDX2STR
       mov eax,[esi+@_EAX]
       call EAX2HEX
       mov edi,offset rEAX
       call EBXEDX2STR

       mov eax,[esi+@_EBX]
       call EAX2HEX
       mov edi,offset rEBX
       call EBXEDX2STR

       mov eax,[esi+@_ECX]
       call EAX2HEX
       mov edi,offset rECX
       call EBXEDX2STR

       mov eax,[esi+@_EDX]
       call EAX2HEX
       mov edi,offset rEDX
       call EBXEDX2STR

       mov eax,[esi+@_ESI]
       call EAX2HEX
       mov edi,offset rESI
       call EBXEDX2STR

       mov eax,[esi+@_EDI]
       call EAX2HEX
       mov edi,offset rEDI
       call EBXEDX2STR

       mov eax,[esi+@_EBP]
       call EAX2HEX
       mov edi,offset rEBP
       call EBXEDX2STR

       mov eax,[esi+@_ESP]
       call EAX2HEX
       mov edi,offset rESP
       call EBXEDX2STR

       mov eax,[esi+@_EIP]
       call EAX2HEX
       mov edi,offset rEIP
       call EBXEDX2STR

       mov eax,[esi+@_DR0]
       call EAX2HEX
       mov edi,offset rDR0
       call EBXEDX2STR

       mov eax,[esi+@_DR1]
       call EAX2HEX
       mov edi,offset rDR1
       call EBXEDX2STR

       mov eax,[esi+@_DR2]
       call EAX2HEX
       mov edi,offset rDR2
       call EBXEDX2STR

       mov eax,[esi+@_DR3]
       call EAX2HEX
       mov edi,offset rDR3
       call EBXEDX2STR

       mov eax,[esi+@_DR6]
       call EAX2HEX
       mov edi,offset rDR6
       call EBXEDX2STR

       mov eax,[esi+@_DR7]
       call EAX2HEX
       mov edi,offset rDR7
       call EBXEDX2STR

       mov eax,[esi+@_CS]
       call EAX2HEX
       mov edi,offset rCS
       call EBXEDX2STR

       mov eax,[esi+@_DS]
       call EAX2HEX
       mov edi,offset rDS
       call EBXEDX2STR

       mov eax,[esi+@_ES]
       call EAX2HEX
       mov edi,offset rES
       call EBXEDX2STR

       mov eax,[esi+@_FS]
       call EAX2HEX
       mov edi,offset rFS
       call EBXEDX2STR

       mov eax,[esi+@_GS]
       call EAX2HEX
       mov edi,offset rGS
       call EBXEDX2STR

       mov eax,[esi+@_SS]
       call EAX2HEX
       mov edi,offset rSS
       call EBXEDX2STR
       pop edi
       push 1
       push ebp
       push offset MSG1
       push 0
       call MessageBoxA
       ret
EBXEDX2STR:
       mov eax,ebx
       call HEXEAX2STR
       mov eax,edx
       call HEXEAX2STR
       ret
HEXEAX2STR:
       mov ecx,4
       NextChar:
       rol eax,8
       cld
       stosb
       loop NextChar
       ret
===== end   displayc.inc =====

===== begin exeption.inc =====
DEBUG   EQU 1  ;  ⫠ .
NODEBUG EQU 0  ;  ⠪ 㤭
DEBUGFLAG EQU DEBUG

         EXCEPTION_SINGLE_STEP EQU 080000004h
         EXCEPTION_BREAKPOINT EQU 080000003h
   EXCEPTION_ACCESS_VIOLATION EQU 0C0000005h
EXCEPTION_ILLEGAL_INSTRUCTION EQU 0C000001Dh

 IF DEBUGFLAG
    EXEPTION EQU dw 0ffffh,090c3h,9090h
    ELSE
    EXEPTION EQU db 0cch
 ENDIF
 IF DEBUGFLAG
  BreakPoint EQU db 0cch
    ELSE
  BreakPoint EQU ;
 ENDIF

callEx macro Arg
       ; call Arg
       push z&Arg
       exeption
       endm
===== end   exeption.inc =====

===== begin hexlib.inc =====
;;ம।  㠫樨 ॣ஢ al, ah, ax, eax
;; 室:
;;arg_n -    ॣ஢ al,ah,ax,eax
;; 室:
;;     dx=Hex8bit
;;    edx=Hex16Bit
;;ebx:edx=Hex32bit
Hex	MACRO	arg_n
LOCAL	main_part,disp,pause,template,VideoBuffer,p_mode,m1,m2,Load2Video
FALSE	equ	0	;;
TRUE	equ	0ffffh	;;⨭
?reg8bit=false	;;䫠 ⮣,  । ॣ al
?reg16bit=false	;;䫠 ⮣,  । ॣ ax
?reg32bit=false	;;䫠 ⮣,  । ॣ eax
?unknow=false
 IFIDNI <al>,<&arg_n>
        ?reg8bit=true
        ?unknow=true
        ENDIF
    IFIDNI <ax>,<&arg_n>
        ?reg16bit=true
        ?unknow=true
        ENDIF
    IFIDNI <eax>,<&arg_n>
        ?reg32bit=true
        ?unknow=true
        ENDIF
    IF (?unknow)
     IF (?reg8bit)
        push eax
        and al,00001111b
        call AL2HEX
        mov dl,al
        pop eax
        and al,11110000b
        shr al,4
        call AL2HEX
        mov dh,al
        ;; dx=al in HEX
        ENDIF
    IF (?reg16bit)
        push eax
        mov al,ah
        and al,00001111b
        call AL2HEX
        mov dl,al
        pop eax
        push eax
        and al,11110000b
        shr al,4
        call AL2HEX
        mov dh,al
        ;; dx=ah in HEX
        shl edx,16
        pop eax
        and al,00001111b
        call AL2HEX
        mov dl,al
        pop eax
        push eax
        and al,11110000b
        shr al,4
        call AL2HEX
        mov dh,al
        ;; edx=ax in HEX
        ENDIF
 IF (?reg32bit)                 ;; eax=AB CD EF 12h
         push eax
         shr eax,8+8+8
         push ax                ;; ax=ABh
         shr al,4
         call AL2HEX
         mov bh,al               ;; bh='A'
         pop ax
         and al,00001111b
         call AL2HEX
         mov bl,al               ;; bl='B'
         shl ebx,16              ;; Hi(ebx)='AB'
        pop eax
        push eax
          shr eax,8+8
          push ax       ;; ax=CDh
          shr al,4
          ;; al=Ch
          call AL2HEX
          mov bh,al               ;; bh='C'
          pop ax
          and al,00001111b
          call AL2HEX
          mov bl,al               ;; bl='D'
                                  ;; bx='CD'
        pop eax
        push eax
           shr eax,8
           push ax   ;; ax=EFh
           shr al,4
           ;; al=Eh
           call AL2HEX
           mov dh,al               ;; dh='E'
           pop ax
           and al,00001111b
           call AL2HEX
          mov dl,al               ;; dl='F'
          shl edx,16              ;; HI(edx)='EF'
        pop eax
           push ax   ;; ax=12h
           shr al,4  ;; al=1h
           call AL2HEX
           mov dh,al  ; dh='1'
           pop ax
           and al,00001111b
           call AL2HEX
           mov dl,al               ;; dl='2'   -> dx='12'
         ;;ebx='ABCD', EDX='EF12'
        ENDIF
   ENDIF
   ENDM
EAX2HEX:
        Hex eax
        ret
AX2HEX: Hex ax
        ret
AltoHEX: Hex al
         ret

AL2HEX:add al,90h
       daa
       adc al,3ah
       daa
       ret
===== end   hexlib.inc =====

===== begin wvoodoo.inc =====
NULL = 0
; GlobalAlloc flags
GMEM_FIXED      =   0000h
GMEM_MOVEABLE   =   0002h
GMEM_NOCOMPACT  =   0010h
GMEM_NODISCARD  =   0020h
GMEM_ZEROINIT   =   0040h
GMEM_MODIFY     =   0080h
GMEM_DISCARDABLE=   0100h
GMEM_NOT_BANKED =   1000h
GMEM_DDESHARE   =   2000h
GMEM_SHARE      =   2000h
GMEM_NOTIFY     =   4000h
GMEM_LOWER      =   GMEM_NOT_BANKED
GHND            =   GMEM_MOVEABLE+GMEM_ZEROINIT
GPTR            =   GMEM_FIXED+GMEM_ZEROINIT
;-----------
 FILE_ATTRIBUTE_READONLY     =    00000001h
 FILE_ATTRIBUTE_HIDDEN       =    00000002h
 FILE_ATTRIBUTE_SYSTEM       =    00000004h
 FILE_ATTRIBUTE_DIRECTORY    =    00000010h
 FILE_ATTRIBUTE_ARCHIVE      =    00000020h
 FILE_ATTRIBUTE_NORMAL       =    00000080h
 FILE_ATTRIBUTE_TEMPORARY    =    00000100h
;-----------
FILE_FLAG_WRITE_THROUGH         = 80000000h
FILE_FLAG_OVERLAPPED            = 40000000h
FILE_FLAG_NO_BUFFERING          = 20000000h
FILE_FLAG_RANDOM_ACCESS         = 10000000h
FILE_FLAG_SEQUENTIAL_SCAN       = 08000000h
FILE_FLAG_DELETE_ON_CLOSE       = 4000000h
FILE_FLAG_BACKUP_SEMANTICS      = 02000000h
FILE_FLAG_POSIX_SEMANTICS       = 01000000h

;------------------------
CREATE_NEW         = 1
CREATE_ALWAYS      = 2
OPEN_EXISTING      = 3
OPEN_ALWAYS        = 4
TRUNCATE_EXISTING  = 5

;-----------
GENERIC_READ               = 80000000h
GENERIC_WRITE              = 40000000h
FILE_SHARE_READ            = 00000001h
FILE_SHARE_WRITE           = 00000002h
;-----------
 PAGE_NOACCESS          = 01h
 PAGE_READONLY          = 02h
 PAGE_READWRITE         = 04h
 PAGE_WRITECOPY         = 08h
 PAGE_EXECUTE           = 10h
 PAGE_EXECUTE_READ      = 20h
 PAGE_EXECUTE_READWRITE = 40h
 PAGE_EXECUTE_WRITECOPY = 80h
 PAGE_GUARD             = 100h
 PAGE_NOCACHE           = 200h
;-------------------
FILE_MAP_WRITE = 2
FILE_MAP_READ  = 4
;-------------------
 NORMAL_PRIORITY_CLASS      = 00000020h
 IDLE_PRIORITY_CLASS        = 00000040h
 HIGH_PRIORITY_CLASS        = 00000080h
 REALTIME_PRIORITY_CLASS    = 00000100h
;--------------------
EXCEPTION_DEBUG_EVENT      = 1
CREATE_THREAD_DEBUG_EVENT  = 2
CREATE_PROCESS_DEBUG_EVENT = 3
EXIT_THREAD_DEBUG_EVENT    = 4
EXIT_PROCESS_DEBUG_EVENT   = 5
LOAD_DLL_DEBUG_EVENT       = 6
UNLOAD_DLL_DEBUG_EVENT     = 7
OUTPUT_DEBUG_STRING_EVENT  = 8
RIP_EVENT                  = 9
;--------------------
PROCESS_ALL_ACCESS  =   0F0000h or 00100000h or 0FFFh
;--------------------locals
        extrn   MessageBoxA:PROC
        extrn   Sleep:PROC
        extrn   ExitProcess:PROC
        extrn   CreateThread:PROC
        extrn   GetLastError:PROC
        extrn   GetModuleHandleA:PROC
        extrn   ExitProcess:PROC
        extrn   GetProcAddress:PROC
        extrn   GetModuleHandleA:PROC
        extrn   GetCurrentThread:PROC
        extrn   VirtualProtectEx:PROC
        extrn   DebugActiveProcess:Proc
        extrn   OpenProcess:PROC
        extrn   WriteProcessMemory:PROC
        extrn   SuspendThread:PROC
        extrn   GetCurrentProcessId:PROC
        extrn   LoadLibraryA:PROC
        extrn   MessageBoxA:PROC
        extrn   MessageBeep:PROC
        extrn   GlobalAlloc:PROC ; retern HGLOBAL
                ; UINT Flags  object allocation attributes
                ; DWORD dwBytes mumber of bytes to allocate
        extrn   GlobalLock:PROC ;Pointer to mem
                ; HGLOBAL hMem address of global memory object
        extrn   GlobalUnlock:PROC
                ; HGLOBAL hMem address of global memory object
        extrn   GlobalFree:PROC
                ;HGlobal hMem handle to the global memory object
     ;---- file mapping --------------------------------------
      extrn CreateFileA:PROC
     ;Retern HANDLE
     ;Parametrs:    LPCTSTR :LpFileName
     ;              DWORD   :dwDesiredAccess (read-write)
     ;              DWORD   : dwShareMode
     ; LPSECURITY_ATTRIBTES :LpSecurityAttrib address of security descriptor
     ;              DWORD   :dwCreationDistribution //how to creat
     ;              DWORD   :dwFlagsAndAttributes
     ;             HANDLE   :hTemplateFile //handle of file with attrib to copy
     extrn CreateFileMappingA:PROC
     ;Retern HANDLE
     ; PARAMMETRS    HANDLE :hfile    //handle of file map
     ;  LpSecurity_Attributes LpFileMappingAttributes //optional security attrib
     ;  Dword  :flProtect
     ;  Dword  :dwMaxSizeHigh
     ;  Dword  :dwMaxSizeLow
     ; LPCTSTR :lpName //name of file-mapping object
     extrn MapViewOfFile:PROC ;(hFileMappingObject:HANDLE,
                              ;  dwDesiredAccess:dw,
                              ;  dwFileOffsetHigh,
                              ;  dwFileOffsetLow,
                              ;  dwNumberOfBytesToMap)
     ;
     ;
     ;
     extrn UnmapViewOfFile:PROC
     extrn CloseHandle:PROC
     extrn FlushViewOfFile:PROC;(LpBaseAddress,dwNumberOfBytesToFlush)
    ;--------------------------------------------------------
     extrn GetFileSize:PROC ; (hFile,LPDWORD LpFileSizeHigh)
     extrn CopyFileA:PROC ;(LpExistingFileName,LpNewFileName)
     extrn ReadFile:PROC  ;(hFile,LpBuffer,nMumberOfBytesToRead,
     ;                    LpNumberOfBytesRead,LpOverlapped)
     extrn DeleteFileA    :PROC;(LpFileName)
     extrn GetLastError  :PROC;
     extrn CreateProcessA:PROC;
     extrn CreateProcessW:PROC;
     extrn CreateFileW:PROC;
     extrn GetStartupInfoA:PROC;
     extrn GetCommandLineA:PROC;
     extrn lstrcpyA:PROC;
     extrn   FindFirstFileA:PROC
     extrn   FindNextFileA:PROC
     extrn   Sleep:PROC ;(dwMilliseconds)
     extrn SetFileAttributesA:PROC;(LpFileName,dwFileAttributes)
     extrn SetFileTime:PROC;
     extrn SetCurrentDirectoryA:PROC;
     extrn GetCurrentDirectoryA:PROC;
     extrn GetExitCodeProcess:PROC;
     extrn GetSystemTime:PROC;
===== end   wvoodoo.inc =====
