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
    }
Exemple #5
0
        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;
        }
Exemple #6
0
 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;
        }
Exemple #8
0
    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
    }
Exemple #9
0
    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);
    }
Exemple #11
0
    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();
    }
Exemple #12
0
    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);
    }
Exemple #13
0
    /// <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);
    }
Exemple #15
0
    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
    }
Exemple #16
0
    public void Install()
    {
        if (LDasm.IsiOS()) // iOS 不支持修改 code 所在区域 page
        {
            return;
        }

        if (isHooked)
        {
            return;
        }

        HookPool.AddHooker(_targetMethod, this);

        InitProxyBuff();
        BackupHeader();
        PatchTargetMethod();
        PatchProxyMethod();

        isHooked = true;
    }
Exemple #17
0
    /// <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);
    }
Exemple #18
0
    /// <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);
        }
    }
Exemple #19
0
        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);
        }
    }