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; } }
/// <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_HEADERS32* ntheader) { return ((IMAGE_SECTION_HEADER*)((int)ntheader + Marshal.OffsetOf(typeof(IMAGE_NT_HEADERS32), "OptionalHeader").ToInt32() + ntheader->FileHeader.SizeOfOptionalHeader)); }