From 5185349acefdc8df04736395a8fb83fcdecae81d Mon Sep 17 00:00:00 2001 From: wj32 Date: Thu, 20 Nov 2008 07:48:35 +0000 Subject: [PATCH] can now read exports! PE Window updated with lots of info git-svn-id: svn://svn.code.sf.net/p/processhacker/code@78 21ef857c-d57f-4fe0-8362-d861dc6d29cd --- trunk/ProcessHacker/Forms/HackerWindow.cs | 10 +- .../ProcessHacker/Forms/PEWindow.Designer.cs | 331 +++++++++++++++++- trunk/ProcessHacker/Forms/PEWindow.cs | 174 +++++++++ trunk/ProcessHacker/Forms/PEWindow.resx | 23 ++ trunk/ProcessHacker/Forms/ProcessGroups.cs | 5 +- .../ProcessHacker/Forms/ProcessPrivileges.cs | 2 + trunk/ProcessHacker/Forms/ResultsWindow.cs | 7 +- trunk/ProcessHacker/Misc/Misc.cs | 274 ++++++++++++++- trunk/ProcessHacker/Misc/Utils.cs | 264 -------------- trunk/ProcessHacker/PE/ExportData.cs | 51 ++- trunk/ProcessHacker/PE/PEFile.cs | 25 +- trunk/ProcessHacker/ProcessHacker.csproj | 1 - 12 files changed, 875 insertions(+), 292 deletions(-) delete mode 100644 trunk/ProcessHacker/Misc/Utils.cs diff --git a/trunk/ProcessHacker/Forms/HackerWindow.cs b/trunk/ProcessHacker/Forms/HackerWindow.cs index 7441840a4..8583dbbfc 100644 --- a/trunk/ProcessHacker/Forms/HackerWindow.cs +++ b/trunk/ProcessHacker/Forms/HackerWindow.cs @@ -2089,13 +2089,9 @@ namespace ProcessHacker { InitializeComponent(); - PropertyInfo property = typeof(ListView).GetProperty("DoubleBuffered", - BindingFlags.NonPublic | BindingFlags.Instance); - - property.SetValue(listMemory, true, null); - property.SetValue(listModules, true, null); - typeof(TreeView).GetProperty("DoubleBuffered", BindingFlags.NonPublic | BindingFlags.Instance).SetValue( - treeMisc, true, null); + Misc.SetDoubleBuffered(listMemory, typeof(ListView), true); + Misc.SetDoubleBuffered(listModules, typeof(ListView), true); + Misc.SetDoubleBuffered(treeMisc, typeof(TreeView), true); if (Win32.WriteTokenPrivilege("SeDebugPrivilege", Win32.SE_PRIVILEGE_ATTRIBUTES.SE_PRIVILEGE_ENABLED) == 0) MessageBox.Show("Debug privilege could not be acquired!" + diff --git a/trunk/ProcessHacker/Forms/PEWindow.Designer.cs b/trunk/ProcessHacker/Forms/PEWindow.Designer.cs index 88de4e4a9..211ff7403 100644 --- a/trunk/ProcessHacker/Forms/PEWindow.Designer.cs +++ b/trunk/ProcessHacker/Forms/PEWindow.Designer.cs @@ -17,6 +17,10 @@ { components.Dispose(); } + + Program.PEWindows.Remove(Id); + Program.UpdateWindows(); + base.Dispose(disposing); } @@ -32,8 +36,43 @@ System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(PEWindow)); this.mainMenu = new System.Windows.Forms.MainMenu(this.components); this.windowMenuItem = new System.Windows.Forms.MenuItem(); + this.tabControl = new System.Windows.Forms.TabControl(); + this.tabCOFFHeader = new System.Windows.Forms.TabPage(); + this.tabCOFFOptionalHeader = new System.Windows.Forms.TabPage(); + this.tabSections = new System.Windows.Forms.TabPage(); + this.tabExports = new System.Windows.Forms.TabPage(); + this.tabImports = new System.Windows.Forms.TabPage(); + this.listExports = new System.Windows.Forms.ListView(); + this.columnExportName = new System.Windows.Forms.ColumnHeader(); + this.columnExportOrdinal = new System.Windows.Forms.ColumnHeader(); + this.columnExportRVA = new System.Windows.Forms.ColumnHeader(); + this.columnExportFileAddress = new System.Windows.Forms.ColumnHeader(); + this.imageList = new System.Windows.Forms.ImageList(this.components); + this.listCOFFHeader = new System.Windows.Forms.ListView(); + this.columnCHName = new System.Windows.Forms.ColumnHeader(); + this.columnCHValue = new System.Windows.Forms.ColumnHeader(); + this.listCOFFOptionalHeader = new System.Windows.Forms.ListView(); + this.columnCOHName = new System.Windows.Forms.ColumnHeader(); + this.columnCOHValue = new System.Windows.Forms.ColumnHeader(); + this.listSections = new System.Windows.Forms.ListView(); + this.columnSectionName = new System.Windows.Forms.ColumnHeader(); + this.columnSectionVA = new System.Windows.Forms.ColumnHeader(); + this.columnSectionFileAddress = new System.Windows.Forms.ColumnHeader(); + this.columnSectionCharacteristics = new System.Windows.Forms.ColumnHeader(); + this.columnSectionVS = new System.Windows.Forms.ColumnHeader(); this.vistaMenu = new wyDay.Controls.VistaMenu(this.components); + this.tabImageData = new System.Windows.Forms.TabPage(); + this.listImageData = new System.Windows.Forms.ListView(); + this.columnIDName = new System.Windows.Forms.ColumnHeader(); + this.columnIDRVA = new System.Windows.Forms.ColumnHeader(); + this.columnIDSize = new System.Windows.Forms.ColumnHeader(); + this.tabControl.SuspendLayout(); + this.tabCOFFHeader.SuspendLayout(); + this.tabCOFFOptionalHeader.SuspendLayout(); + this.tabSections.SuspendLayout(); + this.tabExports.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.vistaMenu)).BeginInit(); + this.tabImageData.SuspendLayout(); this.SuspendLayout(); // // mainMenu @@ -46,21 +85,282 @@ this.windowMenuItem.Index = 0; this.windowMenuItem.Text = "&Window"; // + // tabControl + // + this.tabControl.Controls.Add(this.tabCOFFHeader); + this.tabControl.Controls.Add(this.tabCOFFOptionalHeader); + this.tabControl.Controls.Add(this.tabImageData); + this.tabControl.Controls.Add(this.tabSections); + this.tabControl.Controls.Add(this.tabExports); + this.tabControl.Controls.Add(this.tabImports); + this.tabControl.Dock = System.Windows.Forms.DockStyle.Fill; + this.tabControl.Location = new System.Drawing.Point(0, 0); + this.tabControl.Name = "tabControl"; + this.tabControl.SelectedIndex = 0; + this.tabControl.Size = new System.Drawing.Size(423, 429); + this.tabControl.TabIndex = 0; + // + // tabCOFFHeader + // + this.tabCOFFHeader.Controls.Add(this.listCOFFHeader); + this.tabCOFFHeader.Location = new System.Drawing.Point(4, 22); + this.tabCOFFHeader.Name = "tabCOFFHeader"; + this.tabCOFFHeader.Padding = new System.Windows.Forms.Padding(3); + this.tabCOFFHeader.Size = new System.Drawing.Size(415, 403); + this.tabCOFFHeader.TabIndex = 0; + this.tabCOFFHeader.Text = "COFF Header"; + this.tabCOFFHeader.UseVisualStyleBackColor = true; + // + // tabCOFFOptionalHeader + // + this.tabCOFFOptionalHeader.Controls.Add(this.listCOFFOptionalHeader); + this.tabCOFFOptionalHeader.Location = new System.Drawing.Point(4, 22); + this.tabCOFFOptionalHeader.Name = "tabCOFFOptionalHeader"; + this.tabCOFFOptionalHeader.Padding = new System.Windows.Forms.Padding(3); + this.tabCOFFOptionalHeader.Size = new System.Drawing.Size(415, 403); + this.tabCOFFOptionalHeader.TabIndex = 1; + this.tabCOFFOptionalHeader.Text = "COFF Optional Header"; + this.tabCOFFOptionalHeader.UseVisualStyleBackColor = true; + // + // tabSections + // + this.tabSections.Controls.Add(this.listSections); + this.tabSections.Location = new System.Drawing.Point(4, 22); + this.tabSections.Name = "tabSections"; + this.tabSections.Size = new System.Drawing.Size(415, 403); + this.tabSections.TabIndex = 2; + this.tabSections.Text = "Sections"; + this.tabSections.UseVisualStyleBackColor = true; + // + // tabExports + // + this.tabExports.Controls.Add(this.listExports); + this.tabExports.Location = new System.Drawing.Point(4, 22); + this.tabExports.Name = "tabExports"; + this.tabExports.Padding = new System.Windows.Forms.Padding(3); + this.tabExports.Size = new System.Drawing.Size(415, 403); + this.tabExports.TabIndex = 3; + this.tabExports.Text = "Exports"; + this.tabExports.UseVisualStyleBackColor = true; + // + // tabImports + // + this.tabImports.Location = new System.Drawing.Point(4, 22); + this.tabImports.Name = "tabImports"; + this.tabImports.Size = new System.Drawing.Size(415, 403); + this.tabImports.TabIndex = 4; + this.tabImports.Text = "Imports"; + this.tabImports.UseVisualStyleBackColor = true; + // + // listExports + // + this.listExports.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { + this.columnExportName, + this.columnExportOrdinal, + this.columnExportRVA, + this.columnExportFileAddress}); + this.listExports.Dock = System.Windows.Forms.DockStyle.Fill; + this.listExports.FullRowSelect = true; + this.listExports.HideSelection = false; + this.listExports.Location = new System.Drawing.Point(3, 3); + this.listExports.Name = "listExports"; + this.listExports.ShowItemToolTips = true; + this.listExports.Size = new System.Drawing.Size(409, 397); + this.listExports.SmallImageList = this.imageList; + this.listExports.Sorting = System.Windows.Forms.SortOrder.Ascending; + this.listExports.TabIndex = 0; + this.listExports.UseCompatibleStateImageBehavior = false; + this.listExports.View = System.Windows.Forms.View.Details; + this.listExports.VirtualMode = true; + this.listExports.RetrieveVirtualItem += new System.Windows.Forms.RetrieveVirtualItemEventHandler(this.listExports_RetrieveVirtualItem); + // + // columnExportName + // + this.columnExportName.Text = "Name"; + this.columnExportName.Width = 120; + // + // columnExportOrdinal + // + this.columnExportOrdinal.Text = "Ordinal"; + // + // columnExportRVA + // + this.columnExportRVA.Text = "RVA"; + this.columnExportRVA.Width = 80; + // + // columnExportFileAddress + // + this.columnExportFileAddress.Text = "File Address"; + this.columnExportFileAddress.Width = 80; + // + // imageList + // + this.imageList.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("imageList.ImageStream"))); + this.imageList.TransparentColor = System.Drawing.Color.Transparent; + this.imageList.Images.SetKeyName(0, "forwarder"); + // + // listCOFFHeader + // + this.listCOFFHeader.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { + this.columnCHName, + this.columnCHValue}); + this.listCOFFHeader.Dock = System.Windows.Forms.DockStyle.Fill; + this.listCOFFHeader.FullRowSelect = true; + this.listCOFFHeader.HideSelection = false; + this.listCOFFHeader.Location = new System.Drawing.Point(3, 3); + this.listCOFFHeader.Name = "listCOFFHeader"; + this.listCOFFHeader.ShowItemToolTips = true; + this.listCOFFHeader.Size = new System.Drawing.Size(409, 397); + this.listCOFFHeader.Sorting = System.Windows.Forms.SortOrder.Ascending; + this.listCOFFHeader.TabIndex = 0; + this.listCOFFHeader.UseCompatibleStateImageBehavior = false; + this.listCOFFHeader.View = System.Windows.Forms.View.Details; + // + // columnCHName + // + this.columnCHName.Text = "Name"; + this.columnCHName.Width = 160; + // + // columnCHValue + // + this.columnCHValue.Text = "Value"; + this.columnCHValue.Width = 200; + // + // listCOFFOptionalHeader + // + this.listCOFFOptionalHeader.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { + this.columnCOHName, + this.columnCOHValue}); + this.listCOFFOptionalHeader.Dock = System.Windows.Forms.DockStyle.Fill; + this.listCOFFOptionalHeader.FullRowSelect = true; + this.listCOFFOptionalHeader.HideSelection = false; + this.listCOFFOptionalHeader.Location = new System.Drawing.Point(3, 3); + this.listCOFFOptionalHeader.Name = "listCOFFOptionalHeader"; + this.listCOFFOptionalHeader.ShowItemToolTips = true; + this.listCOFFOptionalHeader.Size = new System.Drawing.Size(409, 397); + this.listCOFFOptionalHeader.Sorting = System.Windows.Forms.SortOrder.Ascending; + this.listCOFFOptionalHeader.TabIndex = 1; + this.listCOFFOptionalHeader.UseCompatibleStateImageBehavior = false; + this.listCOFFOptionalHeader.View = System.Windows.Forms.View.Details; + // + // columnCOHName + // + this.columnCOHName.Text = "Name"; + this.columnCOHName.Width = 160; + // + // columnCOHValue + // + this.columnCOHValue.Text = "Value"; + this.columnCOHValue.Width = 200; + // + // listSections + // + this.listSections.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { + this.columnSectionName, + this.columnSectionVA, + this.columnSectionVS, + this.columnSectionFileAddress, + this.columnSectionCharacteristics}); + this.listSections.Dock = System.Windows.Forms.DockStyle.Fill; + this.listSections.FullRowSelect = true; + this.listSections.HideSelection = false; + this.listSections.Location = new System.Drawing.Point(0, 0); + this.listSections.Name = "listSections"; + this.listSections.ShowItemToolTips = true; + this.listSections.Size = new System.Drawing.Size(415, 403); + this.listSections.TabIndex = 1; + this.listSections.UseCompatibleStateImageBehavior = false; + this.listSections.View = System.Windows.Forms.View.Details; + // + // columnSectionName + // + this.columnSectionName.Text = "Name"; + this.columnSectionName.Width = 70; + // + // columnSectionVA + // + this.columnSectionVA.Text = "Virtual Address"; + this.columnSectionVA.Width = 80; + // + // columnSectionFileAddress + // + this.columnSectionFileAddress.Text = "File Address"; + this.columnSectionFileAddress.Width = 80; + // + // columnSectionCharacteristics + // + this.columnSectionCharacteristics.Text = "Characteristics"; + this.columnSectionCharacteristics.Width = 100; + // + // columnSectionVS + // + this.columnSectionVS.Text = "Virtual Size"; + // // vistaMenu // this.vistaMenu.ContainerControl = this; // + // tabImageData + // + this.tabImageData.Controls.Add(this.listImageData); + this.tabImageData.Location = new System.Drawing.Point(4, 22); + this.tabImageData.Name = "tabImageData"; + this.tabImageData.Size = new System.Drawing.Size(415, 403); + this.tabImageData.TabIndex = 5; + this.tabImageData.Text = "Image Data"; + this.tabImageData.UseVisualStyleBackColor = true; + // + // listImageData + // + this.listImageData.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { + this.columnIDName, + this.columnIDRVA, + this.columnIDSize}); + this.listImageData.Dock = System.Windows.Forms.DockStyle.Fill; + this.listImageData.FullRowSelect = true; + this.listImageData.HideSelection = false; + this.listImageData.Location = new System.Drawing.Point(0, 0); + this.listImageData.Name = "listImageData"; + this.listImageData.ShowItemToolTips = true; + this.listImageData.Size = new System.Drawing.Size(415, 403); + this.listImageData.TabIndex = 2; + this.listImageData.UseCompatibleStateImageBehavior = false; + this.listImageData.View = System.Windows.Forms.View.Details; + // + // columnIDName + // + this.columnIDName.Text = "Name"; + this.columnIDName.Width = 120; + // + // columnIDRVA + // + this.columnIDRVA.Text = "RVA"; + this.columnIDRVA.Width = 100; + // + // columnIDSize + // + this.columnIDSize.Text = "Size"; + this.columnIDSize.Width = 100; + // // PEWindow // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(360, 388); + this.ClientSize = new System.Drawing.Size(423, 429); + this.Controls.Add(this.tabControl); this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.SizableToolWindow; this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); this.Menu = this.mainMenu; this.Name = "PEWindow"; this.Text = "PE File"; + this.Load += new System.EventHandler(this.PEWindow_Load); + this.tabControl.ResumeLayout(false); + this.tabCOFFHeader.ResumeLayout(false); + this.tabCOFFOptionalHeader.ResumeLayout(false); + this.tabSections.ResumeLayout(false); + this.tabExports.ResumeLayout(false); ((System.ComponentModel.ISupportInitialize)(this.vistaMenu)).EndInit(); + this.tabImageData.ResumeLayout(false); this.ResumeLayout(false); } @@ -70,5 +370,34 @@ private System.Windows.Forms.MainMenu mainMenu; private System.Windows.Forms.MenuItem windowMenuItem; private wyDay.Controls.VistaMenu vistaMenu; + private System.Windows.Forms.TabControl tabControl; + private System.Windows.Forms.TabPage tabCOFFHeader; + private System.Windows.Forms.TabPage tabCOFFOptionalHeader; + private System.Windows.Forms.TabPage tabSections; + private System.Windows.Forms.TabPage tabExports; + private System.Windows.Forms.TabPage tabImports; + private System.Windows.Forms.ListView listExports; + private System.Windows.Forms.ColumnHeader columnExportName; + private System.Windows.Forms.ColumnHeader columnExportOrdinal; + private System.Windows.Forms.ColumnHeader columnExportRVA; + private System.Windows.Forms.ColumnHeader columnExportFileAddress; + private System.Windows.Forms.ImageList imageList; + private System.Windows.Forms.ListView listCOFFHeader; + private System.Windows.Forms.ColumnHeader columnCHName; + private System.Windows.Forms.ColumnHeader columnCHValue; + private System.Windows.Forms.ListView listCOFFOptionalHeader; + private System.Windows.Forms.ColumnHeader columnCOHName; + private System.Windows.Forms.ColumnHeader columnCOHValue; + private System.Windows.Forms.ListView listSections; + private System.Windows.Forms.ColumnHeader columnSectionName; + private System.Windows.Forms.ColumnHeader columnSectionVA; + private System.Windows.Forms.ColumnHeader columnSectionFileAddress; + private System.Windows.Forms.ColumnHeader columnSectionCharacteristics; + private System.Windows.Forms.ColumnHeader columnSectionVS; + private System.Windows.Forms.TabPage tabImageData; + private System.Windows.Forms.ListView listImageData; + private System.Windows.Forms.ColumnHeader columnIDName; + private System.Windows.Forms.ColumnHeader columnIDRVA; + private System.Windows.Forms.ColumnHeader columnIDSize; } } \ No newline at end of file diff --git a/trunk/ProcessHacker/Forms/PEWindow.cs b/trunk/ProcessHacker/Forms/PEWindow.cs index 0318265c2..9bcd51595 100644 --- a/trunk/ProcessHacker/Forms/PEWindow.cs +++ b/trunk/ProcessHacker/Forms/PEWindow.cs @@ -18,7 +18,21 @@ namespace ProcessHacker { InitializeComponent(); + Misc.SetDoubleBuffered(listExports, typeof(ListView), true); + listExports.ContextMenu = ListViewMenu.GetMenu(listExports); + Misc.SetDoubleBuffered(listCOFFHeader, typeof(ListView), true); + listCOFFHeader.ContextMenu = ListViewMenu.GetMenu(listCOFFHeader); + Misc.SetDoubleBuffered(listCOFFOptionalHeader, typeof(ListView), true); + listCOFFOptionalHeader.ContextMenu = ListViewMenu.GetMenu(listCOFFOptionalHeader); + Misc.SetDoubleBuffered(listImageData, typeof(ListView), true); + listImageData.ContextMenu = ListViewMenu.GetMenu(listImageData); + Misc.SetDoubleBuffered(listSections, typeof(ListView), true); + listSections.ContextMenu = ListViewMenu.GetMenu(listSections); + _path = path; + this.Text = "PE File - " + path; + + Program.PEWindows.Add(Id, this); if (!this.Read(path)) { @@ -26,6 +40,11 @@ namespace ProcessHacker } } + private void PEWindow_Load(object sender, EventArgs e) + { + Program.UpdateWindows(); + } + public string Id { get { return _path; } @@ -59,7 +78,162 @@ namespace ProcessHacker _peFile = peFile; + // preprare lists + listExports.VirtualListSize = _peFile.ExportData.ExportOrdinalTable.Count; + + #region COFF Header + + // COFF header + listCOFFHeader.Items.Clear(); + listCOFFHeader.Items.Add(new ListViewItem(new string[] { "Target Machine", + _peFile.COFFHeader.Machine.ToString() })); + listCOFFHeader.Items.Add(new ListViewItem(new string[] { "Number of Sections", + _peFile.COFFHeader.NumberOfSections.ToString() })); + listCOFFHeader.Items.Add(new ListViewItem(new string[] { "Time/Date Stamp", + Misc.DateTimeFromUnixTime(_peFile.COFFHeader.TimeDateStamp).ToString() })); + listCOFFHeader.Items.Add(new ListViewItem(new string[] { "Pointer to Symbol Table", + "0x" + _peFile.COFFHeader.PointerToSymbolTable.ToString("x8") })); + listCOFFHeader.Items.Add(new ListViewItem(new string[] { "Number of Symbols", + _peFile.COFFHeader.NumberOfSymbols.ToString() })); + listCOFFHeader.Items.Add(new ListViewItem(new string[] { "Size of Optional Header", + _peFile.COFFHeader.SizeOfOptionalHeader.ToString() })); + listCOFFHeader.Items.Add(new ListViewItem(new string[] { "Characteristics", + Misc.FlagsToString(typeof(ImageCharacteristics), (long)_peFile.COFFHeader.Characteristics) })); + + #endregion + + #region COFF Optional Header + + // COFF optional header + listCOFFOptionalHeader.Items.Clear(); + listCOFFOptionalHeader.Items.Add(new ListViewItem(new string[] { "Magic", + _peFile.COFFOptionalHeader.Magic == COFFOptionalHeader.PE32Magic ? "PE32 (0x10b)" : + (_peFile.COFFOptionalHeader.Magic == COFFOptionalHeader.PE32PlusMagic ? "PE32+ (0x20b)" : + "Unknown (0x" + _peFile.COFFOptionalHeader.Magic.ToString("x") + ")") })); + listCOFFOptionalHeader.Items.Add(new ListViewItem(new string[] { "Linker Version", + _peFile.COFFOptionalHeader.MajorLinkerVersion.ToString() + "." + + _peFile.COFFOptionalHeader.MinorLinkerVersion.ToString() })); + listCOFFOptionalHeader.Items.Add(new ListViewItem(new string[] { "Size of Code", + "0x" + _peFile.COFFOptionalHeader.SizeOfCode.ToString("x") })); + listCOFFOptionalHeader.Items.Add(new ListViewItem(new string[] { "Size of Initialized Data", + "0x" + _peFile.COFFOptionalHeader.SizeOfInitializedData.ToString("x") })); + listCOFFOptionalHeader.Items.Add(new ListViewItem(new string[] { "Size of Uninitialized Data", + "0x" + _peFile.COFFOptionalHeader.SizeOfUninitializedData.ToString("x") })); + listCOFFOptionalHeader.Items.Add(new ListViewItem(new string[] { "Entry Point RVA", + "0x" + _peFile.COFFOptionalHeader.AddressOfEntryPoint.ToString("x8") })); + listCOFFOptionalHeader.Items.Add(new ListViewItem(new string[] { "Base of Code", + "0x" + _peFile.COFFOptionalHeader.BaseOfCode.ToString("x8") })); + if (_peFile.COFFOptionalHeader.Magic == COFFOptionalHeader.PE32PlusMagic) + listCOFFOptionalHeader.Items.Add(new ListViewItem(new string[] { "Base of Data", + "0x" + _peFile.COFFOptionalHeader.BaseOfData.ToString("x8") })); + listCOFFOptionalHeader.Items.Add(new ListViewItem(new string[] { "Preferred Image Base", + "0x" + _peFile.COFFOptionalHeader.ImageBase.ToString("x8") })); + listCOFFOptionalHeader.Items.Add(new ListViewItem(new string[] { "Section Alignment", + _peFile.COFFOptionalHeader.SectionAlignment.ToString() })); + listCOFFOptionalHeader.Items.Add(new ListViewItem(new string[] { "File Alignment", + _peFile.COFFOptionalHeader.FileAlignment.ToString() })); + listCOFFOptionalHeader.Items.Add(new ListViewItem(new string[] { "Operating System Version", + _peFile.COFFOptionalHeader.MajorOperatingSystemVersion.ToString() + "." + + _peFile.COFFOptionalHeader.MinorOperatingSystemVersion.ToString() })); + listCOFFOptionalHeader.Items.Add(new ListViewItem(new string[] { "Image Version", + _peFile.COFFOptionalHeader.MajorImageVersion.ToString() + "." + + _peFile.COFFOptionalHeader.MinorImageVersion.ToString() })); + listCOFFOptionalHeader.Items.Add(new ListViewItem(new string[] { "Subsystem Version", + _peFile.COFFOptionalHeader.MajorSubsystemVersion.ToString() + "." + + _peFile.COFFOptionalHeader.MinorSubsystemVersion.ToString() })); + listCOFFOptionalHeader.Items.Add(new ListViewItem(new string[] { "Size of Image", + "0x" + _peFile.COFFOptionalHeader.SizeOfImage.ToString("x") })); + listCOFFOptionalHeader.Items.Add(new ListViewItem(new string[] { "Size of Headers", + "0x" + _peFile.COFFOptionalHeader.SizeOfHeaders.ToString("x") })); + listCOFFOptionalHeader.Items.Add(new ListViewItem(new string[] { "Checksum", + "0x" + _peFile.COFFOptionalHeader.CheckSum.ToString("x8") })); + listCOFFOptionalHeader.Items.Add(new ListViewItem(new string[] { "Subsystem", + _peFile.COFFOptionalHeader.Subsystem.ToString() })); + listCOFFOptionalHeader.Items.Add(new ListViewItem(new string[] { "DLL Characteristics", + Misc.FlagsToString(typeof(DllCharacteristics), (long)_peFile.COFFOptionalHeader.DllCharacteristics) })); + listCOFFOptionalHeader.Items.Add(new ListViewItem(new string[] { "Size of Stack Reserve", + "0x" + _peFile.COFFOptionalHeader.SizeOfStackReserve.ToString("x") })); + listCOFFOptionalHeader.Items.Add(new ListViewItem(new string[] { "Size of Stack Commit", + "0x" + _peFile.COFFOptionalHeader.SizeOfStackCommit.ToString("x") })); + listCOFFOptionalHeader.Items.Add(new ListViewItem(new string[] { "Size of Heap Reserve", + "0x" + _peFile.COFFOptionalHeader.SizeOfHeapReserve.ToString("x") })); + listCOFFOptionalHeader.Items.Add(new ListViewItem(new string[] { "Size of Heap Commit", + "0x" + _peFile.COFFOptionalHeader.SizeOfHeapCommit.ToString("x") })); + listCOFFOptionalHeader.Items.Add(new ListViewItem(new string[] { "Number of Data Directory Entries", + _peFile.COFFOptionalHeader.NumberOfRvaAndSizes.ToString() })); + + #endregion + + #region Image Data + + listImageData.Items.Clear(); + + for (int i = 0; i < _peFile.ImageData.Count; i++) + { + ImageDataType type = (ImageDataType)i; + ImageData data = _peFile.ImageData[type]; + + if (data.VirtualAddress != 0) + { + ListViewItem item = new ListViewItem(); + + item.Text = type.ToString(); + item.SubItems.Add(new ListViewItem.ListViewSubItem(item, "0x" + data.VirtualAddress.ToString("x8"))); + item.SubItems.Add(new ListViewItem.ListViewSubItem(item, "0x" + data.Size.ToString("x"))); + + listImageData.Items.Add(item); + } + } + + #endregion + + #region Sections + + listSections.Items.Clear(); + + foreach (SectionHeader sh in _peFile.Sections) + { + ListViewItem item = new ListViewItem(); + + item.Text = sh.Name; + item.SubItems.Add(new ListViewItem.ListViewSubItem(item, "0x" + sh.VirtualAddress.ToString("x8"))); + item.SubItems.Add(new ListViewItem.ListViewSubItem(item, "0x" + sh.PointerToRawData.ToString("x8"))); + item.SubItems.Add(new ListViewItem.ListViewSubItem(item, "0x" + sh.VirtualSize.ToString("x"))); + item.SubItems.Add(new ListViewItem.ListViewSubItem(item, + Misc.FlagsToString(typeof(SectionFlags), (long)sh.Characteristics))); + + listSections.Items.Add(item); + } + + #endregion + return true; } + + private void listExports_RetrieveVirtualItem(object sender, RetrieveVirtualItemEventArgs e) + { + if (_peFile != null) + { + e.Item = new ListViewItem(); + + e.Item.Text = _peFile.ExportData.ExportNameTable[e.ItemIndex]; + e.Item.SubItems.Add(new ListViewItem.ListViewSubItem(e.Item, (e.ItemIndex + 1).ToString())); + e.Item.SubItems.Add(new ListViewItem.ListViewSubItem()); + e.Item.SubItems.Add(new ListViewItem.ListViewSubItem()); + + ExportEntry entry = _peFile.ExportData.ExportAddressTable[e.ItemIndex]; + + if (entry.Type == ExportEntry.ExportType.Export) + { + e.Item.SubItems[2].Text = "0x" + entry.ExportRVA.ToString("x8"); + e.Item.SubItems[3].Text = "0x" + PEFile.RvaToVa(_peFile, entry.ExportRVA).ToString("x8"); + } + else if (entry.Type == ExportEntry.ExportType.Forwarder) + { + e.Item.ImageIndex = 0; + e.Item.Text += " > " + entry.ForwardedString; + } + } + } } } diff --git a/trunk/ProcessHacker/Forms/PEWindow.resx b/trunk/ProcessHacker/Forms/PEWindow.resx index 0890d0ced..180a6345d 100644 --- a/trunk/ProcessHacker/Forms/PEWindow.resx +++ b/trunk/ProcessHacker/Forms/PEWindow.resx @@ -120,6 +120,29 @@ 17, 17 + + 235, 17 + + + + AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj0yLjAuMC4w + LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0 + ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAADM + AgAAAk1TRnQBSQFMAwEBAAEEAQABBAEAARABAAEQAQAE/wEhAQAI/wFCAU0BNgcAATYDAAEoAwABQAMA + ARADAAEBAQABIAYAARD/AP8A/wD/AEIAAVYBVwFWAbgDBAEG9AADJgE4AVEBaQFRAfcBWwFeAVsB2dAA + AS0BvgE5Af8BKQG4ATQB/wEkAbEBLgH/AR8BqQEoAf8BGQGhASIB/wETAZkBGwH/AQ0BkQEVAf8BBwGI + AQ4B/wEBAYABBwH/AQsBiAERAf8BJQGhASoB/wEQAYsBFQH/AVkBXAFZAc/MAAExAcMBPQH/AaAB1wGp + Af8BnAHVAaUB/wGYAdMBoQH/AZQB0AGdAf8BkAHOAZgB/wGLAcsBkwH/AYcByQGOAf8BggHGAYkB/wFK + AcMBhAH/AUYBwQGAAf8BQgG+AUgB/wERAYwBFgH/AVkBWwFZAcTIAAE0AccBQAH/AaUB2gGuAf8BogHY + AasB/wGeAdYBpwH/AZoB1AGjAf8BlgHSAZ8B/wGTAc8BmgH/AY4BzAGVAf8BiQHKAZAB/wGFAccBiwH/ + AYEBxQGHAf8BSQHCAYIB/wEWAZEBHAH/AVkBXAFZAcnIAAE0AccBQAH/ATQBxwFAAf8BMQHDAT0B/wEt + Ab4BOQH/ASkBuAE0Af8BJAGxAS4B/wEfAakBKAH/ARkBoQEiAf8BEwGZARsB/wENAZEBFQH/ASYBowEu + Af8BIQGdASgB/wFYAVwBWAHR9AABUQFtAVEB9wFaAV8BWgHb+AABVgFYAVYBuwMEAQb/AP8A/wD/ANAA + AUIBTQE+BwABPgMAASgDAAFAAwABEAMAAQEBAAEBBQABgBcAA/8BAAL/BgAC/wYAAv8GAAL/BgAB/wHn + BgAB/wHHBgABgAEDBgABgAEBBgABgAEBBgABgAEDBgAB/wHnBgAB/wHnBgAC/wYAAv8GAAL/BgAC/wYA + Cw== + + 127, 17 diff --git a/trunk/ProcessHacker/Forms/ProcessGroups.cs b/trunk/ProcessHacker/Forms/ProcessGroups.cs index 44acd10cb..c69d7680f 100644 --- a/trunk/ProcessHacker/Forms/ProcessGroups.cs +++ b/trunk/ProcessHacker/Forms/ProcessGroups.cs @@ -17,6 +17,8 @@ namespace ProcessHacker { InitializeComponent(); + Misc.SetDoubleBuffered(listGroups, typeof(ListView), true); + listGroups.ContextMenu = ListViewMenu.GetMenu(listGroups); _phandle = Win32.OpenProcess(Win32.PROCESS_RIGHTS.PROCESS_QUERY_INFORMATION, 0, PID); @@ -31,9 +33,6 @@ namespace ProcessHacker return; } - typeof(ListView).GetProperty("DoubleBuffered", - BindingFlags.NonPublic | BindingFlags.Instance).SetValue(listGroups, true, null); - Win32.TOKEN_GROUPS groups = Win32.ReadTokenGroups(_phandle); if (groups.GroupCount == 0) diff --git a/trunk/ProcessHacker/Forms/ProcessPrivileges.cs b/trunk/ProcessHacker/Forms/ProcessPrivileges.cs index 8614efe80..c75fa87d3 100644 --- a/trunk/ProcessHacker/Forms/ProcessPrivileges.cs +++ b/trunk/ProcessHacker/Forms/ProcessPrivileges.cs @@ -32,6 +32,8 @@ namespace ProcessHacker { InitializeComponent(); + Misc.SetDoubleBuffered(listPrivileges, typeof(ListView), true); + listPrivileges.ContextMenu = menuPrivileges; _phandle = Win32.OpenProcess(Win32.PROCESS_RIGHTS.PROCESS_QUERY_INFORMATION, 0, PID); diff --git a/trunk/ProcessHacker/Forms/ResultsWindow.cs b/trunk/ProcessHacker/Forms/ResultsWindow.cs index 66890e77a..052744e8b 100644 --- a/trunk/ProcessHacker/Forms/ResultsWindow.cs +++ b/trunk/ProcessHacker/Forms/ResultsWindow.cs @@ -42,13 +42,12 @@ namespace ProcessHacker public ResultsWindow(int PID) { - InitializeComponent(); + InitializeComponent(); + + Misc.SetDoubleBuffered(listResults, typeof(ListView), true); Thread.CurrentThread.Priority = ThreadPriority.Highest; - typeof(ListView).GetProperty("DoubleBuffered", - BindingFlags.NonPublic | BindingFlags.Instance).SetValue(listResults, true, null); - _pid = PID; _id = Program.ResultsIds.Pop(); diff --git a/trunk/ProcessHacker/Misc/Misc.cs b/trunk/ProcessHacker/Misc/Misc.cs index f168c975e..5aa4df72c 100644 --- a/trunk/ProcessHacker/Misc/Misc.cs +++ b/trunk/ProcessHacker/Misc/Misc.cs @@ -18,8 +18,10 @@ */ using System; -using System.Text; using System.Diagnostics; +using System.IO; +using System.Reflection; +using System.Text; using System.Windows.Forms; namespace ProcessHacker @@ -73,6 +75,15 @@ namespace ProcessHacker #endregion + /// + /// Converts a 32-bit Unix time value into a DateTime object. + /// + /// The Unix time value. + public static DateTime DateTimeFromUnixTime(uint time) + { + return new DateTime(1970, 1, 1, 0, 0, 0).Add(new TimeSpan(0, 0, 0, (int)time)); + } + /// /// Disables the menu items contained in the specified menu. /// @@ -203,5 +214,266 @@ namespace ProcessHacker foreach (ListViewItem item in items) item.Selected = true; } + + /// + /// Enables or disables double buffering for a control. + /// + /// The control. + /// The type of the control. + /// The new setting. + public static void SetDoubleBuffered(Control c, Type t, bool value) + { + PropertyInfo property = t.GetProperty("DoubleBuffered", + BindingFlags.NonPublic | BindingFlags.Instance); + + property.SetValue(c, value, null); + } + + #region Stuff from PNG.Net + + public enum Endianness + { + Little, Big + } + + public static bool ArrayContains(T[] array, T element) + { + foreach (T e in array) + if (e.Equals(element)) + return true; + + return false; + } + + public static bool BytesEqual(byte[] b1, byte[] b2) + { + for (int i = 0; i < b1.Length; i++) + if (b1[i] != b2[i]) + return false; + + return true; + } + + public static int BytesToInt(byte[] data, Endianness type) + { + if (type == Endianness.Little) + { + return (data[0]) | (data[1] << 8) | (data[2] << 16) | (data[3] << 24); + } + else if (type == Endianness.Big) + { + return (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | (data[3]); + } + else + { + throw new ArgumentException(); + } + } + + public static uint BytesToUInt(byte[] data, Endianness type) + { + return BytesToUInt(data, 0, type); + } + + public static uint BytesToUInt(byte[] data, int offset, Endianness type) + { + if (type == Endianness.Little) + { + return (uint)(data[offset]) | (uint)(data[offset + 1] << 8) | + (uint)(data[offset + 2] << 16) | (uint)(data[offset + 3] << 24); + } + else if (type == Endianness.Big) + { + return (uint)(data[offset] << 24) | (uint)(data[offset + 1] << 16) | + (uint)(data[offset + 2] << 8) | (uint)(data[offset + 3]); + } + else + { + throw new ArgumentException(); + } + } + + public static ushort BytesToUShort(byte[] data, Endianness type) + { + return BytesToUShort(data, 0, type); + } + + public static ushort BytesToUShort(byte[] data, int offset, Endianness type) + { + if (type == Endianness.Little) + { + return (ushort)(data[offset] | (data[offset + 1] << 8)); + } + else if (type == Endianness.Big) + { + return (ushort)((data[offset] << 8) | data[offset + 1]); + } + else + { + throw new ArgumentException(); + } + } + + public static string FlagsToString(Type e, long value) + { + string r = ""; + + for (int i = 0; i < 32; i++) + { + long fv = 1 << i; + + if ((value & fv) == fv) + { + r += Enum.GetName(e, fv) + ", "; + } + } + + if (r.EndsWith(", ")) + r = r.Remove(r.Length - 2, 2); + + return r; + } + + public static int IntCeilDiv(int a, int b) + { + return (int)Math.Ceiling(((double)a / b)); + } + + public static byte[] IntToBytes(int n, Endianness type) + { + byte[] data = new byte[4]; + + if (type == Endianness.Little) + { + data[0] = (byte)(n & 0xff); + data[1] = (byte)((n >> 8) & 0xff); + data[2] = (byte)((n >> 16) & 0xff); + data[3] = (byte)((n >> 24) & 0xff); + } + else if (type == Endianness.Big) + { + data[0] = (byte)((n >> 24) & 0xff); + data[1] = (byte)((n >> 16) & 0xff); + data[2] = (byte)((n >> 8) & 0xff); + data[3] = (byte)(n & 0xff); + } + else + { + throw new ArgumentException(); + } + + return data; + } + + public static byte[] ReverseBytes(byte[] data) + { + byte[] newdata = new byte[data.Length]; + + for (int i = 0; i < data.Length; i++) + newdata[i] = data[data.Length - i - 1]; + + return newdata; + } + + public static uint ReverseEndian(uint n) + { + uint b0 = n & 0xff; + uint b1 = (n >> 8) & 0xff; + uint b2 = (n >> 16) & 0xff; + uint b3 = (n >> 24) & 0xff; + + b0 <<= 24; + b1 <<= 16; + b2 <<= 8; + + return b0 | b1 | b2 | b3; + } + + public static int ReadInt(Stream s, Endianness type) + { + byte[] buffer = new byte[4]; + + if (s.Read(buffer, 0, 4) == 0) + throw new EndOfStreamException(); + + return BytesToInt(buffer, type); + } + + public static string ReadString(Stream s, int length) + { + byte[] buffer = new byte[length]; + + if (s.Read(buffer, 0, length) == 0) + throw new EndOfStreamException(); + + return System.Text.ASCIIEncoding.ASCII.GetString(buffer); + } + + public static uint ReadUInt(Stream s, Endianness type) + { + byte[] buffer = new byte[4]; + + if (s.Read(buffer, 0, 4) == 0) + throw new EndOfStreamException(); + + return BytesToUInt(buffer, type); + } + + public static uint RoundUpAddress(uint address, uint align) + { + uint t = (uint)Math.Ceiling((double)address / align); + + return t * align; + } + + public static byte[] UIntToBytes(uint n, Endianness type) + { + byte[] data = new byte[4]; + + if (type == Endianness.Little) + { + data[0] = (byte)(n & 0xff); + data[1] = (byte)((n >> 8) & 0xff); + data[2] = (byte)((n >> 16) & 0xff); + data[3] = (byte)((n >> 24) & 0xff); + } + else if (type == Endianness.Big) + { + data[0] = (byte)((n >> 24) & 0xff); + data[1] = (byte)((n >> 16) & 0xff); + data[2] = (byte)((n >> 8) & 0xff); + data[3] = (byte)(n & 0xff); + } + else + { + throw new ArgumentException(); + } + + return data; + } + + public static byte[] UShortToBytes(ushort n, Endianness type) + { + byte[] data = new byte[2]; + + if (type == Endianness.Little) + { + data[0] = (byte)(n & 0xff); + data[1] = (byte)((n >> 8) & 0xff); + } + else if (type == Endianness.Big) + { + data[0] = (byte)((n >> 8) & 0xff); + data[1] = (byte)(n & 0xff); + } + else + { + throw new ArgumentException(); + } + + return data; + } + + #endregion } } diff --git a/trunk/ProcessHacker/Misc/Utils.cs b/trunk/ProcessHacker/Misc/Utils.cs deleted file mode 100644 index 9d9e2f5f2..000000000 --- a/trunk/ProcessHacker/Misc/Utils.cs +++ /dev/null @@ -1,264 +0,0 @@ -/* - * Process Hacker, PNG.Net - * - * Copyright (C) 2008 wj32 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -using System; -using System.Collections.Generic; -using System.Text; -using System.IO; -using System.Drawing; - -namespace ProcessHacker -{ - public static class Utils - { - public enum Endianness - { - Little, Big - } - - public static bool ArrayContains(T[] array, T element) - { - foreach (T e in array) - if (e.Equals(element)) - return true; - - return false; - } - - public static bool BytesEqual(byte[] b1, byte[] b2) - { - for (int i = 0; i < b1.Length; i++) - if (b1[i] != b2[i]) - return false; - - return true; - } - - public static int BytesToInt(byte[] data, Endianness type) - { - if (type == Endianness.Little) - { - return (data[0]) | (data[1] << 8) | (data[2] << 16) | (data[3] << 24); - } - else if (type == Endianness.Big) - { - return (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | (data[3]); - } - else - { - throw new ArgumentException(); - } - } - - public static uint BytesToUInt(byte[] data, Endianness type) - { - return BytesToUInt(data, 0, type); - } - - public static uint BytesToUInt(byte[] data, int offset, Endianness type) - { - if (type == Endianness.Little) - { - return (uint)(data[offset]) | (uint)(data[offset + 1] << 8) | - (uint)(data[offset + 2] << 16) | (uint)(data[offset + 3] << 24); - } - else if (type == Endianness.Big) - { - return (uint)(data[offset] << 24) | (uint)(data[offset + 1] << 16) | - (uint)(data[offset + 2] << 8) | (uint)(data[offset + 3]); - } - else - { - throw new ArgumentException(); - } - } - - public static ushort BytesToUShort(byte[] data, Endianness type) - { - return BytesToUShort(data, 0, type); - } - - public static ushort BytesToUShort(byte[] data, int offset, Endianness type) - { - if (type == Endianness.Little) - { - return (ushort)(data[offset] | (data[offset + 1] << 8)); - } - else if (type == Endianness.Big) - { - return (ushort)((data[offset] << 8) | data[offset + 1]); - } - else - { - throw new ArgumentException(); - } - } - - public static string FlagsToString(Type e, uint value) - { - string r = ""; - - foreach (uint flag in Enum.GetValues(e)) - { - if ((value & flag) == flag) - { - r += Enum.GetName(e, flag) + ", "; - } - } - - if (r.EndsWith(", ")) - r = r.Remove(r.Length - 3, 2); - - return r; - } - - public static int IntCeilDiv(int a, int b) - { - return (int)Math.Ceiling(((double)a / b)); - } - - public static byte[] IntToBytes(int n, Endianness type) - { - byte[] data = new byte[4]; - - if (type == Endianness.Little) - { - data[0] = (byte)(n & 0xff); - data[1] = (byte)((n >> 8) & 0xff); - data[2] = (byte)((n >> 16) & 0xff); - data[3] = (byte)((n >> 24) & 0xff); - } - else if (type == Endianness.Big) - { - data[0] = (byte)((n >> 24) & 0xff); - data[1] = (byte)((n >> 16) & 0xff); - data[2] = (byte)((n >> 8) & 0xff); - data[3] = (byte)(n & 0xff); - } - else - { - throw new ArgumentException(); - } - - return data; - } - - public static byte[] ReverseBytes(byte[] data) - { - byte[] newdata = new byte[data.Length]; - - for (int i = 0; i < data.Length; i++) - newdata[i] = data[data.Length - i - 1]; - - return newdata; - } - - public static uint ReverseEndian(uint n) - { - uint b0 = n & 0xff; - uint b1 = (n >> 8) & 0xff; - uint b2 = (n >> 16) & 0xff; - uint b3 = (n >> 24) & 0xff; - - b0 <<= 24; - b1 <<= 16; - b2 <<= 8; - - return b0 | b1 | b2 | b3; - } - - public static int ReadInt(Stream s, Utils.Endianness type) - { - byte[] buffer = new byte[4]; - - if (s.Read(buffer, 0, 4) == 0) - throw new EndOfStreamException(); - - return BytesToInt(buffer, type); - } - - public static string ReadString(Stream s, int length) - { - byte[] buffer = new byte[length]; - - if (s.Read(buffer, 0, length) == 0) - throw new EndOfStreamException(); - - return System.Text.ASCIIEncoding.ASCII.GetString(buffer); - } - - public static uint ReadUInt(Stream s, Utils.Endianness type) - { - byte[] buffer = new byte[4]; - - if (s.Read(buffer, 0, 4) == 0) - throw new EndOfStreamException(); - - return BytesToUInt(buffer, type); - } - - public static byte[] UIntToBytes(uint n, Endianness type) - { - byte[] data = new byte[4]; - - if (type == Endianness.Little) - { - data[0] = (byte)(n & 0xff); - data[1] = (byte)((n >> 8) & 0xff); - data[2] = (byte)((n >> 16) & 0xff); - data[3] = (byte)((n >> 24) & 0xff); - } - else if (type == Endianness.Big) - { - data[0] = (byte)((n >> 24) & 0xff); - data[1] = (byte)((n >> 16) & 0xff); - data[2] = (byte)((n >> 8) & 0xff); - data[3] = (byte)(n & 0xff); - } - else - { - throw new ArgumentException(); - } - - return data; - } - - public static byte[] UShortToBytes(ushort n, Endianness type) - { - byte[] data = new byte[2]; - - if (type == Endianness.Little) - { - data[0] = (byte)(n & 0xff); - data[1] = (byte)((n >> 8) & 0xff); - } - else if (type == Endianness.Big) - { - data[0] = (byte)((n >> 8) & 0xff); - data[1] = (byte)(n & 0xff); - } - else - { - throw new ArgumentException(); - } - - return data; - } - } -} diff --git a/trunk/ProcessHacker/PE/ExportData.cs b/trunk/ProcessHacker/PE/ExportData.cs index 03e2d84a2..970ef1c74 100644 --- a/trunk/ProcessHacker/PE/ExportData.cs +++ b/trunk/ProcessHacker/PE/ExportData.cs @@ -39,7 +39,7 @@ namespace ProcessHacker.PE public class ExportData { - public ExportData(BinaryReader br, uint imageBase) + public ExportData(BinaryReader br, PEFile peFile) { this.ExportFlags = br.ReadUInt32(); this.TimeDateStamp = br.ReadUInt32(); @@ -54,20 +54,55 @@ namespace ProcessHacker.PE this.OrdinalTableRVA = br.ReadUInt32(); // read address table - br.BaseStream.Seek(imageBase + this.ExportAddressTableRVA, SeekOrigin.Begin); + br.BaseStream.Seek(PEFile.RvaToVa(peFile, this.ExportAddressTableRVA), SeekOrigin.Begin); for (int i = 0; i < this.AddressTableEntries; i++) { uint address = br.ReadUInt32(); - this.ExportAddressTable.Add(new ExportEntry() + ExportEntry entry = new ExportEntry(); + ImageData iD = peFile.ImageData[ImageDataType.ExportTable]; + + if (address >= iD.VirtualAddress && address < iD.VirtualAddress + iD.Size) { - ExportRVA = address - }); + entry.Type = ExportEntry.ExportType.Forwarder; + } + else + { + entry.Type = ExportEntry.ExportType.Export; + } + + entry.ExportRVA = address; + + this.ExportAddressTable.Add(entry); + } + + for (int i = 0; i < this.ExportAddressTable.Count; i++) + { + ExportEntry entry = this.ExportAddressTable[i]; + + if (entry.Type == ExportEntry.ExportType.Forwarder) + { + br.BaseStream.Seek(PEFile.RvaToVa(peFile, entry.ExportRVA), SeekOrigin.Begin); + + string temp = ""; + + while (true) + { + byte b = br.ReadByte(); + + if (b == 0) + break; + + temp += (char)b; + } + + entry.ForwardedString = temp; + } } // read ordinal table - br.BaseStream.Seek(imageBase + this.OrdinalTableRVA, SeekOrigin.Begin); + br.BaseStream.Seek(PEFile.RvaToVa(peFile, this.OrdinalTableRVA), SeekOrigin.Begin); for (int i = 0; i < this.AddressTableEntries; i++) { @@ -75,7 +110,7 @@ namespace ProcessHacker.PE } // read name pointer table - br.BaseStream.Seek(imageBase + this.NamePointerRVA, SeekOrigin.Begin); + br.BaseStream.Seek(PEFile.RvaToVa(peFile, this.NamePointerRVA), SeekOrigin.Begin); for (int i = 0; i < this.NumberOfNamePointers; i++) { @@ -85,7 +120,7 @@ namespace ProcessHacker.PE // read names for (int i = 0; i < this.ExportNamePointerTable.Count; i++) { - br.BaseStream.Seek(imageBase + this.ExportNamePointerTable[i], SeekOrigin.Begin); + br.BaseStream.Seek(PEFile.RvaToVa(peFile, this.ExportNamePointerTable[i]), SeekOrigin.Begin); string temp = ""; diff --git a/trunk/ProcessHacker/PE/PEFile.cs b/trunk/ProcessHacker/PE/PEFile.cs index cb497da44..c867c4d68 100644 --- a/trunk/ProcessHacker/PE/PEFile.cs +++ b/trunk/ProcessHacker/PE/PEFile.cs @@ -61,7 +61,7 @@ namespace ProcessHacker.PE byte[] peSig = br.ReadBytes(4); - if (!Utils.BytesEqual(peSig, PEFile.PESignature)) + if (!Misc.BytesEqual(peSig, PEFile.PESignature)) throw new Exception("Invalid PE signature."); // read COFF header @@ -93,13 +93,32 @@ namespace ProcessHacker.PE if (iD.VirtualAddress != 0) { - s.Seek(iD.VirtualAddress + _coffOptionalHeader.BaseOfCode, SeekOrigin.Begin); + s.Seek(PEFile.RvaToVa(this, iD.VirtualAddress), SeekOrigin.Begin); - this.ExportData = new ExportData(br, _coffOptionalHeader.BaseOfCode); + this.ExportData = new ExportData(br, this); } } } + public static long RvaToVa(PEFile peFile, long rva) + { + SectionHeader section = null; + + foreach (SectionHeader sh in peFile.Sections) + { + if (rva >= sh.VirtualAddress && rva < sh.VirtualAddress + sh.VirtualSize) + { + section = sh; + break; + } + } + + if (section == null) + throw new Exception("Relative virtual address has no matching section."); + + return section.PointerToRawData + rva - section.VirtualAddress; + } + public COFFHeader COFFHeader { get { return _coffHeader; } diff --git a/trunk/ProcessHacker/ProcessHacker.csproj b/trunk/ProcessHacker/ProcessHacker.csproj index bb253d3b2..e606b736f 100644 --- a/trunk/ProcessHacker/ProcessHacker.csproj +++ b/trunk/ProcessHacker/ProcessHacker.csproj @@ -228,7 +228,6 @@ -