/// <summary> /// 备份原始方法头 /// </summary> protected virtual void BackupHeader() { byte *pTarget = (byte *)_targetPtr.ToPointer(); _backupArray = new byte[_headSize]; for (int i = 0; i < _headSize; i++) { if (_proxyPtr != null) { _proxyPtr[i] = pTarget[i]; } _backupArray[i] = pTarget[i]; } if (_proxyPtr != null) { int index = 0; if (LDasm.CheckShortCall(_proxyPtr, s_jmpBuff.Length, out index)) { if (!NativeAPI.IsAndroidARM()) { // 目标地址 = 偏移 + 5 + 指令地址 int oldOffsetAddr = *((int *)(_proxyPtr + index + 1)); long targetAddr = oldOffsetAddr + 5 + (long)_targetPtr + index; // 因为指令地址发生了改变,所以要重新计算偏移 公式: 偏移 = 目标地址 - 指令地址 - 5 int newOffsetAddr = (int)(targetAddr - ((long)_proxyPtr + index) - 5); *((int *)(_proxyPtr + index + 1)) = newOffsetAddr; } } } }
/// <summary> /// 备份原始方法头 /// </summary> protected virtual void BackupHeader() { byte *pTarget = (byte *)_targetPtr.ToPointer(); _backupArray = new byte[_headSize]; for (int i = 0; i < _headSize; i++) { if (_proxyPtr != null) { _proxyPtr[i] = pTarget[i]; } _backupArray[i] = pTarget[i]; } if (_proxyPtr != null) { int index = 0; if (LDasm.CheckShortCall(_proxyPtr, s_jmpBuff.Length, out index)) { if (IntPtr.Size == 8) { // 目标地址 = 偏移 + 5 + 指令地址 int oldOffsetAddr = *((int *)(_proxyPtr + index + 1)); long targetAddr = oldOffsetAddr + 5 + (long)_targetPtr + index; fixed(byte *p = &s_jmpBuff[s_addrOffset]) { IntPtr *ptr = (IntPtr *)p; *ptr = (IntPtr)targetAddr; } // 原来的跳转指令长度为5,现在为 14所以把_headsize 拓宽 _headSize = _headSize - 5 + 14; for (int i = index; i < 14 + index; i++) { _proxyPtr[i] = s_jmpBuff[i - index]; } } else { // 目标地址 = 偏移 + 5 + 指令地址 int oldOffsetAddr = *((int *)(_proxyPtr + index + 1)); long targetAddr = oldOffsetAddr + 5 + (long)_targetPtr + index; // 因为指令地址发生了改变,所以要重新计算偏移 公式: 偏移 = 目标地址 - 指令地址 - 5 int newOffsetAddr = (int)(targetAddr - ((long)_proxyPtr + index) - 5); *((int *)(_proxyPtr + index + 1)) = newOffsetAddr; } } } }
/// <summary> /// 创建一个 native Hooker /// </summary> /// <param name="libraryName">C/C++ 本地库名字</param> /// <param name="symbol">方法符号</param> /// <param name="replace">替换委托</param> public NativeMethodHooker(string libraryName, string symbol, Delegate replace) { SetupJmpBuff(); IntPtr targetPtr = NativeAPI.miku_hooker_get_address(libraryName, symbol); _headSize = (int)LDasm.SizeofMinNumByte(targetPtr.ToPointer(), s_jmpBuff.Length); _proxyBuffSize = _headSize + s_jmpBuff.Length; _targetPtr = targetPtr; _replacPtr = Marshal.GetFunctionPointerForDelegate(replace); _proxyPtr = (byte *)NativeAPI.miku_hooker_jit_alloc(IntPtr.Zero, _proxyBuffSize); Install(); }
/// <summary> /// 创建一个 Hooker /// </summary> /// <param name="target">需要替换的目标方法</param> /// <param name="replace">准备好的替换方法</param> private CSharpMethodHooker(MethodBase target, MethodBase replace, MethodBase proxy) { SetupJmpBuff(); IntPtr targetPtr = NativeAPI.GetFunctionAddr(target); IntPtr replacePtr = NativeAPI.GetFunctionAddr(replace); IntPtr proxyPtr = NativeAPI.GetFunctionAddr(proxy); _headSize = (int)LDasm.SizeofMinNumByte(targetPtr.ToPointer(), s_jmpBuff.Length); _proxyBuffSize = _headSize + s_jmpBuff.Length; _proxyPtr = (byte *)proxyPtr.ToPointer(); _targetPtr = targetPtr; _replacPtr = replacePtr; Install(); }