예제 #1
0
파일: Magic.cs 프로젝트: sbarisic/Hackery
        public static void Main()
        {
            if (!Native.GetModuleHandleEx(ModuleHandleFlags.UnchangedRefCount, "Inkjet.dll", out ThisModule))
            {
                ThisModule = IntPtr.Zero;
            }

            IntPtr        ExeHandle;
            List <string> ExportNames = new List <string>();

            if (Native.GetModuleHandleEx(ModuleHandleFlags.UnchangedRefCount, null, out ExeHandle))
            {
                IMAGE_DOS_HEADER *      DosHeader = (IMAGE_DOS_HEADER *)ExeHandle;
                IMAGE_NT_HEADERS *      Header    = (IMAGE_NT_HEADERS *)(ExeHandle + (int)DosHeader->LFaNew);
                IMAGE_EXPORT_DIRECTORY *Exports   = (IMAGE_EXPORT_DIRECTORY *)(ExeHandle +
                                                                               Header->OptionalHeader.ExportTable.VirtualAddress);

                IntPtr Names = ExeHandle + Exports->AddressOfNames;
                for (int i = 0; i < Exports->NumberOfNames; i++)
                {
                    string Name = Marshal.PtrToStringAnsi(ExeHandle + ((int *)Names)[i]);
                    if (Name.Trim().Length == 0)
                    {
                        continue;
                    }
                    ExportNames.Add(Name);
                }
            }

            File.WriteAllText("E:\\Projects\\Hackery\\bin\\HAAX.txt", string.Join("\n", ExportNames));

            Process Cur = Process.GetCurrentProcess();

            MessageBox.Show("Magic!", string.Format("{0} ({1})", Cur.ProcessName, Cur.Id));
        }
예제 #2
0
        /// <summary>
        /// Parses the given buffer for the header of a PEFile. If it can be parsed correctly,
        /// a new PEHeader object is constructed from the buffer and returned. Otherwise, null
        /// is returned.
        /// </summary>
        internal static PEHeader FromBuffer(PEBuffer buffer, bool virt)
        {
            byte *            ptr    = buffer.Fetch(0, 0x300);
            IMAGE_DOS_HEADER *tmpDos = (IMAGE_DOS_HEADER *)ptr;
            int needed = tmpDos->e_lfanew + sizeof(IMAGE_NT_HEADERS);

            if (buffer.Length < needed)
            {
                ptr = buffer.Fetch(0, needed);

                if (buffer.Length < needed)
                {
                    return(null);
                }

                tmpDos = (IMAGE_DOS_HEADER *)ptr;
            }

            IMAGE_NT_HEADERS *tmpNt = (IMAGE_NT_HEADERS *)((byte *)tmpDos + tmpDos->e_lfanew);

            needed += tmpNt->FileHeader.SizeOfOptionalHeader + sizeof(IMAGE_SECTION_HEADER) * tmpNt->FileHeader.NumberOfSections;

            if (buffer.Length < needed)
            {
                ptr = buffer.Fetch(0, needed);
                if (buffer.Length < needed)
                {
                    return(null);
                }
            }

            return(new PEHeader(buffer, virt));
        }
예제 #3
0
        private unsafe PEHeader(string path)
        {
            var data = new byte[4096];

            using (var stream = File.OpenRead(path))
                stream.Read(data, 0, data.Length);

            fixed(byte *pData = data)
            {
                IMAGE_DOS_HEADER *  idh  = (IMAGE_DOS_HEADER *)pData;
                IMAGE_NT_HEADERS32 *inhs = (IMAGE_NT_HEADERS32 *)(pData + idh->e_lfanew);

                // PE32 (0x10b) or PE32+ (0x20b)
                if (inhs->OptionalHeader.Magic == 0x20b)
                {
                    m_is64Bit = true;
                    if (((IMAGE_NT_HEADERS64 *)inhs)->OptionalHeader.DataDirectory.Size > 0)
                    {
                        m_isManaged = true;
                    }
                }
                else
                {
                    if (inhs->OptionalHeader.DataDirectory.Size > 0)
                    {
                        m_isManaged = true;
                    }
                }
            }
        }
예제 #4
0
        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);
                }
            }
        }
예제 #5
0
파일: PEParser.cs 프로젝트: ca1e/PEParser
        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);
        }
