예제 #1
0
        void CopySections(byte[] data, IMAGE_NT_HEADERS32 *ntHeader)
        {
            if (data == null)
            {
                throw new ArgumentNullException("data");
            }

            if (ntHeader->Signature != NativeDeclarations.IMAGE_NT_SIGNATURE)
            {
                throw new BadImageFormatException("Inavlid PE-Header");
            }

            uint size;
            int *dest;

            IMAGE_SECTION_HEADER *section = NativeDeclarations.IMAGE_FIRST_SECTION(this.headers);

            for (int i = 0; i < this.headers->FileHeader.NumberOfSections; i++, section++)
            {
                if (section->SizeOfRawData == 0)
                {
                    // section doesn't contain data in the dll itself, but may define
                    // uninitialized data
                    size = ntHeader->OptionalHeader.SectionAlignment;
                    if (size > 0)
                    {
                        dest = (int *)NativeDeclarations.VirtualAlloc(
                            new IntPtr(this.codeBase + section->VirtualAddress),
                            size,
                            AllocationType.COMMIT,
                            MemoryProtection.READWRITE).ToPointer();

                        section->PhysicalAddress = (uint)dest;
                        NativeDeclarations.MemSet(new IntPtr(dest), 0, new IntPtr(size));
                    }
                    continue;
                }

                dest = (int *)NativeDeclarations.VirtualAlloc(
                    new IntPtr((int)this.codeBase + section->VirtualAddress),
                    section->SizeOfRawData,
                    AllocationType.COMMIT,
                    MemoryProtection.READWRITE).ToPointer();

                Marshal.Copy(data, (int)section->PointerToRawData, new IntPtr(dest), (int)section->SizeOfRawData);
                section->PhysicalAddress = (uint)dest;
            }
        }
예제 #2
0
        private void MemoryLoadLibrary(byte[] data)
        {
            IMAGE_DOS_HEADER32 *dosHeader;
            IMAGE_NT_HEADERS32 *ntHeader;
            IntPtr dllEntryPtr;
            byte * code, headers, dataPtr;
            uint   locationDelta;

            this.dataHandle = GCHandle.Alloc(data, GCHandleType.Pinned);
            dataPtr         = (byte *)this.dataHandle.AddrOfPinnedObject().ToPointer();

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

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

            code = (byte *)NativeDeclarations.VirtualAlloc(
                new IntPtr(ntHeader->OptionalHeader.ImageBase),
                ntHeader->OptionalHeader.SizeOfImage,
                AllocationType.RESERVE,
                MemoryProtection.READWRITE).ToPointer();

            if (code == null)
            {
                code = (byte *)NativeDeclarations.VirtualAlloc(
                    IntPtr.Zero,
                    ntHeader->OptionalHeader.SizeOfImage,
                    AllocationType.RESERVE,
                    MemoryProtection.READWRITE).ToPointer();
            }

            if (code == null)
            {
                throw new Win32Exception();
            }

            NativeDeclarations.VirtualAlloc(
                new IntPtr(code),
                ntHeader->OptionalHeader.SizeOfImage,
                AllocationType.COMMIT,
                MemoryProtection.READWRITE);

            this.codeBase = code;

            headers = (byte *)NativeDeclarations.VirtualAlloc(
                new IntPtr(code),
                ntHeader->OptionalHeader.SizeOfHeaders,
                AllocationType.COMMIT,
                MemoryProtection.READWRITE).ToPointer();

            if (headers == null)
            {
                throw new Win32Exception();
            }

            Marshal.Copy(data, 0, new IntPtr(headers), (int)(dosHeader->e_lfanew + ntHeader->OptionalHeader.SizeOfHeaders));
            this.headers = (IMAGE_NT_HEADERS32 *)&((byte *)(headers))[dosHeader->e_lfanew];

            this.headers->OptionalHeader.ImageBase = (uint)code;

            this.CopySections(data, ntHeader);

            locationDelta = (uint)(code - ntHeader->OptionalHeader.ImageBase);
            if (locationDelta != 0)
            {
                PerformBaseRelocation(locationDelta);
            }

            this.BuildImportTable();
            this.FinalizeSections();

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

            dllEntryPtr = new IntPtr(code + this.headers->OptionalHeader.AddressOfEntryPoint);

            this.dllEntry = (DllEntryDelegate)Marshal.GetDelegateForFunctionPointer(dllEntryPtr, typeof(DllEntryDelegate));

            if (dllEntry(new IntPtr(code), DllReason.DLL_PROCESS_ATTACH, IntPtr.Zero))
            {
                this.initialized = true;
            }
            else
            {
                this.initialized = false;
                throw new NativeDllLoadException("Can't attach DLL to process.");
            }
        }