                         The Prefetch Buffer Problem
                            By: Techno Phunk / Ti

                                 - TI #1 -

[Introduction]

        O.k, I've noticed that almost EVERY virus I see these days in
source, is realy not a working virus, in all respects, and mostly, because
most of you are using machines like a P2 MMX, and so on. However, in your
luck of owning such a machine, you have forgoten about the greater population
owning a 486 or a normal 586. These machines have a thing called the
Prefetch Queue Buffer. Well, all machines do, however these have a problem
with the SIZE of this. These machines will probably crash if infected. This
article will attempt to cover WHY this happens, and HOW to fix it. I just wrote
this in about 5 minutes, so, please bare with it. I wrote it just because
I was seeing A LOT of people's viruses being both TI members, and others
outside of TI, that where crashing on my 486, when I tested them. This is
easily bypassed, and so, I am going to post both a reminder and a teaching
in one. (reminder for you leet people, and learning for you newbies)

[More Information]

        Basicly, the problem is that these select proccessers of ALL of
them, use a larger cache, and thus, life sucks for viruses. 

        Now, the problem, is that these proccesers use a "Large" Cache
memory, which reads in lots of instructions into this cache. Oviosly, the
code won't be changed in the cache, but in the RAM, and since the RAM and
Cache are NOT equal, the HOST will crash....

RAM           CACHE
-----        -------
xxyyy         yyyxx
                 ^ this is what is ran.
 ^ this is what we want.

Note that the RAM and Cache are diffrent, which, will cause a ovios, and
rather bad, problem.

Just as an example, The following silly program will demonstrate how
a program can crash due to this "bug"

[Silly Program]

; Silly example of the Prefetch Queue problem...
; tasm silly.asm
; tlink /t silly.obj

Code Segment
Assume Cs:Code,Ds:Code,Es:Code

Org 100h

Silly:                       
Mov Word Ptr Cs:[107h],20CDh ; modifies the next instruction (at offset 107)

Mov Ah,9                    ; this code does not run...is replaced by int 20h
Lea Dx,Msg
Int 21h


Msg Db 'Coding is fun! and is good for the soul$'
;          ^ stupid comment ;)

Code Ends
End Silly

---End Silly.asm---

The above program,  if ran under a 486 or 586, will CRASH....However, if
you are under a non-bugy-prefetch processer, then, you are fine, and it'll just
do a Int 20h, and exit.

[Fixing this Bug]

Well, you may be thinking "oh gosh!" this is another Kilobyte of crap I'm
gonna have to my virus. Well, no, not realy....try about, 3 bytes, or
even only *1*. This, thing is easy to fix. In order to fix the bug, we simply
FLUSH the Buffer. This fix also (luckily), does not interfear with ANYTHING
else in the virus, so nothing else needs to be changed, besides the
adding of a simple instruction. Now, for the TWO methods, I'll tell you about
the larger one first, as it is the "standard" way of doing this. And, since
history is always a great thing, I'll go ahead and present that way first.

Jmp short $+2

This or ANY kind of "do-nothing" jump, will very easily, and smoothly, flush
out this buffer.

So, we wind up with something like this in an EXE infector:

        Jmp short $+2

Jumpers:
	Db 0Eah
	Old_Ip Dw 0
	Old_Cs Dw 0
	Old_Sp Dw 0
	Old_Ss Dw 0

-

Now, the *fun* part. But, first, a small explanation on WHY these things work.
O.k, basicly, when the CPU flushes the cache, it's because IP has made a jump.
IP as we know, is a register. This happens anytime there is a JMP, int, etc.
The next method, is probably the best optomised, and works in a similar fasion.

We will use Int 3h, a do nothing (when called normaly), *1* byte interupt.
Yes, the ONLY interupt that is ONE byte long. It's op code (for those wondering)
is: 0cch (0 truncates of course)....Anyhow, when called, the CPU will agian,
flush the prefetch buffer... O.k, I now remembered that I lied, yes you heard
me...I l-i-e-d....there is ONE other interupt that is only one byte...but it's
undocumented, and this is the op code: f1h....it is Int 1h, only in 1 byte.
Usualy is writen as CD01h (how dumb)

so:

Int 3h

Jumpers:
[...]

You could also do any do-nothing interupt that you want...

Understand?  I sure hope so, it's realy a simple thing, and no virus should
be without it!!! It's critical that you *stay* compatible, don't screw up
your hosts ;).

Note, this also could be used for anti-debuging purposes, but, your virus would
no longer run on a 486 or 586. Think about it.

                                                      - Techno Phunk -
