Jump to content
Tuts 4 You

[unpackme] Enigma 1.68+EC Code Packed


kobalt

Recommended Posts

Teddy Rogers

The [unpackme] tag has been added to your topic title.

Please remember to follow and adhere to the topic title format - thankyou!

[This is an automated reply]

Link to comment
Share on other sites

Gotten to OEP (I think):

005EEE6A	FFD0 	CALL EAX
005EEE6C 61 POPAD
005EEE6D 8B40 00 MOV EAX,DWORD PTR DS:[EAX]
005EEE70 03C6 ADD EAX,ESI
005EEE72 56 PUSH ESI
005EEE73 6A 00 PUSH 0
005EEE75 6A 01 PUSH 1
005EEE77 55 PUSH EBP
005EEE78 50 PUSH EAX
005EEE79 96 XCHG EAX,ESI
005EEE7A 8B70 3C MOV ESI,DWORD PTR DS:[EAX+3C]
005EEE7D 96 XCHG EAX,ESI
005EEE7E 8B8430 28000000 MOV EAX,DWORD PTR DS:[EAX+ESI+28]
005EEE85 03C6 ADD EAX,ESI
005EEE87 50 PUSH EAX
005EEE88 C3 RETN <<-- points to OEP

And OEP is 54F6E8. Correct me if wrong (as usual) ;-)

Link to comment
Share on other sites

Yeah, I just noticed :-) SEHs come after that, aaaaaaaaaaalll the way :-) :-)

I assume this is what I have to see:

6xrnmt.png

EDIT1: Yeah, gotten to OEP. And it looks like crap :-) Time to study Enigma, haven't done this so far ;-)

EDIT2: Gotcha!

004898B8	55 	PUSH EBP
004898B9 8BEC MOV EBP,ESP
004898BB 83C4 F0 ADD ESP,-10
004898BE 53 PUSH EBX
004898BF B8 38964800 MOV EAX,CrackMe.00489638
004898C4 E8 2BC7F7FF CALL CrackMe.00405FF4
004898C9 8B1D D8BC4800 MOV EBX,DWORD PTR DS:[48BCD8] ; CrackMe.0048CBE8
004898CF 8B03 MOV EAX,DWORD PTR DS:[EBX]
004898D1 E8 76E8FDFF CALL CrackMe.0046814C
004898D6 8B03 MOV EAX,DWORD PTR DS:[EBX]
004898D8 BA 30994800 MOV EDX,CrackMe.00489930 ; ASCII "Web Thumbnailer"
004898DD E8 62E4FDFF CALL CrackMe.00467D44
Edited by SunBeam
Link to comment
Share on other sites

Damn I don't think I'm going to win this race. ;) I doubt my employer likes it when I start unpacking at work.

@ sun, you can force enigma to write correct API's. :) Not very hard. (But could be an old version, where I exploited that. )

Edited by quosego
Link to comment
Share on other sites

Assuming we now know the target's name and where to get it and making abstraction of that, here's how to get to the "stolen" (actually allocated) OEP:

1. Trace up to here, with F7:

005EE95C 3010 XOR BYTE PTR DS:[EAX],DL

005EE95E 40 INC EAX

005EE95F 49 DEC ECX

005EE960 ^ 0F85 F6FFFFFF JNZ CrackMe.005EE95C

005EE966 E9 04000000 JMP CrackMe.005EE96F

^ First decryption layer. F2 on 5EE966, Shift+F9. Resume tracing.

2. Pass VirtualAlloc call:

005EE98A FF95 F4D01900 CALL DWORD PTR SS:[EBP+19D0F4] ; kernel32.VirtualAlloc

with F8. And get up to here:

005EEC7E	3010 	XOR BYTE PTR DS:[EAX],DL
005EEC80 40 INC EAX
005EEC81 49 DEC ECX
005EEC82 ^ 0F85 F6FFFFFF JNZ CrackMe.005EEC7E
005EEC88 E9 04000000 JMP CrackMe.005EEC91

