diff --git a/trunk/ProcessHacker.Native/Api/Enums.cs b/trunk/ProcessHacker.Native/Api/Enums.cs
index b9dd68188..4e0c847e9 100644
--- a/trunk/ProcessHacker.Native/Api/Enums.cs
+++ b/trunk/ProcessHacker.Native/Api/Enums.cs
@@ -237,13 +237,6 @@ namespace ProcessHacker.Native.Api
WinNT50 = 3
}
- public enum MachineType : uint
- {
- I386 = 0x014c,
- Ia64 = 0x0200,
- Amd64 = 0x8664
- }
-
[Flags]
public enum MemoryState : uint
{
diff --git a/trunk/ProcessHacker.Native/Api/NativeDefinitions.cs b/trunk/ProcessHacker.Native/Api/NativeDefinitions.cs
index 8e0847619..58bd35ae9 100644
--- a/trunk/ProcessHacker.Native/Api/NativeDefinitions.cs
+++ b/trunk/ProcessHacker.Native/Api/NativeDefinitions.cs
@@ -59,6 +59,9 @@ namespace ProcessHacker.Native.Api
public const int MaxKeyValueNameLength = 32767;
public const int MaxStackDepth = 32;
public const int MaxWow64SharedEntries = 16;
+ public const short Pe32Magic = 0x10b;
+ public const short Pe32PlusMagic = 0x20b;
+ public const short RomMagic = 0x107;
public const int PortMessageMaxDataLength = 0x130;
public const int PortMessageMaxLength = 0x148;
public const int ProcessHandleTracingMaxStacks = 16;
diff --git a/trunk/ProcessHacker.Native/Api/NativeEnums.cs b/trunk/ProcessHacker.Native/Api/NativeEnums.cs
index f14aa31a5..c8dda5eab 100644
--- a/trunk/ProcessHacker.Native/Api/NativeEnums.cs
+++ b/trunk/ProcessHacker.Native/Api/NativeEnums.cs
@@ -640,6 +640,348 @@ namespace ProcessHacker.Native.Api
ClassMask = 0x0000f000
}
+ public enum ImageBaseRelocationType : short
+ {
+ ///
+ /// The base relocation is skipped. This type can be used to pad a block.
+ ///
+ Absolute = 0,
+
+ ///
+ /// The base relocation adds the high 16 bits of the difference to the 16-bit
+ /// field at offset. The 16-bit field represents the high value of a 32-bit word.
+ ///
+ High = 1,
+
+ ///
+ /// The base relocation adds the low 16 bits of the difference to the 16-bit
+ /// field at offset. The 16-bit field represents the low half of a 32-bit word.
+ ///
+ Low = 2,
+
+ ///
+ /// The base relocation applies all 32 bits of the difference to the 32-bit
+ /// field at offset.
+ ///
+ HighLow = 3,
+
+ ///
+ /// The base relocation adds the high 16 bits of the difference to the 16-bit
+ /// field at offset. The 16-bit field represents the high value of a 32-bit word.
+ /// The low 16 bits of the 32-bit value are stored in the 16-bit word that follows
+ /// this base relocation. This means that this base relocation occupies two slots.
+ ///
+ HighAdj = 4,
+
+ ///
+ /// The base relocation applies to a MIPS jump instruction.
+ ///
+ MipsJmpAddr = 5,
+
+ ///
+ /// The base relocation applies to a MIPS16 jump instruction.
+ ///
+ MipsJmpAddr16 = 9,
+ Ia64Imm64 = 9,
+
+ ///
+ /// The base relocation applies the difference to the 64-bit field at offset.
+ ///
+ Dir16 = 10
+ }
+
+ [Flags]
+ public enum ImageCharacteristics : ushort
+ {
+ ///
+ /// Image only, Windows CE, and Windows NT® and later. This indicates that the file does
+ /// not contain base relocations and must therefore be loaded at its preferred base address.
+ /// If the base address is not available, the loader reports an error. The default behavior
+ /// of the linker is to strip base relocations from executable (EXE) files.
+ ///
+ RelocsStripped = 0x0001,
+
+ ///
+ /// Image only. This indicates that the image file is valid and can be run. If this flag
+ /// is not set, it indicates a linker error.
+ ///
+ ExecutableImage = 0x0002,
+
+ ///
+ /// COFF line numbers have been removed. This flag is deprecated and should be zero.
+ ///
+ LineNumsStripped = 0x0004,
+
+ ///
+ /// COFF symbol table entries for local symbols have been removed. This flag is deprecated
+ /// and should be zero.
+ ///
+ LocalSymsStripped = 0x0008,
+
+ ///
+ /// Obsolete. Aggressively trim working set. This flag is deprecated for Windows 2000 and later
+ /// and must be zero.
+ ///
+ AggressiveWsTrim = 0x0010,
+
+ ///
+ /// Application can handle > 2 GB addresses.
+ ///
+ LargeAddressAware = 0x0020,
+
+ ///
+ /// This flag is reserved for future use.
+ ///
+ Reserved = 0x0040,
+
+ ///
+ /// Little endian: the least significant bit (LSB) precedes the most significant bit (MSB) in
+ /// memory. This flag is deprecated and should be zero.
+ ///
+ BytesReversedLo = 0x0080,
+
+ ///
+ /// Machine is based on a 32-bit-word architecture.
+ ///
+ ThirtyTwoBitMachine = 0x0100,
+
+ ///
+ /// Debugging information is removed from the image file.
+ ///
+ DebugStripped = 0x0200,
+
+ ///
+ /// If the image is on removable media, fully load it and copy it to the swap file.
+ ///
+ RemovableRunFromSwap = 0x0400,
+
+ ///
+ /// If the image is on network media, fully load it and copy it to the swap file.
+ ///
+ NetRunFromSwap = 0x0800,
+
+ ///
+ /// The image file is a system file, not a user program.
+ ///
+ System = 0x1000,
+
+ ///
+ /// The image file is a dynamic-link library (DLL). Such files are considered
+ /// executable files for almost all purposes, although they cannot be directly run.
+ ///
+ DLL = 0x2000,
+
+ ///
+ /// The file should be run only on a uniprocessor machine.
+ ///
+ UPSystemOnly = 0x4000,
+
+ ///
+ /// Big endian: the MSB precedes the LSB in memory. This flag is deprecated and should be zero.
+ ///
+ BytesReversedHi = 0x8000
+ }
+
+ [Flags]
+ public enum ImageDllCharacteristics : ushort
+ {
+ DynamicBase = 0x0040,
+ ForceIntegrity = 0x0080,
+ NxCompat = 0x0100,
+ NoIsolation = 0x0200,
+ NoSeh = 0x0400,
+ NoBind = 0x0800,
+ WdmDriver = 0x2000,
+ TerminalServerAware = 0x8000
+ }
+
+ public enum ImageI386RelocationType : short
+ {
+ Absolute = 0x0,
+ Dir16 = 0x1,
+ Rel16 = 0x2,
+ Dir32 = 0x6,
+ Dir32Nb = 0x7,
+ Seg12 = 0x9,
+ Section = 0xa,
+ SecRel = 0xb,
+ Token = 0xc,
+ SecRel7 = 0xd,
+ Rel32 = 0x14
+ }
+
+ [Flags]
+ public enum ImageSectionFlags : uint
+ {
+ ///
+ /// Reserved for future use.
+ ///
+ Reserved1 = 0x00000000,
+
+ ///
+ /// Reserved for future use.
+ ///
+ Reserved2 = 0x00000001,
+
+ ///
+ /// Reserved for future use.
+ ///
+ Reserved3 = 0x00000002,
+
+ ///
+ /// Reserved, must be zero.
+ ///
+ Reserved4 = 0x00000004,
+
+ ///
+ /// The section should not be padded to the next boundary.
+ /// This flag is obsolete and is replaced by IMAGE_SCN_ALIGN_1BYTES.
+ /// This is valid only for object files.
+ ///
+ NoPad = 0x00000008,
+
+ ///
+ /// The section contains executable code.
+ ///
+ Code = 0x00000020,
+
+ ///
+ /// The section contains initialized data.
+ ///
+ InitializedData = 0x00000040,
+
+ ///
+ /// The section contains uninitialized data.
+ ///
+ UninitializedData = 0x00000080,
+
+ ///
+ /// Reserved for future use.
+ ///
+ Other = 0x00000100,
+
+ ///
+ /// The section contains comments or other information. The
+ /// .drectve section has this type. This is valid for object
+ /// files only.
+ ///
+ Info = 0x00000200,
+
+ ///
+ /// Reserved for future use.
+ ///
+ Reserved5 = 0x00000400,
+
+ ///
+ /// The section will not become part of the image. This is valid
+ /// only for object files.
+ ///
+ Remove = 0x00000800,
+
+ ///
+ /// The section contains COMDAT data.
+ ///
+ COMDAT = 0x00001000,
+
+ ///
+ /// The section contains data referenced through the global pointer (GP).
+ ///
+ GPRel = 0x00008000,
+
+ ///
+ /// Reserved for future use.
+ ///
+ MemoryPurgeable = 0x00010000,
+
+ ///
+ /// Reserved for future use.
+ ///
+ Memory16Bit = 0x00020000,
+
+ ///
+ /// Reserved for future use.
+ ///
+ MemoryLocked = 0x00040000,
+
+ ///
+ /// Reserved for future use.
+ ///
+ MemoryPeload = 0x00080000,
+
+ Align1Bytes = 0x00100000,
+ Align2Bytes = 0x00200000,
+ Align4Bytes = 0x00300000,
+ Align8Bytes = 0x00400000,
+ Align16Bytes = 0x00500000,
+ Align32Bytes = 0x00600000,
+ Align64Bytes = 0x00700000,
+ Align128Bytes = 0x00800000,
+ Align256Bytes = 0x00900000,
+ Align512Bytes = 0x00a00000,
+ Align1024Bytes = 0x00b00000,
+ Align2048Bytes = 0x00c00000,
+ Align4096Bytes = 0x00d00000,
+ Align8192Bytes = 0x00e00000,
+
+ ///
+ /// The section contains extended relocations.
+ ///
+ NRelocOvfl = 0x01000000,
+
+ ///
+ /// The section can be discarded as needed.
+ ///
+ MemoryDiscardable = 0x02000000,
+
+ ///
+ /// The section cannot be cached.
+ ///
+ MemoryNotCached = 0x04000000,
+
+ ///
+ /// The section is not pageable.
+ ///
+ MemoryNotPaged = 0x08000000,
+
+ ///
+ /// The section can be shared in memory.
+ ///
+ MemoryShared = 0x10000000,
+
+ ///
+ /// The section can be executed as code.
+ ///
+ MemoryExecute = 0x20000000,
+
+ ///
+ /// The section can be read.
+ ///
+ MemoryRead = 0x40000000,
+
+ ///
+ /// The section can be written to.
+ ///
+ MemoryWrite = 0x80000000
+ }
+
+ public enum ImageSubsystem : short
+ {
+ Unknown = 0,
+ Native = 1,
+ WindowsGui = 2,
+ WindowsCui = 3,
+ OS2Cui = 5,
+ PosixCui = 7,
+ NativeWindows = 8,
+ WindowsCeGui = 9,
+ EfiApplication = 10,
+ EfiBootServiceDriver = 11,
+ EfiRuntimeDriver = 12,
+ EfiRom = 13,
+ Xbox = 14,
+ WindowsBootApplication = 16
+ }
+
public enum IoCompletionInformationClass : int
{
IoCompletionBasicInformation
@@ -831,6 +1173,112 @@ namespace ProcessHacker.Native.Api
CompatDatabaseProcessed = 0x80000000
}
+ ///
+ /// Specifies an executable's target CPU type.
+ ///
+ public enum MachineType : ushort
+ {
+ ///
+ /// Assumed to be applicable to any machine type.
+ ///
+ Unknown = 0x0,
+
+ ///
+ /// Matsushita AM33.
+ ///
+ Am33 = 0x1d3,
+
+ ///
+ /// x64.
+ ///
+ Amd64 = 0x8664,
+
+ ///
+ /// ARM little-endian.
+ ///
+ Arm = 0x1c0,
+
+ ///
+ /// EFI byte code.
+ ///
+ Ebc = 0xebc,
+
+ ///
+ /// Intel 386 or later processors and compatible processors.
+ ///
+ I386 = 0x14c,
+
+ ///
+ /// Intel Itanium processor family.
+ ///
+ Ia64 = 0x200,
+
+ ///
+ /// Mitsubishi M32R little endian.
+ ///
+ M32R = 0x9041,
+
+ ///
+ /// MIPS16.
+ ///
+ Mips16 = 0x266,
+
+ ///
+ /// MIPS with FPU.
+ ///
+ MipsFpu = 0x366,
+
+ ///
+ /// MIPS16 with FPU.
+ ///
+ MipsFpu16 = 0x466,
+
+ ///
+ /// PowerPC little-endian.
+ ///
+ PowerPc = 0x1f0,
+
+ ///
+ /// PowerPC with floating point support.
+ ///
+ PowerPcFp = 0x1f1,
+
+ ///
+ /// MIPS little-endian.
+ ///
+ R4000 = 0x166,
+
+ ///
+ /// Hitachi SH3.
+ ///
+ Sh3 = 0x1a2,
+
+ ///
+ /// Hitachi SH3 DSP.
+ ///
+ Sh3Dsp = 0x1a3,
+
+ ///
+ /// Hitachi SH4.
+ ///
+ Sh4 = 0x1a6,
+
+ ///
+ /// Hitachi SH5.
+ ///
+ Sh5 = 0x1a8,
+
+ ///
+ /// Thumb.
+ ///
+ Thumb = 0x1c2,
+
+ ///
+ /// MIPS little-endian WCE v2.
+ ///
+ WceMipsv2 = 0x169
+ }
+
[Flags]
public enum MemExecuteOptions : int
{
diff --git a/trunk/ProcessHacker.Native/Api/NativeFunctions.cs b/trunk/ProcessHacker.Native/Api/NativeFunctions.cs
index 2ce0bde2d..a62167aa4 100644
--- a/trunk/ProcessHacker.Native/Api/NativeFunctions.cs
+++ b/trunk/ProcessHacker.Native/Api/NativeFunctions.cs
@@ -2920,7 +2920,7 @@ namespace ProcessHacker.Native.Api
{
unsafe
{
- int* buffer = (int*)BitMapHeader.Buffer.ToPointer();
+ int* buffer = (int*)BitMapHeader.Buffer;
return (buffer[BitPosition / 32] >> (BitPosition % 32)) & 0x1;
}
diff --git a/trunk/ProcessHacker.Native/Api/NativeStructs.cs b/trunk/ProcessHacker.Native/Api/NativeStructs.cs
index c674b7ce7..5febd6e16 100644
--- a/trunk/ProcessHacker.Native/Api/NativeStructs.cs
+++ b/trunk/ProcessHacker.Native/Api/NativeStructs.cs
@@ -748,6 +748,30 @@ namespace ProcessHacker.Native.Api
public T GenericAll;
}
+ [StructLayout(LayoutKind.Sequential)]
+ public struct ImageBaseRelocation
+ {
+ public int VirtualAddress;
+ public int SizeOfBlock;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ public struct ImageBoundForwarderRef
+ {
+ public int TimeDateStamp;
+ public short OffsetModuleName;
+ public short Reserved;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ public struct ImageBoundImportDescriptor
+ {
+ public int TimeDateStamp;
+ public short OffsetModuleName;
+ public short NumberOfModuleForwarderRefs;
+ public ImageBoundForwarderRef ForwarderRefs;
+ }
+
[StructLayout(LayoutKind.Sequential)]
public struct ImageDataDirectory
{
@@ -755,16 +779,99 @@ namespace ProcessHacker.Native.Api
public int Size;
}
+ [StructLayout(LayoutKind.Sequential)]
+ public struct ImageExportDirectory
+ {
+ public int Characteristics;
+ public int TimeDateStamp;
+ public short MajorVersion;
+ public short MinorVersion;
+ public int Name;
+ public int Base;
+ public int NumberOfFunctions;
+ public int NumberOfNames;
+ public int AddressOfFunctions;
+ public int AddressOfNames;
+ public int AddressOfNameOrdinals;
+ }
+
[StructLayout(LayoutKind.Sequential)]
public struct ImageFileHeader
{
- public short Machine;
+ public MachineType Machine;
public short NumberOfSections;
public int TimeDateStamp;
public int PointerToSymbolTable;
public int NumberOfSymbols;
public short SizeOfOptionalHeader;
- public short Characteristics;
+ public ImageCharacteristics Characteristics;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ public struct ImageImportByName
+ {
+ public short Hint;
+ public byte Name;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ public struct ImageImportDescriptor
+ {
+ public int OriginalFirstThunk; // also Characteristics
+ public int TimeDateStamp;
+ public int ForwarderChain;
+ public int Name;
+ public int FirstThunk;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ public struct ImageLoadConfigDirectory
+ {
+ public int Size;
+ public int TimeDateStamp;
+ public short MajorVersion;
+ public short MinorVersion;
+ public int GlobalFlagsClear;
+ public int GlobalFlagsSet;
+ public int CriticalSectionDefaultTimeout;
+ public int DeCommitFreeBlockThreshold;
+ public int DeCommitTotalFreeThreshold;
+ public int LockPrefixTable;
+ public int MaximumAllocationSize;
+ public int VirtualMemoryThreshold;
+ public int ProcessHeapFlags;
+ public int ProcessAffinityMask;
+ public short CsdVersion;
+ public short Reserved1;
+ public int EditList;
+ public int SecurityCookie;
+ public int SEHandlerTable;
+ public int SEHandlerCount;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ public struct ImageLoadConfigDirectory64
+ {
+ public int Size;
+ public int TimeDateStamp;
+ public short MajorVersion;
+ public short MinorVersion;
+ public int GlobalFlagsClear;
+ public int GlobalFlagsSet;
+ public int CriticalSectionDefaultTimeout;
+ public long DeCommitFreeBlockThreshold;
+ public long DeCommitTotalFreeThreshold;
+ public long LockPrefixTable;
+ public long MaximumAllocationSize;
+ public long VirtualMemoryThreshold;
+ public long ProcessAffinityMask;
+ public int ProcessHeapFlags;
+ public short CsdVersion;
+ public short Reserved1;
+ public long EditList;
+ public long SecurityCookie;
+ public long SEHandlerTable;
+ public long SEHandlerCount;
}
[StructLayout(LayoutKind.Sequential)]
@@ -800,8 +907,8 @@ namespace ProcessHacker.Native.Api
public int SizeOfImage;
public int SizeOfHeaders;
public int CheckSum;
- public short Subsystem;
- public short DllCharacteristics;
+ public ImageSubsystem Subsystem;
+ public ImageDllCharacteristics DllCharacteristics;
public int SizeOfStackReserve;
public int SizeOfStackCommit;
public int SizeOfHeapReserve;
@@ -811,6 +918,82 @@ namespace ProcessHacker.Native.Api
public ImageDataDirectory DataDirectory;
}
+ [StructLayout(LayoutKind.Sequential)]
+ public struct ImageOptionalHeader64
+ {
+ public short Magic;
+ public byte MajorLinkerVersion;
+ public byte MinorLinkerVersion;
+ public int SizeOfCode;
+ public int SizeOfInitializedData;
+ public int SizeOfUninitializedData;
+ public int AddressOfEntryPoint;
+ public int BaseOfCode;
+ public long ImageBase;
+ public int SectionAlignment;
+ public int FileAlignment;
+ public short MajorOperatingSystemVersion;
+ public short MinorOperatingSystemVersion;
+ public short MajorImageVersion;
+ public short MinorImageVersion;
+ public short MajorSubsystemVersion;
+ public short MinorSubsystemVersion;
+ public int Win32VersionValue;
+ public int SizeOfImage;
+ public int SizeOfHeaders;
+ public int CheckSum;
+ public ImageSubsystem Subsystem;
+ public ImageDllCharacteristics DllCharacteristics;
+ public long SizeOfStackReserve;
+ public long SizeOfStackCommit;
+ public long SizeOfHeapReserve;
+ public long SizeOfHeapCommit;
+ public int LoaderFlags;
+ public int NumberOfRvaAndSizes;
+ public ImageDataDirectory DataDirectory;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ public struct ImageRelocation
+ {
+ public int VirtualAddress;
+ public int SymbolTableIndex;
+ public short Type;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ public unsafe struct ImageSectionHeader
+ {
+ public fixed byte Name[8];
+ public int Misc; // PhysicalAddress, VirtualSize
+ public int VirtualAddress;
+ public int SizeOfRawData;
+ public int PointerToRawData;
+ public int PointerToRelocations;
+ public int PointerToLinenumbers;
+ public short NumberOfRelocations;
+ public short NumberOfLinenumbers;
+ public ImageSectionFlags Characteristics;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ public struct ImageThunkData
+ {
+ public int ForwarderString; // byte*
+ public int Function; // int*
+ public int Ordinal;
+ public int AddressOfData; // ImageImportByName*
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ public struct ImageThunkData64
+ {
+ public long ForwarderString; // byte*
+ public long Function; // int*
+ public long Ordinal;
+ public long AddressOfData; // ImageImportByName*
+ }
+
[StructLayout(LayoutKind.Sequential)]
public struct InitialTeb
{
diff --git a/trunk/ProcessHacker.Native/Api/Win32.cs b/trunk/ProcessHacker.Native/Api/Win32.cs
index cd001cb55..87a55cd02 100644
--- a/trunk/ProcessHacker.Native/Api/Win32.cs
+++ b/trunk/ProcessHacker.Native/Api/Win32.cs
@@ -259,7 +259,7 @@ namespace ProcessHacker.Native.Api
sids = new IntPtr[count];
WtsMemoryAlloc data = new WtsMemoryAlloc(processes);
- WtsProcessInfo* dataP = (WtsProcessInfo*)data.Memory.ToPointer();
+ WtsProcessInfo* dataP = (WtsProcessInfo*)data.Memory;
for (int i = 0; i < count; i++)
{
@@ -318,7 +318,7 @@ namespace ProcessHacker.Native.Api
public unsafe static string[] GetMultiString(IntPtr ptr)
{
List list = new List();
- char* chptr = (char*)ptr.ToPointer();
+ char* chptr = (char*)ptr;
StringBuilder currentString = new StringBuilder();
while (true)
diff --git a/trunk/ProcessHacker.Native/Image/ImageDirectoryEntry.cs b/trunk/ProcessHacker.Native/Image/ImageDirectoryEntry.cs
new file mode 100644
index 000000000..896327cff
--- /dev/null
+++ b/trunk/ProcessHacker.Native/Image/ImageDirectoryEntry.cs
@@ -0,0 +1,26 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace ProcessHacker.Native.Image
+{
+ public enum ImageDataEntry : int
+ {
+ Export = 0,
+ Import = 1,
+ Resource = 2,
+ Exception = 3,
+ Security = 4,
+ BaseRelocation = 5,
+ Debug = 6,
+ Copyright = 7,
+ Architecture = 7,
+ GlobalPtr = 8,
+ Tls = 9,
+ LoadConfig = 10,
+ BoundImport = 11,
+ Iat = 12,
+ DelayImport = 13,
+ ComDescriptor = 14
+ }
+}
diff --git a/trunk/ProcessHacker.Native/Image/ImageExports.cs b/trunk/ProcessHacker.Native/Image/ImageExports.cs
new file mode 100644
index 000000000..8cb4349f0
--- /dev/null
+++ b/trunk/ProcessHacker.Native/Image/ImageExports.cs
@@ -0,0 +1,171 @@
+/*
+ * Process Hacker -
+ * image exports reader
+ *
+ * Copyright (C) 2009 wj32
+ *
+ * This file is part of Process Hacker.
+ *
+ * Process Hacker is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Process Hacker 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Process Hacker. If not, see .
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using ProcessHacker.Native.Api;
+using ProcessHacker.Native.Objects;
+using ProcessHacker.Native.Security;
+
+namespace ProcessHacker.Native.Image
+{
+ public unsafe sealed class ImageExports
+ {
+ public delegate bool EnumEntriesDelegate(ImageExportEntry entry);
+
+ private MappedImage _mappedImage;
+ private ImageDataDirectory* _dataDirectory;
+ private ImageExportDirectory* _exportDirectory;
+ private int* _addressTable;
+ private int* _namePointerTable;
+ private short* _ordinalTable;
+
+ internal ImageExports(MappedImage mappedImage)
+ {
+ _mappedImage = mappedImage;
+ _dataDirectory = mappedImage.GetDataEntry(ImageDataEntry.Export);
+ _exportDirectory = mappedImage.GetExportDirectory();
+
+ if (_exportDirectory != null)
+ {
+ _addressTable = (int*)mappedImage.RvaToVa(_exportDirectory->AddressOfFunctions);
+ _namePointerTable = (int*)mappedImage.RvaToVa(_exportDirectory->AddressOfNames);
+ _ordinalTable = (short*)mappedImage.RvaToVa(_exportDirectory->AddressOfNameOrdinals);
+ }
+ }
+
+ public int Count
+ {
+ get
+ {
+ if (_exportDirectory != null)
+ return _exportDirectory->NumberOfFunctions;
+ else
+ return 0;
+ }
+ }
+
+ public ImageExportEntry GetEntry(int index)
+ {
+ if (_exportDirectory == null || _namePointerTable == null || _ordinalTable == null)
+ return ImageExportEntry.Empty;
+ if (index >= _exportDirectory->NumberOfFunctions)
+ return ImageExportEntry.Empty;
+
+ ImageExportEntry entry = new ImageExportEntry();
+
+ entry.Ordinal = (short)(_ordinalTable[index] + _exportDirectory->Base);
+
+ if (index < _exportDirectory->NumberOfNames)
+ entry.Name = new string((sbyte*)_mappedImage.RvaToVa(_namePointerTable[index]));
+
+ return entry;
+ }
+
+ public ImageExportFunction GetFunction(string name)
+ {
+ if (_exportDirectory == null || _namePointerTable == null || _ordinalTable == null)
+ return ImageExportFunction.Empty;
+
+ int index;
+
+ index = this.LookupName(name);
+
+ if (index == -1)
+ return ImageExportFunction.Empty;
+
+ return this.GetFunction((short)(_ordinalTable[index] + _exportDirectory->Base));
+ }
+
+ public ImageExportFunction GetFunction(short ordinal)
+ {
+ if (_exportDirectory == null || _addressTable == null)
+ return ImageExportFunction.Empty;
+ if (ordinal - _exportDirectory->Base >= _exportDirectory->NumberOfFunctions)
+ return ImageExportFunction.Empty;
+
+ int rva = _addressTable[ordinal - _exportDirectory->Base];
+
+ if (
+ rva >= _dataDirectory->VirtualAddress &&
+ rva < _dataDirectory->VirtualAddress + _dataDirectory->Size
+ )
+ {
+ // This is a forwarder RVA.
+ return new ImageExportFunction() { ForwardedName = new string((sbyte*)_mappedImage.RvaToVa(rva)) };
+ }
+ else
+ {
+ // This is a function RVA.
+ return new ImageExportFunction() { Function = (IntPtr)_mappedImage.RvaToVa(rva) };
+ }
+ }
+
+ private int LookupName(string name)
+ {
+ int low = 0;
+ int high = _exportDirectory->NumberOfNames - 1;
+
+ // Do a binary search.
+ while (low <= high)
+ {
+ int i;
+ string n;
+
+ i = (low + high) / 2;
+ n = new string((sbyte*)_mappedImage.RvaToVa(_namePointerTable[i]));
+
+ if (name == n)
+ {
+ return i;
+ }
+ else if (name.CompareTo(n) > 0)
+ {
+ low = i + 1;
+ }
+ else
+ {
+ high = i - 1;
+ }
+ }
+
+ return -1;
+ }
+ }
+
+ public struct ImageExportEntry
+ {
+ public static readonly ImageExportEntry Empty = new ImageExportEntry();
+
+ public string Name;
+ public short Ordinal;
+ }
+
+ public struct ImageExportFunction
+ {
+ public static readonly ImageExportFunction Empty = new ImageExportFunction();
+
+ public IntPtr Function;
+ public string ForwardedName;
+ }
+}
diff --git a/trunk/ProcessHacker.Native/Image/ImageImports.cs b/trunk/ProcessHacker.Native/Image/ImageImports.cs
new file mode 100644
index 000000000..18bddd80a
--- /dev/null
+++ b/trunk/ProcessHacker.Native/Image/ImageImports.cs
@@ -0,0 +1,197 @@
+/*
+ * Process Hacker -
+ * image imports reader
+ *
+ * Copyright (C) 2009 wj32
+ *
+ * This file is part of Process Hacker.
+ *
+ * Process Hacker is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Process Hacker 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Process Hacker. If not, see .
+ */
+
+using ProcessHacker.Native.Api;
+
+namespace ProcessHacker.Native.Image
+{
+ public unsafe sealed class ImageImports
+ {
+ public delegate bool EnumEntriesDelegate(ImageExportEntry entry);
+
+ private MappedImage _mappedImage;
+ private int _count;
+ private ImageImportDescriptor* _descriptorTable;
+ private ImageImportDll[] _dlls;
+
+ internal ImageImports(MappedImage mappedImage)
+ {
+ _mappedImage = mappedImage;
+ _descriptorTable = mappedImage.GetImportDirectory();
+
+ // Do a quick scan.
+ if (_descriptorTable != null)
+ {
+ int i = 0;
+
+ while (_descriptorTable[i].OriginalFirstThunk != 0)
+ i++;
+
+ _count = i;
+ _dlls = new ImageImportDll[i];
+ }
+ }
+
+ public ImageImportDll this[int index]
+ {
+ get { return this.GetDll(index); }
+ }
+
+ public int Count
+ {
+ get { return _count; }
+ }
+
+ public ImageImportDll GetDll(int index)
+ {
+ if (_descriptorTable == null)
+ return null;
+
+ if (index < _count)
+ {
+ if (_dlls[index] == null)
+ _dlls[index] = new ImageImportDll(_mappedImage, &_descriptorTable[index]);
+
+ return _dlls[index];
+ }
+ else
+ {
+ return null;
+ }
+ }
+ }
+
+ public unsafe sealed class ImageImportDll
+ {
+ private MappedImage _mappedImage;
+ private ImageImportDescriptor* _descriptor;
+ private string _name;
+ private void* _lookupTable;
+ private int _count;
+
+ internal ImageImportDll(MappedImage mappedImage, ImageImportDescriptor* descriptor)
+ {
+ _mappedImage = mappedImage;
+ _descriptor = descriptor;
+
+ _lookupTable = _mappedImage.RvaToVa(_descriptor->OriginalFirstThunk);
+
+ // Do a quick scan.
+ if (_lookupTable != null)
+ {
+ int i = 0;
+
+ if (_mappedImage.Magic == Win32.Pe32Magic)
+ {
+ while (((int*)_lookupTable)[i] != 0)
+ i++;
+ }
+ else if (_mappedImage.Magic == Win32.Pe32PlusMagic)
+ {
+ while (((long*)_lookupTable)[i] != 0)
+ i++;
+ }
+
+ _count = i;
+ }
+ }
+
+ public ImageImportEntry this[int index]
+ {
+ get { return this.GetEntry(index); }
+ }
+
+ public int Count
+ {
+ get { return _count; }
+ }
+
+ public string Name
+ {
+ get
+ {
+ if (_name == null)
+ _name = new string((sbyte*)_mappedImage.RvaToVa(_descriptor->Name));
+
+ return _name;
+ }
+ }
+
+ public ImageImportEntry GetEntry(int index)
+ {
+ if (index >= _count)
+ return ImageImportEntry.Empty;
+
+ if (_mappedImage.Magic == Win32.Pe32Magic)
+ {
+ int entry = ((int*)_lookupTable)[index];
+
+ // Is this entry using an ordinal?
+ if ((entry & 0x80000000) != 0)
+ {
+ return new ImageImportEntry() { Ordinal = (short)(entry & 0xffff) };
+ }
+ else
+ {
+ ImageImportByName* nameEntry = (ImageImportByName*)_mappedImage.RvaToVa(entry);
+
+ return new ImageImportEntry()
+ {
+ NameHint = nameEntry->Hint,
+ Name = new string((sbyte*)&nameEntry->Name)
+ };
+ }
+ }
+ else if (_mappedImage.Magic == Win32.Pe32PlusMagic)
+ {
+ long entry = ((long*)_lookupTable)[index];
+
+ // Is this entry using an ordinal?
+ if (((ulong)entry & 0x8000000000000000) != 0)
+ {
+ return new ImageImportEntry() { Ordinal = (short)(entry & 0xffff) };
+ }
+ else
+ {
+ ImageImportByName* nameEntry = (ImageImportByName*)_mappedImage.RvaToVa((int)(entry & 0xffffffff));
+
+ return new ImageImportEntry()
+ {
+ NameHint = nameEntry->Hint,
+ Name = new string((sbyte*)&nameEntry->Name)
+ };
+ }
+ }
+
+ return ImageImportEntry.Empty;
+ }
+ }
+
+ public struct ImageImportEntry
+ {
+ public static readonly ImageImportEntry Empty;
+
+ public short Ordinal;
+ public short NameHint;
+ public string Name;
+ }
+}
diff --git a/trunk/ProcessHacker.Native/Image/MappedImage.cs b/trunk/ProcessHacker.Native/Image/MappedImage.cs
new file mode 100644
index 000000000..f9ed43ac0
--- /dev/null
+++ b/trunk/ProcessHacker.Native/Image/MappedImage.cs
@@ -0,0 +1,314 @@
+/*
+ * Process Hacker -
+ * image mapper and reader
+ *
+ * Copyright (C) 2009 wj32
+ *
+ * This file is part of Process Hacker.
+ *
+ * Process Hacker is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Process Hacker 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Process Hacker. If not, see .
+ */
+
+using System;
+using ProcessHacker.Common.Objects;
+using ProcessHacker.Native.Api;
+using ProcessHacker.Native.Objects;
+using ProcessHacker.Native.Security;
+
+namespace ProcessHacker.Native.Image
+{
+ public unsafe sealed class MappedImage : BaseObject
+ {
+ private SectionView _view;
+ private int _size;
+ private void* _memory;
+ private ImageNtHeaders* _ntHeaders;
+ private ImageSectionHeader* _sections;
+ private short _magic;
+
+ private ImageExports _exports;
+ private ImageImports _imports;
+
+ public MappedImage(string fileName)
+ : this(fileName, true)
+ { }
+
+ public MappedImage(string fileName, bool readOnly)
+ {
+ using (var fhandle = FileHandle.CreateWin32(
+ fileName,
+ readOnly ? (FileAccess.Execute | FileAccess.ReadAttributes | FileAccess.ReadData) :
+ (FileAccess.AppendData | FileAccess.Execute | FileAccess.ReadAttributes | FileAccess.ReadData | FileAccess.WriteAttributes | FileAccess.WriteData),
+ FileShareMode.Read,
+ FileCreationDispositionWin32.OpenExisting
+ ))
+ this.MapAndLoad(fhandle, readOnly);
+ }
+
+ public MappedImage(FileHandle fileHandle, bool readOnly)
+ {
+ this.MapAndLoad(fileHandle, readOnly);
+ }
+
+ protected override void DisposeObject(bool disposing)
+ {
+ if (_view != null)
+ _view.Dispose(disposing);
+ }
+
+ public ImageExports Exports
+ {
+ get
+ {
+ if (_exports == null)
+ _exports = new ImageExports(this);
+
+ return _exports;
+ }
+ }
+
+ public ImageImports Imports
+ {
+ get
+ {
+ if (_imports == null)
+ _imports = new ImageImports(this);
+
+ return _imports;
+ }
+ }
+
+ public short Magic
+ {
+ get { return _magic; }
+ }
+
+ public void* Memory
+ {
+ get { return _memory; }
+ }
+
+ public int NumberOfDataEntries
+ {
+ get
+ {
+ if (_magic == Win32.Pe32Magic)
+ return this.GetOptionalHeader()->NumberOfRvaAndSizes;
+ else if (_magic == Win32.Pe32PlusMagic)
+ return this.GetOptionalHeader64()->NumberOfRvaAndSizes;
+ else
+ return 0;
+ }
+ }
+
+ public int NumberOfSections
+ {
+ get { return _ntHeaders->FileHeader.NumberOfSections; }
+ }
+
+ public ImageNtHeaders* NtHeaders
+ {
+ get { return _ntHeaders; }
+ }
+
+ public ImageSectionHeader* Sections
+ {
+ get { return _sections; }
+ }
+
+ public int Size
+ {
+ get { return _size; }
+ }
+
+ public int GetChecksum()
+ {
+ int oldChecksum;
+
+ return this.GetChecksum(out oldChecksum);
+ }
+
+ public int GetChecksum(out int oldChecksum)
+ {
+ int checksum;
+
+ if (Win32.CheckSumMappedFile(_view, _size, out oldChecksum, out checksum) == IntPtr.Zero)
+ Win32.ThrowLastError();
+
+ return checksum;
+ }
+
+ public ImageDataDirectory* GetDataEntry(ImageDataEntry entry)
+ {
+ if (_magic == Win32.Pe32Magic)
+ {
+ if ((int)entry >= _ntHeaders->OptionalHeader.NumberOfRvaAndSizes)
+ return null;
+
+ return &(&_ntHeaders->OptionalHeader.DataDirectory)[(int)entry];
+ }
+ else if (_magic == Win32.Pe32PlusMagic)
+ {
+ if ((int)entry >= this.GetOptionalHeader64()->NumberOfRvaAndSizes)
+ return null;
+
+ return &(&this.GetOptionalHeader64()->DataDirectory)[(int)entry];
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ public ImageExportDirectory* GetExportDirectory()
+ {
+ ImageDataDirectory* dataEntry;
+
+ dataEntry = this.GetDataEntry(ImageDataEntry.Export);
+
+ return (ImageExportDirectory*)this.RvaToVa(dataEntry->VirtualAddress);
+ }
+
+ public ImageImportDescriptor* GetImportDirectory()
+ {
+ ImageDataDirectory* dataEntry;
+
+ dataEntry = this.GetDataEntry(ImageDataEntry.Import);
+
+ return (ImageImportDescriptor*)this.RvaToVa(dataEntry->VirtualAddress);
+ }
+
+ private void* GetLoadConfig(short magic)
+ {
+ ImageDataDirectory* dataEntry;
+
+ if (_magic != magic)
+ return null;
+
+ dataEntry = this.GetDataEntry(ImageDataEntry.LoadConfig);
+
+ if (dataEntry == null)
+ return null;
+
+ return this.RvaToVa(dataEntry->VirtualAddress);
+ }
+
+ public ImageLoadConfigDirectory* GetLoadConfig()
+ {
+ return (ImageLoadConfigDirectory*)this.GetLoadConfig(Win32.Pe32Magic);
+ }
+
+ public ImageLoadConfigDirectory64* GetLoadConfig64()
+ {
+ return (ImageLoadConfigDirectory64*)this.GetLoadConfig(Win32.Pe32PlusMagic);
+ }
+
+ private ImageNtHeaders* GetNtHeaders()
+ {
+ int offset;
+ ImageNtHeaders* ntHeaders;
+
+ offset = *((int*)((byte*)_memory + 0x3c));
+
+ if (offset == 0)
+ throw new Exception("Invalid NT headers offset.");
+ if (offset >= 0x10000000 || offset >= _size)
+ throw new Exception("The NT headers offset is too large.");
+
+ ntHeaders = (ImageNtHeaders*)((byte*)_memory + offset);
+
+ return ntHeaders;
+ }
+
+ private void* GetOptionalHeader(short magic)
+ {
+ if (_magic != magic)
+ return null;
+
+ return &_ntHeaders->OptionalHeader;
+ }
+
+ public ImageOptionalHeader* GetOptionalHeader()
+ {
+ return (ImageOptionalHeader*)this.GetOptionalHeader(Win32.Pe32Magic);
+ }
+
+ public ImageOptionalHeader64* GetOptionalHeader64()
+ {
+ return (ImageOptionalHeader64*)this.GetOptionalHeader(Win32.Pe32PlusMagic);
+ }
+
+ public string GetSectionName(ImageSectionHeader* section)
+ {
+ return new string((sbyte*)section->Name, 0, 8).TrimEnd('\0');
+ }
+
+ private void MapAndLoad(FileHandle fileHandle, bool readOnly)
+ {
+ using (Section section = new Section(
+ fileHandle,
+ false,
+ readOnly ? MemoryProtection.ExecuteRead : MemoryProtection.ExecuteReadWrite
+ ))
+ {
+ _size = (int)fileHandle.GetSize();
+ _view = section.MapView(_size);
+ _memory = _view;
+
+ byte* start = (byte*)_memory;
+
+ if (start[0] != 'M' || start[1] != 'Z')
+ throw new Exception("The file is not a valid executable image.");
+
+ _ntHeaders = this.GetNtHeaders();
+ _sections = (ImageSectionHeader*)((byte*)&_ntHeaders->OptionalHeader + _ntHeaders->FileHeader.SizeOfOptionalHeader);
+ _magic = _ntHeaders->OptionalHeader.Magic;
+
+ if (_magic != Win32.Pe32Magic && _magic != Win32.Pe32PlusMagic)
+ throw new Exception("The file is not a PE32 or PE32+ image.");
+ }
+ }
+
+ public ImageSectionHeader* RvaToSection(int rva)
+ {
+ if (_ntHeaders->FileHeader.NumberOfSections == 0)
+ return null;
+
+ for (int i = 0; i < _ntHeaders->FileHeader.NumberOfSections; i++)
+ {
+ if (
+ rva >= _sections[i].VirtualAddress &&
+ rva < (_sections[i].VirtualAddress + _sections[i].SizeOfRawData)
+ )
+ {
+ return &_sections[i];
+ }
+ }
+
+ return null;
+ }
+
+ public void* RvaToVa(int rva)
+ {
+ ImageSectionHeader* section;
+
+ section = this.RvaToSection(rva);
+
+ if (section == null)
+ return null;
+
+ return (byte*)_memory + section->PointerToRawData - section->VirtualAddress + rva;
+ }
+ }
+}
diff --git a/trunk/ProcessHacker.Native/IntPtrExtensions.cs b/trunk/ProcessHacker.Native/IntPtrExtensions.cs
index 62ffb1918..8196c9f62 100644
--- a/trunk/ProcessHacker.Native/IntPtrExtensions.cs
+++ b/trunk/ProcessHacker.Native/IntPtrExtensions.cs
@@ -149,22 +149,12 @@ namespace ProcessHacker.Native
public static bool IsGreaterThanOrEqualTo(this IntPtr ptr, IntPtr ptr2)
{
- int result = ptr.CompareTo(ptr2);
-
- if (result == 0 || result == 1)
- return true;
-
- return false;
+ return ptr.CompareTo(ptr2) >= 0;
}
public static bool IsLessThanOrEqualTo(this IntPtr ptr, IntPtr ptr2)
{
- int result = ptr.CompareTo(ptr2);
-
- if (result == -1 || result == 0)
- return true;
-
- return false;
+ return ptr.CompareTo(ptr2) <= 0;
}
public static IntPtr Not(this IntPtr ptr)
@@ -188,7 +178,7 @@ namespace ProcessHacker.Native
// Avoid sign-extending the pointer - we want it zero-extended.
unsafe
{
- void* voidPtr = ptr.ToPointer();
+ void* voidPtr = (void*)ptr;
return (uint)voidPtr;
}
@@ -199,7 +189,7 @@ namespace ProcessHacker.Native
// Avoid sign-extending the pointer - we want it zero-extended.
unsafe
{
- void* voidPtr = ptr.ToPointer();
+ void* voidPtr = (void*)ptr;
return (ulong)voidPtr;
}
diff --git a/trunk/ProcessHacker.Native/Ipc/IpcCircularBuffer.cs b/trunk/ProcessHacker.Native/Ipc/IpcCircularBuffer.cs
index 503c88826..d8f935285 100644
--- a/trunk/ProcessHacker.Native/Ipc/IpcCircularBuffer.cs
+++ b/trunk/ProcessHacker.Native/Ipc/IpcCircularBuffer.cs
@@ -111,7 +111,7 @@ namespace ProcessHacker.Native.Ipc
}
_sectionView = _section.MapView(header.BlockSize * header.NumberOfBlocks);
- _header = (BufferHeader*)_sectionView.Memory.ToPointer();
+ _header = (BufferHeader*)_sectionView.Memory;
_data = &_header->Data;
}
@@ -133,7 +133,7 @@ namespace ProcessHacker.Native.Ipc
public void Read(MemoryRegion data)
{
- this.Read(data.Memory.ToPointer());
+ this.Read((void*)data.Memory);
}
public void Read(void* buffer)
@@ -185,7 +185,7 @@ namespace ProcessHacker.Native.Ipc
public void Write(MemoryRegion data, int offset)
{
- this.Write(data.Memory.Increment(offset).ToPointer());
+ this.Write((void*)data.Memory.Increment(offset));
}
public void Write(void* buffer)
diff --git a/trunk/ProcessHacker.Native/Memory/MemoryAlloc.cs b/trunk/ProcessHacker.Native/Memory/MemoryAlloc.cs
index 96e402ebb..c22a701e3 100644
--- a/trunk/ProcessHacker.Native/Memory/MemoryAlloc.cs
+++ b/trunk/ProcessHacker.Native/Memory/MemoryAlloc.cs
@@ -38,9 +38,9 @@ namespace ProcessHacker.Native
private static Heap _privateHeap = new Heap(HeapFlags.Class1 | HeapFlags.Growable);
private static Heap _processHeap = Heap.GetDefault();
- public static IntPtr PrivateHeap
+ public static Heap PrivateHeap
{
- get { return _privateHeap.Address; }
+ get { return _privateHeap; }
}
///
diff --git a/trunk/ProcessHacker.Native/Objects/FileHandle.cs b/trunk/ProcessHacker.Native/Objects/FileHandle.cs
index fc2456316..d53680601 100644
--- a/trunk/ProcessHacker.Native/Objects/FileHandle.cs
+++ b/trunk/ProcessHacker.Native/Objects/FileHandle.cs
@@ -1548,13 +1548,13 @@ namespace ProcessHacker.Native.Objects
public UnmanagedIsb()
{
- _ioStatusBlock = (IoStatusBlock*)Heap.FromHandle(MemoryAlloc.PrivateHeap).Allocate(0, _isbSize).ToPointer();
+ _ioStatusBlock = (IoStatusBlock*)MemoryAlloc.PrivateHeap.Allocate(0, _isbSize);
}
protected override void DisposeObject(bool disposing)
{
if (_ioStatusBlock != null)
- Heap.FromHandle(MemoryAlloc.PrivateHeap).Free(0, new IntPtr(_ioStatusBlock));
+ MemoryAlloc.PrivateHeap.Free(0, new IntPtr(_ioStatusBlock));
}
public IntPtr Information
diff --git a/trunk/ProcessHacker.Native/Objects/SectionHandle.cs b/trunk/ProcessHacker.Native/Objects/SectionHandle.cs
index 5878ff82b..442cf9118 100644
--- a/trunk/ProcessHacker.Native/Objects/SectionHandle.cs
+++ b/trunk/ProcessHacker.Native/Objects/SectionHandle.cs
@@ -251,7 +251,7 @@ namespace ProcessHacker.Native.Objects
)) >= NtStatus.Error)
Win32.ThrowLastError(status);
- return new SectionView(baseAddress, commitSize);
+ return new SectionView(baseAddress, viewSize);
}
}
}
diff --git a/trunk/ProcessHacker.Native/ProcessHacker.Native.csproj b/trunk/ProcessHacker.Native/ProcessHacker.Native.csproj
index f1e5643a2..40e4fb3a3 100644
--- a/trunk/ProcessHacker.Native/ProcessHacker.Native.csproj
+++ b/trunk/ProcessHacker.Native/ProcessHacker.Native.csproj
@@ -62,6 +62,10 @@
+
+
+
+
diff --git a/trunk/ProcessHacker.Native/Windows.cs b/trunk/ProcessHacker.Native/Windows.cs
index 346ed8106..167c3b7fb 100644
--- a/trunk/ProcessHacker.Native/Windows.cs
+++ b/trunk/ProcessHacker.Native/Windows.cs
@@ -818,7 +818,7 @@ namespace ProcessHacker.Native
{
unsafe
{
- return QueryKSystemTime((KSystemTime*)time.ToPointer());
+ return QueryKSystemTime((KSystemTime*)time);
}
}
diff --git a/trunk/ProcessHacker/Common/PhUtils.cs b/trunk/ProcessHacker/Common/PhUtils.cs
index d830c3f68..eb1a52bc8 100644
--- a/trunk/ProcessHacker/Common/PhUtils.cs
+++ b/trunk/ProcessHacker/Common/PhUtils.cs
@@ -423,7 +423,17 @@ namespace ProcessHacker.Common
/// The exception to notify the user of.
public static void ShowException(string operation, Exception ex)
{
+#if !DEBUG
MessageBox.Show(Form.ActiveForm, FormatException(operation, ex), "Process Hacker", MessageBoxButtons.OK, MessageBoxIcon.Error);
+#else
+ MessageBox.Show(
+ Form.ActiveForm,
+ operation + "\n\n" + ex.ToString(),
+ "Process Hacker",
+ MessageBoxButtons.OK,
+ MessageBoxIcon.Error
+ );
+#endif
}
///
diff --git a/trunk/ProcessHacker/Forms/PEWindow.Designer.cs b/trunk/ProcessHacker/Forms/PEWindow.Designer.cs
index 1d1e260e4..5b15c0fa3 100644
--- a/trunk/ProcessHacker/Forms/PEWindow.Designer.cs
+++ b/trunk/ProcessHacker/Forms/PEWindow.Designer.cs
@@ -58,7 +58,6 @@
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.tabImports = new System.Windows.Forms.TabPage();
this.listImports = new ProcessHacker.ExtendedListView();
@@ -277,9 +276,8 @@
// listExports
//
this.listExports.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
- this.columnExportName,
this.columnExportOrdinal,
- this.columnExportRVA,
+ this.columnExportName,
this.columnExportFileAddress});
this.listExports.Dock = System.Windows.Forms.DockStyle.Fill;
this.listExports.FullRowSelect = true;
@@ -299,17 +297,12 @@
// columnExportName
//
this.columnExportName.Text = "Name";
- this.columnExportName.Width = 120;
+ this.columnExportName.Width = 220;
//
// columnExportOrdinal
//
this.columnExportOrdinal.Text = "Ordinal";
//
- // columnExportRVA
- //
- this.columnExportRVA.Text = "RVA";
- this.columnExportRVA.Width = 80;
- //
// columnExportFileAddress
//
this.columnExportFileAddress.Text = "File Address";
@@ -393,7 +386,6 @@
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.ListView listCOFFHeader;
private System.Windows.Forms.ColumnHeader columnCHName;
diff --git a/trunk/ProcessHacker/Forms/PEWindow.cs b/trunk/ProcessHacker/Forms/PEWindow.cs
index 7ce18f278..c5816e50f 100644
--- a/trunk/ProcessHacker/Forms/PEWindow.cs
+++ b/trunk/ProcessHacker/Forms/PEWindow.cs
@@ -24,16 +24,17 @@ using System;
using System.Collections.Generic;
using System.Windows.Forms;
using ProcessHacker.Common;
-using ProcessHacker.PE;
using ProcessHacker.UI;
+using ProcessHacker.Native;
+using ProcessHacker.Native.Image;
+using ProcessHacker.Native.Api;
namespace ProcessHacker
{
public partial class PEWindow : Form
{
private string _path;
- private PEFile _peFile;
- private List _exportVAs;
+ private MappedImage _mappedImage;
public PEWindow(string path)
{
@@ -49,7 +50,8 @@ namespace ProcessHacker
try
{
- this.Read(_path);
+ _mappedImage = new MappedImage(path);
+ this.Read();
}
catch (Exception ex)
{
@@ -77,6 +79,9 @@ namespace ProcessHacker
Properties.Settings.Default.PEExportsColumns = ColumnSettings.SaveSettings(listExports);
Properties.Settings.Default.PEImportsColumns = ColumnSettings.SaveSettings(listImports);
Properties.Settings.Default.PEWindowSize = this.Size;
+
+ if (_mappedImage != null)
+ _mappedImage.Dispose();
}
private void InitializeLists()
@@ -121,34 +126,28 @@ namespace ProcessHacker
get { return _path; }
}
- private void Read(string path)
+ private unsafe void Read()
{
- PEFile peFile;
-
- peFile = new PEFile(path);
-
- _peFile = peFile;
-
- // preprare lists
+ // Preprare lists
#region COFF Header
// COFF header
listCOFFHeader.Items.Clear();
listCOFFHeader.Items.Add(new ListViewItem(new string[] { "Target Machine",
- _peFile.COFFHeader.Machine.ToString() }));
+ _mappedImage.NtHeaders->FileHeader.Machine.ToString() }));
listCOFFHeader.Items.Add(new ListViewItem(new string[] { "Number of Sections",
- _peFile.COFFHeader.NumberOfSections.ToString() }));
+ _mappedImage.NtHeaders->FileHeader.NumberOfSections.ToString() }));
listCOFFHeader.Items.Add(new ListViewItem(new string[] { "Time/Date Stamp",
- Utils.GetDateTimeFromUnixTime(_peFile.COFFHeader.TimeDateStamp).ToString() }));
+ Utils.GetDateTimeFromUnixTime((uint)_mappedImage.NtHeaders->FileHeader.TimeDateStamp).ToString() }));
listCOFFHeader.Items.Add(new ListViewItem(new string[] { "Pointer to Symbol Table",
- Utils.FormatAddress(_peFile.COFFHeader.PointerToSymbolTable) }));
+ Utils.FormatAddress(_mappedImage.NtHeaders->FileHeader.PointerToSymbolTable) }));
listCOFFHeader.Items.Add(new ListViewItem(new string[] { "Number of Symbols",
- _peFile.COFFHeader.NumberOfSymbols.ToString() }));
+ _mappedImage.NtHeaders->FileHeader.NumberOfSymbols.ToString() }));
listCOFFHeader.Items.Add(new ListViewItem(new string[] { "Size of Optional Header",
- _peFile.COFFHeader.SizeOfOptionalHeader.ToString() }));
+ _mappedImage.NtHeaders->FileHeader.SizeOfOptionalHeader.ToString() }));
listCOFFHeader.Items.Add(new ListViewItem(new string[] { "Characteristics",
- Utils.FormatFlags(typeof(ImageCharacteristics), (long)_peFile.COFFHeader.Characteristics) }));
+ _mappedImage.NtHeaders->FileHeader.Characteristics.ToString() }));
#endregion
@@ -157,60 +156,57 @@ namespace ProcessHacker
// 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") + ")") }));
+ _mappedImage.NtHeaders->OptionalHeader.Magic == Win32.Pe32Magic ? "PE32 (0x10b)" :
+ (_mappedImage.NtHeaders->OptionalHeader.Magic == Win32.Pe32PlusMagic ? "PE32+ (0x20b)" :
+ "Unknown (0x" + _mappedImage.NtHeaders->OptionalHeader.Magic.ToString("x") + ")") }));
listCOFFOptionalHeader.Items.Add(new ListViewItem(new string[] { "Linker Version",
- _peFile.COFFOptionalHeader.MajorLinkerVersion.ToString() + "." +
- _peFile.COFFOptionalHeader.MinorLinkerVersion.ToString() }));
+ _mappedImage.NtHeaders->OptionalHeader.MajorLinkerVersion.ToString() + "." +
+ _mappedImage.NtHeaders->OptionalHeader.MinorLinkerVersion.ToString() }));
listCOFFOptionalHeader.Items.Add(new ListViewItem(new string[] { "Size of Code",
- "0x" + _peFile.COFFOptionalHeader.SizeOfCode.ToString("x") }));
+ "0x" + _mappedImage.NtHeaders->OptionalHeader.SizeOfCode.ToString("x") }));
listCOFFOptionalHeader.Items.Add(new ListViewItem(new string[] { "Size of Initialized Data",
- "0x" + _peFile.COFFOptionalHeader.SizeOfInitializedData.ToString("x") }));
+ "0x" + _mappedImage.NtHeaders->OptionalHeader.SizeOfInitializedData.ToString("x") }));
listCOFFOptionalHeader.Items.Add(new ListViewItem(new string[] { "Size of Uninitialized Data",
- "0x" + _peFile.COFFOptionalHeader.SizeOfUninitializedData.ToString("x") }));
+ "0x" + _mappedImage.NtHeaders->OptionalHeader.SizeOfUninitializedData.ToString("x") }));
listCOFFOptionalHeader.Items.Add(new ListViewItem(new string[] { "Entry Point RVA",
- "0x" + _peFile.COFFOptionalHeader.AddressOfEntryPoint.ToString("x") }));
+ "0x" + _mappedImage.NtHeaders->OptionalHeader.AddressOfEntryPoint.ToString("x") }));
listCOFFOptionalHeader.Items.Add(new ListViewItem(new string[] { "Base of Code",
- "0x" + _peFile.COFFOptionalHeader.BaseOfCode.ToString("x") }));
- if (_peFile.COFFOptionalHeader.Magic == COFFOptionalHeader.PE32PlusMagic)
- listCOFFOptionalHeader.Items.Add(new ListViewItem(new string[] { "Base of Data",
- "0x" + _peFile.COFFOptionalHeader.BaseOfData.ToString("x") }));
+ "0x" + _mappedImage.NtHeaders->OptionalHeader.BaseOfCode.ToString("x") }));
listCOFFOptionalHeader.Items.Add(new ListViewItem(new string[] { "Preferred Image Base",
- "0x" + _peFile.COFFOptionalHeader.ImageBase.ToString("x") }));
+ "0x" + _mappedImage.NtHeaders->OptionalHeader.ImageBase.ToString("x") }));
listCOFFOptionalHeader.Items.Add(new ListViewItem(new string[] { "Section Alignment",
- _peFile.COFFOptionalHeader.SectionAlignment.ToString() }));
+ _mappedImage.NtHeaders->OptionalHeader.SectionAlignment.ToString() }));
listCOFFOptionalHeader.Items.Add(new ListViewItem(new string[] { "File Alignment",
- _peFile.COFFOptionalHeader.FileAlignment.ToString() }));
+ _mappedImage.NtHeaders->OptionalHeader.FileAlignment.ToString() }));
listCOFFOptionalHeader.Items.Add(new ListViewItem(new string[] { "Operating System Version",
- _peFile.COFFOptionalHeader.MajorOperatingSystemVersion.ToString() + "." +
- _peFile.COFFOptionalHeader.MinorOperatingSystemVersion.ToString() }));
+ _mappedImage.NtHeaders->OptionalHeader.MajorOperatingSystemVersion.ToString() + "." +
+ _mappedImage.NtHeaders->OptionalHeader.MinorOperatingSystemVersion.ToString() }));
listCOFFOptionalHeader.Items.Add(new ListViewItem(new string[] { "Image Version",
- _peFile.COFFOptionalHeader.MajorImageVersion.ToString() + "." +
- _peFile.COFFOptionalHeader.MinorImageVersion.ToString() }));
+ _mappedImage.NtHeaders->OptionalHeader.MajorImageVersion.ToString() + "." +
+ _mappedImage.NtHeaders->OptionalHeader.MinorImageVersion.ToString() }));
listCOFFOptionalHeader.Items.Add(new ListViewItem(new string[] { "Subsystem Version",
- _peFile.COFFOptionalHeader.MajorSubsystemVersion.ToString() + "." +
- _peFile.COFFOptionalHeader.MinorSubsystemVersion.ToString() }));
+ _mappedImage.NtHeaders->OptionalHeader.MajorSubsystemVersion.ToString() + "." +
+ _mappedImage.NtHeaders->OptionalHeader.MinorSubsystemVersion.ToString() }));
listCOFFOptionalHeader.Items.Add(new ListViewItem(new string[] { "Size of Image",
- "0x" + _peFile.COFFOptionalHeader.SizeOfImage.ToString("x") }));
+ "0x" + _mappedImage.NtHeaders->OptionalHeader.SizeOfImage.ToString("x") }));
listCOFFOptionalHeader.Items.Add(new ListViewItem(new string[] { "Size of Headers",
- "0x" + _peFile.COFFOptionalHeader.SizeOfHeaders.ToString("x") }));
+ "0x" + _mappedImage.NtHeaders->OptionalHeader.SizeOfHeaders.ToString("x") }));
listCOFFOptionalHeader.Items.Add(new ListViewItem(new string[] { "Checksum",
- "0x" + _peFile.COFFOptionalHeader.CheckSum.ToString("x") }));
+ "0x" + _mappedImage.NtHeaders->OptionalHeader.CheckSum.ToString("x") }));
listCOFFOptionalHeader.Items.Add(new ListViewItem(new string[] { "Subsystem",
- _peFile.COFFOptionalHeader.Subsystem.ToString() }));
+ _mappedImage.NtHeaders->OptionalHeader.Subsystem.ToString() }));
listCOFFOptionalHeader.Items.Add(new ListViewItem(new string[] { "DLL Characteristics",
- Utils.FormatFlags(typeof(DllCharacteristics), (long)_peFile.COFFOptionalHeader.DllCharacteristics) }));
+ _mappedImage.NtHeaders->OptionalHeader.DllCharacteristics.ToString() }));
listCOFFOptionalHeader.Items.Add(new ListViewItem(new string[] { "Size of Stack Reserve",
- "0x" + _peFile.COFFOptionalHeader.SizeOfStackReserve.ToString("x") }));
+ "0x" + _mappedImage.NtHeaders->OptionalHeader.SizeOfStackReserve.ToString("x") }));
listCOFFOptionalHeader.Items.Add(new ListViewItem(new string[] { "Size of Stack Commit",
- "0x" + _peFile.COFFOptionalHeader.SizeOfStackCommit.ToString("x") }));
+ "0x" + _mappedImage.NtHeaders->OptionalHeader.SizeOfStackCommit.ToString("x") }));
listCOFFOptionalHeader.Items.Add(new ListViewItem(new string[] { "Size of Heap Reserve",
- "0x" + _peFile.COFFOptionalHeader.SizeOfHeapReserve.ToString("x") }));
+ "0x" + _mappedImage.NtHeaders->OptionalHeader.SizeOfHeapReserve.ToString("x") }));
listCOFFOptionalHeader.Items.Add(new ListViewItem(new string[] { "Size of Heap Commit",
- "0x" + _peFile.COFFOptionalHeader.SizeOfHeapCommit.ToString("x") }));
+ "0x" + _mappedImage.NtHeaders->OptionalHeader.SizeOfHeapCommit.ToString("x") }));
listCOFFOptionalHeader.Items.Add(new ListViewItem(new string[] { "Number of Data Directory Entries",
- _peFile.COFFOptionalHeader.NumberOfRvaAndSizes.ToString() }));
+ _mappedImage.NtHeaders->OptionalHeader.NumberOfRvaAndSizes.ToString() }));
#endregion
@@ -218,18 +214,19 @@ namespace ProcessHacker
listImageData.Items.Clear();
- for (int i = 0; i < _peFile.ImageData.Count; i++)
+ for (int i = 0; i < _mappedImage.NumberOfDataEntries; i++)
{
- ImageDataType type = (ImageDataType)i;
- ImageData data = _peFile.ImageData[type];
+ ImageDataDirectory* dataEntry;
- if (data.VirtualAddress != 0)
+ dataEntry = _mappedImage.GetDataEntry((ImageDataEntry)i);
+
+ if (dataEntry != null && dataEntry->VirtualAddress != 0)
{
ListViewItem item = new ListViewItem();
- item.Text = type.ToString();
- item.SubItems.Add(new ListViewItem.ListViewSubItem(item, "0x" + data.VirtualAddress.ToString("x")));
- item.SubItems.Add(new ListViewItem.ListViewSubItem(item, "0x" + data.Size.ToString("x")));
+ item.Text = ((ImageDataEntry)i).ToString();
+ item.SubItems.Add(new ListViewItem.ListViewSubItem(item, "0x" + dataEntry->VirtualAddress.ToString("x")));
+ item.SubItems.Add(new ListViewItem.ListViewSubItem(item, "0x" + dataEntry->Size.ToString("x")));
listImageData.Items.Add(item);
}
@@ -241,16 +238,16 @@ namespace ProcessHacker
listSections.Items.Clear();
- foreach (SectionHeader sh in _peFile.Sections)
+ for (int i = 0; i < _mappedImage.NumberOfSections; i++)
{
+ ImageSectionHeader* section = &_mappedImage.Sections[i];
ListViewItem item = new ListViewItem();
- item.Text = sh.Name;
- item.SubItems.Add(new ListViewItem.ListViewSubItem(item, "0x" + sh.VirtualAddress.ToString("x")));
- item.SubItems.Add(new ListViewItem.ListViewSubItem(item, "0x" + sh.VirtualSize.ToString("x")));
- item.SubItems.Add(new ListViewItem.ListViewSubItem(item, "0x" + sh.PointerToRawData.ToString("x")));
- item.SubItems.Add(new ListViewItem.ListViewSubItem(item,
- Utils.FormatFlags(typeof(SectionFlags), (long)sh.Characteristics)));
+ item.Text = _mappedImage.GetSectionName(section);
+ item.SubItems.Add(new ListViewItem.ListViewSubItem(item, "0x" + section->VirtualAddress.ToString("x")));
+ item.SubItems.Add(new ListViewItem.ListViewSubItem(item, "0x" + section->SizeOfRawData.ToString("x")));
+ item.SubItems.Add(new ListViewItem.ListViewSubItem(item, "0x" + section->PointerToRawData.ToString("x")));
+ item.SubItems.Add(new ListViewItem.ListViewSubItem(item, section->Characteristics.ToString()));
listSections.Items.Add(item);
}
@@ -259,26 +256,7 @@ namespace ProcessHacker
#region Exports
- if (_peFile.ExportData != null)
- {
- listExports.VirtualListSize = _peFile.ExportData.ExportOrdinalTable.Count;
-
- _exportVAs = new List();
-
- for (int i = 0; i < _peFile.ExportData.ExportAddressTable.Count; i++)
- {
- ExportEntry entry = _peFile.ExportData.ExportAddressTable[i];
-
- if (entry.ExportRVA != 0)
- _exportVAs.Add(_peFile.RvaToVa(entry.ExportRVA));
- else
- _exportVAs.Add(0);
- }
- }
- else
- {
- listExports.VirtualListSize = 0;
- }
+ listExports.VirtualListSize = _mappedImage.Exports.Count;
#endregion
@@ -287,86 +265,64 @@ namespace ProcessHacker
listImports.Items.Clear();
listImports.Groups.Clear();
- if (_peFile.ImportData != null)
- {
- var list = new List>();
+ var list = new List>();
- for (int i = 0; i < _peFile.ImportData.ImportDirectoryTable.Count; i++)
- list.Add(new KeyValuePair(_peFile.ImportData.ImportDirectoryTable[i].Name, i));
+ for (int i = 0; i < _mappedImage.Imports.Count; i++)
+ list.Add(new KeyValuePair(_mappedImage.Imports[i].Name, i));
- list.Sort((kvp1, kvp2) => StringComparer.CurrentCultureIgnoreCase.Compare(kvp1.Key, kvp2.Key));
+ list.Sort((kvp1, kvp2) => StringComparer.CurrentCultureIgnoreCase.Compare(kvp1.Key, kvp2.Key));
- for (int i = 0; i < list.Count; i++)
+ for (int i = 0; i < list.Count; i++)
+ {
+ var dll = _mappedImage.Imports[list[i].Value];
+ int index = list[i].Value;
+
+ listImports.Groups.Add(new ListViewGroup(list[i].Key));
+
+ for (int j = 0; j < dll.Count; j++)
{
- int index = list[i].Value;
+ var entry = dll[j];
+ ListViewItem item = new ListViewItem(listImports.Groups[listImports.Groups.Count - 1]);
- listImports.Groups.Add(new ListViewGroup(list[i].Key));
-
- for (int j = 0; j < _peFile.ImportData.ImportLookupTable[index].Count; j++)
+ if (entry.Name == null)
{
- ImportLookupEntry entry = _peFile.ImportData.ImportLookupTable[index][j];
- ListViewItem item = new ListViewItem(listImports.Groups[listImports.Groups.Count - 1]);
-
- if (entry.UseOrdinal)
- {
- item.Text = "(Ordinal " + entry.Ordinal.ToString() + ")";
- item.SubItems.Add(new ListViewItem.ListViewSubItem());
- }
- else
- {
- item.Text = entry.NameEntry.Name;
- item.SubItems.Add(new ListViewItem.ListViewSubItem(item, entry.NameEntry.Hint.ToString()));
- }
-
- listImports.Items.Add(item);
+ item.Text = "(Ordinal " + entry.Ordinal.ToString() + ")";
+ item.SubItems.Add(new ListViewItem.ListViewSubItem());
}
+ else
+ {
+ item.Text = entry.Name;
+ item.SubItems.Add(new ListViewItem.ListViewSubItem(item, entry.NameHint.ToString()));
+ }
+
+ listImports.Items.Add(item);
}
-
- //we set Groupstate here else there are no groups to set state
- listImports.SetGroupState(ListViewGroupState.Normal | ListViewGroupState.Collapsible);
-
- //foreach (ListViewGroup lvg in listImports.Groups) //Works - just commented out
- //listImports.SetGroupFooter(lvg, "Imports " + lvg.Items.Count + " " + lvg.Header.ToLower() + " item(s)...");
}
+ //we set Groupstate here else there are no groups to set state
+ listImports.SetGroupState(ListViewGroupState.Normal | ListViewGroupState.Collapsible);
+
+ //foreach (ListViewGroup lvg in listImports.Groups) //Works - just commented out
+ //listImports.SetGroupFooter(lvg, "Imports " + lvg.Items.Count + " " + lvg.Header.ToLower() + " item(s)...");
+
#endregion
}
private void listExports_RetrieveVirtualItem(object sender, RetrieveVirtualItemEventArgs e)
{
- if (_peFile != null)
+ unsafe
{
- ushort ordinal = _peFile.ExportData.ExportOrdinalTable[e.ItemIndex];
+ var entry = _mappedImage.Exports.GetEntry(e.ItemIndex);
+ var function = _mappedImage.Exports.GetFunction(entry.Ordinal);
- if (ordinal >= _peFile.ExportData.ExportAddressTable.Count)
- {
- e.Item = new ListViewItem(new string[] { ordinal.ToString(), ordinal.ToString(), "", "" });
- return;
- }
-
- ExportEntry entry = _peFile.ExportData.ExportAddressTable[ordinal];
-
- e.Item = new ListViewItem();
-
- if (e.ItemIndex < _peFile.ExportData.ExportNameTable.Count)
- e.Item.Text = _peFile.ExportData.ExportNameTable[e.ItemIndex];
-
- e.Item.SubItems.Add(new ListViewItem.ListViewSubItem(e.Item, (e.ItemIndex + _peFile.ExportData.OrdinalBase).ToString()));
- e.Item.SubItems.Add(new ListViewItem.ListViewSubItem());
- e.Item.SubItems.Add(new ListViewItem.ListViewSubItem());
-
- if (entry.Type == ExportEntry.ExportType.Export)
- {
- e.Item.SubItems[2].Text = "0x" + entry.ExportRVA.ToString("x");
-
- if (entry.ExportRVA != 0)
- e.Item.SubItems[3].Text = "0x" + _exportVAs[ordinal].ToString("x");
- }
- else if (entry.Type == ExportEntry.ExportType.Forwarder)
- {
- e.Item.ImageIndex = 0;
- e.Item.Text += " > " + entry.ForwardedString;
- }
+ e.Item = new ListViewItem(new string[]
+ {
+ entry.Ordinal.ToString(),
+ function.ForwardedName != null ? entry.Name + " > " + function.ForwardedName : entry.Name,
+ function.ForwardedName == null ?
+ "0x" + function.Function.Decrement(new IntPtr(_mappedImage.Memory)).ToString("x") :
+ ""
+ });
}
}
diff --git a/trunk/ProcessHacker/PE/COFFHeader.cs b/trunk/ProcessHacker/PE/COFFHeader.cs
deleted file mode 100644
index 251967eb6..000000000
--- a/trunk/ProcessHacker/PE/COFFHeader.cs
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Process Hacker -
- * PE/COFF header reader
- *
- * Copyright (C) 2008 wj32
- * Descriptions from the PE/COFF specification from Microsoft.
- *
- * This file is part of Process Hacker.
- *
- * Process Hacker is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Process Hacker 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Process Hacker. If not, see .
- */
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-using System.IO;
-
-namespace ProcessHacker.PE
-{
- ///
- /// Represents a COFF header.
- ///
- public class COFFHeader
- {
- public COFFHeader(BinaryReader br)
- {
- this.Machine = (MachineType)br.ReadUInt16();
- this.NumberOfSections = br.ReadUInt16();
- this.TimeDateStamp = br.ReadUInt32();
- this.PointerToSymbolTable = br.ReadUInt32();
- this.NumberOfSymbols = br.ReadUInt32();
- this.SizeOfOptionalHeader = br.ReadUInt16();
- this.Characteristics = (ImageCharacteristics)br.ReadUInt16();
- }
-
- ///
- /// The number that identifies the type of target machine.
- ///
- public MachineType Machine;
-
- ///
- /// The number of sections. This indicates the size of the section table, which
- /// immediately follows the headers.
- ///
- public ushort NumberOfSections;
-
- ///
- /// The low 32 bits of the number of seconds since 00:00 January 1, 1970 (a C run-time
- /// time_t value), that indicates when the file was created.
- ///
- public uint TimeDateStamp;
-
- ///
- /// The file offset of the COFF symbol table, or zero if no COFF symbol table is present.
- /// This value should be zero for an image because COFF debugging information is deprecated.
- ///
- public uint PointerToSymbolTable;
-
- ///
- /// The number of entries in the symbol table. This data can be used to locate the string
- /// table, which immediately follows the symbol table. This value should be zero for an image
- /// because COFF debugging information is deprecated.
- ///
- public uint NumberOfSymbols;
-
- ///
- /// The size of the optional header, which is required for executable files but not for
- /// object files. This value should be zero for an object file.
- ///
- public ushort SizeOfOptionalHeader;
-
- ///
- /// The flags that indicate the attributes of the file.
- ///
- public ImageCharacteristics Characteristics;
- }
-}
diff --git a/trunk/ProcessHacker/PE/COFFOptionalHeader.cs b/trunk/ProcessHacker/PE/COFFOptionalHeader.cs
deleted file mode 100644
index b8c7749b8..000000000
--- a/trunk/ProcessHacker/PE/COFFOptionalHeader.cs
+++ /dev/null
@@ -1,297 +0,0 @@
-/*
- * Process Hacker -
- * PE/COFF optional header reader
- *
- * Copyright (C) 2008 wj32
- * Descriptions from the PE/COFF specification from Microsoft.
- *
- * This file is part of Process Hacker.
- *
- * Process Hacker is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Process Hacker 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Process Hacker. If not, see .
- */
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-using System.IO;
-
-namespace ProcessHacker.PE
-{
- ///
- /// Represents a COFF optional header.
- ///
- public class COFFOptionalHeader
- {
- public const ushort PE32Magic = 0x10b;
- public const ushort PE32PlusMagic = 0x20b;
-
- public COFFOptionalHeader(BinaryReader br)
- {
- // standard fields
- this.Magic = br.ReadUInt16();
- this.MajorLinkerVersion = br.ReadByte();
- this.MinorLinkerVersion = br.ReadByte();
- this.SizeOfCode = br.ReadUInt32();
- this.SizeOfInitializedData = br.ReadUInt32();
- this.SizeOfUninitializedData = br.ReadUInt32();
- this.AddressOfEntryPoint = new IntPtr(br.ReadUInt32());
- this.BaseOfCode = br.ReadUInt32();
-
- if (this.Magic == COFFOptionalHeader.PE32Magic)
- this.BaseOfData = br.ReadUInt32();
- else
- this.BaseOfData = 0;
-
- // windows-specific fields
- if (this.Magic == COFFOptionalHeader.PE32Magic)
- this.ImageBase = br.ReadUInt32();
- else if (this.Magic == COFFOptionalHeader.PE32PlusMagic)
- this.ImageBase = br.ReadUInt64();
- else
- throw new Exception("Unknown magic number.");
-
- this.SectionAlignment = br.ReadUInt32();
- this.FileAlignment = br.ReadUInt32();
- this.MajorOperatingSystemVersion = br.ReadUInt16();
- this.MinorOperatingSystemVersion = br.ReadUInt16();
- this.MajorImageVersion = br.ReadUInt16();
- this.MinorImageVersion = br.ReadUInt16();
- this.MajorSubsystemVersion = br.ReadUInt16();
- this.MinorSubsystemVersion = br.ReadUInt16();
- this.Win32VersionValue = br.ReadUInt32();
- this.SizeOfImage = br.ReadUInt32();
- this.SizeOfHeaders = br.ReadUInt32();
- this.CheckSum = br.ReadUInt32();
- this.Subsystem = (ImageSubsystem)br.ReadUInt16();
- this.DllCharacteristics = (DllCharacteristics)br.ReadUInt16();
-
- if (this.Magic == COFFOptionalHeader.PE32Magic)
- {
- this.SizeOfStackReserve = br.ReadUInt32();
- this.SizeOfStackCommit = br.ReadUInt32();
- this.SizeOfHeapReserve = br.ReadUInt32();
- this.SizeOfHeapCommit = br.ReadUInt32();
- }
- else if (this.Magic == COFFOptionalHeader.PE32PlusMagic)
- {
- this.SizeOfStackReserve = br.ReadUInt64();
- this.SizeOfStackCommit = br.ReadUInt64();
- this.SizeOfHeapReserve = br.ReadUInt64();
- this.SizeOfHeapCommit = br.ReadUInt64();
- }
- else
- {
- throw new Exception("Unknown magic number.");
- }
-
- this.LoaderFlags = br.ReadUInt32();
- this.NumberOfRvaAndSizes = br.ReadUInt32();
- }
-
- #region Standard Fields
-
- ///
- /// The unsigned integer that identifies the state of the image file.
- /// The most common number is 0x10B, which identifies it as a normal
- /// executable file. 0x107 identifies it as a ROM image, and 0x20B
- /// identifies it as a PE32+ executable.
- ///
- public ushort Magic;
-
- ///
- /// The linker major version number.
- ///
- public byte MajorLinkerVersion;
-
- ///
- /// The linker minor version number.
- ///
- public byte MinorLinkerVersion;
-
- ///
- /// The size of the code (text) section, or the sum of all code
- /// sections if there are multiple sections.
- ///
- public uint SizeOfCode;
-
- ///
- /// The size of the initialized data section, or the sum of all
- /// such sections if there are multiple data sections.
- ///
- public uint SizeOfInitializedData;
-
- ///
- /// The size of the uninitialized data section (BSS), or the sum
- /// of all such sections if there are multiple BSS sections.
- ///
- public uint SizeOfUninitializedData;
-
- ///
- /// The address of the entry point relative to the image base when
- /// the executable file is loaded into memory. For program images,
- /// this is the starting address. For device drivers, this is the
- /// address of the initialization function. An entry point is
- /// optional for DLLs. When no entry point is present, this field
- /// must be zero.
- ///
- public IntPtr AddressOfEntryPoint;
-
- ///
- /// The address that is relative to the image base of the
- /// beginning-of-code section when it is loaded into memory.
- ///
- public uint BaseOfCode;
-
- ///
- /// The address that is relative to the image base of the
- /// beginning-of-data section when it is loaded into memory. This
- /// field is only present in PE32.
- ///
- public uint BaseOfData;
-
- #endregion
-
- #region Windows-specific Fields
-
- ///
- /// The preferred address of the first byte of image when loaded into
- /// memory; must be a multiple of 64 K. The default for DLLs is
- /// 0x10000000. The default for Windows CE EXEs is 0x00010000. The
- /// default for Windows NT, Windows 2000, Windows XP, Windows 95,
- /// Windows 98, and Windows Me is 0x00400000. This field is only 4 bytes
- /// long for PE32.
- ///
- public ulong ImageBase;
-
- ///
- /// The alignment (in bytes) of sections when they are loaded into memory.
- /// It must be greater than or equal to FileAlignment. The default is
- /// the page size for the architecture.
- ///
- public uint SectionAlignment;
-
- ///
- /// The alignment factor (in bytes) that is used to align the raw data of
- /// sections in the image file. The value should be a power of 2 between
- /// 512 and 64 K, inclusive. The default is 512. If the SectionAlignment
- /// is less than the architecture’s page size, then FileAlignment must
- /// match SectionAlignment.
- ///
- public uint FileAlignment;
-
- ///
- /// The major version number of the required operating system.
- ///
- public ushort MajorOperatingSystemVersion;
-
- ///
- /// The minor version number of the required operating system.
- ///
- public ushort MinorOperatingSystemVersion;
-
- ///
- /// The major version number of the image.
- ///
- public ushort MajorImageVersion;
-
- ///
- /// The minor version number of the image.
- ///
- public ushort MinorImageVersion;
-
- ///
- /// The major version number of the subsystem.
- ///
- public ushort MajorSubsystemVersion;
-
- ///
- /// The minor version number of the subsystem.
- ///
- public ushort MinorSubsystemVersion;
-
- ///
- /// Reserved, must be zero.
- ///
- public uint Win32VersionValue;
-
- ///
- /// The size (in bytes) of the image, including all headers,
- /// as the image is loaded in memory. It must be a multiple
- /// of SectionAlignment.
- ///
- public uint SizeOfImage;
-
- ///
- /// The combined size of an MS DOS stub, PE header, and section
- /// headers rounded up to a multiple of FileAlignment.
- ///
- public uint SizeOfHeaders;
-
- ///
- /// The image file checksum. The algorithm for computing the
- /// checksum is incorporated into IMAGHELP.DLL. The following are
- /// checked for validation at load time: all drivers, any DLL
- /// loaded at boot time, and any DLL that is loaded into a
- /// critical Windows process.
- ///
- public uint CheckSum;
-
- ///
- /// The subsystem that is required to run this image.
- ///
- public ImageSubsystem Subsystem;
-
- ///
- /// DLL characteristics.
- ///
- public DllCharacteristics DllCharacteristics;
-
- ///
- /// The size of the stack to reserve. Only SizeOfStackCommit is
- /// committed; the rest is made available one page at a time until
- /// the reserve size is reached.
- ///
- public ulong SizeOfStackReserve;
-
- ///
- /// The size of the stack to commit.
- ///
- public ulong SizeOfStackCommit;
-
- ///
- /// The size of the local heap space to reserve. Only SizeOfHeapCommit
- /// is committed; the rest is made available one page at a time
- /// until the reserve size is reached.
- ///
- public ulong SizeOfHeapReserve;
-
- ///
- /// The size of the local heap space to commit.
- ///
- public ulong SizeOfHeapCommit;
-
- ///
- /// Reserved, must be zero.
- ///
- public uint LoaderFlags;
-
- ///
- /// The number of data-directory entries in the remainder of the
- /// optional header. Each describes a location and size.
- ///
- public uint NumberOfRvaAndSizes;
-
- #endregion
- }
-}
diff --git a/trunk/ProcessHacker/PE/DllCharacteristics.cs b/trunk/ProcessHacker/PE/DllCharacteristics.cs
deleted file mode 100644
index 5c70e5a61..000000000
--- a/trunk/ProcessHacker/PE/DllCharacteristics.cs
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Process Hacker -
- * DLL characteristics
- *
- * Copyright (C) 2008 wj32
- * Descriptions from the PE/COFF specification from Microsoft.
- *
- * This file is part of Process Hacker.
- *
- * Process Hacker is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Process Hacker 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Process Hacker. If not, see .
- */
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-namespace ProcessHacker.PE
-{
- ///
- /// Specifies a DLL's attributes.
- ///
- [Flags]
- public enum DllCharacteristics : ushort
- {
- ///
- /// Reserved, must be zero.
- ///
- Reserved1 = 0x0001,
-
- ///
- /// Reserved, must be zero.
- ///
- Reserved2 = 0x0002,
-
- ///
- /// Reserved, must be zero.
- ///
- Reserved3 = 0x0004,
-
- ///
- /// Reserved, must be zero.
- ///
- Reserved4 = 0x0008,
-
- ///
- /// DLL can be relocated at load time.
- ///
- DynamicBase = 0x0040,
-
- ///
- /// Code Integrity checks are enforced.
- ///
- ForceIntegrity = 0x0080,
-
- ///
- /// Image is NX compatible.
- ///
- NXCompat = 0x0100,
-
- ///
- /// Isolation aware, but do not isolate the image.
- ///
- NoIsolation = 0x0200,
-
- ///
- /// Does not use structured exception (SE) handling. No SE
- /// handler may be called in this image.
- ///
- NoSEH = 0x0400,
-
- ///
- /// Do not bind the image.
- ///
- NoBind = 0x0800,
-
- ///
- /// Reserved, must be zero.
- ///
- Reserved5 = 0x1000,
-
- ///
- /// A WDM driver.
- ///
- WDMDriver = 0x2000,
-
- ///
- /// Terminal Server aware.
- ///
- TerminalServerAware = 0x8000
- }
-}
diff --git a/trunk/ProcessHacker/PE/ExportData.cs b/trunk/ProcessHacker/PE/ExportData.cs
deleted file mode 100644
index bf6ee5c2e..000000000
--- a/trunk/ProcessHacker/PE/ExportData.cs
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Process Hacker -
- * PE exports reader
- *
- * Copyright (C) 2008 wj32
- *
- * This file is part of Process Hacker.
- *
- * Process Hacker is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Process Hacker 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Process Hacker. If not, see .
- */
-
-using System.Collections.Generic;
-using System.IO;
-using ProcessHacker.Common;
-
-namespace ProcessHacker.PE
-{
- public class ExportEntry
- {
- public enum ExportType
- {
- Export,
- Forwarder
- }
-
- public ExportType Type;
- public uint ExportRVA;
- public string ForwardedString;
- }
-
- public class ExportData
- {
- public ExportData(BinaryReader br, PEFile peFile)
- {
- this.ExportFlags = br.ReadUInt32();
- this.TimeDateStamp = br.ReadUInt32();
- this.MajorVersion = br.ReadUInt16();
- this.MinorVersion = br.ReadUInt16();
- this.NameRVA = br.ReadUInt32();
- this.OrdinalBase = br.ReadUInt32();
- this.AddressTableEntries = br.ReadUInt32();
- this.NumberOfNamePointers = br.ReadUInt32();
- this.ExportAddressTableRVA = br.ReadUInt32();
- this.NamePointerRVA = br.ReadUInt32();
- this.OrdinalTableRVA = br.ReadUInt32();
-
- // read address table
- br.BaseStream.Seek(peFile.RvaToVa(this.ExportAddressTableRVA), SeekOrigin.Begin);
-
- for (int i = 0; i < this.AddressTableEntries; i++)
- {
- uint address = br.ReadUInt32();
-
- ExportEntry entry = new ExportEntry();
- ImageData iD = peFile.ImageData[ImageDataType.ExportTable];
-
- if (address >= iD.VirtualAddress && address < iD.VirtualAddress + iD.Size)
- {
- entry.Type = ExportEntry.ExportType.Forwarder;
- }
- else
- {
- entry.Type = ExportEntry.ExportType.Export;
- }
-
- entry.ExportRVA = address;
-
- this.ExportAddressTable.Add(entry);
- }
-
- if (peFile.GetNames)
- {
- 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(entry.ExportRVA), SeekOrigin.Begin);
- entry.ForwardedString = Utils.ReadString(br.BaseStream);
- }
- }
- }
-
- // read ordinal table
- br.BaseStream.Seek(peFile.RvaToVa(this.OrdinalTableRVA), SeekOrigin.Begin);
-
- for (int i = 0; i < this.AddressTableEntries; i++)
- {
- this.ExportOrdinalTable.Add(br.ReadUInt16());
- }
-
- // read name pointer table
- br.BaseStream.Seek(peFile.RvaToVa(this.NamePointerRVA), SeekOrigin.Begin);
-
- for (int i = 0; i < this.NumberOfNamePointers; i++)
- {
- this.ExportNamePointerTable.Add(br.ReadUInt32());
- }
-
- if (peFile.GetNames)
- {
- // read names
- for (int i = 0; i < this.ExportNamePointerTable.Count; i++)
- {
- br.BaseStream.Seek(peFile.RvaToVa(this.ExportNamePointerTable[i]), SeekOrigin.Begin);
- this.ExportNameTable.Add(Utils.ReadString(br.BaseStream));
- }
- }
- }
-
- public uint ExportFlags;
- public uint TimeDateStamp;
- public ushort MajorVersion;
- public ushort MinorVersion;
- public uint NameRVA;
- public uint OrdinalBase;
- public uint AddressTableEntries;
- public uint NumberOfNamePointers;
- public uint ExportAddressTableRVA;
- public uint NamePointerRVA;
- public uint OrdinalTableRVA;
-
- public List ExportOrdinalTable = new List();
- public List ExportAddressTable = new List();
- public List ExportNamePointerTable = new List();
- public List ExportNameTable = new List();
- }
-}
diff --git a/trunk/ProcessHacker/PE/ImageCharacteristics.cs b/trunk/ProcessHacker/PE/ImageCharacteristics.cs
deleted file mode 100644
index 1549a92b2..000000000
--- a/trunk/ProcessHacker/PE/ImageCharacteristics.cs
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Process Hacker -
- * image characteristics
- *
- * Copyright (C) 2008 wj32
- * Descriptions from the PE/COFF specification from Microsoft.
- *
- * This file is part of Process Hacker.
- *
- * Process Hacker is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Process Hacker 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Process Hacker. If not, see .
- */
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-namespace ProcessHacker.PE
-{
- ///
- /// Specifies an image file's attributes.
- ///
- [Flags]
- public enum ImageCharacteristics : ushort
- {
- ///
- /// Image only, Windows CE, and Windows NT® and later. This indicates that the file does
- /// not contain base relocations and must therefore be loaded at its preferred base address.
- /// If the base address is not available, the loader reports an error. The default behavior
- /// of the linker is to strip base relocations from executable (EXE) files.
- ///
- RelocsStripped = 0x0001,
-
- ///
- /// Image only. This indicates that the image file is valid and can be run. If this flag
- /// is not set, it indicates a linker error.
- ///
- ExecutableImage = 0x0002,
-
- ///
- /// COFF line numbers have been removed. This flag is deprecated and should be zero.
- ///
- LineNumsStripped = 0x0004,
-
- ///
- /// COFF symbol table entries for local symbols have been removed. This flag is deprecated
- /// and should be zero.
- ///
- LocalSymsStripped = 0x0008,
-
- ///
- /// Obsolete. Aggressively trim working set. This flag is deprecated for Windows 2000 and later
- /// and must be zero.
- ///
- AggressiveWsTrim = 0x0010,
-
- ///
- /// Application can handle > 2 GB addresses.
- ///
- LargeAddressAware = 0x0020,
-
- ///
- /// This flag is reserved for future use.
- ///
- Reserved = 0x0040,
-
- ///
- /// Little endian: the least significant bit (LSB) precedes the most significant bit (MSB) in
- /// memory. This flag is deprecated and should be zero.
- ///
- BytesReversedLo = 0x0080,
-
- ///
- /// Machine is based on a 32-bit-word architecture.
- ///
- ThirtyTwoBitMachine = 0x0100,
-
- ///
- /// Debugging information is removed from the image file.
- ///
- DebugStripped = 0x0200,
-
- ///
- /// If the image is on removable media, fully load it and copy it to the swap file.
- ///
- RemovableRunFromSwap = 0x0400,
-
- ///
- /// If the image is on network media, fully load it and copy it to the swap file.
- ///
- NetRunFromSwap = 0x0800,
-
- ///
- /// The image file is a system file, not a user program.
- ///
- System = 0x1000,
-
- ///
- /// The image file is a dynamic-link library (DLL). Such files are considered
- /// executable files for almost all purposes, although they cannot be directly run.
- ///
- DLL = 0x2000,
-
- ///
- /// The file should be run only on a uniprocessor machine.
- ///
- UPSystemOnly = 0x4000,
-
- ///
- /// Big endian: the MSB precedes the LSB in memory. This flag is deprecated and should be zero.
- ///
- BytesReversedHi = 0x8000
- }
-}
diff --git a/trunk/ProcessHacker/PE/ImageData.cs b/trunk/ProcessHacker/PE/ImageData.cs
deleted file mode 100644
index 0711e9d96..000000000
--- a/trunk/ProcessHacker/PE/ImageData.cs
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * Process Hacker -
- * image data
- *
- * Copyright (C) 2008 wj32
- * Descriptions from the PE/COFF specification from Microsoft.
- *
- * This file is part of Process Hacker.
- *
- * Process Hacker is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Process Hacker 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Process Hacker. If not, see .
- */
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-namespace ProcessHacker.PE
-{
- ///
- /// The type of image data.
- ///
- public enum ImageDataType
- {
- ///
- /// The export table.
- ///
- ExportTable = 0,
-
- ///
- /// The import table.
- ///
- ImportTable,
-
- ///
- /// The resource table.
- ///
- ResourceTable,
-
- ///
- /// The exception table.
- ///
- ExceptionTable,
-
- ///
- /// The attribute certificate table.
- ///
- CertificateTable,
-
- ///
- /// The base relocation table.
- ///
- BaseRelocationTable,
-
- ///
- /// The debug data.
- ///
- Debug,
-
- ///
- /// Reserved, must be zero.
- ///
- Architecture,
-
- ///
- /// The RVA of the value to be stored in the global pointer register.
- ///
- GlobalPtr,
-
- ///
- /// The thread local storage (TLS) table.
- ///
- TLSTable,
-
- ///
- /// The load configuration table.
- ///
- LoadConfigTable,
-
- ///
- /// The bound import table.
- ///
- BoundImport,
-
- ///
- /// The import address table.
- ///
- IAT,
-
- ///
- /// The delay import descriptor.
- ///
- DelayImportDescriptor,
-
- ///
- /// The CLR runtime header.
- ///
- CLRRuntimeHeader,
-
- ///
- /// Reserved, must be zero.
- ///
- Reserved
- }
-
- ///
- /// Represents a data directory containing the address and size of a table
- /// or string in the image.
- ///
- public struct ImageData
- {
- ///
- /// The relative virtual address (RVA) of the table.
- ///
- public uint VirtualAddress;
-
- ///
- /// The size, in bytes, of the table.
- ///
- public uint Size;
- }
-}
diff --git a/trunk/ProcessHacker/PE/ImageRelocationType.cs b/trunk/ProcessHacker/PE/ImageRelocationType.cs
deleted file mode 100644
index 83de85b16..000000000
--- a/trunk/ProcessHacker/PE/ImageRelocationType.cs
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Process Hacker -
- * image relocation type
- *
- * Copyright (C) 2008 wj32
- * Descriptions from the PE/COFF specification from Microsoft.
- *
- * This file is part of Process Hacker.
- *
- * Process Hacker is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Process Hacker 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Process Hacker. If not, see .
- */
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-namespace ProcessHacker.PE
-{
- ///
- /// Specifies the type of an image relocation.
- ///
- public enum ImageRelocationType
- {
- ///
- /// The base relocation is skipped. This type can be used to pad a block.
- ///
- Absolute = 0,
-
- ///
- /// The base relocation adds the high 16 bits of the difference to the 16-bit
- /// field at offset. The 16-bit field represents the high value of a 32-bit word.
- ///
- High,
-
- ///
- /// The base relocation adds the low 16 bits of the difference to the 16-bit
- /// field at offset. The 16-bit field represents the low half of a 32-bit word.
- ///
- Low,
-
- ///
- /// The base relocation applies all 32 bits of the difference to the 32-bit
- /// field at offset.
- ///
- HighLow,
-
- ///
- /// The base relocation adds the high 16 bits of the difference to the 16-bit
- /// field at offset. The 16-bit field represents the high value of a 32-bit word.
- /// The low 16 bits of the 32-bit value are stored in the 16-bit word that follows
- /// this base relocation. This means that this base relocation occupies two slots.
- ///
- HighAdj,
-
- ///
- /// The base relocation applies to a MIPS jump instruction.
- ///
- MipsJmpAddr,
- Reserved1,
- Reserved2,
-
- ///
- /// The base relocation applies to a MIPS16 jump instruction.
- ///
- MipsJmpAddr16,
-
- ///
- /// The base relocation applies the difference to the 64-bit field at offset.
- ///
- Dir16
- }
-}
diff --git a/trunk/ProcessHacker/PE/ImageSubsystem.cs b/trunk/ProcessHacker/PE/ImageSubsystem.cs
deleted file mode 100644
index f4a7af7c3..000000000
--- a/trunk/ProcessHacker/PE/ImageSubsystem.cs
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Process Hacker -
- * image subsystem
- *
- * Copyright (C) 2008 wj32
- * Descriptions from the PE/COFF specification from Microsoft.
- *
- * This file is part of Process Hacker.
- *
- * Process Hacker is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Process Hacker 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Process Hacker. If not, see .
- */
-
-
-namespace ProcessHacker.PE
-{
- ///
- /// Specifies the Windows subsystem requied to run an image.
- ///
- public enum ImageSubsystem : ushort
- {
- ///
- /// An unknown subsystem.
- ///
- Unknown = 0,
-
- ///
- /// Device drivers and native Windows processes.
- ///
- Native = 1,
-
- ///
- /// The Windows graphical user interface (GUI) subsystem.
- ///
- WindowsGUI = 2,
-
- ///
- /// The Windows character subsystem.
- ///
- WindowsCUI = 3,
-
- ///
- /// The POSIX character subsystem.
- ///
- POSIXCUI = 7,
-
- ///
- /// Windows CE.
- ///
- WindowsCEGUI = 9,
-
- ///
- /// An Extensible Firmware Interface (EFI) application.
- ///
- EFIApplication = 10,
-
- ///
- /// An EFI driver with boot services.
- ///
- EFIBootServiceDriver = 11,
-
- ///
- /// An EFI driver with run-time services.
- ///
- EFIRuntimeDriver = 12,
-
- ///
- /// An EFI ROM image.
- ///
- EFIROM = 13,
-
- ///
- /// XBOX.
- ///
- XBOX = 14
- }
-}
diff --git a/trunk/ProcessHacker/PE/ImportData.cs b/trunk/ProcessHacker/PE/ImportData.cs
deleted file mode 100644
index c01add89a..000000000
--- a/trunk/ProcessHacker/PE/ImportData.cs
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * Process Hacker -
- * PE imports reader
- *
- * Copyright (C) 2008 wj32
- *
- * This file is part of Process Hacker.
- *
- * Process Hacker is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Process Hacker 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Process Hacker. If not, see .
- */
-
-using System.Collections.Generic;
-using System.IO;
-using ProcessHacker.Common;
-
-namespace ProcessHacker.PE
-{
- public class ImportLookupEntry
- {
- public bool UseOrdinal;
- public ushort Ordinal;
- public uint NameTableRVA;
- public ImportNameEntry NameEntry;
- }
-
- public class ImportNameEntry
- {
- public uint Hint;
- public string Name;
- }
-
- public class ImportDirectoryEntry
- {
- public ImportDirectoryEntry(BinaryReader br)
- {
- this.ImportLookupTableRVA = br.ReadUInt32();
- this.TimeDateStamp = br.ReadUInt32();
- this.ForwarderChain = br.ReadUInt32();
- this.NameRVA = br.ReadUInt32();
- this.ImportAddressTableRVA = br.ReadUInt32();
- }
-
- public uint ImportLookupTableRVA;
- public uint TimeDateStamp;
- public uint ForwarderChain;
- public uint NameRVA;
- public uint ImportAddressTableRVA;
- public string Name;
- }
-
- public class ImportData
- {
- public ImportData(BinaryReader br, PEFile peFile)
- {
- while (true)
- {
- byte[] data = br.ReadBytes(20);
-
- if (Utils.IsEmpty(data))
- break;
-
- br.BaseStream.Seek(-20, SeekOrigin.Current);
-
- this.ImportDirectoryTable.Add(new ImportDirectoryEntry(br));
- }
-
- int dllNumber = 0;
-
- while (dllNumber < this.ImportDirectoryTable.Count)
- {
- this.ImportLookupTable.Add(new List());
-
- while (true)
- {
- ImportLookupEntry entry = new ImportLookupEntry();
- uint number = br.ReadUInt32();
-
- if (number == 0)
- break;
-
- if ((number & 0x80000000) == 1)
- {
- entry.UseOrdinal = true;
- entry.Ordinal = (ushort)(number & 0xffff);
- }
- else
- {
- entry.UseOrdinal = false;
- entry.NameTableRVA = (uint)(number & 0x7fffffff);
-
- try
- {
- peFile.RvaToVa(entry.NameTableRVA);
- }
- catch
- {
- entry.UseOrdinal = true;
- entry.Ordinal = (ushort)(number & 0xffff);
- continue;
- }
- }
-
- this.ImportLookupTable[dllNumber].Add(entry);
- }
-
- dllNumber++;
- }
-
- if (peFile.GetNames)
- {
- foreach (ImportDirectoryEntry entry in this.ImportDirectoryTable)
- {
- br.BaseStream.Seek(peFile.RvaToVa(entry.NameRVA), SeekOrigin.Begin);
-
- entry.Name = Utils.ReadString(br.BaseStream);
- }
-
- for (int i = 0; i < this.ImportLookupTable.Count; i++)
- {
- for (int j = 0; j < this.ImportLookupTable[i].Count; j++)
- {
- ImportLookupEntry entry = this.ImportLookupTable[i][j];
-
- if (!entry.UseOrdinal)
- {
- br.BaseStream.Seek(peFile.RvaToVa(entry.NameTableRVA), SeekOrigin.Begin);
-
- entry.NameEntry = new ImportNameEntry();
- entry.NameEntry.Hint = br.ReadUInt16();
- entry.NameEntry.Name = Utils.ReadString(br.BaseStream);
- }
- }
- }
- }
- }
-
- public List ImportDirectoryTable = new List();
- public List> ImportLookupTable = new List>();
- }
-}
diff --git a/trunk/ProcessHacker/PE/MachineType.cs b/trunk/ProcessHacker/PE/MachineType.cs
deleted file mode 100644
index 8b9d8bc73..000000000
--- a/trunk/ProcessHacker/PE/MachineType.cs
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * Process Hacker -
- * machine type
- *
- * Copyright (C) 2008 wj32
- * Descriptions from the PE/COFF specification from Microsoft.
- *
- * This file is part of Process Hacker.
- *
- * Process Hacker is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Process Hacker 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Process Hacker. If not, see .
- */
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-namespace ProcessHacker.PE
-{
- ///
- /// Specifies an executable's target CPU type.
- ///
- public enum MachineType : ushort
- {
- ///
- /// Assumed to be applicable to any machine type.
- ///
- Unknown = 0x0,
-
- ///
- /// Matsushita AM33.
- ///
- AM33 = 0x1d3,
-
- ///
- /// x64.
- ///
- AMD64 = 0x8664,
-
- ///
- /// ARM little-endian.
- ///
- ARM = 0x1c0,
-
- ///
- /// EFI byte code.
- ///
- EBC = 0xebc,
-
- ///
- /// Intel 386 or later processors and compatible processors.
- ///
- i386 = 0x14c,
-
- ///
- /// Intel Itanium processor family.
- ///
- IA64 = 0x200,
-
- ///
- /// Mitsubishi M32R little endian.
- ///
- M32R = 0x9041,
-
- ///
- /// MIPS16.
- ///
- MIPS16 = 0x266,
-
- ///
- /// MIPS with FPU.
- ///
- MIPSFPU = 0x366,
-
- ///
- /// MIPS16 with FPU.
- ///
- MIPSFPU16 = 0x466,
-
- ///
- /// PowerPC little-endian.
- ///
- PowerPC = 0x1f0,
-
- ///
- /// PowerPC with floating point support.
- ///
- PowerPCFP = 0x1f1,
-
- ///
- /// MIPS little-endian.
- ///
- R4000 = 0x166,
-
- ///
- /// Hitachi SH3.
- ///
- SH3 = 0x1a2,
-
- ///
- /// Hitachi SH3 DSP.
- ///
- SH3DSP = 0x1a3,
-
- ///
- /// Hitachi SH4.
- ///
- SH4 = 0x1a6,
-
- ///
- /// Hitachi SH5.
- ///
- SH5 = 0x1a8,
-
- ///
- /// Thumb.
- ///
- Thumb = 0x1c2,
-
- ///
- /// MIPS little-endian WCE v2.
- ///
- WCEMIPSv2 = 0x169
- }
-}
diff --git a/trunk/ProcessHacker/PE/PEException.cs b/trunk/ProcessHacker/PE/PEException.cs
deleted file mode 100644
index 7d117e4aa..000000000
--- a/trunk/ProcessHacker/PE/PEException.cs
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Process Hacker -
- * PE exception
- *
- * Copyright (C) 2009 wj32
- *
- * This file is part of Process Hacker.
- *
- * Process Hacker is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Process Hacker 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Process Hacker. If not, see .
- */
-
-using System;
-
-namespace ProcessHacker.PE
-{
- public class PEException : Exception
- {
- public PEException()
- : base()
- { }
-
- public PEException(string message)
- : base(message)
- { }
- }
-}
diff --git a/trunk/ProcessHacker/PE/PEFile.cs b/trunk/ProcessHacker/PE/PEFile.cs
deleted file mode 100644
index 5936acae5..000000000
--- a/trunk/ProcessHacker/PE/PEFile.cs
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- * Process Hacker -
- * PE file reader
- *
- * Copyright (C) 2008-2009 wj32
- *
- * This file is part of Process Hacker.
- *
- * Process Hacker is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Process Hacker 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Process Hacker. If not, see .
- */
-
-using System.Collections.Generic;
-using System.IO;
-using ProcessHacker.Common;
-
-namespace ProcessHacker.PE
-{
- public class PEFile
- {
- private static byte[] PESignature = { 0x50, 0x45, 0, 0 };
-
- private COFFHeader _coffHeader;
- private COFFOptionalHeader _coffOptionalHeader;
- private Dictionary _imageData = new Dictionary();
- private List _sections = new List();
-
- public ExportData ExportData { get; private set; }
- public ImportData ImportData { get; private set; }
- public RelocData RelocData { get; private set; }
-
- internal bool GetNames { get; private set; }
-
- public PEFile(string path)
- : this(path, true)
- { }
-
- public PEFile(string path, bool getNames)
- {
- this.GetNames = getNames;
-
- using (FileStream s = new FileStream(path, FileMode.Open, FileAccess.Read))
- {
- this.Read(s);
- }
- }
-
- public PEFile(Stream s)
- {
- this.Read(s);
- }
-
- private void Read(Stream s)
- {
- BinaryReader br = new BinaryReader(s);
-
- // get location of PE signature
- s.Seek(0x3c, SeekOrigin.Begin);
-
- uint peSigLoc = br.ReadUInt32();
-
- try
- {
- s.Seek(peSigLoc, SeekOrigin.Begin);
- }
- catch
- {
- throw new PEException("Could not seek to location 0x" + peSigLoc.ToString("x") + ".");
- }
-
- byte[] peSig = br.ReadBytes(4);
-
- if (!Utils.Equals(peSig, PEFile.PESignature))
- throw new PEException("Invalid PE signature.");
-
- // read COFF header
- _coffHeader = new COFFHeader(br);
-
- // read COFF optional header
- _coffOptionalHeader = new COFFOptionalHeader(br);
-
- // read image data directory
- for (int i = 0; i < _coffOptionalHeader.NumberOfRvaAndSizes; i++)
- {
- _imageData.Add((ImageDataType)i, new ImageData()
- {
- VirtualAddress = br.ReadUInt32(),
- Size = br.ReadUInt32()
- });
- }
-
- // read section headers
- for (int i = 0; i < _coffHeader.NumberOfSections; i++)
- {
- _sections.Add(new SectionHeader(br));
- }
-
- // read export table
- if (_imageData.ContainsKey(ImageDataType.ExportTable))
- {
- ImageData iD = _imageData[ImageDataType.ExportTable];
-
- if (iD.VirtualAddress != 0)
- {
- s.Seek(this.RvaToVa(iD.VirtualAddress), SeekOrigin.Begin);
-
- this.ExportData = new ExportData(br, this);
- }
- }
-
- // read import table
- if (_imageData.ContainsKey(ImageDataType.ImportTable))
- {
- ImageData iD = _imageData[ImageDataType.ImportTable];
-
- if (iD.VirtualAddress != 0)
- {
- s.Seek(this.RvaToVa(iD.VirtualAddress), SeekOrigin.Begin);
-
- this.ImportData = new ImportData(br, this);
- }
- }
-
- // read relocations
- //if (_imageData.ContainsKey(ImageDataType.BaseRelocationTable))
- //{
- // ImageData iD = _imageData[ImageDataType.BaseRelocationTable];
-
- // if (iD.VirtualAddress != 0)
- // {
- // s.Seek(PEFile.RvaToVa(this, iD.VirtualAddress), SeekOrigin.Begin);
-
- // this.RelocData = new RelocData(br, this);
- // }
- //}
- }
-
- public long RvaToVa(long rva)
- {
- SectionHeader section = null;
-
- foreach (SectionHeader sh in this.Sections)
- {
- if (rva >= sh.VirtualAddress && rva < sh.VirtualAddress + sh.VirtualSize)
- {
- section = sh;
- break;
- }
- }
-
- if (section == null)
- throw new PEException("RVA could not be matched to a virtual address.");
-
- return section.PointerToRawData + rva - section.VirtualAddress;
- }
-
- public COFFHeader COFFHeader
- {
- get { return _coffHeader; }
- }
-
- public COFFOptionalHeader COFFOptionalHeader
- {
- get { return _coffOptionalHeader; }
- }
-
- public Dictionary ImageData
- {
- get { return _imageData; }
- }
-
- public List Sections
- {
- get { return _sections; }
- }
- }
-}
diff --git a/trunk/ProcessHacker/PE/RelocData.cs b/trunk/ProcessHacker/PE/RelocData.cs
deleted file mode 100644
index 53dd88484..000000000
--- a/trunk/ProcessHacker/PE/RelocData.cs
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Process Hacker -
- * PE relocations reader
- *
- * Copyright (C) 2008 wj32
- *
- * This file is part of Process Hacker.
- *
- * Process Hacker is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Process Hacker 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Process Hacker. If not, see .
- */
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-using System.IO;
-
-namespace ProcessHacker.PE
-{
- public class ImageRelocationBlock
- {
- public int PageRVA;
- public int BlockSize;
- public List Entries;
- }
-
- public class ImageRelocationEntry
- {
- public ImageRelocationType Type;
- public int Offset;
- }
-
- public class RelocData
- {
- public RelocData(BinaryReader br, PEFile peFile)
- {
- long i = br.BaseStream.Position;
-
- try
- {
- while (i < peFile.ImageData[ImageDataType.BaseRelocationTable].VirtualAddress +
- peFile.ImageData[ImageDataType.BaseRelocationTable].Size)
- {
- var block = new ImageRelocationBlock();
-
- block.PageRVA = br.ReadInt32();
-
- if (block.PageRVA == 0)
- break;
-
- block.BlockSize = br.ReadInt32();
-
- if (block.BlockSize == 0)
- break;
-
- block.Entries = new List();
-
- for (int j = 8; j < block.BlockSize; j += 2)
- {
- var entry = new ImageRelocationEntry();
- ushort val = br.ReadUInt16();
-
- entry.Type = (ImageRelocationType)(val >> 12);
- entry.Offset = val & 0xfff;
- block.Entries.Add(entry);
- }
-
- RelocBlocks.Add(block);
- br.BaseStream.Seek(i += block.BlockSize, SeekOrigin.Begin);
- }
- }
- catch
- { }
- }
-
- public List RelocBlocks = new List();
- }
-}
diff --git a/trunk/ProcessHacker/PE/SectionFlags.cs b/trunk/ProcessHacker/PE/SectionFlags.cs
deleted file mode 100644
index e2d75e18e..000000000
--- a/trunk/ProcessHacker/PE/SectionFlags.cs
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * Process Hacker -
- * section flags
- *
- * Copyright (C) 2008 wj32
- * Descriptions from the PE/COFF specification from Microsoft.
- *
- * This file is part of Process Hacker.
- *
- * Process Hacker is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Process Hacker 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Process Hacker. If not, see .
- */
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-namespace ProcessHacker.PE
-{
- ///
- /// Specifies the attributes of an image section.
- ///
- [Flags]
- public enum SectionFlags : uint
- {
- ///
- /// Reserved for future use.
- ///
- Reserved1 = 0x00000000,
-
- ///
- /// Reserved for future use.
- ///
- Reserved2 = 0x00000001,
-
- ///
- /// Reserved for future use.
- ///
- Reserved3 = 0x00000002,
-
- ///
- /// Reserved, must be zero.
- ///
- Reserved4 = 0x00000004,
-
- ///
- /// The section should not be padded to the next boundary.
- /// This flag is obsolete and is replaced by IMAGE_SCN_ALIGN_1BYTES.
- /// This is valid only for object files.
- ///
- NoPad = 0x00000008,
-
- ///
- /// The section contains executable code.
- ///
- Code = 0x00000020,
-
- ///
- /// The section contains initialized data.
- ///
- InitializedData = 0x00000040,
-
- ///
- /// The section contains uninitialized data.
- ///
- UninitializedData = 0x00000080,
-
- ///
- /// Reserved for future use.
- ///
- Other = 0x00000100,
-
- ///
- /// The section contains comments or other information. The
- /// .drectve section has this type. This is valid for object
- /// files only.
- ///
- Info = 0x00000200,
-
- ///
- /// Reserved for future use.
- ///
- Reserved5 = 0x00000400,
-
- ///
- /// The section will not become part of the image. This is valid
- /// only for object files.
- ///
- Remove = 0x00000800,
-
- ///
- /// The section contains COMDAT data.
- ///
- COMDAT = 0x00001000,
-
- ///
- /// The section contains data referenced through the global pointer (GP).
- ///
- GPRel = 0x00008000,
-
- ///
- /// Reserved for future use.
- ///
- MemoryPurgeable = 0x00010000,
-
- ///
- /// Reserved for future use.
- ///
- Memory16Bit = 0x00020000,
-
- ///
- /// Reserved for future use.
- ///
- MemoryLocked = 0x00040000,
-
- ///
- /// Reserved for future use.
- ///
- MemoryPeload = 0x00080000,
-
- Align1Bytes = 0x00100000,
- Align2Bytes = 0x00200000,
- Align4Bytes = 0x00300000,
- Align8Bytes = 0x00400000,
- Align16Bytes = 0x00500000,
- Align32Bytes = 0x00600000,
- Align64Bytes = 0x00700000,
- Align128Bytes = 0x00800000,
- Align256Bytes = 0x00900000,
- Align512Bytes = 0x00a00000,
- Align1024Bytes = 0x00b00000,
- Align2048Bytes = 0x00c00000,
- Align4096Bytes = 0x00d00000,
- Align8192Bytes = 0x00e00000,
-
- ///
- /// The section contains extended relocations.
- ///
- NRelocOvfl = 0x01000000,
-
- ///
- /// The section can be discarded as needed.
- ///
- MemoryDiscardable = 0x02000000,
-
- ///
- /// The section cannot be cached.
- ///
- MemoryNotCached = 0x04000000,
-
- ///
- /// The section is not pageable.
- ///
- MemoryNotPaged = 0x08000000,
-
- ///
- /// The section can be shared in memory.
- ///
- MemoryShared = 0x10000000,
-
- ///
- /// The section can be executed as code.
- ///
- MemoryExecute = 0x20000000,
-
- ///
- /// The section can be read.
- ///
- MemoryRead = 0x40000000,
-
- ///
- /// The section can be written to.
- ///
- MemoryWrite = 0x80000000
- }
-}
diff --git a/trunk/ProcessHacker/PE/SectionHeader.cs b/trunk/ProcessHacker/PE/SectionHeader.cs
deleted file mode 100644
index d2f79e364..000000000
--- a/trunk/ProcessHacker/PE/SectionHeader.cs
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Process Hacker -
- * PE file section header reader
- *
- * Copyright (C) 2008 wj32
- * Descriptions from the PE/COFF specification from Microsoft.
- *
- * This file is part of Process Hacker.
- *
- * Process Hacker is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Process Hacker 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Process Hacker. If not, see .
- */
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-using System.IO;
-
-namespace ProcessHacker.PE
-{
- ///
- /// Represents a section header.
- ///
- public class SectionHeader
- {
- public SectionHeader(BinaryReader br)
- {
- int i = 0;
-
- while (i < 8)
- {
- byte b = br.ReadByte();
-
- if (b != 0)
- Name += (char)b;
-
- i++;
- }
-
- this.VirtualSize = br.ReadUInt32();
- this.VirtualAddress = br.ReadUInt32();
- this.SizeOfRawData = br.ReadUInt32();
- this.PointerToRawData = br.ReadUInt32();
- this.PointerToRelocations = br.ReadUInt32();
- this.PointerToLinenumbers = br.ReadUInt32();
- this.NumberOfRelocations = br.ReadUInt16();
- this.NumberOfLinenumbers = br.ReadUInt16();
- this.Characteristics = (SectionFlags)br.ReadUInt32();
- }
-
- ///
- /// An 8-byte, null-padded UTF-8 encoded string. If the string
- /// is exactly 8 characters long, there is no terminating null.
- /// For longer names, this field contains a slash (/) that is
- /// followed by an ASCII representation of a decimal number that
- /// is an offset into the string table. Executable images do not
- /// use a string table and do not support section names longer
- /// than 8 characters. Long names in object files are truncated
- /// if they are emitted to an executable file.
- ///
- public string Name;
-
- ///
- /// The total size of the section when loaded into memory. If this
- /// value is greater than SizeOfRawData, the section is zero-padded.
- /// This field is valid only for executable images and should be set
- /// to zero for object files.
- ///
- public uint VirtualSize;
-
- ///
- /// For executable images, the address of the first byte of the
- /// section relative to the image base when the section is loaded
- /// into memory. For object files, this field is the address of
- /// the first byte before relocation is applied; for simplicity,
- /// compilers should set this to zero. Otherwise, it is an arbitrary
- /// value that is subtracted from offsets during relocation.
- ///
- public uint VirtualAddress;
-
- ///
- /// The size of the section (for object files) or the size of the
- /// initialized data on disk (for image files). For executable
- /// images, this must be a multiple of FileAlignment from the
- /// optional header. If this is less than VirtualSize, the remainder
- /// of the section is zero-filled. Because the SizeOfRawData field
- /// is rounded but the VirtualSize field is not, it is possible for
- /// SizeOfRawData to be greater than VirtualSize as well. When a
- /// section contains only uninitialized data, this field should be zero.
- ///
- public uint SizeOfRawData;
-
- ///
- /// The file pointer to the first page of the section within the
- /// COFF file. For executable images, this must be a multiple of
- /// FileAlignment from the optional header. For object files, the
- /// value should be aligned on a 4 byte boundary for best performance.
- /// When a section contains only uninitialized data, this field should
- /// be zero.
- ///
- public uint PointerToRawData;
-
- ///
- /// The file pointer to the beginning of relocation entries for the
- /// section. This is set to zero for executable images or if there are
- /// no relocations.
- ///
- public uint PointerToRelocations;
-
- ///
- /// The file pointer to the beginning of line-number entries for the
- /// section. This is set to zero if there are no COFF line numbers.
- /// This value should be zero for an image because COFF debugging
- /// information is deprecated.
- ///
- public uint PointerToLinenumbers;
-
- ///
- /// The number of relocation entries for the section. This is set to
- /// zero for executable images.
- ///
- public ushort NumberOfRelocations;
-
- ///
- /// The number of line-number entries for the section. This value
- /// should be zero for an image because COFF debugging information is
- /// deprecated.
- ///
- public ushort NumberOfLinenumbers;
-
- ///
- /// The flags that describe the characteristics of the section.
- ///
- public SectionFlags Characteristics;
- }
-}
diff --git a/trunk/ProcessHacker/ProcessHacker.csproj b/trunk/ProcessHacker/ProcessHacker.csproj
index ed8f03ace..65a08f9d7 100644
--- a/trunk/ProcessHacker/ProcessHacker.csproj
+++ b/trunk/ProcessHacker/ProcessHacker.csproj
@@ -807,21 +807,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/trunk/ProcessHacker/Program/Program.cs b/trunk/ProcessHacker/Program/Program.cs
index 86cac1e91..6dda0cd84 100644
--- a/trunk/ProcessHacker/Program/Program.cs
+++ b/trunk/ProcessHacker/Program/Program.cs
@@ -589,51 +589,45 @@ namespace ProcessHacker
public static void Unhook()
{
- PE.PEFile file = new ProcessHacker.PE.PEFile(Environment.SystemDirectory + "\\ntdll.dll");
- System.IO.BinaryReader br = new System.IO.BinaryReader(
- new System.IO.FileStream(Environment.SystemDirectory + "\\ntdll.dll",
- System.IO.FileMode.Open, System.IO.FileAccess.Read));
+ ProcessHacker.Native.Image.MappedImage file =
+ new ProcessHacker.Native.Image.MappedImage(Environment.SystemDirectory + "\\ntdll.dll");
IntPtr ntdll = Win32.GetModuleHandle("ntdll.dll");
MemoryProtection oldProtection;
oldProtection = ProcessHandle.GetCurrent().ProtectMemory(
ntdll,
- (int)file.COFFOptionalHeader.SizeOfCode,
+ (int)file.Size,
MemoryProtection.ExecuteReadWrite
);
- for (int i = 0; i < file.ExportData.ExportOrdinalTable.Count; i++)
+ for (int i = 0; i < file.Exports.Count; i++)
{
- ushort ordinal = file.ExportData.ExportOrdinalTable[i];
+ var entry = file.Exports.GetEntry(i);
- if (ordinal >= file.ExportData.ExportAddressTable.Count)
- continue;
-
- uint address = file.ExportData.ExportAddressTable[ordinal].ExportRVA;
- int fileAddress = (int)file.RvaToVa(address);
-
- string name = file.ExportData.ExportNameTable[i];
-
- if (!name.StartsWith("Nt") || name.StartsWith("Ntdll"))
+ if (!entry.Name.StartsWith("Nt") || entry.Name.StartsWith("Ntdll"))
continue;
byte[] fileData = new byte[5];
- br.BaseStream.Seek(fileAddress, System.IO.SeekOrigin.Begin);
-
- for (int j = 0; j < 5; j++)
+ unsafe
{
- System.Runtime.InteropServices.Marshal.WriteByte(ntdll.Increment((int)address + j), br.ReadByte());
+ IntPtr function = file.Exports.GetFunction(entry.Ordinal).Function;
+
+ Win32.RtlMoveMemory(
+ function.Decrement(new IntPtr(file.Memory)).Increment(ntdll),
+ function,
+ (5).ToIntPtr()
+ );
}
}
- br.Close();
-
ProcessHandle.GetCurrent().ProtectMemory(
ntdll,
- (int)file.COFFOptionalHeader.SizeOfCode,
+ (int)file.Size,
oldProtection
);
+
+ file.Dispose();
}
private static void CheckForPreviousInstance()
@@ -844,7 +838,7 @@ namespace ProcessHacker
info.AppendLine("OS Version: " + Environment.OSVersion.VersionString + " (" + OSVersion.BitsString + ")");
info.AppendLine("Elevation: " + ElevationType.ToString());
info.AppendLine("Working set: " + Utils.FormatSize(Environment.WorkingSet));
- info.AppendLine("Private heap: 0x" + MemoryAlloc.PrivateHeap.ToString("x"));
+ info.AppendLine("Private heap: 0x" + MemoryAlloc.PrivateHeap.Address.ToString("x"));
if (KProcessHacker.Instance == null)
info.AppendLine("KProcessHacker: not running");
@@ -1323,11 +1317,6 @@ namespace ProcessHacker
HackerWindowTopMost = f.TopMost;
}));
- foreach (Form form in Application.OpenForms)
- {
- form.TopMost = f.TopMost;
- }
-
UpdateWindowMenu(((MenuItem)sender).Parent, f);
}
diff --git a/trunk/ProcessHacker/Providers/ProcessSystemProvider.cs b/trunk/ProcessHacker/Providers/ProcessSystemProvider.cs
index d1d7057e7..2abd0c1f4 100644
--- a/trunk/ProcessHacker/Providers/ProcessSystemProvider.cs
+++ b/trunk/ProcessHacker/Providers/ProcessSystemProvider.cs
@@ -31,6 +31,7 @@ using ProcessHacker.Common;
using ProcessHacker.Common.Messaging;
using ProcessHacker.Native;
using ProcessHacker.Native.Api;
+using ProcessHacker.Native.Image;
using ProcessHacker.Native.Objects;
using ProcessHacker.Native.Security;
@@ -533,22 +534,17 @@ namespace ProcessHacker
// 1. The function-to-library ratio is lower than 4
// (on average less than 4 functions are imported from each library)
// 2. It references more than 3 libraries but less than 14 libraries.
- //
- // Note that the PE reader is horribly broken and doesn't work for
- // PE32+ files. That means we'll disable this check for 64-bit.
- if (fileName != null && (Properties.Settings.Default.VerifySignatures || forced) && IntPtr.Size == 4)
+ if (fileName != null && (Properties.Settings.Default.VerifySignatures || forced))
{
try
{
- var peFile = new PE.PEFile(fileName, false);
-
- if (peFile.ImportData != null)
+ using (var mappedImage = new MappedImage(fileName))
{
- int libraryTotal = peFile.ImportData.ImportLookupTable.Count;
+ int libraryTotal = mappedImage.Imports.Count;
int funcTotal = 0;
- foreach (var i in peFile.ImportData.ImportLookupTable)
- funcTotal += i.Count;
+ for (int i = 0; i < mappedImage.Imports.Count; i++)
+ funcTotal += mappedImage.Imports[i].Count;
fpResult.ImportModules = libraryTotal;
fpResult.ImportFunctions = funcTotal;
@@ -560,12 +556,7 @@ namespace ProcessHacker
fpResult.IsPacked = true;
}
}
- catch (System.IO.EndOfStreamException)
- {
- if (pid > 4)
- fpResult.IsPacked = true;
- }
- catch (PE.PEException)
+ catch (AccessViolationException)
{
if (pid > 4)
fpResult.IsPacked = true;