예제 #6
0
            private void ValidateRawDll(Image image)
            {
                IMAGE_DOS_HEADER *dosHeader = (IMAGE_DOS_HEADER *)image.BasePtr;

                if (image.Size < sizeof(IMAGE_DOS_HEADER))
                {
                    throw new LoadFailedException("Bad or unknown DLL format (missing DOS header).");
                }

                if (dosHeader->e_magic_byte[0] != 'M' || dosHeader->e_magic_byte[1] != 'Z')
                {
                    throw new LoadFailedException("Bad or unknown DLL format (missing DOS header 'MZ' signature).");
                }

                if (dosHeader->e_lfanew + sizeof(IMAGE_NT_HEADERS32) > image.Size)
                {
                    throw new LoadFailedException("Bad or unknown DLL format (missing NT header data).");
                }

                IMAGE_NT_HEADERS32 *headers = image.Headers32;

                if (headers->Signature[0] != 'P' || headers->Signature[1] != 'E' ||
                    headers->Signature[2] != '\0' || headers->Signature[3] != '\0')
                {
                    throw new LoadFailedException("Bad or unknown DLL format (missing NT header 'PE' signature).");
                }

                switch (headers->FileHeader.Machine)
                {
                case MachineType.I386:
                    if (Environment.Is64BitProcess)
                    {
                        throw new LoadFailedException("The DLL is compiled for 32-bit x86, but the current process is not a 32-bit process.");
                    }
                    break;

                case MachineType.x64:
                    if (!Environment.Is64BitProcess)
                    {
                        throw new LoadFailedException("The DLL is compiled for 64-bit x64, but the current process is not a 64-bit process.");
                    }
                    break;

                default:
                    throw new LoadFailedException("The DLL is compiled for an unsupported processor architecture.");
                }

                if ((headers->OptionalHeader.SectionAlignment & 1) != 0)
                {
                    throw new LoadFailedException("This DLL has an unsupported section alignment of " + headers->OptionalHeader.SectionAlignment);
                }

                if (headers->OptionalHeader.SizeOfHeaders > image.Size)
                {
                    throw new LoadFailedException("Bad or unknown DLL format (damaged NT header data).");
                }
            }
예제 #7
0
        private static unsafe void WriteDosHeader(byte[] buffer, uint pos, IMAGE_DOS_HEADER header)
        {
            fixed(byte *p = buffer)
            {
                IMAGE_DOS_HEADER *ptr = (IMAGE_DOS_HEADER *)(p + pos);

                *ptr = header;
            }
        }
예제 #8
0
    static unsafe USysCall64()
    {
        UNICODE_STRING szNtdll  = new UNICODE_STRING("ntdll");
        UIntPtr        ptrNtdll = UIntPtr.Zero;

        long ntstatus = LdrGetDllHandle(IntPtr.Zero, IntPtr.Zero, ref szNtdll, ref ptrNtdll);

        if (ntstatus != 0)
        {
            Debugger.Break();
        }

        byte *                   lpNtdll   = (byte *)ptrNtdll;
        IMAGE_DOS_HEADER *       piDH      = (IMAGE_DOS_HEADER *)lpNtdll;
        IMAGE_OPTIONAL_HEADER64 *piOH      = (IMAGE_OPTIONAL_HEADER64 *)(lpNtdll + piDH->e_lfanew + 0x18);
        IMAGE_EXPORT_DIRECTORY * exportDir = (IMAGE_EXPORT_DIRECTORY *)(lpNtdll + piOH->ExportTable.VirtualAddress);

        uint *  names     = (uint *)(lpNtdll + exportDir->AddressOfNames);
        uint *  functions = (uint *)(lpNtdll + exportDir->AddressOfFunctions);
        ushort *ordinals  = (ushort *)(lpNtdll + exportDir->AddressOfNameOrdinals);

        var listOfNames = new List <string>();

        var dictOfZwFunctions = new Dictionary <string, ulong>();

        for (int i = 0; i < exportDir->NumberOfNames; i++)
        {
            var name = Marshal.PtrToStringAnsi(new IntPtr(lpNtdll + names[i]));

            if (!name.StartsWith("Zw"))
            {
                continue;
            }

            var fnAddr = new UIntPtr(lpNtdll + functions[ordinals[i]]);

            dictOfZwFunctions.Add(name, fnAddr.ToUInt64());
        }

        var sortedByAddr = dictOfZwFunctions
                           .OrderBy(x => x.Value)
                           .ToDictionary(x => "Nt" + x.Key.Substring(2, x.Key.Length - 2), x => x.Value);

        var sysCallLookup = new Dictionary <string, uint>();

        uint sysNo = 0;

        foreach (var entry in sortedByAddr)
        {
            sysCallLookup.Add(entry.Key, sysNo);
            sysNo++;
        }

        SysCallTable = sysCallLookup;
    }
