Jump to content
Tuts 4 You

[unpack me]The Enigma Protector 4.20[Single] patch HWID and unpackme


Recommended Posts

  • 4 weeks later...



why you added the not packet file?

So the HWID check you can bypass via simple flag change at VA 529E4E.Later at OEP you can rebuild the bytes and addresses of entire OEP routine or just redirect & dump the memory in one section.Just check VirtualAlloc API and change the parameters also for as alloc type to prevent a topdown..

$ ==> > 0059ABDD /CALL to VirtualAlloc from unpack-m.0059ABD7
$+4 > 00000000 |Address = NULL
$+8 > 003D0900 |Size = 3D0900 (4000000.)
$+C > 00101000 |AllocationType = MEM_COMMIT|MEM_TOP_DOWN <---
$+10 > 00000040 \Protect = PAGE_EXECUTE_READWRITE MEM_TOP_DOWN = Allocates memory at the highest possible address

Some imports are VMed...

00452138 014217A5 unpack-m.014217A5
0045215C 01414951 unpack-m.01414951
00452168 0141FBCD unpack-m.0141FBCD
0045216C 01422153 unpack-m.01422153
00452178 0142D8FF unpack-m.0142D8FF
0045217C 01428343 unpack-m.01428343
004521E4 01422153 unpack-m.01422153
0045221C 01414B24 unpack-m.01414B24
00452230 01431938 unpack-m.01431938
00452238 01419D5F unpack-m.01419D5F
00452240 014211DD unpack-m.014211DD
00452274 014217A5 unpack-m.014217A5
0045228C 0141FBCD unpack-m.0141FBCD
00452290 01422153 unpack-m.01422153
004522B4 0141F9E1 unpack-m.0141F9E1
004522C0 0142A64B unpack-m.0142A64B
004522C8 01428343 unpack-m.01428343
004522E4 0142A5EC unpack-m.0142A5EC
004522F0 01422FC4 unpack-m.01422FC4

...but these you can also solve via VM push values X + who does jump it = Pointer Y which you can find in the hidden new API table.

005622D8 00000001
005622DC 7C800000 kernel32.7C800000
005622E0 7C80B741 kernel32.GetModuleHandleA
005622E4 00526D60 unpack-m.00526D60 <-- jumps to VM push X
005622E8 00000000
005622EC 00000000
005622F0 00000001
005622F4 7C800000 kernel32.7C800000
005622F8 7C80E4DD kernel32.GetModuleHandleW
005622FC 00526DD8 unpack-m.00526DD8 <-- jumps to VM push X
00562300 00000000
00562304 00000000
00562308 00000001
0056230C 7C800000 kernel32.7C800000
00562310 7C801A28 kernel32.CreateFileA
00562314 0046C9BC unpack-m.0046C9BC <-- jumps to VM push X
00562318 00000000
0056231C 0052766C unpack-m.0052766C

005622D8 00000001
005622DC 7C800000 kernel32.7C800000
005622E0 7C80B741 kernel32.GetModuleHandleA
005622E4 00526D60 unpack-m.00526D60 <-- jumps to VM push X
00526D60 /E9 2BAFF100 JMP 01441C90
01441C90 68 6C349B01 PUSH 0x19B346C <---
01441C95 ^ E9 BA8D15FF JMP 0059AA54 VM Push value of GetModuleHandleA = 0x19B346C Not fixed API address
0045216C 01422153 unpack-m.01422153
01422153 LEA ESP,DWORD PTR SS:[ESP-0x4]
0059AA54 PUSHAD <-- Handler routine
[ESP]= 019B346C = Push value
Same value
0045216C 01422153 unpack-m.01422153
0045216C 7C80B741 kernel32.GetModuleHandleA

For this you can create a short simple script to solve the few APIs.




  • Like 7
Link to comment
  • 4 months later...
  • 2 months later...

Sorry for reviving this but here is a version witch keep the Enigma VM in place (and a good comparation for those that want to compare both code reconstructed and VM kept in place) and no code reconstruction is used.

The size is bigger due to fact that you do not romove the VM.

