Breaking SecuROM 7 – A Dissection
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.
Foreword
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,
Shub
Disclaimers
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)
- Forewords (3)
- Settings and Goal (3)
2.1. Goal (3)
2.2. Instrument Used (3) - Defeating the mysterious debug-detection (4)
- Reaching OEP (5)
- Defeating the anti-dumping trick. (7)
- Conclusion (9)
- Last phrases and greetings (9)
Full Cracking SecuRom 7.xx by Human (10)
- Foreword and wanted instruments (10)
- First step: begin of journey (10)
- Second step: put together issues (10)
- Third Step: Load the sport into Olly and rebase (11)
- Fourth Step: daemons instruments and OEP (13)
- Fifth Step: Fixing Anti-dumps (17)
- Sixth Step: fixing the CRCChecks (18)
- Seventh Step: taking good care of antidumps (20)
- Conclusions (34)
SecuROM for the lots by deroko (35)
- Forewords (35)
- Instruments and Goal (35)
- Few phrases about SecuROM (36)
- Dumping SecuROM (37)
- Anti-Dump fixing (48)
- Conclusion (55)
- References (55)
- Greetings (55)
Nicely deep Inside SecuRom by AnonymouS (56)
- The humorous facet of issues (56)
- Code morphing (56)
- Primary API redirection (57)
- Code splicing (58)
- Superior API redirections (59)
- 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 (http://forums.accessroot.com/index.php?showtopic=4361&st=0) 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
0577FAA2 8B40 0C MOV EAX,DWORD PTR DS:[EAX+C] <-- PPEB_LDR_DATA
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
-
Lets load maxi picture into daemon instruments 4.10
-
Run Yasu to cloak digital drives
Archiver’s Word: Don’t hassle utilizing YASU, simply use SecuROM Loader 1.2.
-
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. -
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.
- 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.
Subsequent
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?
Subsequent
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
Subsequent
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
Subsequent
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
Subsequent
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.
- 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.
Human/MiNT
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.
Instruments:
- 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:
- Quite a few execution of similar process would decelerate sport execution
- 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
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
seg000:03A50027 loc_3A50027:
seg000:03A50027 add esi, 10h
seg000:03A5002A
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:
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:
OpenEventA/CloseHandle:
seg000:028600DB mov edx, [edx]
seg000:028600DD xor edx, 0BA6258DBh
seg000:028600E3 name sub_286010A
seg000:028600E8 a01a3ee67056205 db '01A3EE67056205C94339FAF75B158E1CD',0
seg000:0286010A
seg000:0286010A sub_286010A proc close to
seg000:0286010A
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:
1st:
That is GetCurrentProcessId test, which you’ll have to patch with mov eax, dump_pid
2nd:
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, unpack.cn 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 ere.one 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