private IEnumerable <HarmonyImportLibrary> ResolveImports(Image image) { IMAGE_DATA_DIRECTORY directory = Environment.Is64BitProcess ? image.OptionalHeader64->ImportTable : image.OptionalHeader32->ImportTable; if (directory.Size == 0 || (_loadFlags & HarmonyLoadFlags.NoImports) != 0) { return(Enumerable.Empty <HarmonyImportLibrary>()); } Dictionary <string, HarmonyLibrary> otherLibraryLookup = _otherLibraries.ToDictionary(l => (Path.GetFileName(l.Name) ?? l.Name).ToLowerInvariant()); List <HarmonyImportLibrary> imports = new List <HarmonyImportLibrary>(); IMAGE_IMPORT_DESCRIPTOR *importDescriptor = (IMAGE_IMPORT_DESCRIPTOR *)(image.BasePtr + directory.VirtualAddress); for (; !Kernel32.IsBadReadPtr((UIntPtr)importDescriptor, (uint)sizeof(IMAGE_IMPORT_DESCRIPTOR)) && importDescriptor->Name != 0; importDescriptor++) { HarmonyImportLibrary import = LoadImport(image.BasePtr, image.Size, importDescriptor, otherLibraryLookup, _loadFlags); imports.Add(import); } return(imports); }
private static HarmonyImportLibrary LoadHarmonyImport(byte *basePtr, uint size, IMAGE_IMPORT_DESCRIPTOR *importDescriptor, HarmonyLibrary library) { HarmonyImportLibrary importLibrary = ApplyImportLibrary( basePtr, size, importDescriptor, library.Name, HarmonyImportLibraryKind.HarmonyLibrary, library.GetProcAddress, library.GetProcAddressByOrdinal ); return(importLibrary); }
private static HarmonyImportLibrary LoadExternalDllImport(byte *basePtr, uint size, IMAGE_IMPORT_DESCRIPTOR *importDescriptor, string moduleName) { IntPtr moduleHandle = Kernel32.LoadLibrary(moduleName); if (moduleHandle == IntPtr.Zero) { int lastError = Marshal.GetLastWin32Error(); Exception innerEx = new Win32Exception(lastError); innerEx.Data.Add("LastWin32Error", lastError); throw new LoadFailedException(string.Format("Unable to load dependent library \"{0}\".", moduleName), innerEx); } HarmonyImportLibrary importLibrary = ApplyImportLibrary( basePtr, size, importDescriptor, moduleName, HarmonyImportLibraryKind.ExternalDll, name => Kernel32.GetProcAddress(moduleHandle, name), ordinal => Kernel32.GetProcAddressOrdinal(moduleHandle, (IntPtr)ordinal) ); return(importLibrary); }