Example #1
0
        /// <summary>
        /// PE Constructor
        /// </summary>
        /// <param name="PEBytes">PE raw bytes.</param>
        public PEOld(byte[] PEBytes)
        {
            // Read in the DLL or EXE and get the timestamp
            using (MemoryStream stream = new MemoryStream(PEBytes, 0, PEBytes.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);
                }
                this.PEBytes = PEBytes;
            }
        }
Example #2
0
        public bool IsRecognizedFormat(Stream stream)
        {
            stream.Position = 0;
            try
            {
                // Has a valid MS-DOS header?
                IMAGE_DOS_HEADER dos_header = new IMAGE_DOS_HEADER(stream);
                if (dos_header.e_magic != (int)HeaderSignatures.IMAGE_DOS_SIGNATURE)  //MZ
                {
                    return(false);
                }

                //Lets position over the "PE" header
                stream.Seek(dos_header.e_lfanew, SeekOrigin.Begin);

                //Lets read the NE header
                IMAGE_NT_HEADERS nt_header = new IMAGE_NT_HEADERS(stream);
                if (nt_header.Signature != (int)HeaderSignatures.IMAGE_NT_SIGNATURE)  //PE
                {
                    return(false);
                }

                return(true);
            }
            catch (Exception) {}
            return(false);
        }
Example #3
0
        public static IntPtr GetBaseAddress(IntPtr hProcess)
        {
            SYSTEM_INFO system_info;

            GetSystemInfo(out system_info);
            IntPtr lpMinimumApplicationAddress = system_info.lpMinimumApplicationAddress;
            MEMORY_BASIC_INFORMATION structure = new MEMORY_BASIC_INFORMATION();
            uint dwLength = (uint)Marshal.SizeOf(structure);

            while (lpMinimumApplicationAddress.ToInt64() < system_info.lpMaximumApplicationAddress.ToInt64())
            {
                if (!VirtualQueryEx(hProcess, lpMinimumApplicationAddress, out structure, dwLength))
                {
                    Console.WriteLine("Could not VirtualQueryEx {0} segment at {1}; error {2}", hProcess.ToInt64(), lpMinimumApplicationAddress.ToInt64(), Marshal.GetLastWin32Error());
                    return(IntPtr.Zero);
                }
                if (((structure.Type == 0x1000000) && (structure.BaseAddress == structure.AllocationBase)) && ((structure.Protect & 0x100) != 0x100))
                {
                    IMAGE_DOS_HEADER image_dos_header = ReadUnmanagedStructure <IMAGE_DOS_HEADER>(hProcess, lpMinimumApplicationAddress);
                    if (image_dos_header.e_magic == 0x5a4d)
                    {
                        IntPtr lpAddr = new IntPtr(lpMinimumApplicationAddress.ToInt64() + (image_dos_header.e_lfanew + 4));
                        if ((ReadUnmanagedStructure <IMAGE_FILE_HEADER>(hProcess, lpAddr).Characteristics & 2) == 2)
                        {
                            return(lpMinimumApplicationAddress);
                        }
                    }
                }
                long introduced7 = structure.BaseAddress.ToInt64();
                lpMinimumApplicationAddress = new IntPtr(introduced7 + structure.RegionSize.ToInt64());
            }
            return(lpMinimumApplicationAddress);
        }
Example #4
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());
        }
        }                                                           // 3C File address of new exe header

        public static IMAGE_DOS_HEADER Deserialize(MultiPartFile file)
        {
            IMAGE_DOS_HEADER idh = new IMAGE_DOS_HEADER();

            idh.Magic                  = file.ReadUInt16();
            idh.LastPageBytes          = file.ReadUInt16();
            idh.Pages                  = file.ReadUInt16();
            idh.Relocations            = file.ReadUInt16();
            idh.HeaderParagraphSize    = file.ReadUInt16();
            idh.MinimumExtraParagraphs = file.ReadUInt16();
            idh.MaximumExtraParagraphs = file.ReadUInt16();
            idh.InitialSSValue         = file.ReadUInt16();
            idh.InitialSPValue         = file.ReadUInt16();
            idh.Checksum               = file.ReadUInt16();
            idh.InitialIPValue         = file.ReadUInt16();
            idh.InitialCSValue         = file.ReadUInt16();
            idh.RelocationTableAddr    = file.ReadUInt16();
            idh.OverlayNumber          = file.ReadUInt16();
            idh.Reserved1              = new ushort[Constants.ERES1WDS];
            for (int i = 0; i < Constants.ERES1WDS; i++)
            {
                idh.Reserved1[i] = file.ReadUInt16();
            }
            idh.OEMIdentifier  = file.ReadUInt16();
            idh.OEMInformation = file.ReadUInt16();
            idh.Reserved2      = new ushort[Constants.ERES2WDS];
            for (int i = 0; i < Constants.ERES2WDS; i++)
            {
                idh.Reserved2[i] = file.ReadUInt16();
            }
            idh.NewExeHeaderAddr = file.ReadInt32();

            return(idh);
        }
Example #6
0
 public static DOSHeader FromNativeStruct(IMAGE_DOS_HEADER nativeStruct)
 {
     return(new DOSHeader
     {
         e_magic = new string(nativeStruct.e_magic),
         e_cblp = nativeStruct.e_cblp,
         e_cp = nativeStruct.e_cp,
         e_crlc = nativeStruct.e_crlc,
         e_cparhdr = nativeStruct.e_cparhdr,
         e_minalloc = nativeStruct.e_minalloc,
         e_maxalloc = nativeStruct.e_maxalloc,
         e_ss = nativeStruct.e_ss,
         e_sp = nativeStruct.e_sp,
         e_csum = nativeStruct.e_csum,
         e_ip = nativeStruct.e_ip,
         e_cs = nativeStruct.e_cs,
         e_lfarlc = nativeStruct.e_lfarlc,
         e_ovno = nativeStruct.e_ovno,
         e_res1 = nativeStruct.e_res1,
         e_oemid = nativeStruct.e_oemid,
         e_oeminfo = nativeStruct.e_oeminfo,
         e_res2 = nativeStruct.e_res2,
         e_lfanew = nativeStruct.e_lfanew
     });
 }
Example #7
0
        public PeUtility(string filePath)
        {
            // Read in the DLL or EXE and get the timestamp
            Stream = new FileStream(filePath, System.IO.FileMode.Open, System.IO.FileAccess.ReadWrite);

            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);
            MainHeaderOffset = Stream.Position;
            if (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);
            }
        }
Example #8
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);
            }
        }
Example #9
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);

                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;
            }
        }
Example #10
0
        internal DOSHeader(PortableExecutableImage image, IMAGE_DOS_HEADER dosHeader, ulong imageBase)
        {
            _image  = image;
            _header = dosHeader;

            Location = new Location(image, 0, 0, imageBase, Size.ToUInt32(), Size.ToUInt32());
        }
Example #11
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);
            }
        }
    }
