private static HarmonyImportLibrary ApplyImportLibrary(byte *basePtr, uint size, IMAGE_IMPORT_DESCRIPTOR *importDescriptor, string moduleName, HarmonyImportLibraryKind importLibraryKind, Func <string, IntPtr> getImportByName, Func <ushort, IntPtr> getImportByOrdinal) { const uint ImageOrdinalFlag32 = 0x80000000U; const ulong ImageOrdinalFlag64 = 0x8000000000000000UL; List <HarmonyImport> importThunks = new List <HarmonyImport>(); UIntPtr thunkRef; UIntPtr funcRef; if (importDescriptor->OriginalFirstThunk != 0) { thunkRef = (UIntPtr)(basePtr + importDescriptor->OriginalFirstThunk); funcRef = (UIntPtr)(basePtr + importDescriptor->FirstThunk); } else { // No hint table. thunkRef = (UIntPtr)(basePtr + importDescriptor->FirstThunk); funcRef = (UIntPtr)(basePtr + importDescriptor->FirstThunk); } bool is64BitMode = Environment.Is64BitProcess; uint thunk; for (; (thunk = *(uint *)thunkRef) != 0; thunkRef += sizeof(UIntPtr), funcRef += sizeof(UIntPtr)) { IntPtr procAddress; if (!is64BitMode && (thunk & ImageOrdinalFlag32) != 0 || is64BitMode && (thunk & ImageOrdinalFlag64) != 0) { procAddress = getImportByOrdinal((ushort)(thunk & 0xFFFF)); if (procAddress == IntPtr.Zero) { throw new LoadFailedException(string.Format("Unable to dependent library \"{0}\" is missing required import ordinal {1}.", moduleName, thunk & 0xFFFF)); } *(IntPtr *)funcRef = procAddress; importThunks.Add(new HarmonyImport((int)(thunk & 0xFFFF), null, procAddress)); } else { IMAGE_IMPORT_BY_NAME *thunkData = (IMAGE_IMPORT_BY_NAME *)(basePtr + thunk); string thunkName = StringOperations.NulTerminatedBytesToString((byte *)thunkData + 2, basePtr, size); procAddress = getImportByName(thunkName); if (procAddress == IntPtr.Zero) { throw new LoadFailedException(string.Format("Unable to dependent library \"{0}\" is missing required import \"{1}\".", moduleName, thunkName)); } *(IntPtr *)funcRef = procAddress; importThunks.Add(new HarmonyImport(null, thunkName, procAddress)); } } return(new HarmonyImportLibrary(importLibraryKind, moduleName, importThunks)); }
public HarmonyImportLibrary(HarmonyImportLibraryKind kind, string name, IEnumerable <HarmonyImport> imports) { Kind = kind; Name = name; Imports = Array.AsReadOnly(imports.ToArray()); }