^ Second decryption layer. F2 on 5EEC88, Shift+F9. Resume tracing.

3. Pass VirtualFree call:

005EECEB FF95 F8D01900 CALL DWORD PTR SS:[EBP+19D0F8] ; kernel32.VirtualFree

with F8. And get up to here:

005EED84 3010 XOR BYTE PTR DS:[EAX],DL

005EED86 40 INC EAX

005EED87 49 DEC ECX

005EED88 ^ 0F85 F6FFFFFF JNZ CrackMe.005EED84

005EED8E E9 04000000 JMP CrackMe.005EED97

^ Third decryption layer. Same drill, F2 on 5EED8E and Shift+F9. Resume tracing.

4. Imports, API names, etc.. Just make sure you follow this jump:

005EEDA3 837F 0C 00 CMP DWORD PTR DS:[EDI+C],0

005EEDA7 0F84 95000000 JE CrackMe.005EEE42

So, F2 on 5EEE42 and Shift+F9. Resume tracing up to here:

005EEE88 C3 RETN

5. Now we are in (I call this at first glance, don't really know naming conventions) the second shell - or some .dll, from the looks of it (Enigma.dll?):

0054F6E8 55 PUSH EBP ; CrackMe.00400000

0054F6E9 8BEC MOV EBP,ESP

0054F6EB 83C4 C4 ADD ESP,-3C

0054F6EE 53 PUSH EBX

0054F6EF 56 PUSH ESI

0054F6F0 57 PUSH EDI

0054F6F1 B8 10F35400 MOV EAX,CrackMe.0054F310

0054F6F6 E8 614AF6FF CALL CrackMe.004B415C

6. As you can see, SEH + Themida trick :-)

0054F6FE 68 2BF75400 PUSH CrackMe.0054F72B

0054F703 64:FF30 PUSH DWORD PTR FS:[EAX] // sets a SEH

0054F706 64:8920 MOV DWORD PTR FS:[EAX],ESP

0054F709 CC INT3

0054F70A EB 15 JMP SHORT CrackMe.0054F721

0054F70C DB2D 12F75400 FLD TBYTE PTR DS:[54F712] // Themida trick, would crash Olly..

0054F712 FFFF ??? ; Unknown command

0054F714 FFFF ??? ; Unknown command

0054F716 FFFF ??? ; Unknown command

0054F718 FFFF ??? ; Unknown command

Exit point from SEH is @ 54F72B. So, F2 there and let's progress.

7. You should now be here:

004B1674 8B4424 04 MOV EAX,DWORD PTR SS:[ESP+4]

Scroll down a bit and find exit point (no, it's not the RET :-)). It is right here:

004B1776 FFE3 JMP EBX

F2 on it, execute and we see that we exit right here:

0054F730 E8 A722F6FF CALL CrackMe.004B19DC

0054F735 5F POP EDI

Which is right below the JMP that led to the big function:

0054F6FE 68 2BF75400 PUSH CrackMe.0054F72B // set SEH

0054F703 64:FF30 PUSH DWORD PTR FS:[EAX]

0054F706 64:8920 MOV DWORD PTR FS:[EAX],ESP

0054F709 CC INT3

0054F70A EB 15 JMP SHORT CrackMe.0054F721

0054F70C DB2D 12F75400 FLD TBYTE PTR DS:[54F712]

0054F712 FFFF ??? ; Unknown command

0054F714 FFFF ??? ; Unknown command

0054F716 FFFF ??? ; Unknown command

0054F718 FFFF ??? ; Unknown command

0054F71A 3D 40E80000 CMP EAX,0E840

0054F71F 0000 ADD BYTE PTR DS:[EAX],AL

0054F721 33C0 XOR EAX,EAX

0054F723 5A POP EDX

0054F724 59 POP ECX

0054F725 59 POP ECX

0054F726 64:8910 MOV DWORD PTR FS:[EAX],EDX

0054F729 EB 0A JMP SHORT CrackMe.0054F735

0054F72B ^ E9 441FF6FF JMP CrackMe.004B1674 // handle exception -> leads to JMP EBX function

0054F730 E8 A722F6FF CALL CrackMe.004B19DC // exit is right below the handler :-)

Keep that in mind, it will help later ;-) Moving on..