Example #12
0
        public static unsafe bool Is64BitDLL(byte[] dllBytes)
        {
            bool     is64Bit   = false;
            GCHandle scHandle  = GCHandle.Alloc(dllBytes, GCHandleType.Pinned);
            IntPtr   scPointer = scHandle.AddrOfPinnedObject();

            IMAGE_DOS_HEADER dosHeader = (IMAGE_DOS_HEADER)Marshal.PtrToStructure(scPointer, typeof(IMAGE_DOS_HEADER));

            IntPtr NtHeadersPtr = (IntPtr)((UInt64)scPointer + (UInt64)dosHeader.e_lfanew);

            var imageNtHeaders64 = (IMAGE_NT_HEADERS64)Marshal.PtrToStructure(NtHeadersPtr, typeof(IMAGE_NT_HEADERS64));
            var imageNtHeaders32 = (IMAGE_NT_HEADERS)Marshal.PtrToStructure(NtHeadersPtr, typeof(IMAGE_NT_HEADERS));

            if (imageNtHeaders64.Signature != 0x00004550)
            {
                throw new ApplicationException("Invalid IMAGE_NT_HEADER signature.");
            }

            if (imageNtHeaders64.OptionalHeader.Magic == MagicType.IMAGE_NT_OPTIONAL_HDR64_MAGIC)
            {
                is64Bit = true;
            }

            scHandle.Free();

            return(is64Bit);
        }
Example #13
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);
            }
        }
Example #14
0
        public static IntPtr GetBaseAddress(IntPtr hProcess)
        {
            SYSTEM_INFO sYSTEM_INFO;

            GetSystemInfo(out sYSTEM_INFO);
            IntPtr lpMinimumApplicationAddress = sYSTEM_INFO.lpMinimumApplicationAddress;
            MEMORY_BASIC_INFORMATION mEMORY_BASIC_INFORMATION = default(MEMORY_BASIC_INFORMATION);
            uint dwLength = (uint)Marshal.SizeOf(mEMORY_BASIC_INFORMATION);

            while (lpMinimumApplicationAddress.ToInt64() < sYSTEM_INFO.lpMaximumApplicationAddress.ToInt64())
            {
                if (!VirtualQueryEx(hProcess, lpMinimumApplicationAddress, out mEMORY_BASIC_INFORMATION, dwLength))
                {
                    Console.WriteLine("Could not VirtualQueryEx {0} segment at {1}; error {2}", hProcess.ToInt64(), lpMinimumApplicationAddress.ToInt64(), Marshal.GetLastWin32Error());
                    return(IntPtr.Zero);
                }
                if (mEMORY_BASIC_INFORMATION.Type == 16777216u && mEMORY_BASIC_INFORMATION.BaseAddress == mEMORY_BASIC_INFORMATION.AllocationBase && (mEMORY_BASIC_INFORMATION.Protect & 256u) != 256u)
                {
                    IMAGE_DOS_HEADER iMAGE_DOS_HEADER = ReadUnmanagedStructure <IMAGE_DOS_HEADER>(hProcess, lpMinimumApplicationAddress);
                    if (iMAGE_DOS_HEADER.e_magic == 23117)
                    {
                        IntPtr lpAddr = new IntPtr(lpMinimumApplicationAddress.ToInt64() + (long)(iMAGE_DOS_HEADER.e_lfanew + 4));
                        if ((ReadUnmanagedStructure <IMAGE_FILE_HEADER>(hProcess, lpAddr).Characteristics & 2) == 2)
                        {
                            return(lpMinimumApplicationAddress);
                        }
                    }
                }
                lpMinimumApplicationAddress = new IntPtr(mEMORY_BASIC_INFORMATION.BaseAddress.ToInt64() + mEMORY_BASIC_INFORMATION.RegionSize.ToInt64());
            }
            return(lpMinimumApplicationAddress);
        }
Example #15
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);
            }
        }
Example #16
0
 private static extern bool ReadProcessMemory(
     IntPtr hProcess,
     IntPtr lpBaseAddress,
     out IMAGE_DOS_HEADER lpBuffer,
     int nSize,
     IntPtr lpNumberOfBytesRead
     );
Example #17
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);
            }
        }
        /* Assume the IAT resides at the top of the .rdata segment -> find offset&size of .rdata and patch the entry in the IAT */
        static bool FallbackImportPatch(string dllName, IntPtr imageBase, IntPtr oldFuncPtr, IntPtr newPtr)
        {
            IMAGE_DOS_HEADER dosHeader   = (IMAGE_DOS_HEADER)Marshal.PtrToStructure(imageBase, typeof(IMAGE_DOS_HEADER));
            int ntHeaderPtr              = imageBase.ToInt32() + dosHeader.e_lfanew;
            IMAGE_NT_HEADERS32 ntHeaders = (IMAGE_NT_HEADERS32)Marshal.PtrToStructure((IntPtr)ntHeaderPtr, typeof(IMAGE_NT_HEADERS32));

            int sectionHeaderPtr = ntHeaderPtr + 248 /* 248 = sizeof(IMAGE_NT_HEADERS32) */;

            for (int i = 0; i < ntHeaders.FileHeader.NumberOfSections; i++)
            {
                IMAGE_SECTION_HEADER sectionHeader = (IMAGE_SECTION_HEADER)Marshal.PtrToStructure((IntPtr)(sectionHeaderPtr), typeof(IMAGE_SECTION_HEADER));

                if (sectionHeader.SectionName.StartsWith(".rdata"))
                {
                    uint startAddr = (uint)imageBase.ToInt32() + sectionHeader.VirtualAddress;
                    for (uint memAddr = startAddr; memAddr < startAddr + sectionHeader.VirtualSize; memAddr += 4)
                    {
                        if (Marshal.ReadIntPtr((IntPtr)memAddr) == oldFuncPtr)
                        {
                            return(WriteProtectedPtr((IntPtr)memAddr, newPtr));
                        }
                    }
                    throw new Exception("reached end of .rdata, func ptr not found");
                }

                sectionHeaderPtr += Marshal.SizeOf(typeof(IMAGE_SECTION_HEADER));
            }
            throw new Exception("read all sections, .rdata not found");
        }