예제 #9
0
        private static bool GetLibraryInfo(IntPtr handle, out DynLibInfo lib)
        {
            lib = new DynLibInfo();
            if (handle == IntPtr.Zero)
            {
                return(false);
            }


            MEMORY_BASIC_INFORMATION info;

            if (VirtualQuery(handle, out info, Marshal.SizeOf <MEMORY_BASIC_INFORMATION>()) == 0)
            {
                return(false);
            }

            //uintptr_t baseAddr = reinterpret_cast<uintptr_t>(info.AllocationBase);

            IMAGE_DOS_HEADER *     dos  = (IMAGE_DOS_HEADER *)info.AllocationBase;
            IMAGE_NT_HEADERS *     pe   = (IMAGE_NT_HEADERS *)(info.AllocationBase + dos->e_lfanew);
            IMAGE_FILE_HEADER *    file = &pe->FileHeader;
            IMAGE_OPTIONAL_HEADER *opt  = &pe->OptionalHeader;

            if (dos->e_magic != IMAGE_DOS_SIGNATURE)
            {
                return(false);
            }

            if (pe->Signature != IMAGE_NT_SIGNATURE)
            {
                return(false);
            }

            if (opt->Magic != MagicType.IMAGE_NT_OPTIONAL_HDR32_MAGIC)
            {
                return(false);
            }

            if (file->Machine != 0x014c)// Intel 386.
            {
                return(false);
            }

            if ((file->Characteristics & 0x2000) == 0)// File is a DLL.
            {
                return(false);
            }

            lib.memorySize  = opt->SizeOfImage;
            lib.baseAddress = info.AllocationBase;
            return(true);
        }
예제 #10
0
        private static unsafe IMAGE_DOS_HEADER ReadDosHeader(byte[] buffer, uint pos)
        {
            IMAGE_DOS_HEADER dosHeader = new IMAGE_DOS_HEADER();

            fixed(byte *p = buffer)
            {
                IMAGE_DOS_HEADER *ptr = (IMAGE_DOS_HEADER *)(p + pos);

                dosHeader = *ptr;
            }

            return(dosHeader);
        }
예제 #11
0
 public ExportResolver(ProcessModule module)
 {
     lib = (IMAGE_DOS_HEADER *)module.BaseAddress;
     if (lib->e_magic != IMAGE_DOS_SIGNATURE)
     {
         throw new Exception("Invalid IMAGE_DOS_HEADER signature");
     }
     header = (IMAGE_NT_HEADERS *)((byte *)lib + lib->e_lfanew);
     if (header->Signature != IMAGE_NT_SIGNATURE)
     {
         throw new Exception("Invalid IMAGE_NT_HEADERS signature");
     }
     if (header->OptionalHeader.NumberOfRvaAndSizes == 0)
     {
         throw new Exception("Invalid NumberOfRvaAndSizes");
     }
     exports = (IMAGE_EXPORT_DIRECTORY *)((byte *)lib + header->OptionalHeader.ExportTable.VirtualAddress);
 }
        private static bool Is32Bit(string filePath)
        {
            filePath = Environment.ExpandEnvironmentVariables(filePath);

            // Read the first
            byte[] data = new byte[4096];

            FileInfo fileInfo = new FileInfo(filePath);

            using (FileStream fileStream = fileInfo.Open(FileMode.Open, FileAccess.Read)) {
                fileStream.Read(data, 0, 4096);

                fileStream.Flush();
            }

            unsafe
            {
                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;

                    // Now that we have the DOS header, we can get the offset
                    // (e_lfanew) add it to the original address (p_Data) and
                    // squeeze those bytes into a IMAGE_NT_HEADERS32 structure
                    IMAGE_NT_HEADERS32 *inhs = (IMAGE_NT_HEADERS32 *)(idh->e_lfanew + p_Data);

                    // Use the OptionalHeader.Magic. It tells you whether
                    // the assembly is PE32 (0x10b) or PE32+ (0x20b).
                    // PE32+ just means 64-bit. So, instead of checking if it is
                    // an X64 or Itanium, just check if it's a PE32+.
                    if (inhs->OptionalHeader.Magic == 0x20b)
                    {
                        // 64 bit assembly
                        return(false);
                    }
                    else
                    {
                        // 32 bit assembly
                        return(true);
                    }
                }
            }
        }
