From cf9cc30d5ef4c15d831dcb0fca2e945f65b96e8b Mon Sep 17 00:00:00 2001 From: Matt Nadareski Date: Thu, 8 Dec 2022 13:13:16 -0800 Subject: [PATCH] Handle casting exceptions --- BurnOutSharp.Builder/Extensions.cs | 100 +++++++++++++------- BurnOutSharp.Wrappers/PortableExecutable.cs | 25 +++-- 2 files changed, 85 insertions(+), 40 deletions(-) diff --git a/BurnOutSharp.Builder/Extensions.cs b/BurnOutSharp.Builder/Extensions.cs index e96d5d6c..9fef7997 100644 --- a/BurnOutSharp.Builder/Extensions.cs +++ b/BurnOutSharp.Builder/Extensions.cs @@ -130,11 +130,14 @@ namespace BurnOutSharp.Builder /// public static string ReadString(this byte[] content, ref int offset, Encoding encoding) { + if (offset >= content.Length) + return null; + byte[] nullTerminator = encoding.GetBytes(new char[] { '\0' }); int charWidth = nullTerminator.Length; List keyChars = new List(); - while (BitConverter.ToUInt16(content, offset) != 0x0000) + while (offset < content.Length && BitConverter.ToUInt16(content, offset) != 0x0000) { keyChars.Add(encoding.GetChars(content, offset, charWidth)[0]); offset += charWidth; } @@ -266,13 +269,16 @@ namespace BurnOutSharp.Builder /// public static string ReadString(this Stream stream, Encoding encoding) { + if (stream.Position >= stream.Length) + return null; + byte[] nullTerminator = encoding.GetBytes(new char[] { '\0' }); int charWidth = nullTerminator.Length; List tempBuffer = new List(); byte[] buffer = new byte[charWidth]; - while (stream.Read(buffer, 0, charWidth) != 0 && !buffer.SequenceEqual(nullTerminator)) + while (stream.Position < stream.Length && stream.Read(buffer, 0, charWidth) != 0 && !buffer.SequenceEqual(nullTerminator)) { tempBuffer.AddRange(buffer); } @@ -529,9 +535,12 @@ namespace BurnOutSharp.Builder // Read the menu resource as a string dialogTemplateExtended.MenuResource = entry.Data.ReadString(ref offset, Encoding.Unicode); - // Align to the WORD boundary - while ((offset % 2) != 0) - _ = entry.Data.ReadByte(ref offset); + // Align to the WORD boundary if we're not at the end + if (offset != entry.Data.Length) + { + while ((offset % 2) != 0) + _ = entry.Data.ReadByte(ref offset); + } // Read the ordinal if we have the flag set if (menuResourceHasOrdinal) @@ -562,9 +571,12 @@ namespace BurnOutSharp.Builder // Read the class resource as a string dialogTemplateExtended.ClassResource = entry.Data.ReadString(ref offset, Encoding.Unicode); - // Align to the WORD boundary - while ((offset % 2) != 0) - _ = entry.Data.ReadByte(ref offset); + // Align to the WORD boundary if we're not at the end + if (offset != entry.Data.Length) + { + while ((offset % 2) != 0) + _ = entry.Data.ReadByte(ref offset); + } // Read the ordinal if we have the flag set if (classResourcehasOrdinal) @@ -590,9 +602,12 @@ namespace BurnOutSharp.Builder // Read the title resource as a string dialogTemplateExtended.TitleResource = entry.Data.ReadString(ref offset, Encoding.Unicode); - // Align to the WORD boundary - while ((offset % 2) != 0) - _ = entry.Data.ReadByte(ref offset); + // Align to the WORD boundary if we're not at the end + if (offset != entry.Data.Length) + { + while ((offset % 2) != 0) + _ = entry.Data.ReadByte(ref offset); + } } #endregion @@ -664,9 +679,12 @@ namespace BurnOutSharp.Builder // Read the class resource as a string dialogItemTemplate.ClassResource = entry.Data.ReadString(ref offset, Encoding.Unicode); - // Align to the WORD boundary - while ((offset % 2) != 0) - _ = entry.Data.ReadByte(ref offset); + // Align to the WORD boundary if we're not at the end + if (offset != entry.Data.Length) + { + while ((offset % 2) != 0) + _ = entry.Data.ReadByte(ref offset); + } } #endregion @@ -691,9 +709,12 @@ namespace BurnOutSharp.Builder // Read the title resource as a string dialogItemTemplate.TitleResource = entry.Data.ReadString(ref offset, Encoding.Unicode); - // Align to the WORD boundary - while ((offset % 2) != 0) - _ = entry.Data.ReadByte(ref offset); + // Align to the WORD boundary if we're not at the end + if (offset != entry.Data.Length) + { + while ((offset % 2) != 0) + _ = entry.Data.ReadByte(ref offset); + } } #endregion @@ -756,9 +777,12 @@ namespace BurnOutSharp.Builder // Read the menu resource as a string dialogTemplate.MenuResource = entry.Data.ReadString(ref offset, Encoding.Unicode); - // Align to the WORD boundary - while ((offset % 2) != 0) - _ = entry.Data.ReadByte(ref offset); + // Align to the WORD boundary if we're not at the end + if (offset != entry.Data.Length) + { + while ((offset % 2) != 0) + _ = entry.Data.ReadByte(ref offset); + } // Read the ordinal if we have the flag set if (menuResourceHasOrdinal) @@ -789,9 +813,12 @@ namespace BurnOutSharp.Builder // Read the class resource as a string dialogTemplate.ClassResource = entry.Data.ReadString(ref offset, Encoding.Unicode); - // Align to the WORD boundary - while ((offset % 2) != 0) - _ = entry.Data.ReadByte(ref offset); + // Align to the WORD boundary if we're not at the end + if (offset != entry.Data.Length) + { + while ((offset % 2) != 0) + _ = entry.Data.ReadByte(ref offset); + } // Read the ordinal if we have the flag set if (classResourcehasOrdinal) @@ -817,9 +844,12 @@ namespace BurnOutSharp.Builder // Read the title resource as a string dialogTemplate.TitleResource = entry.Data.ReadString(ref offset, Encoding.Unicode); - // Align to the WORD boundary - while ((offset % 2) != 0) - _ = entry.Data.ReadByte(ref offset); + // Align to the WORD boundary if we're not at the end + if (offset != entry.Data.Length) + { + while ((offset % 2) != 0) + _ = entry.Data.ReadByte(ref offset); + } } #endregion @@ -889,9 +919,12 @@ namespace BurnOutSharp.Builder // Read the class resource as a string dialogItemTemplate.ClassResource = entry.Data.ReadString(ref offset, Encoding.Unicode); - // Align to the WORD boundary - while ((offset % 2) != 0) - _ = entry.Data.ReadByte(ref offset); + // Align to the WORD boundary if we're not at the end + if (offset != entry.Data.Length) + { + while ((offset % 2) != 0) + _ = entry.Data.ReadByte(ref offset); + } } #endregion @@ -916,9 +949,12 @@ namespace BurnOutSharp.Builder // Read the title resource as a string dialogItemTemplate.TitleResource = entry.Data.ReadString(ref offset, Encoding.Unicode); - // Align to the WORD boundary - while ((offset % 2) != 0) - _ = entry.Data.ReadByte(ref offset); + // Align to the WORD boundary if we're not at the end + if (offset != entry.Data.Length) + { + while ((offset % 2) != 0) + _ = entry.Data.ReadByte(ref offset); + } } #endregion diff --git a/BurnOutSharp.Wrappers/PortableExecutable.cs b/BurnOutSharp.Wrappers/PortableExecutable.cs index 585a5f1b..63018246 100644 --- a/BurnOutSharp.Wrappers/PortableExecutable.cs +++ b/BurnOutSharp.Wrappers/PortableExecutable.cs @@ -1770,7 +1770,8 @@ namespace BurnOutSharp.Wrappers Console.WriteLine($"{padding}Hardware-dependent icon resource found, not parsed yet"); break; case Models.PortableExecutable.ResourceType.RT_MENU: - var menu = entry.AsMenu(); + Models.PortableExecutable.MenuResource menu = null; + try { menu = entry.AsMenu(); } catch { } if (menu == null) { Console.WriteLine($"{padding}Menu resource found, but malformed"); @@ -1848,7 +1849,8 @@ namespace BurnOutSharp.Wrappers } break; case Models.PortableExecutable.ResourceType.RT_DIALOG: - var dialogBox = entry.AsDialogBox(); + Models.PortableExecutable.DialogBoxResource dialogBox = null; + try { dialogBox = entry.AsDialogBox(); } catch { } if (dialogBox == null) { Console.WriteLine($"{padding}Dialog box resource found, but malformed"); @@ -1971,7 +1973,8 @@ namespace BurnOutSharp.Wrappers } break; case Models.PortableExecutable.ResourceType.RT_STRING: - var stringTable = entry.AsStringTable(); + Dictionary stringTable = null; + try { stringTable = entry.AsStringTable(); } catch { } if (stringTable == null) { Console.WriteLine($"{padding}String table resource found, but malformed"); @@ -1993,7 +1996,8 @@ namespace BurnOutSharp.Wrappers Console.WriteLine($"{padding}Font resource found, not parsed yet"); break; case Models.PortableExecutable.ResourceType.RT_ACCELERATOR: - var acceleratorTable = entry.AsAcceleratorTableResource(); + Models.PortableExecutable.AcceleratorTableEntry[] acceleratorTable = null; + try { acceleratorTable = entry.AsAcceleratorTableResource(); } catch { } if (acceleratorTable == null) { Console.WriteLine($"{padding}Accelerator table resource found, but malformed"); @@ -2012,9 +2016,12 @@ namespace BurnOutSharp.Wrappers break; case Models.PortableExecutable.ResourceType.RT_RCDATA: Console.WriteLine($"{padding}Application-defined resource found, not parsed yet"); + //if (entry.Data != null) + // Console.WriteLine($"{padding}Value (ASCII): {Encoding.ASCII.GetString(entry.Data)}"); break; case Models.PortableExecutable.ResourceType.RT_MESSAGETABLE: - var messageTable = entry.AsMessageResourceData(); + Models.PortableExecutable.MessageResourceData messageTable = null; + try { messageTable = entry.AsMessageResourceData(); } catch { } if (messageTable == null) { Console.WriteLine($"{padding}Message resource data found, but malformed"); @@ -2074,7 +2081,8 @@ namespace BurnOutSharp.Wrappers Console.WriteLine($"{padding}Hardware-independent icon resource found, not parsed yet"); break; case Models.PortableExecutable.ResourceType.RT_VERSION: - var versionInfo = entry.AsVersionInfo(); + Models.PortableExecutable.VersionInfo versionInfo = null; + try { versionInfo = entry.AsVersionInfo(); } catch { } if (versionInfo == null) { Console.WriteLine($"{padding}Version info resource found, but malformed"); @@ -2192,7 +2200,8 @@ namespace BurnOutSharp.Wrappers Console.WriteLine($"{padding}HTML resource found, not parsed yet"); break; case Models.PortableExecutable.ResourceType.RT_MANIFEST: - var assemblyManifest = entry.AsAssemblyManifest(); + Models.PortableExecutable.AssemblyManifest assemblyManifest = null; + try { assemblyManifest = entry.AsAssemblyManifest(); } catch { } if (assemblyManifest == null) { Console.WriteLine($"{padding}Assembly manifest found, but malformed"); @@ -2347,7 +2356,7 @@ namespace BurnOutSharp.Wrappers default: Console.WriteLine($"{padding}Type {(Models.PortableExecutable.ResourceType)resourceType} found, not parsed yet"); //Console.WriteLine($"{padding}Data: {BitConverter.ToString(entry.Data).Replace("-", string.Empty)}"); - Console.WriteLine($"{padding}Data: {Encoding.ASCII.GetString(entry.Data)}"); + //Console.WriteLine($"{padding}Data: {Encoding.ASCII.GetString(entry.Data)}"); break; } }