Пример #1
0
        public PeUtility([NotNull] Stream srcStream)
        {
            curFileStream = srcStream ?? throw new ArgumentNullException(nameof(srcStream));

            var reader = new BinaryReader(curFileStream);

            dosHeader = FromBinaryReader <IMAGE_DOS_HEADER>(reader);

            // Add 4 bytes to the offset
            srcStream.Seek(dosHeader.e_lfanew, SeekOrigin.Begin);

            var ntHeadersSignature = reader.ReadUInt32();

            fileHeader            = FromBinaryReader <IMAGE_FILE_HEADER>(reader);
            this.fileHeaderOffset = srcStream.Position;
            if (this.Is32BitHeader)
            {
                optionalHeader32 = FromBinaryReader <IMAGE_OPTIONAL_HEADER32>(reader);
            }
            else
            {
                optionalHeader64 = FromBinaryReader <IMAGE_OPTIONAL_HEADER64>(reader);
            }

            imageSectionHeaders = new IMAGE_SECTION_HEADER[fileHeader.NumberOfSections];
            for (var headerNo = 0; headerNo < imageSectionHeaders.Length; ++headerNo)
            {
                imageSectionHeaders[headerNo] = FromBinaryReader <IMAGE_SECTION_HEADER>(reader);
            }
        }
Пример #2
0
        private void Init(Stream stream)
        {
            BinaryReader reader = new BinaryReader(stream);

            dosHeader = FromBinaryReader <IMAGE_DOS_HEADER>(reader);

            // Add 4 bytes to the offset
            stream.Seek(dosHeader.e_lfanew, SeekOrigin.Begin);

            UInt32 ntHeadersSignature = reader.ReadUInt32();

            fileHeader = FromBinaryReader <IMAGE_FILE_HEADER>(reader);
            if (this.Is32BitHeader)
            {
                optionalHeader32 = FromBinaryReader <IMAGE_OPTIONAL_HEADER32>(reader);
            }
            else
            {
                optionalHeader64 = FromBinaryReader <IMAGE_OPTIONAL_HEADER64>(reader);
            }

            imageSectionHeaders = new IMAGE_SECTION_HEADER[fileHeader.NumberOfSections];
            for (int headerNo = 0; headerNo < imageSectionHeaders.Length; ++headerNo)
            {
                imageSectionHeaders[headerNo] = FromBinaryReader <IMAGE_SECTION_HEADER>(reader);
            }
        }
Пример #3
0
        internal FileHeader(PortableExecutableImage image, IMAGE_FILE_HEADER fileHeader, ulong headerOffset, ulong imageBase)
        {
            _image  = image;
            _header = fileHeader;

            Location = new Location(image, headerOffset, headerOffset.ToUInt32(), imageBase + headerOffset, Size.ToUInt32(), Size.ToUInt32());
        }
Пример #4
0
        private void Load(Stream stream)
        {
            BinaryReader reader = new BinaryReader(stream);

            dosHeader = FromBinaryReader <IMAGE_DOS_HEADER>(reader, null);

            // Add 4 bytes to the offset
            stream.Seek(dosHeader.e_lfanew, SeekOrigin.Begin);
            UInt32 ntHeadersSignature = reader.ReadUInt32();

            fileHeader = FromBinaryReader <IMAGE_FILE_HEADER>(reader, null);

            // Read optional header magic to determin 32-bit vs 64-bit
            var optMagic = reader.ReadUInt16();

            _is32bit = (optMagic != IMAGE_NT_OPTIONAL_HDR64_MAGIC);
            var lookahead = new byte[] { (byte)(optMagic >> 8), (byte)(optMagic & 0xff) };

            if (_is32bit)
            {
                optionalHeader32 = FromBinaryReader <IMAGE_OPTIONAL_HEADER32>(reader, lookahead);
            }
            else
            {
                optionalHeader64 = FromBinaryReader <IMAGE_OPTIONAL_HEADER64>(reader, lookahead);
            }

            imageSectionHeaders = new IMAGE_SECTION_HEADER[fileHeader.NumberOfSections];
            for (int headerNo = 0; headerNo < imageSectionHeaders.Length; ++headerNo)
            {
                imageSectionHeaders[headerNo] = FromBinaryReader <IMAGE_SECTION_HEADER>(reader, null);
            }
        }
Пример #5
0
        public PELoader(byte[] fileBytes)
        {
            // Read in the DLL or EXE and get the timestamp
            using (MemoryStream stream = new MemoryStream(fileBytes, 0, fileBytes.Length))
            {
                BinaryReader reader = new BinaryReader(stream);
                dosHeader = FromBinaryReader <IMAGE_DOS_HEADER>(reader);

                // Add 4 bytes to the offset
                stream.Seek(dosHeader.e_lfanew, SeekOrigin.Begin);

                UInt32 ntHeadersSignature = reader.ReadUInt32();
                fileHeader = FromBinaryReader <IMAGE_FILE_HEADER>(reader);
                if (this.Is32BitHeader)
                {
                    optionalHeader32 = FromBinaryReader <IMAGE_OPTIONAL_HEADER32>(reader);
                }
                else
                {
                    optionalHeader64 = FromBinaryReader <IMAGE_OPTIONAL_HEADER64>(reader);
                }

                imageSectionHeaders = new IMAGE_SECTION_HEADER[fileHeader.NumberOfSections];
                for (int headerNo = 0; headerNo < imageSectionHeaders.Length; ++headerNo)
                {
                    imageSectionHeaders[headerNo] = FromBinaryReader <IMAGE_SECTION_HEADER>(reader);
                }


                RawBytes = fileBytes;
            }
        }
Пример #6
0
        /// <summary>
        /// Reading from unmanaged memory pointer address.
        /// </summary>
        /// <param name="memPtr"></param>
        /// <param name="index"></param>
        private void Load(IntPtr memPtr, long index)
        {
            var startIndex = index;

            dosHeader = FromMemoryPtr <IMAGE_DOS_HEADER>(memPtr, ref index);
            index     = startIndex + dosHeader.e_lfanew + 4;

            fileHeader = FromMemoryPtr <IMAGE_FILE_HEADER>(memPtr, ref index);

            // See the optiona header magic to determine 32-bit vs 64-bit
            var optMagic = Marshal.ReadInt16(new IntPtr(memPtr.ToInt64() + index));

            _is32bit = (optMagic != IMAGE_NT_OPTIONAL_HDR64_MAGIC);

            if (_is32bit)
            {
                optionalHeader32 = FromMemoryPtr <IMAGE_OPTIONAL_HEADER32>(memPtr, ref index);
            }
            else
            {
                optionalHeader64 = FromMemoryPtr <IMAGE_OPTIONAL_HEADER64>(memPtr, ref index);
            }

            imageSectionHeaders = new IMAGE_SECTION_HEADER[fileHeader.NumberOfSections];
            for (int headerNo = 0; headerNo < imageSectionHeaders.Length; ++headerNo)
            {
                imageSectionHeaders[headerNo] = FromMemoryPtr <IMAGE_SECTION_HEADER>(memPtr, ref index);
            }
        }
Пример #7
0
    public PeHeaderReader(string filePath)
    {
        // Read in the DLL or EXE and get the timestamp
        using (FileStream stream = new FileStream(filePath, System.IO.FileMode.Open, System.IO.FileAccess.Read)) {
            BinaryReader reader = new BinaryReader(stream);
            dosHeader = FromBinaryReader <IMAGE_DOS_HEADER>(reader);

            // Add 4 bytes to the offset
            stream.Seek(dosHeader.e_lfanew, SeekOrigin.Begin);

            UInt32 ntHeadersSignature = reader.ReadUInt32();
            fileHeader = FromBinaryReader <IMAGE_FILE_HEADER>(reader);
            if (this.Is32BitHeader)
            {
                optionalHeader32 = FromBinaryReader <IMAGE_OPTIONAL_HEADER32>(reader);
            }
            else
            {
                optionalHeader64 = FromBinaryReader <IMAGE_OPTIONAL_HEADER64>(reader);
            }

            imageSectionHeaders = new IMAGE_SECTION_HEADER[fileHeader.NumberOfSections];
            for (int headerNo = 0; headerNo < imageSectionHeaders.Length; ++headerNo)
            {
                imageSectionHeaders[headerNo] = FromBinaryReader <IMAGE_SECTION_HEADER>(reader);
            }
        }
    }
Пример #8
0
        private static IMAGE_SECTION_HEADER GetSection(IntPtr hProcess, IntPtr baseAddress, string section)
        {
            IMAGE_DOS_HEADER  image_dos_header  = ReadUnmanagedStructure <IMAGE_DOS_HEADER>(hProcess, baseAddress);
            IntPtr            lpAddr            = new IntPtr(baseAddress.ToInt64() + (image_dos_header.e_lfanew + 4));
            IMAGE_FILE_HEADER image_file_header = ReadUnmanagedStructure <IMAGE_FILE_HEADER>(hProcess, lpAddr);

            lpAddr = new IntPtr(lpAddr.ToInt64() + (Marshal.SizeOf(typeof(IMAGE_FILE_HEADER)) + image_file_header.SizeOfOptionalHeader));
            for (int i = 0; i < image_file_header.NumberOfSections; i++)
            {
                IMAGE_SECTION_HEADER image_section_header = ReadUnmanagedStructure <IMAGE_SECTION_HEADER>(hProcess, lpAddr);
                lpAddr = new IntPtr(lpAddr.ToInt64() + Marshal.SizeOf(typeof(IMAGE_SECTION_HEADER)));
                for (int j = 0; j < 8; j++)
                {
                    if (section.Length == j)
                    {
                        return(image_section_header);
                    }
                    if (section[j] != image_section_header.Name[j])
                    {
                        break;
                    }
                }
            }
            return(new IMAGE_SECTION_HEADER());
        }
