示例#1
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));
        }
示例#2
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));
        }
示例#3
0
        private static unsafe void WriteNTHeader(byte[] buffer, uint pos, IMAGE_NT_HEADERS header)
        {
            fixed(byte *p = buffer)
            {
                IMAGE_NT_HEADERS *ptr = (IMAGE_NT_HEADERS *)(p + pos);

                *ptr = header;
            }
        }
示例#4
0
        /// <summary>
        /// 重定位表的处理
        /// </summary>
        /// <param name="pPEHeader"></param>
        private unsafe void ReLocation(IMAGE_NT_HEADERS *pPEHeader)
        {
#if _WIN64
            Int64 iDelta = (Int64)((Int64)this.mModuleHandle - (Int64)pPEHeader->OptionalHeader.ImageBase);
#else
            Int32 iDelta = (Int32)this.mModuleHandle - (Int32)pPEHeader->OptionalHeader.ImageBase;
#endif
            if (iDelta == 0)
            {
                return;
            }

#if _WIN64
            IMAGE_BASE_RELOCATION *pRelocation = (IMAGE_BASE_RELOCATION *)((IntPtr)((Int64)this.mModuleHandle +
                                                                                    (Int64)pPEHeader->OptionalHeader.GetDirectory(IMAGE_DIRECTORY_ENTRY.IMAGE_DIRECTORY_ENTRY_BASERELOC).VirtualAddress));
            while (pRelocation->VirtualAddress > 0 && pRelocation->SizeOfBlock > 0)
            {
                UInt16 *pLocData       = (UInt16 *)((IntPtr)pRelocation + sizeof(IMAGE_BASE_RELOCATION));
                var     iNumberOfReloc = (pRelocation->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / 2;
                for (Int32 i = 0; i < iNumberOfReloc; i++)
                {
                    if ((pLocData[i] & 0xFFFF) / 0x1000 == Win32API.IMAGE_REL_BASED_HIGHLOW)
                    {
                        UInt32 *lpPoint  = (UInt32 *)((IntPtr)((Int64)this.mModuleHandle + (Int64)pRelocation->VirtualAddress + (pLocData[i] & 0xFFF)));
                        *       lpPoint += (UInt32)iDelta;
                    }
                    else if ((pLocData[i] & 0xFFFF) / 0x1000 == Win32API.IMAGE_REL_BASED_DIR64)
                    {
                        UInt64 *lpPoint  = (UInt64 *)((IntPtr)((Int64)this.mModuleHandle + (Int64)pRelocation->VirtualAddress + (pLocData[i] & 0xFFF)));
                        *       lpPoint += (UInt64)iDelta;
                    }
                }
                pRelocation = (IMAGE_BASE_RELOCATION *)((IntPtr)((Int64)((IntPtr)pRelocation) + (Int64)pRelocation->SizeOfBlock));
            }
#else
            IMAGE_BASE_RELOCATION *pRelocation = (IMAGE_BASE_RELOCATION *)(this.mModuleHandle +
                                                                           (Int32)pPEHeader->OptionalHeader.GetDirectory(IMAGE_DIRECTORY_ENTRY.IMAGE_DIRECTORY_ENTRY_BASERELOC).VirtualAddress);
            while (pRelocation->VirtualAddress > 0 && pRelocation->SizeOfBlock > 0)
            {
                UInt16 *pLocData       = (UInt16 *)((IntPtr)pRelocation + sizeof(IMAGE_BASE_RELOCATION));
                var     iNumberOfReloc = (pRelocation->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / 2;
                for (Int32 i = 0; i < iNumberOfReloc; i++)
                {
                    if ((pLocData[i] & 0xFFFF) / 0x1000 == Win32API.IMAGE_REL_BASED_HIGHLOW)
                    {
                        UInt32 *lpPoint  = (UInt32 *)(this.mModuleHandle + (Int32)pRelocation->VirtualAddress + (pLocData[i] & 0xFFF));
                        *       lpPoint += (UInt32)iDelta;
                    }
                }
                pRelocation = (IMAGE_BASE_RELOCATION *)((IntPtr)pRelocation + (Int32)pRelocation->SizeOfBlock);
            }
#endif
        }
示例#5
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);
        }
示例#6
0
        private static unsafe IMAGE_NT_HEADERS ReadNTHeader(byte[] buffer, uint pos)
        {
            IMAGE_NT_HEADERS dosHeader = new IMAGE_NT_HEADERS();

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

                dosHeader = *ptr;
            }

            return(dosHeader);
        }
示例#7
0
        /// <summary>
        /// 拷贝区段数据到内存
        /// </summary>
        /// <param name="pUnmanagedBuffer"></param>
        /// <param name="pPEHeader"></param>
        /// <param name="pSectionHeader"></param>
        private unsafe void CopyDllDatas(IntPtr pUnmanagedBuffer, IMAGE_NT_HEADERS *pPEHeader, IMAGE_SECTION_HEADER *pSectionHeader)
        {
            Win32API.CopyMemory(this.mModuleHandle, pUnmanagedBuffer, pPEHeader->OptionalHeader.SizeOfHeaders); // 复制(DOS头+DOS STUB) + PE头 + SECTION TABLE

            // 复制每一个SECTION
            for (Int32 i = 0; i < pPEHeader->FileHeader.NumberOfSections; i++)
            {
                if (pSectionHeader[i].VirtualAddress > 0 && pSectionHeader[i].SizeOfRawData > 0)
                {
                    var lpSection = this.mModuleHandle + (Int32)pSectionHeader[i].VirtualAddress;
                    Win32API.CopyMemory(lpSection, pUnmanagedBuffer + (Int32)pSectionHeader[i].PointerToRawData, pSectionHeader[i].SizeOfRawData);
                }
            }
        }
示例#8
0
        /// <summary>
        /// 计算要申请的内存空间大小
        /// </summary>
        /// <param name="pPEHeader"></param>
        /// <param name="pSectionHeader"></param>
        /// <returns></returns>
        private unsafe UInt32 CalcTotalImageSize(IMAGE_NT_HEADERS *pPEHeader, IMAGE_SECTION_HEADER *pSectionHeader)
        {
            var iAlign = pPEHeader->OptionalHeader.SectionAlignment;
            var iSize  = this.GetAlignedSize(pPEHeader->OptionalHeader.SizeOfHeaders, iAlign);

            for (Int32 i = 0; i < pPEHeader->FileHeader.NumberOfSections; i++)
            {
                var iCodeSize    = pSectionHeader[i].VirtualSize;   // 该区块表对应的区块加载到内存后的大小,这是区块的数据在没有进行SectionAlignment对齐处理前的实际大小
                var iLoadSize    = pSectionHeader[i].SizeOfRawData; // 该区块在文件中所占的大小,该字段是已经被FileAlignment对齐处理过的长度。
                var iMaxSize     = iLoadSize > iCodeSize ? iLoadSize : iCodeSize;
                var iSectionSize = this.GetAlignedSize((pSectionHeader[i].VirtualAddress + iMaxSize), iAlign);
                if (iSize < iSectionSize)
                {
                    iSize = iSectionSize;
                }
            }
            return(iSize);
        }
 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);
 }
        static void CopySections(byte *data, IMAGE_NT_HEADERS *old_headers, MEMORYMODULE *module)
        {
            uint   i, size;
            IntPtr codeBase1 = module->codeBase;

#if AMD64
            long codeBaseAddr = (long)codeBase1.ToInt64();
#else
            uint codeBaseAddr = (uint)codeBase1.ToInt64();
#endif
            IntPtr dest;
            IMAGE_SECTION_HEADER *section = IMAGE_FIRST_SECTION(module->headers);
            for (i = 0; i < module->headers->FileHeader.NumberOfSections; i++, section++)
            {
                if (section->SizeOfRawData == 0)
                {
                    // section doesn't contain data in the dll itself, but may define
                    // uninitialized data
                    size = old_headers->OptionalHeader.SectionAlignment;
                    if (size > 0)
                    {
                        dest = VirtualAlloc(new IntPtr(codeBaseAddr + section->VirtualAddress), size, AllocationType.COMMIT, MemoryProtection.READWRITE);// MEM_COMMIT, PAGE_READWRITE);

                        //section->PhysicalAddress = dest;
                        memset(dest, 0, new UIntPtr(size));
                        section->VirtualSize = (uint)(dest.ToInt64() - codeBase1.ToInt64());
                    }

                    // section is empty
                    continue;
                }

                // commit memory block and copy data from dll
                dest = VirtualAlloc(new IntPtr(codeBaseAddr + section->VirtualAddress),
                                    section->SizeOfRawData,
                                    AllocationType.COMMIT, MemoryProtection.READWRITE);

                memcpy((byte *)dest.ToPointer(),
                       (byte *)(data + section->PointerToRawData),
                       new UIntPtr(section->SizeOfRawData));
                section->VirtualSize = (uint)(dest.ToInt64() - codeBase1.ToInt64());
            }
        }