예제 #13
0
파일: Dll.cs 프로젝트: WildGenie/Libraria
        public static Symbol[] GetExports(IntPtr Handle)
        {
            List <Symbol> Exports = new List <Symbol>();

            IMAGE_DOS_HEADER *      DOS        = (IMAGE_DOS_HEADER *)Handle;
            IMAGE_NT_HEADERS *      NT         = (IMAGE_NT_HEADERS *)((byte *)DOS + DOS->LFaNew);
            IMAGE_OPTIONAL_HEADER * Optional   = &NT->OptionalHeader;
            IMAGE_EXPORT_DIRECTORY *ExportsDir = (IMAGE_EXPORT_DIRECTORY *)((byte *)Handle + Optional->ExportTable.VirtualAddress);

            uint *AddrOfNames = (uint *)((byte *)Handle + ExportsDir->AddressOfNames);
            uint *AddrOfFuncs = (uint *)((byte *)Handle + ExportsDir->AddressOfNames);

            for (int j = 0; j < ExportsDir->NumberOfNames; j++)
            {
                string Name = Marshal.PtrToStringAnsi((IntPtr)((uint)Handle + AddrOfNames[j]));
                long   Func = AddrOfFuncs[j];
                Exports.Add(new Symbol(Name, (ulong)Func, 0));
            }

            return(Exports.ToArray());
        }
예제 #14
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;
                }
            }
        }
예제 #15
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;
                            }
                        }
                    }
                }
            }
        }
예제 #16
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();
                }
            }
        }