Пример #9
0
        /// <summary>
        /// return the machine type
        /// </summary>
        /// <returns></returns>
        public string GetMachineType(PeHeaderReader reader)
        {
            IMAGE_FILE_HEADER fileHeader = reader.FileHeader;
            UInt16            machine    = fileHeader.Machine;

            //string hexValue = machine.ToString("X");
            switch (machine)
            {
            case 332:
                return("Intel 386");

                break;

            case 512:
                return("Intel 64");

                break;

            case 34404:
                return("AMD 64");

                break;

            default:
                return("Machine type Unknown");

                break;
            }
        }
Пример #10
0
 public PeFile32(IMAGE_DOS_HEADER dosHeader, IMAGE_FILE_HEADER peHeader, IMAGE_OPTIONAL_HEADER32 optionalHeader, IMAGE_EXPORT_DIRECTORY exportDirectory, Dictionary <string, IntPtr> exports)
 {
     this.DosHeader       = dosHeader;
     this.PeHeader        = peHeader;
     this.OptionalHeader  = optionalHeader;
     this.ExportDirectory = exportDirectory;
     Exports = exports;
 }
Пример #11
0
        /// <summary>
        ///     Create a new IMAGE_NT_HEADERS object.
        /// </summary>
        /// <param name="buff">A PE file as a byte array.</param>
        /// <param name="offset">Raw offset of the NT header.</param>
        public IMAGE_NT_HEADERS(byte[] buff, uint offset)
            : base(buff, offset)
        {
            FileHeader = new IMAGE_FILE_HEADER(buff, offset + 0x4);

            var is32Bit = FileHeader.Machine == 0x14c;

            OptionalHeader = new IMAGE_OPTIONAL_HEADER(buff, offset + 0x18, !is32Bit);
        }
Пример #12
0
        public void ImageFileHeaderConstructorWorks_Test()
        {
            var fileHeader = new IMAGE_FILE_HEADER(RawStructures.RawFileHeader, 2);

            Assert.Equal((ushort)0x1100, fileHeader.Machine);
            Assert.Equal((ushort)0x3322, fileHeader.NumberOfSections);
            Assert.Equal((uint)0x77665544, fileHeader.TimeDateStamp);
            Assert.Equal(0xbbaa9988, fileHeader.PointerToSymbolTable);
            Assert.Equal(0xffeeddcc, fileHeader.NumberOfSymbols);
            Assert.Equal((ushort)0x2211, fileHeader.SizeOfOptionalHeader);
            Assert.Equal((ushort)0x4433, fileHeader.Characteristics);
        }
Пример #13
0
 public static PE64FileHeader FromNativeStruct(IMAGE_FILE_HEADER nativeStruct)
 {
     return(new PE64FileHeader
     {
         Machine = nativeStruct.Machine,
         NumberOfSections = nativeStruct.NumberOfSections,
         TimeDateStamp = nativeStruct.TimeDateStamp,
         PointerToSymbolTable = nativeStruct.PointerToSymbolTable,
         NumberOfSymbols = nativeStruct.NumberOfSymbols,
         SizeOfOptionalHeader = nativeStruct.SizeOfOptionalHeader,
         Characteristics = nativeStruct.Characteristics
     });
 }
Пример #14
0
        public static IMAGE_FILE_HEADER Deserialize(MultiPartFile file)
        {
            IMAGE_FILE_HEADER ifh = new IMAGE_FILE_HEADER();

            ifh.Machine              = file.ReadUInt16();
            ifh.NumberOfSections     = file.ReadUInt16();
            ifh.TimeDateStamp        = file.ReadUInt32();
            ifh.PointerToSymbolTable = file.ReadUInt32();
            ifh.NumberOfSymbols      = file.ReadUInt32();
            ifh.SizeOfOptionalHeader = file.ReadUInt16();
            ifh.Characteristics      = file.ReadUInt16();

            return(ifh);
        }
Пример #15
0
        public PEReader(string filePath)
        {
            using (FileStream stream = new FileStream(filePath, System.IO.FileMode.Open, System.IO.FileAccess.Read))
            {
                BinaryReader reader = new BinaryReader(stream);
                dosHeader = FromBinaryReader <IMAGE_DOS_HEADER>(reader);

                stream.Seek(dosHeader.e_lfanew, SeekOrigin.Begin);

                UInt32 ntHeadersSignature = reader.ReadUInt32();
                fileHeader       = FromBinaryReader <IMAGE_FILE_HEADER>(reader);
                optionalHeader32 = FromBinaryReader <IMAGE_OPTIONAL_HEADER32>(reader);
            }
        }
Пример #16
0
        public bool IsPE(string fileName)
        {
            using (var stream = new FileStream(fileName, System.IO.FileMode.Open, System.IO.FileAccess.Read))
            {
                var reader = new BinaryReader(stream);

                var peHeader = reader.ReadBytes(2);

                // PE Header is less than the minimum
                if (peHeader.Length < 2)
                {
                    return(false);
                }

                // Check the first two bytes to rule out anything not DLL, EXE, SYS etc
                if (peHeader[0] != (byte)'M' && peHeader[1] != (byte)'Z')
                {
                    return(false);
                }

                reader.BaseStream.Seek(0, SeekOrigin.Begin);

                dosHeader = FromBinaryReader <IMAGE_DOS_HEADER>(reader);

                // Add 4 bytes to the offset
                stream.Seek(dosHeader.e_lfanew, SeekOrigin.Begin);

                var ntHeadersSignature = reader.ReadUInt32();

                fileHeader = FromBinaryReader <IMAGE_FILE_HEADER>(reader);

                if (Is32BitHeader)
                {
                    optionalHeader32 = FromBinaryReader <IMAGE_OPTIONAL_HEADER32>(reader);
                }
                else
                {
                    optionalHeader64 = FromBinaryReader <IMAGE_OPTIONAL_HEADER64>(reader);
                }

                imageSectionHeaders = new IMAGE_SECTION_HEADER[fileHeader.NumberOfSections];

                for (var headerNo = 0; headerNo < imageSectionHeaders.Length; ++headerNo)
                {
                    imageSectionHeaders[headerNo] = FromBinaryReader <IMAGE_SECTION_HEADER>(reader);
                }

                return(true);
            }
        }
Пример #17
0
        public PeFileHeaderReader(string path)
        {
            Path = path;

            using (var stream = new FileStream(path, System.IO.FileMode.Open, System.IO.FileAccess.Read))
            {
                var reader = new BinaryReader(stream);

                var dosHeader = FromBinaryReader <IMAGE_DOS_HEADER>(reader);

                reader.BaseStream.Position = stream.Seek(dosHeader.e_lfanew, SeekOrigin.Begin) + 4;

                _fileHeader = FromBinaryReader <IMAGE_FILE_HEADER>(reader);
            }
        }
