private void CreateCodePatcher() { long addrOffset = Math.Abs(_targetPtr.ToInt64() - _replacementPtr.ToInt64()); if (LDasm.IsAndroidARM()) { if (IntPtr.Size == 8) { _codePatcher = new CodePatcher_arm64(_targetPtr, _replacementPtr, _proxyPtr); } else if (addrOffset < ((1 << 25) - 1)) { _codePatcher = new CodePatcher_arm32_near(_targetPtr, _replacementPtr, _proxyPtr); } else if (addrOffset < ((1 << 27) - 1)) { _codePatcher = new CodePatcher_arm32_far(_targetPtr, _replacementPtr, _proxyPtr); } else { throw new Exception("address of target method and replacement method are too far, can not hook"); } } else { if (IntPtr.Size == 8) { _codePatcher = new CodePatcher_x64(_targetPtr, _replacementPtr, _proxyPtr); } else { _codePatcher = new CodePatcher_x86(_targetPtr, _replacementPtr, _proxyPtr); } } }
protected override void MakePlacholderMethodCallPointsToRawMethod(MethodBase method) { uint oldProtect; var needSize = LDasm.SizeofMin5Byte(rawMethodPtr); byte[] src_instr = new byte[needSize]; for (int i = 0; i < needSize; i++) { src_instr[i] = rawMethodPtr[i]; } fixed(byte *p = &jmp_inst[3]) { *((ulong *)p) = (ulong)(rawMethodPtr + needSize); } var totalLength = src_instr.Length + jmp_inst.Length; IntPtr ptr = Marshal.AllocHGlobal(totalLength); Marshal.Copy(src_instr, 0, ptr, src_instr.Length); Marshal.Copy(jmp_inst, 0, ptr + src_instr.Length, jmp_inst.Length); NativeAPI.VirtualProtect(ptr, (uint)totalLength, Protection.PAGE_EXECUTE_READWRITE, out oldProtect); RuntimeHelpers.PrepareMethod(method.MethodHandle); *((ulong *)((uint *)method.MethodHandle.Value.ToPointer() + 2)) = (ulong)ptr; }
protected unsafe override void CreateOriginalMethod(MethodInfo method) { uint needSize = LDasm.SizeofMin5Byte((void *)this.srcPtr); byte[] src_instr = new byte[needSize]; int i = 0; while ((long)i < (long)((ulong)needSize)) { src_instr[i] = this.srcPtr[i]; i++; } fixed(byte *p = &this.jmp_inst[3]) { *(long *)p = (long)(this.srcPtr + needSize); } int totalLength = src_instr.Length + this.jmp_inst.Length; IntPtr ptr = Marshal.AllocHGlobal(totalLength); Marshal.Copy(src_instr, 0, ptr, src_instr.Length); Marshal.Copy(this.jmp_inst, 0, ptr + src_instr.Length, this.jmp_inst.Length); uint oldProtect; NativeAPI.VirtualProtect(ptr, (uint)totalLength, Protection.PAGE_EXECUTE_READWRITE, out oldProtect); RuntimeHelpers.PrepareMethod(method.MethodHandle); *(long *)((byte *)method.MethodHandle.Value.ToPointer() + 8) = (long)ptr; }
public void Install() { if (LDasm.IsiOS()) // iOS 不支持修改 code 所在区域 page { return; } if (isHooked) { return; } #if UNITY_EDITOR if (s_fi_GUISkin_current.GetValue(null) != null) { DoInstall(); } else { EditorApplication.update += OnEditorUpdate; } #else DoInstall(); #endif }
protected unsafe virtual void CreateOriginalMethod(MethodInfo method) { uint needSize = LDasm.SizeofMin5Byte((void *)this.srcPtr); int total_length = (int)(needSize + 5U); byte[] code = new byte[total_length]; IntPtr ptr = Marshal.AllocHGlobal(total_length); int i = 0; while ((long)i < (long)((ulong)needSize)) { code[i] = this.srcPtr[i]; i++; } code[(int)((UIntPtr)needSize)] = 233; fixed(byte *p = &code[(int)((UIntPtr)(needSize + 1U))]) { *(int *)p = (int)(this.srcPtr - (uint)((int)ptr) - 5U); } Marshal.Copy(code, 0, ptr, total_length); uint oldProtect; NativeAPI.VirtualProtect(ptr, (uint)total_length, Protection.PAGE_EXECUTE_READWRITE, out oldProtect); RuntimeHelpers.PrepareMethod(method.MethodHandle); *(int *)((byte *)method.MethodHandle.Value.ToPointer() + 8) = (int)ptr; }
static MethodHook() { if (LDasm.IsAndroidARM()) { s_addrOffset = 4; if (IntPtr.Size == 4) { s_jmpBuff = s_jmpBuff_arm32_arm; //if (!LDasm.IsIL2CPP()) // s_jmpBuff = s_jmpBuff_arm32_arm; //else //{ // s_jmpBuff = s_jmpBuff_arm32_thumb; // s_addrOffset = 32; //} } else { s_jmpBuff = s_jmpBuff_arm64; } } else { if (IntPtr.Size == 4) { s_jmpBuff = s_jmpBuff_32; s_addrOffset = 1; } else { s_jmpBuff = s_jmpBuff_64; s_addrOffset = 6; } } }
/// <summary> /// 将对originalMethod的调用指向原函数 /// </summary> /// <param name="originalMethod"></param> protected virtual void MakePlacholderMethodCallPointsToRawMethod(MethodBase originalMethod) { uint oldProtect; var needSize = LDasm.SizeofMin5Byte(rawMethodPtr); var total_length = (int)needSize + 5; byte[] code = new byte[total_length]; IntPtr ptr = Marshal.AllocHGlobal(total_length); //code[0] = 0xcc;//调试用 for (int i = 0; i < needSize; i++) { code[i] = rawMethodPtr[i]; } code[needSize] = 0xE9; fixed(byte *p = &code[needSize + 1]) { *((uint *)p) = (uint)rawMethodPtr - (uint)ptr - 5; } Marshal.Copy(code, 0, ptr, total_length); NativeAPI.VirtualProtect(ptr, (uint)total_length, Protection.PAGE_EXECUTE_READWRITE, out oldProtect); RuntimeHelpers.PrepareMethod(originalMethod.MethodHandle); *((uint *)originalMethod.MethodHandle.Value.ToPointer() + 2) = (uint)ptr; }
public void Install() { if (_targetMethod == null || _replacementMethod == null) { throw new Exception("MethodHook:_targetMethod and _replacementMethod can not be null"); } if (LDasm.IsiOS()) // iOS 不支持修改 code 所在区域 page { return; } if (isHooked) { return; } #if UNITY_EDITOR if (s_fi_GUISkin_current.GetValue(null) != null) { DoInstall(); } else { EditorApplication.update += OnEditorUpdate; } #else DoInstall(); #endif }
private void EnableAddrModifiable(IntPtr ptr, int size) { if (!LDasm.IsIL2CPP()) { return; } IL2CPPHelper.SetAddrFlagsToRWE(ptr, size); }
private void EnableAddrModifiable() { if (!LDasm.IsIL2CPP()) { return; } HookUtils.SetAddrFlagsToRWE(new IntPtr(_pTarget), _targetHeaderBackup.Length); HookUtils.SetAddrFlagsToRWE(new IntPtr(_pProxy), _targetHeaderBackup.Length + _jmpCodeSize); }
private void Start() { StringBuilder sb = new StringBuilder(); sb.AppendFormat("pointer size:{0}\r\n", System.IntPtr.Size); sb.AppendFormat("is IL2CPP:{0}\r\n", LDasm.IsIL2CPP()); sb.AppendFormat("operation name:{0}\r\n", SystemInfo.operatingSystem); sb.AppendFormat("processorType:{0}\r\n", SystemInfo.processorType); sb.AppendLine(); txtInfo.text = sb.ToString(); }
private void EnableAddrModifiable(IntPtr ptr, uint size) { if (!LDasm.IsIL2CPP()) { return; } uint oldProtect; bool ret = IL2CPPHelper.VirtualProtect(ptr, size, IL2CPPHelper.Protection.PAGE_EXECUTE_READWRITE, out oldProtect); Debug.Assert(ret); }
/// <summary> /// 备份原始方法头 /// </summary> private void BackupHeader() { byte *pTarget = (byte *)_targetPtr.ToPointer(); uint requireSize = LDasm.SizeofMinNumByte(pTarget, s_jmpCode.codeSize); _targetHeaderBackup = new byte[requireSize]; for (int i = 0, imax = _targetHeaderBackup.Length; i < imax; i++) { _targetHeaderBackup[i] = *pTarget++; } }
protected void BackupHeader() { if (_targetHeaderBackup != null) { return; } uint requireSize = LDasm.SizeofMinNumByte(_pTarget, _jmpCodeSize); _targetHeaderBackup = new byte[requireSize]; fixed(void *ptr = _targetHeaderBackup) HookUtils.MemCpy(ptr, _pTarget, _targetHeaderBackup.Length); }
static MethodHook() { if (LDasm.IsAndroidARM()) { s_jmpCode = IntPtr.Size == 4 ? s_jmpCode_arm32_arm : s_jmpCode_arm64; } else // x86/x64 { s_jmpCode = IntPtr.Size == 4 ? s_jmpCode_x86 : s_jmpCode_x64; } #if UNITY_EDITOR s_fi_GUISkin_current = typeof(GUISkin).GetField("current", BindingFlags.Static | BindingFlags.NonPublic); #endif }
public void Install() { if (LDasm.IsiOS()) // iOS 不支持修改 code 所在区域 page { return; } if (isHooked) { return; } HookPool.AddHooker(_targetMethod, this); InitProxyBuff(); BackupHeader(); PatchTargetMethod(); PatchProxyMethod(); isHooked = true; }
/// <summary> /// 获取对应函数jit后的native code的地址 /// </summary> private bool GetFunctionAddr() { _targetPtr = GetFunctionAddr(_targetMethod); _replacementPtr = GetFunctionAddr(_replacementMethod); if (_proxyMethod != null) { _proxyPtr = GetFunctionAddr(_proxyMethod); } if (_targetPtr == IntPtr.Zero || _proxyPtr == IntPtr.Zero) { return(false); } if (LDasm.IsThumb(_targetPtr) || LDasm.IsThumb(_replacementPtr)) { throw new Exception("does not support thumb arch"); } return(true); }
/// <summary> /// 获取方法指令地址 /// </summary> /// <param name="method"></param> /// <returns></returns> private IntPtr GetFunctionAddr(MethodBase method) { if (!LDasm.IsIL2CPP()) { return(method.MethodHandle.GetFunctionPointer()); } else { __ForCopy __forCopy = new __ForCopy() { method = method }; long *ptr = &__forCopy.__dummy; ptr++; // addr of _forCopy.method IntPtr methodAddr = IntPtr.Zero; if (sizeof(IntPtr) == 8) { long methodDataAddr = *(long *)ptr; byte *ptrData = (byte *)methodDataAddr + sizeof(IntPtr) * 2; // offset of Il2CppReflectionMethod::const MethodInfo *method; long methodPtr = 0; methodPtr = *(long *)ptrData; methodAddr = new IntPtr(*(long *)methodPtr); // MethodInfo::Il2CppMethodPointer methodPointer; } else { int methodDataAddr = *(int *)ptr; byte *ptrData = (byte *)methodDataAddr + sizeof(IntPtr) * 2; // offset of Il2CppReflectionMethod::const MethodInfo *method; int methodPtr = 0; methodPtr = *(int *)ptrData; methodAddr = new IntPtr(*(int *)methodPtr); } return(methodAddr); } }
public void Install() { if (LDasm.IsiOS()) // iOS 不支持修改 code 所在区域 page { return; } if (isHooked) { return; } HookPool.AddHooker(_targetMethod, this); InitProxyBuff(); BackupHeader(); PatchTargetMethod(); PatchProxyMethod(); HookLog.LogFormat($"hook \"{_targetMethod.Name}\" success!!!"); isHooked = true; }
/// <summary> /// 获取方法指令地址 /// </summary> /// <param name="method"></param> /// <returns></returns> private IntPtr GetFunctionAddr(MethodBase method) { if (!LDasm.IsIL2CPP()) { return(method.MethodHandle.GetFunctionPointer()); } else { /* * // System.Reflection.MonoMethod * typedef struct Il2CppReflectionMethod * { * Il2CppObject object; * const MethodInfo *method; * Il2CppString *name; * Il2CppReflectionType *reftype; * } Il2CppReflectionMethod; * * typedef Il2CppClass Il2CppVTable; * typedef struct Il2CppObject * { * union * { * Il2CppClass *klass; * Il2CppVTable *vtable; * }; * MonitorData *monitor; * } Il2CppObject; * * typedef struct MethodInfo * { * Il2CppMethodPointer methodPointer; // this is the pointer to native code of method * InvokerMethod invoker_method; * const char* name; * Il2CppClass *klass; * const Il2CppType *return_type; * const ParameterInfo* parameters; * // ... * } */ __ForCopy __forCopy = new __ForCopy() { method = method }; long *ptr = &__forCopy.__dummy; ptr++; // addr of _forCopy.method IntPtr methodAddr = IntPtr.Zero; if (sizeof(IntPtr) == 8) { long methodDataAddr = *(long *)ptr; byte *ptrData = (byte *)methodDataAddr + sizeof(IntPtr) * 2; // offset of Il2CppReflectionMethod::const MethodInfo *method; long methodPtr = 0; methodPtr = *(long *)ptrData; methodAddr = new IntPtr(*(long *)methodPtr); // MethodInfo::Il2CppMethodPointer methodPointer; } else { int methodDataAddr = *(int *)ptr; byte *ptrData = (byte *)methodDataAddr + sizeof(IntPtr) * 2; // offset of Il2CppReflectionMethod::const MethodInfo *method; int methodPtr = 0; methodPtr = *(int *)ptrData; methodAddr = new IntPtr(*(int *)methodPtr); } return(methodAddr); } }