8. F8 over the call, enter next call @ 54F738. Once inside it, stop here:

004B1F76 E8 A1FEFFFF CALL CrackMe.004B1E1C

Enter the caller and at the end of the function, we see this:

004B1E46 C2 0C00 RETN 0C // leads to 54F2AC

Moving onward, we get up to here:

0054F2DE E8 D1F4FFFF CALL CrackMe.0054E7B4 // don't pass this, program will run

Entering call, we get up to here:

0054E7E5 68 12E85400 PUSH CrackMe.0054E812 // set SEH

0054E7EA 64:FF30 PUSH DWORD PTR FS:[EAX]

0054E7ED 64:8920 MOV DWORD PTR FS:[EAX],ESP

0054E7F0 CC INT3

0054E7F1 EB 15 JMP SHORT CrackMe.0054E808

0054E7F3 DB2D F9E75400 FLD TBYTE PTR DS:[54E7F9]

0054E7F9 FFFF ??? ; Unknown command

0054E7FB FFFF ??? ; Unknown command

0054E7FD FFFF ??? ; Unknown command

0054E7FF FFFF ??? ; Unknown command

0054E801 3D 40E80000 CMP EAX,0E840

0054E806 0000 ADD BYTE PTR DS:[EAX],AL

0054E808 33C0 XOR EAX,EAX

0054E80A 5A POP EDX

0054E80B 59 POP ECX

0054E80C 59 POP ECX

0054E80D 64:8910 MOV DWORD PTR FS:[EAX],EDX

0054E810 EB 0A JMP SHORT CrackMe.0054E81C

0054E812 ^ E9 5D2EF6FF JMP CrackMe.004B1674 // exit SEH; this leads to JMP EBX function :-)

0054E817 E8 C031F6FF CALL CrackMe.004B19DC // my guess is the exit is here, what do you think? :-P

Remember this? :-) So yeah, F2 @ 54E817, Shift+F9. Enter call, trace and you'll find another similarity:

004B1A09 /FFE2 JMP EDX ; CrackMe.0054E81C

Yeah, you guessed it. It JMPs right below call we entered at 54E817 :-)

0054E81C 33D2 XOR EDX,EDX

Moving on..

9. Careful, SEHs all the way:

0054E82A 68 4BE85400 PUSH CrackMe.0054E84B

0054E82F 64:FF35 00000000 PUSH DWORD PTR FS:[0]

0054E836 64:8925 00000000 MOV DWORD PTR FS:[0],ESP

F2 at 54E84B and Shift+F9. Moving on.

0054E84B 8B4424 0C MOV EAX,DWORD PTR SS:[ESP+C]

0054E84F 8B4C24 04 MOV ECX,DWORD PTR SS:[ESP+4]

0054E853 C740 04 00000000 MOV DWORD PTR DS:[EAX+4],0

0054E85A C740 08 00000000 MOV DWORD PTR DS:[EAX+8],0

0054E861 C740 0C 00000000 MOV DWORD PTR DS:[EAX+C],0

0054E868 C740 10 00000000 MOV DWORD PTR DS:[EAX+10],0

0054E86F 8160 14 F00FFFFF AND DWORD PTR DS:[EAX+14],FFFF0FF0

0054E876 8160 18 00DC0000 AND DWORD PTR DS:[EAX+18],0DC00

0054E87D C780 B8000000 8AE85400 MOV DWORD PTR DS:[EAX+B8],CrackMe.0054E88A

0054E887 31C0 XOR EAX,EAX

0054E889 C3 RETN

