Non classé

Le piratage des consoles: un parcours d'apprentissage (partie 4)

Par Garry , le 13 août 2019 - 13 minutes de lecture

(Article précédent de cette série: Consoles de piratage: un voyage d'apprentissage, troisième partie)

Introduction:

Bonjour et bienvenue dans mon parcours d'apprentissage! La semaine dernière, nous avons réussi à écraser Patapon 2 comme nous le souhaitions, en utilisant un faux nom de joueur dans notre fichier de sauvegarde. Cela n’a peut-être pas semblé beaucoup à l’époque, mais c’était en fait le premier pas vers la réalisation de quelque chose.

Maintenant, avant même de commencer le post d’aujourd’hui, je voudrais corriger une erreur dans la dernière: comme un utilisateur anonyme l’a souligné dans les commentaires, j’ai gâché mes bits et mes octets en parlant du nom dans le fichier de sauvegarde. Vous voyez, la notation hexadécimale est utile car, en binaire, un octet est composé de 8 bits, et nous pouvons le raccourcir d'un facteur 4 en hexadécimal. C’est-à-dire que FF en hex est 1111 1111 en binaire et A1 sera 1010 0001. Cela signifie donc que deux chiffres hexadécimaux forment un octet et quatre, deux octets. Par conséquent, si chaque lettre de la sauvegarde occupe 4 chiffres hexadécimaux au lieu de 2, ils utilisent 2 octets au lieu de 1, et non 4 au lieu de 2 comme je l’ai dit.

Résumé du jour:

Eh bien, j'ai quelque chose de très excitant à vous présenter aujourd'hui. J'ai réussi à faire un pas de plus sur notre chemin de piratage, en transformant notre crash de Patapon 2 en un événement plus puissant. Pour l'instant, je n'ai fait en sorte que le jeu se termine, mais cela signifie que j'ai pratiquement le contrôle de ce qui est exécuté dans le jeu, ce qui signifie que je peux charger n'importe quel programme binaire que je veux maintenant.

Je prévois de diviser cela en deux parties, cependant. Aujourd’hui, nous allons appeler cette fonction de sortie sans expliquer en grande partie le code d’assemblage derrière celle-ci, et la prochaine fois, je consacrerai tout le message à approfondir le code lui-même. Grâce à cela, les personnes qui se divertiront pourront avoir la version simplifiée ici, et les personnes désirant réellement apprendre le sujet auront un petit cours la prochaine fois.

Commencer:

Aujourd'hui, nous aurons besoin de quelques outils supplémentaires par rapport à la dernière fois. Tout d’abord, vous aurez besoin d’un moyen de faire des calculs hexadécimaux très simples (la calculatrice de Windows le fait, par exemple). Vous aurez également besoin du SDK PSP minimal, que nous avons installé il y a quelque temps, ainsi que d’un éditeur de code (je vais utiliser Atom) et de notre fidèle éditeur hexadécimal (HxD pour moi).

PRXDecrypter est la dernière chose dont vous aurez besoin pour décrypter l’EBOOT de Patapon 2. Pour que ce soit une application sur votre console, vous devez placer le contenu de ce fichier dans le dossier / PSP / GAME de votre clé USB.



Je suivrai également le message de Wololo sur l’écriture d’un chargeur binaire pour la PSP, alors dirigez-vous là pour suivre également.

Enfin, le (s) fichier (s) dont je vais vous parler ici sera disponible sur mon référentiel GitHub nouvellement créé.

Le piratage:

Bien, bien, bien… Pour être tout à fait honnête avec vous, je ne sais pas vraiment comment organiser ce message. Nous allons couvrir beaucoup de choses ici, dont beaucoup seront relativement techniques (en particulier pour les débutants en piratage ou programmation de bas niveau), donc ce sera un article dense.

Comme je l’ai mentionné ci-dessus, j’ai l’intention de n’expliquer que les processus décrits dans ce post et d’expliquer l’assemblage dans un prochain, afin de garder des éléments intéressants pour ceux qui ne sont pas intéressés par les aspects techniques. Je vais quand même expliquer un peu les choses, alors supporte-moi.


Tout d’abord, comprenons pourquoi ce que nous avons réalisé la dernière fois était intéressant. Vous voyez, quand un programme est créé (Patapon 2, par exemple), cela devient une série complexe d’instructions exécutées par le processeur de la console. Ajoutez ceci et cela, allumez ce pixel en jaune, et ainsi de suite… Et pour savoir quoi faire et quand le faire, il y a des variables dans ce processeur. La variable nommée $ ra, par exemple, indique au programme où aller ensuite dans son ensemble d'instructions (quelque part dans la mémoire).

Vous pouvez penser que c'est un livre de rôle très complexe. «Si vous avez décidé d'attaquer cette personne, allez à la page 18», par exemple. Eh bien, ce 18 aurait été stocké dans la variable $ ra s'il s'agissait d'un programme exécuté sur un ordinateur. Cela signifie que si nous pouvons prendre le contrôle de cette variable, nous pouvons faire en sorte que le programme aille où bon nous semble, et même à un endroit où nous avons écrit notre propre morceau de code.

Ce qui est très intéressant, c’est que lorsque nous avons écrit notre nom à la place du nom de notre joueur dans le fichier de sauvegarde de Patapon 2, nous avons en fait pris le contrôle de cette variable $ ra. La conséquence directe de cela est que nous pouvons maintenant écrire du code dans le fichier de sauvegarde lui-même, rediriger le processeur vers ce code en utilisant la variable $ ra que nous contrôlons maintenant, puis faire exécuter notre code au jeu. Cool, n'est-ce pas?

Vous voyez, ce qui est génial, c’est que lorsqu’un jeu interagit avec sa sauvegarde, celle-ci est (au moins partiellement) chargée telle quelle dans la mémoire. Et, si vous vous souvenez de notre problème avec $ ra, la mémoire correspond exactement à l'emplacement où le processeur trouve ce qu'il doit faire ensuite. Sachant que, si nous pouvons mettre quelque chose à faire pour le processeur dans notre sauvegarde de jeu, trouver l'adresse exacte de la mémoire (pensez à la page 18 de plus tôt) où se trouve ce contenu, puis pointer le jeu dessus à l'aide de $ ra, le processeur va lisez nos trucs sans le savoir.

Attends quoi?

Eh… En bref: nous pouvons écrire des choses utiles, puis nous pouvons y diriger le programme pour pouvoir exécuter les choses intéressantes. Ai-je clarifié les choses?


Maintenant, comprendre que tout est une partie de la chose, être capable de la retirer en est une autre. Pour le moment, la seule chose dont nous sommes sûrs, c’est que nous avons le contrôle sur $ ra. La prochaine étape, après cela, consiste à rechercher où le fichier de sauvegarde est chargé dans la mémoire du jeu, et à partir de là, de trouver où placer notre code. dans le fichier save afin de le retrouver dans la mémoire par la suite.

Pour avancer dans cette direction, la première chose à faire est de lire la mémoire du jeu. Quand nous aurons cela, nous pourrons trouver le contenu de notre fichier de sauvegarde à l’intérieur.

Pour cela, nous devons juste lancer PSPLink, planter notre jeu comme nous l’avons fait la dernière fois, et une fois que nous sommes là, nous pouvons écrire cette commande:

savemem 0x08800000 200000000 memdump.bin

Cela créera un fichier memdump.bin dans le même dossier que PSPLink, alors allez le chercher et ouvrez-le dans votre éditeur hexadécimal préféré. Puisque vous y êtes, vous devez également charger le fichier de sauvegarde Patapon 2 sur lequel nous avons travaillé dans le dernier message. Si vous prenez une partie du fichier save et le recherchez dans le fichier memdump, vous devriez pouvoir le trouver assez facilement.

Vous devriez pouvoir trouver des endroits identiques assez facilement.

Commencez-vous à voir le plan ici? Si nous pouvons trouver des parties du fichier de sauvegarde dans la mémoire du jeu, cela signifie que tout ce que nous aurons dans la sauvegarde ici sera également dans la mémoire et qu’il aura également une adresse.

En parlant d’adresse, vous allez vouloir prendre note du décalage de votre modèle, car nous avons besoin de savoir quoi mettre en $ ra pour pointer le processeur là-bas. Dans mon cas, le modèle que j'ai trouvé commence à l'offset 0x00519720 dans le memdump. Comme notre commande savemem que nous avions précédemment recommandée à PSPLink de rassembler tout ce qui se trouvait après l'adresse 0x08800000 dans la mémoire, cela signifie que nous devons faire un petit ajout afin de trouver le véritable emplacement où notre modèle sera situé en mémoire. Dans notre cas, 0x08800000 + 0x00519720 = 0x08D19720.


Maintenant, je vous encourage à faire une pause et à revenir sur ce que nous avons fait aujourd’hui, car c’est déjà une bonne quantité d’informations. Nous avons appris que prendre le contrôle de $ ra dans un crash de jeu était la clé de l’exécution arbitraire du code, ce à quoi nous en arrivons, et qu’une grande partie du fichier de sauvegarde du jeu avait été trouvée dans la mémoire du jeu. Nous avons également trouvé l’adresse réelle de ce bloc dans la mémoire.

Rassembler toutes ces informations nous donne ceci: nous pouvons écraser ce bloc dans le fichier de sauvegarde avec ce que nous voulons, et puisque nous en connaissons l'adresse, nous pouvons utiliser le contrôle que nous avons sur $ ra pour indiquer à la PSP ce motif juste écrasé, et il exécutera tout ce qui est dedans. Est-ce que les choses ont un peu plus de sens?

Si c'est le cas, génial! Nous pouvons maintenant arriver à des choses qui auront encore moins de sens!

Tout d’abord, vous aurez besoin de saisir une image ISO de votre partie. Si vous en avez déjà une, c’est une chose à faire, mais si vous jouez sur un UMD, il vous suffit de faire basculer l’option USB de votre micrologiciel personnalisé de «Memory Stick» à «UMD». De cette façon, vous aurez accès au fichier ISO qui y est présent.

Lorsque vous avez cela quelque part sur votre ordinateur, il vous suffit d’ouvrir ce fichier avec votre gestionnaire d’archives préféré (j’utilise personnellement 7-ZIP) et d’accéder au dossier SYSDIR situé dans le dossier PSP_GAME. Une fois que vous y êtes, prenez le fichier EBOOT.BIN et enregistrez-le dans un endroit agréable sur votre ordinateur.

Votre fichier EBOOT.BIN sera probablement crypté. Vous devrez donc créer un dossier nommé «enc» sur la clé USB de votre PSP, puis y placer l’EBOOT. Vous pouvez maintenant lancer PRXDecrypter, lui dire de déchiffrer le fichier, puis le récupérer dans le dossier «dec» de votre PSP. Si PRXDecrypter vous indique que votre fichier est déjà déchiffré, bonne nouvelle, vous pouvez déjà y travailler tel quel.

Si vous avez installé le SDK Minimal PSP sur votre ordinateur comme vous le devriez déjà, vous pouvez maintenant utiliser un joli petit truc appelé prxtool, que nous utiliserons pour nous dire quelles sont les fonctions importées du jeu.

Je serai honnête avec vous, celui-ci m’a pris beaucoup de temps à comprendre et, même maintenant, je ne suis pas tout à fait à l’aise avec cela. C'est pourquoi aucune explication ne sera donnée ici, seulement le processus approximatif. Si vous voulez savoir exactement comment et pourquoi nous faisons ce que nous allons faire, tout sera expliqué dans le prochain post.


Pour manipuler le jeu avec tout ce que nous allons écraser avec le motif dans le fichier de sauvegarde, nous devons savoir comment appeler les différentes fonctions que le jeu utilise en premier lieu, car nous n’aurons accès à rien d’autre. que ça. Pour cela, nous pouvons utiliser cette commande:

prxtool -f EBOOT.BIN

Cette commande nous donnera la liste des importations de fonctions triées par bibliothèque, mais elles ne serviront à rien tant que nous ne pourrons les traduire en noms de fonctions réels. C’est là que le fichier psplibdoc_660.xml situé dans mon référentiel GitHub sera utile:

prxtool -f -n psplibdoc_660.xml EBOOT.BIN

La sortie de cette fonction sera la même que celle d’avant, mais avec les noms réels des fonctions au lieu de quelque chose que nous ne pouvons pas utiliser.

Malheureusement, je ne peux pas expliquer la partie suivante sans plonger dans le code de montage, et comme cela est prévu pour le prochain article de la série…

En gros, la prochaine étape consiste à créer ce que nous avons mis dans le fichier de sauvegarde. En d'autres termes, nous fabriquons les instructions que nous voulons que le jeu exécute, puis nous les plaçons dans le fichier de sauvegarde à la place du modèle choisi précédemment. La toute dernière étape consiste à définir $ ra à l'adresse que nous avons eue plus tôt, et le tour est joué! Ce que j’ai fait, c’est d’appeler la fonction qui quitte le jeu afin de voir si cela fonctionnait et c’est ainsi.

Conclusion:

La journée a été lourde, non? Nous avons trouvé comment contrôler où la console lirait les prochaines instructions et, grâce à tout un processus de fouille dans les données du jeu, j’ai pu appeler la fonction qui quitte le jeu. Cela peut sembler différent de ce que nous avions fait la dernière fois, mais c’est vraiment le cas: maintenant, au lieu de nous contenter de casser le jeu, nous avons en fait le contrôle sur le comportement du jeu, ce qui permettra beaucoup de choses.

Si vous voulez comprendre les détails techniques de ce qui s’est passé aujourd’hui, connectez-vous à la partie 4.5 pour que je fasse de mon mieux pour expliquer quelque chose que je ne me comprends pas bien. En attendant, adieu!


P.S .:

La journée d’aujourd’hui a été très lourde pour moi. Je sais que je ne suis pas le meilleur enseignant et que le texte ci-dessus n’est pas assez clair. Venez poser vos questions, converser et aidez-moi à améliorer la série sur mon compte Twitter. @ theoct0. Le piratage informatique s’améliore, mais j’ai également besoin de me perfectionner dans les domaines de l’enseignement, de l’explication et de nombreuses choses. L’aide et les astuces seraient donc les bienvenues.

Garry