예제 #17
0
        /// <summary>
        /// 加载dLL
        /// </summary>
        /// <param name="pUnmanagedBuffer"></param>
        /// <param name="iBufferLength"></param>
        /// <returns></returns>
        private unsafe Boolean LoadDLLFromMemory(IntPtr pUnmanagedBuffer, Int32 iBufferLength)
        {
            try
            {
                if (iBufferLength < sizeof(IMAGE_DOS_HEADER))
                {
                    throw new Exception("Data is too short");
                }
                IMAGE_DOS_HEADER *pDosHeader = (IMAGE_DOS_HEADER *)pUnmanagedBuffer;
                if (pDosHeader->e_magic != 0x5A4D)
                {
                    throw new Exception("DOS file format error");
                }

                if (iBufferLength < pDosHeader->e_lfanew + sizeof(IMAGE_NT_HEADERS))
                {
                    throw new Exception("Data is short");
                }
                IMAGE_NT_HEADERS *pPEHeader = (IMAGE_NT_HEADERS *)(pUnmanagedBuffer + pDosHeader->e_lfanew);
                if (pPEHeader->Signature != Win32API.IMAGE_NT_SIGNATURE)
                {
                    throw new Exception("windows file Signature error");
                }
                if ((pPEHeader->FileHeader.Characteristics & Win32API.IMAGE_FILE_DLL) != Win32API.IMAGE_FILE_DLL)
                {
                    throw new Exception("Dll Not dynamic library");
                }

                IMAGE_SECTION_HEADER *pSectionHeader = (IMAGE_SECTION_HEADER *)(pUnmanagedBuffer + pDosHeader->e_lfanew + sizeof(IMAGE_NT_HEADERS));
                for (Int32 i = 0; i < pPEHeader->FileHeader.NumberOfSections; i++)
                {
                    if (pSectionHeader[i].PointerToRawData + pSectionHeader[i].SizeOfRawData > iBufferLength)
                    {
                        throw new Exception("Section data error");
                    }
                }
                //计算空间
                this.mModuleSize = this.CalcTotalImageSize(pPEHeader, pSectionHeader);
                if (this.mModuleSize == 0 || this.mModuleSize > iBufferLength * 10)
                {
                    throw new Exception("unknown error");
                }
#if _WIN64
                this.mModuleHandle = Win32API.VirtualAlloc((IntPtr)((Int64)pPEHeader->OptionalHeader.ImageBase), this.mModuleSize, Win32API.MEM_COMMIT | Win32API.MEM_RESERVE, Win32API.PAGE_EXECUTE_READWRITE);
#else
                this.mModuleHandle = Win32API.VirtualAlloc((IntPtr)((Int32)pPEHeader->OptionalHeader.ImageBase), this.mModuleSize, Win32API.MEM_COMMIT | Win32API.MEM_RESERVE, Win32API.PAGE_EXECUTE_READWRITE);
#endif
                if (this.mModuleHandle == IntPtr.Zero)
                {
                    Int32 iLastError = Marshal.GetLastWin32Error();
                    this.mModuleHandle = Win32API.VirtualAlloc(IntPtr.Zero, this.mModuleSize, Win32API.MEM_COMMIT | Win32API.MEM_RESERVE, Win32API.PAGE_EXECUTE_READWRITE);
                }

                if (this.mModuleHandle == IntPtr.Zero)
                {
                    throw new Exception("run out of memory?");
                }

                this.CopyDllDatas(pUnmanagedBuffer, pPEHeader, pSectionHeader);
                pDosHeader     = (IMAGE_DOS_HEADER *)this.mModuleHandle;
                pPEHeader      = (IMAGE_NT_HEADERS *)(this.mModuleHandle + pDosHeader->e_lfanew);
                pSectionHeader = (IMAGE_SECTION_HEADER *)(this.mModuleHandle + pDosHeader->e_lfanew + sizeof(IMAGE_NT_HEADERS));
                if (pDosHeader->e_magic != 0x5A4D)
                {
                    throw new Exception("DOS file format error");
                }
                if (iBufferLength < pDosHeader->e_lfanew + sizeof(IMAGE_NT_HEADERS))
                {
                    throw new Exception("DOS file header data error");
                }
                if (pPEHeader->Signature != Win32API.IMAGE_NT_SIGNATURE)
                {
                    throw new Exception("windows file Signature error");
                }
                if ((pPEHeader->FileHeader.Characteristics & Win32API.IMAGE_FILE_DLL) != Win32API.IMAGE_FILE_DLL)
                {
                    throw new Exception("Dll Not dynamic library");
                }
                for (Int32 i = 0; i < pPEHeader->FileHeader.NumberOfSections; i++)
                {
                    if (pSectionHeader[i].PointerToRawData + pSectionHeader[i].SizeOfRawData > iBufferLength)
                    {
                        throw new Exception("Section data error");
                    }
                }

                //重定位
                var baseRelocDirEntry = pPEHeader->OptionalHeader.GetDirectory(IMAGE_DIRECTORY_ENTRY.IMAGE_DIRECTORY_ENTRY_BASERELOC);
                if (baseRelocDirEntry.VirtualAddress > 0 && baseRelocDirEntry.Size > 0)
                {
                    this.ReLocation(pPEHeader);
                }
                this.FillImportTable(pPEHeader);
#if _WIN64
                this.mDllMain = (DllMainHandle)Marshal.GetDelegateForFunctionPointer((IntPtr)((Int64)this.mModuleHandle + (Int64)pPEHeader->OptionalHeader.AddressOfEntryPoint), typeof(DllMainHandle));
#else
                this.mDllMain = (DllMainHandle)Marshal.GetDelegateForFunctionPointer(this.mModuleHandle + (Int32)pPEHeader->OptionalHeader.AddressOfEntryPoint, typeof(DllMainHandle));
#endif
                return(this.mDllMain.Invoke(this.mModuleHandle, Win32API.DLL_PROCESS_ATTACH, IntPtr.Zero));
            }
            catch (Exception ex)
            {
                throw (ex);
            }
        }
