public static unsafe string GetPeArchitecture(byte[] fileBytes)
        {
            // GetPeArchitecture takes the file and checks the Machine Type to
            // make sure the file is either x86 or x64, which are the only 2
            // file architectures we can deal with
            fixed(byte *ptr_data = fileBytes)
            {
                // Get the DOS header
                IMAGE_DOS_HEADER *dos_header = (IMAGE_DOS_HEADER *)ptr_data;

                // Get the NT header using e_lfanew
                IMAGE_NT_HEADERS64 *nt_header = (IMAGE_NT_HEADERS64 *)(ptr_data + dos_header->e_lfanew);

                // Get the image architecture. We only want x86 and x64.
                if (nt_header->FileHeader.Machine == IMAGE_FILE_MACHINE_AMD64)
                {
                    return("x64");
                }
                else if (nt_header->FileHeader.Machine == IMAGE_FILE_MACHINE_I386)
                {
                    return("x86");
                }
                else
                {
                    return(null);
                }
            }
        }
Exemple #2
0
        void CalcHeaders()
        {
            _dosHeader   = (IMAGE_DOS_HEADER *)_address;
            _ntHeaders32 = (IMAGE_NT_HEADERS32 *)(_address + _dosHeader->e_lfanew);
            _ntHeaders64 = (IMAGE_NT_HEADERS64 *)(_address + _dosHeader->e_lfanew);
            _isPE64      = _ntHeaders32->OptionalHeader.Magic == (ushort)OptionalHeaderMagic.PE32Plus;

            _fileHeader = _isPE64 ? &_ntHeaders64->FileHeader : &_ntHeaders32->FileHeader;

            _header32 = &_ntHeaders32->OptionalHeader;
            _header64 = &_ntHeaders64->OptionalHeader;
            _sections = new IMAGE_SECTION_HEADER[_fileHeader->NumberOfSections];

            var offset = _isPE64 ? sizeof(IMAGE_NT_HEADERS64) : sizeof(IMAGE_NT_HEADERS32);

            fixed(void *sections = _sections)
            {
                Buffer.MemoryCopy((byte *)_ntHeaders32 + offset, sections, _sections.Length * sizeof(IMAGE_SECTION_HEADER), _sections.Length * sizeof(IMAGE_SECTION_HEADER));
            }

            FileHeader = new FileHeader(_fileHeader);
            if (IsPE64)
            {
                OptionalHeader = new OptionalHeader(_header64);
            }
            else
            {
                OptionalHeader = new OptionalHeader(_header32);
            }

            _workBuffer = Marshal.AllocCoTaskMem(1 << 12);
        }
Exemple #3
0
 public static IMAGE_SECTION_HEADER *IMAGE_FIRST_SECTION(byte *ptr_image_nt_headers)
 {
     if (Environment.Is64BitProcess)
     {
         IMAGE_NT_HEADERS64 *image_nt_headers = (IMAGE_NT_HEADERS64 *)ptr_image_nt_headers;
         return((IMAGE_SECTION_HEADER *)((long)image_nt_headers +
                                         (long)Marshal.OffsetOf(typeof(IMAGE_NT_HEADERS64), "OptionalHeader") +
                                         image_nt_headers->FileHeader.SizeOfOptionalHeader));
     }
     else
     {
         IMAGE_NT_HEADERS32 *image_nt_headers = (IMAGE_NT_HEADERS32 *)ptr_image_nt_headers;
         return((IMAGE_SECTION_HEADER *)((long)image_nt_headers +
                                         (long)Marshal.OffsetOf(typeof(IMAGE_NT_HEADERS32), "OptionalHeader") +
                                         image_nt_headers->FileHeader.SizeOfOptionalHeader));
     }
 }
