static void Hook() { foreach (ProcessModule module in Process.GetCurrentProcess().Modules) { if (Path.GetFileName(module.FileName) == "clrjit.dll") { var jitaddr = GetProcAddress(module.BaseAddress, "getJit"); var getJit = Marshal.GetDelegateForFunctionPointer <GetJitDelegate>(jitaddr); var jit = getJit(); var jitTable = Marshal.ReadIntPtr(jit); var getVerIdPtr = Marshal.ReadIntPtr(jitTable, IntPtr.Size * 4); var getVerId = Marshal.GetDelegateForFunctionPointer <GetVersionIdentifierDelegate>(getVerIdPtr); getVerId(jitaddr, out var version); if (version != ExpectedJitVersion) { throw new Exception("Unexpected Jit Version xD"); } var compileMethodPtr = Marshal.ReadIntPtr(jitTable, 0); DefaultCompileMethod = Marshal.GetDelegateForFunctionPointer <CompileMethodDelegate>(compileMethodPtr); NewCompileMethod = CompileMethod; var newCompileMethodPtr = Marshal.GetFunctionPointerForDelegate(NewCompileMethod); var trampolinePtr = AllocateTrampoline(newCompileMethodPtr); var trampoline = Marshal.GetDelegateForFunctionPointer <CompileMethodDelegate>(trampolinePtr); var emptyInfo = default(CORINFO_METHOD_INFO); trampoline(IntPtr.Zero, IntPtr.Zero, ref emptyInfo, 0, out var entry, out var size); FreeTrampoline(trampolinePtr); VirtualProtect(jitTable, new IntPtr(IntPtr.Size), MemoryProtection.ReadWrite, out var oldFlags); Marshal.WriteIntPtr(jitTable, 0, newCompileMethodPtr); VirtualProtect(jitTable, new IntPtr(IntPtr.Size), oldFlags, out oldFlags); isHooked = true; InjectHereInstance = InjectHere; InjectHerePtr = Marshal.GetFunctionPointerForDelegate <InjectDelegate>(InjectHere); // NewCompileMethod(IntPtr.Zero, IntPtr.Zero, ref emptyInfo, 0, out var _, out var _); break; } } }
/// <summary> /// インジェクションを追加します。 /// </summary> /// <param name="injectionAction">インジェクション関数を指定します。</param> /// <param name="mode">インジェクションの方針を決定します。</param> public void Injection(InjectDelegate <T> injectAction, InjectionMode mode) { switch (mode) { case InjectionMode.InjectionFirst: this.callFirst.AddFirst(injectAction); break; case InjectionMode.InjectionLast: this.callLast.AddLast(injectAction); break; case InjectionMode.NoConsider: default: this.callMiddle.AddLast(injectAction); break; } }
internal static void LoadDll() { try { // Get handle to Unmanaged DLL UnmanagedModule = NativeImports.LoadLibrary(UnmanagedDllName); if (UnmanagedModule != IntPtr.Zero) { // We have a valid handle // Get address to our unmanaged function var pProcAddress = NativeImports.GetProcAddress(UnmanagedModule, "Inject"); if (pProcAddress != IntPtr.Zero) { InjectDLL = Marshal.GetDelegateForFunctionPointer(pProcAddress, typeof(InjectDelegate)) as InjectDelegate; if (InjectDLL == null) { throw new Exception("Failed to get delegate for function pointer"); } } else { throw new Exception("Failed to load export."); } } else { throw new Exception(string.Format("Failed to load: {0}, error code: {1}", UnmanagedDllName, Marshal.GetLastWin32Error())); } } catch (Exception ex) { MessageBox.Show(ex.ToString()); } }
private Action <T> MakeCallFunc(InjectDelegate <T> call, Action <T> ncall, Action <T> finalCallback) { return(arg => call(arg, ncall, finalCallback)); }
/// <summary> /// インジェクションを追加します。 /// </summary> /// <param name="injectionAction">インジェクション関数を指定します。</param> public void Injection(InjectDelegate <T> injectAction) { this.Injection(injectAction, InjectionMode.NoConsider); }
private Func <T, TResult> MakeCallFunc(InjectDelegate <T, TResult> call, Func <T, TResult> ncall, Func <T, TResult> finalCallback) { return(arg => call(arg, ncall, finalCallback)); }