Very known handler, resets DRx flags and sets exit point to 54E88A. Which, again (o_O) is below the RET :-) Set bp there with F2 and Shift+F9.

Here comes another one:

0054E894 68 B5E85400 PUSH CrackMe.0054E8B5

0054E899 64:FF35 00000000 PUSH DWORD PTR FS:[0]

0054E8A0 64:8925 00000000 MOV DWORD PTR FS:[0],ESP

SEH should be right below it (if you check 54E8B5). Exit point is set here:

0054E8E5 C780 B8000000 F2E85400 MOV DWORD PTR DS:[EAX+B8],CrackMe.0054E8F2

So, F2 at 54E8F2, Shift+F9. And we're there. Now comes a tricky, yet funky anti-debug trick :-P

10. If you manually trace through this code:

0054E8FC E8 037CFEFF CALL CrackMe.00536504

0054E901 E8 967CFEFF CALL CrackMe.0053659C

0054E906 50 PUSH EAX

0054E907 89C1 MOV ECX,EAX

0054E909 B8 47E95400 MOV EAX,CrackMe.0054E947

0054E90E E8 357CFEFF CALL CrackMe.00536548

0054E913 010424 ADD DWORD PTR SS:[ESP],EAX

0054E916 C3 RETN

Up to the RETN at 54E916, you will notice that the value at [ESP] is a bogus one :-P

$ ==> > B0AA9538

So RETN will obviously fail. If we are to set a hardware breakpoint at that RETN, we see this:

$ ==> > 0054E947 CrackMe.0054E947

This value is set here:

0054E909 B8 47E95400 MOV EAX,CrackMe.0054E947

