Unwrapping eLicense 4.0

Monday, July 17 2006 @ 12:10 PM CEST

Contributed by: haggar

Level : newbie

Unwrapping eLicense 4.0





This small tut will describe removing protection layer from eLicense 4.0 protected programs. Since eLicense is not available for evaluation, I was not able to protect some mine file with it and make a target for tutorial. Because of that, I used shareware application for a target. However, I will not provide target name or downlad link in this tutorial. I want to keep it legal (if cracking tutorial can be that at all) as much as possible.






1. Intruduction

After installing protected application, I scanned install folder with PEiD 0.94. PEiD did not give any possible indication that some file is protected with eLicense protector. On the main executable of installed application it returned "Nothing found*". But in the same folder, one file is recognized as ASPack 2.12. That file was elicen40.dll . Name of this file clearly suggest that this dll is part of eLicense protection system.

Next step was loading main executable in OllyDbg. I got 4 warnings that some modules have entry point outside of code section before evaluation window showed. Why 4 modules when only one (elicen40.dll) is packed? Also , evaluation window showed altough I didn't started target.

I found that upon starting target or loading it in olly, it creates file in temporary folder. That file s1cc.2xcp , is a DLL packed with ASPack 2.12 too and it is also part of eLicense system. Second file is ofcourse elicen40.dll. Other two files are lcmmfu.cpl and mmfs.dll , both placed in windows folder, also packed with ASPack. I do not know does this two files are part of protection, but right now that is not important.

After all modules are loaded and evaluation window is showed, I clicked on "Trial" bottun and my main exe file just crushed in Olly at this point:

00453132 A0 C8BF0068 MOV AL,BYTE PTR DS:[6800BFC8]
00453137 5C POP ESP
00453138 25 450064A1 AND EAX,A1640045
0045313D 0000 ADD BYTE PTR DS:[EAX],AL
0045313F 0000 ADD BYTE PTR DS:[EAX],AL
00453141 50 PUSH EAX
00453142 64:8925 00000000 MOV DWORD PTR FS:[0],ESP
00453149 83EC 58 SUB ESP,58
0045314C 53 PUSH EBX
0045314D 56 PUSH ESI
0045314E 57 PUSH EDI
0045314F 8965 E8 MOV DWORD PTR SS:[EBP-18],ESP
00453152 FF15 74C24500 CALL DWORD PTR DS:[45C274]
00453158 33D2 XOR EDX,EDX ; WS2_32.71AC4070
0045315A 8AD4 MOV DL,AH
0045315C 8915 8C3B4700 MOV DWORD PTR DS:[473B8C],EDX ; WS2_32.71AC4070
00453162 8BC8 MOV ECX,EAX


Later I sow that this is OEP of main protected executable. Whole file is decrypted, but couple first OEP bytes are destroyed (?) so file crushed. But OEP is found. Solution lies in elicen40.dll. Main executable is encrypted and this dll performs decryption. Protection is so simple that I didn't even bother to go deeper inside. Let's see how we can unwrapp target.






2. Unpacking DLL and finding OEP

To unpack main executable, we need to unpack elicen40.dll. I hope that you know how to unpack ASPack packed DLL. Ok, in case that you don't know, here is how:

- load elicen40.dll in Olly
- place bp on GetProcAddress and run 3 times (then remove bp), return to code
- scroll down and find

024A53AF 61 POPAD
024A53B0 75 08 JNZ SHORT elicen40.024A53BA
024A53B2 B8 01000000 MOV EAX,1
024A53B7 C2 0C00 RETN 0C
024A53BA 68 00000000 PUSH 0
024A53BF C3 RETN

- place bp on last RETN
- run to break on that bp
- press F7 to go on DLL OEP

