Esempio n. 1
0
        private static unsafe int HookedCompileMethod(IntPtr thisPtr, [In] IntPtr corJitInfo,
                                                      [In] Data.CorMethodInfo64 *methodInfo, Data.CorJitFlag flags,
                                                      [Out] IntPtr nativeEntry, [Out] IntPtr nativeSizeOfCode)
        {
            int token;

            Console.WriteLine("Compilation:\r\n");
            Console.WriteLine("Token: " + (token = (0x06000000 + *(ushort *)methodInfo->methodHandle)).ToString("x8"));
            Console.WriteLine("Name: " + typeof(Program).Module.ResolveMethod(token).Name);
            Console.WriteLine("Body size: " + methodInfo->ilCodeSize);

            var bodyBuffer = new byte[methodInfo->ilCodeSize];

            Marshal.Copy(methodInfo->ilCode, bodyBuffer, 0, bodyBuffer.Length);

            Console.WriteLine("Body: " + BitConverter.ToString(bodyBuffer));

            /*
             * Change output of "Foo" to 1337 instead of 1000:
             *
             * uint old;
             * VirtualProtect(methodInfo->ilCode + 2, sizeof (int), 0x40, out old);
             *(int*) (methodInfo->ilCode + 2) = 1337;
             * VirtualProtect(methodInfo->ilCode + 2, sizeof (int), old, out old);
             *
             */

            return(_jitHook.OriginalCompileMethod(thisPtr, corJitInfo, methodInfo, flags, nativeEntry, nativeSizeOfCode));
        }
Esempio n. 2
0
        private unsafe void HandleCompile(JitMethodBase method_base, Data.CorMethodInfo64 *methodInfo)
        {
            var msil_bytes = new byte[methodInfo->ilCodeSize];

            Marshal.Copy(methodInfo->ilCode, msil_bytes, 0, msil_bytes.Length);


            if (method_base is EncryptedMethod ecr_method) //encrypted method
            {
                Win32.Print("\tOriginal: " + BitConverter.ToString(msil_bytes));

                //virtual protect --- we are about to write to this location
                if (!Win32.VirtualProtect(methodInfo->ilCode, methodInfo->ilCodeSize, Protection.PAGE_EXECUTE_READWRITE, out Protection old_protect))
                {
                    Win32.Print("VirtualProtect #1 Failed");
                    SafeCrash.ForceCrash();
                }

                byte[] new_bytes = ecr_method.Decrypt(); //--- decrypt our method

                if (new_bytes.Length == 0)
                {
                    Win32.Print("New bytes length = 0");
                    SafeCrash.ForceCrash();
                }

                Win32.Print("Decrypted: " + BitConverter.ToString(new_bytes));

                // write our decrypted bytes
                for (uint i = 0; i < methodInfo->ilCodeSize; i++)
                {
                    byte *address = ((byte *)methodInfo->ilCode) + i;
                    *     address = new_bytes[i];
                }

                //wipe our decrypte bytes from the stack
                Array.Clear(new_bytes, 0, new_bytes.Length);


                //virtual protect --- we are done writing so restore our protection
                if (!Win32.VirtualProtect(methodInfo->ilCode, methodInfo->ilCodeSize, old_protect, out Protection ignore))
                {
                    Win32.Print("VirtualProtect #2 failed");
                    SafeCrash.ForceCrash();
                }
            }
            else if (method_base is HashedMethod hsh_method)
            {
                //hashed method --- verify integrity
                hsh_method.VerifyHash(msil_bytes);
            }
            else
            {
                Win32.Print("Unknown Method Type");
                SafeCrash.ForceCrash(); //Not definitive type, crash us
            }
        }
