Game hacking sous Playstation 4

Écrit par l’équipe HackGyver12 juin 2026

Table des matières

Introduction

Ce tutoriel fait suite à la séance en présentiel HackGyver du vendredi 12 juin 2026, consacrée au game hacking sur PS4.

hg_conf

Nous allons voir ici comment tricher dans vos jeux PS4 favoris en scannant et modifiant la mémoire à la volée.

La PS4 possède une architecture x86-64 très similaire à celle des ordinateurs modernes.

Ainsi, ceux qui ont déjà des bases en lecture de code assembleur x64 ne seront pas trop dépaysés.

La liste d’outils

Ce tutoriel utilisera une PS4 sous firmware v11.00 avec GoldHEN v2.4b18.

Comme jeu cobaye, on va utiliser Cyberpunk 2077 v1.60 et God Of War 3 Remastered v01.01.

Installation de ps4debug

Depuis le menu de la console, aller dans Paramètres, puis tout au-dessus on accède au Menu GoldHEN.

Ensuite on va dans Servers Settings et on active l'option Enable BinLoader Server.

On note au passage l'adresse IP.

binloader

Nous pouvons maintenant ouvrir Reaper Studio, puis dans le menu Tools on ouvre Payload Injector.

On rentre les infos de la notification BinLoader, on met l'IP de la console et on sélectionne comme payload ps4debug, ensuite il n'y a plus qu'à injecter.

payloadinjector

Si tout va bien, sur votre console ceci doit s'afficher dans le coin gauche de l'écran.

Vous pouvez maintenant lancer le jeu.

ps4debug

Munitions illimitées: Trouver le pointeur

Allez, on rentre dans le vif du sujet, ouvrez PS4 Cheater, entrer l'IP de la console, cliquer sur Refresh.

Sur la console, assurez vous que la cible (Cyberpunk 2077) soit déjà lancée.

Puis sélectionner le processus eboot.bin

Un peu plus bas, sélectionner toutes les régions mémoire en cochant Select All

Aller en jeu, rentrer le nombre de munition que vous avez dans le chargeur de votre arme en main (pas ceux de la réserve).

Pour moi ça sera 4

Laisser en 4 bytes car ce genre de compteur est souvent un Int32 et Exact Value puis cliquer sur First Scan

Il faudra ensuite patienter le temps que PS4 cheater parcourt la mémoire du processus à la recherche de nos valeurs.

ps4cheater1

Une fois le scan terminé, les premiers résultats apparaissent.

Il va falloir les réduire, pour cela, retourner en jeu et tirer une cartouche pour décrémenter le compteur.

Retourner sur PS4 Cheater, rentrer le nouveau nombre, puis cliquer sur Next Scan

répéter l'opération d'affinage pour réduire les résultats au minimum.

À force d'essayer, il ne nous reste plus que 15 résultats qui semblent tous suivre le compteur de munition.

Double-cliquez sur les valeurs pour les faires passer dans la fenêtre d'édition du bas.

Puis essayer de changer une valeur, appliquer le changement en cliquant sur le bouton X retourner dans le jeu et observer votre compteur.

Si le compteur n'augmente pas, répéter l'opération avec une autre valeur, jusqu'à trouver la bonne.

Dans notre cas le bon pointeur sera 0x1049EC45D8

ps4cheater2

Reaper Studio: Utilisation du débogueur

On retourne maintenant sur Reaper Studio, dans la barre du menu rentrer l'adresse IP de la console.

Puis depuis le menu PS4 cliquer sur Connect

Votre console affichera alors une notification pour dire que Reaper studio est connecté..

En dessous du menu, sélectionner le process eboot.bin comme avec PS4 Cheater.

Une nouvelle boite de dialogue s'affiche ensuite et vous demande le nom de votre projet, mettez ce que vous voulez puis cliquer sur OK

rs_1

Basculer maintenant sur l'onglet Debugger et cliquer sur le bouton Attach debugger

Une notification arrive aussi sur la console pour vous notifier que le débogueur est attaché.

Une fois attaché, le contenu de l'onglet Debugger se déverrouille, voici l'interface:

rs_2

La WatchPoint List est ce que nous allons utiliser en premier.

Un WatchPoint surveille une adresse mémoire et interrompt l'exécution du jeu dès qu'elle est lue ou écrite.