02485415 55 PUSH EBP
02485416 8BEC MOV EBP,ESP
02485418 53 PUSH EBX ; elicen40.
02485419 8B5D 08 MOV EBX,DWORD PTR SS:[EBP+8] ; elicen40.
0248541C 56 PUSH ESI
0248541D 8B75 0C MOV ESI,DWORD PTR SS:[EBP+C] ; elicen40.02480000
02485420 57 PUSH EDI
02485421 8B7D 10 MOV EDI,DWORD PTR SS:[EBP+10]
02485424 85F6 TEST ESI,ESI
02485426 75 09 JNZ SHORT elicen40.02485431
02485428 833D A8F84902 00 CMP DWORD PTR DS:[249F8A8],0
0248542F EB 26 JMP SHORT elicen40.02485457
02485431 83FE 01 CMP ESI,1
02485434 74 05 JE SHORT elicen40.0248543B
02485436 83FE 02 CMP ESI,2
02485439 75 22 JNZ SHORT elicen40.0248545D

- open LordPE, select loaddll.exe process, in lower pane select our elicen40.dll and make full dump
- open ImpREC, attach to loaddll.exe, click on "Pick DLL" and select our elicen40.dll
- enter your OEP=OEP-ImageBase, in my case it is 00005415=02485415-02480000
- press "IAT auto search", then "Get imports", and then "Fix dump" to rebuild IAT
- our elicen40.dll is now unpacked from ASPack

Change name of that dumped_.dll to elicen40.dll and start main exe to see did you unpacked dll correctly. Mine works good. Btw, ASPack can be unpacked without use of ImpREC and in that case we would ge clener dump. But that is not important.


This dll unpacks our target and then it jumps to OEP via one jump. But if we run target within debugger, OEP bytes will be destroyed. There is quick way around that "bug".
Load unpacked elicen40.dll in Olly. Select first line at the beggining of code section.Right click on code and select "Search for"->"command". Enter JMP DWORD [CONST] and hit "Find" button. First jump that is founded is our OEP jump:

02483CCF . FF25 5CF84902 JMP DWORD PTR DS:[249F85C]
02483CD5 > 5E POP ESI ; ntdll.7C9011A7
02483CD6 . 5D POP EBP ; ntdll.7C9011A7
02483CD7 . 5B POP EBX ; ntdll.7C9011A7
02483CD8 . 8BE5 MOV ESP,EBP
02483CDA . 5D POP EBP ; ntdll.7C9011A7


We binary change first two bytes to EB FE (infinite jump) and then we save changes:

02483CCF -EB FE JMP SHORT elicen40.02483CCF
02483CD1 5C POP ESP ; ntdll.7C9011A7
02483CD2 F8 CLC
02483CD3 49 DEC ECX
02483CD4 025E 5D ADD BL,BYTE PTR DS:[ESI+5D]
02483CD7 . 5B POP EBX ; ntdll.7C9011A7
02483CD8 . 8BE5 MOV ESP,EBP
02483CDA . 5D POP EBP ; ntdll.7C9011A7


Now , after program is unpacked, it will run in memory forever. Start main execuatble, click on "Trial" button and program will eneter in infinite jump. Now , opene Olly and just attached to target. Shift+F9 to run it, then F12 to pause it, and you are on the right place:

02483CCF -EB FE JMP SHORT elicen40.02483CCF
02483CD1 5C POP ESP ; kernel32.7C816D4F
02483CD2 F8 CLC
02483CD3 49 DEC ECX
02483CD4 025E 5D ADD BL,BYTE PTR DS:[ESI+5D]
02483CD7 5B POP EBX ; kernel32.7C816D4F
02483CD8 8BE5 MOV ESP,EBP
02483CDA 5D POP EBP ; kernel32.7C816D4F


Restore original bytes FF 25:

02483CCF -FF25 5CF84902 JMP DWORD PTR DS:[249F85C] ; target.
02483CD5 5E POP ESI ; kernel32.7C816D4F
02483CD6 5D POP EBP ; kernel32.7C816D4F
02483CD7 5B POP EBX ; kernel32.7C816D4F
02483CD8 8BE5 MOV ESP,EBP
02483CDA 5D POP EBP ; kernel32.7C816D4F