Esempio n. 3
0
        private unsafe int ClrCompile64(IntPtr thisPtr, [In] IntPtr corJitInfo,
                                        [In] Data.CorMethodInfo64 *methodInfo, Data.CorJitFlag flags,
                                        [Out] IntPtr nativeEntry, [Out] IntPtr nativeSizeOfCode)
        {
            JitMethodBase[] compiling_methods = FindMethods(methodInfo);

            //IntPtr corJitInfo_vTable = Marshal.ReadIntPtr(corJitInfo);

            if (compiling_methods.Length != 0)
            {
                //detect debuggers
                if (AntiDebug.DetectDebuggers())
                {
                    Win32.Print("On Compile - Debugger Present");
                    SafeCrash.ForceCrash();
                }

                JitMethodBase method_base = compiling_methods[0];
                Win32.Print($"Compiling: {method_base.Method.Name}");


                if (compiling_methods.Length == 1)
                {
                    //--- one matching method, HandleCompile we determine what to do
                    HandleCompile(method_base, methodInfo);
                }
                else
                {
                    //--- two matching methods, must handle decryption before hashing
                    foreach (JitMethodBase method in compiling_methods)
                    {
                        if (method is EncryptedMethod encrypted)
                        {
                            HandleCompile(encrypted, methodInfo);
                            break;
                        }
                    }
                    foreach (JitMethodBase method in compiling_methods)
                    {
                        if (method is HashedMethod hashed)
                        {
                            HandleCompile(hashed, methodInfo);
                            break;
                        }
                    }
                }
            }

            return(_jitHook64.OriginalCompileMethod(thisPtr, corJitInfo, methodInfo, flags, nativeEntry, nativeSizeOfCode));
        }
Esempio n. 4
0
        private unsafe JitMethodBase[] FindMethods(Data.CorMethodInfo64 *methodInfo)
        {
            if (methodInfo->methodHandle == IntPtr.Zero)
            {
                return(new JitMethodBase[0]);
            }

            List <JitMethodBase> result = new List <JitMethodBase>();

            for (int i = 0; i < Methods.Count; i++)
            {
                if (Methods[i].DoesMatch(methodInfo->moduleHandle, *(ushort *)methodInfo->methodHandle))
                {
                    result.Add(Methods[i]);
                }
            }
            return(result.ToArray());
        }
Esempio n. 5
0
        private unsafe JitMethodBase[] FindMethods(Data.CorMethodInfo64 *methodInfo)
        {
            if (methodInfo->methodHandle == IntPtr.Zero)
            {
                return(new JitMethodBase[0]);
            }

            //--- quickly check if this method exists in our dictionarys & if it does add it to be returned
            long value = methodInfo->moduleHandle.ToInt64() + (0x06000000 + *(ushort *)methodInfo->methodHandle);
            List <JitMethodBase> methods = new List <JitMethodBase>();

            if (EncryptedMethods.ContainsKey(value))
            {
                methods.Add(EncryptedMethods[value]);
            }
            if (HashedMethods.ContainsKey(value))
            {
                methods.Add(HashedMethods[value]);
            }

            return(methods.ToArray());
        }
