Browse Source

Convert FastNativeDetour to use PageAllocator

ghorsington 3 years ago
parent
commit
37aa81e996
2 changed files with 14 additions and 47 deletions
  1. 6 32
      BepInEx.IL2CPP/Hook/DetourGenerator.cs
  2. 8 15
      BepInEx.IL2CPP/Hook/FastNativeDetour.cs

+ 6 - 32
BepInEx.IL2CPP/Hook/DetourGenerator.cs

@@ -66,9 +66,9 @@ namespace BepInEx.IL2CPP
 			byte[] instructionBuffer = new byte[32];
 			Marshal.Copy(originalFuncPointer, instructionBuffer, 0, 32);
 
-			var trampolinePtr = DetourHelper.Native.MemAlloc(80);
+			var trampolinePtr = PageAllocator.Instance.Allocate(originalFuncPointer);
 
-			DetourHelper.Native.MakeWritable(trampolinePtr, 80);
+			DetourHelper.Native.MakeWritable(trampolinePtr, PageAllocator.PAGE_SIZE);
 
 			var arch = IntPtr.Size == 8 ? Architecture.X64 : Architecture.X86;
 
@@ -77,7 +77,7 @@ namespace BepInEx.IL2CPP
 			CreateTrampolineFromFunction(instructionBuffer, originalFuncPointer, trampolinePtr, minimumTrampolineLength, arch, out trampolineLength, out jmpLength);
 
 			DetourHelper.Native.MakeExecutable(originalFuncPointer, 32);
-			DetourHelper.Native.MakeExecutable(trampolinePtr, (uint)trampolineLength);
+			DetourHelper.Native.MakeExecutable(trampolinePtr, PageAllocator.PAGE_SIZE);
 
 			return trampolinePtr;
 		}
@@ -106,27 +106,6 @@ namespace BepInEx.IL2CPP
 			{
 				decoder.Decode(out var instr);
 
-				if (instr.IsIPRelativeMemoryOperand)
-				{
-					// TODO: AssemlberRegisters not needed, figure out what props to actually change
-					// TODO: Check if it's better to use InternalOp0Kind (and other similar props) instead of normal ones
-					// TODO: Probably need to check if the target is within the trampoline boundaries and thus shouldn't be fixed
-					logger.LogDebug($"Got ptr with relative memory operand: {instr}");
-					var addr = instr.IPRelativeMemoryAddress;
-					logger.LogDebug($"Address: {addr:X}");
-					instr.MemoryBase = Register.None;
-					var op = AssemblerRegisters.__byte_ptr[addr].ToMemoryOperand(64);
-					instr.Op0Kind = OpKind.Memory;
-					instr.MemoryBase = op.Base;
-					instr.MemoryIndex = op.Index;
-					instr.MemoryIndexScale = op.Scale;
-					instr.MemoryDisplSize = op.DisplSize;
-					instr.MemoryDisplacement = (uint)op.Displacement;
-					instr.IsBroadcast = op.IsBroadcast;
-					instr.SegmentPrefix = op.SegmentPrefix;
-					logger.LogDebug($"After edit: {instr}");
-				}
-				
 				origInstructions.Add(instr);
 				
 				totalBytes += (uint)instr.Length;
@@ -140,19 +119,14 @@ namespace BepInEx.IL2CPP
 					case FlowControl.Next:
 						break;
 
-					case FlowControl.UnconditionalBranch:
-						if (instr.Op0Kind == OpKind.NearBranch64)
-						{
-							var target = instr.NearBranchTarget;
-						}
-
-						break;
-					//goto default;
 					case FlowControl.Interrupt:// eg. int n
 						break;
 
+					// Handled by BlockEncoder in most cases
+					case FlowControl.UnconditionalBranch:
 					case FlowControl.IndirectBranch:// eg. jmp reg/mem
 					case FlowControl.ConditionalBranch:// eg. je, jno, etc
+						break;
 					case FlowControl.Return:// eg. ret
 					case FlowControl.Call:// eg. call method
 					case FlowControl.IndirectCall:// eg. call reg/mem

+ 8 - 15
BepInEx.IL2CPP/Hook/FastNativeDetour.cs

@@ -36,13 +36,13 @@ namespace BepInEx.IL2CPP.Hook
 			Marshal.Copy(originalFunctionPtr, BackupBytes, 0, 20);
 		}
 
