/// <summary> /// Gets the SteamStub header size from the given file. /// </summary> /// <param name="f"></param> /// <returns></returns> private uint GetHeaderSize(Pe64File f) { // Obtain the bind section data.. var bind = f.GetSectionData(".bind"); // Attempt to locate the known v3.x signature.. var varient = Pe64Helpers.FindPattern(bind, "E8 00 00 00 00 50 53 51 52 56 57 55 41 50"); if (varient == 0) { return(0); } // Attempt to determine the varient version.. var offset = Pe64Helpers.FindPattern(bind, "48 8D 91 ?? ?? ?? ?? 48"); // 3.0 if (offset == 0) { offset = Pe64Helpers.FindPattern(bind, "48 8D 91 ?? ?? ?? ?? 41"); // 3.1 } // Ensure a pattern was found.. if (offset == 0) { return(0); } // Read the header size.. (The header size is only 32bit!) return((uint)Math.Abs(BitConverter.ToInt32(bind, (int)offset + 3))); }
/// <summary> /// Processing function called when a file is being unpacked. Allows plugins to check the file /// and see if it can handle the file for its intended purpose. /// </summary> /// <param name="file"></param> /// <returns></returns> public override bool CanProcessFile(string file) { try { // Load the file.. var f = new Pe64File(file); if (!f.Parse() || !f.IsFile64Bit() || !f.HasSection(".bind")) { return(false); } // Obtain the bind section data.. var bind = f.GetSectionData(".bind"); // Attempt to locate the known v3.x signature.. var varient = Pe64Helpers.FindPattern(bind, "E8 00 00 00 00 50 53 51 52 56 57 55 41 50"); if (varient == 0) { return(false); } // Attempt to determine the varient version.. var offset = Pe64Helpers.FindPattern(bind, "48 8D 91 ?? ?? ?? ?? 48"); // 3.0 if (offset == 0) { offset = Pe64Helpers.FindPattern(bind, "48 8D 91 ?? ?? ?? ?? 41"); // 3.1 } if (offset == 0) { offset = Pe64Helpers.FindPattern(bind, "48 C7 84 24 ?? ?? ?? ?? ?? ?? ?? ?? 48"); // 3.1.2 if (offset > 0) { offset += 5; } } // Ensure a pattern was found.. if (offset == 0) { return(false); } // Read the header size.. (The header size is only 32bit!) var headerSize = Math.Abs(BitConverter.ToInt32(bind, (int)offset + 3)); // Check for the known 3.1 header size.. return(headerSize == 0xF0); } catch { return(false); } }
/// <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 == -1) { 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); }