Пример #18
0
        static void HideHollowedProcess(IntPtr hProcess, HostProcessInfo hpi)
        {
            if (IntPtr.Size == 4)
            {
                Console.WriteLine("[=] Hide allow process not available on x86 yet, use --disable-header-patch to supress this warning");
                return;
            }

            //Pull out the current image headers
            IMAGE_DOS_HEADER        dosHeader      = ReadType <IMAGE_DOS_HEADER>(hProcess, hpi.newLoadAddress);
            IMAGE_FILE_HEADER       fileHeader     = ReadType <IMAGE_FILE_HEADER>(hProcess, new IntPtr(hpi.newLoadAddress.ToInt64() + dosHeader.e_lfanew));
            IMAGE_OPTIONAL_HEADER64 optionalHeader = ReadType <IMAGE_OPTIONAL_HEADER64>(hProcess, new IntPtr(hpi.newLoadAddress.ToInt64() + dosHeader.e_lfanew +
                                                                                                             Marshal.SizeOf(typeof(IMAGE_FILE_HEADER))));

            //Clear some key areas used to spot PE files in memory
            ClearMemory(hProcess, hpi.newLoadAddress, 3);
            ClearMemory(hProcess, new IntPtr(hpi.newLoadAddress.ToInt64() + 0x40), (int)dosHeader.e_lfanew - 0x40);
            ClearMemory(hProcess, new IntPtr(hpi.newLoadAddress.ToInt64() + (int)dosHeader.e_lfanew), Marshal.SizeOf(typeof(IMAGE_FILE_HEADER)));

            //Clear out section names and characteristics used to identify implanted PE files
            for (int section = 0; section < fileHeader.NumberOfSections; section++)
            {
                IntPtr sectionOffset = new IntPtr(hpi.newLoadAddress.ToInt64() +
                                                  (int)dosHeader.e_lfanew + Marshal.SizeOf(typeof(IMAGE_FILE_HEADER)) +
                                                  fileHeader.SizeOfOptionalHeader +
                                                  (Marshal.SizeOf(typeof(Execute.PE.IMAGE_SECTION_HEADER)) * section));

                Execute.PE.IMAGE_SECTION_HEADER ish = ReadType <Execute.PE.IMAGE_SECTION_HEADER>(hProcess, sectionOffset);
                ish.Name            = new char[8];
                ish.Characteristics = 0;
                WriteType <Execute.PE.IMAGE_SECTION_HEADER>(hProcess, sectionOffset, ish);
            }

            //Replace base address in PEB with the original
            WritePointer(hProcess, new IntPtr(hpi.peb.ToInt64() + 0x10), hpi.previousLoadAddress);

            //Finally replace main module load address and entrypoint with original host process
            IntPtr               pebLdrDataPtr = ReadPointer(hProcess, new IntPtr(hpi.peb.ToInt64() + 0x18));
            PEB_LDR_DATA         pebLdrData    = ReadType <PEB_LDR_DATA>(hProcess, pebLdrDataPtr);
            LDR_DATA_TABLE_ENTRY mainModule    = ReadType <LDR_DATA_TABLE_ENTRY>(hProcess, pebLdrData.InLoadOrderModuleListPtr.Flink);

            mainModule.DllBase    = hpi.previousLoadAddress;
            mainModule.EntryPoint = hpi.previousEntryPoint;
            WriteType(hProcess, pebLdrData.InLoadOrderModuleListPtr.Flink, mainModule);
        }
        public PELoader(string filePath)
        {
            // Read in the DLL or EXE and get the timestamp
            try
            {
                using (FileStream stream = new FileStream(filePath, System.IO.FileMode.Open, System.IO.FileAccess.Read))
                {
                    BinaryReader reader = new BinaryReader(stream);
                    dosHeader = FromBinaryReader <IMAGE_DOS_HEADER>(reader);
                    stream.Seek(dosHeader.e_lfanew, SeekOrigin.Begin);

                    UInt32 ntHeadersSignature = reader.ReadUInt32();
                    fileHeader = FromBinaryReader <IMAGE_FILE_HEADER>(reader);
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("[!] {0}", e.Message);
                Environment.Exit(0);
            }
        }
Пример #20
0
        /// <summary>
        /// find the header information
        /// </summary>
        /// <returns></returns>
        private void GetHeader(List <HeaderObject> Headers, PeHeaderReader reader)
        {
            IMAGE_FILE_HEADER fileHeader           = reader.FileHeader;
            UInt16            machine              = fileHeader.Machine;
            UInt16            numberOfSections     = fileHeader.NumberOfSections;
            UInt32            timeDateStamp        = fileHeader.TimeDateStamp;
            UInt32            pointerToSymbolTable = fileHeader.PointerToSymbolTable;
            UInt32            numberOfSymbols      = fileHeader.NumberOfSymbols;
            UInt16            sizeOfOptionalHeader = fileHeader.SizeOfOptionalHeader;
            UInt16            characteristics      = fileHeader.Characteristics;
            string            MachineType          = GetMachineType(reader);
            string            character            = GetCharacterInformation(characteristics);

            Headers.Add(new HeaderObject("Machine", MachineType));
            Headers.Add(new HeaderObject("Number of sections", numberOfSections.ToString()));
            Headers.Add(new HeaderObject("Timestamp", timeDateStamp.ToString()));
            Headers.Add(new HeaderObject("Pointer to symbol table", pointerToSymbolTable.ToString()));
            Headers.Add(new HeaderObject("Number of symbols", numberOfSymbols.ToString()));
            Headers.Add(new HeaderObject("Size of optional header", sizeOfOptionalHeader.ToString()));
            Headers.Add(new HeaderObject("Characteristics", character));
            return;
        }
Пример #21
0
        public PeHeaderReader(string filePath)
        {
            // Read in the DLL or EXE and get the timestamp
            using (FileStream stream = new FileStream(filePath, System.IO.FileMode.Open, System.IO.FileAccess.Read))
            {
                BinaryReader reader = new BinaryReader(stream);
                dosHeader = FromBinaryReader <IMAGE_DOS_HEADER>(reader);

                // Add 4 bytes to the offset
                stream.Seek(dosHeader.e_lfanew, SeekOrigin.Begin);

                uint ntHeadersSignature = reader.ReadUInt32();
                fileHeader = FromBinaryReader <IMAGE_FILE_HEADER>(reader);
                if (Is32BitHeader)
                {
                    optionalHeader32 = FromBinaryReader <IMAGE_OPTIONAL_HEADER32>(reader);
                }
                else
                {
                    optionalHeader64 = FromBinaryReader <IMAGE_OPTIONAL_HEADER64>(reader);
                }
            }
        }
Пример #22
0
        /// <summary>
        /// find the section information for a given file
        /// </summary>
        /// <returns></returns>
        private void GetSections(List <SectionObject> Sections, PeHeaderReader reader)
        {
            PeHeaderReader.IMAGE_SECTION_HEADER[] sections = reader.ImageSectionHeaders;
            IMAGE_FILE_HEADER fileheader      = reader.FileHeader;
            UInt32            numberofSection = fileheader.NumberOfSections;

            foreach (PeHeaderReader.IMAGE_SECTION_HEADER section in sections)
            {
                char[] name                 = section.Name;
                UInt32 virtualAddress       = section.VirtualAddress;
                UInt32 pointerToRawData     = section.PointerToRawData;
                UInt32 virtualSize          = section.VirtualSize;
                UInt32 sizeOFrawData        = section.SizeOfRawData;
                UInt32 pointerToRelocations = section.PointerToRelocations;
                UInt32 pointerToLineNumber  = section.PointerToLinenumbers;
                UInt16 numberOfRelocations  = section.NumberOfRelocations;
                UInt16 NumberOfLineNumbers  = section.NumberOfLinenumbers;
                PeHeaderReader.DataSectionFlags dataSectionFlags = section.Characteristics;
                string nameOfSection = section.Section;

                Sections.Add(new SectionObject(nameOfSection, virtualAddress, virtualSize, pointerToRawData, sizeOFrawData));
            }
            return;
        }
Пример #23
0
        public PESupport(string LibraryName)
        {
            Debug.Assert(LibraryName != null);

            this.LibraryName = LibraryName;

            hLibrary = IntPtr.Zero;
            IntPtr original_hLibrary = LoadLibraryEx(this.LibraryName, IntPtr.Zero, LoadLibraryFlags.DONT_RESOLVE_DLL_REFERENCES); // access violations occur with LOAD_LIBRARY_AS_DATAFILE, but don't with DONT_RESOLVE_DLL_REFERENCES for some reason
            hLibrary = new IntPtr(original_hLibrary.ToInt32() - original_hLibrary.ToInt32() % 4); // adjust things to a DWORD boundary

            int error = Marshal.GetLastWin32Error();
            if (hLibrary == null && error != 0)
            {
                throw new System.ApplicationException("Got error " + error + " when loading library " + LibraryName);
            }

            // do some sanity checking
            dosHeader = (IMAGE_DOS_HEADER)Marshal.PtrToStructure(hLibrary, typeof(IMAGE_DOS_HEADER));
            if (!dosHeader.isValid)
            {
                throw new System.ApplicationException("Library does not appear to be a valid DOS file!");
            }

            ntHeader = (IMAGE_NT_HEADERS32)Marshal.PtrToStructure(hLibrary + dosHeader.e_lfanew, typeof(IMAGE_NT_HEADERS32));
            if (!ntHeader.isValid)
            {
                throw new System.ApplicationException("Library NT Header does not appear valid!");
            }

            fileHeader = ntHeader.FileHeader;
            if (fileHeader.Machine != (UInt16)(MachineType.I386))
            {
                throw new System.ApplicationException("Library appears to be compiled for x64 while this program only supports x86 libraries.");
            }
            optionalHeader = ntHeader.OptionalHeader;

            exports = new Dictionary<int, List<string>>();

            // if we don't have an export directory, move on
            if (optionalHeader.ExportTable.VirtualAddress == 0 || optionalHeader.ExportTable.Size == 0)
            {
                FreeLibrary(original_hLibrary);
                return;
            }

            // initialise the export header
            exportHeader = (IMAGE_EXPORT_DIRECTORY)Marshal.PtrToStructure(hLibrary + (int)optionalHeader.ExportTable.VirtualAddress, typeof(IMAGE_EXPORT_DIRECTORY));

            for (int i = 0; i < exportHeader.NumberOfNames; i++)
            {

                // grab the pointer to the next entry in the string table. In C, this would be a char*
                IntPtr namePtr = (IntPtr)Marshal.PtrToStructure(hLibrary + (int)(exportHeader.AddressOfNames) + (4 * i), typeof(IntPtr));

                // dereference the previous char*
                string name;
                try
                {
                    name = Marshal.PtrToStringAnsi(hLibrary + namePtr.ToInt32());
                }
                catch (Exception ex)
                {
                    name = "";
                    Console.WriteLine(ex.StackTrace);
                }

                // grab the address for this function
                int address = ((IntPtr)Marshal.PtrToStructure(hLibrary + (int)(exportHeader.AddressOfFunctions) + 4 * i, typeof(IntPtr))).ToInt32();
                address += (int)optionalHeader.ImageBase;

                if (exports.ContainsKey(address))
                {
                    exports[address].Add(name);
                }
                else
                {
                    exports[address] = new List<string>();
                    exports[address].Add(name);
                }

            }

            FreeLibrary(original_hLibrary);
        }
Пример #24
0
        public PESupport(string LibraryName)
        {
            Debug.Assert(LibraryName != null);

            this.LibraryName = LibraryName;

            hLibrary = IntPtr.Zero;
            IntPtr original_hLibrary = LoadLibraryEx(this.LibraryName, IntPtr.Zero, LoadLibraryFlags.DONT_RESOLVE_DLL_REFERENCES); // access violations occur with LOAD_LIBRARY_AS_DATAFILE, but don't with DONT_RESOLVE_DLL_REFERENCES for some reason

            hLibrary = new IntPtr(original_hLibrary.ToInt32() - original_hLibrary.ToInt32() % 4);                                  // adjust things to a DWORD boundary


            int error = Marshal.GetLastWin32Error();

            if (hLibrary == null && error != 0)
            {
                throw new System.ApplicationException("Got error " + error + " when loading library " + LibraryName);
            }

            // do some sanity checking
            dosHeader = (IMAGE_DOS_HEADER)Marshal.PtrToStructure(hLibrary, typeof(IMAGE_DOS_HEADER));
            if (!dosHeader.isValid)
            {
                throw new System.ApplicationException("Library does not appear to be a valid DOS file!");
            }

            ntHeader = (IMAGE_NT_HEADERS32)Marshal.PtrToStructure(hLibrary + dosHeader.e_lfanew, typeof(IMAGE_NT_HEADERS32));
            if (!ntHeader.isValid)
            {
                throw new System.ApplicationException("Library NT Header does not appear valid!");
            }

            fileHeader = ntHeader.FileHeader;
            if (fileHeader.Machine != (UInt16)(MachineType.I386))
            {
                throw new System.ApplicationException("Library appears to be compiled for x64 while this program only supports x86 libraries.");
            }
            optionalHeader = ntHeader.OptionalHeader;

            exports = new Dictionary <int, List <string> >();

            // if we don't have an export directory, move on
            if (optionalHeader.ExportTable.VirtualAddress == 0 || optionalHeader.ExportTable.Size == 0)
            {
                FreeLibrary(original_hLibrary);
                return;
            }

            // initialise the export header
            exportHeader = (IMAGE_EXPORT_DIRECTORY)Marshal.PtrToStructure(hLibrary + (int)optionalHeader.ExportTable.VirtualAddress, typeof(IMAGE_EXPORT_DIRECTORY));

            for (int i = 0; i < exportHeader.NumberOfNames; i++)
            {
                // grab the pointer to the next entry in the string table. In C, this would be a char*
                IntPtr namePtr = (IntPtr)Marshal.PtrToStructure(hLibrary + (int)(exportHeader.AddressOfNames) + (4 * i), typeof(IntPtr));

                // dereference the previous char*
                string name;
                try
                {
                    name = Marshal.PtrToStringAnsi(hLibrary + namePtr.ToInt32());
                }
                catch (Exception ex)
                {
                    name = "";
                    Console.WriteLine(ex.StackTrace);
                }

                // grab the address for this function
                int address = ((IntPtr)Marshal.PtrToStructure(hLibrary + (int)(exportHeader.AddressOfFunctions) + 4 * i, typeof(IntPtr))).ToInt32();
                address += (int)optionalHeader.ImageBase;

                if (exports.ContainsKey(address))
                {
                    exports[address].Add(name);
                }
                else
                {
                    exports[address] = new List <string>();
                    exports[address].Add(name);
                }
            }


            FreeLibrary(original_hLibrary);
        }
Пример #25
0
    public static bool Is32BitHeader(IMAGE_FILE_HEADER fileHeader)
    {
        UInt16 IMAGE_FILE_32BIT_MACHINE = 0x0100;

        return((IMAGE_FILE_32BIT_MACHINE & fileHeader.Characteristics) == IMAGE_FILE_32BIT_MACHINE);
    }
Пример #26
0
        public PeHeaderReader(string filePath)
        {
            using (FileStream stream = new FileStream(filePath, System.IO.FileMode.Open, System.IO.FileAccess.Read))
            {
                BinaryReader reader = new BinaryReader(stream);
                dosHeader = FromBinaryReader <IMAGE_DOS_HEADER>(reader);

                // Add 4 bytes to the offset
                stream.Seek(dosHeader.e_lfanew, SeekOrigin.Begin);

                UInt32 ntHeadersSignature = reader.ReadUInt32();
                fileHeader = FromBinaryReader <IMAGE_FILE_HEADER>(reader);
                if (this.Is32BitHeader)
                {
                    optionalHeader32 = FromBinaryReader <IMAGE_OPTIONAL_HEADER32>(reader);
                }
                else
                {
                    optionalHeader64 = FromBinaryReader <IMAGE_OPTIONAL_HEADER64>(reader);
                }

                uint offDebug     = 0;
                uint cbDebug      = 0;
                long cbFromHeader = 0;
                int  loopexit     = 0;

                if (this.Is32BitHeader)
                {
                    cbDebug = optionalHeader32.Debug.Size;
                }
                else
                {
                    cbDebug = optionalHeader64.Debug.Size;
                }

                imageSectionHeaders = new IMAGE_SECTION_HEADER[fileHeader.NumberOfSections];
                for (int headerNo = 0; headerNo < imageSectionHeaders.Length; ++headerNo)
                {
                    imageSectionHeaders[headerNo] = FromBinaryReader <IMAGE_SECTION_HEADER>(reader);

                    if ((imageSectionHeaders[headerNo].PointerToRawData != 0) &&
                        (imageSectionHeaders[headerNo].SizeOfRawData != 0) &&
                        (cbFromHeader < (long)
                         (imageSectionHeaders[headerNo].PointerToRawData + imageSectionHeaders[headerNo].SizeOfRawData)))
                    {
                        cbFromHeader = (long)
                                       (imageSectionHeaders[headerNo].PointerToRawData + imageSectionHeaders[headerNo].SizeOfRawData);
                    }

                    if (cbDebug != 0)
                    {
                        if (this.Is32BitHeader)
                        {
                            if (imageSectionHeaders[headerNo].VirtualAddress <= optionalHeader32.Debug.VirtualAddress &&
                                ((imageSectionHeaders[headerNo].VirtualAddress + imageSectionHeaders[headerNo].SizeOfRawData) > optionalHeader32.Debug.VirtualAddress))
                            {
                                offDebug = optionalHeader32.Debug.VirtualAddress - imageSectionHeaders[headerNo].VirtualAddress + imageSectionHeaders[headerNo].PointerToRawData;
                            }
                        }
                        else
                        {
                            if (imageSectionHeaders[headerNo].VirtualAddress <= optionalHeader64.Debug.VirtualAddress &&
                                ((imageSectionHeaders[headerNo].VirtualAddress + imageSectionHeaders[headerNo].SizeOfRawData) > optionalHeader64.Debug.VirtualAddress))
                            {
                                offDebug = optionalHeader64.Debug.VirtualAddress - imageSectionHeaders[headerNo].VirtualAddress + imageSectionHeaders[headerNo].PointerToRawData;
                            }
                        }
                    }
                }

                stream.Seek(offDebug, SeekOrigin.Begin);

                while (cbDebug >= Marshal.SizeOf(typeof(IMAGE_DEBUG_DIRECTORY)))
                {
                    if (loopexit == 0)
                    {
                        imageDebugDirectory = FromBinaryReader <IMAGE_DEBUG_DIRECTORY>(reader);
                        long seekPosition = stream.Position;

                        if (imageDebugDirectory.Type == 0x2)
                        {
                            stream.Seek(imageDebugDirectory.PointerToRawData, SeekOrigin.Begin);
                            DebugInfo = FromBinaryReader <IMAGE_DEBUG_DIRECTORY_RAW>(reader);
                            loopexit  = 1;

                            //Downloading logic for .NET native images
                            if (new string(DebugInfo.name).Contains(".ni."))
                            {
                                stream.Seek(seekPosition, SeekOrigin.Begin);
                                loopexit = 0;
                            }
                        }

                        if ((imageDebugDirectory.PointerToRawData != 0) &&
                            (imageDebugDirectory.SizeOfData != 0) &&
                            (cbFromHeader < (long)
                             (imageDebugDirectory.PointerToRawData + imageDebugDirectory.SizeOfData)))
                        {
                            cbFromHeader = (long)
                                           (imageDebugDirectory.PointerToRawData + imageDebugDirectory.SizeOfData);
                        }
                    }

                    cbDebug -= (uint)Marshal.SizeOf(typeof(IMAGE_DEBUG_DIRECTORY));
                }

                if (loopexit != 0)
                {
                    _pdbName = new string(DebugInfo.name);
                    _pdbName = _pdbName.Remove(_pdbName.IndexOf("\0"));

                    _pdbage    = DebugInfo.age.ToString("X");
                    _debugGUID = DebugInfo.guid;
                }
            }
        }
Пример #27
0
        private unsafe void PopulateHeaderStructs(FileStream fin)
        {
            byte[] Data  = new byte[4096];
            int    iRead = fin.Read(Data, 0, 4096);

            fin.Flush();
            fin.Close();

            fixed(byte *p_Data = Data)
            {
                IMAGE_DOS_HEADER *  idh  = (IMAGE_DOS_HEADER *)p_Data;
                IMAGE_NT_HEADERS32 *inhs = (IMAGE_NT_HEADERS32 *)(idh->nt_head_ptr + p_Data);

                ModuleMachineType = (MachineType)inhs->FileHeader.Machine;

                if (ModuleMachineType == MachineType.I386)
                {
                    IMAGE_NT_HEADERS32 *inhs32 = (IMAGE_NT_HEADERS32 *)(idh->nt_head_ptr + p_Data);
                    ImageFileHeader       = inhs32->FileHeader;
                    ModuleMachineType     = (MachineType)inhs32->FileHeader.Machine;
                    ImageOptionalHeader32 = inhs32->OptionalHeader;
                    ModuleImageBase       = (IntPtr)inhs32->OptionalHeader.ImageBase;

                    ImageNTHeaders32 = new IMAGE_NT_HEADERS32
                    {
                        Signature      = inhs32->Signature,
                        FileHeader     = inhs32->FileHeader,
                        OptionalHeader = inhs32->OptionalHeader
                    };

                    byte[] bytes = new byte[256];
                    var    ret   = ErcCore.ReadProcessMemory(ModuleProcess.Handle,
                                                             (IntPtr)((uint)ModuleBase + ImageOptionalHeader32.LoadConfigTable.VirtualAddress), bytes, 256, out int BytesRead);
                    if (BitConverter.ToUInt32(bytes, 58) > 0 || BitConverter.ToUInt32(bytes, 62) > 0)
                    {
                        ModuleSafeSEH = true;
                    }
                }
                else if (ModuleMachineType == MachineType.x64)
                {
                    IMAGE_NT_HEADERS64 *inhs64 = (IMAGE_NT_HEADERS64 *)(idh->nt_head_ptr + p_Data);
                    ImageFileHeader       = inhs64->FileHeader;
                    ImageOptionalHeader64 = inhs64->OptionalHeader;
                    ModuleImageBase       = (IntPtr)inhs64->OptionalHeader.ImageBase;

                    ImageNTHeaders64 = new IMAGE_NT_HEADERS64
                    {
                        Signature      = inhs64->Signature,
                        FileHeader     = inhs64->FileHeader,
                        OptionalHeader = inhs64->OptionalHeader
                    };

                    byte[] bytes = new byte[256];
                    var    ret   = ErcCore.ReadProcessMemory(ModuleProcess.Handle,
                                                             (IntPtr)((long)ModuleBase + (long)ImageOptionalHeader64.LoadConfigTable.VirtualAddress), bytes, 256, out int BytesRead);
                    if (BitConverter.ToUInt64(bytes, 88) > 0 || BitConverter.ToUInt64(bytes, 96) > 0)
                    {
                        ModuleSafeSEH = true;
                    }
                }
                else
                {
                    ModuleFailed = true;
                }
            }
        }
Пример #28
0
        /// <summary>
        /// Parses the specified data.
        /// </summary>
        /// <param name="data">The PE image data.</param>
        private void ParseData(byte[] data)
        {
            using (DwarfMemoryReader reader = new DwarfMemoryReader(data))
            {
                dosHeader = reader.ReadStructure <IMAGE_DOS_HEADER>();
                if (dosHeader.e_magic != IMAGE_DOS_SIGNATURE)
                {
                    throw new ArgumentException($"Invalid IMAGE_DOS_HEADER magic constant. Expected: 0x{IMAGE_DOS_SIGNATURE:X}, Got: 0x{dosHeader.e_magic:X}");
                }

                reader.Position = (int)dosHeader.e_lfanew;
                ntHeaders32     = reader.ReadStructure <IMAGE_NT_HEADERS32>();
                if (ntHeaders32.Signature != IMAGE_NT_SIGNATURE)
                {
                    throw new ArgumentException($"Invalid optional header signature. Expected: 0x{IMAGE_NT_SIGNATURE:X}, Got: 0x{ntHeaders32.Signature:X}");
                }
                if (ntHeaders32.FileHeader.Machine == IMAGE_FILE_MACHINE_AMD64 ||
                    ntHeaders32.FileHeader.Machine == IMAGE_FILE_MACHINE_IA64)
                {
                    reader.Position   = (int)dosHeader.e_lfanew;
                    ntHeaders64       = reader.ReadStructure <IMAGE_NT_HEADERS64>();
                    Is64bit           = true;
                    fileHeader        = ntHeaders64.FileHeader;
                    reader.Position  += ntHeaders64.FileHeader.SizeOfOptionalHeader - Marshal.SizeOf <IMAGE_OPTIONAL_HEADER64>();
                    CodeSegmentOffset = ntHeaders64.OptionalHeader.ImageBase;
                }
                else
                {
                    Is64bit           = false;
                    fileHeader        = ntHeaders32.FileHeader;
                    reader.Position  += ntHeaders32.FileHeader.SizeOfOptionalHeader - Marshal.SizeOf <IMAGE_OPTIONAL_HEADER32>();
                    CodeSegmentOffset = ntHeaders32.OptionalHeader.ImageBase;
                }

                // Load image section headers
                uint stringTablePosition = fileHeader.PointerToSymbolTable + fileHeader.NumberOfSymbols * IMAGE_SIZEOF_SYMBOL;

                imageSectionHeaders = new IMAGE_SECTION_HEADER[fileHeader.NumberOfSections];
                for (int section = 0; section < imageSectionHeaders.Length; section++)
                {
                    IMAGE_SECTION_HEADER imageSectionHeader = reader.ReadStructure <IMAGE_SECTION_HEADER>();
                    imageSectionHeaders[section] = imageSectionHeader;
                    string name = imageSectionHeader.Section;
                    if (imageSectionHeader.Name[0] == '/')
                    {
                        uint position = stringTablePosition + uint.Parse(imageSectionHeader.Section.Substring(1));

                        name = reader.ReadString((int)position);
                    }

                    switch (name)
                    {
                    case ".debug_info":
                        DebugData = reader.ReadBlock(imageSectionHeader.SizeInImage, (int)imageSectionHeader.PointerToRawData);
                        break;

                    case ".debug_abbrev":
                        DebugDataDescription = reader.ReadBlock(imageSectionHeader.SizeInImage, (int)imageSectionHeader.PointerToRawData);
                        break;

                    case ".debug_line":
                        DebugLine = reader.ReadBlock(imageSectionHeader.SizeInImage, (int)imageSectionHeader.PointerToRawData);
                        break;

                    case ".debug_frame":
                        DebugFrame = reader.ReadBlock(imageSectionHeader.SizeInImage, (int)imageSectionHeader.PointerToRawData);
                        break;

                    case ".debug_str":
                        DebugDataStrings = reader.ReadBlock(imageSectionHeader.SizeInImage, (int)imageSectionHeader.PointerToRawData);
                        break;

                    case ".eh_frame":
                        EhFrame        = reader.ReadBlock(imageSectionHeader.SizeInImage, (int)imageSectionHeader.PointerToRawData);
                        EhFrameAddress = imageSectionHeader.PointerToRawData + CodeSegmentOffset;
                        break;

                    case ".data":
                        DataSectionAddress = imageSectionHeader.PointerToRawData + CodeSegmentOffset;
                        break;

                    case ".text":
                        TextSectionAddress = imageSectionHeader.PointerToRawData + CodeSegmentOffset;
                        break;
                    }
                }

                // Load image symbols
                List <PublicSymbol> publicSymbols = new List <PublicSymbol>();
                byte toSkip = 0;

                reader.Position = (int)fileHeader.PointerToSymbolTable;
                for (uint i = 0; i < fileHeader.NumberOfSymbols; i++)
                {
                    int          position = reader.Position;
                    IMAGE_SYMBOL symbol   = reader.ReadStructure <IMAGE_SYMBOL>();

                    if (toSkip == 0)
                    {
                        string name = symbol.SymbolName;

                        if (string.IsNullOrEmpty(name))
                        {
                            int stringPosition = (int)reader.ReadUint(position);
                            stringPosition = (int)reader.ReadUint(position + 4);

                            name = reader.ReadString((int)stringTablePosition + stringPosition);
                        }


                        if (symbol.SectionNumber > 0 && symbol.SectionNumber <= imageSectionHeaders.Length)
                        {
                            uint sectionAddress = imageSectionHeaders[symbol.SectionNumber - 1].VirtualAddress;
                            sectionAddress += symbol.Value;

                            publicSymbols.Add(new PublicSymbol(name, sectionAddress));
                        }

                        toSkip = symbol.NumberOfAuxSymbols;
                    }
                    else
                    {
                        toSkip--;
                    }
                }
                PublicSymbols = publicSymbols;
            }
        }
Пример #29
0
        public IntPtr GetRemoteProcAddress(IntPtr ptrHandle, IntPtr hBaseAddress, string sProcName)
        {
            IMAGE_DOS_HEADER32 dosHeader = new IMAGE_DOS_HEADER32();

            uint uiSignature = 0;
            IMAGE_FILE_HEADER       fileHeader      = new IMAGE_FILE_HEADER();
            IMAGE_OPTIONAL_HEADER32 optHeader32     = new IMAGE_OPTIONAL_HEADER32();
            IMAGE_DATA_DIRECTORY    exportDirectory = new IMAGE_DATA_DIRECTORY();
            IMAGE_EXPORT_DIRECTORY  exportTable     = new IMAGE_EXPORT_DIRECTORY();

            IntPtr ptrFunctionTable = IntPtr.Zero;
            IntPtr ptrNameTable     = IntPtr.Zero;
            IntPtr ptrOrdinalTable  = IntPtr.Zero;

            if (ptrHandle == IntPtr.Zero || hBaseAddress == IntPtr.Zero)
            {
                WriteError("Invalid call.");
                return(IntPtr.Zero);
            }

            IntPtr ptrNumBytesRead = IntPtr.Zero;

            if (!ReadProcessMemory(ptrHandle, hBaseAddress,
                                   &dosHeader, Marshal.SizeOf(dosHeader), out ptrNumBytesRead))
            {
                WriteError("Failed. Error code: " + Marshal.GetLastWin32Error().ToString());
                return(IntPtr.Zero);
            }

            if (dosHeader.e_magic != 0x5A4D)
            {
                WriteError("Image is not a valid DLL. " + dosHeader.e_magic.ToString());
                return(IntPtr.Zero);
            }

            if (!ReadProcessMemory(ptrHandle, hBaseAddress + (dosHeader.e_lfanew),
                                   &uiSignature, Marshal.SizeOf(uiSignature), out ptrNumBytesRead))
            {
                WriteError("Failed. Error code: " + Marshal.GetLastWin32Error().ToString());
                return(IntPtr.Zero);
            }

            if (uiSignature != 0x4550)
            {
                WriteError("Invalid NT signature...");
                return(IntPtr.Zero);
            }

            if (!ReadProcessMemory(ptrHandle, hBaseAddress + (dosHeader.e_lfanew + Marshal.SizeOf(uiSignature)),
                                   &fileHeader, Marshal.SizeOf(fileHeader), out ptrNumBytesRead))
            {
                WriteError("Failed. Error code: " + Marshal.GetLastWin32Error().ToString());
                return(IntPtr.Zero);
            }

            if (!ReadProcessMemory(ptrHandle, hBaseAddress + (dosHeader.e_lfanew + Marshal.SizeOf(uiSignature) + Marshal.SizeOf(fileHeader)),
                                   &optHeader32, Marshal.SizeOf(optHeader32), out ptrNumBytesRead))
            {
                WriteError("Failed. Error code: " + Marshal.GetLastWin32Error().ToString());
                return(IntPtr.Zero);
            }

            if (optHeader32.NumberOfRvaAndSizes >= 1)
            {
                exportDirectory.VirtualAddress =
                    (optHeader32.ExportTable.VirtualAddress);
                exportDirectory.Size = (optHeader32.ExportTable.Size);
            }
            else
            {
                WriteError("No export table found.");
                return(IntPtr.Zero);
            }

            if (!ReadProcessMemory(ptrHandle, hBaseAddress + (int)(exportDirectory.VirtualAddress),
                                   &exportTable, Marshal.SizeOf(exportTable), out ptrNumBytesRead))
            {
                WriteError("Failed. Error code: " + Marshal.GetLastWin32Error().ToString());
                return(IntPtr.Zero);
            }

            uint[]  uiExportFuncTable    = ReadUIntArray(ptrHandle, hBaseAddress + (int)(exportTable.AddressOfFunctions), (int)exportTable.NumberOfFunctions);
            uint[]  uiExportNameTable    = ReadUIntArray(ptrHandle, hBaseAddress + (int)(exportTable.AddressOfNames), (int)exportTable.NumberOfNames);
            short[] usExportOrdinalTable = ReadShortArray(ptrHandle, hBaseAddress + (int)(exportTable.AddressOfNameOrdinals), (int)exportTable.NumberOfNames);

            for (int i = 0; i < exportTable.NumberOfNames; i++)
            {
                if (ReadString(ptrHandle, hBaseAddress + (int)(uiExportNameTable[i])) == sProcName)
                {
                    return(new IntPtr((int)hBaseAddress + uiExportFuncTable[usExportOrdinalTable[i]]));
                }
            }

            WriteError("Unable to find the provided procedure name!");
            return(IntPtr.Zero);
        }
Пример #30
0
        private void parsePEbytes(string sBytes)
        {
            byte[] bytes = Encoding.Default.GetBytes(sBytes);

            List <string> results = new List <string>();

            // IMAGE_DOS_HEADER
            IMAGE_DOS_HEADER dosHeader = BytesToStructure <IMAGE_DOS_HEADER>(bytes);

            results.Add("IMAGE_DOS_HEADER.e_magic;" + dosHeader.e_magic + ";0x" + dosHeader.e_magic.ToString("x") + ";Magic number");
            results.Add("IMAGE_DOS_HEADER.e_cblp;" + dosHeader.e_cblp + ";;Bytes on last page of file");
            results.Add("IMAGE_DOS_HEADER.e_cp;" + dosHeader.e_cp + ";;Relocations");
            results.Add("IMAGE_DOS_HEADER.e_crlc;" + dosHeader.e_crlc + ";;Bytes on last page of file");
            results.Add("IMAGE_DOS_HEADER.e_cparhdr;" + dosHeader.e_cparhdr + ";;Size of header in paragraphs");
            results.Add("IMAGE_DOS_HEADER.e_minalloc;" + dosHeader.e_minalloc + ";;Minimum extra paragraphs needed");
            results.Add("IMAGE_DOS_HEADER.e_maxalloc;" + dosHeader.e_maxalloc + ";;Maximum extra paragraphs needed");
            results.Add("IMAGE_DOS_HEADER.e_ss;" + dosHeader.e_ss + ";;Initial (relative) SS value");
            results.Add("IMAGE_DOS_HEADER.e_sp;" + dosHeader.e_sp + ";;Initial SP value");
            results.Add("IMAGE_DOS_HEADER.e_csum;" + dosHeader.e_csum + ";;Checksum");
            results.Add("IMAGE_DOS_HEADER.e_ip;" + dosHeader.e_ip + ";;Initial IP value");
            results.Add("IMAGE_DOS_HEADER.e_cs;" + dosHeader.e_cs + ";;Initial (relative) CS value");
            results.Add("IMAGE_DOS_HEADER.e_lfarlc;" + dosHeader.e_lfarlc + ";;File address of relocation table");
            results.Add("IMAGE_DOS_HEADER.e_ovno;" + dosHeader.e_ovno + ";;Overlay number");
            results.Add("IMAGE_DOS_HEADER.e_res_0;" + dosHeader.e_res_0 + ";;Reserved words");
            results.Add("IMAGE_DOS_HEADER.e_res_1;" + dosHeader.e_res_1 + ";;Reserved words");
            results.Add("IMAGE_DOS_HEADER.e_res_2;" + dosHeader.e_res_2 + ";;Reserved words");
            results.Add("IMAGE_DOS_HEADER.e_res_3;" + dosHeader.e_res_3 + ";;Reserved words");
            results.Add("IMAGE_DOS_HEADER.e_oemid;" + dosHeader.e_oemid + ";;OEM identifier (for e_oeminfo)");
            results.Add("IMAGE_DOS_HEADER.e_oeminfo;" + dosHeader.e_oeminfo + ";;OEM information (e_oemid specific)");
            results.Add("IMAGE_DOS_HEADER.e_res2_0;" + dosHeader.e_res2_0 + ";;Reserved words");
            results.Add("IMAGE_DOS_HEADER.e_res2_1;" + dosHeader.e_res2_1 + ";;Reserved words");
            results.Add("IMAGE_DOS_HEADER.e_res2_2;" + dosHeader.e_res2_2 + ";;Reserved words");
            results.Add("IMAGE_DOS_HEADER.e_res2_3;" + dosHeader.e_res2_3 + ";;Reserved words");
            results.Add("IMAGE_DOS_HEADER.e_res2_4;" + dosHeader.e_res2_4 + ";;Reserved words");
            results.Add("IMAGE_DOS_HEADER.e_res2_5;" + dosHeader.e_res2_5 + ";;Reserved words");
            results.Add("IMAGE_DOS_HEADER.e_res2_6;" + dosHeader.e_res2_6 + ";;Reserved words");
            results.Add("IMAGE_DOS_HEADER.e_res2_7;" + dosHeader.e_res2_7 + ";;Reserved words");
            results.Add("IMAGE_DOS_HEADER.e_res2_8;" + dosHeader.e_res2_8 + ";;Reserved words");
            results.Add("IMAGE_DOS_HEADER.e_res2_9;" + dosHeader.e_res2_9 + ";;Reserved words");
            results.Add("IMAGE_DOS_HEADER.e_lfanew;" + dosHeader.e_lfanew + ";;File address of new exe header");

            // IMAGE_FILE_HEADER
            IMAGE_FILE_HEADER fileHeader = BytesToStructure <IMAGE_FILE_HEADER>(bytes.Skip((int)dosHeader.e_lfanew + 4).ToArray());

            results.Add("IMAGE_FILE_HEADER.Machine;" + fileHeader.Machine + ";0x" + fileHeader.Machine.ToString("x"));
            results.Add("IMAGE_FILE_HEADER.NumberOfSections;" + fileHeader.NumberOfSections);
            results.Add("IMAGE_FILE_HEADER.TimeDateStamp;" + fileHeader.TimeDateStamp);
            results.Add("IMAGE_FILE_HEADER.PointerToSymbolTable;" + fileHeader.PointerToSymbolTable);
            results.Add("IMAGE_FILE_HEADER.NumberOfSymbols;" + fileHeader.NumberOfSymbols);
            results.Add("IMAGE_FILE_HEADER.SizeOfOptionalHeader;" + fileHeader.SizeOfOptionalHeader);
            results.Add("IMAGE_FILE_HEADER.Characteristics;" + fileHeader.Characteristics + ";0x" + fileHeader.Characteristics.ToString("x"));

            bool   Is32BitHeader = fileHeader.Machine != 0 && fileHeader.Machine != 0x8664;
            UInt64 ImageBase     = 0;
            // IMAGE_OPTIONAL_HEADER
            IMAGE_OPTIONAL_HEADER32 optionalHeader32;
            IMAGE_OPTIONAL_HEADER64 optionalHeader64;

            IMAGE_DATA_DIRECTORIES[] dataDirectories = new IMAGE_DATA_DIRECTORIES[16];
            long offset = dosHeader.e_lfanew + 4 + Marshal.SizeOf(typeof(IMAGE_FILE_HEADER));

            if (Is32BitHeader)
            {
                optionalHeader32 = BytesToStructure <IMAGE_OPTIONAL_HEADER32>(bytes.Skip((int)offset).ToArray());
                offset          += Marshal.SizeOf(typeof(IMAGE_OPTIONAL_HEADER32));

                ImageBase = optionalHeader32.ImageBase;

                results.Add("IMAGE_OPTIONAL_HEADER32.Magic;" + optionalHeader32.Magic);
                results.Add("IMAGE_OPTIONAL_HEADER32.MajorLinkerVersion;" + optionalHeader32.MajorLinkerVersion);
                results.Add("IMAGE_OPTIONAL_HEADER32.MinorLinkerVersion;" + optionalHeader32.MinorLinkerVersion);
                results.Add("IMAGE_OPTIONAL_HEADER32.SizeOfCode;" + optionalHeader32.SizeOfCode);
                results.Add("IMAGE_OPTIONAL_HEADER32.SizeOfInitializedData;" + optionalHeader32.SizeOfInitializedData);
                results.Add("IMAGE_OPTIONAL_HEADER32.SizeOfUninitializedData;" + optionalHeader32.SizeOfUninitializedData);
                results.Add(string.Format("IMAGE_OPTIONAL_HEADER32.AddressOfEntryPoint;{0};0x{1:x}", optionalHeader32.AddressOfEntryPoint, optionalHeader32.AddressOfEntryPoint.ToString("x")));
                results.Add("IMAGE_OPTIONAL_HEADER32.BaseOfCode;" + optionalHeader32.BaseOfCode);
                results.Add("IMAGE_OPTIONAL_HEADER32.BaseOfData;" + optionalHeader32.BaseOfData);
                results.Add("IMAGE_OPTIONAL_HEADER32.ImageBase;" + optionalHeader32.ImageBase + ";0x" + optionalHeader32.ImageBase.ToString("x"));
                results.Add("IMAGE_OPTIONAL_HEADER32.SectionAlignment;" + optionalHeader32.SectionAlignment);
                results.Add("IMAGE_OPTIONAL_HEADER32.FileAlignment;" + optionalHeader32.FileAlignment);
                results.Add("IMAGE_OPTIONAL_HEADER32.MajorOperatingSystemVersion;" + optionalHeader32.MajorOperatingSystemVersion);
                results.Add("IMAGE_OPTIONAL_HEADER32.MinorOperatingSystemVersion;" + optionalHeader32.MinorOperatingSystemVersion);
                results.Add("IMAGE_OPTIONAL_HEADER32.MajorImageVersion;" + optionalHeader32.MajorImageVersion);
                results.Add("IMAGE_OPTIONAL_HEADER32.MinorImageVersion;" + optionalHeader32.MinorImageVersion);
                results.Add("IMAGE_OPTIONAL_HEADER32.MajorSubsystemVersion;" + optionalHeader32.MajorSubsystemVersion);
                results.Add("IMAGE_OPTIONAL_HEADER32.MinorSubsystemVersion;" + optionalHeader32.MinorSubsystemVersion);
                results.Add("IMAGE_OPTIONAL_HEADER32.Win32VersionValue;" + optionalHeader32.Win32VersionValue);
                results.Add("IMAGE_OPTIONAL_HEADER32.SizeOfImage;" + optionalHeader32.SizeOfImage);
                results.Add("IMAGE_OPTIONAL_HEADER32.SizeOfHeaders;" + optionalHeader32.SizeOfHeaders);
                results.Add("IMAGE_OPTIONAL_HEADER32.CheckSum;" + optionalHeader32.CheckSum);
                results.Add("IMAGE_OPTIONAL_HEADER32.Subsystem;" + optionalHeader32.Subsystem);
                results.Add("IMAGE_OPTIONAL_HEADER32.DllCharacteristics;" + optionalHeader32.DllCharacteristics);
                results.Add("IMAGE_OPTIONAL_HEADER32.SizeOfStackReserve;" + optionalHeader32.SizeOfStackReserve);
                results.Add("IMAGE_OPTIONAL_HEADER32.SizeOfStackCommit;" + optionalHeader32.SizeOfStackCommit);
                results.Add("IMAGE_OPTIONAL_HEADER32.SizeOfHeapReserve;" + optionalHeader32.SizeOfHeapReserve);
                results.Add("IMAGE_OPTIONAL_HEADER32.SizeOfHeapCommit;" + optionalHeader32.SizeOfHeapCommit);
                results.Add("IMAGE_OPTIONAL_HEADER32.LoaderFlags;" + optionalHeader32.LoaderFlags);
                results.Add("IMAGE_OPTIONAL_HEADER32.NumberOfRvaAndSizes;" + optionalHeader32.NumberOfRvaAndSizes);
            }
            else
            {
                optionalHeader64 = BytesToStructure <IMAGE_OPTIONAL_HEADER64>(bytes.Skip((int)offset).ToArray());
                offset          += Marshal.SizeOf(typeof(IMAGE_OPTIONAL_HEADER64));

                ImageBase = optionalHeader64.ImageBase;

                results.Add("IMAGE_OPTIONAL_HEADER64.Magic;" + optionalHeader64.Magic);
                results.Add("IMAGE_OPTIONAL_HEADER64.MajorLinkerVersion;" + optionalHeader64.MajorLinkerVersion);
                results.Add("IMAGE_OPTIONAL_HEADER64.MinorLinkerVersion;" + optionalHeader64.MinorLinkerVersion);
                results.Add("IMAGE_OPTIONAL_HEADER64.SizeOfCode;" + optionalHeader64.SizeOfCode);
                results.Add("IMAGE_OPTIONAL_HEADER64.SizeOfInitializedData;" + optionalHeader64.SizeOfInitializedData);
                results.Add("IMAGE_OPTIONAL_HEADER64.SizeOfUninitializedData;" + optionalHeader64.SizeOfUninitializedData);
                results.Add("IMAGE_OPTIONAL_HEADER64.AddressOfEntryPoint;" + (optionalHeader64.ImageBase + optionalHeader64.AddressOfEntryPoint) + ";0x" + (optionalHeader64.ImageBase + optionalHeader64.AddressOfEntryPoint).ToString("x"));
                results.Add("IMAGE_OPTIONAL_HEADER64.BaseOfCode;" + optionalHeader64.BaseOfCode);
                results.Add("IMAGE_OPTIONAL_HEADER64.ImageBase;" + optionalHeader64.ImageBase + ";0x" + optionalHeader64.ImageBase.ToString("x"));
                results.Add("IMAGE_OPTIONAL_HEADER64.SectionAlignment;" + optionalHeader64.SectionAlignment);
                results.Add("IMAGE_OPTIONAL_HEADER64.FileAlignment;" + optionalHeader64.FileAlignment);
                results.Add("IMAGE_OPTIONAL_HEADER64.MajorOperatingSystemVersion;" + optionalHeader64.MajorOperatingSystemVersion);
                results.Add("IMAGE_OPTIONAL_HEADER64.MinorOperatingSystemVersion;" + optionalHeader64.MinorOperatingSystemVersion);
                results.Add("IMAGE_OPTIONAL_HEADER64.MajorImageVersion;" + optionalHeader64.MajorImageVersion);
                results.Add("IMAGE_OPTIONAL_HEADER64.MinorImageVersion;" + optionalHeader64.MinorImageVersion);
                results.Add("IMAGE_OPTIONAL_HEADER64.MajorSubsystemVersion;" + optionalHeader64.MajorSubsystemVersion);
                results.Add("IMAGE_OPTIONAL_HEADER64.MinorSubsystemVersion;" + optionalHeader64.MinorSubsystemVersion);
                results.Add("IMAGE_OPTIONAL_HEADER64.Win32VersionValue;" + optionalHeader64.Win32VersionValue);
                results.Add("IMAGE_OPTIONAL_HEADER64.SizeOfImage;" + optionalHeader64.SizeOfImage);
                results.Add("IMAGE_OPTIONAL_HEADER64.SizeOfHeaders;" + optionalHeader64.SizeOfHeaders);
                results.Add("IMAGE_OPTIONAL_HEADER64.CheckSum;" + optionalHeader64.CheckSum);
                results.Add("IMAGE_OPTIONAL_HEADER64.Subsystem;" + optionalHeader64.Subsystem);
                results.Add("IMAGE_OPTIONAL_HEADER64.DllCharacteristics;" + optionalHeader64.DllCharacteristics);
                results.Add("IMAGE_OPTIONAL_HEADER64.SizeOfStackReserve;" + optionalHeader64.SizeOfStackReserve);
                results.Add("IMAGE_OPTIONAL_HEADER64.SizeOfStackCommit;" + optionalHeader64.SizeOfStackCommit);
                results.Add("IMAGE_OPTIONAL_HEADER64.SizeOfHeapReserve;" + optionalHeader64.SizeOfHeapReserve);
                results.Add("IMAGE_OPTIONAL_HEADER64.SizeOfHeapCommit;" + optionalHeader64.SizeOfHeapCommit);
                results.Add("IMAGE_OPTIONAL_HEADER64.LoaderFlags;" + optionalHeader64.LoaderFlags);
                results.Add("IMAGE_OPTIONAL_HEADER64.NumberOfRvaAndSizes;" + optionalHeader64.NumberOfRvaAndSizes);
            }

            // IMAGE_DATA_DIRECTORIES
            for (int i = 0; i < 16; i++)
            {
                long dd_offset = offset + i * Marshal.SizeOf(typeof(IMAGE_DATA_DIRECTORIES));
                dataDirectories[i] = BytesToStructure <IMAGE_DATA_DIRECTORIES>(bytes.Skip((int)dd_offset).ToArray());
            }

            for (int i = 0; i < 16; i++)
            {
                if (dataDirectories[i].VirtualAddress == 0 && dataDirectories[i].Size == 0)
                {
                    continue;
                }
                results.Add("IMAGE_DATA_DIRECTORIES[" + i + "].VirtualAddress;" + dataDirectories[i].VirtualAddress + ";0x" + dataDirectories[i].VirtualAddress.ToString("x") + ";" + ((Dir)i).ToString());
                results.Add("IMAGE_DATA_DIRECTORIES[" + i + "].Size;" + dataDirectories[i].Size);
            }

            //number of sections
            int ns = Math.Min((int)fileHeader.NumberOfSections, 32);

            //IMAGE_SECTION_HEADER
            offset += 16 * Marshal.SizeOf(typeof(IMAGE_DATA_DIRECTORIES));
            IMAGE_SECTION_HEADER[] sectHeaders = new IMAGE_SECTION_HEADER[ns];
            for (int i = 0; i < ns; i++)
            {
                long dd_offset = offset + i * Marshal.SizeOf(typeof(IMAGE_SECTION_HEADER));
                sectHeaders[i] = BytesToStructure <IMAGE_SECTION_HEADER>(bytes.Skip((int)dd_offset).ToArray());
            }

            results.Add("IMAGE_SECTION_HEADER.Columns;Name;VirtualSize;VirtualAddress;VirtualAddress;SizeOfRawData;PointerToRawData;PointerToRawData;PointerToRelocations;PointerToLinenumbers;NumberOfRelocations;NumberOfLinenumbers;Characteristics_dec;Characteristics_hex;Characteristics");
            for (int i = 0; sectHeaders != null && i < ns; i++)
            {
                String        sectName = sectHeaders[i].Name.ToString("X");
                StringBuilder secname  = new StringBuilder(8);
                for (int x = sectName.Length - 2; x >= 0; x -= 2)
                {
                    int value = Convert.ToInt32(sectName.Substring(x, 2), 16);
                    if (value > 0)
                    {
                        secname.Append(Char.ConvertFromUtf32(value));
                    }
                }
                results.Add("IMAGE_SECTION_HEADER[" + i + "];" + secname + ";" +
                            sectHeaders[i].VirtualSize + ";" +
                            (ImageBase + sectHeaders[i].VirtualAddress) + ";" +
                            "0x" + (ImageBase + sectHeaders[i].VirtualAddress).ToString("x") + ";" +
                            sectHeaders[i].SizeOfRawData + ";" +
                            sectHeaders[i].PointerToRawData + ";" +
                            "0x" + sectHeaders[i].PointerToRawData.ToString("x") + ";" +
                            sectHeaders[i].PointerToRelocations + ";" +
                            sectHeaders[i].PointerToLinenumbers + ";" +
                            sectHeaders[i].NumberOfRelocations + ";" +
                            sectHeaders[i].NumberOfLinenumbers + ";" +
                            sectHeaders[i].Characteristics + ";" +
                            "0x" + sectHeaders[i].Characteristics.ToString("x") + ";" +
                            "characteristics");
            }

            offset = sectHeaders[(int)Dir.Resource].PointerToRawData;

            RESOURCE_DIRECTORY ResourceDir = BytesToStructure <RESOURCE_DIRECTORY>(bytes.Skip((int)offset).ToArray());

            results.Add("RESOURCE_DIR_ROOT.Characteristics;" + ResourceDir.Characteristics);
            results.Add("RESOURCE_DIR_ROOT.TimeDateStamp;" + ResourceDir.TimeDateStamp);
            results.Add("RESOURCE_DIR_ROOT.MajorVersion;" + ResourceDir.MajorVersion);
            results.Add("RESOURCE_DIR_ROOT.MinorVersion;" + ResourceDir.MinorVersion);
            results.Add("RESOURCE_DIR_ROOT.NumberOfNamedEntries;" + ResourceDir.NumberOfNamedEntries);
            results.Add("RESOURCE_DIR_ROOT.NumberOfldEntries;" + ResourceDir.NumberOfldEntries);

            offset += Marshal.SizeOf(typeof(RESOURCE_DIRECTORY_ENTRY)) + 8;
            // RESOURCE_DIRECTORY_ENTRY
            List <RESOURCE_DIRECTORY_ENTRY> res_entries = new List <RESOURCE_DIRECTORY_ENTRY>();
            RESOURCE_DIRECTORY_ENTRY        res_ent;

            for (int ie = 0; ie < ResourceDir.NumberOfNamedEntries + ResourceDir.NumberOfldEntries; ie++)
            {
                // read resource entries
                long dd_offset = offset + ie * Marshal.SizeOf(typeof(RESOURCE_DIRECTORY_ENTRY));
                res_ent = BytesToStructure <RESOURCE_DIRECTORY_ENTRY>(bytes.Skip((int)dd_offset).ToArray());
                res_entries.Add(res_ent);
                // TODO
                //long name_offset = sectHeaders[(int)Dir.Resource].PointerToRawData + (res_ent.Name); //resname
                //string name=string.Concat(bytes.Skip((int)name_offset).Take(32).Where(b => b > 0).Select(c => (char)c));
            }

            for (int i = 0; i < res_entries.Count; i++)
            {
                //string resname = res_entry_names[i].Length > 0 ? res_entry_names[i] : resType(res_entries[i].Name);
                results.Add("RESOURCE_ENTRY[" + i + "];" +
                            res_entries[i].Name // + ";" +
                                                //"name"

                                                /*res_entries[i].OffsetToData + ";" +
                                                 * res_dirs[i].Characteristics + ";" +
                                                 * res_dirs[i].TimeDateStamp + ";" +
                                                 * res_dirs[i].MajorVersion + ";" +
                                                 * res_dirs[i].MinorVersion + ";" +
                                                 * res_dirs[i].NumberOfNamedEntries + ";" +
                                                 * res_dirs[i].NumberOfldEntries*/
                            );
            }
            // finaly
            ConsoleWrite_Atom(string.Join("\n", results));
        }
Пример #31
0
        /// <summary>
        /// Process a PE executable header
        /// </summary>
        private ExecutableType ProcessPe(ref bool searchAgainAtEnd)
        {
            inputFile.Seek(dataBase + currentFormat.ExecutableOffset + 4);
            IMAGE_FILE_HEADER     ifh = IMAGE_FILE_HEADER.Deserialize(inputFile);
            IMAGE_OPTIONAL_HEADER ioh = IMAGE_OPTIONAL_HEADER.Deserialize(inputFile);

            // Read sections until we have the ones we need
            IMAGE_SECTION_HEADER temp     = null;
            IMAGE_SECTION_HEADER resource = null;

            for (int i = 0; i < ifh.NumberOfSections; i++)
            {
                IMAGE_SECTION_HEADER sectionHeader = IMAGE_SECTION_HEADER.Deserialize(inputFile);
                string headerName = Encoding.ASCII.GetString(sectionHeader.Name, 0, 8);

                // .text
                if (headerName.StartsWith(".text"))
                {
                    currentFormat.CodeSectionLength = sectionHeader.VirtualSize;
                }

                // .rdata
                else if (headerName.StartsWith(".rdata"))
                {
                    // No-op
                }

                // .data
                else if (headerName.StartsWith(".data"))
                {
                    currentFormat.DataSectionLength = sectionHeader.VirtualSize;
                    if ((ifh.Characteristics & (1 << 0)) == 0)
                    {
                        temp = sectionHeader;
                    }
                }

                // .rsrc
                else if (headerName.StartsWith(".rsrc"))
                {
                    resource = sectionHeader;
                    if ((ifh.Characteristics & (1 << 0)) != 0)
                    {
                        temp = sectionHeader;
                    }
                }
            }

            // the unpacker of the self-extractor does not use any resource functions either.
            if (temp.SizeOfRawData > 20000)
            {
                for (int f = 0; f <= 20000 - 0x80; f++)
                {
                    inputFile.Seek(dataBase + temp.PointerToRawData + f);
                    IMAGE_DOS_HEADER exeHdr = IMAGE_DOS_HEADER.Deserialize(inputFile);

                    if ((exeHdr.Magic == Constants.IMAGE_NT_SIGNATURE || exeHdr.Magic == Constants.IMAGE_DOS_SIGNATURE) &&
                        exeHdr.HeaderParagraphSize >= 4 &&
                        exeHdr.NewExeHeaderAddr >= 0x40 &&
                        (exeHdr.Relocations == 0 || exeHdr.Relocations == 3))
                    {
                        currentFormat.ExecutableOffset = (int)temp.PointerToRawData + f;
                        fileEnd          = (int)(dataBase + temp.PointerToRawData + ioh.DataDirectory[2].Size);
                        searchAgainAtEnd = true;
                        break;
                    }
                }
            }

            currentFormat.ExecutableOffset = (int)(resource.PointerToRawData + resource.SizeOfRawData);
            return(ExecutableType.PE);
        }