private static void MakeWritable(MemoryBasicInformation thunkMemoryInfo) { if (!UnsafeNativeMethods.VirtualProtect( thunkMemoryInfo.BaseAddress, thunkMemoryInfo.RegionSize, MemoryProtectionOptions.ExecuteReadWrite, &thunkMemoryInfo.Protect)) { throw new Win32Exception(); } }
private static void RestoreOriginalProtection(MemoryBasicInformation thunkMemoryInfo) { MemoryProtectionOptions ignore; if (!UnsafeNativeMethods.VirtualProtect( thunkMemoryInfo.BaseAddress, thunkMemoryInfo.RegionSize, thunkMemoryInfo.Protect, &ignore)) { throw new Win32Exception(); } }
private static Patched <TFunction> ApplyPatch <TFunction>( ProcessModule module, string importedModule, string importedName, ThunkPredicate isCorrectFunction, Func <TFunction, TFunction> buildReplacementFunction) where TFunction : class { AssertDelegate <TFunction>("TFunction"); module.NotNull("module"); importedModule.NotEmpty("importedModule"); isCorrectFunction.NotNull("isCorrectFunction"); buildReplacementFunction.NotNull("buildReplacementFunction"); ImageImportDescriptor *descriptors = module.GetImportDescriptors(); ImageImportDescriptor *descriptor = module.FindImportedModule(descriptors, importedModule); ImageThunkData * thunk = module.FindImportedFunction(descriptor, isCorrectFunction); MemoryBasicInformation thunkMemory = GetMemoryInformation(thunk); MakeWritable(thunkMemory); try { TFunction originalFunction = GetDelegateForFunctionPointer <TFunction>(thunk->Function); if (originalFunction == null) { throw new ArgumentException("Could not create a delegate for the original function to be patched."); } TFunction replacementFunction = buildReplacementFunction(originalFunction); thunk->Function = GetFunctionPointerForDelegate(replacementFunction); return(PatchedFunction.From( importedModule, importedName, replacementFunction, originalFunction)); } finally { RestoreOriginalProtection(thunkMemory); } }