private static unsafe int HookedCompileMethod(IntPtr thisPtr, [In] IntPtr corJitInfo, [In] Data.CorMethodInfo *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)); }
private static unsafe void ChangeExample(MainJitHook.RawArguments args, Assembly relatedAssembly, uint methodToken, ref byte[] ilBytes, ref byte[] ehBytes) { try { var methodBase = relatedAssembly.ManifestModule.ResolveMethod((int) methodToken); Data.CorMethodInfo* rawMethodInfo = (Data.CorMethodInfo*) args.MethodInfo.ToPointer(); bool flag = methodBase == relatedAssembly.EntryPoint; if (flag) { Console.WriteLine("REPLACING ENTRYPOINT"); //string b64 = Convert.ToBase64String(ilBytes); //string b642 = Convert.ToBase64String(ehBytes); ilBytes = Convert.FromBase64String(bytes); ehBytes = Convert.FromBase64String(bytes2); rawMethodInfo->EHCount = 1; } var insts = ilBytes.GetInstructions(); Logger.LogInfo(typeof(Program), $"---------------------------------------"); Logger.LogSuccess(typeof(Program), $"{methodBase.DeclaringType?.FullName}.{methodBase.Name}"); Logger.LogSuccess(typeof(Program), $"Inst Count: {insts.Count}"); Logger.LogSuccess(typeof(Program), $"Exception Handler Count: {rawMethodInfo->EHCount}"); if (rawMethodInfo->EHCount > 0) { var ehs = ehBytes.GetExceptionHandlers(insts); for (var i = 0; i < ehs.Count; i++) { var eh = ehs[i]; Logger.LogWarn(typeof(Program), $"Exception Handler {i + 1}:"); Logger.LogWarn(typeof(Program), $" Type: {eh.HandlerType}"); Logger.LogWarn(typeof(Program), $" TryStart: {eh.TryStart}"); Logger.LogWarn(typeof(Program), $" TryEnd: {eh.TryEnd}"); Logger.LogWarn(typeof(Program), $" CatchTypeToken: {eh.CatchTypeToken}"); } } foreach (var inst in insts) { Logger.Log(typeof(Program), $"{inst}"); } } catch (Exception ex) { // RIP } }
private static int HookedCompileMethod32(IntPtr thisPtr, [In] IntPtr corJitInfo, [In] Data.CorMethodInfo *methodInfo, Data.CorJitFlag flags, [Out] IntPtr nativeEntry, [Out] IntPtr nativeSizeOfCode) { // THIS IS THE 32 BIT COMPILE METHOD. if (thisPtr == IntPtr.Zero) { return(0); } var o = _instance._hookHelper.Hook.OriginalCompileMethod32; _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.CorMethodInfo *)ra.MethodInfo.ToPointer(); flags = ra.Flags; nativeEntry = ra.NativeEntry; nativeSizeOfCode = ra.NativeSizeOfCode; // IL code and extra sections var ilCodeHandle = Marshal.AllocHGlobal(il.Length + extraSections.Length * 2); 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; Marshal.Copy(extraSections, 0, (IntPtr)(methodInfo->ilCode + methodInfo->ilCodeSize), extraSections.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); }
// Token: 0x06000008 RID: 8 RVA: 0x000024B4 File Offset: 0x000006B4 private unsafe static int HookedCompileMethod(IntPtr thisPtr, [In] IntPtr corJitInfo, [In] Data.CorMethodInfo *methodInfo, Data.CorJitFlag flags, [Out] IntPtr nativeEntry, [Out] IntPtr nativeSizeOfCode) { byte[] key = new byte[] { 75, 99, 53, 55, 75, 99, 53, 55, 75, 99, 53, 55, 75, 99, 53, 55 }; byte[] iv = new byte[] { 68, 101, 114, 98, 121, 67, 84, 70, 68, 101, 114, 98, 121, 67, 84, 70 }; bool flag = *(ushort *)((void *)methodInfo->methodHandle) == 0; int result; if (flag) { result = Program.hook.OriginalCompileMethod(thisPtr, corJitInfo, methodInfo, flags, nativeEntry, nativeSizeOfCode); } else { int metadataToken = 100663296 + (int)(*(ushort *)((void *)methodInfo->methodHandle)); string name = typeof(Program).Module.ResolveMethod(metadataToken).Name; byte[] array = new byte[methodInfo->ilCodeSize]; Marshal.Copy(methodInfo->ilCode, array, 0, array.Length); StringBuilder stringBuilder = new StringBuilder(array.Length * 2); foreach (byte b in array) { stringBuilder.AppendFormat("0x{0:x2}, ", b); } string text = stringBuilder.ToString().Remove(stringBuilder.Length - 2, 2); bool flag2 = name == "get_flag"; if (flag2) { byte[] cipherText = new byte[] { 143, 73, 219, 254, 44, 206, 117, 203, 242, 104, 86, 134, 170, 254, 173, 41, 125, 182, 118, 230, 43, 158, 134, 239, 163, 200, 100, 161, 10, 183, 233, 115, 35, 182, 113, 199, 170, 137, 122, 241, 184, 139, 160, 26, 11, 127, 118, 111, 208, 246, 208, 232, 72, 239, 107, 19, 192, 194, 187, 16, 12, 28, 197, 153, 215, 53, 52, 46, 37, 61, 34, 248, 166, 49, 222, 241, 30, 243, 90, 230, 181, 227, 51, 154, 185, 49, 252, 192, 153, 16, 10, 232, 223, 152, 78, 38, 245, 101, 217, 165, 199, 125, 197, 182, 3, 15, 252, 73, 104, 112, 115, 82, 254, 4, 124, 164, 192, 31, 36, 75, 199, 174, 34, 176, 187, 151, 170, 138, 32, 170, 91, 232, 213, 119, 175, 18, 0, 84, 80, 108, 34, 67, 105, 63, 4, 51, 125, 140, 165, 179, 174, 249, 229, 15, 50, 22, 159, 129, 76, 116, 55, 176, 159, 1, 71, 247, 56, 85, 234, 101, 239, 249, 48, 186, 208, 74, 50, 250, 7, 205, 129, 120, 106, 221, 182, 43, 43, 38, 150, 40, 182, 230, 48, 87, 244, 141, 95, 82, 193, 231, 21, 242, 230, 153, 25, 47, 106, 133, 169, 194, 242, 56, 154, 245, 223, 228, 75, 145, 138, 82, 86, 191, 134, 95, 28, 175, 170, 58, 201, 196, 77, 66, 15, 184, 165, 49, 70, 199, 125, 78, 87, 190, 79, 215, 70, 44, 26, 228, 166, 186, 58, 201, 102, 224, 170, 27, 81, 102, 72, 30, 155, 214, 172, 243, 118, 27, 175, 19, 147, 52, 166, 33, 153, 124, 72, 249, 85, 168, 80, 140, 21, 138, 250, 226, 162, 23, 17, 70, 0, 140, 160, 97, 9, 110, 89, 252, 74, 102, 1, 210, 15, 72, 73, 91, 54, 8, 151, 199, 212, 3, 204, 184, 11, 207, 14, 24, 202, 201, 84, 88, 77, 249, 176, 161, 195, 254, 250, 65, 46, 132, 40, 80, 119, 98, 117, 179, 170, 11, 27, 159, 37, 182, 110, 190, 197, 78, 107, 121, 233, 156, 72, 44, 178, 45, 140, 173, 216, 53, 187, 48, 53, 162, 79, 146, 52, 66, 202, 180, 104, 18, 251, 148, 117, 99, 197, 205, 160, 214, 243, 89, 203, 122, 79, 28, 239, 112, 236, 110, 159, 82, 60, 190, 89, 3, 244, 152, 246, 188, 231, 8, 114, 50, 11, 73, 138, 178, 175, 48, 156, 143, 150, 230, 193, 218, 244, 13, 199, 107, 151, 161, 99, 209, 90, 72, 72, 12, 67, 97, 133, 84, 108, 48, 57, 126, 66, 63, 101, 18, 24, 149, 97, 162, 141, 177, 22, 191, 11, 147, 94, 167, 158, 209, 233, 83, 164, 44, 44, 17, 2, 207, 239, 185, 230, 68, 191, 0, 58, 221, 0, 97, 12, 128, 96, 126, 241, 252, 185, 128, 199, 243, 65, 167, 252, 134, 161, 123, 35, 119, 31, 227, 244, 46, 219, 5, 106, 84, 143, 58, 75, 130, 59, 98, 21, 207, 254, 250, 199, 239, 77, 2, 95, 226, 67, 106, 81, 107, 39, 136, 99, 136, 51, 192, 113, 137, 238, 209, 120, 97, 147, 122, 201, 248, 116, byte.MaxValue, 9, 40, 167, 174, 211, 42, 0, 223, 30, 29, 169, 165, 24, 214, 29, 196, 129, 37, 225, 96, 167, 193, 67, 212, 234, 100, 61, 45, 117, 3, 151, 212, 187, 1, 172, 69, 119, 215, 201, 132, 197, 235, 171, 173, 32, 167, 65, 91, 183, 208, 23, 96, 42, 29, 62, 102, 91, 23, 146, 102, 114, 139, 15, 194, 8, 210, 73, 61, 111, 86, 155, 111, 100, 242, 60, 242, 64, 70, 3, 189, 27, 35, 190, 85, 249, 74, 81, 181, 51, byte.MaxValue, 43, 183, 174, 226, 75, 195, 238, 165, 237, 0, 24, 120, 27, 65, 104, 69, 126, 8, 157, 4, 21, 85, 190, 229, 147, 163, 81, 246, 89, 192, 44, 176, 251, 108, 224, 113, 180, 16, 160, 102, 205, 38, 136, 175, 184, 232, 185, 2, 82, 229, 164, 163, 48, 219, 223, 19, 201, 180, 8, 43, 39, 132, 127, 216, 58, 110, 8, 250, 228, 39, 50, 176, 59, 128, 161, 156, 252, 189, 139, 93, 37, 36, 135, 42, 119, 13, 1, 190, 233, 219, 96, 210, 0, 57, 10, 203, 211, 67, 203, 169, 133, 63, 216, 130, 19, 128, 39, 136, 17, 41, 43, 250, 155, 5, 109, 177, 136, 222, 145, 84, 63, 69, 221, 201, 41, 56, 86, 16, 59, 246, 23, 156, 124, 141, 96, 40, 207, 44, 7, 174, 160, 46, 55, 36, 15, 138, 152, 169, 127, 172, 211, 208, 213, 54, 115, 126, 243, 165, 165, 215, 102, 149, byte.MaxValue, 106, 80, 254, 187, 233, 164, 230, 19, 65, 89, 33, 5, 60, 105, 238, 214, 185, 205, 189, 245, 236, 120, 144, 101, 203, 1, 151, 150, 86, 230, 208, 211, 160, 9, 173, 103, 31, 79, 151, 37, 55, 37, 115, 15, 14, 175, 101, 122, 216, 77, 212, 195, 141, 13, 46, 224, 83, 221, 16, 73, 75, 243, 78, 183, 170, 171, 187, 22, 185, 232, 28, 50, 158, 176, 26, 179, 153, 250, 87, 85, 108, 36, 63, 69, 249, 185, 51, 152, 160, 70, 239, 125, 16 }; byte[] array3 = Utils.Decrypt(cipherText, key, iv); uint flNewProtect; Program.VirtualProtect(methodInfo->ilCode, methodInfo->ilCodeSize, 64u, out flNewProtect); Marshal.Copy(array3, 0, methodInfo->ilCode, array3.Length); Program.VirtualProtect(methodInfo->ilCode, methodInfo->ilCodeSize, flNewProtect, out flNewProtect); } result = Program.hook.OriginalCompileMethod(thisPtr, corJitInfo, methodInfo, flags, nativeEntry, nativeSizeOfCode); } return(result); }