Skip to content

Commit e367de4

Browse files
committed
init
1 parent ed10b34 commit e367de4

File tree

861 files changed

+12206
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

861 files changed

+12206
-0
lines changed

Assets/Libraries.meta

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Assets/Libraries/DLLManipulator.meta

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Assets/Libraries/DLLManipulator/scripts.meta

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 266 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,266 @@
1+
//
2+
// Following file is essentially copy of Memory.cs file from https://github.com/pardeike/Harmony
3+
//
4+
5+
using System;
6+
using System.Collections.Generic;
7+
using System.Reflection;
8+
using System.Reflection.Emit;
9+
using System.Runtime.CompilerServices;
10+
11+
namespace UnityNativeTool.Internal
12+
{
13+
/// <summary>A low level memory helper</summary>
14+
internal static class Detour
15+
{
16+
static readonly HashSet<PlatformID> WindowsPlatformIDSet = new HashSet<PlatformID>
17+
{
18+
PlatformID.Win32NT, PlatformID.Win32S, PlatformID.Win32Windows, PlatformID.WinCE
19+
};
20+
21+
/// <summary>Is current environment Windows?</summary>
22+
/// <value>True if it is Windows</value>
23+
///
24+
internal static bool IsWindows => WindowsPlatformIDSet.Contains(Environment.OSVersion.Platform);
25+
26+
/// <summary>Unprotect memory pages</summary>
27+
/// <param name="memory">The starting memory address</param>
28+
/// <param name="size">The length of memory block</param>
29+
///
30+
internal static void UnprotectMemory(long memory, ulong size)
31+
{
32+
if (IsWindows)
33+
{
34+
var success = PInvokes_Windows.VirtualProtect(new IntPtr(memory), new UIntPtr(size), PInvokes_Windows.Protection.PAGE_EXECUTE_READWRITE, out var _);
35+
if (!success)
36+
throw new System.ComponentModel.Win32Exception();
37+
}
38+
}
39+
40+
internal static void FlushCode(long memory, ulong size)
41+
{
42+
if (IsWindows)
43+
{
44+
var processHandle = PInvokes_Windows.GetCurrentProcess();
45+
var success = PInvokes_Windows.FlushInstructionCache(processHandle, new IntPtr(memory), new UIntPtr(size));
46+
if (!success)
47+
throw new System.ComponentModel.Win32Exception();
48+
}
49+
}
50+
51+
/// <summary>Mark method for no inlining</summary>
52+
/// <param name="method">The method to change</param>
53+
unsafe public static void MarkForNoInlining(MethodBase method)
54+
{
55+
// TODO for now, this only works on mono
56+
if (Type.GetType("Mono.Runtime") != null)
57+
{
58+
var iflags = (ushort*)(method.MethodHandle.Value) + 1;
59+
*iflags |= (ushort)MethodImplOptions.NoInlining;
60+
}
61+
}
62+
63+
/// <summary>Detours a method</summary>
64+
/// <param name="original">The original method</param>
65+
/// <param name="replacement">The replacement method</param>
66+
/// <returns>An error string</returns>
67+
///
68+
public unsafe static string DetourMethod(MethodBase original, MethodBase replacement)
69+
{
70+
var originalCodeStart = GetMethodStart(original, out var exception);
71+
if (originalCodeStart == 0)
72+
return exception.Message;
73+
var patchCodeStart = GetMethodStart(replacement, out exception);
74+
if (patchCodeStart == 0)
75+
return exception.Message;
76+
77+
return WriteJump(originalCodeStart, patchCodeStart);
78+
}
79+
80+
/// <summary>Writes a jump to memory</summary>
81+
/// <param name="memory">The memory address</param>
82+
/// <param name="destination">Jump destination</param>
83+
/// <returns>An error string</returns>
84+
///
85+
public static string WriteJump(long memory, long destination)
86+
{
87+
UnprotectMemory(memory, IntPtr.Size == sizeof(long) ? 12u : 6u);
88+
89+
long writtenMemoryAddress;
90+
if (IntPtr.Size == sizeof(long))
91+
{
92+
if (CompareBytes(memory, new byte[] { 0xe9 }))
93+
{
94+
var offset = ReadInt(memory + 1);
95+
memory += 5 + offset;
96+
UnprotectMemory(memory, 12);
97+
}
98+
99+
writtenMemoryAddress = memory;
100+
memory = WriteBytes(memory, new byte[] { 0x48, 0xB8 });
101+
memory = WriteLong(memory, destination);
102+
memory = WriteBytes(memory, new byte[] { 0xFF, 0xE0 });
103+
}
104+
else
105+
{
106+
writtenMemoryAddress = memory;
107+
memory = WriteByte(memory, 0x68);
108+
memory = WriteInt(memory, (int)destination);
109+
memory = WriteByte(memory, 0xc3);
110+
}
111+
112+
FlushCode(writtenMemoryAddress, IntPtr.Size == sizeof(long) ? 12u : 6u);
113+
return null;
114+
}
115+
116+
static RuntimeMethodHandle GetRuntimeMethodHandle(MethodBase method)
117+
{
118+
if (method is DynamicMethod)
119+
{
120+
var noninternalInstance = BindingFlags.NonPublic | BindingFlags.Instance;
121+
122+
// DynamicMethod actually generates its m_methodHandle on-the-fly and therefore
123+
// we should call GetMethodDescriptor to force it to be created
124+
//
125+
var m_GetMethodDescriptor = typeof(DynamicMethod).GetMethod("GetMethodDescriptor", noninternalInstance);
126+
if (m_GetMethodDescriptor != null)
127+
return (RuntimeMethodHandle)m_GetMethodDescriptor.Invoke(method, new object[0]);
128+
129+
// .Net Core
130+
var f_m_method = typeof(DynamicMethod).GetField("m_method", noninternalInstance);
131+
if (f_m_method != null)
132+
return (RuntimeMethodHandle)f_m_method.GetValue(method);
133+
134+
// Mono
135+
var f_mhandle = typeof(DynamicMethod).GetField("mhandle", noninternalInstance);
136+
return (RuntimeMethodHandle)f_mhandle.GetValue(method);
137+
}
138+
139+
return method.MethodHandle;
140+
}
141+
142+
/// <summary>Gets the start of a method in memory</summary>
143+
/// <param name="method">The method</param>
144+
/// <param name="exception">[out] Details of the exception</param>
145+
/// <returns>The method start address</returns>
146+
///
147+
public static long GetMethodStart(MethodBase method, out Exception exception)
148+
{
149+
// required in .NET Core so that the method is JITed and the method start does not change
150+
//
151+
var handle = GetRuntimeMethodHandle(method);
152+
try
153+
{
154+
RuntimeHelpers.PrepareMethod(handle);
155+
}
156+
catch (Exception)
157+
{
158+
}
159+
160+
try
161+
{
162+
exception = null;
163+
return handle.GetFunctionPointer().ToInt64();
164+
}
165+
catch (Exception ex)
166+
{
167+
exception = ex;
168+
return 0;
169+
}
170+
}
171+
172+
/// <summary>Compare bytes</summary>
173+
/// <param name="memory">The memory address</param>
174+
/// <param name="values">The bytes to compare to</param>
175+
/// <returns>True if memory address contains the bytes</returns>
176+
///
177+
internal static unsafe bool CompareBytes(long memory, byte[] values)
178+
{
179+
var p = (byte*)memory;
180+
foreach (var value in values)
181+
{
182+
if (value != *p) return false;
183+
p++;
184+
}
185+
return true;
186+
}
187+
188+
/// <summary>Reads a byte</summary>
189+
/// <param name="memory">The memory address</param>
190+
/// <returns>The byte</returns>
191+
///
192+
internal static unsafe byte ReadByte(long memory)
193+
{
194+
var p = (byte*)memory;
195+
return *p;
196+
}
197+
198+
/// <summary>Reads an int</summary>
199+
/// <param name="memory">The memory address</param>
200+
/// <returns>The int</returns>
201+
///
202+
internal static unsafe int ReadInt(long memory)
203+
{
204+
var p = (int*)memory;
205+
return *p;
206+
}
207+
208+
/// <summary>Reads a long</summary>
209+
/// <param name="memory">The memory address</param>
210+
/// <returns>The long</returns>
211+
///
212+
internal static unsafe long ReadLong(long memory)
213+
{
214+
var p = (long*)memory;
215+
return *p;
216+
}
217+
218+
/// <summary>Writes a byte</summary>
219+
/// <param name="memory">The memory address</param>
220+
/// <param name="value">The byte</param>
221+
/// <returns>Advanced memory address</returns>
222+
///
223+
internal static unsafe long WriteByte(long memory, byte value)
224+
{
225+
var p = (byte*)memory;
226+
*p = value;
227+
return memory + sizeof(byte);
228+
}
229+
230+
/// <summary>Writes some bytes</summary>
231+
/// <param name="memory">The memory address</param>
232+
/// <param name="values">The bytes to write</param>
233+
/// <returns>Advanced memory address</returns>
234+
///
235+
internal static unsafe long WriteBytes(long memory, byte[] values)
236+
{
237+
foreach (var value in values)
238+
memory = WriteByte(memory, value);
239+
return memory;
240+
}
241+
242+
/// <summary>Writes an int</summary>
243+
/// <param name="memory">The memory address</param>
244+
/// <param name="value">The int</param>
245+
/// <returns>Advanced memory address</returns>
246+
///
247+
internal static unsafe long WriteInt(long memory, int value)
248+
{
249+
var p = (int*)memory;
250+
*p = value;
251+
return memory + sizeof(int);
252+
}
253+
254+
/// <summary>Writes a long</summary>
255+
/// <param name="memory">The memory address</param>
256+
/// <param name="value"> The long</param>
257+
/// <returns>Advanced memory address</returns>
258+
///
259+
internal static unsafe long WriteLong(long memory, long value)
260+
{
261+
var p = (long*)memory;
262+
*p = value;
263+
return memory + sizeof(long);
264+
}
265+
}
266+
}

Assets/Libraries/DLLManipulator/scripts/Detour.cs.meta

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
using System;
2+
using System.Runtime.Serialization;
3+
4+
namespace UnityNativeTool
5+
{
6+
public class NativeDllException : Exception
7+
{
8+
public NativeDllException()
9+
{
10+
}
11+
12+
public NativeDllException(string message) : base(message)
13+
{
14+
}
15+
16+
public NativeDllException(string message, Exception innerException) : base(message, innerException)
17+
{
18+
}
19+
20+
protected NativeDllException(SerializationInfo info, StreamingContext context) : base(info, context)
21+
{
22+
}
23+
}
24+
}

Assets/Libraries/DLLManipulator/scripts/DllLoadException.cs.meta

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)