Link to comment
  • 2 months later...



How do you rebuild OEP like your file? Your rebuilt OEP and not-packed OEP are the same.


Would you wanna guide how to rebuild OEP? I'm so curious.



Link to comment

@ icarusdcSo you can try to find out all OEP commands if you do stop on each access to code codesection.So you just need to stop on each call address of codesection.If you check any not protected delphi apps then you can see it so the OEP build is very simple & easy so that you just need to interpret the register & stack & eip = call to.In this unpackme you can do this.First you do stop at the real OEP address which is a call to VM.

0044ED20    E8 7FBE1400      CALL 0059ABA4 // OEP

Also here you can restore the entire OEP datas.Now mark the stack enter the call and set a mem bp access on codesection and run til you stop.


Below the data of your first stop.Now interpret the datas and build your first OEP block.

-----------------------------------------00405BC8    53               PUSH EBXEAX 0044EB40 unpack-m.0044EB40  <--- eaxECX 00466000 ASCII "MZP"EDX 0024E97FEBX 0012FEE8ESP 0012FEECEBP 0012FF00  mov ebp,esp (0012FF00 - 0012FEEC - 4 = 10 = -10)ESI 0012FEE4EDI 0247D983EIP 00405BC8 unpack-m.00405BC8 <-- call to$-18     > 7FBD4BC0-------- -10 lenght$-14     > 0012FEE4$-10     > 0247D983$-C      > 0012FF04$-8      > 00000000------- add esp, -10$-4      > 0012FEEC  push ebp$ ==>    > 005535F7  unpack-m.005535F7--------------------------------------------------------------------------push ebpmov ebp,espadd esp, -10mov eax, 0044EB40call 00405BC8--------------------------------------------------------------------------

Now you got the first OEP block.Execute the routine till the output return and now do the same again till you stop on next call routine.Here you need to find addresses & commands which was executed before you did stop.Look at eax....

0044D374    53             PUSH EBX // next mem stop codesectionEAX 02D516D4  <---- find in section under data one timeECX 0012FEDCEDX 0012FEF4EBX 0012FEE8ESP 0012FEECEBP 0012FF00ESI 0012FEE4EDI 0247D983EIP 0044D374 unpack-m.0044D37400451BB0  02D516D4 <-- find 00451BB0 in data section0044FFD0  00451BB0 --------------------------------------------------------------------------mov eax,dword [0044FFD0]mov eax,dword [EAX]call 0044D374--------------------------------------------------------------------------

Now do same again to reach next stop...here you do stop in Enigmasection which does access the codesection where it moves a address from codesection into ebx so keep this in your mind.

0063537E    8B1A           MOV EBX,DWORD PTR DS:[EDX] 0044E914  0044E960  <-- to ebx0044D38C    55             PUSH EBP // next stopEAX 02D516D4  <-- same as beforeECX 00451BD0 unpack-m.00451BD0 <-- search = 004500AC  00451BD0EDX 0044E960 unpack-m.0044E960 <-- look above ebx = 0044E914  0044E960EBX 0012FEE8ESP 0012FEECEBP 0012FF00ESI 0012FEE4EDI 0247D983EIP 0044D38C unpack-m.0044D38C--------------------------------------------------------------------------mov eax,dword [0044FFD0]mov eax,dword [EAX]mov ecx,dword [004500AC]mov edx,dword [0044E914]call 0044D38C--------------------------------------------------------------------------

Now do same again...at the end of this routine set a BP and run and now you see the app starts.Press ok on UnpackMe or exit and you do stop at ret....

0044D40C    55             PUSH EBP  // next stopEAX 02D516D4 <-- same againECX 00451BD0 unpack-m.00451BD0EDX 0044317C unpack-m.0044317CEBX 0012FEE8ESP 0012FEECEBP 0012FF00ESI 0012FEE4EDI 0247D983EIP 0044D40C unpack-m.0044D40C--------------------------------------------------------------------------mov eax,dword [0044FFD0]mov eax,dword [EAX]call 0044D40C  // app starts--------------------------------------------------------------------------

...after the stop on ret do same again...