Example #19
0
        // Get function addresses
        private static Boolean GetFunctionAddreses(ref IntPtr VirtualAllocAddr, ref IntPtr CreateThreadAddr, ref IntPtr WaitForSingleObjectAddr)
        {
            // Get 'Kernel32.dll' image base address
            IntPtr                 Kernel32BaseAddr = FindKernel32();
            IMAGE_DOS_HEADER       ImageDosHeader   = (IMAGE_DOS_HEADER)Marshal.PtrToStructure(Kernel32BaseAddr, typeof(IMAGE_DOS_HEADER));
            MagicType              Architecture     = (MagicType)Marshal.ReadInt32((IntPtr)(Kernel32BaseAddr.ToInt64() + ImageDosHeader.e_lfanew + 4 + 20));
            IMAGE_EXPORT_DIRECTORY ImageExportDirectory;

            switch (Architecture)
            {
            case MagicType.IMAGE_NT_OPTIONAL_HDR32_MAGIC:
                IMAGE_OPTIONAL_HEADER32 PEHeader32 = (IMAGE_OPTIONAL_HEADER32)Marshal.PtrToStructure((IntPtr)(Kernel32BaseAddr.ToInt64() + ImageDosHeader.e_lfanew + 4 + 20), typeof(IMAGE_OPTIONAL_HEADER32));
                ImageExportDirectory = (IMAGE_EXPORT_DIRECTORY)Marshal.PtrToStructure((IntPtr)(Kernel32BaseAddr.ToInt64() + (int)PEHeader32.ExportTable.VirtualAddress), typeof(IMAGE_EXPORT_DIRECTORY));
                break;

            case MagicType.IMAGE_NT_OPTIONAL_HDR64_MAGIC:
                IMAGE_OPTIONAL_HEADER64 PEHeader64 = (IMAGE_OPTIONAL_HEADER64)Marshal.PtrToStructure((IntPtr)(Kernel32BaseAddr.ToInt64() + ImageDosHeader.e_lfanew + 4 + 20), typeof(IMAGE_OPTIONAL_HEADER64));
                ImageExportDirectory = (IMAGE_EXPORT_DIRECTORY)Marshal.PtrToStructure((IntPtr)(Kernel32BaseAddr.ToInt64() + (int)PEHeader64.ExportTable.VirtualAddress), typeof(IMAGE_EXPORT_DIRECTORY));
                break;

            default:
                Console.WriteLine("Failed to identify 'kernel32.dll' architecture");
                return(false);
            }
            ;

            // Setup variables for iterating over export table
            int    CurrentFunctionNameAddr;
            String CurrentFunctionName;

            // Iterate over export table
            for (int i = 0; i < ImageExportDirectory.NumberOfNames; i++)
            {
                // Get current function's address (pointer) and name (pointer)
                CurrentFunctionNameAddr = Marshal.ReadInt32((IntPtr)(Kernel32BaseAddr.ToInt64() + (int)ImageExportDirectory.AddressOfNames + (i * 4)));
                CurrentFunctionName     = Marshal.PtrToStringAnsi((IntPtr)(Kernel32BaseAddr.ToInt64() + (int)CurrentFunctionNameAddr));

                // Check to see if it is the required function
                if (CurrentFunctionName.Equals("VirtualAlloc"))
                {
                    VirtualAllocAddr = (IntPtr)(Kernel32BaseAddr.ToInt64() + Marshal.ReadInt32((IntPtr)(Kernel32BaseAddr.ToInt64() + (int)ImageExportDirectory.AddressOfFunctions + (i * 4))));
                }
                else if (CurrentFunctionName.Equals("CreateThread"))
                {
                    CreateThreadAddr = (IntPtr)(Kernel32BaseAddr.ToInt64() + Marshal.ReadInt32((IntPtr)(Kernel32BaseAddr.ToInt64() + (int)ImageExportDirectory.AddressOfFunctions + (i * 4))));
                }
                else if (CurrentFunctionName.Equals("WaitForSingleObject"))
                {
                    WaitForSingleObjectAddr = (IntPtr)(Kernel32BaseAddr.ToInt64() + Marshal.ReadInt32((IntPtr)(Kernel32BaseAddr.ToInt64() + (int)ImageExportDirectory.AddressOfFunctions + (i * 4))));
                }

                // Return if all functions have been found
                if ((VirtualAllocAddr != IntPtr.Zero) && (CreateThreadAddr != IntPtr.Zero) && (WaitForSingleObjectAddr != IntPtr.Zero))
                {
                    return(true);
                }
            }
            return(false);
        }
Example #20
0
 public PE32File(IMAGE_DOS_HEADER dosHeader, IMAGE_NT_HEADERS32 peHeader, byte[] dosStub)
 {
     Type      = PEType.PE32;
     DOSHeader = DOSHeader.FromNativeStruct(dosHeader);
     PEHeader  = PE32Header.FromNativeStruct(peHeader);
     Sections  = new PESection[peHeader.FileHeader.NumberOfSections];
     DOS_Stub  = dosStub;
 }
Example #21
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;
 }
Example #22
0
        public static int Run(byte[] file, string cmd, string location)
        {
            GCHandle gHandle = GCHandle.Alloc(file, GCHandleType.Pinned);
            int      iPointer;
            uint     outtt;
            UIntPtr  outt;

            iPointer = gHandle.AddrOfPinnedObject().ToInt32();
            CONTEXT              CTX     = new CONTEXT();
            IMAGE_DOS_HEADER     DHD     = new IMAGE_DOS_HEADER();
            IMAGE_NT_HEADERS     NHD     = new IMAGE_NT_HEADERS();
            IMAGE_SECTION_HEADER SHD     = default(IMAGE_SECTION_HEADER);
            PROCESS_INFORMATION  procinf = new PROCESS_INFORMATION();

            DHD = (IMAGE_DOS_HEADER)Marshal.PtrToStructure(new IntPtr(iPointer), typeof(IMAGE_DOS_HEADER));
            NHD = (IMAGE_NT_HEADERS)Marshal.PtrToStructure(new IntPtr(iPointer + DHD.e_lfanew), typeof(IMAGE_NT_HEADERS));
            CreateProcess(location, cmd, IntPtr.Zero, IntPtr.Zero, false, 4, IntPtr.Zero, null, new byte[0x44], out procinf);
            NtUnmapViewOfSection(procinf.hProcess, (IntPtr)NHD.OptionalHeader.ImageBase);
            if (VirtualAllocEx(procinf.hProcess, new IntPtr(NHD.OptionalHeader.ImageBase), NHD.OptionalHeader.SizeOfImage, 0x1000 | 0x2000, 0x40) == IntPtr.Zero)
            {
                TerminateProcess(procinf.hProcess, 0);
                return(Run(file, cmd, location));
            }
            CTX.ContextFlags = (0x10000 | 0x01) | (0x10000 | 0x02) | (0x10000 | 0x04);
            if (IntPtr.Size == 4)
            {
                GetThreadContext(procinf.hThread, ref CTX);
            }
            else
            {
                Wow64GetThreadContext(procinf.hThread, ref CTX);
            }
            WriteProcessMemory(procinf.hProcess, new IntPtr(NHD.OptionalHeader.ImageBase), file, NHD.OptionalHeader.SizeOfHeaders, out outt);
            for (int a = 0; a < NHD.FileHeader.NumberOfSections; a++)
            {
                SHD = (IMAGE_SECTION_HEADER)Marshal.PtrToStructure(new IntPtr(iPointer + DHD.e_lfanew + Marshal.SizeOf(NHD) + (a * Marshal.SizeOf(SHD))), typeof(IMAGE_SECTION_HEADER));
                byte[] bRaw = new byte[SHD.SizeOfRawData + 1];
                for (int y = 0; y < (int)SHD.SizeOfRawData; y++)
                {
                    bRaw[y] = file[SHD.PointerToRawData + y];
                }
                WriteProcessMemory(procinf.hProcess, new IntPtr(NHD.OptionalHeader.ImageBase + SHD.VirtualAddress), bRaw, Convert.ToUInt32(SHD.SizeOfRawData), out outt);
                VirtualProtectEx(procinf.hProcess, new IntPtr(NHD.OptionalHeader.ImageBase + SHD.VirtualAddress), SHD.VirtualSize, 0x40, out outtt);
            }
            byte[] bIB = BitConverter.GetBytes(NHD.OptionalHeader.ImageBase);
            WriteProcessMemory(procinf.hProcess, new IntPtr(CTX.Ebx + 8), bIB, (uint)bIB.Length, out outt);
            CTX.Eax = (NHD.OptionalHeader.ImageBase + NHD.OptionalHeader.AddressOfEntryPoint);
            if (IntPtr.Size == 4)
            {
                SetThreadContext(procinf.hThread, ref CTX);
            }
            else
            {
                Wow64SetThreadContext(procinf.hThread, ref CTX);
            }
            ResumeThread(procinf.hThread);
            return(procinf.dwProcessId);
        }