示例#11
0
        /// <summary>
        /// Loads a unmanged (native) DLL in the memory.
        /// </summary>
        /// <param name="data">Dll as a byte array</param>
        public MemoryModule(byte[] data)
        {
            if (data == null)
            {
                throw new ArgumentNullException("data");
            }

            _headers     = null;
            _codeBase    = null;
            _pageSize    = 0;
            _modules     = new List <HCoustomMudule>();
            _initialized = false;
            _exeEntry    = null;
            _dllEntry    = null;

            Disposed     = false;
            _isRelocated = false;

            MemoryLoadLibrary(data);
        }
示例#12
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());
        }
示例#13
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);
            }
        }
示例#14
0
        private void MemoryLoadLibrary(byte[] data)
        {
            IMAGE_DOS_HEADER *    dosHeader;
            IMAGE_NT_HEADERS *    oldHeader;
            IMAGE_SECTION_HEADER *section;
            SYSTEM_INFO           systemInfo;
            void *   dllEntryPtr;
            void *   exeEntryPtr;
            byte *   headers, dataPtr, code;
            SizeT    optionalSectionSize;
            SizeT    lastSectionEnd = 0;
            SizeT    alignedImageSize;
            PtrDiffT locationDelta;

            _dataHandle = GCHandle.Alloc(data, GCHandleType.Pinned);
            if (!_dataHandle.IsAllocated)
            {
                throw new NativeDllLoadException("Can't allocate memory.");
            }

            dataPtr = (byte *)_dataHandle.AddrOfPinnedObject();

            dosHeader = (IMAGE_DOS_HEADER *)dataPtr;
            if (dosHeader->e_magic != Win.IMAGE_DOS_SIGNATURE)
            {
                throw new BadImageFormatException("Not a valid executable file.");
            }

            oldHeader = (IMAGE_NT_HEADERS *)(dataPtr + dosHeader->e_lfanew);
            if (oldHeader->Signature != Win.IMAGE_NT_SIGNATURE)
            {
                throw new BadImageFormatException("Not a valid PE file.");
            }

            if (oldHeader->FileHeader.Machine != GetMachineType())
            {
                throw new BadImageFormatException("Machine type doesn't fit. (i386 vs. AMD64)");
            }

            if ((oldHeader->OptionalHeader.SectionAlignment & 1) > 0)
            {
                throw new BadImageFormatException("Wrong section alignment");
            }

            section             = Win.IMAGE_FIRST_SECTION(oldHeader);
            optionalSectionSize = oldHeader->OptionalHeader.SectionAlignment;
            for (int i = 0; i < oldHeader->FileHeader.NumberOfSections; i++, section++)
            {
                SizeT endOfSection;
                if (section->SizeOfRawData == 0) // Section without data in the DLL
                {
                    endOfSection = section->VirtualAddress + optionalSectionSize;
                }
                else
                {
                    endOfSection = section->VirtualAddress + section->SizeOfRawData;
                }

                if (endOfSection > lastSectionEnd)
                {
                    lastSectionEnd = endOfSection;
                }
            }

            Win.GetNativeSystemInfo(&systemInfo);
            alignedImageSize = AlignValueUp(oldHeader->OptionalHeader.SizeOfImage, systemInfo.dwPageSize);
            if (alignedImageSize != AlignValueUp(lastSectionEnd, systemInfo.dwPageSize))
            {
                throw new BadImageFormatException("Wrong section alignment.");
            }

            code = (byte *)Win.VirtualAlloc(
                (void *)(oldHeader->OptionalHeader.ImageBase),
                oldHeader->OptionalHeader.SizeOfImage,
                AllocationType.RESERVE | AllocationType.COMMIT,
                MemoryProtection.READWRITE);

            if (code == null)
            {
                code = (byte *)Win.VirtualAlloc(
                    null,
                    oldHeader->OptionalHeader.SizeOfImage,
                    AllocationType.RESERVE | AllocationType.COMMIT,
                    MemoryProtection.READWRITE);
            }

            if (code == null)
            {
                throw new NativeDllLoadException("Out of Memory");
            }

#if WIN64
            while ((((ulong)code) >> 32) < (((ulong)(code + alignedImageSize)) >> 32))
            {
                _blockedMemory.Add((IntPtr)code);

                code = (byte *)Win.VirtualAlloc(
                    null,
                    alignedImageSize,
                    AllocationType.RESERVE | AllocationType.COMMIT,
                    MemoryProtection.READWRITE);

                if (code == null)
                {
                    throw new NativeDllLoadException("Out of Memory");
                }
            }
#endif

            _pageSize = systemInfo.dwPageSize;
            _codeBase = code;
            IsDll     = (oldHeader->FileHeader.Characteristics & Win.IMAGE_FILE_DLL) != 0;

            headers = (byte *)Win.VirtualAlloc(
                code,
                oldHeader->OptionalHeader.SizeOfHeaders,
                AllocationType.COMMIT,
                MemoryProtection.READWRITE);

            if (headers == null)
            {
                throw new NativeDllLoadException("Out of Memory");
            }

            Marshal.Copy(data, 0, (IntPtr)headers, (int)(dosHeader->e_lfanew + oldHeader->OptionalHeader.SizeOfHeaders));
            _headers = (IMAGE_NT_HEADERS *)&(headers)[dosHeader->e_lfanew];

            _headers->OptionalHeader.ImageBase = (UIntPtrT)code;

            CopySections(data, oldHeader);

            locationDelta = (PtrDiffT)(_headers->OptionalHeader.ImageBase - oldHeader->OptionalHeader.ImageBase);
            if (locationDelta != 0)
            {
                _isRelocated = PerformBaseRelocation(locationDelta);
            }
            else
            {
                _isRelocated = true;
            }

            BuildImportTable();
            FinalizeSections();
            ExecuteTLS();

            if (_headers->OptionalHeader.AddressOfEntryPoint == 0)
            {
                throw new NativeDllLoadException("DLL has no entry point");
            }

            if (IsDll)
            {
                dllEntryPtr = code + _headers->OptionalHeader.AddressOfEntryPoint;
                _dllEntry   = (DllEntryDelegate)Marshal.GetDelegateForFunctionPointer((IntPtr)dllEntryPtr, typeof(DllEntryDelegate));

                if (_dllEntry != null && _dllEntry(code, DllReason.DLL_PROCESS_ATTACH, null))
                {
                    _initialized = true;
                }
                else
                {
                    _initialized = false;
                    throw new NativeDllLoadException("Can't attach DLL to process.");
                }
            }
            else
            {
                exeEntryPtr = code + _headers->OptionalHeader.AddressOfEntryPoint;
                _exeEntry   = Marshal.GetDelegateForFunctionPointer <ExeEntryDelegate>((IntPtr)exeEntryPtr);
            }
        }
 /// <summary>
 /// Equivalent to the IMAGE_FIRST_SECTION macro
 /// </summary>
 /// <param name="ntheader">Pointer to to ntheader</param>
 /// <returns>Pointer to the first section</returns>
 public static IMAGE_SECTION_HEADER *IMAGE_FIRST_SECTION(IMAGE_NT_HEADERS *ntheader)
 {
     return((IMAGE_SECTION_HEADER *)((UIntPtrT)ntheader +
                                     (UIntPtrT)Marshal.OffsetOf(typeof(IMAGE_NT_HEADERS), "OptionalHeader") +
                                     ntheader->FileHeader.SizeOfOptionalHeader));
 }
