Example #1
0
        private int FindUnityVersion(uint exitFuncPtr)
        {
            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");
            }

            uint      magic_val       = 0x6F6E6F6D; // "mono"
            ValueImpl exitFuncPtrAddr = _vita.CreateIntPtr(UIntToVitaInt(exitFuncPtr - 1));

            // Check for Unity 1.05
            ValueImpl offset = new ValueImpl();

            offset.Value = 0x110D08;
            ValueImpl val = _vita.RunMethod(methid_readint32, null, new ValueImpl[] { exitFuncPtrAddr, offset });

            if (VitaIntToUInt((Int32)val.Value) == magic_val)
            {
                return(0x105);
            }

            // Check for Unity 1.06
            offset.Value = 0x110C00;
            val          = _vita.RunMethod(methid_readint32, null, new ValueImpl[] { exitFuncPtrAddr, offset });

            if (VitaIntToUInt((Int32)val.Value) == magic_val)
            {
                return(0x106);
            }

            throw new InvalidOperationException("Unsupported Unity version!");
            return(0x0);
        }
Example #2
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
            uint      mono_images_init_addr = addr - 1 + 0x1206;
            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 PSM_111
            uint import_table = addr - 1 + 0x12dbaa;
#else
            uint import_table = addr - 1 + 0x12D7A2;
#endif
            ValueImpl faddr = _vita.CreateIntPtr(UIntToVitaInt(import_table));
            offset.Value = 0x184;
            ValueImpl fval = _vita.RunMethod(methid_readint32, null, new ValueImpl[] { faddr, offset });
            unlock_fptr  = VitaIntToUInt((Int32)fval.Value);
            offset.Value = 0x198;
            fval         = _vita.RunMethod(methid_readint32, null, new ValueImpl[] { faddr, offset });
            lock_fptr    = VitaIntToUInt((Int32)fval.Value);
            offset.Value = 0x350;
            fval         = _vita.RunMethod(methid_readint32, null, new ValueImpl[] { faddr, offset });
            free_fptr    = VitaIntToUInt((Int32)fval.Value);
#if PSM_111
            offset.Value = 0x460;
#else
            offset.Value = 0x468;
#endif
            fval         = _vita.RunMethod(methid_readint32, null, new ValueImpl[] { faddr, offset });
            alloc_fptr   = VitaIntToUInt((Int32)fval.Value);
            offset.Value = 0x40;
            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;
#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);
        }