Studying a Polymorphic Engine: PolyEnE v.0.01

This is where members can submit tutorials that they have created on any computing related subject.
Post Reply
User avatar
kka_kenny
Your Senior
Posts: 901
Joined: Sat May 15, 2004 5:42 pm

Studying a Polymorphic Engine: PolyEnE v.0.01

Post by kka_kenny » Thu Jul 21, 2005 5:38 am

Studying a Polymorphic Engine: PolyEnE v.0.01
Author: kka_kenny
Date: 02 July 2005


Requirements:
Ollydbg (any version will do)
Brain


This archive contains:
Am0kCM_2.zip - original, packed and patched CrackMe
polyene001prealpha.zip - PolyEne packer
The Paper - this paper you are reading right now dumbasss! =D

Introduction:

Well to be honest I don’t know where I downloaded this packer. I don’t even know why its still on my computer but today is its lucky day cause this is the day when I first touched it =D. Anyways for those people who wishes to study about polymorphic codes, this is a good engine to study, this is somewhat a “stereotype” I suppose. It contains junk codes, scramblers and basic encryption decryption loop


btw I would like to say that this packer we would be playing with is not really the best packer in the world. In compression in handling api’s etc. but I have to give applause to the author for his work. Indeed it is a very nice small packer for small executables, more like a virus packer I suppose. I tried packing bigger applications but this packer doesn’t seem to be able enough to handle it. Just incase it comes to any importance; I’m running under WindowsXP SP2. I’m not sure if that is the case for Win9X OS’s as well. Anyways let’s start cracking.


The Paper:

Fire up Ollydbg and look at the first codes

Code: Select all

00407000 > 60               PUSHAD

00407001   48               DEC EAX

00407002   40               INC EAX

00407003   87DB             XCHG EBX,EBX

00407005   E9 1B030000      JMP packed.00407325

0040700A  -79 EB            JNS SHORT packed.00406FF7

0040700C   01A9 E9090000    ADD DWORD PTR DS:[ECX+9E9],EBP

00407012   0023             ADD BYTE PTR DS:[EBX],AH

00407014   FFD0             CALL EAX

00407016   E9 AC090000      JMP packed.004079C7

0040701B   EF               OUT DX,EAX                               ; I/O command

0040701C   EB 05            JMP SHORT packed.00407023

0040701E   0F23EB           MOV DR5,EBX                              ; Privileged command

00407021   0331             ADD ESI,DWORD PTR DS:[ECX]

00407023  ^EB FB            JMP SHORT packed.00407020

00407025   68 40000000      PUSH 40


Those are the first codes of the packer, it’s pretty typical for polymorphics to have an EP such as PUSHAD, not to mention the amount of junk codes it has in between the real codes. Look at it, DEC EAX then INC EAX then do XCHG of the same register, I mean wtf? This really is a a stereotype of a polymorphic code. This stuff is normally done by virus writers before to confuse AV’s until now its working but I guess some AV’s nowadays are making generic unpackers built in. One feature mentioned by the author of this packer is that, it generates different codes all the time so generic unpacking for this is not as easy, I never really tested it so F*** knows if he’s telling the truth. We aren’t working for no AV company so to be honest it’s not in our business.


Back to our business, look at the codes again and notice the amount of jumps you see o_0, there sure is tons of them. Example

Code: Select all

004073AA   74 0E            JE SHORT packed.004073BA

004073AC   4E               DEC ESI

004073AD   74 15            JE SHORT packed.004073C4

004073AF   4E               DEC ESI

004073B0   74 1C            JE SHORT packed.004073CE

004073B2   83E0 1F          AND EAX,1F

004073B5   83C5 05          ADD EBP,5

004073B8   EB 1A            JMP SHORT packed.004073D4

004073BA   25 FF1F0000      AND EAX,1FFF

004073BF   83C5 0D          ADD EBP,0D

004073C2   EB 10            JMP SHORT packed.004073D4

004073C4   25 FF030000      AND EAX,3FF

004073C9   83C5 0A          ADD EBP,0A

004073CC   EB 06            JMP SHORT packed.004073D4

 
OMG look at that, how many times does this engine need to scramble itself? If I would trace this manually to be honest I would simply blow my brains out, this is basically another technique of a polymorphic code, it basically scrambles the file so instead of a file looking like this

Code: Select all

Call 004073C4

Mov eax,1
Xor eax, ebx

 
It becomes

 
Call 004073C4

Jmp to some routine

Jump back

Mov eax,1

Jump to some routine

Jump back

Xor eax, ebx


OR

Code: Select all

Call 004073C4

Jmp to X (Where X is address which contains “Mov EAX,1”)

Jmp back

Blah balh

I hope you get the idea I’m trying to convey.

Going back to the codes is its encryption decryption loop. The author used simple encryption OP’s like XOR. It’s not as complicated that is why it’s very good start for people who’s studying basic polymorphics. I don’t know if anyone finds this hard to understand but if ever you do then you need to lay back a little while, don’t try to study other viruses made by well know vx groups as they are much more complicated than this. The encryption used in a laymen’s eye would look something like this, of course not exactly like that but the idea is there.


Get Start and End Addresses

Mov Start Address

XOR Enryption or whatever

Junk codes & Scrambled routine

Cmp if equal to End Address

Loop back if not until Addresses meet


That’s just a simple example the author might have don it differently. If still you don’t get it from written explanation then look at the diagram below instead


================================
| Start address of the file |
| |
| More codes here |
| |
| End Address to the file |
| |
|=============================== |
| Engine attaches here takes the |
| start and end values |
| |
| Does encryption routine and changes the |
| Entry point here |
| |
| Decrypts the program |
| Jumps back to the OEP |
|_________________________________ __ |


That’s a basic observation of the engine we did not really do nothing much but a simple observation. I tried to stay away from big terms or big codes as much as I can just for the comprehension of those people who are still starting out.


Unpacking and Inline patching the Packer:


Well let’s try to unpack the file, after which make a generic unpacker for it even. Well not really but a simple script to find the OEP. Genric unpacking for this application is actually pretty simple as in contrast to the author’s comments, first reasons is the handling of api’s. The packer does not touch the api’s at all or whatsoever, there is no tricks used in this packer except for its encryption routine, scrambled filled with junk codes. Apart from that no other feature is used. Let’s open it up in olly again only this time set a Hardware Breakpoint On Access at the ECX Register. After studying the packer for a short while I found out that placing a hardware breakpoint would take us to the end of the decryption routine

Code: Select all

EAX 00000000

ECX 0012FFB0                                                      >>>>>>>>>>>>> Follow in Dump

EDX 7C90EB94 ntdll.KiFastSystemCallRet

EBX 7FFD5000

ESP 0012FFC4

EBP 0012FFF0

ESI FFFFFFFF

EDI 7C910738 ntdll.7C910738

EIP 00407000 packed.<ModuleEntryPoint>

 

0012FFB0  4E E6 90 7C 4C 6D 81 7C FE FF FF FF 09 00 00 00  Næ?|Lm?|þÿÿÿ....

0012FFC0  F8 FF 12 00 4F 6D 81 7C 38 07 91 7C FF FF FF FF  øÿ.Om?|8‘|ÿÿÿÿ

0012FFD0  00 D0 FD 7F 40 06 00 00 C8 FF 12 00 78 97 35 89  .Ðý@..Èÿ.x—5‰

0012FFE0  FF FF FF FF F3 99 83 7C 58 6D 81 7C 00 00 00 00  ÿÿÿÿó™ƒ|Xm?|....

0012FFF0  00 00 00 00 00 00 00 00 00 70 40 00 00 00 00 00  .........p@.....

 
Highlight the first four bytes and set the hardware breakpoint. After setting the breakpoint run the file and you will end up in a code either a “Push EBP” or a “JMP” but it doesn’t really matter to us, for me I ended up here

Code: Select all

004078E8  ^E9 8BF9FFFF      JMP packed.00407278

004078ED   EF               OUT DX,EAX                               ; I/O command

004078EE   57               PUSH EDI

004078EF   87FB             XCHG EBX,EDI

004078F1   EB 01            JMP SHORT packed.004078F4

004078F3   0F5B             ???                                      ; Unknown command

004078F5   87FB             XCHG EBX,EDI

004078F7   EB 00            JMP SHORT packed.004078F9

004078F9   E9 0A000000      JMP packed.00407908

004078FE   B4 EB            MOV AH,0EB

00407900   01A9 E902FDFF    ADD DWORD PTR DS:[ECX+FFFD02E9],EBP

00407906   FF79             ???                                      ; Unknown command

 
Now keep stepping over/into those commands until you reach an unanalyzed commands, those unanalyzed commands contains the OEP.