示例#16
0
        void CopySections(byte[] data, IMAGE_NT_HEADERS *oldHeader)
        {
            if (data == null)
            {
                throw new ArgumentNullException("data");
            }

            if (oldHeader->Signature != Win.IMAGE_NT_SIGNATURE)
            {
                throw new BadImageFormatException("Invalid PE-Header");
            }

            uint  size;
            byte *dest;

            IMAGE_SECTION_HEADER *section = Win.IMAGE_FIRST_SECTION(_headers);

            for (int i = 0; i < _headers->FileHeader.NumberOfSections; i++, section++)
            {
                if (section->SizeOfRawData == 0)
                {
                    // section doesn't contain data in the dll itself, but may define
                    // uninitialized data
                    size = oldHeader->OptionalHeader.SectionAlignment;
                    if (size > 0)
                    {
                        dest = (byte *)Win.VirtualAlloc(
                            _codeBase + section->VirtualAddress,
                            size,
                            AllocationType.COMMIT,
                            MemoryProtection.READWRITE);

                        if (dest == null)
                        {
                            throw new NativeDllLoadException("Unable to allocate memory.");
                        }

                        dest = _codeBase + section->VirtualAddress;

                        section->PhysicalAddress = (uint)dest & 0xffffffff;
                        Win.MemSet(dest, 0, (void *)size);
                    }
                    continue;
                }

                dest = (byte *)Win.VirtualAlloc(
                    _codeBase + section->VirtualAddress,
                    section->SizeOfRawData,
                    AllocationType.COMMIT,
                    MemoryProtection.READWRITE);

                if (dest == null)
                {
                    throw new NativeDllLoadException("Out of memory.");
                }

                dest = _codeBase + section->VirtualAddress;
                Marshal.Copy(data, (int)section->PointerToRawData, (IntPtr)dest, (int)section->SizeOfRawData);
                section->PhysicalAddress = (uint)dest & 0xffffffff;
            }
        }
 static IMAGE_SECTION_HEADER *IMAGE_FIRST_SECTION(IMAGE_NT_HEADERS *img)
 {
     return((IMAGE_SECTION_HEADER *)((ulong)img + 0x18 + img->FileHeader.SizeOfOptionalHeader));
 }