So, obviously, the CALL below it will **** up the return value in [ESP]. You got two choices, either study the CALL or use HWBPs :-) (I'll probably study it afterward, hehe).

11. We should now be here:

0054E947 E8 045BFEFF CALL CrackMe.00534450

Tracing onward, we get up to here:

0054EABC 68 DDEA5400 PUSH CrackMe.0054EADD

0054EAC1 64:FF35 00000000 PUSH DWORD PTR FS:[0]

0054EAC8 64:8925 00000000 MOV DWORD PTR FS:[0],ESP

You know the drill. Follow 54EADD. We find exit here:

0054EB0F C780 B8000000 1CEB5400 MOV DWORD PTR DS:[EAX+B8],CrackMe.0054EB1C

Follow that and we see another trick:

0054EB1C 64:8F05 00000000 POP DWORD PTR FS:[0]

0054EB23 83C4 04 ADD ESP,4

0054EB26 E8 2978FEFF CALL CrackMe.00536354

0054EB2B E8 6C7AFEFF CALL CrackMe.0053659C

0054EB30 50 PUSH EAX

0054EB31 89C1 MOV ECX,EAX

0054EB33 B8 71EB5400 MOV EAX,CrackMe.0054EB71

0054EB38 E8 0B7AFEFF CALL CrackMe.00536548

0054EB3D 010424 ADD DWORD PTR SS:[ESP],EAX

0054EB40 C3 RETN

HWBP at RETN, Shift+F9. Trace code up to here:

0054ED75 68 A2ED5400 PUSH CrackMe.0054EDA2

0054ED7A 64:FF30 PUSH DWORD PTR FS:[EAX]

0054ED7D 64:8920 MOV DWORD PTR FS:[EAX],ESP

0054ED80 CC INT3

0054ED81 EB 15 JMP SHORT CrackMe.0054ED98

0054ED83 DB2D 89ED5400 FLD TBYTE PTR DS:[54ED89]

0054ED89 FFFF ??? ; Unknown command

0054ED8B FFFF ??? ; Unknown command

0054ED8D FFFF ??? ; Unknown command

0054ED8F FFFF ??? ; Unknown command

Exit of SEH is at 54EDA2.

0054EDA7 E8 302CF6FF CALL CrackMe.004B19DC // JMP r32 function

0054EDAC E8 2772FEFF CALL CrackMe.00535FD8

Continue tracing up to here, and follow directions I specified:

0054EDCC A1 E00F5600 MOV EAX,DWORD PTR DS:[560FE0]

0054EDD1 80B8 B4160000 00 CMP BYTE PTR DS:[EAX+16B4],0

0054EDD8 74 0F JE SHORT CrackMe.0054EDE9

0054EDDA A1 A00B5600 MOV EAX,DWORD PTR DS:[560BA0]

0054EDDF 8038 00 CMP BYTE PTR DS:[EAX],0

0054EDE2 75 05 JNZ SHORT CrackMe.0054EDE9 // FORCE JUMP [1]

0054EDE4 E8 0BFAFEFF CALL CrackMe.0053E7F4 // Nag with HWID function

0054EDE9 A1 A00B5600 MOV EAX,DWORD PTR DS:[560BA0]

0054EDEE 8038 00 CMP BYTE PTR DS:[EAX],0

0054EDF1 75 13 JNZ SHORT CrackMe.0054EE06 // FORCE JUMP [2]

0054EDF3 A1 E00F5600 MOV EAX,DWORD PTR DS:[560FE0]

0054EDF8 80B8 5E040000 00 CMP BYTE PTR DS:[EAX+45E],0

0054EDFF 74 05 JE SHORT CrackMe.0054EE06

0054EE01 E8 9AA4FFFF CALL CrackMe.005492A0 // ExitProcess function

0054EE06 E8 B575FEFF CALL CrackMe.005363C0 // good_boy

If above indications are followed, and we run a Shift+F9 while at 54EE06, you'll see program opens up :-) Let's progress to OEP :-P

12. Keep tracing up to here:

0054EE33 50 PUSH EAX // you are here

0054EE34 89C1 MOV ECX,EAX

0054EE36 B8 74EE5400 MOV EAX,CrackMe.0054EE74

0054EE3B E8 0877FEFF CALL CrackMe.00536548

0054EE40 010424 ADD DWORD PTR SS:[ESP],EAX

0054EE43 C3 RETN // set HWBP here, remember the trick

Exit RETN. Solve SEH:

0054EE74 68 95EE5400 PUSH CrackMe.0054EE95

0054EE79 64:FF35 00000000 PUSH DWORD PTR FS:[0]

0054EE80 64:8925 00000000 MOV DWORD PTR FS:[0],ESP

Exit (in the end) is here:

0054EED4 64:8F05 00000000 POP DWORD PTR FS:[0]

0054EEDB 83C4 04 ADD ESP,4

Trace up to here:

0054EF76 E8 35BBFFFF CALL CrackMe.0054AAB0

Now, if you look at hex dump window (which should show 48A000 memory region), you will see that, after passing that CALL with F8, resources are "resolved" (unpacked, whatever) :-)

0048A060 E5 8D 40 00 45 72 72 6F 72 00 8B C0 52 75 6E 74 å@.Error.‹ÀRunt
0048A070 69 6D 65 20 65 72 72 6F 72 20 20 20 20 20 61 74 ime error at
0048A080 20 30 30 30 30 30 30 30 30 00 8B C0 30 31 32 33 00000000.‹À0123
0048A090 34 35 36 37 38 39 41 42 43 44 45 46 FF FF FF FF 456789ABCDEFÿÿÿÿ

Moving on. Trace up to this point:

0054F064 50 PUSH EAX // you are here

0054F065 89C1 MOV ECX,EAX

0054F067 B8 A5F05400 MOV EAX,CrackMe.0054F0A5

0054F06C E8 D774FEFF CALL CrackMe.00536548

0054F071 010424 ADD DWORD PTR SS:[ESP],EAX

0054F074 C3 RETN

Same trick. HWBP at RETN, Shift+F9. Exit RETN and get up to this point:

0054F1C0 E8 F319FFFF CALL CrackMe.00540BB8

