void AddLoaderEntry(Core hProc, string imageName, ulong moduleHandle) { log.Log(LogType.Normal, $"Linking {imageName}({moduleHandle.ToString("x2")}) to module list"); var imagePath = Exts.FindDll(imageName) ?? imageName; var listBase = hProc.GetLoaderData().InLoadOrderModuleList; var lastEntry = hProc.Read <WinAPI._LDR_DATA_TABLE_ENTRY>((IntPtr)listBase.Blink); var allocatedDllPath = (ulong)hProc.AllocateAndWriteBytes(Encoding.Unicode.GetBytes(imagePath)); // CRAFT CUSTOM LOADER ENTRY var fileName = Path.GetFileName(imagePath); WinAPI._LDR_DATA_TABLE_ENTRY myEntry = new WinAPI._LDR_DATA_TABLE_ENTRY() { InLoadOrderLinks = new WinAPI._LIST_ENTRY() { Flink = lastEntry.InLoadOrderLinks.Flink, Blink = listBase.Flink }, InMemoryOrderLinks = lastEntry.InMemoryOrderLinks, InInitializationOrderLinks = lastEntry.InInitializationOrderLinks, DllBase = moduleHandle, EntryPoint = 0, SizeOfImage = (ulong)MappedRawImages[imageName].Length, FullDllName = new WinAPI.UNICODE_STRING(imagePath) { Buffer = allocatedDllPath }, BaseDllName = new WinAPI.UNICODE_STRING(fileName) { Buffer = allocatedDllPath + (ulong)imagePath.IndexOf(fileName) * 2 /*WIDE CHAR*/ }, Flags = lastEntry.Flags, LoadCount = lastEntry.LoadCount, TlsIndex = lastEntry.TlsIndex, Reserved4 = lastEntry.Reserved4, CheckSum = lastEntry.CheckSum, TimeDateStamp = lastEntry.TimeDateStamp, EntryPointActivationContext = lastEntry.EntryPointActivationContext, PatchInformation = lastEntry.PatchInformation, ForwarderLinks = lastEntry.ForwarderLinks, ServiceTagLinks = lastEntry.ServiceTagLinks, StaticLinks = lastEntry.StaticLinks, }; // ALLOCATE AND WRITE OUR MODULE ENTRY var newEntryPointer = hProc.AllocateAndWriteBytes(Exts.GetBytes(myEntry)); // SET LAST LINK IN InLoadOrderLinks CHAIN TO POINT TO OUR ENTRY lastEntry.InLoadOrderLinks.Flink = (ulong)newEntryPointer; hProc.Write(lastEntry, (IntPtr)listBase.Blink); }
unsafe void FixImportTable(ulong localImage, WinAPI.IMAGE_OPTIONAL_HEADER64 optionalHeader, WinAPI.IMAGE_NT_HEADERS64 *ntHeaders) { unsafe { WinAPI.IMAGE_DATA_DIRECTORY *directory = WinAPI.GET_HEADER_DIRECTORY(ntHeaders, WinAPI.IMAGE_DIRECTORY_ENTRY_IMPORT); WinAPI.IMAGE_IMPORT_DESCRIPTOR *importDescriptor = (WinAPI.IMAGE_IMPORT_DESCRIPTOR *)(localImage + directory->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 = (ulong)WinAPI.LoadLibrary(libraryName); libraryName = GetModuleBaseName(WinAPI.GetCurrentProcess(), 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 = Exts.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); InjectDependency(dependencyPath); --importDescriptor; continue; } remoteLibraryHandle = MapImage(libraryName, File.ReadAllBytes(dependencyPath)); mappedDependency = true; } ulong *functionAddress = (ulong *)(localImage + importDescriptor->FirstThunk); ulong *importEntry = (ulong *)(localImage + importDescriptor->Characteristics); do { ulong procNamePointer = *importEntry < 0x8000000000000000 /*IMAGE_ORDINAL_FLAG64*/ ? // IS ORDINAL? localImage + *importEntry + sizeof(ushort) /*SKIP HINT*/ : // FUNCTION BY NAME *importEntry & 0xFFFF; // ORDINAL var localFunctionPointer = (ulong)WinAPI.GetProcAddress((IntPtr)localLibraryHandle, (uint)procNamePointer); var rva = localFunctionPointer - localLibraryHandle; // SET NEW FUNCTION POINTER *functionAddress = mappedDependency ? remoteLibraryHandle + rva : localFunctionPointer; // GET NEXT ENTRY ++functionAddress; ++importEntry; } while (*importEntry > 0); } } }