Steamless.NET

3 minute read

Please note; this project has been replaced by the main Steamless repo now. Please be sure to use that code here:

Recently I ported my Steamless project to .NET. I made this port because more and more people are in the RE scene have been making use of .NET languages (C# and Vb.NET). I wanted to make the project open to more people in the scene if they ever wanted to contribute back or share ideas for the project.

I plan on keeping the C/C++ version, just that it will be a little while before I start updating it again and bring it up to speed with this new repository for the .NET version.

Steamless.NET is written in C# and is made to be as easy to follow, understand, and expand onto.

The code is setup to use reflection to find known unpackers internally and can be easily adjusted to load external modules as unpackers as well. I went with this approach so that people can get into a specific part of the code base easily and modify or extend any part of the code they wish.

The unpackers make use of a custom attribute ‘SteamStubUnpackerAttribute’ that tells the executable the class inheriting the attribute is used as an unpacker for a specific version of the DRM. The attribute has a few properties, one of which is a pattern. The pattern is used to find and determine the version of the DRM being used. For example, this is the variant version 2 class definition:

[SteamStubUnpacker(
    Author = "atom0s (thanks to Cyanic)", Name = "SteamStub Variant #2",
    Pattern = "53 51 52 56 57 55 8B EC 81 EC 00 10 00 00 C7")]
public class SteamStubVariant2 : SteamStubUnpacker
{

Here the attribute tells us the author and name of this stub unpacker, as well as the pattern used to determine the version. Patterns are based on the .bind section code within the file and should be unique to other versions to ensure proper unpacking. In later versions I plan to add a force-flag command line parameter to allow users to specifically state what unpacker they want to use in case a file has false-positives.

All unpacker classes inherit a base class ‘SteamStubUnpacker’ to allow for reflection to initialize and invoke the classes unpacking process. The base class forces the inheritee to implement a function called Process that takes in the current loaded file to be unpacked and then the class is free to do whatever from that point on. For example in the v2 and v3 unpackers I have written so far, I broke each part of the unpacking process into different steps. This helps keep the code base clean and easily maintainable as well as easily readable for new comers to the project.

While the v2 and v3 unpackers are near 100% completion they do come with some bugs.

For the v2 unpacker:

  • x64 bit files are not handled at this time.
  • Not all flags may be handled correctly as only a few executables have been tested and validated.
  • In certain cases, overlay data may not be restored properly. (Some files store this into a section called .extra)

For the v3 unpacker:

  • x64bit files are not handled at this time.
  • Not all flags may be handled correctly as only a few executables have been tested and validated.
  • If a file has no .text section (or it was renamed) the unpacking will force-fail. (This will be fixed soon.)

Again, a big thanks to Golem_x86 for his assistance in this project. :)

Comments