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); } } }
private unsafe static bool ProcessRelocDir(LockdownHeap heap, byte *baseaddr, PeFileReader.NtHeaders.ImageDataDirectory *relocDir) { int i, edx; int[] data = new int[4]; PeFileReader.ImageBaseRelocation *relocation = (PeFileReader.ImageBaseRelocation *)(baseaddr + relocDir->VirtualAddress); for (; relocation->VirtualAddress > 0;) { short *relocInfo = (short *)((byte *)relocation + IMAGE_SIZEOF_BASE_RELOCATION); for (i = 0; i < ((relocation->SizeOfBlock - IMAGE_SIZEOF_BASE_RELOCATION) / 2); i++, relocInfo++) { int type, offset; type = *relocInfo >> 12; offset = *relocInfo & 0xfff; if (type != 0) { switch (type) { case IMAGE_REL_BASED_LOW: edx = 2; break; case IMAGE_REL_BASED_HIGHLOW: edx = 4; break; case IMAGE_REL_BASED_DIR64: edx = 8; break; default: return(false); } data[0] = relocation->VirtualAddress + offset; data[1] = edx; data[2] = 2; data[3] = type; heap.Add(data); } } relocation = (PeFileReader.ImageBaseRelocation *)(((byte *)relocation) + relocation->SizeOfBlock); } return(true); }