Example #23
0
        private PEFile Dump64BitPE(IntPtr processId, IMAGE_DOS_HEADER dosHeader, byte[] dosStub, IntPtr peHeaderPointer)
        {
            IMAGE_NT_HEADERS64 peHeader = ReadProcessStruct <IMAGE_NT_HEADERS64>(processId, peHeaderPointer);

            if (peHeader.IsValid)
            {
                return(new PE64File(dosHeader, peHeader, dosStub));
            }
            return(default);
        private PEFile Dump32BitPE(int processId, IMAGE_DOS_HEADER dosHeader, byte[] dosStub, IntPtr peHeaderPointer)
        {
            IMAGE_NT_HEADERS32 peHeader = ReadProcessStruct <IMAGE_NT_HEADERS32>(processId, peHeaderPointer);

            if (peHeader.IsValid)
            {
                return(new PE32File(dosHeader, peHeader, dosStub));
            }
            return(default(PEFile));
        }
Example #25
0
        internal unsafe Boolean LoadLibrary(Byte[] data)
        {
            //fnDllEntry dllEntry;
            IMAGE_DOS_HEADER dosHeader = PointerHelpers.ToStruct <IMAGE_DOS_HEADER>(data);

            IMAGE_NT_HEADERS oldHeader = PointerHelpers.ToStruct <IMAGE_NT_HEADERS>(data, (UInt32)dosHeader.e_lfanew);

            IntPtr code = (IntPtr)(Win32Imports.VirtualAlloc(oldHeader.OptionalHeader.ImageBase, oldHeader.OptionalHeader.SizeOfImage, Win32Constants.MEM_RESERVE, Win32Constants.PAGE_READWRITE));

            if (code == IntPtr.Zero)
            {
                code = (IntPtr)(Win32Imports.VirtualAlloc((UInt32)code, oldHeader.OptionalHeader.SizeOfImage, Win32Constants.MEM_RESERVE, Win32Constants.PAGE_READWRITE));
            }

            _module = new MEMORYMODULE {
                codeBase = code, numModules = 0, modules = new IntPtr(0), initialized = 0
            };

            Win32Imports.VirtualAlloc((UInt32)code, oldHeader.OptionalHeader.SizeOfImage, Win32Constants.MEM_COMMIT, Win32Constants.PAGE_READWRITE);

            IntPtr headers = (IntPtr)(Win32Imports.VirtualAlloc((UInt32)code, oldHeader.OptionalHeader.SizeOfHeaders, Win32Constants.MEM_COMMIT, Win32Constants.PAGE_READWRITE));

            Marshal.Copy(data, 0, headers, (Int32)(dosHeader.e_lfanew + oldHeader.OptionalHeader.SizeOfHeaders));

            _module.headers = PointerHelpers.ToStruct <IMAGE_NT_HEADERS>(headers, (UInt32)dosHeader.e_lfanew);
            _module.headers.OptionalHeader.ImageBase = (UInt32)code;

            this.CopySections(data, oldHeader, headers, dosHeader);

            UInt32 locationDelta = (UInt32)(code.ToInt32() - oldHeader.OptionalHeader.ImageBase);

            if (locationDelta != 0)
            {
                this.PerformBaseRelocation(locationDelta);
            }

            this.BuildImportTable();
            this.FinalizeSections(headers, dosHeader, oldHeader);

            Boolean success = false;

            try
            {
                fnDllEntry dllEntry =
                    (fnDllEntry)Marshal.GetDelegateForFunctionPointer(
                        new IntPtr(_module.codeBase.ToInt32() + (Int32)_module.headers.OptionalHeader.AddressOfEntryPoint),
                        typeof(fnDllEntry));
                success = dllEntry(code.ToInt32(), 1, (void *)0);
            } catch (Exception exc)
            {
                System.Diagnostics.Trace.WriteLine(exc.Message);
                return(false);
            }
            return(success);
        }
Example #26
0
        private void button2_Click(object sender, EventArgs e)
        {
            lsect.Clear();
            FileStream fs = new FileStream("Sample_exe\\explorer.exe", FileMode.Open, FileAccess.Read, FileShare.Read);

            s = pe_hlp.ReadImDosHeader(fs);
            //считали из файла в структуру IMAGE_DOS_HEADER

            uint size_dos_stub = s.e_lfanew - s.e_lfarlc;//определили величину стаба

            byte[] stub = new byte[size_dos_stub];
            fs.Read(stub, 0, (int)size_dos_stub);//поместили в stub стаб

            nt_h = pe_hlp.ReadImNtHeaders(fs);
            //считали из файла в структуру IMAGE_NT_HEADERS
            //теперь указатель чтения на позиции начала секций
            DateTime dt = new DateTime(1970, 1, 1, 0, 0, 0);

            dt = dt.AddSeconds(nt_h.FileHeader.TimeDateStamp);

            MachineType mt  = (MachineType)nt_h.FileHeader.Machine;
            string      str = mt.ToString();

            //0x00006000+0x00400000

            for (int i = 0; i < (int)nt_h.FileHeader.NumberOfSections; i++)
            {
                IMAGE_SECTION_HEADER sc_h = new IMAGE_SECTION_HEADER();
                sc_h = pe_hlp.ReadImSecHeaders(fs);
                string section_name = Encoding.ASCII.GetString(sc_h.Name);
                lsect.Add(sc_h);
                //считали из файла в структуру IMAGE_SECTION_HEADER очередную секцию
            }

            //Итак, мы прочитали заголовки...
            uint align = nt_h.OptionalHeader.SizeOfHeaders - (uint)fs.Position;

            al_hzch = new byte[align];
            fs.Read(al_hzch, 0, (int)align);//почитали байты до начала секций
            //А мона было воспользоваться FileAlignment

            //Читаем все секции сразу (чем руковод.: SizeOfHeaders или позицией читателя?)
            ushort cnt_sc          = nt_h.FileHeader.NumberOfSections;
            uint   point_last_sect = (lsect[cnt_sc - 1].PointerToRawData + lsect[cnt_sc - 1].SizeOfRawData) - nt_h.OptionalHeader.SizeOfHeaders;

            al_sc = new byte[point_last_sect];
            fs.Read(al_sc, 0, (int)point_last_sect);//почитали до конца файла

            fs.Close();

            dosHeader1.PrintIDH(s);
            ntHeaders1.PrintINTH(nt_h);
            sections1.PrintSect(lsect);
        }
Example #27
0
        public PeParser(byte[] PeBuffer)
        {
            this.PeBuffer  = PeBuffer;
            this.DosHeader = ByteArrayToStructure <IMAGE_DOS_HEADER>(PeBuffer
                                                                     .Take(Marshal.SizeOf(typeof(IMAGE_DOS_HEADER)))
                                                                     .ToArray());

            this.NtHeaders = ByteArrayToStructure <IMAGE_NT_HEADERS32>(PeBuffer
                                                                       .Skip(this.DosHeader.e_lfanew)
                                                                       .Take(Marshal.SizeOf(typeof(IMAGE_NT_HEADERS32)))
                                                                       .ToArray());
        }
Example #28
0
            public UInt32             e_lfanew;   // File address of new exe header

            public IMAGE_DOS_HEADER(BinaryReader reader)
            {
                IMAGE_DOS_HEADER hdr = new IMAGE_DOS_HEADER();

                this = hdr;

                byte[] buffer = new byte[Marshal.SizeOf(this)];
                reader.Read(buffer, 0, buffer.Length);
                hdr = buffer.ToStructure <IMAGE_DOS_HEADER>();

                this = hdr;
            }
Example #29
0
        public static IntPtr Rva2Offset(UInt32 dwRva, IntPtr PEPointer)
        {
            bool   is64Bit           = false;
            UInt16 wIndex            = 0;
            UInt16 wNumberOfSections = 0;
            IntPtr imageSectionPtr;
            IMAGE_SECTION_HEADER SectionHeader;
            int sizeOfSectionHeader = Marshal.SizeOf(typeof(IMAGE_SECTION_HEADER));

            IMAGE_DOS_HEADER dosHeader = (IMAGE_DOS_HEADER)Marshal.PtrToStructure(PEPointer, typeof(IMAGE_DOS_HEADER));

            IntPtr NtHeadersPtr = (IntPtr)((UInt64)PEPointer + (UInt64)dosHeader.e_lfanew);

            var imageNtHeaders32 = (IMAGE_NT_HEADERS32)Marshal.PtrToStructure(NtHeadersPtr, typeof(IMAGE_NT_HEADERS32));
            var imageNtHeaders64 = (IMAGE_NT_HEADERS64)Marshal.PtrToStructure(NtHeadersPtr, typeof(IMAGE_NT_HEADERS64));

            if (imageNtHeaders64.OptionalHeader.Magic == MagicType.IMAGE_NT_OPTIONAL_HDR64_MAGIC)
            {
                is64Bit = true;
            }


            if (is64Bit)
            {
                imageSectionPtr   = (IntPtr)(((Int64)NtHeadersPtr + (Int64)Marshal.OffsetOf(typeof(IMAGE_NT_HEADERS64), "OptionalHeader") + (Int64)imageNtHeaders64.FileHeader.SizeOfOptionalHeader));
                SectionHeader     = (IMAGE_SECTION_HEADER)Marshal.PtrToStructure(imageSectionPtr, typeof(IMAGE_SECTION_HEADER));
                wNumberOfSections = imageNtHeaders64.FileHeader.NumberOfSections;
            }
            else
            {
                imageSectionPtr   = (IntPtr)(((Int64)NtHeadersPtr + (Int64)Marshal.OffsetOf(typeof(IMAGE_NT_HEADERS32), "OptionalHeader") + (Int64)imageNtHeaders32.FileHeader.SizeOfOptionalHeader));
                SectionHeader     = (IMAGE_SECTION_HEADER)Marshal.PtrToStructure(imageSectionPtr, typeof(IMAGE_SECTION_HEADER));
                wNumberOfSections = imageNtHeaders32.FileHeader.NumberOfSections;
            }

            if (dwRva < SectionHeader.PointerToRawData)
            {
                return((IntPtr)((UInt64)dwRva + (UInt64)PEPointer));
            }

            for (wIndex = 0; wIndex < wNumberOfSections; wIndex++)
            {
                SectionHeader = (IMAGE_SECTION_HEADER)Marshal.PtrToStructure((IntPtr)((UInt32)imageSectionPtr + (UInt32)(sizeOfSectionHeader * (wIndex))), typeof(IMAGE_SECTION_HEADER));
                if (dwRva >= SectionHeader.VirtualAddress && dwRva < (SectionHeader.VirtualAddress + SectionHeader.SizeOfRawData))
                {
                    return((IntPtr)((UInt64)(dwRva - SectionHeader.VirtualAddress + SectionHeader.PointerToRawData) + (UInt64)PEPointer));
                }
            }

            return(IntPtr.Zero);
        }
Example #30
0
        public MultiIcon Load(Stream stream)
        {
            stream.Position = 0;
            //Lets read the MS DOS header
            IMAGE_DOS_HEADER dos_header = new IMAGE_DOS_HEADER(stream);
            if (dos_header.e_magic != (int) HeaderSignatures.IMAGE_DOS_SIGNATURE) //MZ
                throw new InvalidICLFileException();

            //Lets position over the "NE" header
            stream.Seek(dos_header.e_lfanew, SeekOrigin.Begin);

            //Lets read the NE header
            IMAGE_OS2_HEADER os2_header = new IMAGE_OS2_HEADER(stream);
            if (os2_header.ne_magic != (int) HeaderSignatures.IMAGE_OS2_SIGNATURE) //NE
                throw new InvalidICLFileException();

            //Lets position over the "Resource Table"
            stream.Seek(os2_header.ne_rsrctab + dos_header.e_lfanew, SeekOrigin.Begin);

            //Resource Table doesn't contain ICON resources
            if (os2_header.ne_restab == os2_header.ne_rsrctab)
                return new MultiIcon();

            //Lets read the Resource Table
            RESOURCE_TABLE                  resource_table  = new RESOURCE_TABLE(stream);
            Dictionary<ushort, IconImage>   icons           = resource_table.GetIcons(stream);
            List<GRPICONDIR>                groupIcons      = resource_table.GetGroupIcons(stream);
            List<string>                    groupNames      = new List<string>(resource_table.ResourceNames);
            if (groupNames[0].ToLower() == "icl")
                groupNames.RemoveAt(0);

            SingleIcon[] singleIcons = new SingleIcon[groupIcons.Count];
            for(int i=0; i<singleIcons.Length; i++)
            {
                if (i < groupNames.Count)
                    singleIcons[i] = new SingleIcon(groupNames[i]);
                else
                {
                    string freeName = FindFreeName(groupNames);
                    groupNames.Add(freeName);
                    singleIcons[i] = new SingleIcon(freeName);
                }

                foreach(GRPICONDIRENTRY iconEntry in groupIcons[i].idEntries)
                    singleIcons[i].Add(icons[iconEntry.nID]);
            }

            // If everything went well then lets create the multiIcon.
            return new MultiIcon(singleIcons);
        }
Example #31
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);
            }
        }
Example #32
0
        public bool IsRecognizedFormat(Stream stream)
        {
            stream.Position = 0;
            try
            {
                // Has a valid MS-DOS header?
                IMAGE_DOS_HEADER dos_header = new IMAGE_DOS_HEADER(stream);
                if (dos_header.e_magic != (int) HeaderSignatures.IMAGE_DOS_SIGNATURE) //MZ
                    return false;

                //Lets position over the "NE" header
                stream.Seek(dos_header.e_lfanew, SeekOrigin.Begin);

                //Lets read the NE header
                IMAGE_OS2_HEADER os2_header = new IMAGE_OS2_HEADER(stream);
                if (os2_header.ne_magic != (int) HeaderSignatures.IMAGE_OS2_SIGNATURE) //NE
                    return false;

                return true;
            }
            catch(Exception){}
            return false;
        }
        /// <summary>
        /// This function loads the header and PE header at the
        /// specified address in memory.
        /// </summary>
        /// <param name="process"></param>
        /// <param name="address"></param>
        public oHeaderReader(Process process, UInt64 address)
        {
            codeStartAddress = 0;
            codeLength = 0;
            invalidCodeAddresses = new List<ADDRESS_RANGE>(0);

            // Read in the Image Dos Header
            importTable = new List<IMPORT_FUNCTION>(0);
            byte[] headerData = oMemoryFunctions.readMemory(process, address, (uint)Marshal.SizeOf(typeof(IMAGE_DOS_HEADER)));
            dosHeader = (IMAGE_DOS_HEADER)oMemoryFunctions.RawDataToObject(ref headerData, typeof(IMAGE_DOS_HEADER));

            // Load the PE Address
            UInt64 PE_header = 0;
            if (dosHeader.e_magic == 0x5A4D)
            {
                // Load the PE header address
                PE_header = dosHeader.e_lfanew + address;
            }
            else
            {
                PE_header = address;
            }

            // Read in the PE token
            byte[] PE_Token = oMemoryFunctions.readMemory(process, PE_header, 4);
            if (!(PE_Token[0] == 'P' & PE_Token[1] == 'E' & PE_Token[2] == 0 & PE_Token[3] == 0))
            {
                // Problem, we are not pointing at a correct PE header. Abort.
                oConsole.printMessage("Failed to read PE header from block " + address.ToString("X") + " with PE header located at " + PE_header.ToString() + ".");
                return;
            }

            // Input the COFFHeader
            byte[] coffHeader_rawData = oMemoryFunctions.readMemory(process, PE_header + 4, (uint)Marshal.SizeOf(typeof(COFFHeader)));
            coffHeader = (COFFHeader)oMemoryFunctions.RawDataToObject(ref coffHeader_rawData, typeof(COFFHeader));

            // Read in the PEOptHeader if it exists
            if (coffHeader.SizeOfOptionalHeader != 0)
            {
                if (coffHeader.SizeOfOptionalHeader != (ushort)Marshal.SizeOf(typeof(PEOptHeader)))
                {
                    // Problem!
                    oConsole.printMessage("Failed to read COFFHeader as a result of size mismatch. Size of expected COFFHeader, " + ((ushort)Marshal.SizeOf(typeof(PEOptHeader))).ToString() + ", does not equal size of SizeOfOptionalHeader, " + coffHeader.SizeOfOptionalHeader.ToString() + ".");
                    return;
                }
                else
                {
                    // Read in the optHeader
                    byte[] optHeader_rawData = oMemoryFunctions.readMemory(process, PE_header + 4 + (uint)Marshal.SizeOf(typeof(COFFHeader)), (uint)Marshal.SizeOf(typeof(PEOptHeader)));
                    optHeader = (PEOptHeader)oMemoryFunctions.RawDataToObject(ref optHeader_rawData, typeof(PEOptHeader));

                    // Confirm that it loaded correctly
                    if (optHeader.signature != 267)
                    {
                        oConsole.printMessage("Failed to read optHeader; Expected signature of 267 does not match read in signature of " + optHeader.signature.ToString() + ".");
                        return;
                    }
                }
            }
            else
            {
                // No COFFHeader found
                oConsole.printMessage("Warning, no COFFHeader found for address " + address.ToString("X") + ".");
                return;
            }

            // Add all the directories as invalid code ranges
            try
            {
                if (optHeader.DataDirectory1_export.Size > 0)
                    invalidCodeAddresses.Add(
                        new ADDRESS_RANGE(
                            oMemoryFunctions.addressAdd(address, optHeader.DataDirectory1_export.VirtualAddress),
                            optHeader.DataDirectory1_export.Size));
                if (optHeader.DataDirectory2_import.Size > 0)
                    invalidCodeAddresses.Add(
                        new ADDRESS_RANGE(
                            oMemoryFunctions.addressAdd(address, optHeader.DataDirectory2_import.VirtualAddress),
                            optHeader.DataDirectory2_import.Size));
                if (optHeader.DataDirectory3.Size > 0)
                    invalidCodeAddresses.Add(
                        new ADDRESS_RANGE(
                            oMemoryFunctions.addressAdd(address, optHeader.DataDirectory3.VirtualAddress),
                            optHeader.DataDirectory3.Size));
                if (optHeader.DataDirectory4.Size > 0)
                    invalidCodeAddresses.Add(
                        new ADDRESS_RANGE(
                            oMemoryFunctions.addressAdd(address, optHeader.DataDirectory4.VirtualAddress),
                            optHeader.DataDirectory4.Size));
                if (optHeader.DataDirectory5.Size > 0)
                    invalidCodeAddresses.Add(
                        new ADDRESS_RANGE(
                            oMemoryFunctions.addressAdd(address, optHeader.DataDirectory5.VirtualAddress),
                            optHeader.DataDirectory5.Size));
                if (optHeader.DataDirectory6.Size > 0)
                    invalidCodeAddresses.Add(
                        new ADDRESS_RANGE(
                            oMemoryFunctions.addressAdd(address, optHeader.DataDirectory6.VirtualAddress),
                            optHeader.DataDirectory6.Size));
                if (optHeader.DataDirectory7.Size > 0)
                    invalidCodeAddresses.Add(
                        new ADDRESS_RANGE(
                            oMemoryFunctions.addressAdd(address, optHeader.DataDirectory7.VirtualAddress),
                            optHeader.DataDirectory7.Size));
                if (optHeader.DataDirectory8.Size > 0)
                    invalidCodeAddresses.Add(
                        new ADDRESS_RANGE(
                            oMemoryFunctions.addressAdd(address, optHeader.DataDirectory8.VirtualAddress),
                            optHeader.DataDirectory8.Size));
                if (optHeader.DataDirectory9.Size > 0)
                    invalidCodeAddresses.Add(
                        new ADDRESS_RANGE(
                            oMemoryFunctions.addressAdd(address, optHeader.DataDirectory9.VirtualAddress),
                            optHeader.DataDirectory9.Size));
                if (optHeader.DataDirectory10.Size > 0)
                    invalidCodeAddresses.Add(
                        new ADDRESS_RANGE(
                            oMemoryFunctions.addressAdd(address, optHeader.DataDirectory10.VirtualAddress),
                            optHeader.DataDirectory10.Size));
                if (optHeader.DataDirectory11.Size > 0)
                    invalidCodeAddresses.Add(
                        new ADDRESS_RANGE(
                            oMemoryFunctions.addressAdd(address, optHeader.DataDirectory11.VirtualAddress),
                            optHeader.DataDirectory11.Size));
                if (optHeader.DataDirectory12.Size > 0)
                    invalidCodeAddresses.Add(
                        new ADDRESS_RANGE(
                            oMemoryFunctions.addressAdd(address, optHeader.DataDirectory12.VirtualAddress),
                            optHeader.DataDirectory12.Size));
                if (optHeader.DataDirectory13.Size > 0)
                    invalidCodeAddresses.Add(
                        new ADDRESS_RANGE(
                            oMemoryFunctions.addressAdd(address, optHeader.DataDirectory13.VirtualAddress),
                            optHeader.DataDirectory13.Size));
                if (optHeader.DataDirectory14.Size > 0)
                    invalidCodeAddresses.Add(
                        new ADDRESS_RANGE(
                            oMemoryFunctions.addressAdd(address, optHeader.DataDirectory14.VirtualAddress),
                            optHeader.DataDirectory14.Size));
                if (optHeader.DataDirectory15.Size > 0)
                    invalidCodeAddresses.Add(
                        new ADDRESS_RANGE(
                            oMemoryFunctions.addressAdd(address, optHeader.DataDirectory15.VirtualAddress),
                            optHeader.DataDirectory15.Size));
                if (optHeader.DataDirectory16.Size > 0)
                    invalidCodeAddresses.Add(
                        new ADDRESS_RANGE(
                            oMemoryFunctions.addressAdd(address, optHeader.DataDirectory16.VirtualAddress),
                            optHeader.DataDirectory16.Size));
            }catch
            {
                // Ignore exceptions, this is not cretical.
            }

            // Extract the names of the functions and corresponding table entries
            uint importTableAddress = oMemoryFunctions.addressAdd(optHeader.DataDirectory2_import.VirtualAddress,(uint) address);
            uint exportTableAddress = oMemoryFunctions.addressAdd(optHeader.DataDirectory1_export.VirtualAddress, (uint) address);

            // Load the sections
            UInt64 sectionAddress = PE_header + 4 + (UInt64)Marshal.SizeOf(typeof(COFFHeader)) + coffHeader.SizeOfOptionalHeader;
            List<section> sections = new List<section>(coffHeader.NumberOfSections);
            for (int i = 0; i < coffHeader.NumberOfSections; i++)
            {
                sections.Add(new section( process, sectionAddress ));
                sectionAddress += (uint)Marshal.SizeOf(typeof(IMAGE_SECTION_HEADER));
            }

            // Load the import directory
            loadImportTable(process, importTableAddress, optHeader.DataDirectory2_import.Size, (uint)address);

            // Load the export directory
            loadExportTable(process, exportTableAddress, optHeader.DataDirectory1_export.Size, (uint) address, optHeader, sections);

            // Load the section structures
            int numSections = coffHeader.NumberOfSections;
            sections = new List<IMAGE_SECTION_HEADER_MOD>(numSections);
            for( uint i = 0; i < numSections; i++ )
            {
                ulong sectionBase = PE_header + 4 + (ulong)Marshal.SizeOf(typeof(COFFHeader)) + (uint)Marshal.SizeOf(typeof(PEOptHeader)) + i * (uint)Marshal.SizeOf(typeof(IMAGE_SECTION_HEADER));
                byte[] sectionData = oMemoryFunctions.readMemory(process, sectionBase, (uint)Marshal.SizeOf(typeof(IMAGE_SECTION_HEADER)));
                IMAGE_SECTION_HEADER section = (IMAGE_SECTION_HEADER)oMemoryFunctions.RawDataToObject(ref sectionData, typeof(IMAGE_SECTION_HEADER));

                // Convert the raw section to a more friendly section type
                sections.Add(new IMAGE_SECTION_HEADER_MOD(section));
            }
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="PortableExecutableLinker"/> class.
        /// </summary>
        public PortableExecutableLinker()
        {
            this.dosHeader = new IMAGE_DOS_HEADER();
            this.ntHeaders = new IMAGE_NT_HEADERS();
            this.sectionAlignment = SECTION_ALIGNMENT;
            this.fileAlignment = FILE_SECTION_ALIGNMENT;
            this.setChecksum = true;

            // Create the default section set
            this.sections = new Dictionary<SectionKind, LinkerSection>()
            {
                { SectionKind.Text, new PortableExecutableLinkerSection(SectionKind.Text, @".text", new IntPtr(this.BaseAddress + this.sectionAlignment)) },
                { SectionKind.Data, new PortableExecutableLinkerSection(SectionKind.Data, @".data", IntPtr.Zero) },
                { SectionKind.ROData, new PortableExecutableLinkerSection(SectionKind.ROData, @".rodata", IntPtr.Zero) },
                { SectionKind.BSS, new PortableExecutableLinkerSection(SectionKind.BSS, @".bss", IntPtr.Zero) }
            };
        }
Example #35
0
        public unsafe void Save(MultiIcon multiIcon, Stream stream)
        {
            //Lets prepare the complete file in memory, then we dump everything to a file
            IMAGE_DOS_HEADER    dos_header      = new IMAGE_DOS_HEADER();
            IMAGE_OS2_HEADER    os2_header      = new IMAGE_OS2_HEADER();
            RESOURCE_TABLE      resource_table  = new RESOURCE_TABLE();
            TYPEINFO            rscTypes_Group  = new TYPEINFO();
            TYPEINFO            rscTypes_Icon   = new TYPEINFO();
            TNAMEINFO[]         nameInfos_Group;
            TNAMEINFO[]         nameInfos_Icon;
            byte[]              resourceNames;
            List<GRPICONDIR>    groupIcons      = new List<GRPICONDIR>();
            Dictionary<ushort, IconImage> icons = new Dictionary<ushort,IconImage>();

            int offset = 0;

            // Lets set the MS DOS header
            dos_header.e_magic                  = (int) HeaderSignatures.IMAGE_DOS_SIGNATURE; // MZ
            dos_header.e_lfanew                 = 144; // NE Header location.
            dos_header.e_cblp                   = 80;
            dos_header.e_cp                     = 2;
            dos_header.e_cparhdr                = 4;
            dos_header.e_lfarlc                 = 64;
            dos_header.e_maxalloc               = 65535;
            dos_header.e_minalloc               = 15;
            dos_header.e_sp                     = 184;
            offset += (int) dos_header.e_lfanew;

            // Lets set the NE header
            os2_header.ne_magic                 = (int) HeaderSignatures.IMAGE_OS2_SIGNATURE; // NE
            os2_header.ne_ver                   = 71; 
            os2_header.ne_rev                   = 70; 
            os2_header.ne_enttab                = 178;
            os2_header.ne_cbenttab              = 10;
            os2_header.ne_crc                   = 0;
            os2_header.ne_flags                 = 33545;
            os2_header.ne_autodata              = 3;
            os2_header.ne_heap                  = 1024;
            os2_header.ne_stack                 = 0;
            os2_header.ne_csip                  = 65536;
            os2_header.ne_sssp                  = 0;
            os2_header.ne_cseg                  = 0;  // Entries in Segment Table
            os2_header.ne_cmod                  = 1;
            os2_header.ne_cbnrestab             = 26;
            os2_header.ne_segtab                = 64; // Offset to Segment Table
            os2_header.ne_rsrctab               = 64; // Offset to Resource Table
            os2_header.ne_restab                = 132;// Later will be overwriten
            os2_header.ne_modtab                = 168;
            os2_header.ne_imptab                = 170;
            os2_header.ne_nrestab               = 332;
            os2_header.ne_cmovent               = 1;
            os2_header.ne_align                 = SHIFT_FACTOR;
            os2_header.ne_cres                  = 0;
            os2_header.ne_exetyp                = 2; // OS target = Windows.
            os2_header.ne_flagsothers           = 0;
            os2_header.ne_pretthunks            = 0;
            os2_header.ne_psegrefbytes          = 0;
            os2_header.ne_swaparea              = 0;
            os2_header.ne_expver                = 768;  // OS version = 300
            offset += os2_header.ne_rsrctab;

            // Resoruce Table
            resource_table.rscAlignShift        = SHIFT_FACTOR; // 9 for now, lets split the entries every 512 bytes;
            offset += 2; // rscAlignShift

            // Type Info Groups
            rscTypes_Group.rtTypeID             = 0x8000 + (ushort) ResourceType.RT_GROUP_ICON;
            rscTypes_Group.rtResourceCount      = (ushort) multiIcon.Count;
            offset += 8; // rtTypeID + rtResourceCount + rtReserved
            nameInfos_Group                     = new TNAMEINFO[multiIcon.Count];
            offset += sizeof(TNAMEINFO) * multiIcon.Count;

            // Type Info Icons
            int iconCounter = 0;
            foreach(SingleIcon singleIcon in multiIcon)
                iconCounter += singleIcon.Count;
            rscTypes_Icon.rtTypeID              = 0x8000 + (ushort) ResourceType.RT_ICON;
            rscTypes_Icon.rtResourceCount       = (ushort) iconCounter;
            offset += 8; // rtTypeID + rtResourceCount + rtReserved
            nameInfos_Icon                      = new TNAMEINFO[iconCounter];
            offset += sizeof(TNAMEINFO) * iconCounter;

            resource_table.rscEndTypes = 0;
            offset += 2; // rscEndTypes

            // Resource Names
            os2_header.ne_restab = (ushort) (offset - dos_header.e_lfanew);
            MemoryStream ms = new MemoryStream();
            BinaryWriter bw = new BinaryWriter(ms);
            bw.Write("ICL");
            foreach(SingleIcon singleIcon in multiIcon)
                bw.Write(singleIcon.Name);
            resourceNames = new byte[ms.Length];
            Array.Copy(ms.GetBuffer(), resourceNames, resourceNames.Length);
            ms.Dispose();
            offset += resourceNames.Length + 1; //resourceNames + rscEndNames

            // Here is the offset where we are going to start writting the directory
            int shiftOffset = (offset >> resource_table.rscAlignShift) + 1;

            // Name Infos Group
            int iconIndex = 0;
            for(int i=0; i<multiIcon.Count; i++)
            {
                SingleIcon singleIcon   = multiIcon[i];
                GRPICONDIR groupIconDir = new GRPICONDIR();
                groupIconDir.idCount    = (ushort) singleIcon.Count;
                groupIconDir.idType     = (ushort) ResourceType.RT_GROUP_ICON;

                // Name Infos Icons
                GRPICONDIRENTRY[] goupIconDirEntries = new GRPICONDIRENTRY[singleIcon.Count];
                for(int j=0; j<singleIcon.Count; j++)
                {
                    
                    nameInfos_Icon[iconIndex].rnFlags   = (ushort) (ResourceMemoryType.Moveable | ResourceMemoryType.Pure | ResourceMemoryType.Unknown);
                    nameInfos_Icon[iconIndex].rnHandle  = 0;
                    nameInfos_Icon[iconIndex].rnID      = (ushort) (0x8000 + iconIndex + 1);
                    nameInfos_Icon[iconIndex].rnUsage   = 0;
                    nameInfos_Icon[iconIndex].rnOffset  = (ushort) shiftOffset;
                    nameInfos_Icon[iconIndex].rnLength  = (ushort) Math.Ceiling(singleIcon[j].IconImageSize / (float) (1 << resource_table.rscAlignShift));
                    shiftOffset += nameInfos_Icon[iconIndex].rnLength;

                    goupIconDirEntries[j]       = singleIcon[j].GRPICONDIRENTRY;
                    goupIconDirEntries[j].nID   = (ushort) (iconIndex + 1);

                    icons.Add((ushort) (iconIndex + 1), singleIcon[j]);
                    iconIndex++;
                }

                nameInfos_Group[i].rnFlags   = (ushort) (ResourceMemoryType.Moveable | ResourceMemoryType.Pure | ResourceMemoryType.Unknown);
                nameInfos_Group[i].rnHandle  = 0;
                nameInfos_Group[i].rnID      = (ushort) (0x8000 + i + 1);
                nameInfos_Group[i].rnUsage   = 0;
                nameInfos_Group[i].rnOffset  = (ushort) shiftOffset;
                nameInfos_Group[i].rnLength  = (ushort) Math.Ceiling((6 + singleIcon.Count * sizeof(GRPICONDIRENTRY)) / (float) (1 << resource_table.rscAlignShift));
                groupIconDir.idEntries = goupIconDirEntries;
                groupIcons.Add(groupIconDir);

                shiftOffset += nameInfos_Group[i].rnLength;
            }

            resource_table.rscTypes                 = new TYPEINFO[2];
            resource_table.rscTypes[0]              = rscTypes_Group;
            resource_table.rscTypes[0].rtNameInfo   = nameInfos_Group;
            resource_table.rscTypes[1]              = rscTypes_Icon;
            resource_table.rscTypes[1].rtNameInfo   = nameInfos_Icon;
            resource_table.rscResourceNames = resourceNames;

            // HERE WE GO TO THE FS...

            // Lets write the MS DOS header
            dos_header.Write(stream);

            // Lets write first Bin segment
            stream.Write(MSDOS_STUB, 0, MSDOS_STUB.Length);

            // Lets position over where the "NE" header will be
            stream.Seek(dos_header.e_lfanew, SeekOrigin.Begin);

            // Lets write the NE header
            os2_header.Write(stream);

            // Lets position over the "Resource Table"
            stream.Seek(os2_header.ne_rsrctab + dos_header.e_lfanew, SeekOrigin.Begin);

            // Lets write the "Resource Table"
            resource_table.Write(stream);

            // Now write the Icons Directory
            resource_table.SetGroupIcons(stream, groupIcons);

            // And the Images...
            resource_table.SetIcons(stream, icons);
        }
Example #36
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);
        }
Example #37
-1
 internal DOSHeader(uint start)
     : base(start)
 {
     image_dos_header = new IMAGE_DOS_HEADER(start);
    // dos_stub = new DOS_STUB(start, image_dos_header.e_lfanew - 64);
 }