Exemple #1
0
        private void ReplaceJit(IntPtr jitAddr)
        {
            _jitAddr = jitAddr;
            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 guid);
            CLRVersionID = guid;

            var compileMethodPtr = Marshal.ReadIntPtr(jitTable, 0);

            _originalCompileMethod = Marshal.GetDelegateForFunctionPointer <CompileMethodDelegate>(compileMethodPtr);
            _replacedCompileMethod = CompileMethod;
            var replacedCompileMethodPtr = Marshal.GetFunctionPointerForDelegate(_replacedCompileMethod);

            var trampolinePtr = AllocateTrampoline(replacedCompileMethodPtr);
            var trampoline    = Marshal.GetDelegateForFunctionPointer <CompileMethodDelegate>(trampolinePtr);
            var emptyInfo     = default(CORINFO_METHOD_INFO);

            trampoline(IntPtr.Zero, IntPtr.Zero, ref emptyInfo, 0, out var _, out var _);
            FreeTrampoline(trampolinePtr);

            VirtualProtect(jitTable, new IntPtr(IntPtr.Size), MemoryProtection.ReadWrite, out var oldFlags);
            Marshal.WriteIntPtr(jitTable, 0, replacedCompileMethodPtr);
            VirtualProtect(jitTable, new IntPtr(IntPtr.Size), oldFlags, out _);

            IsHooked = true;
        }
Exemple #2
0
        /// <summary>
        /// Load info from JIT.
        /// </summary>
        protected RuntimeFramework(bool isCore)
        {
            IsCore = isCore;
            Jit    = GetJitAddress();
            ICorJitCompileVTable = Marshal.ReadIntPtr(Jit);
            IntPtr compileMethodPtr = Marshal.ReadIntPtr(ICorJitCompileVTable);

            CompileMethod = Marshal.GetDelegateForFunctionPointer <CompileMethodDelegate>(compileMethodPtr);
            IdentifyFrameworkVersion();
        }
Exemple #3
0
        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;
                }
            }
        }
Exemple #4
0
        static ManagedJit()
        {
            JitLock             = new object();
            MapHandleToAssembly = new Dictionary <IntPtr, Assembly>(IntPtrEqualityComparer.Instance);
            var process = Process.GetCurrentProcess();

            foreach (ProcessModule module in process.Modules)
            {
                if (Path.GetFileName(module.FileName) == "clrjit.dll")
                {
                    // This is the address of ICorJitCompiler
                    // https://github.com/dotnet/coreclr/blob/bb01fb0d954c957a36f3f8c7aad19657afc2ceda/src/inc/corjit.h#L391-L445
                    var jitAddress = GetProcAddress(module.BaseAddress, "getJit");
                    if (jitAddress != IntPtr.Zero)
                    {
                        var getJit = (GetJitDelegate)Marshal.GetDelegateForFunctionPointer(jitAddress, typeof(GetJitDelegate));
                        var jit    = getJit();
                        if (jit != IntPtr.Zero)
                        {
                            JitVtable = Marshal.ReadIntPtr(jit);

                            // Check JitVersion
                            var getVersionIdentifierPtr = Marshal.ReadIntPtr(JitVtable, IntPtr.Size * ICorJitCompiler_getVersionIdentifier_index);
                            var getVersionIdentifier    = (GetVersionIdentifierDelegate)Marshal.GetDelegateForFunctionPointer(getVersionIdentifierPtr, typeof(GetVersionIdentifierDelegate));
                            getVersionIdentifier(jitAddress, out var version);
                            if (version != ExpectedJitVersion)
                            {
                                return;
                            }

                            // If version, ok, get CompileMethod
                            DefaultCompileMethodPtr = Marshal.ReadIntPtr(JitVtable, IntPtr.Size * ICorJitCompiler_compileMethod_index);
                            DefaultCompileMethod    = (CompileMethodDelegate)Marshal.GetDelegateForFunctionPointer(DefaultCompileMethodPtr, typeof(CompileMethodDelegate));
                        }
                    }
                    break;
                }
            }
        }
Exemple #5
0
        public void Dispose()
        {
            lock (JitLock)
            {
                if (_isDisposed)
                {
                    return;
                }

                if (_overrideCompileMethodPtr == IntPtr.Zero)
                {
                    return;
                }

                UninstallManagedJit();
                _overrideCompileMethodPtr = IntPtr.Zero;
                _overrideCompileMethod    = null;
                _isDisposed        = true;
                ManagedJitInstance = null;
                _isHookInstalled   = false;
            }
        }
Exemple #6
0
        private ManagedJit()
        {
            if (DefaultCompileMethod != null)
            {
                // 1) Converts a reference to our compile method to a `CompileMethodDelegate`
                _overrideCompileMethod    = CompileMethod;
                _overrideCompileMethodPtr = Marshal.GetFunctionPointerForDelegate(_overrideCompileMethod);

                // 2) Build a trampoline that will allow to simulate a call from native to our delegate
                var trampolinePtr = AllocateTrampoline(_overrideCompileMethodPtr);
                var trampoline    = (CompileMethodDelegate)Marshal.GetDelegateForFunctionPointer(trampolinePtr, typeof(CompileMethodDelegate));

                // 3) Call our trampoline
                IntPtr value;
                int    size;
                var    emptyInfo = default(CORINFO_METHOD_INFO);
                trampoline(IntPtr.Zero, IntPtr.Zero, ref emptyInfo, 0, out value, out size);
                FreeTrampoline(trampolinePtr);

                // 4) Once our `CompileMethodDelegate` can be accessible from native code, we can install it
                InstallManagedJit(_overrideCompileMethodPtr);
                _isHookInstalled = true;
            }
        }