public MemoryProtect(IntPtr process, IntPtr address, int size, uint protect) { this.process = process; this.address = address; this.size = (UIntPtr)size; this.success = NativeFunctions.VirtualProtectEx(process, address, this.size, protect, out this.oldProtect); }
public void Dispose() { if (!this.success) { return; } NativeFunctions.VirtualProtectEx(this.process, this.address, this.size, this.oldProtect, out _); NativeFunctions.FlushInstructionCache(this.process, this.address, this.size); }
public IHook <TDelegate> Hook <TDelegate>(IntPtr nativeFuncPtr, TDelegate hookFunc) where TDelegate : notnull { try { var process = NativeFunctions.GetCurrentProcess(); var hookFuncPtr = Marshal.GetFunctionPointerForDelegate(hookFunc); var jumpAsm = GetJumpAsm(nativeFuncPtr, hookFuncPtr); var readSize = jumpAsm.Length + 20; using var protect = new MemoryProtect(NativeFunctions.GetCurrentProcess(), nativeFuncPtr, readSize, NativeFunctions.Consts.PAGE_EXECUTE_READWRITE); var disassembler = new Disassembler(nativeFuncPtr, readSize, this.arch.IsX64 ? ArchitectureMode.x86_64 : ArchitectureMode.x86_32); var patchSize = GetPatchSize(disassembler.Disassemble(), jumpAsm.Length); var originalHead = new byte[jumpAsm.Length]; Marshal.Copy(nativeFuncPtr, originalHead, 0, originalHead.Length); if (patchSize < 0) { Marshal.Copy(jumpAsm, 0, nativeFuncPtr, jumpAsm.Length); var nativeFunc = Marshal.GetDelegateForFunctionPointer <TDelegate>(nativeFuncPtr); return(new ThreadUnsafeHook <TDelegate>(process, nativeFuncPtr, nativeFunc, originalHead, jumpAsm)); } else { var patch = new byte[patchSize]; Marshal.Copy(nativeFuncPtr, patch, 0, patchSize); var heapSize = patchSize + 20; var heap = Marshal.AllocHGlobal(heapSize); Marshal.Copy(patch, 0, heap, patchSize); var patchToOriginalJumpAsm = GetJumpAsm(heap + patchSize, nativeFuncPtr + patchSize); Marshal.Copy(patchToOriginalJumpAsm, 0, heap + patchSize, patchToOriginalJumpAsm.Length); uint oldProtect; var suc = NativeFunctions.VirtualProtectEx(process, heap, (UIntPtr)heapSize, NativeFunctions.Consts.PAGE_EXECUTE_READWRITE, out oldProtect); NativeFunctions.FlushInstructionCache(process, heap, (UIntPtr)heapSize); var nativeFunc = Marshal.GetDelegateForFunctionPointer <TDelegate>(heap); Marshal.Copy(jumpAsm, 0, nativeFuncPtr, jumpAsm.Length); return(new ThreadSafeHook <TDelegate>(process, nativeFuncPtr, nativeFunc, originalHead, heap, (uint)heapSize, oldProtect)); } } catch { throw new MoguException("Error occured while hooking"); } }
public void Dispose() { Write(this.originalHead); NativeFunctions.VirtualProtectEx(this.process, this.patchHeap, (UIntPtr)this.heapSize, this.heapOldProtect, out _); Marshal.FreeHGlobal(this.patchHeap); }