Exemple #4
0
            private static uint GetEffectiveSectionSize64(IMAGE_NT_HEADERS64 *ntHeaders64, IMAGE_SECTION_HEADER *section)
            {
                if (section->SizeOfRawData != 0)
                {
                    return(section->SizeOfRawData);
                }

                if ((section->Characteristics & DataSectionFlags.ContentInitializedData) != 0)
                {
                    return(ntHeaders64->OptionalHeader.SizeOfInitializedData);
                }

                if ((section->Characteristics & DataSectionFlags.ContentUninitializedData) != 0)
                {
                    return(ntHeaders64->OptionalHeader.SizeOfUninitializedData);
                }

                return(0);
            }
        public static unsafe Offset RvaToOffset(IMAGE_NT_HEADERS64 *nt64, IMAGE_NT_HEADERS32 *nt32, uint rva, string friendlyName)
        {
            Offset offsets = new Offset();

            if (nt64 != null) // x64
            {
                IMAGE_SECTION_HEADER *section = IMAGE_FIRST_SECTION((byte *)nt64);
                for (int i = 1; i < nt64->FileHeader.NumberOfSections + 1; i++)
                {
                    if (rva >= section->VirtualAddress && rva < section->VirtualAddress + section->SizeOfRawData)
                    {
                        offsets.RVA       = section->VirtualAddress;
                        offsets.RawOffset = section->PointerToRawData;
                    }

                    section = (IMAGE_SECTION_HEADER *)((long)section + (long)Marshal.SizeOf(typeof(IMAGE_SECTION_HEADER)));
                }
                uint offset = offsets.RawOffset + (rva - offsets.RVA);

                return(offsets);
            }
            else if (nt32 != null) // x86
            {
                IMAGE_SECTION_HEADER *section = IMAGE_FIRST_SECTION((byte *)nt32);
                for (int i = 1; i < nt32->FileHeader.NumberOfSections + 1; i++)
                {
                    if (rva >= section->VirtualAddress && rva < section->VirtualAddress + section->SizeOfRawData)
                    {
                        offsets.RVA       = section->VirtualAddress;
                        offsets.RawOffset = section->PointerToRawData;
                    }
                    section = (IMAGE_SECTION_HEADER *)((long)section + (long)Marshal.SizeOf(typeof(IMAGE_SECTION_HEADER)));
                }

                uint offset = offsets.RawOffset + (rva - offsets.RVA);

                return(offsets);
            }
            else
            {
                return(offsets);
            }
        }
Exemple #6
0
 private static IMAGE_SECTION_HEADER* IMAGE_FIRST_SECTION64(IMAGE_NT_HEADERS64* ntheader)
 {
     return (IMAGE_SECTION_HEADER*)((ulong)ntheader + 24 + ntheader->FileHeader.SizeOfOptionalHeader);
 }
 public static void *ImageRvaToVa64([NativeTypeName("PIMAGE_NT_HEADERS")] IMAGE_NT_HEADERS64 *NtHeaders, [NativeTypeName("PVOID")] void *Base, [NativeTypeName("ULONG")] uint Rva, [NativeTypeName("PIMAGE_SECTION_HEADER *")] IMAGE_SECTION_HEADER **LastRvaSection)
 {
     return(ImageRvaToVa(NtHeaders, Base, Rva, LastRvaSection));
 }
 public static IMAGE_SECTION_HEADER *ImageRvaToSection64([NativeTypeName("PIMAGE_NT_HEADERS")] IMAGE_NT_HEADERS64 *NtHeaders, [NativeTypeName("PVOID")] void *Base, [NativeTypeName("ULONG")] uint Rva)
 {
     return(ImageRvaToSection(NtHeaders, Base, Rva));
 }