00403D20    53             PUSH EBX  // next stopEAX 02D516D4ECX 02D516D4EDX 0012FEF4EBX 0012FEE8ESP 0012FEECEBP 0012FF00ESI 0012FEE4EDI 0247D983EIP 00403D20 unpack-m.00403D2000403DDA    E8 45D4FFFF    CALL 00401224 // app exits--------------------------------------------------------------------------call 00403D20--------------------------------------------------------------------------

Now if you trace this routine then you see you come not back anymore so its called the exit inside which also means you don't need any more OEP datas to rebuild.Now write all OEP datas you found out together and assemble them at the OEP address and save the new code....

Rebuild OEP blocks-------------------------------------push ebpmov ebp,espadd esp, -10mov eax, 0044EB40call 00405BC8mov eax,dword [0044FFD0]mov eax,dword [EAX]call 0044D374mov eax,dword [0044FFD0]mov eax,dword [EAX]mov ecx,dword [004500AC]mov edx,dword [0044E914]call 0044D38Cmov eax,dword [0044FFD0]mov eax,dword [EAX]call 0044D40C  // app startscall 00403D20

...and thats already.Just play a little with this and also you can do this too with not protected delphi apps so there you can practice & study.



  • Like 6
  • Thanks 1
Link to comment



That is amazing explanation about rebuilding Delphi's OEP manually. I've followed your steps and succeed :) Thank you, dear.


