private static unsafe void CopySections(byte *data, PeFileReader.NtHeaders *header, byte *baseaddr) { int i, size; byte *dest; // roughly, IMAGE_FIRST_SECTION macro. 0x18 is the offset of the optional header, plus size of optional header. PeFileReader.ImageSectionHeader *section = (PeFileReader.ImageSectionHeader *)(((byte *)header) + 0x18 + header->SizeOfOptionalHeader); for (i = 0; i < header->NumberOfSections; i++, section++) { if (section->SizeOfRawData == 0) { size = header->OptionalHeader.SectionAlignment; if (size > 0) { dest = (byte *)(baseaddr + section->VirtualAddress); section->PhysicalAddress = (int)dest; Native.Memset(dest, 0, size); } } else { dest = (byte *)(baseaddr + section->VirtualAddress); Native.Memcpy(dest, data + section->PointerToRawData, section->SizeOfRawData); section->PhysicalAddress = (int)dest; } } }
private static unsafe void PerformBaseReloc(byte *baseaddr, PeFileReader.NtHeaders *ntheader, int relocOffset) { int i; PeFileReader.NtHeaders.ImageDataDirectory *directory; directory = (PeFileReader.NtHeaders.ImageDataDirectory *) & ntheader->OptionalHeader.IDD5; if (directory->Size > 0) { PeFileReader.ImageBaseRelocation *relocation = (PeFileReader.ImageBaseRelocation *)(baseaddr + directory->VirtualAddress); for (; relocation->VirtualAddress > 0;) { byte * dest = (byte *)(baseaddr + relocation->VirtualAddress); ushort *relocInfo = (ushort *)((byte *)relocation + IMAGE_SIZEOF_BASE_RELOCATION); for (i = 0; i < ((relocation->SizeOfBlock - IMAGE_SIZEOF_BASE_RELOCATION) / 2); i++, relocInfo++) { uint *patch_addr; int type, offset; type = *relocInfo >> 12; offset = *relocInfo & 0xfff; if (type == IMAGE_REL_BASED_HIGHLOW) { patch_addr = (uint *)(dest + offset); *patch_addr += unchecked ((uint)relocOffset); } } relocation = (PeFileReader.ImageBaseRelocation *)(((ulong)relocation) + (ulong)relocation->SizeOfBlock); } } }