public void RelocateImageByDelta(UInt32 localImage, UInt32 remoteImage, NT.IMAGE_OPTIONAL_HEADER64 optionalHeader) { // https://github.com/DarthTon/Blackbone/blob/master/src/BlackBone/ManualMap/MMap.cpp#L691 NT.IMAGE_BASE_RELOCATION *baseRelocation = (NT.IMAGE_BASE_RELOCATION *)(localImage + optionalHeader.BaseRelocationTable.VirtualAddress); var memoryDelta = remoteImage - optionalHeader.ImageBase; int relocBaseSize = Marshal.SizeOf <NT.IMAGE_BASE_RELOCATION>(); while (baseRelocation->SizeOfBlock > 0) { // START OF RELOCATION UInt32 relocStartAddress = localImage + baseRelocation->VirtualAddress; // AMOUNT OF RELOCATIONS IN THIS BLOCK int relocationAmount = ((int)baseRelocation->SizeOfBlock - relocBaseSize /*DONT COUNT THE MEMBERS*/) / sizeof(ushort) /*SIZE OF DATA*/; // ITERATE ALL RELOCATIONS AND FIX THE HIGHLOWS for (int i = 0; i < relocationAmount; i++) { // GET RELOCATION DATA var data = GetRelocationData(i); // WORD Offset : 12; // WORD Type : 4; var fixOffset = data & 0x0FFF; var fixType = data & 0xF000; // THIS IS A HIGHLOW ACCORDING TO MY GHETTO MASK // ¯\_(ツ)_/¯ if (fixType == 40960) { *(UInt32 *)(relocStartAddress + (uint)fixOffset) += memoryDelta; // ADD MEMORY DELTA TO SPECIFIED ADDRESS } } // GET THE NEXT BLOCK baseRelocation = (NT.IMAGE_BASE_RELOCATION *)((ulong)baseRelocation + baseRelocation->SizeOfBlock); } ushort GetRelocationData(int index) => *(ushort *)((long)baseRelocation + Marshal.SizeOf <NT.IMAGE_BASE_RELOCATION>() + sizeof(ushort) * index); }
public void FixImportTable(UInt32 localImage, NT.IMAGE_OPTIONAL_HEADER64 optionalHeader) { NT.IMAGE_IMPORT_DESCRIPTOR *importDescriptor = (NT.IMAGE_IMPORT_DESCRIPTOR *)(localImage + optionalHeader.ImportTable.VirtualAddress); for (; importDescriptor->FirstThunk > 0; ++importDescriptor) { string libraryName = Marshal.PtrToStringAnsi((IntPtr)(localImage + importDescriptor->Name)); // RECODE THIS, THIS IS STUPID & DANGEROUS // I AM ONLY DOING THIS BECAUSE OF API-SET DLLS // I COULDNT BE ARSED TO MAKE A PINVOKE FOR ApiSetResolveToHost ulong localLibraryHandle = NT.LoadLibrary(libraryName); libraryName = NTM.GetModuleBaseName(Process.GetCurrentProcess().Handle, localLibraryHandle).ToLower(); // IF WE MAPPED DEPENDENCY EARLIER, WE SHOULD USE RVA // INSTEAD OF STATIC MEMORY ADDRESS bool mappedDependency = MappedModules.TryGetValue(libraryName, out ulong remoteLibraryHandle); bool linkedInProcess = LinkedModules.TryGetValue(libraryName, out remoteLibraryHandle); if (!mappedDependency && !linkedInProcess) // DEPENDENCY NOT FOUND, MAP IT! { string dependencyPath = Tools.FindDll(libraryName); // SKIP IF DEPENDENCY COULDN'T BE FOUND if (dependencyPath == null) { continue; } // [8:44 PM] markhc: i had something similar // [8:44 PM] markhc: it was deep inside CRT initialization(edited) // [8:45 PM] Ch40zz: how did you fix it? // [8:46 PM] markhc: i didnt fix it // [8:46 PM] markhc: i thought it was something wrong with my manual mapper code, but i couldnt figure out what was it // [8:46 PM] markhc: so i threw it all away if (libraryName == "msvcp140.dll") { var tempOptions = Options; tempOptions.EraseHeaders = false; new LoadLibraryInjection(TargetProcess, TypeOfExecution, tempOptions).InjectImage(dependencyPath); --importDescriptor; continue; } remoteLibraryHandle = MapImage(libraryName, File.ReadAllBytes(dependencyPath)); mappedDependency = true; } UInt32 *functionAddress = (UInt32 *)(localImage + importDescriptor->FirstThunk); UInt32 *importEntry = (UInt32 *)(localImage + importDescriptor->OriginalFirstThunk); do { ulong procNamePointer = *importEntry < 0x8000000000000000 /*IMAGE_ORDINAL_FLAG64*/ ? // IS ORDINAL? localImage + *importEntry + sizeof(ushort) /*SKIP HINT*/ : // FUNCTION BY NAME *importEntry & 0xFFFF; // ORDINAL var localFunctionPointer = NT.GetProcAddress(localLibraryHandle, procNamePointer); var rva = localFunctionPointer - localLibraryHandle; // SET NEW FUNCTION POINTER *functionAddress = (UInt32)(mappedDependency ? remoteLibraryHandle + rva : localFunctionPointer); // GET NEXT ENTRY ++functionAddress; ++importEntry; } while (*importEntry > 0); } }
public static void GetImageHeaders(byte[] rawImage, out NT.IMAGE_DOS_HEADER dosHeader, out NT.IMAGE_FILE_HEADER fileHeader, out NT.IMAGE_OPTIONAL_HEADER64 optionalHeader) { fixed(byte *imagePointer = &rawImage[0]) { dosHeader = *(NT.IMAGE_DOS_HEADER *)imagePointer; NT.IMAGE_NT_HEADERS *ntHeader = (NT.IMAGE_NT_HEADERS *)(imagePointer + dosHeader.e_lfanew); fileHeader = ntHeader->FileHeader; optionalHeader = ntHeader->OptionalHeader; } }