Log in

View Full Version : SecuROM 7 SMC/obfuscation cleaner


doug
August 24th, 2005, 20:38
I found this laying on my hdd doing nothing, so I made a small update & decided to share it here.
===============
Readme:

In v5 and v7, SecuROM incorporates a sofisticated code obfuscator engine. It
is better than any obfuscation I have seen elsewhere, so the simple pattern
matching of macros do not work very well (at all).

This tool cleans code that was protected/obfuscated with SecuROM's
code obfuscator. While this tool handles a LOT of things, it is not perfect,
so don't expect to be able to run files that were cleaned with it. The purpose
of this tool is to simplify a reverse-engineering/security analysis
of those binaries.

Full source code is included (GPL for the files with my name in the header).

This tool only supports PE images. Since starting with some version,
the securom .text section is compressed, just use LordPE to dump the
entire process (dump full) to disk at the point where the .init section
jumps (via a RET) to the real securom entrypoint in .text.


Usage
------
Just run the srom7_cleaner.exe and specify the file that you which to clean.

Recommended:
* Redirect the output to a text file. The log can get up to 7 MB large.
Use the included .bat file for that purpose.

* First just scan .init to analyze the decompression code. Then dump
the process when .text (securom's) is unpacked.

* When the process is dumped, you may clean both .text & .init.

* Load in IDA and enjoy ;-).


Known issues:
------------
* The CMP pattern is known to produce a lot of collisions/errors, so I
just commented out the line in the source code. The handler needs a
little rework before I feel that I can enable it again.


===============

Sample Report from log:

=================================================
== Scan Report ==
=================================================
Jmp : Fixed: 6803, Failed: 0
AddEsp : Fixed: 4985, Failed: 0
AddEsp s : Fixed: 667, Failed: 0
SubEsp : Fixed: 602, Failed: 0
AntiTrace : Fixed: 42106, Failed: 0
AddRegConst : Fixed: 15374, Failed: 4042
Slicer : Fixed: 4042, Failed: 0
Test reg/reg : Fixed: 1684, Failed: 0
Jcc 1a : Fixed: 12148, Failed: 0
Jcc 1b : Fixed: 58, Failed: 0
AddRegImm : Fixed: 1925, Failed: 0
Prolog : Fixed: 945, Failed: 0
Epilog : Fixed: 888, Failed: 0
StackRead : Fixed: 26350, Failed: 0
Call : Fixed: 6429, Failed: 0
MovRegImm32 : Fixed: 662, Failed: 0
MovRegDwordPtr : Fixed: 1043, Failed: 14
LeaRegDwordPtr : Fixed: 10107, Failed: 102
Push Offset1 : Fixed: 1224, Failed: 0
Push Offset2 : Fixed: 144, Failed: 0
MovRegImm32_2 : Fixed: 2, Failed: 0
PushReg : Fixed: 18914, Failed: 0
Ret : Fixed: 247, Failed: 0
PopReg : Fixed: 389, Failed: 0
MovRegImm32s : Fixed: 46, Failed: 0
=================================================
Total fixed: 157784
Total failed: 4158
Failure rate: 2.64%

Without AddRegConst acceptable errors:
Total failed: 116
Failure rate: 0.07%
=================================================



Enjoy!
doug

dELTA
August 26th, 2005, 18:59
Cool, nice work indeed.

Kayaker
August 26th, 2005, 21:22
Yeah, this definitely looks like a labor of love(/hate). I've been wanting to comment on it, but keep getting caught up trying to get a grasp of the details. As you mention in a header file, "The code here is pretty dense & hardcore to follow unless you have already played with a target EXE". I've been wanting to do exactly that because this looks like an excellent template/example for applying deobfuscation techniques. The pattern-scanning code itself is a useful example.

Kudos on an awfully nice piece of RE work once again doug.

Regards,
Kayaker

doug
August 27th, 2005, 18:02
Thanks. Yea, certainly love/hate. A lot of time went into this, but the joy that fills your heart when you see the code cleaned up, makes it worth it

I guess I should add that the .txt files contained in the "pattern" directory are all the obfuscation tricks that I've encountered. These provide a good help for the handler.cpp (which is the hardest to understand, I'm sure). One should first start with the simple patterns like "jmp_1", "add_esp", "epilog", and then move on to more complex ones - "slice", "add_reg_const", - which are sometimes nested inside other patterns (nasty) or *have* to be simulated/emulated because the code flow depends on CRC checks of other pieces of code.

I suppose I should have included a file description in the package:

ADE*: Instruction length engine by z0mbie

handlers: Where most of the handling is done, but no so useful for someone that is not interested in this protection. (And I'm not particularly proud of my coding style there ) This code is processing the signatures.

peImageHlp: This can be useful to some people, but I'm still programming it. Basically a library for commonly used PE functions - some provided by Windows through imagehlp - but also new ones, like adding sections & auto-resizing an image, etc... (BTW: imagehlp does NOT conform to the documentation on MSDN, particularly the LastError codes).

produceCode: just helper functions. Not much there.

sig_tracer: This is a pattern matcher that supports a byte pattern and a mask for it. I.e.: allows you to look for all instances of MOV REG, REG in 1 pattern instead of having 1 pattern for each register combination. Called from srom7_cleaner.cpp

srom7_cleaner: Defines all the patterns & masks. This code can most likely be re-used in other projects since all the modifications needed are data-related. i.e.: patterns[] = {
// FriendlyName, FUNCTION, SIGNATURE, SIG_SIZE, HAS_MASK, MASK, COUNTERS
The code there is independant of securom; it opens a PE file, and just scans for patterns. When a pattern is found, it calls the handler function as it was defined in the array.

Regards
doug

laola
August 31st, 2005, 11:44
Great work, indeed! Thanks for this fine piece of software
And the kewl ideas behind the code
BTW, I know who's responsible for the current developments in SR7 I have little doubt that he'll just whip out a completely changed strategy in no time. So you can look forward to more adventures in SR land

(And no, it's not me. This stuff is a bit beyond me, basically because I am too lazy to get a grip on that stuff

nikolatesla20
September 13th, 2005, 12:23
I've been trying to apply byte pattern regex's for a while that could do this sort of thing to detect OEP signatures.. but unfortunately things like the regex library you can get for free don't seem to support binary, only text ! *dang* Using a regular expression would be the best way for pattern matching...is this how this code works?

Anyway, thanks for the tools!

-nt20

doug
September 13th, 2005, 13:13
It isn't exactly using regular expressions - the pattern lengths are fixed to what they are defined - it doesn't support things like kleene stars.

let's say you were looking for INC REG. You would define the pattern as 0x40 and a mask of 0xF7. Bytes encountered will first be AND'ed with the mask (0xF7), and compared with the pattern (0x40). This recognizes all INC REG instructions.
(Note: Obviously, just 1 byte pattern would raise tons of false hits)

I think that this is the starting point for a regex that supports binary. The problem with regular expressions, and especially on x86 systems, is that the same instruction can be encoded in a variety of ways.

I'm not sure what kind of regex you are seeking though; one that can recognize patterns like
- "MOV REG1, REG2", regardless of the encoding (quite hard I think);regex is machine specific
- "MOV EAX, ECX", regardless of the encoding (easier);regex is machine specific
- Fixed, Encoded byte patterns, but with the ability to use regexp operators. In this case the regex isn't machine-specific - only the rules are.

Uradox
September 16th, 2005, 06:35
nice tool

Bros
September 29th, 2005, 04:21
Thanks for this very nice tool