Exemple #9
0
        /// <summary>
        /// Simple PE Parser, That Extracts The PDB Location From a PE File, which also checks for PE File Validity.
        /// </summary>
        /// <param name="path"></param>
        public PEFile(string path)
        {
            if (String.IsNullOrEmpty(path))
            {
                throw new ArgumentNullException("path");
            }

            FileInfo peContainer = new FileInfo(path);

            if (!peContainer.Exists)
            {
                throw new FileNotFoundException(path);
            }

            m_fileInfo = peContainer;
            try {
                m_fileVersionInfo = FileVersionInfo.GetVersionInfo(path);
            }
            catch (Exception exc) {
                Debug.WriteLine(exc.ToString());
                m_fileVersionInfo = null;
            }

            using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read))
            {
                using (BinaryReader br = new BinaryReader(fs))
                {
                    // Find the address of the PE Header
                    try
                    {
                        br.BaseStream.Seek(PESignatureOffsetLoc, SeekOrigin.Begin);
                        // BugFix For Bug Number 677
                        // After the MS DOS stub, at the file offset specified at offset 0x3c,
                        // We must read 4 bytes to located the position of the PE Header In The Executable File
                        // is a 4-byte signature that identifies the file as a PE format image file.
                        // This signature is “PE\0\0” (the letters “P” and “E” followed by two null bytes).
                        // m_PESignatureOffset = br.ReadByte();
                        // Thx to Microsofts mdb source code in pdb2xml this was wrongly implemented.
                        // Should i trust their code :)
                        // Better Writing The Code Like In Pdb Extractor myself seems to be the right way :)
                        m_PESignatureOffset = br.ReadUInt32();
                        br.BaseStream.Seek(m_PESignatureOffset, SeekOrigin.Begin);
                        // The PE Signature like defined
                        // in Microsoft Portable Executable and Common Object File Format Specification v8.0
                        if (br.ReadByte() != 'P')
                        {
                            throw new FileLoadException("PE Signature corrupt");
                        }
                        if (br.ReadByte() != 'E')
                        {
                            throw new FileLoadException("PE Signature corrupt");
                        }
                        if (br.ReadByte() != '\0')
                        {
                            throw new FileLoadException("PE Signature corrupt");
                        }
                        if (br.ReadByte() != '\0')
                        {
                            throw new FileLoadException("PE Signature corrupt");
                        }
                    }
                    catch (EndOfStreamException)
                    {
                        throw new FileLoadException("Read past end of file");
                    }
                }
            }


            m_ExePath = path;

            byte[] Data = System.IO.File.ReadAllBytes(path);

            //This section is unsafe so faster access is achieved :)
            unsafe
            {
                //First Check The Length If it is lesser then dos header + image headers
                if (peContainer.Length < (sizeof(IMAGE_DOS_HEADER)) + sizeof(IMAGE_NT_HEADERS32))
                    throw new FileLoadException("Invalid PE File");

                fixed(byte *p_Data = Data)
                {
                    // Get the first 64 bytes and turn it into a IMAGE_DOS_HEADER
                    IMAGE_DOS_HEADER *idh =
                        (IMAGE_DOS_HEADER *)p_Data;
                    //Read Image Nt Headers
                    IMAGE_NT_HEADERS64 *inhs64 =
                        (IMAGE_NT_HEADERS64 *)(idh->lfanew + p_Data);

                    //Check The PE00 signature
                    if (inhs64->Signature != PEMAGIC)
                    {
                        throw new FileLoadException("PE Signature corrupt");
                    }

                    // The calculated values that are different depending on
                    // 32 vs. 64-bit.
                    int    SizeOfOptionalHeader = 0;
                    uint   rva              = 0;
                    uint   DebugDirSize     = 0;
                    ushort NumberOfSections = 0;

                    if (inhs64->OptionalHeader.Magic == PE32)
                    {
                        // Get all the 32-bit offsets.
                        IMAGE_NT_HEADERS32 *inhs32 =
                            (IMAGE_NT_HEADERS32 *)(idh->lfanew + p_Data);

                        SizeOfOptionalHeader = (int)
                                               inhs32->FileHeader.SizeOfOptionalHeader;
                        //Debug Section Is Always In 7th Member Of The Optional Headers Data Directory
                        rva          = inhs32->OptionalHeader.DataDirectory7.VirtualAddress;
                        DebugDirSize =
                            inhs32->OptionalHeader.DataDirectory7.Size;
                        NumberOfSections = inhs32->FileHeader.NumberOfSections;
                    }
                    else if (inhs64->OptionalHeader.Magic == PE32PLUS)
                    {
                        SizeOfOptionalHeader = (int)
                                               inhs64->FileHeader.SizeOfOptionalHeader;
                        //Debug Section Is Always In 7th Member Of The Optional Headers Data Directory
                        rva =
                            inhs64->OptionalHeader.DataDirectory7.VirtualAddress;
                        DebugDirSize =
                            inhs64->OptionalHeader.DataDirectory7.Size;
                        NumberOfSections = inhs64->FileHeader.NumberOfSections;
                    }

                    //No Debug Section Found So Exit.
                    if ((rva == 0) || (DebugDirSize == 0))
                    {
                        throw new NoDebugSectionException( );
                    }

                    //Find out the data section
                    Int32 dataSectionsOffset = (idh->lfanew) +
                                               4 +
                                               sizeof(IMAGE_FILE_HEADER)
                                               +
                                               (int)SizeOfOptionalHeader;
                    bool found = false;

                    //Loop through the debug sections, enumerate whole sections try to locate the type 2(CODEVIEW) section
                    //with magical header 0x53445352 For PDB 7.0 Entries , my code won't support PDB V2.0 Entries , because none
                    //of the .Net Assemblies Use It.
                    for (int i = 0; i < NumberOfSections; i++)
                    {
                        PESectionHeader *myHeader =
                            (PESectionHeader *)(dataSectionsOffset + p_Data);

                        uint sectionSize =
                            myHeader->VirtualSize;

                        if (sectionSize == 0)
                        {
                            sectionSize = myHeader->RawDataSize;
                        }

                        if ((rva >= myHeader->VirtualAddress) &&
                            (rva < myHeader->VirtualAddress + sectionSize))
                        {
                            found = true;
                        }

                        if (found)
                        {
                            found = false;

                            int diff =
                                (int)(myHeader->VirtualAddress - myHeader->RawDataAddress);

                            UInt32 fileOffset = rva - (uint)diff;

                            _IMAGE_DEBUG_DIRECTORY *debugDirectory =
                                (_IMAGE_DEBUG_DIRECTORY *)(fileOffset + p_Data);

                            int NumEntries = (int)(DebugDirSize / sizeof(_IMAGE_DEBUG_DIRECTORY));


                            for (int ix = 1; ix <= NumEntries; ix++, debugDirectory++)
                            {
                                if (debugDirectory->Type == 2)
                                {
                                    UInt32 cvSignature = *(UInt32 *)(p_Data + debugDirectory->PointerToRawData);
                                    if (cvSignature == 0x53445352)
                                    {
                                        CV_INFO_PDB70 *pCvInfo =
                                            (CV_INFO_PDB70 *)(p_Data + debugDirectory->PointerToRawData);

                                        string hexAge = pCvInfo->Age.ToString("x2");

                                        if (hexAge != "0")
                                        {
                                            hexAge = (hexAge.StartsWith("0") ? hexAge.Substring(1) : hexAge);
                                        }
                                        else
                                        {
                                            hexAge = "0";
                                        }

                                        m_pdbAge = pCvInfo->Age.ToString();

                                        string finalHex = String.Empty;

                                        byte[] firstHeader =
                                            BitConverter.GetBytes(pCvInfo->firstPart);

                                        byte[] secondHeader =
                                            BitConverter.GetBytes(pCvInfo->secondPart);

                                        byte[] thirdHeader =
                                            BitConverter.GetBytes(pCvInfo->thirdPart);

                                        byte[] fourthHeader =
                                            BitConverter.GetBytes(pCvInfo->fourthPart);


                                        byte[] finalGuid = new byte[16];

                                        //Make The Byte Order Correct So We Can Construct The Right Guid Out Of It

                                        //Guid Buildup Begin
                                        finalGuid[0] = firstHeader[3];
                                        finalGuid[1] = firstHeader[2];
                                        finalGuid[2] = firstHeader[1];
                                        finalGuid[3] = firstHeader[0];
                                        //c section
                                        finalGuid[4] = secondHeader[5 - 4];
                                        finalGuid[5] = secondHeader[4 - 4];
                                        //d relocation
                                        finalGuid[6] = secondHeader[7 - 4];
                                        finalGuid[7] = secondHeader[6 - 4];

                                        for (int xx = 8; xx < 12; xx++)
                                        {
                                            finalGuid[xx] = thirdHeader[xx - 8];
                                        }

                                        for (int x = 12; x < 16; x++)
                                        {
                                            finalGuid[x] = fourthHeader[x - 12];
                                        }
                                        //Guid Buildup End
                                        //Get The Original Guid
                                        m_pdbGuid = new Guid(finalGuid);

                                        finalHex = Utility.ByteArrayToHex(finalGuid);

                                        m_pdbVersion =
                                            finalHex.ToUpperInvariant() + hexAge.ToUpperInvariant();

                                        //Locate The Pdb Name Entry, it is a null terminated string.
                                        uint stringBeginLocation =
                                            debugDirectory->PointerToRawData + 24;

                                        byte stringLocator =
                                            *(p_Data + stringBeginLocation);

                                        System.Text.StringBuilder resultBuilder =
                                            new System.Text.StringBuilder();

                                        MemoryStream stringHolder = new MemoryStream();

                                        while (stringLocator != 0)
                                        {
                                            stringHolder.WriteByte(stringLocator);
                                            //resultBuilder.Append(Encoding.ASCII.GetString(new byte[]{stringLocator}));

                                            stringBeginLocation++;

                                            stringLocator = *(p_Data + stringBeginLocation);
                                        }
                                        ;

                                        // Buildup The String And Return It.
                                        // We assume always that it is ascii encoded.
                                        m_pdbFullName = Encoding.ASCII.GetString(stringHolder.ToArray());    //resultBuilder.ToString();


                                        return;
                                    }
                                }
                            }
                        }

                        dataSectionsOffset +=
                            sizeof(PESectionHeader);
                    }
                    throw new NoPdbSectionException();
                }
            }
        }
        public static unsafe List <string> GetDynamicImports(byte[] fileBytes, string arch)
        {
            // This function walks the PE header to get the offset of the Delay-Load Descriptor Table
            // (DLDT) and then resolves the imports' names
            List <string> dynamicModuleNames = new List <string>();

            fixed(byte *ptr_data = fileBytes)
            {
                // Initial validation
                UnsafeHelpers.IMAGE_DOS_HEADER *dos_header = (UnsafeHelpers.IMAGE_DOS_HEADER *)ptr_data;
                if (dos_header->e_magic != UnsafeHelpers.IMAGE_DOS_SIGNATURE)
                {
                    Console.WriteLine("[-] Magic bytes don't match");
                    return(dynamicModuleNames);
                }

                // Get the NT headers
                if (arch == "x64")
                {
                    IMAGE_NT_HEADERS64 *nt_header = (IMAGE_NT_HEADERS64 *)(ptr_data + dos_header->e_lfanew);
                    if (nt_header->Signature != IMAGE_NT_SIGNATURE)
                    {
                        Console.WriteLine("[-] NT Header signature mismatch");
                        return(dynamicModuleNames);
                    }

                    // Get the offset for the delay-load import tables
                    ulong *DataDirectory       = nt_header->OptionalHeader.DataDirectory;
                    IMAGE_DATA_DIRECTORY *dldt = (IMAGE_DATA_DIRECTORY *)(&nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT]);
                    uint dldtRVA = dldt->VirtualAddress;
                    if (dldtRVA == 0) // No delayed imports found
                    {
                        return(dynamicModuleNames);
                    }

                    Offset offsets = RvaToOffset(nt_header, null, dldtRVA, "DLDT");
                    uint   offset  = offsets.RawOffset + (dldtRVA - offsets.RVA);

                    // Iterate over the list of delay-loaded modules
                    IMAGE_DELAY_IMPORT_DESCRIPTOR *firstModule = (UnsafeHelpers.IMAGE_DELAY_IMPORT_DESCRIPTOR *)(ptr_data + offset);

                    while (firstModule->szName != 0)
                    {
                        Offset offsetToNames = RvaToOffset(nt_header, null, firstModule->szName, "szName");
                        uint   offset2       = offsetToNames.RawOffset + (firstModule->szName - offsetToNames.RVA);
                        dynamicModuleNames.Add(Marshal.PtrToStringAnsi((IntPtr)(ptr_data + offset2)));
                        firstModule = (UnsafeHelpers.IMAGE_DELAY_IMPORT_DESCRIPTOR *)((long)firstModule + (long)Marshal.SizeOf(typeof(UnsafeHelpers.IMAGE_DELAY_IMPORT_DESCRIPTOR)));
                    }
                }
                else // x86
                {
                    IMAGE_NT_HEADERS32 *nt_header = (IMAGE_NT_HEADERS32 *)(ptr_data + dos_header->e_lfanew);
                    if (nt_header->Signature != IMAGE_NT_SIGNATURE)
                    {
                        Console.WriteLine("[-] NT Header signature mismatch");
                        return(dynamicModuleNames);
                    }

                    // Get the offset for the delay-load import tables
                    ulong *DataDirectory       = nt_header->OptionalHeader.DataDirectory;
                    IMAGE_DATA_DIRECTORY *dldt = (IMAGE_DATA_DIRECTORY *)(&nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT]);
                    uint dldtRVA = dldt->VirtualAddress;
                    if (dldtRVA == 0) // No delayed imports found
                    {
                        return(dynamicModuleNames);
                    }

                    Offset offsets = RvaToOffset(null, nt_header, dldtRVA, "DLDT");
                    uint   offset  = offsets.RawOffset + (dldtRVA - offsets.RVA);

                    // Iterate over the list of delay-loaded modules
                    IMAGE_DELAY_IMPORT_DESCRIPTOR *firstModule = (IMAGE_DELAY_IMPORT_DESCRIPTOR *)(ptr_data + offset);

                    while (firstModule->szName != 0)
                    {
                        Offset offsetToNames = RvaToOffset(null, nt_header, firstModule->szName, "szName");
                        uint   offset2       = offsetToNames.RawOffset + (firstModule->szName - offsetToNames.RVA);
                        dynamicModuleNames.Add(Marshal.PtrToStringAnsi((IntPtr)(ptr_data + offset2)));
                        firstModule = (IMAGE_DELAY_IMPORT_DESCRIPTOR *)((long)firstModule + (long)Marshal.SizeOf(typeof(UnsafeHelpers.IMAGE_DELAY_IMPORT_DESCRIPTOR)));
                    }
                }

                return(dynamicModuleNames);
            }
        }