Dans la colonne Adress on rentre 0x1049EC45D8, puis on clique sur Enable

Il n'y a plus que retourner dans le jeu et tirer une balle, si tout va bien votre console devrait freeze.

La fenêtre du désassembleur s'affiche dans Reaper Studio stoppé sur un opcode qui a tenté de modifier notre pointeur.

Félicitations, vous déboguez maintenant votre process de PS4.

rs_3

Interprétons un peu ce que nous observons, nous sommes stoppés sur la ligne cmp byte ptr [r14+0x2BA],0

Sur la ligne d'avant nous avons: mov dword ptr [r14+0x2E8],ebx

Dans la fenêtre des registres, on observe que RBX contient 0x1, la valeur actuelle de mon chargeur (une balle)

Cette valeur est ensuite transmise dans notre pointeur à l'adresse r14+0x2E8 (0x1049EC45D8)

Ce qui a provoqué l'arrêt.

mov  eax,dword ptr [r14+0x2E8]
mov  rdi,qword ptr [r14+0x340]
cmp  ax,r13w
cmovbe r13d,eax
sub  eax,r13d
mov  dword ptr [rbp-0x78],r13d
movzx ebx,ax
mov  esi,ebx
call 0x0000000001F5FDB0
mov  dword ptr [r14+0x2E8],ebx
cmp  byte ptr [r14+0x2BA],0
je   0x0000000001F84871
mov  rdi,qword ptr [rbp-0x60]
test rdi,rdi
je   0x0000000001F84871
mov  rax,qword ptr [rdi]
call qword ptr [rax+0x1C0]
vmovdqu xmm0,xmmword ptr [r14+0x288]
lea  rsi,[rbp-0x50]
mov  rdi,rax
vmovdqu xmmword ptr [rbp-0x50],xmm0

Nous pouvons remplacer l'instruction mov dword ptr [r14+0x2E8],ebx par des NOPs pour empêcher d'écrire sur le pointeur, ainsi celui ci ne changera plus.

Ou faire un peu plus propre en manipulant EBX, on va faire ça.

En dessous du menu de Reaper, entrer dans le champ Adress: 0x1F84828 puis cliquer sur Disassemble

Faites ensuite un clic droit sur la ligne call 0x0000000001F5FDB0 et depuis le menu contextuel: Patch selection > Direct

Un dialogue Patch Label apparaît vous demandant un nom pour ce patch, mettez y un truc du genre: Munitions inf !

Ensuite une deuxième fenêtre s'affiche Find unique AOB (Array Of Bytes) on clique sur Yes

Comme les programmes modernes utilisent l'ASLR, les adresses changent à chaque exécution.

L'AOB permet de chercher automatiquement une séquence de code plus large unique autour de cette instruction pour être sûr qu'il n'y a qu'une seule occurrence dans tout le binaire.

De cette manière, à chaque redémarrage on saura retrouver exactement la bonne séquence du binaire pour le patcher.

Bon maintenant nous sommes dans un nouvel onglet Patch

A gauche cliquer sur l'onglet Activated value et remplacer le code par: mov ebx, 0x3E7

0x3E7 correspond a 999 en décimal, ici notre instruction se traduit par: prend 999, et place le dans EBX.

Pour passer de la valeur décimale à son équivalent facilement en hex, vous pouvez utiliser la calculette de reaper studio.

rs_4

Cliquer sur le bouton Check Validation puis sur l'icone Enregistrer.

Une boite de dialogue s'affiche pour vous confirmer la sauvegarde, et votre fenêtre Project Explorer contient maintenant 1 patch.

Il n'y a plus qu'à tester la logique maintenant..

Retourner dans l'onglet Debugger et dans la WatchPoint List décocher Enable pour le breakpoint en 0x1049EC45D8

Ensuite reprenez l'execution du processus PS4 en cliquant sur l'icone 'Run' qui est à côté du champ de selection du processus.

Le jeu a repris maintenant son exécution..

Revenez sur l'onglet Project Info, et cliquer sur Attach Trainer

Une notification apparait sur la console, en parallèle sur Reaper cliquer sur votre patch Munitions inf ! pour l'activer

Il n'y a plus qu'à tester !

munitions

ça marche !

