ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ 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