F7 to get on OEP:

0045312C > 55 PUSH EBP
0045312D 8BEC MOV EBP,ESP
0045312F 6A FF PUSH -1
00453131 68 A0C84500 PUSH target.0045C8A0
00453136 68 5C254500 PUSH target.0045255C
0045313B 64:A1 00000000 MOV EAX,DWORD PTR FS:[0]
00453141 50 PUSH EAX
00453142 64:8925 00000000 MOV DWORD PTR FS:[0],ESP
00453149 83EC 58 SUB ESP,58
0045314C 53 PUSH EBX
0045314D 56 PUSH ESI ; ntdll.ZwQueryValueKey
0045314E 57 PUSH EDI
0045314F 8965 E8 MOV DWORD PTR SS:[EBP-18],ESP
00453152 FF15 74C24500 CALL DWORD PTR DS:[45C274]
00453158 33D2 XOR EDX,EDX ; ws2_32.71AC4070
0045315A 8AD4 MOV DL,AH
0045315C 8915 8C3B4700 MOV DWORD PTR DS:[473B8C],EDX ; ws2_32.71AC4070
00453162 8BC8 MOV ECX,EAX
00453164 81E1 FF000000 AND ECX,0FF
0045316A 890D 883B4700 MOV DWORD PTR DS:[473B88],ECX


And that is OEP! With correct bytes. Now we need to dump files and to fix imports.






3. Dumping and rebuilding IAT

First we need to dump main executable. Open LordPE and in options, under "Task viever", select "Full dump:Paste header from disk". That is important since eLicense corrupts PE header in memory. Now make a full dump.

Imports are hidden. If check one call:

00453152 FF15 74C24500 CALL DWORD PTR DS:[45C274] ; DS:[0045C274]=0015C6DD

Then we follow it:

0015C6DD 50 PUSH EAX
0015C6DE A1 38C71500 MOV EAX,DWORD PTR DS:[15C738]
0015C6E3 3305 48C71500 XOR EAX,DWORD PTR DS:[15C748]
0015C6E9 A3 485B1400 MOV DWORD PTR DS:[145B48],EAX
0015C6EE 58 POP EAX ; kernel32.7C816D4F
0015C6EF FF25 485B1400 JMP DWORD PTR DS:[145B48]

We can see that it has encrypted imports. But it is simple:

Import = Encrypted_import XOR some_constant




I just wrote one script for olly , that will restore all imports in my target. It does same thing as eLicense code - it just XOR two values. Check script and try to write one that will work for your target:


//eLicense 4.0 import fixer

var pointer
var constant
var addr
mov addr,45c000 //Start of import table.

label_01:
cmp addr,45c5f4 //End of import table.
ja end_01
mov pointer,[addr]
and pointer,0FFFF0000
cmp pointer,00160000
add addr,4
jne label_01
sub addr,4
mov pointer,[addr]
add pointer,2
mov pointer,[pointer]
mov pointer,[pointer]

mov constant,[addr]
add constant,8
mov constant,[constant]
mov constant,[constant]

xor pointer,constant

mov [addr],pointer
add addr,4

jmp label_01
end_01:

ret


Script scans import table in file and not code section.
After fixing imports, we need to use ImpREC. In ImpREC options, select also "Use PE header from disc". Then attach to target, click "IAT auto search", then "Get imports", and then "Fix dump". Find dumped.exe and fix it. Run dumped_.exe and if it's work, you have unpacked eLicense 4.0.




4. Last words

There it was - the unpacking of eLicense. There was requests for this tutorial on couple boards and I hope that this tutorial give needed answers.


Greets to everybody on BIW, ARTEAM, SnD, crackmes.de, and...... to you ;-) See you folks!



~~ haggar ~~





7 comments



http://www.reversing.be/article.php?story=20060717121012208