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;