These were the last addresses I had before the packer went to the OEP

Code: Select all

00407908   68 88104000      PUSH packed.00401088

0040790D   58               POP EAX

0040790E   E9 50000000      JMP packed.00407963

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

0040790D   58               POP EAX

0040790E   E9 50000000      JMP packed.00407963

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

00407963   FFF0             PUSH EAX

00407965  ^E9 AAFFFFFF      JMP packed.00407914

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

00407914   C3               RETN                   >>>>> Returns to the OEP

So the OEP is

Code: Select all

00401088     55             DB 55                                    ;  CHAR 'U'

00401089     8B             DB 8B

0040108A     EC             DB EC

0040108B     6A             DB 6A                                    ;  CHAR 'j'

0040108C     FF             DB FF

0040108D     68             DB 68                                    ;  CHAR 'h'

0040108E     A0             DB A0

0040108F     40             DB 40                                    ;  CHAR '@'

00401090     40             DB 40                                    ;  CHAR '@'

00401091     00             DB 00

00401092     68             DB 68                                    ;  CHAR 'h'

00401093     BC             DB BC

00401094     1B             DB 1B

 
Press CTRL + A for it to be analysed

 
00401088  /. 55             PUSH EBP

00401089  |. 8BEC           MOV EBP,ESP

0040108B  |. 6A FF          PUSH -1

0040108D  |. 68 A0404000    PUSH packed.004040A0

00401092  |. 68 BC1B4000    PUSH packed.00401BBC                     ;  SE handler installation

00401097  |. 64:A1 00000000 MOV EAX,DWORD PTR FS:[0]

 
Now if you wish to unpack this, dump it and rebuild the tables but since the packer doesn’t have any sort of integrity or CRC check we would simply do an inline patch.

Since we found the last codes before reaching the OEP we already know what addresses to manipulate. What we will basically do is change the jump which goes to the “ret”, change it to jump to our patch codes then jumps back to the “ret” command then the “ret” command to the OEP so instead of


Jmp >>>> Ret >>>> OEP


It becomes


Jmp >>>> Patch codes >>>> Ret >>>> OEP


So change this jump to a jump going to some zero bytes

Code: Select all

00407965  ^E9 AAFFFFFF      JMP packed.00407914
There are a couple of few zero bytes below

Code: Select all

004079D2   0000             ADD BYTE PTR DS:[EAX],AL

004079D4   0000             ADD BYTE PTR DS:[EAX],AL

004079D6   0000             ADD BYTE PTR DS:[EAX],AL

004079D8   0000             ADD BYTE PTR DS:[EAX],AL

004079DA   0000             ADD BYTE PTR DS:[EAX],AL

004079DC   0000             ADD BYTE PTR DS:[EAX],AL

 
So change the jump to “Jmp 004079D2”


And on the zerobytes insert your patch codes. After which make it jump back to the “ret” command. So for example

Code: Select all

004079D2   C605 18104000 74 MOV BYTE PTR DS:[401018],74

004079D9   C605 1D104000 74 MOV BYTE PTR DS:[40101D],74

004079E0  ^E9 2FFFFFFF      JMP inline.00407914


I added the inline patch in the archives for those who still don’t understand.


Conclusion:

This is a simple paper explaining a simple Polymorphic Engine. Probably next time we would be debugging and understanding a real virus. On the next paper we would try to firstly understand what and how the virus works, afterwards we will be disinfecting it.

If in any case you wish to give comments rants and suggestions. Throw your hate mail at kkakenny[at]gmail[dot]com
It starts with with a simpl[e] lie then you die.

User avatar
matt
Challenge Winner [1x]
Posts: 772
Joined: Sun Jul 18, 2004 1:19 pm
Location: u.kingdom Manhood: large
Contact:

Post by matt » Thu Jul 21, 2005 3:58 pm

very interesting ;)

User avatar
hotx
Hacker in Training
Posts: 78
Joined: Thu Jun 30, 2005 4:08 pm
Location: Michigan
Contact:

Post by hotx » Thu Jul 21, 2005 8:26 pm

What processor microcode was this performed on?

romance30_06
n00b
Posts: 1
Joined: Sat Mar 17, 2007 10:52 pm

Post by romance30_06 » Sat Mar 17, 2007 10:54 pm

gooooooooood

Post Reply