Exemple #1
0
        public static IntPtr ResolveICall(string signature)
        {
            MelonDebug.Msg("Resolving ICall " + signature);
            IntPtr icallPtr;

            if (MelonUtils.IsGameIl2Cpp())
            {
                icallPtr = il2cpp_resolve_icall(signature);
            }
            else
            {
                // We generate a fake MonoMethod + MonoMethodSignature + MonoClass struct to exploit the lookup code and force resolve our icall without the class/method being registered
                // (Slaynash: Yes this is illegal)
                MonoMethod *monoMethod = IcallToFakeMonoMethod(signature);
                icallPtr = mono_lookup_internal_call((IntPtr)monoMethod);
                DestroyFakeMonoMethod(monoMethod);
            }

            if (icallPtr == IntPtr.Zero)
            {
                //MelonLogger.Error($"ICall {signature} not resolved");
                //return IntPtr.Zero;
                throw new Exception($"ICall {signature} not resolved");
            }
            MelonDebug.Msg($" > 0x{(long)icallPtr:X}");

            return(icallPtr);
        }
Exemple #2
0
 private static unsafe void DestroyFakeMonoMethod(MonoMethod *monoMethod)
 {
     Marshal.FreeHGlobal((IntPtr)monoMethod->signature);
     Marshal.FreeHGlobal(*(IntPtr *)((long)&monoMethod->klass->nested_in_0x04 + monoClassOffset));
     Marshal.FreeHGlobal(*(IntPtr *)((long)&monoMethod->klass->nested_in_0x08 + monoClassOffset));
     Marshal.FreeHGlobal((IntPtr)monoMethod->klass);
     Marshal.FreeHGlobal((IntPtr)monoMethod->name);
     Marshal.FreeHGlobal((IntPtr)monoMethod);
 }
Exemple #3
0
        private static unsafe MonoMethod *IcallToFakeMonoMethod(string icallName)
        {
            string[] typeAndMethod    = icallName.Split(new[] { "::" }, StringSplitOptions.None);
            int      parenthesisIndex = typeAndMethod[1].IndexOf('(');

            if (parenthesisIndex >= 0)
            {
                typeAndMethod[1] = typeAndMethod[1].Substring(0, parenthesisIndex);
            }
            // We add a padding to the end of each allocated memory since our structs are supposed to be bigger than the one we have here
            MonoMethod *monoMethod = (MonoMethod *)Marshal.AllocHGlobal(sizeof(MonoMethod) + 0x100);

            monoMethod->applyZeroes();
            monoMethod->klass = (MonoClass *)Marshal.AllocHGlobal(sizeof(MonoClass) + 0x100);
            monoMethod->klass->applyZeroes();
            monoMethod->name = (byte *)Marshal.StringToHGlobalAnsi(typeAndMethod[1]);
            int lastDotIndex = typeAndMethod[0].LastIndexOf('.');

            if (lastDotIndex < 0)
            {
                *(IntPtr *)((long)&monoMethod->klass->nested_in_0x08 + monoClassOffset) = Marshal.StringToHGlobalAnsi("");
                *(IntPtr *)((long)&monoMethod->klass->nested_in_0x04 + monoClassOffset) = Marshal.StringToHGlobalAnsi(typeAndMethod[0]);
            }
            else
            {
                string name_space = typeAndMethod[0].Substring(0, lastDotIndex);
                string name       = typeAndMethod[0].Substring(lastDotIndex + 1);
                *(IntPtr *)((long)&monoMethod->klass->nested_in_0x08 + monoClassOffset) = Marshal.StringToHGlobalAnsi(name_space);
                *(IntPtr *)((long)&monoMethod->klass->nested_in_0x04 + monoClassOffset) = Marshal.StringToHGlobalAnsi(name);
            }

            MonoMethodSignature *monoMethodSignature = (MonoMethodSignature *)Marshal.AllocHGlobal(sizeof(MonoMethodSignature));

            monoMethodSignature->ApplyZeroes();
            monoMethod->signature = monoMethodSignature;

            return(monoMethod);
        }