Advertisement
Guest User

Untitled

a guest
Dec 23rd, 2016
214
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 4.80 KB | None | 0 0
  1.     using System;
  2.     using System.Collections.Generic;
  3.     using System.Reflection;
  4.     using Verse;
  5.      
  6.     namespace MyRimworldMod
  7.     {
  8.      
  9.             public static class Detours
  10.             {
  11.      
  12.                     private static List<string> detoured = new List<string>();
  13.                     private static List<string> destinations = new List<string>();
  14.      
  15.                     /**
  16.                 This is a basic first implementation of the IL method 'hooks' (detours) made possible by RawCode's work;
  17.                 https://ludeon.com/forums/index.php?topic=17143.0
  18.                 Performs detours, spits out basic logs and warns if a method is detoured multiple times.
  19.             **/
  20.                     public static unsafe bool TryDetourFromTo(MethodInfo source, MethodInfo destination)
  21.                     {
  22.      
  23.                             if (source == null) {
  24.                                     Log.Error("Source MethodInfo is null: Detours");
  25.                                     return false;
  26.                             }
  27.                             if (destination == null) {
  28.                                     Log.Error("Destination MethodInfo is null: Detours");
  29.                                     return false;
  30.                             }
  31.      
  32.                             // keep track of detours and spit out some messaging
  33.                             string sourceString = source.DeclaringType.FullName + "." + source.Name + " @ 0x" + source.MethodHandle.GetFunctionPointer().ToString("X" + (IntPtr.Size * 2).ToString());
  34.                             string destinationString = destination.DeclaringType.FullName + "." + destination.Name + " @ 0x" + destination.MethodHandle.GetFunctionPointer().ToString("X" + (IntPtr.Size * 2).ToString());
  35.      
  36.                             detoured.Add(sourceString);
  37.                             destinations.Add(destinationString);
  38.      
  39.                             if (IntPtr.Size == sizeof(Int64)) {
  40.                                     // 64-bit systems use 64-bit absolute address and jumps
  41.                                     // 12 byte destructive
  42.      
  43.                                     // Get function pointers
  44.                                     long Source_Base = source.MethodHandle.GetFunctionPointer().ToInt64();
  45.                                     long Destination_Base = destination.MethodHandle.GetFunctionPointer().ToInt64();
  46.      
  47.                                     // Native source address
  48.                                     byte* Pointer_Raw_Source = (byte*)Source_Base;
  49.      
  50.                                     // Pointer to insert jump address into native code
  51.                                     long* Pointer_Raw_Address = (long*)(Pointer_Raw_Source + 0x02);
  52.      
  53.                                     // Insert 64-bit absolute jump into native code (address in rax)
  54.                                     // mov rax, immediate64
  55.                                     // jmp [rax]
  56.                                     *(Pointer_Raw_Source + 0x00) = 0x48;
  57.                                     *(Pointer_Raw_Source + 0x01) = 0xB8;
  58.                                     *Pointer_Raw_Address = Destination_Base; // ( Pointer_Raw_Source + 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 )
  59.                                     *(Pointer_Raw_Source + 0x0A) = 0xFF;
  60.                                     *(Pointer_Raw_Source + 0x0B) = 0xE0;
  61.      
  62.                             }
  63.                             else {
  64.                                     // 32-bit systems use 32-bit relative offset and jump
  65.                                     // 5 byte destructive
  66.      
  67.                                     // Get function pointers
  68.                                     int Source_Base = source.MethodHandle.GetFunctionPointer().ToInt32();
  69.                                     int Destination_Base = destination.MethodHandle.GetFunctionPointer().ToInt32();
  70.      
  71.                                     // Native source address
  72.                                     byte* Pointer_Raw_Source = (byte*)Source_Base;
  73.      
  74.                                     // Pointer to insert jump address into native code
  75.                                     int* Pointer_Raw_Address = (int*)(Pointer_Raw_Source + 1);
  76.      
  77.                                     // Jump offset (less instruction size)
  78.                                     int offset = (Destination_Base - Source_Base) - 5;
  79.      
  80.                                     // Insert 32-bit relative jump into native code
  81.                                     *Pointer_Raw_Source = 0xE9;
  82.                                     *Pointer_Raw_Address = offset;
  83.                             }
  84.      
  85.                             // done!
  86.                             return true;
  87.                     }
  88.      
  89.             }
  90.      
  91.     }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement