Now Reading
Breaking SecuROM 7 – A Dissection

Breaking SecuROM 7 – A Dissection

2024-01-28 09:03:31

That is an archive of an previous whitepaper made by three reverse engineering consultants on breaking down SecuROM and its a number of layers of safety.

Archive Opening Notes

As talked about, this can be a whitepaper launched by ARTeam in 2007/8, revealing how SecuROM 7 may be damaged down utilizing reverse engineering methods. The tutorial is now round 10 years previous, so lots of the instruments used are outdated or laborious to search out. All the instruments used on this tutorial have been added to the global index, and are saved on this web site.

This offers a really attention-grabbing take a look at how the expertise was carried out, primarily stitching two executables collectively, and how one can dump and take away the DRM altogether.

Please observe that this was written by an exterior supply, ARTeam, and formatted by yours actually to be used in a weblog, in addition to archiving all the photographs and instruments required.

LostFileArchives will not be answerable for any repercussions that will
come from utilizing this doc, and is solely storing it for archival functions.


After the publication of our first essay on SecuROM I acquired plenty of curiosity and replies on this argument, the primary essay was contributed by AnonymouS and was only a bit, an perception into SecuROM, plenty of issues had been nonetheless lacking, like fixing different anti-debugging and anti-dump strategies, fixing redirections and VM. I then organized with deroko, Human and AnonymouS once more to jot down a extra full walkthrough on SecuROM, this time overlaying all of the required points to efficiently personal it.
The result’s this new Particular Difficulty gathering the contributions of those authors.

This protector is on the scene since time started, and all of the video games protected with it have already been cracked then it’s time to make these items clearly public in order anybody can perceive them.
I’m additionally distributing the instruments and scripts used within the tutorials composing this particular difficulty.

After all I need to thanks authors right here for his or her time and their instruments. SecuROM was a safety which unprotection was stored secret for a very long time, now no extra.

Have phun,


All code included with this tutorial is free to make use of and modify; we solely ask that you simply point out the place you discovered it. This tutorial can also be free to distribute in its present unaltered kind, with all of the included dietary supplements.

Archive observe: Dietary supplements for this tutorial may be present in The Index’s chilly storage.

All of the industrial applications used inside this doc have been used just for the aim of demonstrating the theories and strategies described. No distribution of patched functions has been executed underneath any media or host. The functions used had been a lot of the occasions already been patched, and cracked variations had been accessible since plenty of time. ARTeam or the authors of the paper can’t be thought-about answerable for damages to the businesses holding rights on these applications. The scope of this tutorial in addition to every other ARTeam tutorial is of sharing information and instructing how one can patch functions, how one can bypass protections and usually talking how one can enhance the RCE artwork and usually the comprehension of what occurs underneath the hood. We’re not releasing any cracked software. We’re what we all know.

Desk of Contents

Some Insights into SecuROM 7.30.0014 by AnonymouS (3)

  1. Forewords (3)
  2. Settings and Goal (3)
    2.1. Goal (3)
    2.2. Instrument Used (3)
  3. Defeating the mysterious debug-detection (4)
  4. Reaching OEP (5)
  5. Defeating the anti-dumping trick. (7)
  6. Conclusion (9)
  7. Last phrases and greetings (9)

Full Cracking SecuRom 7.xx by Human (10)

  1. Foreword and wanted instruments (10)
  2. First step: begin of journey (10)
  3. Second step: put together issues (10)
  4. Third Step: Load the sport into Olly and rebase (11)
  5. Fourth Step: daemons instruments and OEP (13)
  6. Fifth Step: Fixing Anti-dumps (17)
  7. Sixth Step: fixing the CRCChecks (18)
  8. Seventh Step: taking good care of antidumps (20)
  9. Conclusions (34)

SecuROM for the lots by deroko (35)

  1. Forewords (35)
  2. Instruments and Goal (35)
  3. Few phrases about SecuROM (36)
  4. Dumping SecuROM (37)
  5. Anti-Dump fixing (48)
  6. Conclusion (55)
  7. References (55)
  8. Greetings (55)

Nicely deep Inside SecuRom by AnonymouS (56)

  1. The humorous facet of issues (56)
  2. Code morphing (56)
  3. Primary API redirection (57)
  4. Code splicing (58)
  5. Superior API redirections (59)
  6. Digital Machine (60)

Archive Word: All of those tutorials use extraordinarily previous instruments. The identical impact may be achieved with extra fashionable decompilation applications corresponding to AIDA64 and others.

Some Insights into SecuROM 7.30 by AnonymouS

1. Forewords

It’s been some time since I did any reversing. It hasn’t been a lot reversing for the reason that launch of the X-Prot v2 unpacker. To start with as a result of I’m lazy, however actual life additionally had lots occurring. Anyway, I’ve been following the SecuRom thread ( on ARTeam’s discussion board for some time, determined to look deeper into SecuRom 7.

Initially I needed to code an unpacker and began coding unpackers for SecuRom 7.10 via 7.12. As I started coding on an unpacker for SecuRom V7.18 I discovered that the duty was fairly demanding so I deserted 7.18 and moved on to 7.30.0014.

This small tutorial/essay will not be about utterly reversing SecuRom 7.30.0014. It’s only a assist for folks on how one can attain OEP and on the way in which defeating the anti-debugger trick that apparently stops lots of people. I will even present I bypass the anti-dump trick utilized by SecuRom.

The tutorial/essay will not be very explaining as I do suppose that folks studying this will likely be someway greater than only a beginner reverser. SecuRom is a tricky safety and good reversing abilities are wanted as a way to absolutely reverse this safety.

2. Settings and Goal

2.1. Goal

Resident Evil 4 from Capcom

2.2. Instrument Used

OllyDbg V1.10 OllyDbg plugin (HideOD) with the next settings:


TaskMngr by drizz (Hyperlink to Offline Website)

3. Defeating the mysterious debug-detection

Okay, let’s go to work… Run Olly, choose executable and let Olly unfastened. We hit to exceptions earlier than get this error message:


Within the earlier variations I used to get this at any time when the ZwQueryObject trick was launched, however once I patch this I nonetheless get the error message, so I are likely to suppose it’s the mysterious debugger detection individuals are speaking about on the ARTeam thread.

How does it detect us?? We’re utilizing HideOD and ZwQueryObject will not be the rationale, so this have to be new debugger detection. Let’s begin tracing… I’ll spare you for the agonizing of tracing via large quantity for checksums with SecuRom and allow you to straight to the reply.


Discover the CMP BYTE PTR DS:[EAX+4],0 ??? It’s actually part of a a lot massive process… Anyway, modify this by setting TRUE again to FALSE (1 to 0).


To be sincere, I’m not fairly positive what precisely occur, however check out this clear code, stripped from obfuscation, trap-flag safety and checksums:

0577F556 FFD5             CALL EBP    <-- name RtlAcquirePebLock 
056D89E3 8B45 08       MOV EAX,DWORD PTR SS:[EBP+8]  <-- [EBP+8] == 30h
056D89E6 64:8B00       MOV EAX,DWORD PTR FS:[EAX]  <-- Get PEB handle
0577FDC9 8078 04 00    CMP BYTE PTR DS:[EAX+4],0  <-- TRUE if debugged
0577FDD3 75 12         JNZ SHORT sport.0577FDE7  <-- leap unhealthy boy 

From Microsoft’s library I got here throughout this:


From what I can see the flag at [EAX+4] is someway switched on when debugged. I attempted coding somewhat check myself however I at all times got here up with a TRUE outcome even when I used to be not operating a debugger !?!

4. Reaching OEP

Hearth up Olly and run via all exceptions, together with fixing the anti-debug trick, till you attain:


Then set a conditional BPX on VirtualProtect and run it.


As soon as Olly breaks clear BPX and droop all threads besides the principle one.


Now set a breakpoint on ReleaseMutex and let Olly run till it breaks once more. CTRL+F9 will lead you to the RETN in ReleaseMutex. Hint again into user-code and you’ll find yourself right here:


Now seek for the sample: C9 87 3C 24


Remember there are extra offsets that match this sample however the first one discovered needs to be the “good” one. If this isn’t the case, you higher begin tracing 😉 Anyway ought to look one thing like this:


Place a {Hardware} breakpoint on the instruction after the LEAVE opcode and run Olly. When Olly breaks go to Reminiscence Map and place a breakpoint code part utilizing F2 and run Olly.


Subsequent time Olly breaks we’re at OEP.


Now we will dump…. Or can we ???

5. Defeating the anti-dumping trick.

As one can see, reaching the OEP of SecuRom 7.30.0014 is pretty straightforward. Nonetheless, the authors did one other try and sluggish us down. After we hearth up our PE-dumper we get this message:


Hmm… What occurs right here ?? Our dumper gained’t dump ?!? Don’t fear… That is simply defeated … Fortunately for you I did all of the tracing via SecuRom’s checksum hell. Let’s rewind time somewhat bit 😉

As I encountered this I made a decision to search out out the place precisely made this anti-dump trick attainable. I let the executable run till the primary exception and tried to dump. Right here I additionally obtained the error message… So, which means the anti-dump trick is setup earlier than the primary exception. Now I easy began the sluggish strategy of tracing via tons of checksums. First I encountered this:


This let me to the thought that SecuRom for some unusual purpose GUARD PAGE the .securom part. So I set at breakpoint on VirtualProtect and after a number of hits I ended right here:


I then retraced my means again to the consumer code (CTRL-F9) and ended right here:


Now we all know what to do when attain the OEP, so let’s quick ahead to the OEP and open up the Reminiscence Map and set the entry again to FULL ACCESS on the .securom part:


Now we will lastly dump the executable with none issues.


6. Conclusion

As one can see it’s pretty straightforward to succeed in the OEP of SecuRom 7.30.0014. It’s additionally attainable to dump the executable as soon as we set again the web page entry to FULL. As for the mysterious debugger detection, we discovered it and is ready to repair the issue. Nonetheless, reaching OEP and having the ability to dump the executable will not be sufficient to defeating SecuRom. The dump is full of VM code, code-splicings and so on. and so on. I solely confirmed the way in which to the promised land, it’s now as much as you to work your means via it your self 😉

7. Last phrases and greetings

As said within the forewords this isn’t an entire tutorial on how one can reverse SecuRom, however merely a fast step-by-step on how one can attain the OEP of model 7.30.0014. I need to admit that I haven’t regarded into the VM and code-splicing of this model. I initially type of promised that I might code one other unpacker however I doubt that I’ll ever code any once more. Mainly I haven’t obtained the time anymore and the credit you get out of your many hours of labor are minimal. Nonetheless, if my good pal, Nacho DJ, speak me into it I’d do some extra tutorials 😉

Final however not least I want to ship out my greetings to:

  • My spouse, Kristine and my son Frederik
  • All ARTeam member (particularly Nacho DJ)
  • Drizz
  • All I forgot

Sincerely, AnonymouS / ARTeam

Full Cracking SecuROM 7 by Human

1. Foreword and wanted instruments

Hi there and Welcome to my tut about cracking securom 7.xx (one thing round 7.30)

What we want..

And my scripts:

  • Securom 7.x Cpuid Fixer (included into this distribution)
  • Securom 7.x CRC Test Fixer (included into this distribution)
  • Securom 7.x Leap Bridge & Crypted Code Fixer (included into this distribution)

    Archiver’s Word: Discover the above information in Chilly Storage underneath the identify “SecuROM Writeup Required Information”.

    Word: this tutorial is extra like unpacking tutorial and never a deep analyze why I do issues, I spent plenty of time analyzing this, so if you would like perceive higher.

Do it alone, test how secuRom makes use of these. With this tut it might be simpler for you.

2. First step: begin of journey

Lets begin with putting in sport.

3. Second step: put together issues

Set up patch(in case you have biohazard you continue to can set up patch after some steps)

First insert Reg file with path to your biohazard 4

REGEDIT4 [HKEY_LOCAL_MACHINESOFTWARECAPCOMresident evil 4] "PATH"="e:Video gamesbiohazard 4" 

Subsequent lets load patch into ollydbg and patch its complain about no sport to replace 😛


You see 00407E4B change it to JMP SHORT upd_pal1.00407EAB and patch will begin patching us to 1.1 and securom protected (properly it takes some time)


4. Third Step: Load the sport into Olly and rebase

Lets load sport.exe into olly. Press alt+M to see reminiscence.
As you’ll be able to see d3dx9_30.dll blocks our dump to have linear areas 🙁


So we now have to make use of rebaser from Dr.Golova to repair it to our wants (dont fear All Works after it) rebase it to 20000000h


Lets reload sport.exe and voila All is ok All vary after exe until 20000000h is free:)


5. Fourth Step: daemons instruments and OEP

  1. Lets load maxi picture into daemon instruments 4.10

  2. Run Yasu to cloak digital drives

Archiver’s Word: Don’t hassle utilizing YASU, simply use SecuROM Loader 1.2.

  1. Set break level on CreateProcessInternalA and run, after break you will notice on stack param to make use of with oepfind, so lets use it.

  2. For me command to run In Whole commander is like this:

    oep sport.exe /Sonydadc /05f0612d /05f0612d /220792E1 /1

Final param is time in ms, antidebug that spawns one other occasion of exe and kills dad or mum if distinction is simply too excessive from present GetTickCount. However due we patch GetTickCount to depend slower in charge of +1, we use /1 as an alternative of authentic time

With oepfind we use these settings:

Now Press detach to search for OEP. After about 10 seconds we now have:


High quality so Press sure or Any key In your language. Run Olly and fix to our sport.exe. Keep in mind PID due we are going to want it later, mine is right here 75C

Don’t run simply in menu choose view/threads and double click on that one suspended.


Like you’ll be able to see we’re AT OEP 🙂

Press OK In oepfind to take away infinite leap. However dont shut it but!!

Once more we should Press alt+M and alter .securom part axx rights to full so proper click on on it and do Set Entry/Full Entry Now it’s time to dump reminiscence areas I do know it’s plenty of reminiscence however I’m too lazy to code correct reminiscence supervisor. As you’ll be able to see our reminiscence begins at 0x6130000


And ends at 94CF000+1000 so its 94D0000 (final area that doesn’t present Any file identify, right here final earlier than d3dx9_30.dll). Let put these into oepfind to Fields that are actually not grayed out.


Press dump and in your dir you’ll discover a file named DUMP_06130000-094D0000 of 54mb, with all of the dumped vary. Now you’ll be able to shut oepfind.

6. Fifth Step: Fixing Anti-dumps

Now we’re able to dump exe, however earlier than that we should do one factor. One other securom safety is left. Securom makes use of additionally EP as antidump. So when ollydump change now EP to OEP we will likely be screwed. Securom provides return params from many Apis to handle. So when for instance authentic PID is 200 and dumped program’s PID is 100, we now have 200-100+handle will get mistaken information and finish with a web page fault. So it at all times needs to be 0, when each are similar.

Okay, then again to our EP, what to do? Merely transfer the header someplace else. Choose all from 400140 until 400300 do binary copy and binary paste it to 4001C0

Then we alter 40 to C0 at 40003C to level to a brand new place.


Now we will dump our exe with unticked rebuild imports.

As you’ll be able to see exe is 97Mb, biohazard exe with out securom is Simply 6Mb, that’s how protections harm clients, not my fault then.

Subsequent step will likely be to repair imports and add our areas. So let hearth up CFF Explorer (I patched mine due I used to be pissed with asking ought to I load greater than fucked 20MB, what a dumb query in the present day, when minimal reminiscence is 2GB).

Click on part headers and proper click on to do “Add Part (file information)” so as to add our dumped areas.

Repair digital handle with begin address-imagebase 6130000400000=5D30000 and alter part rights to E0000020


Do proper click on, rebuild picture dimension, header and save exe.

Now repair imports, properly we don’t want imprec all we want is into the .idata part. Run Winhex with sport.exe and press alt+G now go to 66b000 are you able to see these addresses? So copy these until API names.

Shut it and now run Winhex on dump.exe, press alt+G and go to 53E8000, now Ctrl+B to stick our IAT, that now as you’ll be able to see will not be RVA, solely 7Cxxxxxx. Save the exe and rebuild from the start. After the rebuild we are going to once more paste IAT due from Olly we are going to dump exe once more with API addresses modified from RVA to 7Cxxxxxx.

7. Sixth Step: fixing the CRCChecks

Until now we dumped the exe, mounted the IAT and the PE header, and added lacking file areas. We are able to begin with fixing relaxation.

We begin with fixing CRCchecks, for this we are going to use my Securom 7.x CRC Test Fixer.txt script (included in goodies folder of this distribution). CRCchecks is available in 2 flavours: reminiscence and register. Reminiscence CRC updates at all times some handle [esp+xx] and later makes use of it, different kind updates considered one of registers eax,ebx,ecx and so on.

So what this script does? It searches for patterns of CRCcheck and units an HW breakpoint, after calculation loop it replaces all the things with nops and paste there simply calculated worth that will likely be then hardcoded.


Like you’ll be able to see 057EE02D ADD DWORD PTR SS:[ESP+14],EDI. That is the place of our repair. (I seen that, and actually don’t know why, odbgscript runs quicker when I’ve some some film in background, open however stopped).

It takes plenty of time even on my Intel C2D E6700 (with a film stopped it runs 4x quicker :P). Anyway the homework this script does is actually large, it has to repair greater than 100.000 places. The works is completed into a brief reminiscence buffer: CRCchecks calc CRCs utilizing their very own native loops, after this the temp buffer is copied again into sections substituting the CrCCheck simply executed. Minimizing Olly window additionally hurries up as a result of Home windows doesn’t redraw all.

A results of the script is proven right here:


Like you’ll be able to see in above determine, ESP+14 updates at all times to 164E, and log reveals script took 724983ms so 12 minutes 😛

Don’t alter script, it is not going to be quicker, I already optimized it to max. Even direct write of opcodes as bytes is quicker than assembling new instruction. CRCcheck sample is in 2 sections, so each these are In script.

  1. Seventh Step: taking good care of antidumps

Now its time to handle antidump APIs. On this model securom makes use of the next:

  • GetCurrentProcessId: each course of will get PID however to make it work, dump must return PID as authentic course of
  • GetVersion: each home windows have personal model, so to make it work on vista however dumped on xp we have to return xp model
  • CPUID: each CPU have personal ID returned in eax & edx, so to make it work on different CPUs it has to return the ID saved within the dump, ours then.
  • ResetEvent: each securom exe creates occasion or occasions, dump doesn’t have them so we have to return 1
  • GetComputerNameA: each laptop has a reputation, so different laptop should match what we retailer into the dump
  • GetUserNameA: each consumer logged has a reputation, different consumer logged and it crashes, so similar applies right here
  • RtlGetLastWin32Error: right here once more we have to return 1, in case there are errors we inform there aren’t any
  • GetSystemInfo: each laptop has personal 20 bytes System data desk returned, once more it should match our

Figuring out all this we will begin patching securom. For this we want a spot, I select 9BFF00. And that’s the way it will look:

009BFF00    B8 88030000             MOV EAX,388 
009BFF05    034424 04               ADD EAX,DWORD PTR SS:[ESP+4]                   ; ntdll.7C910738 
009BFF09    C2 0400                 RETN 4 
009BFF0C    B8 0501280A             MOV EAX,0A280105 
009BFF11    2B4424 04               SUB EAX,DWORD PTR SS:[ESP+4]                   ; ntdll.7C910738 
009BFF15    C2 0400                 RETN 4 
009BFF18    B8 D6060000             MOV EAX,6D6 
009BFF1D    334424 04               XOR EAX,DWORD PTR SS:[ESP+4]                   ; ntdll.7C910738 
009BFF21    C2 0400                 RETN 4 
009BFF24    A1 88BAD705             MOV EAX,DWORD PTR DS:[5D7BA88] 
009BFF29    C2 0400                 RETN 4 009BFF2C    8B4424 04               MOV EAX,DWORD PTR SS:[ESP+4]                   ; ntdll.7C910738 
009BFF30    8B0D 98BAD705           MOV ECX,DWORD PTR DS:[5D7BA98] 
009BFF36    03C1                    ADD EAX,ECX 
009BFF38    35 A416827C             XOR EAX,7C8216A4 
009BFF3D    C2 0400                 RETN 4 