Esempio n. 6
0
        private static int HookedCompileMethod64(IntPtr thisPtr, [In] IntPtr corJitInfo,
                                                 [In] Data.CorMethodInfo64 *methodInfo, Data.CorJitFlag flags,
                                                 [Out] IntPtr nativeEntry, [Out] IntPtr nativeSizeOfCode)
        {
            // THIS IS THE 64 BIT COMPILE METHOD.
            if (thisPtr == IntPtr.Zero)
            {
                return(0);
            }

            var o = _instance._hookHelper.Hook.OriginalCompileMethod64;

            _instance.EntryCount++;
            if (_instance.EntryCount > 1)
            {
                _instance.EntryCount--;
                return(o(thisPtr, corJitInfo, methodInfo, flags,
                         nativeEntry, nativeSizeOfCode));
            }


            var safeMethodInfo = new IntPtr((int *)methodInfo);

#if NET4
            EHInfoHook exceptionHandlerHook = null;
#endif

#if NET4
            var functionPtr  = Marshal.ReadIntPtr(Marshal.ReadIntPtr(corJitInfo), IntPtr.Size * GET_METHOD_DEF_FROM_METHOD_SLOT_INDEX);
            var getMethodDef = (Data.GetMethodDefFromMethodDel)Marshal.GetDelegateForFunctionPointer(functionPtr, typeof(Data.GetMethodDefFromMethodDel));
            var token        = getMethodDef(corJitInfo, methodInfo->ftn);
#else
            var token = (uint)(0x06000000 | *(ushort *)methodInfo->ftn);
#endif

            lock (_jitCompileMethodLock)
            {
                Assembly relatedAssembly = null;
                if (!_instance._scopeMap.ContainsKey(methodInfo->scope))
                {
                    _instance._scopeMap = AppDomain.CurrentDomain.GetScopeMap();
                }
                if (_instance._scopeMap.ContainsKey(methodInfo->scope))
                {
                    relatedAssembly = _instance._scopeMap[methodInfo->scope];
                }
                else
                {
                    _instance.EntryCount--;
                    return(o(thisPtr, corJitInfo, methodInfo, flags,
                             nativeEntry, nativeSizeOfCode));
                }

                var ra = new RawArguments
                {
                    ThisPtr          = thisPtr,
                    CorJitInfo       = corJitInfo,
                    MethodInfo       = safeMethodInfo,
                    Flags            = flags,
                    NativeEntry      = nativeEntry,
                    NativeSizeOfCode = nativeSizeOfCode
                };

                byte[] il = new byte[methodInfo->ilCodeSize];
                Marshal.Copy((IntPtr)methodInfo->ilCode, il, 0, il.Length);

                // Extra sections contains the exception handlers.
                byte[] extraSections = new byte[0];
                if (methodInfo->EHCount > 0)
                {
                    byte *extraSectionsPtr = methodInfo->ilCode + methodInfo->ilCodeSize;
                    extraSections = TryReadExtraSections(extraSectionsPtr);
                }

                _instance.OnCompileMethod -= OnCompileEventResetMethod;
                _instance.OnCompileMethod += OnCompileEventResetMethod;
                _instance.OnCompileMethod(ra, relatedAssembly, token, ref il, ref extraSections);
                _instance._compileMethodResetEvent.WaitOne();

                // Assume something has changed.
                thisPtr          = ra.ThisPtr;
                corJitInfo       = ra.CorJitInfo;
                methodInfo       = (Data.CorMethodInfo64 *)ra.MethodInfo.ToPointer();
                flags            = ra.Flags;
                nativeEntry      = ra.NativeEntry;
                nativeSizeOfCode = ra.NativeSizeOfCode;

                // IL code and extra sections
                var ilCodeHandle = Marshal.AllocHGlobal(il.Length);
                Marshal.Copy(il, 0, ilCodeHandle, il.Length);
                Data.VirtualProtect((IntPtr)methodInfo->ilCode, (uint)IntPtr.Size, Data.Protection.PAGE_READWRITE,
                                    out uint prevProt);
                methodInfo->ilCode     = (byte *)ilCodeHandle.ToPointer();
                methodInfo->ilCodeSize = (uint)il.Length;

#if NET4
                if (methodInfo->EHCount > 0 || extraSections.Length > 2)
                {
                    exceptionHandlerHook = new EHInfoHook(corJitInfo, methodInfo->ftn, il, extraSections);
                }
#endif
            }

            var res = o(thisPtr, corJitInfo, methodInfo, flags,
                        nativeEntry, nativeSizeOfCode);

#if NET4
            exceptionHandlerHook?.Dispose();
#endif
            _instance.EntryCount--;
            return(res);
        }
Esempio n. 7
0
 public unsafe int CompileMethod(IntPtr thisPtr, IntPtr corJitInfo, Data.CorMethodInfo64 *methodInfo, Data.CorJitFlag flags, IntPtr nativeEntry, IntPtr nativeSizeOfCode)
 {
     return(this._compileMethod64(thisPtr, corJitInfo, methodInfo, flags, nativeEntry, nativeSizeOfCode));
 }