Level : newbie
ExeShield 3.7 - manually unpacking
This tutorial will describe manually unpacking ExeShield 3.7 protector.
1. Introduction words
Hi and welcome to a new unpacking tutorial! This time we will have a very easy job.
ExeShield is maybe the easiest protector that I have seen and that includes freeware protectors too. It supports dongle(hardware key) protection but this tutorial won't discuss about that part, only software protection. And that software protection is very weak. Also notice that if you scan protected file with PEiD, you will get incorrect scan result "PECompact 2.x -> Jeremy Collake". Don't be surprised, a lot of protectors today have fake first bytes in order to confuse non-experienced crackers. Or maybe ExeShield just uses PECompact for compression.
You will need next tools for this tutorial.
- OllyDbg 1.10
- target , here http://www.reversing.be/binaries/articles/20051022184044949.rar
If you run protected target you will see that is creates one hidden file in the same folder. That file is our crippled executable. If you open it in olly you'll see that first half of code section is filled with zeros. That half of code will be written in memory directly. And that is main protection trick in ExeStealth. From anti-debug tricks, protector only has FindWindowA check that is searching for OLLYDBG windows. Ok, let's unpack our target RICHEDIT.EXE.
Load it in olly and in olly debug options, under events tab, check "Break on new module (dll)" and press F9 untill you see in modules window that user32.dll is loaded in memory:
Base Size Entry Name File version Path
00400000 005C9000 00401000 RICHEDIT D:xxxxxxExeShieldRICHEDIT.EXE
77D40000 0008C000 77D53A05 user32 5.1.2600.1561 (x C:WINDOWSsystem32user32.dll <----- It's red in olly!
77E60000 000E6000 77E7ADB3 kernel32 5.1.2600.1560 (x C:WINDOWSsystem32kernel32.dll
77F50000 000A7000 ntdll 5.1.2600.1106 (x C:WINDOWSSystem32ntdll.dll
That means user32.dll is loaded now in memory so uncheck "Break on new module (dll)" in Olly and place bp's on FindWindowA and WriteProcessMemory. Now keep pressing F9 untill you see in stack window OLLYDBG name:
000CD7E4 00470612 /CALL to FindWindowA from RICHEDIT.0047060D
000CD7E8 004749A0 |Class = "OLLYDBG"
000CD7EC 00000000 Title = NULL
FindWindowA function here checks for OLLYDBG. To kill that, press Ctrl+F9 to return to code and just set EAX=0 and continue with F9. You may see couple times OLLYDBG in stack and every time you just need to set EAX=0 when you exit that API.
Then you will see one ugly nag window (I forgot to uncheck this option). Continue and you will soon break on WriteProcessMemory API, check stack:
0130E19C 0046F417 /CALL to WriteProcessMemory from RICHEDIT.0046F412
0130E1A0 000000B4 |hProcess = 000000B4 (window)
0130E1A4 00401000 |Address = 401000 <-------------------------------- Where to write!
0130E1A8 0047BB00 |Buffer = RICHEDIT.0047BB00 <---------------------- Where are original bytes stored!
0130E1AC 00001ABF |BytesToWrite = 1ABF (6847.) <--------------------- How many there is bytes, size!
0130E1B0 0136FF84 pBytesWritten = 0136FF84
And this is what we where waiting for. Protector has created that temporary file in same dir, "xshld4997.tmp" in my case and it created process from it. Then it will write missing bytes with our API function to that process. We can see where missing bytes are (in buffer) , it's size and where it will write them. Now, copy that "xshld4997.tmp" file in the same folder and you will get new one "Copy of xshld4997.tmp". Rename it's extension to exe so you get "Copy of xshld4997.exe" file. Open it another Olly instance and you'll see that it is full of zeroes from 401000 to 40269E. We gona just paste those "stolen bytes" from buffer in our first Olly. In first olly follow this buffer in disassembler (right click and select that option):
0130E1A8 0047BB00 |Buffer = RICHEDIT.0047BB00 <---- Follow in disassembler window!
You will land here:
0047BB00 PUSH EBP
0047BB01 MOV EBP,ESP
0047BB03 ADD ESP,-20
0047BB06 PUSH 7D0
0047BB0B PUSH DWORD PTR DS:[4041E8]
0047BB11 CALL RICHEDIT.0047D4A6
0047BB16 MOV DWORD PTR DS:,EAX
0047BB1B JMP SHORT RICHEDIT.0047BB2D
0047BB1D PUSH ESP
Select all code from 0047BB00 to 0047D596 and binary copy it. That is actually whole code section of our packed target. Now just paste it in second olly from 401000 to 402A96 (you'll see that it matches) and save changes to that file. Now run that "Copy of xshld4997.exe" and you will see that it works normally :) And that is all! There are no fixing imports or finding OEP, repaired file is perfect copy of original non-packed file.
3. Final words
Is this was easy or not!?! ExeStealth has one option for inserting markers for runtime encryption/decryption code, but that option is not available in the trial version so I couldn't test that. But probably it's nothing special.
From what I noticed, ExeShield always steal part of first section and then it writes it in memory. That first section doesn't have to be code, it can be data or imports. You have such example on one unpackme (UnPackMe_ExeShield3.6.c.exe) on Teddy Rogers site (http://tuts4you.com/unpackme/). In that example I couldn't save changes in my "copy of xshl..." file from some reson so just dumped it to disk and dump worked. Again no IAT and OEP problems.
In the archive you will find all my files.
Greets goes as usuall, to all folks on biw, arteam, and crackmes.de.
[ haggar ]