009BFF40    A1 F4BAD705             MOV EAX,DWORD PTR DS:[5D7BAF4] 
009BFF45    8B0D 04BBD705           MOV ECX,DWORD PTR DS:[5D7BB04] 
009BFF4B    03C1                    ADD EAX,ECX 
009BFF4D    0305 ECBAD705           ADD EAX,DWORD PTR DS:[5D7BAEC] 
009BFF53    C2 0400                 RETN 4 
009BFF56    B8 E0F7CB85             MOV EAX,85CBF7E0 
009BFF5B    C2 0400                 RETN 4 
009BFF5E    E8 00000000             CALL b.009BFF63 
009BFF63    5E                      POP ESI                                        ; kernel32.7C816FD7 
009BFF64    83C6 19                 ADD ESI,19 
009BFF67    57                      PUSH EDI                                       ; ntdll.7C910738 
009BFF68    8B7C24 08               MOV EDI,DWORD PTR SS:[ESP+8] 
009BFF6C    B9 24000000             MOV ECX,24 
009BFF71    F3:A4                   REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI] 009BFF73    BE 10000000             MOV ESI,10 
009BFF78    5F                      POP EDI                                        ; kernel32.7C816FD7 
009BFF79    C2 0400                 RETN 4

Right here you will have binary copy of the patch you’ll be able to paste in binary format:

B8 74 05 00 00 03 44 24 04 C2 04 00 B8 05 01 28 0A 2B 44 24 04 C2 04 00 B8 D6 06 00 00 33 44 24 04 C2 04 00 A1 88 BA D7 05 C2 04 00 8B 44 24 04 8B 0D 98 BA D7 05 03 C1 35 A4 16 82 7C C2 04 00 A1 F4 BA D7 05 8B 0D 04 BB D7 05 03 C1 03 05 EC BA D7 05 C2 04 00 B8 CF F7 4B 87 C2 04 00 E8 00 00 00 00 5E 83 C6 19 57 8B 7C 24 08 B9 24 00 00 00 F3 A4 BE 10 00 00 00 5F C2 04 00 00 00 00 00 00 10 00 00 00 00 01 00 FF FF FE 7F 03 00 00 00 02 00 00 00 4A 02 00 00 00 00 01 00 06 00 06 0F 

Now I’ll clarify why it appears to be like prefer it. To start with go to handle 0x5A61A7B


Lets see what’s inside CALL DWORD PTR DS:[5EA4634]?

05A66760    FF15 7CBAD705           CALL DWORD PTR DS:[5D7BA7C]             ; kernel32.GetCurrentProcessId 
05A66766    034424 04               ADD EAX,DWORD PTR SS:[ESP+4]            ; ntdll.7C910738 
05A6676A    C2 0400                 RETN 4 

This code needs our PID, and later provides worth pushed on stack to it. That’s why we should always have right here:

MOV EAX,75C                       ; is my PID of securom course of that I dumped ADD EAX,DWORD PTR SS:[ESP+4] RETN 4 

Now get again out of it. Do you see this?

05A61A7A    50                      PUSH EAX 
05A61A7B    FF15 3446EA05           CALL DWORD PTR DS:[5EA4634]                 ; b.05A66760 
05A61A81    35 6067A605             XOR EAX,5A66760 
05A61A86    3305 3446EA05           XOR EAX,DWORD PTR DS:[5EA4634]              ; b.05A66760 

Difficult, it does a XOR on EAX, with the handle of this small code half after which does once more a XOR with the handle of small code half that’s held in [5EA4634] so we will’t change handle for our patch. However hey simply change 2nd XOR to similar as 1st one, 2 chained XORs with similar worth will give us 0 so EAX is not going to change. Similar trick we are going to do on different under, and underneath [5EA4634] we are going to now put 9BFF00 for our patch.

One executed few extra to go.

What have we in 05A61A92 CALL DWORD PTR DS:[5EA4638] ?

Oh its:

05A66770    FF15 80BAD705           CALL DWORD PTR DS:[5D7BA80]                 ; kernel32.GetVersion 
05A66776    2B4424 04               SUB EAX,DWORD PTR SS:[ESP+4]                ; ntdll.7C910738 
05A6677A    C2 0400                 RETN 4 

So changing it with:

009BFF0C    B8 0501280A             MOV EAX,0A280105                            ; my xp model 009BFF11    2B4424 04               SUB EAX,DWORD PTR SS:[ESP+4]                ; ntdll.7C910738 
009BFF15    C2 0400                 RETN 4 

We are going to defeat that half too.


05A61AA9    FF15 3C46EA05           CALL DWORD PTR DS:[5EA463C]                 ; b.05A66780 
05A66780    8D6424 FC               LEA ESP,DWORD PTR SS:[ESP-4] 
05A66784    892C24                  MOV DWORD PTR SS:[ESP],EBP 
05A66787    8BEC                    MOV EBP,ESP 
05A66789    8D6424 FC               LEA ESP,DWORD PTR SS:[ESP-4] 
05A6678D    890C24                  MOV DWORD PTR SS:[ESP],ECX 
05A66790    8D6424 FC               LEA ESP,DWORD PTR SS:[ESP-4] 
05A66794    891C24                  MOV DWORD PTR SS:[ESP],EBX 
05A66797    8B0D 2046EA05           MOV ECX,DWORD PTR DS:[5EA4620] 
05A6679D    85C9                    TEST ECX,ECX 
05A6679F    7E 16                   JLE SHORT b.05A667B7 
05A667A1    A1 B4BAD705             MOV EAX,DWORD PTR DS:[5D7BAB4] 
05A667A6    3345 08                 XOR EAX,DWORD PTR SS:[EBP+8]                ; b.<ModuleEntryPoint> 
05A667A9    2B0D 2446EA05           SUB ECX,DWORD PTR DS:[5EA4624] 
05A667AF    890D 2046EA05           MOV DWORD PTR DS:[5EA4620],ECX 
05A667B5    EB 41                   JMP SHORT b.05A667F8 
05A667B7    D13D 2446EA05           SAR DWORD PTR DS:[5EA4624],1 
05A667BD    53                      PUSH EBX 
05A667BE    51                      PUSH ECX 
05A667BF    52                      PUSH EDX                                    ; ntdll.KiFastSystemCallRet 05A667C0    B8 01000000             MOV EAX,1 
05A667C5    0FA2                    CPUID 
05A667C7    5A                      POP EDX                                     ; kernel32.7C816FD7 
05A667C8    59                      POP ECX                                     ; kernel32.7C816FD7 
05A667C9    5B                      POP EBX                                     ; kernel32.7C816FD7 
05A667CA    83E0 DF                 AND EAX,FFFFFFDF 


05A667CD    A3 B4BAD705             MOV DWORD PTR DS:[5D7BAB4],EAX 
05A667D2    3345 08                 XOR EAX,DWORD PTR SS:[EBP+8]                ; b.<ModuleEntryPoint> 
05A667D5    8945 FC                 MOV DWORD PTR SS:[EBP-4],EAX 
05A667D8    833D 2446EA05 00        CMP DWORD PTR DS:[5EA4624],0 
05A667DF    8B45 FC                 MOV EAX,DWORD PTR SS:[EBP-4] 
05A667E2    C705 2046EA05 00000100  MOV DWORD PTR DS:[5EA4620],10000            ; UNICODE "=D:=D:" 
05A667EC    75 0A                   JNZ SHORT b.05A667F8 
05A667EE    C705 2446EA05 01000000  MOV DWORD PTR DS:[5EA4624],1 
05A667F8    5B                      POP EBX                                     ; kernel32.7C816FD7 
05A667F9    C9                      LEAVE 
05A667FA    C2 0400                 RETN 4 

Oh it’s the CPUID!!!

And as you’ll be able to see it does on it:

05A667CA    83E0 DF                 AND EAX,FFFFFFDF 
05A667D2    3345 08                 XOR EAX,DWORD PTR SS:[EBP+8] 

So correct patch for my CPU, somewhat optimized, is:

009BFF18    B8 D6060000             MOV EAX,6D6 
009BFF1D    334424 04               XOR EAX,DWORD PTR SS:[ESP+4]                ; ntdll.7C910738 
009BFF21    C2 0400                 RETN 4 

Why not esp+8? Why I don’t push and pop ebx?


05A61AC0    FF15 4046EA05           CALL DWORD PTR DS:[5EA4640]                 ; b.05A66800 
05A66800    A1 90BAD705             MOV EAX,DWORD PTR DS:[5D7BA90] 
05A66805    3B05 2846EA05           CMP EAX,DWORD PTR DS:[5EA4628] 
05A6680B    7C 2C                   JL SHORT b.05A66839 
05A6680D    FF35 88BAD705           PUSH DWORD PTR DS:[5D7BA88] 
05A66813    FF15 84BAD705           CALL DWORD PTR DS:[5D7BA84]                 ; kernel32.ResetEvent 
05A66819    85C0                    TEST EAX,EAX 
05A6681B    75 22                   JNZ SHORT b.05A6683F 
05A6681D    2105 90BAD705           AND DWORD PTR DS:[5D7BA90],EAX 05A66823    813D 2846EA05 00001000  CMP DWORD PTR DS:[5EA4628],100000 
05A6682D    7D 06                   JGE SHORT b.05A66835 
05A6682F    D125 2846EA05           SHL DWORD PTR DS:[5EA4628],1 
05A66835    33C0                    XOR EAX,EAX 
05A66837    EB 0B                   JMP SHORT b.05A66844 
05A66839    FF05 90BAD705           INC DWORD PTR DS:[5D7BA90] 
05A6683F    A1 88BAD705             MOV EAX,DWORD PTR DS:[5D7BA88] 
05A66844    C2 0400                 RETN 4 

And all we want of that is:

009BFF24    A1 88BAD705             MOV EAX,DWORD PTR DS:[5D7BA88] 
009BFF29    C2 0400                 RETN 4 


05A61AE5    FF15 4446EA05           CALL DWORD PTR DS:[5EA4644]                 ; b.05A66850 
05A66850    8D6424 FC               LEA ESP,DWORD PTR SS:[ESP-4] 
05A66854    EB 00                   JMP SHORT b.05A66856 
05A66856    893424                  MOV DWORD PTR SS:[ESP],ESI 
05A66859    A1 94BAD705             MOV EAX,DWORD PTR DS:[5D7BA94] 
05A6685E    3B05 2C46EA05           CMP EAX,DWORD PTR DS:[5EA462C] 
05A66864    7C 70                   JL SHORT b.05A668D6 
05A66866    BE D4BAD705             MOV ESI,b.05D7BAD4 
05A6686B    56                      PUSH ESI 
05A6686C    FF15 B8BAD705           CALL DWORD PTR DS:[5D7BAB8]               ; ntdll.RtlEnterCriticalSection 
05A66872    68 98BAD705             PUSH b.05D7BA98 
05A66877    68 C4BAD705             PUSH b.05D7BAC4                             ; ASCII "HUMAN" 
05A6687C    C705 98BAD705 10000000  MOV DWORD PTR DS:[5D7BA98],10 
05A66886    FF15 C0BAD705           CALL DWORD PTR DS:[5D7BAC0]                 ; kernel32.GetComputerNameA 
05A6688C    85C0                    TEST EAX,EAX 
05A6688E    75 24                   JNZ SHORT b.05A668B4 
05A66890    813D 2C46EA05 00100000  CMP DWORD PTR DS:[5EA462C],1000 
05A6689A    7D 06                   JGE SHORT b.05A668A2 


05A6689C    D125 2C46EA05           SHL DWORD PTR DS:[5EA462C],1 05A668A2    8325 94BAD705 00        AND DWORD PTR DS:[5D7BA94],0 
05A668A9    56                      PUSH ESI 
05A668AA    FF15 BCBAD705           CALL DWORD PTR DS:[5D7BABC]               ; ntdll.RtlLeaveCriticalSection 
05A668B0    33C0                    XOR EAX,EAX 
05A668B2    EB 3A                   JMP SHORT b.05A668EE 
05A668B4    56                      PUSH ESI 
05A668B5    FF15 BCBAD705           CALL DWORD PTR DS:[5D7BABC]               ; ntdll.RtlLeaveCriticalSection 
05A668BB    8325 94BAD705 00        AND DWORD PTR DS:[5D7BA94],0 
05A668C2    813D 2C46EA05 00100000  CMP DWORD PTR DS:[5EA462C],1000 
05A668CC    7D 0E                   JGE SHORT b.05A668DC 
05A668CE    D125 2C46EA05           SHL DWORD PTR DS:[5EA462C],1 
05A668D4    EB 06                   JMP SHORT b.05A668DC 
05A668D6    FF05 94BAD705           INC DWORD PTR DS:[5D7BA94] 
05A668DC    8B4424 08               MOV EAX,DWORD PTR SS:[ESP+8] 
05A668E0    8B0D 98BAD705           MOV ECX,DWORD PTR DS:[5D7BA98] 
05A668E6    03C1                    ADD EAX,ECX 
05A668E8    3305 C0BAD705           XOR EAX,DWORD PTR DS:[5D7BAC0]              ; kernel32.GetComputerNameA 
05A668EE    5E                      POP ESI                                     ; kernel32.7C816FD7 
05A668EF    C2 0400                 RETN 4 

And correct patch of this code will likely be? Nicely have you learnt already?

009BFF2C    8B4424 04               MOV EAX,DWORD PTR SS:[ESP+4]                ; ntdll.7C910738 
009BFF30    8B0D 98BAD705           MOV ECX,DWORD PTR DS:[5D7BA98] 
009BFF36    03C1                    ADD EAX,ECX 
009BFF38    35 A416827C             XOR EAX,7C8216A4 
009BFF3D    C2 0400                 RETN 4 

Once more no esp+8 no have to push pop esi. Nicely now you marvel why XOR EAX,7C8216A4

Look nearer and you will notice it XOR with handle of GetComputerNameA, so for me handle of this api is 7C8216A4


05A61AF9    FF15 4846EA05           CALL DWORD PTR DS:[5EA4648]                 ; b.05A66900 

Right here as you’ll comply with you will notice nothing is conditional or reminiscence dependent:

08AF0000    E8 00000000             CALL b.08AF0005 
08AF0005    58     POP EAX                                     ; kernel32.7C816FD7 
08AF0006    05 AA4EA605             ADD EAX,b.05A64EAA 
08AF000B    2D AF4EA605             SUB EAX,b.05A64EAF 
08AF0010    C3                 RETN

So we go away it as it’s


05A61B1E    FF15 4C46EA05           CALL DWORD PTR DS:[5EA464C]                 ; b.05A66910 
05A66910    8D6424 FC               LEA ESP,DWORD PTR SS:[ESP-4] 
05A66914    892C24                  MOV DWORD PTR SS:[ESP],EBP 
05A66917    8BEC                    MOV EBP,ESP 
05A66919    8D6424 FC               LEA ESP,DWORD PTR SS:[ESP-4] 
05A6691D    890C24                  MOV DWORD PTR SS:[ESP],ECX 
05A66920    8D6424 FC               LEA ESP,DWORD PTR SS:[ESP-4] 
05A66924    90                      NOP 
05A66925    893424                  MOV DWORD PTR SS:[ESP],ESI 
05A66928    A1 68BAD705             MOV EAX,DWORD PTR DS:[5D7BA68] 
05A6692D    3B05 3046EA05           CMP EAX,DWORD PTR DS:[5EA4630] 
05A66933    7C 6B                   JL SHORT b.05A669A0 
05A66935    BE F0BBD705             MOV ESI,b.05D7BBF0 
05A6693A    56                      PUSH ESI 
05A6693B    FF15 08BCD705           CALL DWORD PTR DS:[5D7BC08]               ; ntdll.RtlEnterCriticalSection 
05A66941    8D45 FC                 LEA EAX,DWORD PTR SS:[EBP-4] 
05A66944    50                      PUSH EAX 
05A66945    68 ECBAD705             PUSH b.05D7BAEC                             ; ASCII "Human" 
05A6694A    C745 FC 01010000        MOV DWORD PTR SS:[EBP-4],101 
05A66951    FF15 6CBAD705           CALL DWORD PTR DS:[5D7BA6C]                 ; ADVAPI32.GetUserNameA 
05A66957    85C0                    TEST EAX,EAX 
05A66959    75 23                   JNZ SHORT b.05A6697E 
05A6695B    2105 68BAD705           AND DWORD PTR DS:[5D7BA68],EAX 
05A66961    813D 3046EA05 00100000  CMP DWORD PTR DS:[5EA4630],1000 


05A6696B    7D 06                   JGE SHORT b.05A66973 
05A6696D    D125 3046EA05           SHL DWORD PTR DS:[5EA4630],1 
05A66973    56                      PUSH ESI 
05A66974    FF15 0CBCD705           CALL DWORD PTR DS:[5D7BC0C]               ; ntdll.RtlLeaveCriticalSection 
05A6697A    33C0                    XOR EAX,EAX 
05A6697C    EB 3B                   JMP SHORT b.05A669B9 
05A6697E    56                      PUSH ESI 
05A6697F    FF15 0CBCD705           CALL DWORD PTR DS:[5D7BC0C]               ; ntdll.RtlLeaveCriticalSection 
05A66985    8325 68BAD705 00        AND DWORD PTR DS:[5D7BA68],0 
05A6698C    813D 3046EA05 00100000  CMP DWORD PTR DS:[5EA4630],1000 
05A66996    7D 0E                   JGE SHORT b.05A669A6 
05A66998    D125 3046EA05           SHL DWORD PTR DS:[5EA4630],1 
05A6699E    EB 06                   JMP SHORT b.05A669A6 
05A669A0    FF05 68BAD705           INC DWORD PTR DS:[5D7BA68] 
05A669A6    A1 F4BAD705             MOV EAX,DWORD PTR DS:[5D7BAF4] 
05A669AB    8B0D 04BBD705           MOV ECX,DWORD PTR DS:[5D7BB04] 
05A669B1    03C1                    ADD EAX,ECX 
05A669B3    0305 ECBAD705           ADD EAX,DWORD PTR DS:[5D7BAEC] 
05A669B9    5E                      POP ESI                                      ; kernel32.7C816FD7 
05A669BA    C9                      LEAVE 
05A669BB    C2 0400                 RETN 4 

So correct patch is:

009BFF40    A1 F4BAD705             MOV EAX,DWORD PTR DS:[5D7BAF4] 
009BFF45    8B0D 04BBD705           MOV ECX,DWORD PTR DS:[5D7BB04] 
009BFF4B    03C1                    ADD EAX,ECX 
009BFF4D    0305 ECBAD705           ADD EAX,DWORD PTR DS:[5D7BAEC] 
009BFF53    C2 0400                 RETN 4 

And eventually final one is

05A61B32    FF15 5046EA05           CALL DWORD PTR DS:[5EA4650]                 ; b.05A669C0 
 05A669C0    8B15 74BAD705           MOV EDX,DWORD PTR DS:[5D7BA74]              ; ADVAPI32.77DC0000 
 05A669C6    66:813A 4D5A            CMP WORD PTR DS:[EDX],5A4D 
 05A669CB    75 0C                   JNZ SHORT b.05A669D9 
 05A669CD    A1 78BAD705             MOV EAX,DWORD PTR DS:[5D7BA78] 
 05A669D2    66:8138 4D5A            CMP WORD PTR DS:[EAX],5A4D 
 05A669D7    74 04                   JE SHORT b.05A669DD 
 05A669D9    33C0                    XOR EAX,EAX 
 05A669DB    EB 38                   JMP SHORT b.05A66A15 
 05A669DD    8B48 3C                 MOV ECX,DWORD PTR DS:[EAX+3C] 
 05A669E0    03C8                    ADD ECX,EAX 
 05A669E2    8B42 3C                 MOV EAX,DWORD PTR DS:[EDX+3C] 
 05A669E5    03D0                    ADD EDX,EAX 
 05A669E7    8B42 58                 MOV EAX,DWORD PTR DS:[EDX+58] 
 05A669EA    0B42 28                 OR EAX,DWORD PTR DS:[EDX+28] 
 05A669ED    56                      PUSH ESI 
 05A669EE    0B42 08                 OR EAX,DWORD PTR DS:[EDX+8] 
 05A669F1    8B71 58                 MOV ESI,DWORD PTR DS:[ECX+58] 
 05A669F4    0B71 28                 OR ESI,DWORD PTR DS:[ECX+28] 
 05A669F7    0B71 08                 OR ESI,DWORD PTR DS:[ECX+8] 
 05A669FA    03C6                    ADD EAX,ESI 
 05A669FC    0FB772 42               MOVZX ESI,WORD PTR DS:[EDX+42] 
 05A66A00    0FB752 40               MOVZX EDX,WORD PTR DS:[EDX+40] 
 05A66A04    03C6                    ADD EAX,ESI 
 05A66A06    03C2                    ADD EAX,EDX                                 ; ntdll.KiFastSystemCallRet 05A66A08    0FB751 42               MOVZX EDX,WORD PTR DS:[ECX+42] 
 05A66A0C    0FB749 40               MOVZX ECX,WORD PTR DS:[ECX+40] 
 05A66A10    03C2                    ADD EAX,EDX                                 ; ntdll.KiFastSystemCallRet 
 05A66A12    03C1                    ADD EAX,ECX 
 05A66A14    5E                      POP ESI                                     ; kernel32.7C816FD7 
 05A66A15    C2 0400                 RETN 4 

What it does? Nicely calculates CRC of advapi32.dll, with different dll model, language all will likely be mistaken. So, the correct patch will likely be simply to return the worth of EAXx, simply earlier than returning. For me it’s:

009BFF56    B8 E0F7CB85             MOV EAX,85CBF7E0 
009BFF5B    C2 0400                 RETN 4 

Now remaining transfer is replace handle desk of antidumps to our patches so at 5EA4634 we are going to binary paste:

00 FF 9B 00 0C FF 9B 00 18 FF 9B 00 24 FF 9B 00 2C FF 9B 00 00 69 A6 05 40 FF 9B 00 56 FF 9B 00 

It’s higher to not contact addresses and opcodes due securom additionally makes use of these as encryption, when it calculates some worth in EAX or different register it likes to do ROL with worth of some reminiscence.

For instance from

05A61B32    FF15 
5046EA05           CALL DWORD PTR DS:[5EA4650]   

it could actually do:

ROL EAX,[05A61B34] 

so it does ROL EAX, 50 after we change handle in that decision then encryption is screwed.

It’s like a mine area or small CRCs, you could actually be careful what you modify even with CRCchecks mounted.

Subsequent step is:

05ADC7D5    E8 18440000             CALL a.05AE0BF2 
05ADC7DA    8B48 14                 MOV ECX,DWORD PTR DS:[EAX+14] 
05ADC7DD    69C9 FD430300           IMUL ECX,ECX,343FD 
05ADC7E3    81C1 C39E2600           ADD ECX,269EC3 
05ADC7E9    8948 14                 MOV DWORD PTR DS:[EAX+14],ECX 

And inside 5AE0BF2 we now have:

05AE0BF2    53                      PUSH EBX 
05AE0BF3    56                      PUSH ESI 
05AE0BF4    FF15 D8990306           CALL DWORD PTR DS:[60399D8]                 ; ntdll.RtlGetLastWin32Error 
05AE0BFA    FF35 7473F405           PUSH DWORD PTR DS:[5F47374] 
05AE0C00    8BD8                    MOV EBX,EAX 
05AE0C02    FF15 2CC3D705           CALL DWORD PTR DS:[5D7C32C]                 ; kernel32.TlsGetValue 
05AE0C08    8BF0                    MOV ESI,EAX 
05AE0C0A    85F6                    TEST ESI,ESI 
05AE0C0C    75 49                   JNZ SHORT b.05AE0C57 
05AE0C0E    68 8C000000             PUSH 8C 05AE0C13    6A 01                   PUSH 1 
05AE0C15    E8 E7D0FFFF             CALL b.05ADDD01 
05AE0C1A    8BF0                    MOV ESI,EAX 
05AE0C1C    85F6                    TEST ESI,ESI 
05AE0C1E    59                      POP ECX                                     ; kernel32.7C816FD7 
05AE0C1F    59                      POP ECX                                     ; kernel32.7C816FD7 
05AE0C20    74 2D                   JE SHORT b.05AE0C4F 
05AE0C22    56                      PUSH ESI 
05AE0C23    FF35 7473F405           PUSH DWORD PTR DS:[5F47374]
05AE0C29    FF15 30C3D705           CALL DWORD PTR DS:[5D7C330]                 ; kernel32.TlsSetValue 
05AE0C2F    85C0                    TEST EAX,EAX 
05AE0C31    74 1C                   JE SHORT b.05AE0C4F 
05AE0C33    C746 54 2877F405        MOV DWORD PTR DS:[ESI+54],b.05F47728 
05AE0C3A    C746 14 01000000        MOV DWORD PTR DS:[ESI+14],1 
05AE0C41    FF15 BC9A0306           CALL DWORD PTR DS:[6039ABC]                 ; kernel32.GetCurrentThreadId 
05AE0C47    834E 04 FF              OR DWORD PTR DS:[ESI+4],FFFFFFFF 
05AE0C4B    8906                    MOV DWORD PTR DS:[ESI],EAX 
05AE0C4D    EB 08                   JMP SHORT b.05AE0C57
05AE0C4F    6A 10                   PUSH 10 
05AE0C51    E8 0DCAFFFF             CALL b.05ADD663 
05AE0C56    59                      POP ECX                                          ; kernel32.7C816FD7 
05AE0C57    53                      PUSH EBX 
05AE0C58    FF15 209B0306           CALL DWORD PTR DS:[6039B20]                ; ntdll.RtlSetLastWin32Error 
05AE0C5E    8BC6                    MOV EAX,ESI 05AE0C60    5E                      POP ESI                                          ; kernel32.7C816FD7 
05AE0C61    5B                      POP EBX                                          ; kernel32.7C816FD7 
05AE0C62    C3                      RETN 

In order I mentioned we should return 1, assemble simply there a MOV EAX,1 and RET and all is ok.

Now you can ask why not change name to 05AE0BF2 into MOV EAX,1 it’s additionally 5 bytes? Nicely, as a result of I wager that E8 from name is used as ROL in some place. I’ve already seen that in older securom once I tried to repair E8 name that results in some winapi to level to my IAT desk leap.

Nicely its not over but with RtlGetLastWin32Error! Why?

Lets take a look at:

05ADC7DA    8B48 14                 MOV ECX,DWORD PTR DS:[EAX+14] 
05ADC7E9    8948 14                 MOV DWORD PTR DS:[EAX+14],ECX 

After we return 1 and add 14 then we now have 15 (lol I’m so good at math :P, however I nonetheless don’t understand how a lot is 2*2 :P) and when these two execute then we get web page fault 🙁 So solely attainable means is to NOP these two and all is ok.

Subsequent step is:

05BB8F15    E8 2CB0C7FF             CALL a.05833F46 
05BB8F1A    83FE 04                 CMP ESI,4 
05BB8F1D    7C 05                   JL SHORT a.05BB8F24 

And 5833F46 after many directions results in:

05833FA6    68 EC55FD05             PUSH b.05FD55EC                             ; ASCII "GetSystemInfo" 05833FAB    68 1454FD05             PUSH b.05FD5414                             ; ASCII "KERNEL32.dll" 
05833FB0    FF15 A09A0306           CALL DWORD PTR DS:[6039AA0]                 ; kernel32.GetModuleHandleA 
05833FB6    50                      PUSH EAX 
05833FB7    FF15 5C9A0306           CALL DWORD PTR DS:[6039A5C]                 ; b.05813282 
05833FBD    A3 E066D505             MOV DWORD PTR DS:[5D566E0],EAX 
05833FC2    EB 05                   JMP SHORT b.05833FC9 

With GetProcAddress and name so solely attainable resolution is to repeat these 20 bytes, paste them at 9BFF7A, change that decision to level into our patch and it appears to be like prefer it:

009BFF5E    E8 00000000             CALL b.009BFF63 
009BFF63    5E                      POP ESI                                     ; kernel32.7C816FD7 
009BFF64    83C6 19                 ADD ESI,19 
009BFF67    57                      PUSH EDI                                    ; ntdll.7C910738 
009BFF68    8B7C24 08               MOV EDI,DWORD PTR SS:[ESP+8] 
009BFF6C    B9 24000000             MOV ECX,24 
009BFF71    F3:A4                   REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI] 009BFF73    BE 10000000             MOV ESI,10 
009BFF78    5F                      POP EDI                                     ; kernel32.7C816FD7 
009BFF79    C2 0400                 RETN 4 

And eventually once more at

05BBD15E    FF15 A49A0306           CALL DWORD PTR DS:[6039AA4] 

This one may be changed with

MOV EAX, 75C    ;my PID

And we’re virtually dwelling. If you now run exe it would work, however solely in your machine, however objective is to make it run on every other.

Now after we patched all antidump apis run this script: Securom 7.x Leap Bridge & Crypted Code Fixer.txt (included into goodies folder).

Do you see it? And the place it goes?


What right here script does it would set HWBP on write into that DWORD when securom will replace it with new handle. That’s the way it appears to be like now:


Nicely after write it appears to be like prefer it:

And vacation spot appears to be like prefer it:

Nicely at this level we may end and go to subsequent leap bridge, however as you’ll be able to see I’ve in script now HWBP on execute. It’s not wanted right here, simply to make loop common for crypted code, as an alternative of code splicing or virtualized code by securom it could actually result in crypted code. That we should execute on our machine to decrypt it, due inside there may be crypted CPUID test and won’t uncrypt on different CPU simply crash. So let analyze one other leap bridge:

004DDD50  - FF25 54E40606           JMP DWORD PTR DS:[606E454]                  ; b.06073A10 

That leads us to:


You see that decision? Its name to decrypted code at and after handle of that decision, so after execute and HWBP on execute on 4DDD50 we get:

Good uncrypted code that can keep similar after we once more dump and run on every other machine, due no extra checks there. Run complete script to achive that. Once more 54890ms (solely asm could make it quicker)

And now final half to repair is CPUID checks that may be in spliced code.


Run Securom 7.x Cpuid Fixer.txt to repair all these (included into the goodies folder of this tutorials authentic package deal):


What script does is to seek for CPUID and checks if there may be an instruction like “and eax,FFFFFFDF”, simply after the CPUID additionally there may be EB leap to “and eax,FFFFFFDF”, so we should additionally deal with it. Easiest technique to repair it’s to interchange “and eax,FFFFFFDF” with a “mov eax,6D6” that’s my CPUID after and’ing. Script will get your CPUID routinely so that you don’t want to switch it.

  1. Conclusions

Lastly we’re at finish and might now dump and once more repair IAT with Winhex. It ought to run now on any laptop we like. After all you’ll be able to dump simply as soon as at finish, however I did this few occasions due its higher for me to jot down this tut and get photos of code so I may paste them right here. I hope you loved it and realized one thing.

Greatest regards to: all scene competitors, all those that make scene alive, ARTeam, exetools, SND and unpack dot cn.


SecuROM for the Plenty by deroko

1. Forewords

SecuROM is a well-known safety utilized by many video games these days. Humorous factor is that it’s cracking doesn’t take an excessive amount of time, solely takes time if you find yourself doing it for the primary time, after that it goes flowless. There aren’t tutorials about SecuROM within the public so far as I’m conscious. First tutorial which offers with SecuROM 7.xx was submitted to ARTeam by AnonymouS writer, so I feel we should always write extra about it, only for enjoyable…

2. Instruments and Goal

Goal that we’ll be utilizing is Command & Conquer : Tiberium Wars v1.0, so you will have to get that DVD to comply with this tut.

Archive Word: The tactic of inspecting the ASS is identical right here as for different SecuROM 7.xx video games.

Nicely any SecuROM will work as strategy is kinda generic.


  • SoftICE
  • Olly just for kewl screenshots…
  • IDA
  • Asm/C compiler

Additionally just be sure you have authentic DVD as sport builders deserve cash for his or her work…

To run this sport you’ll have to copy cnc3game.dat from RetailExe1.0 to folder the place is situated cnc3.exe and easily kind:

cnc3game.dat –win –config  CNC3_english_1.0.SkuDef 

-win is for windowed mode

After all, you don’t have to do that if you are unpacking safety, it is just required if you find yourself testing your dump, in any other case you’ll get this message for those who run dump with out that command line:


Related output you’ll get when your dumped file is began with out correct command line.

3. Few phrases about SecuROM

SecuROM safety consists of 1 .exe hooked up to authentic .exe. In case you hint somewhat bit trough SecuROM layer you will notice 2nd exe being appended, even requirements MSVC initialization routine are held on this higher layer. If you need you might dump at this layer and analyze securom safety, however that isn’t essential for us atm.

SecuROM makes use of plenty of buffers to make itself anti-dump that are at all times allotted on completely different base addresses which leads us to easy conclusion that some type of random generator is used to allocate these buffers. Additionally SecuROM makes use of a number of anti-dump methods corresponding to GetCurrentProcessId, OpenEventA/CloseHandle, ResetEvent, TlsSet/GetValue, entrypoint handle, imagesize from PE header and so on… which we will patch after all.

It allocates a plenty of buffers to execute its code and when dumped these buffers take ~40mb. Fortunately when compressed they take round 1MB or much less, as all redirections are allotted at 64K boundary however solely 1KB is commited. That is results of calling VirtualAlloc a plenty of occasions (strive making infinite loop with VirtualAlloc and watch what occurs). Thus 64K-1K is padded with zeros in your dump and giving actually actually good compression ratio. Only for comparability, I’ve dump of 70MB compressed again to 7MB, properly, virtually like virgin file  Nicely I’ll additionally focus on about making this dump smaller : virgin + ~20mb.

Earlier than we even suppose to fireplace up SoftICE with SecuROM safety we now have to cover it correctly, properly, my softice is hidden it this manner:

- NtCreateFile - Int1/int3/int41 patched - NtQuerySystemInformation - UnhandledExceptionFilter 

Another means stays to detect SoftICE and that’s to question it’s service and test whether it is lively, for this I exploit hook of OpenServiceA to remove NTICE service opening. This hook code and different stuff used to log SecuROM execution could also be present in hookdll.c. Additionally SoftICE exercise may be detected with EnumServicesStatusExA which is utilized by ActiveMARK however that’s one other story.

4. Dumping SecuROM

There are just a few methods to dump SecuROM on the OEP:

  • Use methodology described by nameless writer [see first chapter of this document]
  • Discover vm_exit, hook it, and wait when it jumps again to 1st part
  • Hook generally used APIs at MSVC oep and watch when these are known as from 1st part
  • Simply dump .exe, load it in IDA, and apply MSVC signatures, then seek for OEP
  • Use PAGE_GUARD to search out when code part jmp to oep

Nicely there are a number of methods as you might even see, however it’s upto you to search out methodology which inserts your wants the perfect.

OEP on this goal is situated at: 0x40A1B3

.textual content:0040A1B3                 name    ___security_init_cookie .textual content:0040A1B8                 jmp     ___tmainCRTStartup 

.textual content:00409EF2 ___tmainCRTStartup: .textual content:00409EF2                 push    58h 
.textual content:00409EF4                 push    offset unk_B95678 
.textual content:00409EF9                 name    sub_40A250 
.textual content:00409EFE                 xor     ebx, ebx 
.textual content:00409F00                 mov     [ebp-1Ch], ebx 
.textual content:00409F03                 mov     [ebp-4], ebx 
.textual content:00409F06                 lea     eax, [ebp-68h] 
.textual content:00409F09                 push    eax 
.textual content:00409F0A                 name    ds:GetStartupInfoA 
.textual content:00409F10                 mov     dword ptr [ebp-4], 0FFFFFFFEh 
.textual content:00409F17                 mov     dword ptr [ebp-4], 1 
.textual content:00409F1E                 mov     eax, massive fs:18h 
.textual content:00409F24                 mov     esi, [eax+4] 
.textual content:00409F27                 mov     edi, offset unk_C5DD54 

When dumping SecuROM you must know that it’s PE header in reminiscence is definitely PE header of a virgin file (besides AddressOfEntryPoint is foobared and used as anti-dump on a number of locations).

As we all know this reality we could write dumper for SecuROM and dump virgin file to the disk. You may even see sromd.asm for detailed code (nothing particular simply learn PE header from reminiscence and dump picture to disk + add further part for SecuROM sections).

SecuROM makes use of jmp to execute some stolen procedures that are combined with SecuROM code. To search out such process you gained’t have to go looking a lot, first name in OEP leads us to SecuROM code:


This jmp solely first time will take you to SecuROM digital buffers:


In case you hold traceing trough it you’ll ultimately find yourself right here:


Now look, it would take you to stolen and combined process right here:


You may even see how this process is combined with addresses from .securom part, and a few jccs are resulting in that part. If we take one step again and look once more on the jmp from which we now have began to hint, we might even see that SecuROM wrote to jmp dword ptr[] appropriate handle:


Word handle in 2nd column, it’s similar as handle of stolen process. There are no less than 2 the reason why that is executed in such means:

  1. Quite a few execution of similar process would decelerate sport execution
  2. Make code anti-dump as you might not merely dump it with out fixing these jmps

These jmp dword ptr[] may be simply discovered by utilizing byte search, thus, you’ll both have to jot down your personal instrument, or use olly scripts to do the job for you. Earlier than we even dump file, we now have to repair these jmps, and for that I exploit srom_logger.exe and vmtrace.dll.

Srom_logger.exe may be very easy search engine which searches for jmp dword ptr[] and checks if they’re main us to .securom part. If such jmp is discovered, loader is injected into distant course of which will likely be answerable for loading vmtrace.dll and calling it’s export vmtrace!tracer.

Let’s analyze these codes somewhat bit so you might understand how and why I’m doing what:

loader:                                          name    __delta __delta:                pop     ebp                         sub     ebp, offset __delta                         

                    x_push  ecx, <vmtrace.dll~>                         name    [ebp+loadlibrarya], esp                         x_pop                                                  x_push  ecx, <tracer~>                         name    [ebp+getprocaddress], eax, esp                         x_pop                                                        push    0deadc0deh trace_addr              =       $-4                         name    eax                         mov     [ebp+redirection], eax                         name    [ebp+exitthread], 0 

loadlibrarya            dd      ? getprocaddress          dd      ? exitthread              dd      ? redirection             dd      ? size_loader             =       $-loader 

tracer export from vmtrace.dll may be very easy and it’s job is to set HWBP on write at handle from jmp dword ptr[]:

tracer                  proc                         arg     trace_address                         pusha                         mov     eax, trace_address                         mov     global_trace_address, eax                                                  xor     eax, eax                         push    offset setdr0                         push    dword ptr fs:[eax]                         mov     dword ptr fs:[eax], esp                         mov     eax, [eax]                         pop     dword ptr fs:[eax]                         add     esp, 4                                                                         name    hook_kiuser                         mov     save_esp, esp                         mov     eax, trace_address                         jmp     [eax]                          __baby:                 name    unhook_kiuser                         mov     eax, vacation spot                                                  mov     [esp.Pushad_eax], eax                         popa                         go away                       retn    4 

Additionally you might even see in vmtrace.asm code answerable for hooking KiUserExceptionDispatcher, which is able to carry out stealth tracing from context of our goal.

Now merely execute that handle and we’re going to nonintrusive tracer:

