Cleanup and bugfixes; additional notes

This commit is contained in:
Matt Nadareski
2021-09-10 15:32:37 -07:00
parent 1e70d960ba
commit 5344de96b2
67 changed files with 261 additions and 229 deletions

View File

@@ -74,7 +74,7 @@ namespace BurnOutSharp.ExecutableType.Microsoft.Entries
rde.Reserved = stream.ReadUInt32();
int realOffsetToData = (int)PortableExecutable.ConvertVirtualAddress(rde.OffsetToData, sections);
if (realOffsetToData > -1 && realOffsetToData < stream.Length)
if (realOffsetToData > -1 && realOffsetToData < stream.Length && (int)rde.Size > 0 && realOffsetToData + (int)rde.Size < stream.Length)
{
long lastPosition = stream.Position;
stream.Seek(realOffsetToData, SeekOrigin.Begin);
@@ -95,7 +95,7 @@ namespace BurnOutSharp.ExecutableType.Microsoft.Entries
rde.Reserved = BitConverter.ToUInt32(content, offset); offset += 4;
int realOffsetToData = (int)PortableExecutable.ConvertVirtualAddress(rde.OffsetToData, sections);
if (realOffsetToData > -1 && realOffsetToData < content.Length)
if (realOffsetToData > -1 && realOffsetToData < content.Length && (int)rde.Size > 0 && realOffsetToData + (int)rde.Size < content.Length)
rde.Data = new ArraySegment<byte>(content, realOffsetToData, (int)rde.Size).ToArray();
return rde;

View File

@@ -27,6 +27,9 @@ namespace BurnOutSharp.ExecutableType.Microsoft.Entries
var rds = new ResourceDirectoryString();
rds.Length = stream.ReadUInt16();
if (rds.Length + stream.Position > stream.Length)
return null;
rds.UnicodeString = new string(stream.ReadChars(rds.Length, Encoding.Unicode));
return rds;
@@ -37,6 +40,9 @@ namespace BurnOutSharp.ExecutableType.Microsoft.Entries
var rds = new ResourceDirectoryString();
rds.Length = BitConverter.ToUInt16(content, offset); offset += 2;
if (rds.Length + offset > content.Length)
return null;
rds.UnicodeString = Encoding.Unicode.GetString(content, offset, rds.Length); offset += rds.Length;
return rds;

View File

@@ -100,12 +100,12 @@ namespace BurnOutSharp.ExecutableType.Microsoft
}
/// <summary>
/// Get the section based on name, if possible
/// Get the first section based on name, if possible
/// </summary>
/// <param name="sectionName">Name of the section to check for</param>
/// <param name="exact">True to enable exact matching of names, false for starts-with</param>
/// <returns>Section data on success, null on error</returns>
public SectionHeader GetSection(string sectionName, bool exact = false)
public SectionHeader GetFirstSection(string sectionName, bool exact = false)
{
// If we have no sections, we can't do anything
if (SectionTable == null || !SectionTable.Any())
@@ -120,6 +120,27 @@ namespace BurnOutSharp.ExecutableType.Microsoft
return SectionTable.FirstOrDefault(s => Encoding.ASCII.GetString(s.Name).Trim('\0').StartsWith(sectionName));
}
/// <summary>
/// Get the last section based on name, if possible
/// </summary>
/// <param name="sectionName">Name of the section to check for</param>
/// <param name="exact">True to enable exact matching of names, false for starts-with</param>
/// <returns>Section data on success, null on error</returns>
public SectionHeader GetLastSection(string sectionName, bool exact = false)
{
// If we have no sections, we can't do anything
if (SectionTable == null || !SectionTable.Any())
return null;
// If we're checking exactly, return only exact matches (with nulls trimmed)
if (exact)
return SectionTable.LastOrDefault(s => Encoding.ASCII.GetString(s.Name).Trim('\0').Equals(sectionName));
// Otherwise, check if section name starts with the value
else
return SectionTable.LastOrDefault(s => Encoding.ASCII.GetString(s.Name).Trim('\0').StartsWith(sectionName));
}
/// <summary>
/// Get the list of section names
/// </summary>
@@ -210,11 +231,10 @@ namespace BurnOutSharp.ExecutableType.Microsoft
// }
// Resource Table
var table = pex.GetSection(".rsrc", true);
var table = pex.GetLastSection(".rsrc", true);
if (table != null && table.VirtualSize > 0)
{
int tableAddress = (int)ConvertVirtualAddress(table.VirtualAddress, pex.SectionTable);
stream.Seek(tableAddress, SeekOrigin.Begin);
int tableAddress = (int)table.PointerToRawData;
pex.ResourceSection = ResourceSection.Deserialize(stream, pex.SectionTable);
}
}
@@ -276,10 +296,10 @@ namespace BurnOutSharp.ExecutableType.Microsoft
// }
// Resource Table
var table = pex.GetSection(".rsrc", true);
var table = pex.GetLastSection(".rsrc", true);
if (table != null && table.VirtualSize > 0)
{
int tableAddress = (int)ConvertVirtualAddress(table.VirtualAddress, pex.SectionTable);
int tableAddress = (int)table.PointerToRawData;
pex.ResourceSection = ResourceSection.Deserialize(content, ref tableAddress, pex.SectionTable);
}
}
@@ -307,10 +327,14 @@ namespace BurnOutSharp.ExecutableType.Microsoft
if (sections[i] == null)
continue;
// If the section "starts" at 0, just skip it
if (sections[i].PointerToRawData == 0)
continue;
// Attempt to derive the physical address from the current section
var section = sections[i];
if (virtualAddress >= section.VirtualAddress && virtualAddress <= section.VirtualAddress + section.VirtualSize)
return section.PointerToRawData + virtualAddress - section.VirtualAddress;
return section.PointerToRawData + virtualAddress - section.VirtualAddress;
}
return 0;

View File

@@ -1,6 +1,4 @@
using System;
using System.IO;
using BurnOutSharp.Tools;
namespace BurnOutSharp.ExecutableType.Microsoft.Resources
{

View File

@@ -1,4 +1,3 @@
using System;
using System.IO;
using System.Text;
using BurnOutSharp.Tools;

View File

@@ -1,6 +1,4 @@
using System;
using System.IO;
using BurnOutSharp.Tools;
namespace BurnOutSharp.ExecutableType.Microsoft.Resources
{

View File

@@ -1,6 +1,4 @@
using System;
using System.IO;
using BurnOutSharp.Tools;
namespace BurnOutSharp.ExecutableType.Microsoft.Resources
{

View File

@@ -1,6 +1,5 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using BurnOutSharp.ExecutableType.Microsoft.Tables;
namespace BurnOutSharp.ExecutableType.Microsoft.Sections