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
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@.....
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
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]
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
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
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