So I tested to my UnpackMe but again, get confused :(

The real OEP from original file like this.

0050D2D8 > 55 PUSH EBP
0050D2DB 83C4 F0 ADD ESP,-0x10
0050D2DE B8 90CD5000 MOV EAX,0x50CD90
0050D2E3 E8 9896EFFF CALL 00406980 ; OPOK_AS.00406980
0050D2E8 68 7CD35000 PUSH 0x50D37C ; ASCII "OPOK_AS"
0050D2ED 6A FF PUSH -0x1
0050D2EF 6A 00 PUSH 0x0
0050D2F1 E8 DE98EFFF CALL 00406BD4 ; OPOK_AS.00406BD4
0050D2F6 A3 38535100 MOV DWORD PTR DS:[0x515338],EAX
0050D2FB E8 CC99EFFF CALL 00406CCC ; <JMP.&kernel32.GetLastError>
0050D300 3D B7000000 CMP EAX,0xB7
0050D305 74 6F JE SHORT 0050D376 ; OPOK_AS.0050D376
0050D307 33C0 XOR EAX,EAX
0050D309 55 PUSH EBP
0050D30A 68 6FD35000 PUSH 0x50D36F
0050D312 64:8920 MOV DWORD PTR FS:[EAX],ESP
0050D315 A1 7C2F5100 MOV EAX,DWORD PTR DS:[0x512F7C]
0050D31C E8 6732F5FF CALL 00460588 ; OPOK_AS.00460588
0050D321 A1 7C2F5100 MOV EAX,DWORD PTR DS:[0x512F7C]
0050D328 BA 8CD35000 MOV EDX,0x50D38C ; ASCII "OPOK Telkomsel"
0050D32D E8 3E2EF5FF CALL 00460170 ; OPOK_AS.00460170
0050D332 8B0D 18315100 MOV ECX,DWORD PTR DS:[0x513118] ; OPOK_AS.00515318
0050D338 A1 7C2F5100 MOV EAX,DWORD PTR DS:[0x512F7C]
0050D33F 8B15 849C5000 MOV EDX,DWORD PTR DS:[0x509C84] ; OPOK_AS.00509CD0
0050D345 E8 5632F5FF CALL 004605A0 ; OPOK_AS.004605A0
0050D34A A1 7C2F5100 MOV EAX,DWORD PTR DS:[0x512F7C]
0050D351 E8 CA32F5FF CALL 00460620 ; OPOK_AS.00460620
0050D356 33C0 XOR EAX,EAX
0050D358 5A POP EDX
0050D359 59 POP ECX
0050D35A 59 POP ECX
0050D35B 64:8910 MOV DWORD PTR FS:[EAX],EDX
0050D35E 68 76D35000 PUSH 0x50D376
0050D363 A1 38535100 MOV EAX,DWORD PTR DS:[0x515338]
0050D368 50 PUSH EAX
0050D369 E8 3E98EFFF CALL 00406BAC ; <JMP.&kernel32.CloseHandle>
0050D36E C3 RETN
0050D36F ^ E9 D46CEFFF JMP 00404048 ; OPOK_AS.00404048
0050D374 ^ EB ED JMP SHORT 0050D363 ; OPOK_AS.0050D363
0050D376 E8 F971EFFF CALL 00404574 ; OPOK_AS.00404574

This OEP has many differences.

I understand little bit about some bytes like this.

push ebp
mov esp,ebp
add esp,-0x10
mov eax, 0050CD90
call 00406980 push 0050D37C
push -0x1
push 0x0
Call 00406BD4 $ ==> > 008BAC5D OPOK_AS_.008BAC5D <<< Call 00406BD4
$+4 > 00000000 <<< PUSH 0x0
$+8 > FFFFFFFF <<< PUSH -0x1
$+C > 0050D37C OPOK_AS_.0050D37C <<< PUSH 0050D37C

But the remain bytes, I have no clue anymore.


Here is the unpackme (clean and protected). LINK


Oh, sorry. I don't mean to spam this thread. Should I make new thread about asking how to rebuild OEP? 

I just wanna study about it. Surely, it is interesting.



Link to comment



so in some cases if the OEP routine is too complex (not only calls & move commands) then you need to check the VM datas of each command but for this you need to know how to translate the VM blocks (each command = 44 byte block).If you don't know it then you can just try to dump the VM and add it to your dumped file.I made a little video with your target where you can see what you can do.Of course its just a simple alternative method you can choose.Just have a look.



Dump OEP VM.rar

  • Like 2
Link to comment



I've looked your video and tried to follow your steps and of course, got succeed. Then I tried to implent the method to unpack this The Enigma Protector 4.20. The VM pattern is different. I'm lost, again. What a shame, haha.


GIV's unpacked file has VM OEP. I studied the dumped section and all different like my dump. Confusing. I'm lost :(


In this The Enigma Protector 4.20 Unpackme, I just only know about VA 7FBD0000 need to be dumped. I don't know what section need to be dumped except VA 7FBD0000. Your Engma Alternativ Unpacker 1.1 says NO OUTER VM used so no VM dumped. But I'm pretty sure this unpackme need some VM section to be dumped.


I'm feeling it looks like spoonfeeding to me. What a shame for newbie like me. :'( Got some hints and succeed but when got something different, got lost :(



Link to comment



so this UnpackMe does differ and used also a another VM and your file not so you see the difference right at OEP jump to 7FBD0000.You need to dump the important used VM (best you do redirect them into one section).Ok I made now also a quick video for this with that UnpackMe and wrote also a quick script for it which you can use and follow step by step later.Just download watch & try it.



Redirect VM + Script + Video.rar

  • Like 3
Link to comment



Is your Script only for this Enigma Protector 4.20 Unpackme? Or maybe only for version 4.20?

I tried script for my Unpackme (3.70 VM OEP) and 4.30 DEMO (VM OEP). The result I got is only 0 KB of VM.mem.

The ID, VA, and OEP sure I already change before running the script.



Link to comment



of course the script is just for this UnpackMe. :) Sure you can change the values but you also need then to disable the ID part if not used in your xy UnpackMe and you need to check the TYPE & SIZE.


Also remember if UnpackMe file was protected by 3.70 then it dosen't use this kind of RISC VM like in the UnpackMe of this topic so this VM was added since version 4.00.



  • Like 2
Link to comment
  • 2 weeks later...

I do as folows:

Bp on VirtualAlloc, use bpgoto command of Ollyscript and check the high alloc pointer and disable.


cmp [esp+c], 00001000
log ebx, ""
cmp [esp+c], 00101000
je pauza
jmp Urmatorul

mov [esp+c], 1000

Link to comment
  • 4 months later...

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