예제 #18
0
        /// <summary>
        /// 获取API函数地址
        /// </summary>
        /// <param name="sProcName"></param>
        /// <returns></returns>
        private unsafe IntPtr GetProcAddress(String sProcName)
        {
            if (this.mModuleHandle == IntPtr.Zero)
            {
                return(IntPtr.Zero);
            }

            if (String.IsNullOrEmpty(sProcName))
            {
                return(IntPtr.Zero);
            }

            IMAGE_DOS_HEADER *pDosHeader = (IMAGE_DOS_HEADER *)this.mModuleHandle;
            IMAGE_NT_HEADERS *pPEHeader  = (IMAGE_NT_HEADERS *)(this.mModuleHandle + pDosHeader->e_lfanew);
            var exportDirectoryEntry     = pPEHeader->OptionalHeader.GetDirectory(IMAGE_DIRECTORY_ENTRY.IMAGE_DIRECTORY_ENTRY_EXPORT);
            var iOffsetStart             = exportDirectoryEntry.VirtualAddress;
            var iSize = exportDirectoryEntry.Size;

            if (iOffsetStart == 0 || iSize == 0)
            {
                return(IntPtr.Zero);
            }

#if _WIN64
            IMAGE_EXPORT_DIRECTORY *pExportDirectory = (IMAGE_EXPORT_DIRECTORY *)((IntPtr)((Int64)this.mModuleHandle + (Int64)iOffsetStart));
            UInt32 *pAddressOfFunctions    = (UInt32 *)((IntPtr)((Int64)this.mModuleHandle + (Int64)pExportDirectory->AddressOfFunctions));
            UInt16 *pAddressOfNameOrdinals = (UInt16 *)((IntPtr)((Int64)this.mModuleHandle + (Int64)pExportDirectory->AddressOfNameOrdinals));
            UInt32 *pAddressOfNames        = (UInt32 *)((IntPtr)((Int64)this.mModuleHandle + (Int64)pExportDirectory->AddressOfNames));
#else
            IMAGE_EXPORT_DIRECTORY *pExportDirectory = (IMAGE_EXPORT_DIRECTORY *)(this.mModuleHandle + (Int32)iOffsetStart);
            UInt32 *pAddressOfFunctions    = (UInt32 *)(this.mModuleHandle + (Int32)pExportDirectory->AddressOfFunctions);
            UInt16 *pAddressOfNameOrdinals = (UInt16 *)(this.mModuleHandle + (Int32)pExportDirectory->AddressOfNameOrdinals);
            UInt32 *pAddressOfNames        = (UInt32 *)(this.mModuleHandle + (Int32)pExportDirectory->AddressOfNames);
#endif
            UInt16 iOrdinal = 0;
            if (UInt16.TryParse(sProcName, out iOrdinal))
            {
                if (iOrdinal >= pExportDirectory->Base)
                {
                    iOrdinal = (UInt16)(iOrdinal - pExportDirectory->Base);
                    if (iOrdinal >= 0 && iOrdinal < pExportDirectory->NumberOfFunctions)
                    {
                        var iFunctionOffset = pAddressOfFunctions[iOrdinal];
                        if (iFunctionOffset > iOffsetStart && iFunctionOffset < (iOffsetStart + iSize)) // maybe Export Forwarding
                        {
                            return(IntPtr.Zero);
                        }
                        else
                        {
#if _WIN64
                            return((IntPtr)((Int64)this.mModuleHandle + iFunctionOffset));
#else
                            return((IntPtr)((Int32)this.mModuleHandle + iFunctionOffset));
#endif
                        }
                    }
                }
            }
            else
            {
                for (Int32 i = 0; i < pExportDirectory->NumberOfNames; i++)
                {
#if _WIN64
                    var sFuncName = Marshal.PtrToStringAnsi((IntPtr)((Int64)this.mModuleHandle + (Int64)pAddressOfNames[i]));
#else
                    var sFuncName = Marshal.PtrToStringAnsi(this.mModuleHandle + (Int32)pAddressOfNames[i]);
#endif
                    if (sProcName.Equals(sFuncName))
                    {
                        iOrdinal = pAddressOfNameOrdinals[i];
                        if (iOrdinal >= 0 && iOrdinal < pExportDirectory->NumberOfFunctions)
                        {
                            var iFunctionOffset = pAddressOfFunctions[iOrdinal];
                            if (iFunctionOffset > iOffsetStart && iFunctionOffset < (iOffsetStart + iSize)) // maybe Export Forwarding
                            {
                                return(IntPtr.Zero);
                            }
                            else
                            {
#if _WIN64
                                return((IntPtr)((Int64)this.mModuleHandle + iFunctionOffset));
#else
                                return((IntPtr)((Int32)this.mModuleHandle + iFunctionOffset));
#endif
                            }
                        }
                    }
                }
            }
            return(IntPtr.Zero);
        }