kiuser_hook:            mov     ecx, [esp+4]                         mov     ebx, [esp]                         pusha                         cmp     dword ptr[ebx], EXCEPTION_SINGLE_STEP                         je      __checkdrx                                      xor     eax, eax                         mov     [ecx.context_dr6], eax                         mov     [ecx.context_dr0], eax                         mov     [ecx.context_dr1], eax                         mov     vacation spot, eax                         mov     [ecx.context_eip], offset __baby                         mov     eax, save_esp                         mov     [ecx.context_esp], eax                         jmp     __allgood                          __checkdrx:             check    [ecx.context_dr6], 4000h        ;single steping...                         jnz     __goback                                                 check    [ecx.context_dr6], 1                                                     jnz     __write                                       check    [ecx.context_dr6], 2                         jz      __goback        ;dr1 hit...                         xor     eax, eax                         mov     [ecx.context_dr6], eax                         mov     [ecx.context_dr0], eax                         mov     [ecx.context_dr1], eax                         mov     eax, save_esp                         mov     [ecx.context_esp], eax                         mov     eax, offset __baby                         xchg    [ecx.context_eip], eax                         mov     vacation spot, eax                         jmp     __allgood                        

                    ;dr0 hit... __write:                mov     esi, ecx                         name    ReadProcessMemory, -1, global_trace_address, o vacation spot, 4, 0                         name    ReadProcessMemory, -1, vacation spot, o old_data, 4, 0                         check    eax, eax                         jz      __goback                                                                                          mov     eax, vacation spot                         mov     [esi.context_dr1], eax                         or      [esi.context_dr7], 4                                     __allgood:              popa                         name    NtContinue, ecx, 1                         nop                         nop 

__goback:               popa                         jmp     old_kiuser 

You’ll most likely marvel why I’m utilizing ReadProcessMemory to learn handle from my very own course of. Nicely trick is easy, as I used HWBP on r/w every learn from r3 would trigger HWBP to generate exception, even if you find yourself studying from exception handler, now as code is rewritten to make use of HWBP on write this isn’t wanted anymore. Additionally you might even see that I’m setting HWBP on execution on remaining vacation spot. That is executed to keep away from mistaken identification of vacation spot when SecuROM writes 2 occasions to this handle. Every time write there happens we take that handle and HWBP on execution on that handle. When dr1 is hit (execution HWBP) we all know we now have good pointer, and we log it.

Additionally it would happen that procedures are in digital reminiscence so we dump that too to the disk which is able to permit us to repair them simply. Additionally srom_logger.asm will produce log file which is able to look one thing like this:

redirection at 0x00401023 to 0x013D34C3 
redirection at 0x00401098 to 0x013F11F8 
redirection at 0x004010C5 to 0x013F66A5 
redirection at 0x00401103 to 0x00434D33 
redirection at 0x00401141 to 0x0044D2F1 
redirection at 0x0040116F to 0x013EA3CF 
redirection at 0x004011AD to 0x013F2BBD 

There’s 2957 these jmps so we have to automate strategy of fixing. Additionally areas with procedures are dumped to the disk for later fixing (once more in one other instrument named sfixer.asm). Word that after you run srom_logger.asm you’ll have mounted jmp dword ptr[] in your goal in reminiscence so that is the purpose whenever you dump it to the disk with mounted jmps.

Right here is an instance of 1 stolen process saved someplace in digital reminiscence:

seg000:03A5000B                 push    esi 
seg000:03A5000C                 mov     esi, [esp+8] 
seg000:03A50010                 jmp     brief loc_3A5002A 
seg000:03A50012 loc_3A50012: 
seg000:03A50012                 mov     ecx, esi 
seg000:03A50014                 push    offset loc_3A50027 
seg000:03A50019                 push    7FE20Fh 
seg000:03A5001E                 retn 
seg000:03A5001F                 dd 0DF8A7B4Ah 
seg000:03A50023                 dd 0E5B9FAh 
seg000:03A50027 loc_3A50027: 
seg000:03A50027                 add     esi, 10h 
seg000:03A5002A loc_3A5002A: seg000:03A5002A                 cmp     esi, [esp+0Ch] 
seg000:03A5002E                 jnz     brief loc_3A50012 
seg000:03A50030                 pop     esi 
seg000:03A50031                 retn 

You’ll be able to’t put it again to its authentic place as SecuROM makes use of that area in code part for different anti-dump methods.

We’re virtually near dumping this goal.

Subsequent factor we should always know is the place are all digital buffers that we now have to dump and append. For this objective I exploit hookdll.c which can be utilized with my Final Hooking Engine [1]. Additionally it is suggested to make use of hook of rdtsc to keep away from randomness in reminiscence allocation.

Oki, inject hookdll.dll into goal by typing: hook cnc3game.dat, and after just a few seconds you’ll be greeted with MessageBoxA much like this one on the image:


Write down these reminiscence addresses, and press okay. Your goal will likely be within the infinite loop in hook of GetTickCount. Don’t connect Olly but!!! Run srom_logger.exe and you’ll get output much like this one :


Oki doki, we now have produced 0xXXXXXXXX.dmp information and splices.bin + we now have mounted jmp dword ptr[] in protected program. Now you might connect olly, or just ctrl+d in case you are utilizing SoftICE and you’ll be right here:


What I’ve executed right here is to test for return handle in GetTickCount, and whether it is known as from sure location I put goal into infinite loop, this giving me chance to at all times break at OEP quick. It is best to nop out this jmp $ however do NOT run goal but, as you will have to get additionally TlsValue with index 0xF which is used as antidump at one level. Merely assemble this code:

See Also


The rationale why I’m doing this at this second is to save lots of you a while, you would simply determine this factor afterward, after which you’ll have to dump another time. Not letting you already know at this level about this trick could be imply. Additionally you must write down PID of this course of!!!!

Now, you might even see that in PE header there may be legitimate virgin header, so you might dump it like that. I exploit my dumper for SecuROM which dumps that pe header from reminiscence and picture because it was earlier than packing, and appends to it different reminiscence occupied by SecuROM.

After operating sromd.asm you’ll have dumped_securom.exe which is able to appear like this:


To date so good. You wrote down addresses displayed in MessageBoxA? If not go another time.

Now take a more in-depth take a look at spliced information dumped by srom_logger.exe:

Splices begin:


Splices finish:


By splices we might even see that these are allotted on 0x10000 boundary, however there may be one small hole between all these splices situated right here:


Look nearer and you will notice that we’re lacking reminiscence area between 45D0000 and 4960000. So we must dump that area too.

To date we now have 2 areas which must be dumped:

1480000 – 37F0000 and 45D0000 – 4960000, dump them, and use CFF explorer by Daniel Pistelli so as to add these areas to dumped_securom.exe. For me it appears to be like like this:


Another factor left to go over, and that’s so as to add splices, with sfixer.exe . Earlier than you run sfixer.exe it’s best to save splices.bin to, for instance, splices_save.bin as sfixer.exe will modify this file, and if one thing goes mistaken you gained’t have this file, additionally it’s best to know that sfixer.exe assumes that you’re fixing file “remaining.exe” so copy up to date dumped_securom.exe to “remaining.exe”. Word additionally that this step is NOT required,

you would simply dump reminiscence from heap1 to highmem from MessageBoxA however your dump could be + ~20mb. On this means, with splices fixing we’re lowering dump dimension + we’re making nicer dump.

After operating sfixer.asm we could test a few of our digital reminiscence redirections from log_redirection.exe (produced by srom_logger.asm):

redirection at 0x00410BC1 to 0x03B20001   <--- from log_redirections.txt 


And glued splice:


I’ll additionally present you two splices which weren’t mounted by my instrument accurately, and which I’ve mounted by hand (from protected sport in reminiscence):

From my dump:


And when mounted by hand it ought to appear like:


And second splice:

And when mounted:


As you might even see on this image, splice is mounted, however earlier than fixing this name was inflicting crash as complete splice was rebased to the brand new handle.

Theoretically talking sfixer.asm may be rewritten to comply with execution circulation and rebuild these procedures in higher means. We might even see 3 patterns used as name:

push   <ret_splice_address> push   <proc_address> ret 

push   <ret_splice_address> jmp    __proc_address 

