-
Notifications
You must be signed in to change notification settings - Fork 130
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Problem in update dialog #221
Comments
Make sure you retain the right binary format for Reference: |
I wrote the dialog parsing code based on the c++ code here (https://blog.csdn.net/zhyulo/article/details/88239145), the result same as what I tested on https://speedtesting.herokuapp.com/peviewer/. but It seems to be troublesome to write back to new section. codeusing AsmResolver;
using AsmResolver.PE;
using AsmResolver.PE.File;
using AsmResolver.PE.Win32Resources;
using System;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
namespace CallTest
{
class Program
{
#pragma warning disable 0649
public struct ControlData
{
public uint Style;
public uint ExStyle;
public ushort x;
public ushort y;
public ushort cx;
public ushort cy;
public ushort id;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct DialogBoxHeader
{
public uint Style;
public uint ExStyle;
public ushort DlgItems; //control amount
public ushort x;
public ushort y;
public ushort cx;
public ushort cy;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public byte[] menuName;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct DialogFont
{
public ushort wPointSize;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public byte[] FontName;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct DialogBoxHeaderEx
{
public uint SignEx; //0xFFFF0001
public uint Version;
public uint ExStyle;
public uint Style;
public ushort DlgItems; //control amount
public ushort x;
public ushort y;
public ushort cx;
public ushort cy;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public byte[] menuName;
}
[StructLayout(LayoutKind.Sequential)]
public struct DialogFontEx
{
public ushort wPointSize;
public ushort Weight;
public byte Italic;
public byte CharSet;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public byte[] FontName;
}
#pragma warning restore 0649
static void Main(string[] args)
{
string filePath = @"C:\Windows\en-US\notepad.exe.mui";
ModifyFileDescription(filePath, "modify.mui");
Console.ReadKey();
}
static void ModifyFileDescription(string input, string output)
{
var file = PEFile.FromFile(input);
var image = PEImage.FromFile(file);
var stringTables = (IResourceDirectory)image.Resources.Entries.First(e => e.Id == (int)ResourceType.Dialog);
var stringEntry = (IResourceDirectory)stringTables.Entries.First(e => e.Id == 1541); // ID
var dataEntry = (IResourceData)stringEntry.Entries.First(e => e.Id == 1033); // Lang ID
byte[] content = ((AsmResolver.DataSegment)dataEntry.Contents).Data;
ParseDialog( content);
}
private static byte[] ParseDialog( byte[] bytesIn)
{
bool isDialogEx = false;
dynamic DlgBoxHeader;
#region DlgBoxHeader
if (Enumerable.SequenceEqual(bytesIn.Take(4).ToArray(), new byte[] { 0x1, 0x0, 0xFF, 0xFF })) //Dialog or DialogEx
{
isDialogEx = true;
DlgBoxHeader = new DialogBoxHeaderEx();
}
else
{
isDialogEx = false;
DlgBoxHeader = new DialogBoxHeader();
}
int size = Marshal.SizeOf(DlgBoxHeader);
IntPtr buff = Marshal.AllocHGlobal(size);
Marshal.Copy(bytesIn.Take(size).ToArray(), 0, buff, size);
DlgBoxHeader = isDialogEx ? (DialogBoxHeaderEx)Marshal.PtrToStructure(buff, typeof(DialogBoxHeaderEx)) : (DialogBoxHeader)Marshal.PtrToStructure(buff, typeof(DialogBoxHeader));
if (DlgBoxHeader.ExStyle != 0)
{
Console.WriteLine("0x" + DlgBoxHeader.ExStyle.ToString("x8"));
}
bytesIn = bytesIn.Skip(size).ToArray();
#endregion
#region MenuName
byte[] bClassName = null;
byte[] bMenuName = DlgBoxHeader.menuName;
if (BitConverter.ToInt16(bMenuName.Take(2).ToArray(), 0) == -1)
{
bClassName = bytesIn;
}
else if (BitConverter.ToInt16(bMenuName.Take(2).ToArray(), 0) != 0)
{
var len = GetUnicodeStringLength(bytesIn);
var szMenuName = Encoding.Unicode.GetString(bytesIn, 0, len);
Console.WriteLine("MenuName:" + szMenuName);
bClassName = bytesIn.Skip(len).ToArray();
}
else
{
bClassName = bytesIn;
}
#endregion
#region ClassName
byte[] bCaption = null;
if (BitConverter.ToInt16(bClassName.Take(2).ToArray(), 0) == -1)
{
bCaption = bClassName.Skip(2).ToArray();
}
else if (BitConverter.ToInt16(bClassName.Take(2).ToArray(), 0) != 0)
{
var len = GetUnicodeStringLength(bClassName);
var szClassName = Encoding.Unicode.GetString(bClassName, 0, len);
Console.WriteLine("ClassName:" + szClassName);
bCaption = bClassName.Skip(len + 2).ToArray();
}
else
{
bCaption = bClassName.Skip(2).ToArray();
}
#endregion
#region Caption
byte[] bItemData = null;
if (BitConverter.ToInt16(bCaption.Take(2).ToArray(), 0) != 0)
{
var len = GetUnicodeStringLength(bCaption);
var szCaption = Encoding.Unicode.GetString(bCaption, 0, len);
Console.WriteLine("Caption:" + szCaption);
bItemData = bCaption.Skip(len + 2).ToArray();
}
else
{
bItemData = bCaption.Skip(2).ToArray();
}
#endregion
#region DialogFont
if ((DlgBoxHeader.Style & (uint)DialogBoxStyles.DS_SETFONT) != 0) //if have font
{
DialogFontEx DlgFont = new DialogFontEx();
size = Marshal.SizeOf(DlgFont);
buff = Marshal.AllocHGlobal(size);
Marshal.Copy(bItemData.Take(size).ToArray(), 0, buff, size);
DlgFont = (DialogFontEx)Marshal.PtrToStructure(buff, typeof(DialogFontEx));
if (BitConverter.ToInt16(DlgFont.FontName.Take(2).ToArray(), 0) != 0)
{
bItemData = bItemData.Skip(size - 2).ToArray();
var len = GetUnicodeStringLength(bItemData);
var szFontName = Encoding.Unicode.GetString(bItemData, 0, len);
Console.WriteLine("FontName:" + szFontName);
bItemData = bItemData.Skip(len).ToArray();
}
}
#endregion
#region ControlList
int isControl = 0;
bItemData = bItemData.Skip(4).ToArray();
for (int i = 0; i < DlgBoxHeader.DlgItems; i++)
{
ControlData ctlData = new ControlData();
size = Marshal.SizeOf(ctlData);
buff = Marshal.AllocHGlobal(size);
uint helpID = 0;
if (isDialogEx)
{
helpID = (uint)BitConverter.ToInt16(bItemData.Take(2).ToArray(), 0);
Marshal.Copy(bItemData.Skip(2).Take(size).ToArray(), 0, buff, size);
}
else
{
Marshal.Copy(bItemData.Take(size).ToArray(), 0, buff, size);
}
ctlData = (ControlData)Marshal.PtrToStructure(buff, typeof(ControlData));
Console.WriteLine("IDC_" + ctlData.id.ToString());
Console.WriteLine(ctlData.x.ToString() + "," + ctlData.y.ToString() + "," + ctlData.cx.ToString() + "," + ctlData.cy.ToString());
var Style = isDialogEx ? ctlData.ExStyle : ctlData.Style;
var ExStyle = isDialogEx ? ctlData.Style : ctlData.ExStyle;
byte[] bClassID = bItemData.Skip(size).ToArray(); //move to id in struct
if (isDialogEx)
{
bClassID = bClassID.Skip(2).ToArray();
}
uint NotStyle = 0;
#region ControlStyle
byte[] bCtlName = null;
if (BitConverter.ToInt16(bClassID.Take(2).ToArray(), 0) == -1)
{
switch (bClassID[2])
{
case 0x80:
switch (Style & 0xF)
{
case (uint)WindowStyles.BS_PUSHBUTTON:
Console.WriteLine("PUSHBUTTON");
NotStyle = (uint)(WindowStyles.BS_PUSHBUTTON | WindowStyles.WS_TABSTOP);
break;
case (uint)WindowStyles.BS_DEFPUSHBUTTON:
Console.WriteLine("DEFPUSHBUTTON");
NotStyle = (uint)(WindowStyles.BS_DEFPUSHBUTTON | WindowStyles.WS_TABSTOP);
break;
case (uint)WindowStyles.BS_CHECKBOX:
Console.WriteLine("CHECKBOX");
NotStyle = (uint)(WindowStyles.BS_CHECKBOX | WindowStyles.WS_TABSTOP);
break;
case (uint)WindowStyles.BS_AUTOCHECKBOX:
Console.WriteLine("AUTOCHECKBOX");
NotStyle = (uint)WindowStyles.BS_AUTOCHECKBOX;
break;
case (uint)WindowStyles.BS_RADIOBUTTON:
Console.WriteLine("RADIOBUTTON");
NotStyle = (uint)WindowStyles.BS_RADIOBUTTON;
break;
case (uint)WindowStyles.BS_3STATE:
Console.WriteLine("STATE3" + "\t");
NotStyle = (uint)WindowStyles.BS_3STATE;
break;
case (uint)WindowStyles.BS_AUTO3STATE:
Console.WriteLine("AUTO3STATE");
NotStyle = (uint)WindowStyles.BS_AUTO3STATE;
break;
case (uint)WindowStyles.BS_GROUPBOX:
Console.WriteLine("GROUPBOX");
NotStyle = (uint)WindowStyles.BS_GROUPBOX;
break;
case (uint)WindowStyles.BS_AUTORADIOBUTTON:
Console.WriteLine("AUTORADIOBUTTON");
NotStyle = (uint)WindowStyles.BS_AUTORADIOBUTTON;
break;
default:
Console.WriteLine("CONTROL" + "\t");
NotStyle = 0;
isControl = 1;
break;
}
break;
case 0x81:
Console.WriteLine("EDITTEXT");
NotStyle = (uint)(WindowStyles.ES_LEFT | WindowStyles.WS_BORDER | WindowStyles.WS_TABSTOP);
break;
case 0x82:
switch (Style & 0xF)
{
case (uint)WindowStyles.SS_LEFT:
Console.WriteLine("LTEXT" + "\t");
NotStyle = (uint)(WindowStyles.SS_LEFT | WindowStyles.WS_GROUP);
break;
case (uint)WindowStyles.SS_RIGHT:
Console.WriteLine("RTEXT" + "\t");
NotStyle = (uint)(WindowStyles.SS_RIGHT | WindowStyles.WS_GROUP);
break;
case (uint)WindowStyles.SS_CENTER:
Console.WriteLine("CTEXT" + "\t");
NotStyle = (uint)(WindowStyles.SS_CENTER | WindowStyles.WS_GROUP);
break;
case (uint)WindowStyles.SS_ICON:
Console.WriteLine("ICON" + "\t");
NotStyle = (uint)WindowStyles.SS_ICON;
break;
default:
Console.WriteLine("CONTROL" + "\t");
NotStyle = 0;
isControl = 2;
break;
}
break;
case 0x83:
Console.WriteLine("LISTBOX" + "\t");
NotStyle = (uint)(WindowStyles.WS_BORDER | WindowStyles.LBS_NOTIFY);
break;
case 0x84:
Console.WriteLine("SCROLLBAR");
NotStyle = 0;
break;
case 0x85:
Console.WriteLine("COMBOBOX");
NotStyle = 0;
break;
default:
Console.WriteLine("CONTROL" + "\t");
NotStyle = 0;
isControl = -2;
break;
}
bCtlName = bClassID.Skip(4).ToArray();
}
else
{
var len = GetUnicodeStringLength(bClassID);
var szCtlName = Encoding.Unicode.GetString(bClassID, 0, len);
Console.WriteLine("CtlName:" + szCtlName);
bCtlName = bClassID.Skip(len + 2).ToArray();
}
#endregion
NotStyle |= (uint)WindowStyles.WS_CHILD | (uint)WindowStyles.WS_VISIBLE;
Style &= ~NotStyle;
NotStyle &= ~(isDialogEx ? ctlData.ExStyle : ctlData.Style);
#region ControlName
byte[] bCtlId = null;
if (BitConverter.ToInt16(bCtlName.Take(2).ToArray(), 0) == -1)
{
bCtlId = bCtlName.Skip(6).ToArray();
}
else
{
if (isControl == 0 && (bClassID[1] == 0x81 || bClassID[1] == 0x83 || bClassID[1] == 0x84 || bClassID[1] == 0x85))
{
bCtlId = bCtlName.Skip(2).ToArray();
}
else
{
var len = GetUnicodeStringLength(bCtlName);
var szCtlId = Encoding.Unicode.GetString(bCtlName, 0, len);
Console.WriteLine("CtlId:" + szCtlId);
if (len > 2)
{
bCtlId = bCtlName.Skip(len + 4).ToArray();
}
else
{
bCtlId = bCtlName.Skip(2).ToArray();
}
}
}
#endregion
string[] pStyle = { "", "button", "static" };
if (isControl != 0)
{
if (isControl == -1)
{
Console.WriteLine(BitConverter.ToInt16(bCtlName.Take(2).ToArray(), 0).ToString());
}
else if (isControl > 0)
{
Console.WriteLine(pStyle[isControl]);
}
else
{
Console.WriteLine(bClassID[0].ToString());
}
if (Convert.ToInt32(Style) != 0 || NotStyle == 0)
{
Console.WriteLine("0x" + Style.ToString("x8"));
}
if (NotStyle != 0)
{
Console.WriteLine("0x" + NotStyle.ToString("x8"));
}
NotStyle = 0;
Style = NotStyle;
}
if (Style!=0 || NotStyle!=0 || ExStyle !=0 || (isDialogEx && helpID !=0))
{
if (Style != 0 || ((~NotStyle) != 0 && (~isControl) != 0))
{
Console.WriteLine("0x" + Style.ToString("x8"));
}
if (NotStyle != 0)
{
if (Style!=0)
{
Console.WriteLine(" |0x" + NotStyle.ToString("x8"));
}
else
{
Console.WriteLine(",0x" + NotStyle.ToString("x8"));
}
}
if (ExStyle != 0 || (isDialogEx && helpID != 0))
{
if (ExStyle == (uint)WindowExStyles.WS_EX_STATICEDGE)
{
Console.WriteLine(", WS_EX_STATICEDGE");
}
else
{
Console.WriteLine("0x" + ExStyle.ToString("x8"));
}
if (isDialogEx && helpID != 0)
{
Console.WriteLine(ctlData.id.ToString());
}
}
}
bItemData = bCtlId.Skip(2).ToArray();
if (isDialogEx)
{
bItemData = bItemData.Skip(2).ToArray();
}
}
#endregion
return bytesIn;
}
private static int GetUnicodeStringLength(byte[] byteIn)
{
int nullterm = 0;
while (nullterm < byteIn.Length && byteIn[nullterm] != 0)
{
nullterm += 2;
}
return nullterm;
}
public enum DialogBoxStyles
{
DS_SETFOREGROUND = 0x200,
DS_NOFAILCREATE = 0x10,
DS_CONTEXTHELP = 0x2000,
DS_CENTERMOUSE = 0x1000,
DS_MODALFRAME = 0x80,
DS_S_SUCCESS = 0,
DS_SHELLFONT = DS_SETFONT | DS_FIXEDSYS,
DS_NOIDLEMSG = 0x100,
DS_LOCALEDIT = 0x20,
DS_SYSMODAL = 0x2,
DS_FIXEDSYS = 0x8,
DS_ABSALIGN = 0x1,
DS_SETFONT = 0x40,
DS_CONTROL = 0x400,
DS_CENTER = 0x800,
DS_3DLOOK = 0x4
}
public enum WindowExStyles
{
WS_EX_DLGMODALFRAME = 0x1,
WS_EX_NOPARENTNOTIFY = 0x4,
WS_EX_TOPMOST = 0x8,
WS_EX_ACCEPTFILES = 0x10,
WS_EX_TRANSPARENT = 0x20,
WS_EX_MDICHILD = 0x40,
WS_EX_TOOLWINDOW = 0x80,
WS_EX_WINDOWEDGE = 0x100,
WS_EX_CLIENTEDGE = 0x200,
WS_EX_CONTEXTHELP = 0x400,
WS_EX_RIGHT = 0x1000,
WS_EX_LEFT = 0x0,
WS_EX_RTLREADING = 0x2000,
WS_EX_LTRREADING = 0x0,
WS_EX_LEFTSCROLLBAR = 0x4000,
WS_EX_RIGHTSCROLLBAR = 0x0,
WS_EX_CONTROLPARENT = 0x10000,
WS_EX_STATICEDGE = 0x20000,
WS_EX_APPWINDOW = 0x40000,
WS_EX_OVERLAPPEDWINDOW = (WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE),
WS_EX_PALETTEWINDOW = (WS_EX_WINDOWEDGE | WS_EX_TOOLWINDOW | WS_EX_TOPMOST),
WS_EX_LAYERED = 0x80000,
WS_EX_NOREDIRECTIONBITMAP = 0x200000,
WS_EX_NOINHERITLAYOUT = 0x100000,
WS_EX_NOACTIVATE = 0x8000000,
WS_EX_LAYOUTRTL = 0x400000,
WS_EX_COMPOSITED = 0x2000000
}
public enum WindowStyles : uint
{
WS_OVERLAPPED = 0x0,
WS_POPUP = 0x80000000U,
WS_CHILD = 0x40000000,
WS_MINIMIZE = 0x20000000,
WS_VISIBLE = 0x10000000,
WS_DISABLED = 0x8000000,
WS_CLIPSIBLINGS = 0x4000000,
WS_CLIPCHILDREN = 0x2000000,
WS_MAXIMIZE = 0x1000000,
WS_CAPTION = 0xC00000,
WS_BORDER = 0x800000,
WS_DLGFRAME = 0x400000,
WS_VSCROLL = 0x200000,
WS_HSCROLL = 0x100000,
WS_SYSMENU = 0x80000,
WS_THICKFRAME = 0x40000,
WS_GROUP = 0x20000,
WS_TABSTOP = 0x10000,
WS_MINIMIZEBOX = 0x20000,
WS_MAXIMIZEBOX = 0x10000,
WS_TILED = 0x0,
WS_ICONIC = 0x20000000,
WS_SIZEBOX = 0x40000,
WS_TILEDWINDOW = 0xCF0000,
WS_OVERLAPPEDWINDOW = (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX),
WS_POPUPWINDOW = (WS_POPUP | WS_BORDER | WS_SYSMENU),
WS_CHILDWINDOW = (WS_CHILD),
//
// * Edit Control Styles
//
ES_LEFT = 0x0,
ES_CENTER = 0x1,
ES_RIGHT = 0x2,
ES_MULTILINE = 0x4,
ES_UPPERCASE = 0x8,
ES_LOWERCASE = 0x10,
ES_PASSWORD = 0x20,
ES_AUTOVSCROLL = 0x40,
ES_AUTOHSCROLL = 0x80,
ES_NOHIDESEL = 0x100,
ES_OEMCONVERT = 0x400,
ES_READONLY = 0x800,
ES_WANTRETURN = 0x1000,
ES_NUMBER = 0x2000,
//
// * Button Control Styles
//
BS_PUSHBUTTON = 0x0,
BS_DEFPUSHBUTTON = 0x1,
BS_CHECKBOX = 0x2,
BS_AUTOCHECKBOX = 0x3,
BS_RADIOBUTTON = 0x4,
BS_3STATE = 0x5,
BS_AUTO3STATE = 0x6,
BS_GROUPBOX = 0x7,
BS_USERBUTTON = 0x8,
BS_AUTORADIOBUTTON = 0x9,
BS_PUSHBOX = 0xA,
BS_OWNERDRAW = 0xB,
BS_TYPEMASK = 0xF,
BS_LEFTTEXT = 0x20,
BS_TEXT = 0x0,
BS_ICON = 0x40,
BS_BITMAP = 0x80,
BS_LEFT = 0x100,
BS_RIGHT = 0x200,
BS_CENTER = 0x300,
BS_TOP = 0x400,
BS_BOTTOM = 0x800,
BS_VCENTER = 0xC00,
BS_PUSHLIKE = 0x1000,
BS_MULTILINE = 0x2000,
BS_NOTIFY = 0x4000,
BS_FLAT = 0x8000,
BS_RIGHTBUTTON = BS_LEFTTEXT,
//
// * Static Control Constants
//
SS_LEFT = 0x0,
SS_CENTER = 0x1,
SS_RIGHT = 0x2,
SS_ICON = 0x3,
SS_BLACKRECT = 0x4,
SS_GRAYRECT = 0x5,
SS_WHITERECT = 0x6,
SS_BLACKFRAME = 0x7,
SS_GRAYFRAME = 0x8,
SS_WHITEFRAME = 0x9,
SS_USERITEM = 0xA,
SS_SIMPLE = 0xB,
SS_LEFTNOWORDWRAP = 0xC,
SS_OWNERDRAW = 0xD,
SS_BITMAP = 0xE,
SS_ENHMETAFILE = 0xF,
SS_ETCHEDHORZ = 0x10,
SS_ETCHEDVERT = 0x11,
SS_ETCHEDFRAME = 0x12,
SS_TYPEMASK = 0x1F,
SS_REALSIZECONTROL = 0x40,
SS_NOPREFIX = 0x80,
SS_NOTIFY = 0x100,
SS_CENTERIMAGE = 0x200,
SS_RIGHTJUST = 0x400,
SS_REALSIZEIMAGE = 0x800,
SS_SUNKEN = 0x1000,
SS_EDITCONTROL = 0x2000,
SS_ENDELLIPSIS = 0x4000,
SS_PATHELLIPSIS = 0x8000,
SS_WORDELLIPSIS = 0xC000,
SS_ELLIPSISMASK = 0xC000,
// Dialog Styles
DS_ABSALIGN = 0x1,
DS_SYSMODAL = 0x2,
DS_LOCALEDIT = 0x20,
DS_SETFONT = 0x40,
DS_MODALFRAME = 0x80,
DS_NOIDLEMSG = 0x100,
DS_SETFOREGROUND = 0x200,
DS_3DLOOK = 0x4,
DS_FIXEDSYS = 0x8,
DS_NOFAILCREATE = 0x10,
DS_CONTROL = 0x400,
DS_CENTER = 0x800,
DS_CENTERMOUSE = 0x1000,
DS_CONTEXTHELP = 0x2000,
DS_SHELLFONT = (DS_SETFONT | DS_FIXEDSYS),
// Listbox Styles
LBS_NOTIFY = 0x1,
LBS_SORT = 0x2,
LBS_NOREDRAW = 0x4,
LBS_MULTIPLESEL = 0x8,
LBS_OWNERDRAWFIXED = 0x10,
LBS_OWNERDRAWVARIABLE = 0x20,
LBS_HASSTRINGS = 0x40,
LBS_USETABSTOPS = 0x80,
LBS_NOINTEGRALHEIGHT = 0x100,
LBS_MULTICOLUMN = 0x200,
LBS_WANTKEYBOARDINPUT = 0x400,
LBS_EXTENDEDSEL = 0x800,
LBS_DISABLENOSCROLL = 0x1000,
LBS_NODATA = 0x2000,
LBS_NOSEL = 0x4000,
LBS_COMBOBOX = 0x8000,
LBS_STANDARD = (LBS_NOTIFY | LBS_SORT | WS_VSCROLL | WS_BORDER),
// combobox styles
CBS_SIMPLE = 0x1,
CBS_DROPDOWN = 0x2,
CBS_DROPDOWNLIST = 0x3,
CBS_OWNERDRAWFIXED = 0x10,
CBS_OWNERDRAWVARIABLE = 0x20,
CBS_AUTOHSCROLL = 0x40,
CBS_OEMCONVERT = 0x80,
CBS_SORT = 0x100,
CBS_HASSTRINGS = 0x200,
CBS_NOINTEGRALHEIGHT = 0x400,
CBS_DISABLENOSCROLL = 0x800,
CBS_UPPERCASE = 0x2000,
CBS_LOWERCASE = 0x4000,
// Scroll Bar Styles
SBS_HORZ = 0x0,
SBS_VERT = 0x1,
SBS_TOPALIGN = 0x2,
SBS_LEFTALIGN = 0x2,
SBS_BOTTOMALIGN = 0x4,
SBS_RIGHTALIGN = 0x4,
SBS_SIZEBOXTOPLEFTALIGN = 0x2,
SBS_SIZEBOXBOTTOMRIGHTALIGN = 0x4,
SBS_SIZEBOX = 0x8,
SBS_SIZEGRIP = 0x10,
//treeview styles
TVS_HASBUTTONS = 0x1,
TVS_HASLINES = 0x2,
TVS_LINESATROOT = 0x4,
TVS_EDITLABELS = 0x8,
TVS_DISABLEDRAGDROP = 0x10,
TVS_SHOWSELALWAYS = 0x20,
TVS_RTLREADING = 0x40,
TVS_NOTOOLTIPS = 0x80,
TVS_CHECKBOXES = 0x100,
TVS_TRACKSELECT = 0x200,
TVS_SINGLEEXPAND = 0x400,
TVS_INFOTIP = 0x800,
TVS_FULLROWSELECT = 0x1000,
TVS_NOSCROLL = 0x2000,
TVS_NONEVENHEIGHT = 0x4000,
TVS_NOHSCROLL = 0x8000,
//tab control styles
TCS_SCROLLOPPOSITE = 0x1,
TCS_BOTTOM = 0x2,
TCS_RIGHT = 0x2,
TCS_MULTISELECT = 0x4,
TCS_FLATBUTTONS = 0x8,
TCS_FORCEICONLEFT = 0x10,
TCS_FORCELABELLEFT = 0x20,
TCS_HOTTRACK = 0x40,
TCS_VERTICAL = 0x80,
TCS_TABS = 0x0,
TCS_BUTTONS = 0x100,
TCS_SINGLELINE = 0x0,
TCS_MULTILINE = 0x200,
TCS_RIGHTJUSTIFY = 0x0,
TCS_FIXEDWIDTH = 0x400,
TCS_RAGGEDRIGHT = 0x800,
TCS_FOCUSONBUTTONDOWN = 0x1000,
TCS_OWNERDRAWFIXED = 0x2000,
TCS_TOOLTIPS = 0x4000,
TCS_FOCUSNEVER = 0x8000,
//spin styles
UDS_WRAP = 0x1,
UDS_SETBUDDYINT = 0x2,
UDS_ALIGNRIGHT = 0x4,
UDS_ALIGNLEFT = 0x8,
UDS_AUTOBUDDY = 0x10,
UDS_ARROWKEYS = 0x20,
UDS_HORZ = 0x40,
UDS_NOTHOUSANDS = 0x80,
UDS_HOTTRACK = 0x100,
//progress styles
PBS_SMOOTH = 0x1,
PBS_VERTICAL = 0x4,
//list view styles
LVS_ICON = 0x0,
LVS_REPORT = 0x1,
LVS_SMALLICON = 0x2,
LVS_LIST = 0x3,
LVS_TYPEMASK = 0x3,
LVS_SINGLESEL = 0x4,
LVS_SHOWSELALWAYS = 0x8,
LVS_SORTASCENDING = 0x10,
LVS_SORTDESCENDING = 0x20,
LVS_SHAREIMAGELISTS = 0x40,
LVS_NOLABELWRAP = 0x80,
LVS_AUTOARRANGE = 0x100,
LVS_EDITLABELS = 0x200,
LVS_OWNERDATA = 0x1000,
LVS_NOSCROLL = 0x2000,
LVS_TYPESTYLEMASK = 0xFC00,
LVS_ALIGNTOP = 0x0,
LVS_ALIGNLEFT = 0x800,
LVS_ALIGNMASK = 0xC00,
LVS_OWNERDRAWFIXED = 0x400,
LVS_NOCOLUMNHEADER = 0x4000,
LVS_NOSORTHEADER = 0x8000,
ACS_CENTER = 0x1,
ACS_TRANSPARENT = 0x2,
ACS_AUTOPLAY = 0x4,
ACS_TIMER = 0x8
}
}
} |
Maybe I am missing something, but that code doesn't do any writing / updating of the resource directory, only parsing? Reconstructing the resources directory of this particular PE file (notepad.exe.mui) works fine for me as well using the code below. It must mean the code you use to edit the contents of that particular resource is not conforming to the format of an Bare minimum example code for reconstructing the resources directory// Read raw PE file.
var file = PEFile.FromFile("/tmp/notepad.exe.mui");
var image = PEImage.FromFile(file);
/* ... Do something here with image.Resources ... */
// Reconstruct rsrc section.
var rsrc = file.Sections.First(s => s.Name == ".rsrc");
var contents = new ResourceDirectoryBuffer();
contents.AddDirectory(image.Resources!);
rsrc.Contents = contents;
// Update optional header.
file.AlignSections();
file.OptionalHeader.DataDirectories[(int) DataDirectoryIndex.ResourceDirectory]
= new DataDirectory(contents.DataEntryTable.Rva, contents.DataEntryTable.GetPhysicalSize());
// Save
file.Write("/tmp/notepad2.exe.mui"); Remember that AsmResolver does not have rich support for these types of resources in the Win32Resources package (#66), and as such it does not do any verification on the data you construct. If you are editing a resource file, then you are currently responsible for (re)constructing it correctly. |
The notepad.exe.mui sample, I change byte[] bytesWrite = content.Take(index - 1).ToArray().Concat(content.Skip(index - 1 + byteSearch.Length).Take(content.Length - index - byteSearch.Length + 1).ToArray()).ToArray();
using (var stream = new MemoryStream())
{
var writer = new BinaryStreamWriter(stream);
writer.WriteUInt16((ushort)bytesWrite.Length);
writer.WriteBytes(bytesWrite);
writer.Align(4);
dataEntry.Contents = new AsmResolver.DataSegment(stream.ToArray());
var rsrc = file.Sections.First(s => s.Name == ".rsrc");
var newContents = new ResourceDirectoryBuffer();
newContents.AddDirectory(image.Resources);
rsrc.Contents = newContents;
file.AlignSections();
file.OptionalHeader.DataDirectories[(int)DataDirectoryIndex.ResourceDirectory] = new DataDirectory(newContents.DirectoryTable.Rva, newContents.DirectoryTable.GetPhysicalSize());
file.Write(output);
} to byte[] bytesWrite = content.Take(index - 1).ToArray().Concat(content.Skip(index - 1 + byteSearch.Length).Take(content.Length - index - byteSearch.Length + 1).ToArray()).ToArray();
dataEntry.Contents = new AsmResolver.DataSegment(bytesWrite);
var rsrc = file.Sections.First(s => s.Name == ".rsrc");
var newContents = new ResourceDirectoryBuffer();
newContents.AddDirectory(image.Resources!);
rsrc.Contents = newContents;
file.AlignSections();
file.OptionalHeader.DataDirectories[(int)DataDirectoryIndex.ResourceDirectory] = new DataDirectory(newContents.DirectoryTable.Rva, newContents.DirectoryTable.GetPhysicalSize());
file.Write(output); It update successful。 |
I am not sure what this statement means. Does it mean that it has solved your problem? If so, can I close the issue? If not, can you clarify what you mean by this? Remember that reconstructing a PE file without applying any changes does not always mean the exact same file will be produced. AsmResolver will (re)do some calculations of offsets as it lays out the sections. It is not guaranteed to follow the exact same linkage as the original compiler has done for the original program. |
yes, you can close the issue. |
Perfect! Glad you got it working! |
I want to try to use AsmResolver library to update dialog controls, I took C:\Windows\en-US\notepad.exe.mui as an experiment
pic1
I want try to delete help button in dialog form.
pic2
After comparing using tools, I found three differences
pic3
Below is the code:
code
After updated, However, garbled characters appear, and the dialog box cannot be opened completely.Don't know where the problem is.
error
The text was updated successfully, but these errors were encountered: