Copy Link
Add to Bookmark
Report
Xine - issue #5 - Phile 103
Ú-----------------------------¿
| Xine - issue #5 - Phile 103 |
À-----------------------------Ù
Metamorphism essay - part II
a bit more technical
Hello again my dear readers. I've written the original 'Metamorphism Essay'
some time ago, and was published in Xine-4. I haven't previewed to write a
continuation of it, but some more metamorphism ideas (and some more techni-
cal stuff) came up to my mind, so i wanted to write another document about
that matter. If you didn't liked the 'part I', there is no reason for read
this one. Btw, as this is a 'part II', i assume you've read the 'part I' :)
By the way, thanx to Qozah/29A for supporting me and suggesting meta ideas.
Ú----------------------------------------------¿
| Introduction to Metamorphism Essay - part II |
À----------------------------------------------Ù
The 'part I' was my first contribution as iKXer. Ok, cool. But now i've re-
searched a bit more on it, so i can teach you some more interesting things.
The metamorphism is a technique so far away from all those lamers and/or
wanabees, even from the newbies, or the people with medium skills. It's just
an elite technique (even if i don't like this word, as it's discriminative
and shows the lameness of the people that claims himself to be it). In this
document i'll do a deeper description of some methods and ideas that could
be useful, always for Win32, not DOS (i've forgotten all about DOS code).
Ú----------------¿
| Block swapping |
À----------------Ù
No, don't blame me. This is *NOT* metamorphism. But i think it can be a gre-
at addition to your meta virus. Just see the DOS virus Bad Boy, it swaps
blocks of code between them. Ok, the blocks are big enough for let an AV
catch an scan string for your virus, but imagine it with code expanding and
shrinking (alternatively), register swapping and such... Simply unreachable!
Let's me do some grafx (of how should be virus code w/ 4 swappable blocks):
Ú--------¿ Ú--------¿ Ú--------¿
| Header | | Header | | Header |
Ã--------´ Ã--------´ Ã--------´
| Exec | | Exec | | Exec |
Ã--------´ Ã--------´ Ã--------´
| Block1 | BSE | Block3 | BSE | Block2 | BSE
Ã--------´ --> Ã--------´ --> Ã--------´ --> [...]
| Block2 | | Block1 | | Block4 |
Ã--------´ Ã--------´ Ã--------´
| Block3 | | Block2 | | Block1 |
Ã--------´ Ã--------´ Ã--------´
| Block4 | | Block4 | | Block3 |
À--------Ù À--------Ù À--------Ù
As you can see, there are two blocks that don't change of place (but inter-
nally one of them do). Well, i guess i'd have to explain the terms i've used
here.
+ Header : is where we out all global data (ie, used by any of the
blocks, as kernel base address, APIs, etc), and all the
offsets to all the swappable blocks (that will be changed
with each call to the BSE (block swapping engine)) and of
course the size of each block.
+ Exec : Is the place of code where we load in the correct order of
execution the block we want, and pass the control to it.
+ Block : The blocks (any of them) are independent routines that the
virus can execute separatelly,although some of them should
follow an order. For example, a block for antidebugging,
a block for retro, another for infection...
+ BSE : That's the term i use for denominate a block swapping en-
gine. This engine should be able to swap the code of the
desired blocks, and also fix its position in their varia-
bles located in Header.
It is a good idea that, instead execute all swappable blocks one per one,
to launch them as threads (or even fibers, but i recommend threads), so they
would be executed at the same time, and no time would be lost :)
% Problems with the Block Swapping %
There is nothing impossible, i know. (Btw, you know what Napoleon said? He
said some like this: "impossible is the adjective of the suckers". Well,
the block swapping, although it's asimple technique, raises some problems
that go beyond the idea itself. The first one is the relocation factor. Ok,
this has a simple solution,to get the delta offset in the very first part of
the code, so it would be relative to it and not to block offset. So, you
wouldn't be able (easily i mean) to use local variables in the own code
block.So, to put all the data at the 'Header' part is a good idea that solve
many problems with it. Another problem is how to know, if we have some
dependant blocks, their execution order.I think that there are two solutions
here:
a) don't use dependant blocks :)
b) use an structure, such as
BYTE BlockAttributes,
WORD nBlockSize;
DWORD lpBlockOffset;
Of course, in block attributes you should play with bit fields and such, it
is completly up to you. So, you can manage easily with that byte all the
possible dependences of the blocks. Use your imagination :)
Another problem inherent to the technique, is its detectability. Just solve
it by using another techs that avoid that, such as poly :)
% Final words about Block Swapping %
It's a simple technique (not as simple as com overwriting,but what the heck,
it's more simple than the other parts of this essay), but it has its usage.
I think it could be a good adding for your virus. I haven't seen yet this
technique in Win32 viruses... Mmmm... this is giving me an idea... X-D
Ú-------------------¿
| Register Swapping |
À-------------------Ù
Ok, here comes the greet you were waiting for... Greetings Vecna, our god!.
Sincerely, under my opinion, Vecna is probably, with Dark Avenger, Quantum
and Neurobasher, the best coder of virus of everytime. Well, you are wonder-
ing why all those greetings to Vecna. Simple, he coded the first approach in
Win32 to the metamorphism, via the called Register Swapping technique.
The Register swapping is part of the light metamorphism techniques, and i
will soon explain why. It consist in swap the registers used in the whole
virus body, so most of the opcodes get changed in any way. There are two
ways of approaching the Register Swapping technique: using an emulator and
using tables. Vecna's Win9x.RegSwap uses the last technique. If you want
an example of the first one, we have Z0MBiE's A/ZCME engines. As far as i
heard, Lord ASD coded MPE (Monster Polymorphic Engine) for his Win32.Appari-
tion viruses, that used the first technique too. But i'll focus this part of
the document to Vecna's approach (using tables) because that thing of the
emulator will be in another part of this document.
Well, let's imagine a basic opcode, such as a MOV reg32,imm32.In it's binary
form, it's B8+reg32 imm32. Let's pay attention to that B8+reg32:
10 111 xxx
^^^reg32
So, we can easily change the register of that opcode, by making an OR with
the base value (B8) and the register wanted. So Vecna figured in his RegSwap
virus, that a table for handle where there were swappable registers, and the
possition of the bits in that opcode that handle the register, would do the
work, besides an engine for interpretate that tables, of course. Here goes
Vecna's table structure (btw, it's a word):
+ 00..06 Register index
+ 07..08 Position of reg in instruction (xx 000 xxx or xx xxx 000)
+ 09..16 Distance from previous reg-using instruction
So, at the end of RegSwap, there are huge tables of this structure...
% Problems with the Register Swapping %
It's a cool technique this one, but let's see it's bad points:
a) It's weak
b) The shape of the morphed code is basically the same, so the AV
would be able to detect it with wildcards
c) The tables are fixed, so they are a very reliable scan string :(
Even though, some of these things can be fixed. For example, by using also
in the virus another meta technique... Mmm... also, it's not needed... just
encrypt with a little poly engine the tables (or the whole virus).
It was a cool experience for Vecna, and for all us also because we are his
disciples :)
% Final words about Register Swapping %
Yes, it's cool. It is great for a first experience in metamorphism, but i
consider that a mental exercise rather than an attempt of undetectability.
Any good poly will be always better than this kind of metamorphism, but it
is meta, so it rocks!
Ú--------------------¿
| Itxoiten technique |
À--------------------Ù
Ok, i think i invented this technique (noone has said the opposite, so i am
in my right of think that i did, huh?), so i gave it this name. This was
deeply discussed in the part I of this document, but some lines would be
good for refresh our ideas. It's based in the idea of a translator. We build
an ITX header, and then pass it to a routine that processes all its informa-
tion, and converts it to a virus. The ITX header would be as a coding lan-
guage. Ok, let's imagine how the IHP (ITX header processor) would translate
a MOV reg32,imm32 from one language to opcodes:
01 00 12345678 --¯---¯-[ IHP ]--¯---¯- B8 12345678
À´ ÃÙ Ã------Ù ÃÙ Ã------Ù
ITX's MOV <Ù v À> imm32 MOV <Ù À> imm32
reg32
As you can imagine, the engine won't stop here. For perform that simple MOV
the engine will be able to use many different ways... For example,
xor eax,eax
add eax,12345678h
or
sub eax,eax
sub eax,-12345678h
etc, etc, etc... So, with completly different codes (bigger or even smaller
in size) we are performing the same task. Imagine the metamorphism rate...
WOW! ;)
Ok, that would be part of the code section of the ITX header. Of course, it
will have its own data section, and its own import table (by means of the
CRC32 of the APIs). I've began to work in all it, but i don't promiss any-
thing.
% Problems with the Itxoiten technique %
As you can guess, there are some problems that are delaying this project.
The first one is the fact is inherent to the idea of something like the ITX
header: The header would be much bigger than the virus that it could genera-
te, and the problem is that those bytes are fixed :( The only possible solu-
tion would be to construct a polymorphic decryptor for that ITX header. But,
heck, build with a metamorphic engine a polymorphic engine... seems (and in
fact it is) a redundant idea, mmmm... even a bad idea. Another big problem
call with the relocations of the generated code. I've been thinking a lot
about this matter, but any effective and simple solution came to my mind. If
you have an idea for solve this, i'd like to receive a mail from you.
% Final words about the Itxoiten technique %
Yes, it's a powerful metamorphism technique, but the problems i described
make it,at this moment (and until i find the solution) an useless technique.
Fuck, it's sad that i'm criticizing the technique i wanted to use for my
meta viruses, but, as always, to have good ideas is not the same that build
the code for make them possible. My conclusions came because i've tried to
make the ITX project to be a reality... But with all the problems, at now, i
don't feel that i would able to finish it now. Maybe, who knows, one day the
solutions came to my mind and i'm able to finish what i've began. Sigh.
Ú------------------------------------------------------¿
| Internal Disassembler (aka self-emulation) technique |
À------------------------------------------------------Ù
It is undoubtly the most reliable way for metamorphism i can think of,albeit
the building of a code emulator is not as easy as it appears to be, at least
in Win32 enviroments. We can manage the INT 1 as well, but only in Win9x en-
viroments, as in NT we cannot jump to Ring-0 and such. Mmm, no. Another po-
ssible approach is to make an emulator that will go executing the opcode it-
self in a protected execution zone, where we will store after the execution
of the opcode all the register in some memory variables for such purpose.
It is the solution,but the hard point of it is that we need to know the size
of the opcode to emulate, no exception. This can be done, not easily, but it
can. This principle can be seen into Wintermute's tunneling engines in Zohra
and in Ithaqua. But Win32, as always, raises some problems. The biggest an
unavoidable one is the API. We *CANNOT* and *MUST NOT* emulate inside the
code of an API. It's useless and dangerous. But also we can't avoid it, just
because we don't know how many bytes were needed by the API to be in the
stack for its execution. There is no possible solution to it. But, we can
still emulate our own code, taking care of how many bytes we need to push to
every call to an API that our virus should do. Yes, it's difficult, but it
can be made, as we know what our code should do.
Ok, imagine we've already done our emulator (the hardest thing!). Now the
way that lead us to the metamorphism is easier.We can swap between registers
and even the instruction order in some parts of the virus. Also, we can use
alternative ways for perform a same instruction. It's like the polymorphism
but applied to all the virus body with some improvisation :)
This is so far the most effective metamorphism technique and i think that we
should guide our steps here, instead of wasting time in another useless or
easily detectable metamorphism way. Imagine all the possible ways to make
a mov reg,imm. Almost infinite!
Well, as we are emulating, we must avoid to always expand the code used for
a simple action. If we expand in one part of the code too much times, we
will notice the presence of the virus by showing some obvious symptoms:
decrements the free disk space and the programs got executed more slowly
because the nonsense code. So, besides expand, we should think on including
a shrinking procedure, so some useless opcodes could be removed in order to
save more space. I think you've realized that the shrinking is much harder
to implement rather than the expanding. We should do it alternatively, so
in some parts of the code we increase the size and in others we decrement it
Mmmm... compensation law!
Ú------¿ Ú--¯--< Expand >--¯--¿ Ú------¿
| CODE Ã---¯---¯---¯---¯---´ Ã---¯---¯---¯---¯---´ CODE |
À------Ù À--¯--< Shrink >--¯--Ù À------Ù
À---------Â----------Ù
[ MORPHER ]
That is, under my viewpoint, what the morpher should do: randomly expand or
shrink.
% Problems with the Internal Disassembler technique %
The most clear one are the ones inherent to the construction of a code emu-
lator: know all the sizes of all the opcodes, avoid protection problems,
the impossibility of emulate through API code... I've already commented the
possible solutions to these problems before. But even inside the technique
itself there are some more possible problems, relative mainly to the reloca-
tion factor and the shrinking part of the morpher.
The relocation problem has a solution: use the parallelism between the old
code we are morphing and the code being reconstructed. We should take care
of where are the equivalent memory accesses, and fix the amount of bytes
(positive or negatively) in the own instruction, of where the possition of
the memory address changed.
The shrinking part is a bit more difficult. I think that the possible way
for do shrinking is to have patterns of all the ways we have for the expan-
ding, so we know while seeing the expanded code what was the "base" code of
it. I hope you understood that.
% Last words about the Internal Disassembler technique %
It's so far the best way to reach the metamorphism objective. Also, it's one
of the hardest ones, albeit it's very possible. It requires many time and
patience of the coder. I push you all to try to do a metamorphic virus using
this technique!
Ú-----------------------------------¿
| Is metamorphism worth to be done? |
À-----------------------------------Ù
Mmm... hard question. Apparently, it is worth. But, if you've read Qozah's
article 'Polymorphism and Grammars' (29A#4, i *REALLY* recomend you to read
it!) everything we code is always detectable. Well, we are trying to make
the life harder to the AV, because they'll have to work many more in detect
and clean (if possible) our virus. But, anyway, sooner or later, they will
be able to detect it. Almost always, we spend many time coding a metamorphic
virus, and the AV spends much less time in detecting it.
So, metamorphism is a technique only for elite virus writers,those assembler
"gurus" that are always surprising us. The only matter i can think of make a
metamorphic virus is for demonstrate that the guy that coded it has sumthing
"special", that makes him not to be as that heap of virus writers that only
arrive to the simple perprocess resident viruses (oh, shit, i include myself
on that heap...) for Win32.
Metamorphic viruses are for priviledged assembler coders, able to do almost
everything with their assemblers. So keep yourself away if you think that
even to code a poly perprocess, etc is difficult. Is wouldn't be for you.
Back to the question, the answer depends from the viewpoint:
a) It is worth if what you want to do is to do an exercise for your
priviledged mind, and you are enough clever for handle that. Also,
if you want AVers to be surprised from your coding skills, or even
if you want to distinguish yourself from the heap of other virus
writers.
b) It is not worth if what you are searching is permanent undetecta-
bility, ehem... nothing is worth if you are searching it. So go
and code other thingies. AV will always detect our virus sooner or
later if they have it.
Everything clear? i hope so.
Ú----------------------¿
| Author's final words |
À----------------------Ù
I hope you recognize the serious work i've done with this document. Well, it
is not at all serious (if you know me personally you'll know why ;),but i've
tried to use an objective viewpoint for treat all the discussed themes in
this article. If you haven't understood all what i've explained, let me know
by e-mail, and i'll try to solve your doubts.
I haven't tried in any way to demonstrate that i am elite among this arti-
cle, because i know i am not, and i have to walk a long road to became one
of the chosen. The best is to remain humble always, and make people not to
expect big things of you, so if you code something cool, you'll always have
the "surprise" factor :) It's my philosophy as VX, follow it if you want.
Hrm, this tute was finished the 9 of September of 1999 (9-9-99), while hea-
ring in the local radios that the y2k was a virus, that all the computers
would have today a virus, and such like shit, produced always when ignorant
guys talk about things they don't know. Don't you hate it? I do. Ignorance
has been always the weapon of the totalitarian societies. Erradicate the
ignorance and this world will be much better. Oh, shit, i'm talking about
politic things again! :) Damn, i cannot control myself...
Well, i hope this little tute has helped you in your attempt of coding a
metamorphic engine. Join the elite virus writing! (damn, i'll have to code
something for achieve such a goal!).
- You can't smell your own shit under your knees - (Marilyn Manson)
----------------------------------------------------------------------------
(c) Billy Belcebu/IKX [15/12/99] "i'm not a terrorist. i'm an artist"
þ URL þ www.billybelcebu.org - www.beautifulpeople.cjb.net
þ EMAIL þ billy_belcebu@mixmail.com - billy_belcebu@ikx4ever.org
þ IRC þ irc-hispano #virus, undernet #virus #ikx