Les mêmes techniques s'appliquent à n'importe quelle valeur du jeu: argent, grenades, statistiques...

Code cave avec variable

Dans le cas de modifications plus lourdes nécessitant la réécriture de plusieurs ligne d'assembleur il faut utiliser ce qu'on appelle un codecave:

faire un patch dans la routine pour faire un saut ailleurs dans le code la ou on a de l'espace non utilisé, et remplir cette 'cave' de notre code et a la fin resauter sur le flux originel.

Pour cela, la démarche est la même que tout à l'heure:

Dans votre fenêtre de désassembleur, clic droit sur la ligne call 0x0000000001F5FDB0 et depuis le menu contextuel: Patch selection > Code Cave

Un dialogue Patch Label apparaît vous demandant un nom pour ce patch, mettez y un truc du genre: MunitionsCustom

Ensuite une deuxième fenêtre s'affiche Find unique AOB (Array Of Bytes) on clique sur Yes

La fenêtre Target Code contient:

MunitionsCustomTarget:
   call 0x0000000001F5FDB0
   jmp MunitionsCustomReturn

C'est le code que contient notre cave, on remplacera la ligne call 0x0000000001F5FDB0 par ce que nous voulons.

Disons que l'on veut laisser le choix a l'utilisateur d'entrer sa propre valeur à la place de bloquer ça bêtement à 999

A gauche dans la fenêtre Patch Control, appuyer sur le bouton Add Variable

Sélectionner UInt32 en type de variable, puis donner lui un nom, ainsi qu'une valeur, puis cliquer sur OK

variable

Dans Target Code il ne nous reste plus qu'à appeler notre variable comme ceci:

MunitionsCustomTarget:
   mov ebx, dword ptr[Ammo]
   jmp MunitionsCustomReturn

Puis de cliquer sur le bouton Check Validation puis sur l'icone Enregistrer.

Vous n'avez plus qu'à attacher le trainer et de tester.

Ouaip ça marche bien aussi !

trainermenu

Notre code édité par la cave:

0x1F84823      0F-B7-D8               movzx ebx,ax
0x1F84826      89-DE                  mov  esi,ebx
0x1F84828      E9-BB-BB-07-7D         jmp  0x000000007F0003E8
0x1F8482D      41-89-9E-E8-02-00-00   mov  dword ptr [r14+0x2E8],ebx

On se rend en 0x7F0003E8:

0x7F0003D6      00-00                  add byte ptr [rax],al
0x7F0003D8      00-00                  add byte ptr [rax],al
0x7F0003DA      00-00                  add byte ptr [rax],al
0x7F0003DC      00-00                  add byte ptr [rax],al
0x7F0003DE      00-00                  add byte ptr [rax],al
0x7F0003E0      00-00                  add byte ptr [rax],al
0x7F0003E2      00-00                  add byte ptr [rax],al
0x7F0003E4      00-00                  add byte ptr [rax],al
0x7F0003E6      00-00                  add byte ptr [rax],al
0x7F0003E8      8B-1C-25-F8-2A-00-7F   mov ebx, dword ptr [0x7F002AF8]
0x7F0003EF      E9-39-44-F8-82         jmp 0x0000000001F8482D
0x7F0003F4      90                     nop
0x7F0003F5      90                     nop
0x7F0003F6      90                     nop
0x7F0003F7      90                     nop
0x7F0003F8      90                     nop
0x7F0003F9      90                     nop

Flyhack

Pour faire un flyhack nous voulons connaître notre position en hauteur.

Celle la va nous demander un peu plus de temps de recherche avec PS4 Cheater.

Ces coordonnées sont souvent un nombre décimal comme 13.333337 qui ne peut exister qu'en float.

Vu que nous connaissons pas la valeur de notre hauteur dans l'espace, on va devoir faire une premiere recherche initiale globale Unknow Initial Value en float.

Puis il suffit de monter un escalier et de chercher en Increased Value

Ensuite descendre de l'escalier et de chercher en Decreased Value

Répéter les étapes de l'escalier jusqu'à réduire au minimum les résultats.

De temps en temps, ne toucher pas à votre position après avoir fait un scan en Increased ou Decreased mais faites une recherche en Unchanged Value cela peut aider aussi.

ps4cheater3