+		private static ManualLogSource logger = Logger.CreateLogSource("FastNativeDetour");
 
 		public void Apply()
 		{
 			Apply(null);
 		}
 
-
 		public void Apply(ManualLogSource debuggerLogSource)
 		{
 			if (IsApplied)
@@ -51,14 +51,10 @@ namespace BepInEx.IL2CPP.Hook
 
 			DetourHelper.Native.MakeWritable(OriginalFunctionPtr, 32);
 
-
 			if (debuggerLogSource != null)
 			{
 				debuggerLogSource.LogDebug($"Detouring 0x{OriginalFunctionPtr.ToString("X")} -> 0x{DetourFunctionPtr.ToString("X")}");
-
-
 				debuggerLogSource.LogDebug("Original (32) asm");
-
 				DetourGenerator.Disassemble(debuggerLogSource, OriginalFunctionPtr, 32);
 			}
 
@@ -68,17 +64,12 @@ namespace BepInEx.IL2CPP.Hook
 
 			DetourGenerator.ApplyDetour(OriginalFunctionPtr, DetourFunctionPtr, arch, trampolineLength - jmpLength);
 
-
 			if (debuggerLogSource != null)
 			{
 				debuggerLogSource.LogDebug($"Trampoline allocation: 0x{TrampolinePtr.ToString("X")}");
-
 				debuggerLogSource.LogDebug("Modified (32) asm");
-
 				DetourGenerator.Disassemble(debuggerLogSource, OriginalFunctionPtr, 32);
-
 				debuggerLogSource.LogDebug($"Trampoline ({trampolineLength}) asm");
-
 				DetourGenerator.Disassemble(debuggerLogSource, TrampolinePtr, trampolineLength);
 			}
 
@@ -100,16 +91,18 @@ namespace BepInEx.IL2CPP.Hook
 			byte[] instructionBuffer = new byte[32];
 			Marshal.Copy(OriginalFunctionPtr, instructionBuffer, 0, 32);
 
-			var trampolineAlloc = DetourHelper.Native.MemAlloc(80);
-
-			DetourHelper.Native.MakeWritable(trampolineAlloc, 80);
+			var trampolineAlloc = PageAllocator.Instance.Allocate(OriginalFunctionPtr);
+			
+			logger.LogDebug($"Original: {OriginalFunctionPtr.ToInt64():X}, Trampoline: {trampolineAlloc.ToInt64():X}, diff: {Math.Abs(OriginalFunctionPtr.ToInt64() - trampolineAlloc.ToInt64()):X}; is within +-1GB range: {PageAllocator.IsInRelJmpRange(OriginalFunctionPtr, trampolineAlloc)}");
+			
+			DetourHelper.Native.MakeWritable(trampolineAlloc, PageAllocator.PAGE_SIZE);
 
 			var arch = IntPtr.Size == 8 ? Architecture.X64 : Architecture.X86;
 
 			DetourGenerator.CreateTrampolineFromFunction(instructionBuffer, OriginalFunctionPtr, trampolineAlloc,
 				DetourGenerator.GetDetourLength(arch), arch, out trampolineLength, out jmpLength);
 
-			DetourHelper.Native.MakeExecutable(trampolineAlloc, 80);
+			DetourHelper.Native.MakeExecutable(trampolineAlloc, PageAllocator.PAGE_SIZE);
 
 			TrampolinePtr = trampolineAlloc;
 			TrampolineSize = trampolineLength;
@@ -124,7 +117,7 @@ namespace BepInEx.IL2CPP.Hook
 
 			Marshal.Copy(BackupBytes, 0, OriginalFunctionPtr, BackupBytes.Length);
 
-			DetourHelper.Native.MemFree(TrampolinePtr);
+			PageAllocator.Instance.Free(TrampolinePtr);
 
 			TrampolinePtr = IntPtr.Zero;
 			TrampolineSize = 0;