Category PS4 Jailbreaking       Thread starter PSXHAX       Start date Nov 22, 2016 at 10:41 PM       10,600       18            
Last week we saw a PS4 API Demo from them, and today PlayStation 4 developers @kurt2467 and @BadChoicesZ are back with some more PS4 GTA V hax with full natives working... meaning any hacks that were possible on PS3 are now possible on Sony's PlayStation 4 console! :thumbup:

Here's the latest Grand Theft Auto V PS4 video demo from kurt2467's YouTube channel with the caption below, to quote: [PS4] Some More GTA V Hax

I finally got all of the natives to work! This means that anything that was possible on PS3, is possible on PS4 :D

PlayStation 4 GTAV Modding C# Code by Kurt2467 (Remote Procedure Calls)
From Pastebin.com: [PS4] GTA V RPC
Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace PS4_GTA
{
    public class RPC
    {
		private uint nativeArgBase = 0;
        private uint hookAddress = 0;
        private uint rpcCodeAddress = 0;
        private List<uint> nativeFuncList = new List<uint>();
        private List<UInt64> nativeHashList = new List<UInt64>();

        public RPC()
        {
            nativeArgBase = 0x2DCD820;
            hookAddress = 0xD8F480;
            rpcCodeAddress = 0x5046D0;
        }

        public void InitRPC()
        {
            WriteU64(nativeArgBase, 0);
            byte[] hook = new byte[] {
                0x55, //push rbp
                0xE8, 	0x4A, 	0x52, 	0x77, 	0xFF, //call 0x5046D0
                0x5D, //pop rbp
                0xC3, //retn
            };
            byte[] asmx86 = new byte[] { 
                0x55, //push rbp
                0x41, 	0x52, //push r10
                0x53, //push rbx
                0x49, 	0xC7, 	0xC2, 	0x20, 	0xD8, 	0xDC, 	0x02, //mov r10, 0x2DCD820
                0x49, 	0x8B, 	0x1A, //mov rbx, [r10]
                0x48, 	0x85, 	0xDB, //test rbx, rbx
                0x74, 	0x1A, //jz 0x5046FB
                0x48, 	0xC7, 	0xC7, 	0x30, 	0xD8, 	0xDC, 	0x02, //mov rdi, 0x2DCD830
                0xFF, 	0xD3, //call rbx
                0x49, 	0xC7, 	0xC2, 	0x20, 	0xD8, 	0xDC, 	0x02, //mov r10, 0x2DCD820
                0x48, 	0xC7, 	0xC3, 	0x00, 	0x00, 	0x00, 	0x00, //mov rbx, 0
                0x49, 	0x89, 	0x1A, //mov [r10], rbx
                0x5B, //pop rbx
                0x41, 	0x5A, //pop r10
                0x5D, //pop rbp
                0xC3, //retn
            };
            SetMemory(rpcCodeAddress, asmx86);
            SetMemory(hookAddress, hook);
            WriteU64(nativeArgBase + 0x10, nativeArgBase + 0x50);
            WriteU64(nativeArgBase + 0x20, nativeArgBase + 0x70);
        }

        public uint GetNativeAddress(UInt64 nativeHash)
        {
            uint nativeTable, index;
            UInt64 nativeAddy;
            nativeTable = 0x3644A28;
            index = (uint)nativeHash & 0xFF;
            nativeAddy = ReadU64(nativeTable + (index * 8));
            while (nativeAddy != 0)
            {
                uint count = ReadU32(nativeAddy + 0x40);
                for (uint i = 0; i < count; i++)
                {
                    UInt64 hash = ReadU64(nativeAddy + 0x48 + (i * 8));
                    if (hash == nativeHash)
                    {
                        return ReadU32(nativeAddy + 0x8 + (i * 8));
                    }
                }
                nativeAddy = ReadU64(nativeAddy);
            }
            return 0;
        }

        public T CallRaw<T>(UInt64 address, params object[] args)
        {
            byte[] argBytes = new byte[0xA0];
            ArrayBuilder ab = new ArrayBuilder(argBytes);
            uint argStart = nativeArgBase + 0x70;
            uint strStart = nativeArgBase + 0x120;
            uint strCount = 0;
            uint nativeArgCount = 0;
            for (int i = 0; i < args.Length; i++)
            {
                if (args[i] is float)
                {
                    ab.Write.SetFloat((int)nativeArgCount * 8, (float)args[i], ArrayBuilder.ArrayWriter.EndianType.LittleEndian);
                    nativeArgCount++;
                }
                else if (args[i] is string)
                {
                    uint strPtr = (uint)strStart + (strCount * 0x20);
                    WriteString(strPtr, (string)args[i]);
                    ab.Write.SetUInt32((int)nativeArgCount * 8, strPtr, ArrayBuilder.ArrayWriter.EndianType.LittleEndian);
                    strCount++;
                    nativeArgCount++;
                }
                else if (args[i] is int)
                {
                    ab.Write.SetInt32((int)nativeArgCount * 8, (int)args[i], ArrayBuilder.ArrayWriter.EndianType.LittleEndian);
                    nativeArgCount++;
                }
                else
                {
                    UInt64 tmp = Convert.ToUInt64(args[i]);
                    ab.Write.SetUInt64((int)nativeArgCount * 8, tmp, ArrayBuilder.ArrayWriter.EndianType.LittleEndian);
                    nativeArgCount++;
                }
            }
            SetMemory(argStart, argBytes);
            System.Threading.Thread.Sleep(10);
            WriteU64(nativeArgBase, (UInt64)address);
            System.Threading.Thread.Sleep(30);
            object ret = 0;
            if (typeof(T).ToString() == "System.Int32")
            {
                ret = ReadI32(nativeArgBase + 0x50);
                ret = (T)Convert.ChangeType(ret, typeof(T));
            }
            if (typeof(T).ToString() == "System.Int64")
            {
                ret = ReadI64(nativeArgBase + 0x50);
                ret = (T)Convert.ChangeType(ret, typeof(T));
            }
            if (typeof(T).ToString() == "System.UInt32")
            {
                ret = ReadU32(nativeArgBase + 0x50);
                ret = (T)Convert.ChangeType(ret, typeof(T));
            }
            if (typeof(T).ToString() == "System.UInt64")
            {
                ret = ReadU64(nativeArgBase + 0x50);
                ret = (T)Convert.ChangeType(ret, typeof(T));
            }
            if (typeof(T).ToString() == "System.Single")
            {
                ret = ReadFloat(nativeArgBase + 0x50);
                ret = (T)Convert.ChangeType(ret, typeof(T));
            }
            if (typeof(T).ToString() == "System.Single[]")
            {
                float[] fRet = new float[3];
                fRet[0] = ReadFloat(nativeArgBase + 0x50);
                fRet[1] = ReadFloat(nativeArgBase + 0x58);
                fRet[2] = ReadFloat(nativeArgBase + 0x60);
                ret = (T)Convert.ChangeType(fRet, typeof(T));
            }
            return (T)ret;
        }

        public T CallFunc<T>(UInt64 nativeAddress, params object[] args)
        {
            return CallRaw<T>(nativeAddress, args);
        }

        public T CallHash<T>(UInt64 nativeHash, params object[] args)
        {
            uint func;
            if (nativeHashList.Contains((UInt64)nativeHash))
                func = nativeFuncList[nativeHashList.IndexOf((UInt64)nativeHash)];
            else
                func = GetNativeAddress((UInt64)nativeHash);
            if (func != 0)
            {
                nativeHashList.Add((UInt64)nativeHash);
                nativeFuncList.Add(func);
                return CallRaw<T>(func, args);
            }
            return (T)Convert.ChangeType(0, typeof(T));
        }
	}
}
From Pastebin.com: ArrayBuilder.cs
Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace PS4_GTA
{
    public class ArrayBuilder
    {
        private byte[] buffer;
        private int size;

        public ArrayWriter Write
        {
            get
            {
                return new ArrayWriter(this.buffer);
            }
        }
        public ArrayBuilder(byte[] bytes)
        {
            this.buffer = bytes;
            this.size = bytes.Length;
        }
        public class ArrayWriter
        {
            private byte[] buffer;
            private int size;

            public enum EndianType
            {
                LittleEndian,
                BigEndian
            };

            public ArrayWriter(byte[] bytes)
            {
                this.buffer = bytes;
                this.size = bytes.Length;
            }

            public void SetByte(int pos, byte value)
            {
                this.buffer[pos] = value;
            }
            public void SetInt32(int pos, int value, EndianType Type = EndianType.BigEndian)
            {
                byte[] bytes = BitConverter.GetBytes(value);
                if (Type == EndianType.BigEndian)
                    Array.Reverse(bytes, 0, 4);
                for (int i = 0; i < 4; i++)
                    this.buffer[i + pos] = bytes[i];
            }
            public void SetInt64(int pos, Int64 value, EndianType Type = EndianType.BigEndian)
            {
                byte[] bytes = BitConverter.GetBytes(value);
                if (Type == EndianType.BigEndian)
                    Array.Reverse(bytes, 0, 8);
                for (int i = 0; i < 8; i++)
                    this.buffer[i + pos] = bytes[i];
            }
            public void SetUInt32(int pos, uint value, EndianType Type = EndianType.BigEndian)
            {
                byte[] bytes = BitConverter.GetBytes(value);
                if (Type == EndianType.BigEndian)
                    Array.Reverse(bytes, 0, 4);
                for (int i = 0; i < 4; i++)
                    this.buffer[i + pos] = bytes[i];
            }
            public void SetUInt64(int pos, UInt64 value, EndianType Type = EndianType.BigEndian)
            {
                byte[] bytes = BitConverter.GetBytes(value);
                if (Type == EndianType.BigEndian)
                    Array.Reverse(bytes, 0, 8);
                for (int i = 0; i < 8; i++)
                    this.buffer[i + pos] = bytes[i];
            }
            public void SetBytes(int pos, byte[] value)
            {
                for (int i = 0; i < value.Length; i++)
                    this.buffer[i + pos] = value[i];
            }
            public void SetString(int pos, string str)
            {
                byte[] bytes = Encoding.UTF8.GetBytes(str + '\0');
                for (int i = 0; i < bytes.Length; i++)
                    this.buffer[i + pos] = bytes[i];
            }
            public void SetFloat(int pos, float value, EndianType Type = EndianType.BigEndian)
            {
                byte[] bytes = BitConverter.GetBytes(value);
                if (Type == EndianType.BigEndian)
                    Array.Reverse(bytes, 0, 4);
                for (int i = 0; i < 4; i++)
                    this.buffer[i + pos] = bytes[i];
            }
        }
    }
}
Thanks @raedoob and @GrimDoe for sharing the news in the PSXHAX Shoutbox! <3
PS4 GTA V Hax Demo Anything on PS3 Now Possible on PlayStation 4.jpg
 

Comments

Recent Articles
Red Dead Redemption 2 PS4 Models and Textures Tool by ID-Daemon
Following his Spider-Man PS4 Skeletal Models & Textures Tool release and the recent RDR2 PS4 Modding Demos data miner @iddaemon (aka ID-Daemon) shared details on his Red Dead Redemption 2 PS4...
3D Renders of Rumored PS5 / PlayStation 5 Development Kit Patent Design
Proceeding the rumored PS5 / PlayStation 5 DevKit Patent that surfaced earlier this week, today some artist renditions based on the Sony patent have surfaced for those seeking a closer look at the...
Latest PlayStation 4 Game Trailer Videos from Gamescom 2019
Earlier this week we saw a Call of Duty: Modern Warfare 2v2 Alpha PS4 trailer video from Gamescom 2019, and below is some more fresh PlayStation 4 video game footage from this year's Gamescom...
Chiaki: Free and Open Source PS4 Remote Play Client by Thestr4ng3r!
Last month we reported on a PS4 Remote Play open source client in development by thestr4ng3r, and today he released Chiaki... the first free and open source PS4 Remote Play client software for...
Top