On tombe finalement sur 0x104A83A744, que l'on met dans notre WatchPoint List dans Reaper Studio, on n'oubliera pas de modifier la varType en Float

On break ici:

mov  rdi,qword ptr [r13+0x120]
mov  rsi,r15
call 0x0000000003A71BF0
mov  qword ptr [r13+0x110],r15
mov  byte ptr [r13+0x260],r12b
vmovups xmm0,xmmword ptr [r14]
vmovups xmmword ptr [r13+0x208],xmm0
mov  rax,qword ptr [r14+0x10]
mov  qword ptr [r13+0x218],rax
mov  rsi,qword ptr [r13+0x200]
test rsi,rsi
je   0x0000000003AEEC2C
mov  rax,qword ptr [rsp+0x50]
vmovsd xmm0,qword ptr [rsp+0x20]
vmovapd xmm1,xmmword ptr [rsp+0x30]
vsubsd xmm0,xmm0,qword ptr [rax+8]
vsubpd xmm1,xmm1,xmmword ptr [rax+0x10]

Pour ne plus tomber du ciel on peut NOPper mov qword ptr [r13+0x218], rax.

La hauteur ne sera plus jamais mise à jour via RAX. Nous figeant dans les airs.

On peut toujours se déplacer en X et Z.

graviter

Voila pour la petite présentation de l'outil.

DX/Watch: Utilisation du Débogueur

Intéressons nous maintenant à DX/Watch, un autre environnement complet débogueur, désassembleur, et création de trainers.

Il est un peu plus récent et maintenu que Reaper Studio, et a une interface plus complète nous permettant d'avoir plus de finesse que Reaper Studio, les deux outils sont complémentaires.

dxwatch_1

Le bouton Send Payload envoie la version v.1.1.19 de PS4Debug directement, contrairement à Reaper Studio qui envoie la version v.1.1.17 dans son injecteur.

Bon alors on va prendre un autre jeu pour changer, God Of War 3 Remastered, un grand classique sur Playstation.

Ici on va s'attaquer à notre santé qui est en float aussi, la technique est similaire au flyhack, chercher tous les pointeurs float et prendre des dégâts et affiner les recherches.

Une fois que l'on a notre pointeur, on rentre son adresse dans la fenêtre Memory Data et on Click sur Go

Une fenêtre s'affiche contenant le contenu de la ram en hex à cette adresse.

La fenêtre Data Inspector nous indique une valeur float à 130, notre santé actuelle.

dxwatch_2

On fait un clic droit sur le premier byte du dump, puis dans le menu contextuel: Find out what Instruction > Access in Write/Only mode

Le WatchPoint Manager se lance, on retourne dans le jeu prendre des coups, puis on met le jeu en pause.

Sur DX/Watch dans le WatchPoint Manager on clique sur le bouton Stop all WP, et on observe le ou les résultats.

dxwatch_3

Dans la colonne view, cliquer sur l'icone de la flèche pour suivre l'adresse dans le désassembleur.

dxwatch_4

On arrive ici:

4503DE      E9-A1-00-00-00                   jmp 0x450484
4503E3      C5-FA-10-45-A4                   vmovss xmm0, dword ptr [rbp - 0x5c]       
4503E8      C5-FA-5C-45-A0                   vsubss xmm0, xmm0, dword ptr [rbp - 0x60] 
4503ED      C5-F0-57-C9                      vxorps xmm1, xmm1, xmm1                   
4503F1      C5-FA-5F-C1                      vmaxss xmm0, xmm0, xmm1                   
4503F5      C4-C1-7A-5D-85-D0-01-00-00       vminss xmm0, xmm0, dword ptr [r13 + 0x1d0]
4503FE      C4-C1-7A-11-85-CC-01-00-00       vmovss dword ptr [r13 + 0x1cc], xmm0      
450407      49-8B-45-00                      mov rax, qword ptr [r13]

Interprétons ce que nous observons.

La ligne 7 vmovss dword ptr [r13 + 0x1cc], xmm0 est celle qui écrit la valeur de santé en mémoire, c'est notre cible.

En posant un point d'arrêt sur 4503E3, et en débuggant pas à pas on comprend que...

vmovss xmm0, dword ptr [rbp - 0x5c] charge la santé de [rbp-0x5c] dans XMM0