Past this CALL, program runs. So, let's enter it, trace, and stop here:

005412A4 FFE0 JMP EAX

Yum. In my case, EAX points to this location:

00B5CC00 E8 97999DFF CALL CrackMe.0053659C

Trace the code with F7 or F8 (make sure not to run target) up to this point:

00B5CCF6 3BE0 CMP ESP,EAX

..

00B5CD01 ^\0F85 D8FFFFFF JNZ 00B5CCDF

00B5CD07 /E9 04000000 JMP 00B5CD10 // set hwbp here with, then Shift+F9

Continue with tracing, and we exit here:

00B5CD4F FFE0 JMP EAX // JMPs to 00B54BC0, in my case

So, OEP is here :-)

00B54BC0 55 PUSH EBP

00B54BC1 8BEC MOV EBP,ESP

00B54BC3 83C4 F0 ADD ESP,-10

00B54BC6 53 PUSH EBX

00B54BC7 B8 38964800 MOV EAX,489638

00B54BCC E8 23148BFF CALL CrackMe.00405FF4

00B54BD1 - E9 F34C93FF JMP CrackMe.004898C9

Stolen code is ranging from B54BC0 till B54BCC ;-) As you can see, after all that execution, code JMPs back to main Delphi section (@4898C9) :-)

004898C9 8B1D D8BC4800 MOV EBX,DWORD PTR DS:[48BCD8] ; CrackMe.0048CBE8

004898CF 8B03 MOV EAX,DWORD PTR DS:[EBX]

004898D1 E8 76E8FDFF CALL CrackMe.0046814C

004898D6 8B03 MOV EAX,DWORD PTR DS:[EBX]

004898D8 BA 30994800 MOV EDX,CrackMe.00489930 ; ASCII "Web Thumbnailer"

If you binary copy those bytes (B54BC0 till B54BCC), then hit an analyze on the code at 4898C9, you'll see this:

004898A8 \08964800 DD CrackMe.00489608

004898AC D8954800 DD CrackMe.004895D8

004898B0 00 DB 00

004898B1 00 DB 00

004898B2 00 DB 00

004898B3 00 DB 00

004898B4 10964800 DD CrackMe.00489610 // init_table_start

So, OEP is below that table, at 4898B8. Select code from 4898B8 downward, and binary paste the code we just copied earlier. Remove analysis. Result:

004898B8 55 PUSH EBP

004898B9 8BEC MOV EBP,ESP

004898BB 83C4 F0 ADD ESP,-10

004898BE 53 PUSH EBX

004898BF B8 38964800 MOV EAX,CrackMe.00489638

004898C4 E8 23148BFF CALL FFD3ACEC // DON'T FORGET TO ADJUST THIS :-P

004898C9 8B1D D8BC4800 MOV EBX,DWORD PTR DS:[48BCD8] ; CrackMe.0048CBE8

004898CF 8B03 MOV EAX,DWORD PTR DS:[EBX]

004898D1 E8 76E8FDFF CALL CrackMe.0046814C

004898D6 8B03 MOV EAX,DWORD PTR DS:[EBX]

004898D8 BA 30994800 MOV EDX,CrackMe.00489930 ; ASCII "Web Thumbnailer"

That's about it :-)

Edited by SunBeam
Link to comment
Share on other sites

BytePlayeR

Until 1.68 it quite easy, but the author had changed the protection mechanism from 1.70 ahead :)

Link to comment
Share on other sites

Yes its quite easy if the VM is not used but in this UnpackMe is SDK VM used and this makes it a lot harder to unpack.

0059F00C  PUSH 0
0059F011 JMP 0053CC50
0059F016 PUSH 1
0059F01B JMP 0053CC50
0059F020 PUSH 2
0059F025 JMP 0053CC50
0059F02A PUSH 0A
0059F02F JMP 0053CC50
etc

Follow the jmp address and you find the VM table....

greetz

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...