mirror of
https://github.com/SabreTools/BinaryObjectScanner.git
synced 2026-07-30 04:33:00 +00:00
Add PE dialog template extended
This commit is contained in:
@@ -484,11 +484,130 @@ namespace BurnOutSharp.Builder
|
||||
int possibleSignature = entry.Data.ReadUInt16(ref signatureOffset);
|
||||
if (possibleSignature == 0xFFFF)
|
||||
{
|
||||
Console.WriteLine("Extended dialog box template found, but not implemented");
|
||||
|
||||
#region Extended dialog template
|
||||
|
||||
// TODO: Implement extended dialog template
|
||||
var dialogTemplateExtended = new Models.PortableExecutable.DialogTemplateExtended();
|
||||
|
||||
dialogTemplateExtended.Version = entry.Data.ReadUInt16(ref offset);
|
||||
dialogTemplateExtended.Signature = entry.Data.ReadUInt16(ref offset);
|
||||
dialogTemplateExtended.HelpID = entry.Data.ReadUInt32(ref offset);
|
||||
dialogTemplateExtended.ExtendedStyle = (Models.PortableExecutable.ExtendedWindowStyles)entry.Data.ReadUInt32(ref offset);
|
||||
dialogTemplateExtended.Style = (Models.PortableExecutable.WindowStyles)entry.Data.ReadUInt32(ref offset);
|
||||
dialogTemplateExtended.DialogItems = entry.Data.ReadUInt16(ref offset);
|
||||
dialogTemplateExtended.PositionX = entry.Data.ReadInt16(ref offset);
|
||||
dialogTemplateExtended.PositionY = entry.Data.ReadInt16(ref offset);
|
||||
dialogTemplateExtended.WidthX = entry.Data.ReadInt16(ref offset);
|
||||
dialogTemplateExtended.HeightY = entry.Data.ReadInt16(ref offset);
|
||||
|
||||
#region Menu resource
|
||||
|
||||
int currentOffset = offset;
|
||||
ushort menuResourceIdentifier = entry.Data.ReadUInt16(ref offset);
|
||||
offset = currentOffset;
|
||||
|
||||
// 0x0000 means no elements
|
||||
if (menuResourceIdentifier == 0x0000)
|
||||
{
|
||||
// Increment the pointer if it was empty
|
||||
offset += sizeof(ushort);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Flag if there's an ordinal at the end
|
||||
bool menuResourceHasOrdinal = menuResourceIdentifier == 0xFFFF;
|
||||
if (menuResourceHasOrdinal)
|
||||
offset += sizeof(ushort);
|
||||
|
||||
// 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);
|
||||
|
||||
// Read the ordinal if we have the flag set
|
||||
if (menuResourceHasOrdinal)
|
||||
dialogTemplateExtended.MenuResourceOrdinal = entry.Data.ReadUInt16(ref offset);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Class resource
|
||||
|
||||
currentOffset = offset;
|
||||
ushort classResourceIdentifier = entry.Data.ReadUInt16(ref offset);
|
||||
offset = currentOffset;
|
||||
|
||||
// 0x0000 means no elements
|
||||
if (classResourceIdentifier == 0x0000)
|
||||
{
|
||||
// Increment the pointer if it was empty
|
||||
offset += sizeof(ushort);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Flag if there's an ordinal at the end
|
||||
bool classResourcehasOrdinal = classResourceIdentifier == 0xFFFF;
|
||||
if (classResourcehasOrdinal)
|
||||
offset += sizeof(ushort);
|
||||
|
||||
// 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);
|
||||
|
||||
// Read the ordinal if we have the flag set
|
||||
if (classResourcehasOrdinal)
|
||||
dialogTemplateExtended.ClassResourceOrdinal = entry.Data.ReadUInt16(ref offset);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Title resource
|
||||
|
||||
currentOffset = offset;
|
||||
ushort titleResourceIdentifier = entry.Data.ReadUInt16(ref offset);
|
||||
offset = currentOffset;
|
||||
|
||||
// 0x0000 means no elements
|
||||
if (titleResourceIdentifier == 0x0000)
|
||||
{
|
||||
// Increment the pointer if it was empty
|
||||
offset += sizeof(ushort);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 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);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Point size and typeface
|
||||
|
||||
// Only if DS_SETFONT is set are the values here used
|
||||
if (dialogTemplateExtended.Style.HasFlag(Models.PortableExecutable.WindowStyles.DS_SETFONT))
|
||||
{
|
||||
dialogTemplateExtended.PointSize = entry.Data.ReadUInt16(ref offset);
|
||||
dialogTemplateExtended.Weight = entry.Data.ReadUInt16(ref offset);
|
||||
dialogTemplateExtended.Italic = entry.Data.ReadByte(ref offset);
|
||||
dialogTemplateExtended.CharSet = entry.Data.ReadByte(ref offset);
|
||||
dialogTemplateExtended.Typeface = entry.Data.ReadString(ref offset, Encoding.Unicode);
|
||||
}
|
||||
|
||||
// Align to the DWORD boundary
|
||||
while ((offset % 4) != 0)
|
||||
_ = entry.Data.ReadByte(ref offset);
|
||||
|
||||
#endregion
|
||||
|
||||
dialogBoxResource.DialogTemplateExtended = dialogTemplateExtended;
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
@@ -9,11 +9,22 @@
|
||||
/// <see href="https://learn.microsoft.com/en-us/windows/win32/menurc/resource-file-formats"/>
|
||||
public class DialogBoxResource
|
||||
{
|
||||
#region Dialog template
|
||||
|
||||
/// <summary>
|
||||
/// Dialog box header structure
|
||||
/// </summary>
|
||||
public DialogTemplate DialogTemplate;
|
||||
|
||||
/// <summary>
|
||||
/// Dialog box extended header structure
|
||||
/// </summary>
|
||||
public DialogTemplateExtended DialogTemplateExtended;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Dialog item templates
|
||||
|
||||
/// <summary>
|
||||
/// Following the DLGTEMPLATE header in a standard dialog box template are one or more
|
||||
/// DLGITEMTEMPLATE structures that define the dimensions and style of the controls in the dialog
|
||||
@@ -21,5 +32,7 @@
|
||||
/// These DLGITEMTEMPLATE structures must be aligned on DWORD boundaries.
|
||||
/// </summary>
|
||||
public DialogItemTemplate[] DialogItemTemplates;
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
172
BurnOutSharp.Models/PortableExecutable/DialogTemplateExtended.cs
Normal file
172
BurnOutSharp.Models/PortableExecutable/DialogTemplateExtended.cs
Normal file
@@ -0,0 +1,172 @@
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace BurnOutSharp.Models.PortableExecutable
|
||||
{
|
||||
/// <summary>
|
||||
/// An extended dialog box template begins with a DLGTEMPLATEEX header that describes
|
||||
/// the dialog box and specifies the number of controls in the dialog box. For each
|
||||
/// control in a dialog box, an extended dialog box template has a block of data that
|
||||
/// uses the DLGITEMTEMPLATEEX format to describe the control.
|
||||
///
|
||||
/// The DLGTEMPLATEEX structure is not defined in any standard header file. The
|
||||
/// structure definition is provided here to explain the format of an extended template
|
||||
/// for a dialog box.
|
||||
/// </summary>
|
||||
/// <see href="https://learn.microsoft.com/en-us/windows/win32/dlgbox/dlgtemplateex"/>
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public class DialogTemplateExtended
|
||||
{
|
||||
/// <summary>
|
||||
/// The version number of the extended dialog box template. This member must be
|
||||
/// set to 1.
|
||||
/// </summary>
|
||||
public ushort Version;
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether a template is an extended dialog box template. If signature
|
||||
/// is 0xFFFF, this is an extended dialog box template. In this case, the dlgVer
|
||||
/// member specifies the template version number. If signature is any value other
|
||||
/// than 0xFFFF, this is a standard dialog box template that uses the DLGTEMPLATE
|
||||
/// and DLGITEMTEMPLATE structures.
|
||||
/// </summary>
|
||||
public ushort Signature;
|
||||
|
||||
/// <summary>
|
||||
/// The help context identifier for the dialog box window. When the system sends a
|
||||
/// WM_HELP message, it passes this value in the wContextId member of the HELPINFO
|
||||
/// structure.
|
||||
/// </summary>
|
||||
public uint HelpID;
|
||||
|
||||
/// <summary>
|
||||
/// The extended windows styles. This member is not used when creating dialog boxes,
|
||||
/// but applications that use dialog box templates can use it to create other types
|
||||
/// of windows.
|
||||
/// </summary>
|
||||
public ExtendedWindowStyles ExtendedStyle;
|
||||
|
||||
/// <summary>
|
||||
/// The style of the dialog box.
|
||||
///
|
||||
/// If style includes the DS_SETFONT or DS_SHELLFONT dialog box style, the DLGTEMPLATEEX
|
||||
/// header of the extended dialog box template contains four additional members (pointsize,
|
||||
/// weight, italic, and typeface) that describe the font to use for the text in the client
|
||||
/// area and controls of the dialog box. If possible, the system creates a font according
|
||||
/// to the values specified in these members. Then the system sends a WM_SETFONT message
|
||||
/// to the dialog box and to each control to provide a handle to the font.
|
||||
/// </summary>
|
||||
public WindowStyles Style;
|
||||
|
||||
/// <summary>
|
||||
/// The number of controls in the dialog box.
|
||||
/// </summary>
|
||||
public ushort DialogItems;
|
||||
|
||||
/// <summary>
|
||||
/// The x-coordinate, in dialog box units, of the upper-left corner of the dialog box.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The x, y, cx, and cy members specify values in dialog box units. You can convert these values
|
||||
/// to screen units (pixels) by using the MapDialogRect function.
|
||||
/// </remarks>
|
||||
public short PositionX;
|
||||
|
||||
/// <summary>
|
||||
/// The y-coordinate, in dialog box units, of the upper-left corner of the dialog box.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The x, y, cx, and cy members specify values in dialog box units. You can convert these values
|
||||
/// to screen units (pixels) by using the MapDialogRect function.
|
||||
/// </remarks>
|
||||
public short PositionY;
|
||||
|
||||
/// <summary>
|
||||
/// The width, in dialog box units, of the dialog box.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The x, y, cx, and cy members specify values in dialog box units. You can convert these values
|
||||
/// to screen units (pixels) by using the MapDialogRect function.
|
||||
/// </remarks>
|
||||
public short WidthX;
|
||||
|
||||
/// <summary>
|
||||
/// The height, in dialog box units, of the dialog box.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The x, y, cx, and cy members specify values in dialog box units. You can convert these values
|
||||
/// to screen units (pixels) by using the MapDialogRect function.
|
||||
/// </remarks>
|
||||
public short HeightY;
|
||||
|
||||
/// <summary>
|
||||
/// A variable-length array of 16-bit elements that identifies a menu resource for the dialog box.
|
||||
/// If the first element of this array is 0x0000, the dialog box has no menu and the array has no
|
||||
/// other elements. If the first element is 0xFFFF, the array has one additional element that
|
||||
/// specifies the ordinal value of a menu resource in an executable file. If the first element has
|
||||
/// any other value, the system treats the array as a null-terminated Unicode string that specifies
|
||||
/// the name of a menu resource in an executable file.
|
||||
/// </summary>
|
||||
public string MenuResource;
|
||||
|
||||
/// <summary>
|
||||
/// The ordinal value of a menu resource in an executable file.
|
||||
/// </summary>
|
||||
public ushort MenuResourceOrdinal;
|
||||
|
||||
/// <summary>A variable-length array of 16-bit elements that identifies the window class of the
|
||||
/// dialog box. If the first element of the array is 0x0000, the system uses the predefined dialog
|
||||
/// box class for the dialog box and the array has no other elements. If the first element is 0xFFFF,
|
||||
/// the array has one additional element that specifies the ordinal value of a predefined system
|
||||
/// window class. If the first element has any other value, the system treats the array as a
|
||||
/// null-terminated Unicode string that specifies the name of a registered window class.
|
||||
/// </summary>
|
||||
public string ClassResource;
|
||||
|
||||
/// <summary>
|
||||
/// The ordinal value of a predefined system window class.
|
||||
/// </summary>
|
||||
public ushort ClassResourceOrdinal;
|
||||
|
||||
/// <summary>
|
||||
/// The title of the dialog box. If the first element of this array is 0x0000, the dialog box has no
|
||||
/// title and the array has no other elements.
|
||||
/// </summary>
|
||||
public string TitleResource;
|
||||
|
||||
/// <summary>
|
||||
/// The point size of the font to use for the text in the dialog box and its controls.
|
||||
///
|
||||
/// This member is present only if the style member specifies DS_SETFONT or DS_SHELLFONT.
|
||||
/// </summary>
|
||||
public ushort PointSize;
|
||||
|
||||
/// <summary>
|
||||
/// The weight of the font. Note that, although this can be any of the values listed for the lfWeight
|
||||
/// member of the LOGFONT structure, any value that is used will be automatically changed to FW_NORMAL.
|
||||
///
|
||||
/// This member is present only if the style member specifies DS_SETFONT or DS_SHELLFONT.
|
||||
/// </summary>
|
||||
public ushort Weight;
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the font is italic. If this value is TRUE, the font is italic.
|
||||
///
|
||||
/// This member is present only if the style member specifies DS_SETFONT or DS_SHELLFONT.
|
||||
/// </summary>
|
||||
public byte Italic;
|
||||
|
||||
/// <summary>
|
||||
/// The character set to be used. For more information, see the lfcharset member of LOGFONT.
|
||||
///
|
||||
/// This member is present only if the style member specifies DS_SETFONT or DS_SHELLFONT.
|
||||
/// </summary>
|
||||
public byte CharSet;
|
||||
|
||||
/// <summary>
|
||||
/// The name of the typeface for the font.
|
||||
///
|
||||
/// This member is present only if the style member specifies DS_SETFONT or DS_SHELLFONT.
|
||||
/// </summary>
|
||||
public string Typeface;
|
||||
}
|
||||
}
|
||||
@@ -1248,6 +1248,63 @@ namespace ExecutableTest
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (dialogBox.DialogTemplateExtended != null)
|
||||
{
|
||||
Console.WriteLine($"{padding}Version: {dialogBox.DialogTemplateExtended.Version}");
|
||||
Console.WriteLine($"{padding}Signature: {dialogBox.DialogTemplateExtended.Signature}");
|
||||
Console.WriteLine($"{padding}Help ID: {dialogBox.DialogTemplateExtended.HelpID}");
|
||||
Console.WriteLine($"{padding}Extended style: {dialogBox.DialogTemplateExtended.ExtendedStyle}");
|
||||
Console.WriteLine($"{padding}Style: {dialogBox.DialogTemplateExtended.Style}");
|
||||
Console.WriteLine($"{padding}Item count: {dialogBox.DialogTemplateExtended.DialogItems}");
|
||||
Console.WriteLine($"{padding}X-coordinate of upper-left corner: {dialogBox.DialogTemplateExtended.PositionX}");
|
||||
Console.WriteLine($"{padding}Y-coordinate of upper-left corner: {dialogBox.DialogTemplateExtended.PositionY}");
|
||||
Console.WriteLine($"{padding}Width of the dialog box: {dialogBox.DialogTemplateExtended.WidthX}");
|
||||
Console.WriteLine($"{padding}Height of the dialog box: {dialogBox.DialogTemplateExtended.HeightY}");
|
||||
Console.WriteLine($"{padding}Menu resource: {dialogBox.DialogTemplateExtended.MenuResource ?? "[EMPTY]"}");
|
||||
Console.WriteLine($"{padding}Menu resource ordinal: {dialogBox.DialogTemplateExtended.MenuResourceOrdinal}");
|
||||
Console.WriteLine($"{padding}Class resource: {dialogBox.DialogTemplateExtended.ClassResource ?? "[EMPTY]"}");
|
||||
Console.WriteLine($"{padding}Class resource ordinal: {dialogBox.DialogTemplateExtended.ClassResourceOrdinal}");
|
||||
Console.WriteLine($"{padding}Title resource: {dialogBox.DialogTemplateExtended.TitleResource ?? "[EMPTY]"}");
|
||||
Console.WriteLine($"{padding}Point size: {dialogBox.DialogTemplateExtended.PointSize}");
|
||||
Console.WriteLine($"{padding}Weight: {dialogBox.DialogTemplateExtended.Weight}");
|
||||
Console.WriteLine($"{padding}Italic: {dialogBox.DialogTemplateExtended.Italic}");
|
||||
Console.WriteLine($"{padding}Character set: {dialogBox.DialogTemplateExtended.CharSet}");
|
||||
Console.WriteLine($"{padding}Typeface: {dialogBox.DialogTemplateExtended.Typeface ?? "[EMPTY]"}");
|
||||
Console.WriteLine();
|
||||
//Console.WriteLine($"{padding}Dialog item templates");
|
||||
//Console.WriteLine($"{padding}-------------------------");
|
||||
//if (dialogBox.DialogTemplate.ItemCount == 0
|
||||
// || dialogBox.DialogItemTemplates == null
|
||||
// || dialogBox.DialogItemTemplates.Length == 0)
|
||||
//{
|
||||
// Console.WriteLine($"{padding}No dialog item templates");
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// for (int i = 0; i < dialogBox.DialogItemTemplates.Length; i++)
|
||||
// {
|
||||
// var dialogItemTemplate = dialogBox.DialogItemTemplates[i];
|
||||
|
||||
// Console.WriteLine($"{padding}Dialog item template {i}");
|
||||
// Console.WriteLine($"{padding} Style: {dialogItemTemplate.Style}");
|
||||
// Console.WriteLine($"{padding} Extended style: {dialogItemTemplate.ExtendedStyle}");
|
||||
// Console.WriteLine($"{padding} X-coordinate of upper-left corner: {dialogItemTemplate.PositionX}");
|
||||
// Console.WriteLine($"{padding} Y-coordinate of upper-left corner: {dialogItemTemplate.PositionY}");
|
||||
// Console.WriteLine($"{padding} Width of the control: {dialogItemTemplate.WidthX}");
|
||||
// Console.WriteLine($"{padding} Height of the control: {dialogItemTemplate.HeightY}");
|
||||
// Console.WriteLine($"{padding} ID: {dialogItemTemplate.ID}");
|
||||
// Console.WriteLine($"{padding} Class resource: {dialogItemTemplate.ClassResource ?? "[EMPTY]"}");
|
||||
// Console.WriteLine($"{padding} Class resource ordinal: {dialogItemTemplate.ClassResourceOrdinal}");
|
||||
// Console.WriteLine($"{padding} Title resource: {dialogItemTemplate.TitleResource ?? "[EMPTY]"}");
|
||||
// Console.WriteLine($"{padding} Title resource ordinal: {dialogItemTemplate.TitleResourceOrdinal}");
|
||||
// Console.WriteLine($"{padding} Creation data size: {dialogItemTemplate.CreationDataSize}");
|
||||
// if (dialogItemTemplate.CreationData != null && dialogItemTemplate.CreationData.Length != 0)
|
||||
// Console.WriteLine($"{padding} Creation data: {BitConverter.ToString(dialogItemTemplate.CreationData).Replace("-", string.Empty)}");
|
||||
// else
|
||||
// Console.WriteLine($"{padding} Creation data: [EMPTY]");
|
||||
// }
|
||||
//}
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine($"{padding}Dialog box resource found, but malformed");
|
||||
|
||||
Reference in New Issue
Block a user