vsubss xmm0, xmm0, dword ptr [rbp - 0x60] soustrait les dégâts reçus à la santé.

dxwatch_4

Dans les registres, rbp-0x60 = 07EEFFA540, on peut se rendre la bas via l'outil Memory Data on va modifier la Lengh Hex en 0x12 et on clique sur Go

On se retrouve sur le pointeur de dégâts, qui a une valeur float de 4, on a pris 4 points de dégâts.

XMM0 est à 0x42EE0000 (119.0), donc XMM0 = 119.0-4.0 = 115.0, notre nouvelle santé après l'attaque.

dxwatch_7

vxorps xmm1, xmm1, xmm1: met XMM1 à zéro.

vmaxss xmm0, xmm0, xmm1: ici il prend le plus grand des deux, 115 > 0, donc XMM0 reste à 115.0.

Si les dégâts dépassent la santé, on bloque à 0 plutôt que d'obtenir une valeur négative.

vminss xmm0, xmm0, dword ptr [r13 + 0x1d0] le contraire de vmaxss, prend le plus petit des deux.

Si l'on regarde [r13 + 0x1d0] on a un float contenant 150, La santé max.

La santé reste donc à 115 car elle est déjà inférieure au maximum.

vmovss dword ptr [r13+0x1cc], xmm0 la dernière ligne, prend xmm0 (115) et l'écrit dans notre pointeur final de santé.

Voilà, maintenant que l'on comprend le mécanisme il n'y a plus qu'à faire un patch, le candidat idéal est vminss xmm0, xmm0, [r13+0x1d0]

Dans le désassembleur placé votre curseur sur cette ligne puis faite un clic droit pour ouvrir le menu contextuel, aller dans Patch selection > Assembler here..

Une nouvelle fenêtre s'ouvre, dans Trainer Control activé Create New Trainer

Ensuite dans la fenêtre de droite ASM Target Code a la place de vminss xmm0, xmm0, [r13+0x1d0] rentrer: vmovss xmm0, [r13+0x1d0]

On sait que [r13+0x1d0] contient notre santé max, donc on bouge la santé max dans XMM0 tout simplement.

Cliquer sur le bouton Check Syntax / Fix Code puis sur le bouton Send code

La fenêtre se ferme, maintenant sur le menu à onglet de gauche, cliquer sur Trainer manager la fenêtre du trainer manager s'ouvre.

Dans le champ Game donnez-lui un nom et cliquer sur le bouton Save As, avant de pouvoir tester votre trainer, vous devez le sauvegarder.

Une fois ça fait, vous pouvez cliquer sur le bouton Preview en bas de la fenêtre.

Vous pouvez alors tester votre trainer.

dxwatch_5

Kratos est maintenant invincible face à Zeus.

godofwarsante

Note : Dans le cas de God of War 3 Remastered sur PS4, les adresses mémoire sont statiques, elles ne changent pas entre les sessions. Le pointeur trouvé sera donc toujours valide au prochain démarrage, sans avoir besoin d'un scan AOB. Ce n'est pas le cas de tous les jeux.

Quelques adresses de pointeurs en float:

Rage de Sparte: 2298D7348

Orbes rouges: 2298D7358

Barre de magie: 2298D7340

Taille de Kratos: 2298D4CB8

Vitesse de Kratos: 2298D4CBC

Code cave avec variable

Pour faire un code cave avec DX Watch, vous devez d'abord sélectionner une zone mémoire.

Pour cela, rendez vous dans l'onglet Memory Map.

Cliquer sur le bouton Clear ALL puis ensuite vous devez trouver une section avec PROT = 3

Faite un clic droit sur la section, puis dans le menu contextuel: Create Master Memory Base Cave

dxwatch_8

Une fois que vous avez cliquer sur OK la fenetre des bookmarks apparaît, avec l'adresse de la zone mémoire si vous souhaitez aller voir a quoi ressemble la mémoire.

Maintenant on clique sur l'onglet Variable Manager la fenetre s'ouvre.

On clique sur le bouton New Variable puis on donne un nom a notre variable, ainsi que son type (Float)

Puis on clique sur OK et ensuite sur le bouton Save du Variable Manager.

dxwatch_9