Exemple #11
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;
                }
            }
        }
Exemple #12
0
        public PEFile(FileStream Fin, int BufferLength)
        {
            this.fin          = Fin;
            this.BufferLength = BufferLength;
            this.bData        = ReadFile(fin, BufferLength);
            bool b64 = false;

            unsafe
            {
                fixed(byte *pData = this.bData)
                {
                    IMAGE_DOS_HEADER *  pIdh    = (IMAGE_DOS_HEADER *)pData;
                    IMAGE_NT_HEADERS32 *pInhs32 = (IMAGE_NT_HEADERS32 *)(pIdh->e_lfanew + pData);
                    IMAGE_NT_HEADERS64 *pInhs64 = (IMAGE_NT_HEADERS64 *)(pIdh->e_lfanew + pData);

                    if (pInhs32->FileHeader.SizeOfOptionalHeader > 0) // check for non object file
                    {
                        if (pInhs32->OptionalHeader.Magic == 0x10b)
                        {
                            // 32 Bit
                        }

                        if (pInhs32->OptionalHeader.Magic == 0x20b)
                        {
                            // 64 Bit
                            b64 = true;
                        }

                        if (pInhs32->OptionalHeader.CLRDataDirectory.Size > 0)
                        {
                            m_IsManaged = true;
                        }
                        else
                        {
                            m_IsManaged = false;
                        }

                        if ((this.bData.Length < 9192) && (pInhs32->OptionalHeader.BaseOfCode > 2048))
                        {
                            iEntryPoint = 2048;
                        }
                        else
                        {
                            if (b64)
                            {
                                iEntryPoint = pInhs64->OptionalHeader.BaseOfCode;
                            }
                            else
                            {
                                iEntryPoint = pInhs32->OptionalHeader.BaseOfCode;
                            }
                        }

                        m_BinImprint = viGetFullImprint_ByteArray(bData, iEntryPoint);

                        iNTHeaderOffset       = pIdh->e_lfanew;
                        iOptionalHeaderOffset = iNTHeaderOffset + 4 + (int)sizeof(IMAGE_FILE_HEADER);
                        iSectionOffset        = iOptionalHeaderOffset + (int)pInhs32->FileHeader.SizeOfOptionalHeader;
                        iOffset = iSectionOffset + (int)pData;

                        for (int i = 0; i < pInhs32->FileHeader.NumberOfSections; i++)
                        {
                            IMAGE_SECTION_HEADER *pIsh = (IMAGE_SECTION_HEADER *)(iOffset + (int)(sizeof(IMAGE_SECTION_HEADER) * i));
                            iBaseRVA = pIsh->PointerToRawData + (uint)pData;

                            if (MakeStringFromUTF8((byte *)&pIsh->Name) == ".rsrc")
                            {
                                if (pIsh->VirtualSize > 0)
                                {
                                    iImageSectionHeaderSize = pIsh->VirtualSize;
                                }
                                else
                                {
                                    iImageSectionHeaderSize = pIsh->SizeOfRawData;
                                }

                                if (b64)
                                {
                                    if (pInhs64->OptionalHeader.ResourceDataDirectory.VirtualAddress >= pIsh->VirtualAddress &&
                                        pInhs64->OptionalHeader.ResourceDataDirectory.VirtualAddress < pIsh->VirtualAddress + iImageSectionHeaderSize)
                                    {
                                        IMAGE_RESOURCE_DIRECTORY *      pIrd  = (IMAGE_RESOURCE_DIRECTORY *)(pIsh->PointerToRawData + (uint)pData);
                                        IMAGE_RESOURCE_DIRECTORY_ENTRY *pIrde = (IMAGE_RESOURCE_DIRECTORY_ENTRY *)(pIrd + 1);
                                        nEntries = (UInt16)(pIrd->NumberOfIdEntries + pIrd->NumberOfNamedEntries);

                                        for (int j = 0; j < nEntries; j++)
                                        {
                                            if (!processImageResourceDirectory(pIrd, pIrde, iBaseRVA, pIsh, pData))
                                            {
                                                throw new Exception("Error during resource directory parsing.");
                                            }
                                            pIrde++;
                                        }
                                    }
                                }
                                else
                                {
                                    if (pInhs32->OptionalHeader.ResourceDataDirectory.VirtualAddress >= pIsh->VirtualAddress &&
                                        pInhs32->OptionalHeader.ResourceDataDirectory.VirtualAddress < pIsh->VirtualAddress + iImageSectionHeaderSize)
                                    {
                                        IMAGE_RESOURCE_DIRECTORY *      pIrd  = (IMAGE_RESOURCE_DIRECTORY *)(pIsh->PointerToRawData + (uint)pData);
                                        IMAGE_RESOURCE_DIRECTORY_ENTRY *pIrde = (IMAGE_RESOURCE_DIRECTORY_ENTRY *)(pIrd + 1);
                                        nEntries = (UInt16)(pIrd->NumberOfIdEntries + pIrd->NumberOfNamedEntries);

                                        for (int j = 0; j < nEntries; j++)
                                        {
                                            if (!processImageResourceDirectory(pIrd, pIrde, iBaseRVA, pIsh, pData))
                                            {
                                                throw new Exception("Error during resource directory parsing.");
                                            }
                                            pIrde++;
                                        }
                                    }
                                }
                            }

                            if (iOffset >= iOptionalHeaderOffset + (int)sizeof(IMAGE_OPTIONAL_HEADER32) + 8 * 16 + (int)pData) // just for savety reasons
                            {
                                break;
                            }
                        }
                    }
                }
            }
        }