hybridclr_unity/Editor/3rds/UnityHook/HookUtils_OSX.cs

102 lines
3.2 KiB
C#

#if (UNITY_STANDALONE_OSX || UNITY_EDITOR_OSX)
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using UnityEngine;
namespace MonoHook
{
public static unsafe class HookUtils
{
static bool jit_write_protect_supported;
private static readonly long _Pagesize;
static HookUtils()
{
jit_write_protect_supported = pthread_jit_write_protect_supported_np() != 0;
PropertyInfo p_SystemPageSize = typeof(Environment).GetProperty("SystemPageSize");
if (p_SystemPageSize == null)
throw new NotSupportedException("Unsupported runtime");
_Pagesize = (int)p_SystemPageSize.GetValue(null, new object[0]);
}
public static void MemCpy(void* pDst, void* pSrc, int len)
{
byte* pDst_ = (byte*)pDst;
byte* pSrc_ = (byte*)pSrc;
for (int i = 0; i < len; i++)
*pDst_++ = *pSrc_++;
}
public static void MemCpy_Jit(void* pDst, byte[] src)
{
fixed(void * p = &src[0])
{
memcpy_jit(new IntPtr(pDst), new IntPtr(p), src.Length);
}
}
/// <summary>
/// set flags of address to `read write execute`
/// </summary>
public static void SetAddrFlagsToRWX(IntPtr ptr, int size) { }
public static void FlushICache(void* code, int size) { }
public static KeyValuePair<long, long> GetPageAlignedAddr(long code, int size)
{
long pagesize = _Pagesize;
long startPage = (code) & ~(pagesize - 1);
long endPage = (code + size + pagesize - 1) & ~(pagesize - 1);
return new KeyValuePair<long, long>(startPage, endPage);
}
const int PRINT_SPLIT = 4;
const int PRINT_COL_SIZE = PRINT_SPLIT * 4;
public static string HexToString(void* ptr, int size, int offset = 0)
{
Func<IntPtr, string> formatAddr = (IntPtr addr__) => IntPtr.Size == 4 ? $"0x{(uint)addr__:x}" : $"0x{(ulong)addr__:x}";
byte* addr = (byte*)ptr;
StringBuilder sb = new StringBuilder(1024);
sb.AppendLine($"addr:{formatAddr(new IntPtr(addr))}");
addr += offset;
size += Math.Abs(offset);
int count = 0;
while (true)
{
sb.Append($"\r\n{formatAddr(new IntPtr(addr + count))}: ");
for (int i = 1; i < PRINT_COL_SIZE + 1; i++)
{
if (count >= size)
goto END;
sb.Append($"{*(addr + count):x2}");
if (i % PRINT_SPLIT == 0)
sb.Append(" ");
count++;
}
}
END:;
return sb.ToString();
}
[DllImport("pthread", SetLastError = true, CallingConvention = CallingConvention.Cdecl)]
private static extern int pthread_jit_write_protect_supported_np();
[DllImport("libMonoHookUtils_OSX", SetLastError = true, CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr memcpy_jit(IntPtr dst, IntPtr src, int len);
}
}
#endif