Maintenant nous pouvons retourner dans notre désassembleur et sélectionner la ligne à patcher et depuis le menu contextuel: Patch Selection > CodeCave From...

dxwatch_10

on rentrera comme instructions:

vmovss xmm0,dword ptr [@VitesseKratos]
jmp 0x450ca3

Pendant que vous écriver votre code, vous pouvez appuyer sur F1 pour sélectionner votre variable.

dxwatch_11

Cliquer sur le bouton Check Syntax / Fix Code puis sur le bouton Send code

Voila, maintenant vous pouvez retourner dans le trainer manager, sauvegarder, et tester.

Tout marche bien !

dxwatch_13

Faire ses propres trainers

Bien qu'il existe de nombreux outils pour utiliser des cheats créés avec Reaper Studio ou DXWatch, ainsi que des outils telle que MultiTrainer II (codé d'ailleurs par l'auteur de Reaper Studio).

multitrainer2

Si vous voulez créer votre propre trainer, il vous suffira d'utiliser votre langage de prog favori et d'exploiter les fonctionnalités de ps4debug.

Exemple d'utilisation avec la lib PyPS4debug pour python, ou bien encore libdebug pour C#.

Avec l'aide de Claude, au Hackgyver on a décidé de faire notre propre trainer pour communiquer avec ps4debug en assembleur syntaxe MASM32.

La communication avec ps4debug se fait en TCP sur le port 744, avec un protocole basé sur header + ACK.

A l'origine, ps4debug avait été proposé par jogolden en open source, la version adaptée par Ctn est fermée.

Il suffit d'aller voir comment le projet d'origine marche pour comprendre comment travailler avec.

Sinon on peut aussi aller voir les autres adaptations, par exemple celle de ps4debug-NG qui est 100% compatible avec les commandes du ps4debug de base.

Chaque commande envoyée à ps4debug commence par un header de 12 octets :

struct cmd_packet {
    uint32_t magic;    // toujours 0xFFAABBCC
    uint32_t cmd;      // identifiant de la commande
    uint32_t datalen;  // taille du payload qui suit
};

Ensuite la console répond avec un ACK de 4 octets (0x80000000 = succès), et on envoie les données.

Pour écrire en mémoire, notre code assembleur fait cela :

ps4dbg_WriteMemory PROC pid:DWORD, addrLo:DWORD, addrHi:DWORD,
                         pData:DWORD, cbLen:DWORD
 
    invoke _SendCmd, CMD_MEMORY_WRITE, SIZEOF WRITE_MEM_PAYLOAD
    invoke _SendAll, ADDR payload, SIZEOF WRITE_MEM_PAYLOAD
    invoke _ReadStatus ; on attend l'ACK de la PS4
    invoke _SendAll, pData, cbLen

À la fin, on arrive avec un exécutable de 57,0 Ko réparti comme ceci :

  • 40 Ko de code assembleur
  • 17 Ko de ressources (12.6 Ko de bitmap, 2.66 Ko d'icônes, 1.4 Ko pour l'interface)

Le plus gros coupable de la taille est « XXControls.lib » qui représente 26.0 Ko du code.

On aurait pu s'en passer, mais c'est plus cool que les boutons classiques de Windows.

hgtrainer

Si l'on essaye de compresser notre binaire avec UPX, on arrive à le réduire de plus de 40% pour finir avec une taille de 24,0 Ko (24 576 octets)

Le code est disponible ici:

📥 hg-gow3_trainer.zip

Conclusion

Nous avons couvert dans ce tutoriel les bases du game hacking sur PS4.

Scanner la mémoire avec PS4 Cheater, identifier un pointeur, remonter jusqu'à l'instruction assembleur responsable avec Reaper Studio ou DX/Watch, et y appliquer un patch direct, un NOP, ou un code cave avec variable.

Les mêmes techniques s'appliquent à n'importe quel jeu PS4 jailbreaké.

Reaper Studio et DX/Watch sont également compatibles PS5 et le workflow est identique: même approche, mêmes outils, même logique d'analyse assembleur.

Seul le payload change, ps5debug remplace ps4debug.

Plus vous pratiquez, plus la lecture du désassembleur devient naturelle et les patterns reconnaissables.

Pour aller plus loin, la scène PS4 est active et bien documentée.

← Retour aux projets