push   <ret_splice_address> push   dword ptr[API_pointer_from_IAT> ret 

And those are only patterns which are fixed by sfixer.asm, of course, better engine could be written, but, this is good enough 

Voila, dumping is done now. All we have to do is to get rid of anti-dump tricks present in the SecuROM, and we will have dumped and fixed game.

5. Anti-Dump fixing

This is part where your head might start hurting a little bit, so my advice is to grab pen and paper and write your observation. Well at least that’s how I do with all protectors.

First anti-dump that you will see is when you enter into SecuROM vm interpreter. I don’t want to trouble you mutch so here is address to be hit first:

.bla:00CBEC00 sub_CBEC00      proc near                
.bla:00CBEC00                 jmp     ds:dword_125D9EC 
.bla:00CBEC00 sub_CBEC00      endp 

Depending on your dump address to which this jmp is leading could be different, but for me it is at 3320000:

seg000:03320345                 mov     eax, large fs:18h 
seg000:0332034B                 inc     ebp 
seg000:0332034C                 db      3Eh 
seg000:0332034C                 mov     eax, [eax+30h] 
seg000:03320350                 db      3Eh 
seg000:03320350                 mov     eax, [eax+8] 
seg000:03320354                 db      3Eh 
seg000:03320354                 mov     edx, [eax+3Ch] 
seg000:03320358                 dec     ebp 
seg000:0332035A                 db      3Eh 
seg000:0332035A                   mov     edx, [edx+eax+50h] 

Right here it takes OptionalHeader.SizeOfImage for those who dump your goal it would have completely different picture dimension from the one which SecuROM expects to be there. So you’ll have to repair it, it’s, 87A000, properly merely dump goal from reminiscence with LordPE and you will notice appropriate values.

Okay it’s essential to patch it… merely patch mov edx, [edx+eax+50h] with mod edx, 87A000, and first anti-dump is defeated. Subsequent anti dump is CPUID trick  which makes dump solely CPU particular eg. It gained’t work on different CPUs for those who don’t repair it:

seg000:03320305                 mov     eax, 1 
seg000:0332030A                 push    ebx 
seg000:0332030B                 add     ebp, eax 
seg000:0332030D                 cpuid 
seg000:0332030F                   and     eax, 0FFFFFFDFh 

That is comparatively easy to repair, what you’ll do is to go looking trough dumped vm areas for sure byte patern: mov eax. 1. If you discover it, now use lde to test if cpuid is current in subsequent 5 directions, for those who discover jmp __ comply with it. If you discover cpuid you already know what to repair. Use once more lde from cpuid offset to search out and eax, 0FFFFFFDFh and patch it with mov eax, worth which is returned in your CPU.

This search’n’exchange is simple to jot down, so you might train somewhat bit.

There are 2 extra anti-dumps in VM interpreter. GetCurrentProcessId and OpenEventA/CloseHandle. Trick right here is to patch GetCurrentProcessId name to return PID of your dump, and OpenEventA/CloseHandle to return 1 for CloseHandle:

seg000:028400F1                 mov     edx, [edx] 
seg000:028400F3                 xor     edx, 0CC5C4764h 
seg000:028400F9                 name    edx  <-- GetCurrentProcessId 
seg000:028400FB                 and     ebp, edx 
seg000:028400FD                 mov     edx, eax 
seg000:028400FF                 sub     edx, ecx 
seg000:02840101                 btc     ebp, eax 
seg000:02840104                 pop     ecx 

So it ought to look one thing like this when patched:



seg000:028600DB                 mov     edx, [edx] 
seg000:028600DD                 xor     edx, 0BA6258DBh 
seg000:028600E3                 name    sub_286010A 
seg000:028600E8 a01a3ee67056205 db '01A3EE67056205C94339FAF75B158E1CD',0 
seg000:0286010A sub_286010A     proc close to                
seg000:0286010A                 btc     ebp, eax 
seg000:0286010D                 push    0 
seg000:02860112                 mov     ebp, 8A9FAD20h 
seg000:02860117                 push    2 
seg000:0286011C                 name    edx  <--- OpenEvent 
seg000:0286011E                 inc     ebp 
seg000:02860120                 push    eax 
seg000:02860121                 xadd    ebp, ebp 
seg000:02860124                 mov     edx, [ebx+28h] 
seg000:02860127                 add     edx, 14h 
seg000:0286012D                 xchg    ebp, ebp 
seg000:0286012F                 mov     edx, [edx] 
seg000:02860131                 xor     edx, 0AC86A5A7h 
seg000:02860137                 xor     ebp, 0C9C0E01Dh 
seg000:0286013D                 name    edx  <--- CloseHandle 

It is best to patch this half in a sensible means, first you must patch push 2/name edx with add esp, 8 to remove 2nd and third arguments handed to OpenEvent, now you’ll have to patch push eax (occasion deal with with nop) and xor edx, 0AC86A5A7h with mov eax,1 and nop name edx (CloseHandle).

Good, good, VM handlers are actually anti-dump patched.

Let’s proceed to a different anti-dump in code of SecuROM:


Hmmm what’s what right here? Lets begin by going to every considered one of them and seeing what’s going on:



That is GetCurrentProcessId test, which you’ll have to patch with mov eax, dump_pid



Test for OS model by way of GetVersion, so that you patch it with mov eax, version_of_your_os

third test:


Nicely just about self explanatory, patch it with worth which cpuid returns in your machine

4th test:


Patch this as mov eax, 1, and nop out name to ResetEvent

fifth test:


Hey, there may be my pc identify, good. So SecuROM right here checks for size of your pc identify. Test line 0xFA678F and a couple of strains after it’s set to 0x10, which is most dimension of buffer handed to GetComputerNameA. Then at line 0xFA67BE it takes size of pc identify returned by name to GetComputerName, so your patch right here could be to nop out EnterCriticalSection and LeaveCriticalSection, additionally nop out name to GetComputerNameA and nop passing arguments to it, and assemble there mov [12F5A2C], len_of_your_computer_name , and nop je at 0xFA67AB. Straightforward…

sixth test:


And buffer:


This buffer will merely return it’s handle, so above test it’s best to patch with: mov eax, 4650000

seventh test:


That’s my consumer identify over there: Weeeeeee. Nicely at line 0xFA6843 it takes 4 chars from identify and provides them to EAX, that is quite simple to patch so you are able to do it by yourself. Not a lot stuff occurring.

In easy phrases, for those who run dump as completely different consumer, it would crash in some unspecified time in the future.

And final and eighth test:


Quite simple anti-dump test, it masses handle of advapi32.dll in edx, and handle of kernel32.dll to eax, now it performs somewhat bit with PE header. After all on completely different home windows model kernel32.dll and advapi32.dll most likely can have completely different values there. It may occur that in MS updates these two, or no less than considered one of them is up to date, and in such PE will likely be screwed, and mistaken worth will likely be returned. One easy technique to bypass this anti-dump is to run this process and get worth returned in eax then simly patch this routine with mov eax, that_value/retn 4

Solely 2 extra anti-dumps left to go over, solely 2 extra.

Subsequent anti-dump is expounded to EntryPoint saved in PE header in reminiscence and is situated right here:


adc edi, [400150] is definitely including OptionalHeader.AddressOfEntryPoint to edi. Your dump can have completely different EntryPoint, however on this actual goal, SecuROM excepts it to be: 4d5b98h . I’ve situated no less than 1 extra test, however no have to search for all of them, it’s extra then sufficient so as to add further code to the dump which is able to overwrite OptionalHead.AddressOfEntryPoint with this worth, and in addition will replace OptionalHeader.SizeOfImage with worth which SecuROM needs in its VM interpreter, so we will likely be injection this code into SecuROM:

loader:                 pusha                         name    __delta __delta:                pop     ebp                         sub     ebp, offset __delta                                                  name    getkernelbase                         xchg    eax, ebx                         gethash <VirtualProtect>                         name    getprocaddress, ebx, hash                                                  push    esp                         mov     ecx, esp                         name    eax, 400000h, 1000h, PAGE_READWRITE, ecx                         add     esp, 4                                                  mov     esi, 400000h                         add     esi, [esi+3ch]                         mov     [esi.pe_addressofentrypoint], 4d5b98h                         mov     [esi.pe_sizeofimage], 87a000h 

                        mov     eax, [ebp+old_entry_point]                         mov     [esp.Pushad_eax], eax                         popa                       jmp     eax 

And now, do you keep in mind that TLS stuff I discussed earlier? Nicely right here it goes:


It calls TlsGetValue(0x0F), so you’ll have to patch it with worth you bought like this:


And so it has been executed, now run your dumped/patched exe, and you’ll have your sport up and operating.

That’s all of us…

6. Conclusion

Nicely as you might even see it’s comparatively easy to repair SecuROM, nonetheless, going for the virgin file could be good, but it surely requires extra free time as you’ll have to reverse SecuROM VM to repair it correctly.

7. References

[1] Final Hooking Engine, deroko of ARTeam,
(Hyperlink to Deroko’s Web page)

8. Greetings

I want to thank to all my mates in ARTeam for sharing their information, to 29a for among the best e-zines, crew (fly, shoooo, heXer, softworm, okododo), AnonymouS tut contributor, he know who he’s, and naturally, you for studying this doc.

С вером у Бога, deroko of ARTeam

Deep Inside SecuRom by AnonymouS

1. The humorous facet of issues

The authors of SecuRom cracks me up:


“Time to drink .securom”

And within the redirector proc:

“no one transfer, no one will get harm”
“Plenty Towards the Courses”

“yates remains to be thing kinda Ooooh”

“Are there no honor amongst thieves Mr. Yates ??”

2. Code morphing

This PUSH 10 and JMP look a bit unusual:


Comply with leap and you’ll find yourself right here:


As one can all this does is that it pushes a worth onto stack. Anyway, this isn’t vital to us. The dump works high quality with out patching this 😉

3. Primary API redirection

Right here is the place we first meet a redirection of a name to API:


Let’s hint into 05693644h


As one can see, that is really a name to GetProcAddress.

If we load our dump into LordPE and try the Listing Desk (ImportTable):

Operating via the ImportTable (kernel32.dll) we seen the next API’s will get redirected:

GetProcAddress (5670A38)
LoadLibraryA (5670A3C)
ExitProcess (5670AD8)
TerminateProcess (5670AE0)

We have to repair these API’s. One can do that both by hand or by utilizing ImpRec or ReVirgin. I desire nothing it routinely coding a unpacker !!!

4. Code splicing

The code splicing in SecuRom normally appears to be like like this:


As soon as we hint into 05EB4000h we are going to enter the great world of SecuRom redirection. I’ll spare you the heartbreak for going via all of the calculation loops, however what it mainly does is redirection you to the code splicing code. Anyway, right here is the start:


It would ultimately find yourself right here:

As one may see that is a part of the code splicing. Nonetheless we will repair this by forcing the leap at 095A859h to leap to 05E6EEE9h. Now right here is one thing attention-grabbing… Look above at line 05E6EF70h… What is that this ?? Let’s hint… A brand new chapter begins…

5. Superior API redirections

Like with the code splicing the superior API redirection is trigged by a run via the calculation loops. Most frequently round 10 occasions. No massive deal… After somewhat tracing we find yourself right here:


It is a name to GetStartupInfoA !!

As one can see it’s not superior in any respect. I solely selected to name it this due to the calculation/obfuscation loops.

Typically calls to API appears to be like similar to calls to a different SecuRom trick…. The Digital Machine (VM)… Let’s check out this characteristic…

6. Digital Machine



Archive Closing Notes

All supplies included right here may be discovered on the index.

(c) ARTeam, 2007/2008.
Reformatted for Archive use by LFATeam, 2018

Source Link

What's Your Reaction?
In Love
Not Sure
View Comments (0)

Leave a Reply

Your email address will not be published.

2022 Blinking Robots.
WordPress by Doejo

Scroll To Top