mirror of
https://github.com/atom0s/Steamless.git
synced 2024-12-19 23:07:41 +01:00
Unpacker: v30.x64 - Renamed header field Unknown0003
to HasTlsCallback
.
Unpacker: v30.x64 - Add support for handling files packed with TlsCallback overrides. This feature is currently only supported in this variant for the time being. (Until other samples are provided that have a TlsCallback override for the other variants.) Notes on how this file type works can be found here: https://github.com/atom0s/Steamless/issues/20#issuecomment-1078821463 This fixes: #20
This commit is contained in:
parent
0ad40aeabd
commit
b97f148945
2 changed files with 60 additions and 3 deletions
|
@ -63,7 +63,7 @@ namespace Steamless.Unpacker.Variant30.x64.Classes
|
||||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x04)]
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x04)]
|
||||||
public uint[] EncryptionKeys; // Encryption keys used for decrypting SteamDRMP.dll file.
|
public uint[] EncryptionKeys; // Encryption keys used for decrypting SteamDRMP.dll file.
|
||||||
|
|
||||||
public uint Unknown0003; // [Cyanic: This field is most likely used to flag if the file has Tls data or not.]
|
public uint HasTlsCallback; // Flag that states if the file was protected with a TlsCallback present.
|
||||||
public uint Unknown0004;
|
public uint Unknown0004;
|
||||||
public uint Unknown0005;
|
public uint Unknown0005;
|
||||||
public uint Unknown0006;
|
public uint Unknown0006;
|
||||||
|
|
|
@ -35,6 +35,7 @@ namespace Steamless.Unpacker.Variant30.x64
|
||||||
using Classes;
|
using Classes;
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
|
|
||||||
|
@ -189,6 +190,48 @@ namespace Steamless.Unpacker.Variant30.x64
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Rebuilds the file TlsCallback information and repairs the proper OEP.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
private bool RebuildTlsCallbackInformation()
|
||||||
|
{
|
||||||
|
// Ensure the modified main TlsCallback is within the .bind section..
|
||||||
|
var section = this.File.GetOwnerSection(this.File.GetRvaFromVa(this.File.TlsCallbacks[0]));
|
||||||
|
if (!section.IsValid || string.Compare(section.SectionName, ".bind", System.Globalization.CultureInfo.InvariantCulture, System.Globalization.CompareOptions.IgnoreCase) != 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Obtain the section that holds the Tls directory information..
|
||||||
|
var addr = this.File.GetFileOffsetFromRva(this.File.GetRvaFromVa(this.File.TlsDirectory.AddressOfCallBacks));
|
||||||
|
var tlsd = this.File.GetOwnerSection(addr);
|
||||||
|
|
||||||
|
if (!tlsd.IsValid)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
addr -= tlsd.PointerToRawData;
|
||||||
|
|
||||||
|
// Restore the true original TlsCallback address..
|
||||||
|
var callback = BitConverter.GetBytes(this.File.NtHeaders.OptionalHeader.ImageBase + this.StubHeader.OriginalEntryPoint);
|
||||||
|
Array.Copy(callback, 0, this.File.GetSectionData(this.File.GetSectionIndex(tlsd)), (int)addr, callback.Length);
|
||||||
|
|
||||||
|
// Find the original entry point function..
|
||||||
|
var entry = this.File.GetFileOffsetFromRva(this.File.NtHeaders.OptionalHeader.AddressOfEntryPoint);
|
||||||
|
var data = this.File.FileData.Skip((int)entry).Take(0x100).ToArray();
|
||||||
|
|
||||||
|
// Find the XOR key from within the function..
|
||||||
|
var res = Pe64Helpers.FindPattern(data, "48 81 EA ?? ?? ?? ?? 8B 12 81 F2");
|
||||||
|
if (res == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Decrypt and recalculate the true OEP address..
|
||||||
|
var key = (ulong)(this.StubHeader.XorKey ^ BitConverter.ToInt32(data, (int)res + 0x0B));
|
||||||
|
var off = (ulong)((this.File.NtHeaders.OptionalHeader.ImageBase + this.File.NtHeaders.OptionalHeader.AddressOfEntryPoint) + key);
|
||||||
|
|
||||||
|
// Store the proper OEP..
|
||||||
|
this.TlsOepOverride = (uint)(off - this.File.NtHeaders.OptionalHeader.ImageBase);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Step #1
|
/// Step #1
|
||||||
///
|
///
|
||||||
|
@ -234,7 +277,13 @@ namespace Steamless.Unpacker.Variant30.x64
|
||||||
// Tls was valid for the real oep..
|
// Tls was valid for the real oep..
|
||||||
this.TlsAsOep = true;
|
this.TlsAsOep = true;
|
||||||
this.TlsOepRva = this.File.GetRvaFromVa(this.File.TlsCallbacks[0]);
|
this.TlsOepRva = this.File.GetRvaFromVa(this.File.TlsCallbacks[0]);
|
||||||
|
|
||||||
|
// Is the TlsCallback replacing the OEP..
|
||||||
|
if (this.StubHeader.HasTlsCallback != 1 || this.File.TlsCallbacks[0] == 0)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
// Rebuild the file Tls callback information..
|
||||||
|
return this.RebuildTlsCallbackInformation();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -447,7 +496,10 @@ namespace Steamless.Unpacker.Variant30.x64
|
||||||
|
|
||||||
// Update the entry point of the file..
|
// Update the entry point of the file..
|
||||||
var ntHeaders = this.File.NtHeaders;
|
var ntHeaders = this.File.NtHeaders;
|
||||||
|
if (this.StubHeader.HasTlsCallback != 1)
|
||||||
ntHeaders.OptionalHeader.AddressOfEntryPoint = this.StubHeader.OriginalEntryPoint;
|
ntHeaders.OptionalHeader.AddressOfEntryPoint = this.StubHeader.OriginalEntryPoint;
|
||||||
|
else
|
||||||
|
ntHeaders.OptionalHeader.AddressOfEntryPoint = this.TlsOepOverride;
|
||||||
this.File.NtHeaders = ntHeaders;
|
this.File.NtHeaders = ntHeaders;
|
||||||
|
|
||||||
// Write the NT headers to the file..
|
// Write the NT headers to the file..
|
||||||
|
@ -510,6 +562,11 @@ namespace Steamless.Unpacker.Variant30.x64
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private ulong TlsOepRva { get; set; }
|
private ulong TlsOepRva { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the Tls Oep override value to use when the stub has set the HasTlsCallback flag.
|
||||||
|
/// </summary>
|
||||||
|
private uint TlsOepOverride { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the Steamless options this file was requested to process with.
|
/// Gets or sets the Steamless options this file was requested to process with.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
Loading…
Reference in a new issue