示例#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);
        }
示例#19
0
        /// <summary>
        /// 填充导入表
        /// </summary>
        /// <param name="pPEHeader"></param>
        private unsafe void FillImportTable(IMAGE_NT_HEADERS *pPEHeader)
        {
#if _WIN64
            var iOffset = pPEHeader->OptionalHeader.GetDirectory(IMAGE_DIRECTORY_ENTRY.IMAGE_DIRECTORY_ENTRY_IMPORT).VirtualAddress;
            if (iOffset == 0)
            {
                return;
            }

            if (pPEHeader->OptionalHeader.GetDirectory(IMAGE_DIRECTORY_ENTRY.IMAGE_DIRECTORY_ENTRY_IMPORT).Size == 0)
            {
                return;
            }

            IMAGE_IMPORT_DESCRIPTOR *pImportDescriptor = (IMAGE_IMPORT_DESCRIPTOR *)((IntPtr)((Int64)this.mModuleHandle + (Int64)iOffset));
            while (pImportDescriptor->Name != 0)
            {
                UInt64 *pRealIAT     = (UInt64 *)((IntPtr)((Int64)this.mModuleHandle + (Int64)pImportDescriptor->FirstThunk));
                UInt64 *pOriginalIAT = (UInt64 *)((IntPtr)((Int64)this.mModuleHandle + (pImportDescriptor->OriginalFirstThunk == 0 ? (Int64)pImportDescriptor->FirstThunk : (Int64)pImportDescriptor->OriginalFirstThunk)));
                var     sDllName     = Marshal.PtrToStringAnsi((IntPtr)((Int64)this.mModuleHandle + (Int64)pImportDescriptor->Name));

                var hDll = Win32API.GetModuleHandle(sDllName);
                if (hDll == IntPtr.Zero)
                {
                    hDll = Win32API.LoadLibrary(sDllName);
                }

                if (hDll == IntPtr.Zero)
                {
                    throw new Exception(String.Format("load library({0}) fail", sDllName));
                }

                while (*pOriginalIAT != 0)
                {
                    IntPtr lpFunction = IntPtr.Zero;
                    if ((*pOriginalIAT & Win32API.IMAGE_ORDINAL_FLAG) == Win32API.IMAGE_ORDINAL_FLAG) // 最高位是1
                    {
                        var iFuncID = *pOriginalIAT & 0x0000FFFF;
                        lpFunction = Win32API.GetProcAddress(hDll, (IntPtr)((Int32)iFuncID));
                    }
                    else
                    {
                        //var sFuncName = Marshal.PtrToStringAnsi((IntPtr)((Int64)this.mModuleHandle + (Int64)(*pOriginalIAT) + 2));
                        lpFunction = Win32API.GetProcAddress(hDll, (IntPtr)((Int64)this.mModuleHandle + (Int64)(*pOriginalIAT) + 2));
                    }
                    if (lpFunction != IntPtr.Zero)
                    {
                        *pRealIAT = (UInt64)lpFunction;
                    }
                    pRealIAT++;
                    pOriginalIAT++;
                }
                pImportDescriptor++;
            }
#else
            var iOffset = pPEHeader->OptionalHeader.GetDirectory(IMAGE_DIRECTORY_ENTRY.IMAGE_DIRECTORY_ENTRY_IMPORT).VirtualAddress;
            if (iOffset == 0)
            {
                return;
            }

            if (pPEHeader->OptionalHeader.GetDirectory(IMAGE_DIRECTORY_ENTRY.IMAGE_DIRECTORY_ENTRY_IMPORT).Size == 0)
            {
                return;
            }

            IMAGE_IMPORT_DESCRIPTOR *pImportDescriptor = (IMAGE_IMPORT_DESCRIPTOR *)(this.mModuleHandle + (Int32)iOffset);
            while (pImportDescriptor->Name != 0)
            {
                UInt32 *pRealIAT     = (UInt32 *)(this.mModuleHandle + (Int32)pImportDescriptor->FirstThunk);
                UInt32 *pOriginalIAT = (UInt32 *)(this.mModuleHandle + (pImportDescriptor->OriginalFirstThunk == 0 ? (Int32)pImportDescriptor->FirstThunk : (Int32)pImportDescriptor->OriginalFirstThunk));
                var     sDllName     = Marshal.PtrToStringAnsi(this.mModuleHandle + (Int32)pImportDescriptor->Name);

                var hDll = Win32API.GetModuleHandle(sDllName);
                if (hDll == IntPtr.Zero)
                {
                    hDll = Win32API.LoadLibrary(sDllName);
                }

                if (hDll == IntPtr.Zero)
                {
                    throw new Exception(String.Format("load library({0}) fail", sDllName));
                }

                while (*pOriginalIAT != 0)
                {
                    IntPtr lpFunction = IntPtr.Zero;
                    if ((*pOriginalIAT & Win32API.IMAGE_ORDINAL_FLAG) == Win32API.IMAGE_ORDINAL_FLAG) // 最高位是1
                    {
                        var iFuncID = *pOriginalIAT & 0x0000FFFF;
                        lpFunction = Win32API.GetProcAddress(hDll, (IntPtr)((Int32)iFuncID));
                    }
                    else
                    {
                        //var sFuncName = Marshal.PtrToStringAnsi(this.mModuleHandle + (Int32)(*pOriginalIAT) + 2);
                        lpFunction = Win32API.GetProcAddress(hDll, this.mModuleHandle + (Int32)(*pOriginalIAT) + 2);
                    }
                    if (lpFunction != IntPtr.Zero)
                    {
                        *pRealIAT = (UInt32)lpFunction;
                    }
                    pRealIAT++;
                    pOriginalIAT++;
                }
                pImportDescriptor++;
            }
#endif
        }