[PS3] Atelier Ayesha - Comment extraire et injecter texte ou désassembler-assembler fichier SELF?

Des soucis pour hacker votre jeu ? C'est ici qu'il faut exposer votre problème.
AtelierFlamel
Messages : 1
Inscription : 28 juil. 2020, 13:41
[PS3] Atelier Ayesha - Comment extraire et injecter texte ou désassembler-assembler fichier SELF?

Message non lu par AtelierFlamel »

Bonjour tout le monde,

Je suis relativement nouveau dans le milieu, mais j'ai décidé de me lancer dans la traduction du jeu Atelier Ayesha ~ The Alchemist of Dusk ~ (la version PS3 originale) de l'anglais vers le français.
J'ai décompressé l'iso et trouvé que le texte du jeu était soit stocké dans des fichiers .ebm (texte correspondant aux dialogues apparaissant dans les évènements faisant progresser l'histoire, soit le texte principal), soit dans le fichier eboot.bin (décrypté) lui-même (texte lié aux objets/combats/)
Après quelques recherches, j'ai trouvé des outils (HyoutaTools) qui me permettent de modifier facilement les .ebm en les convertissant en fichiers .sqlite.
Par contre, je bloque vraiment sur la façon d'abord le texte dans le SELF/eboot.bin, et c'est pour ça que je viens solliciter votre aide : quelqu'un pourrait-t-il me recommander des ressources/tutoriels/guides pour comprendre comment extraire et injecter du texte dans un fichier SELF de PS3?
Les vagues ressources que je trouve en ligne concernent seulement des consoles des vieilles générations (PS/PS2 au mieux), et je n'ai quasiment rien trouvé pour comprendre comment désassembler les SELF et les manipuler dans tous les cas de figures.
Je ne suis pas opposé à une manipulation directe dans un éditeur hexadécimal du fichier, mais je n'ai également trouvé nulle part de méthode vraiment claire pour trouver les tables de pointeurs vers les lignes de texte dans des (S)ELF alors que beaucoup de ressources en parlent, et puis il y a le problème d'encodage de caractères spéciaux français que je ne vois pas non plus comment traiter.
Je sais que c'est difficile, je possède une certaine pratique de la programmation (due à mes études notamment) et je suis prêt à investir énormément de temps - c'est juste que je ne trouve absolument pas de ressources (moderne) intéressante de rétro-ingénierie/assembleur/romhacking qui pourraient m'aider à aborder ce problème sous le bon jour. N'importe quelle information/ressource me sera d'une grande aide!

Je vous remercie d'avoir pris le temps de lire ce pavé un peu long :-) , je suis un peu désespéré et j'ai vu qu'il y a beaucoup de gens qui s'y connaissent beaucoup ici, c'est pour ça que j'ai posté.

Avatar de l’utilisateur
Maybach
Nouveau Floodeur
Messages : 21
Inscription : 26 mars 2017, 14:17
Re: [PS3] Atelier Ayesha - Comment extraire et injecter texte ou désassembler-assembler fichier SELF?

Message non lu par Maybach »

Bonsoir,
Alors premièrement je m'y connais très peu en PS3 ou programmation, mais comme toi j'ai été confronté à ce problème.
Pour une traduction, j'avais tenté ma chance sur des EBOOT.BIN de PS Vita qui sont en fait des fichiers SELF/ELF (je ne sais pas faire la différence).
Il faut savoir que la PS Vita et la PS3 partagent énormément de chose niveau encodage, j'ai parfois pu appliquer des algos de PS3 à des jeux PSV

En fait dans mon cas, les EBOOT.BIN étaient des fichiers "FSELF" c'est à dire avec une couche de cryptage avant d'être convertis en ELF. Bien heureusement on peut se servir de la console pour les décrypter, et parfois même depuis un PC si les développeurs ont hacké cette partie.
Après une brève recherche, je crois qu'il faut TrueAncestor SELF Resigner v1.98 cependant je n'ai aucune expérience et je ne l'ai jamais testé.

Un jour j'avais trouvé de bons outils PS3, ça s'appelait PS3_Tools by Aldo : http://www.logic-sunrise.com/news-88942 ... nible.html
Je ne sais pas à quel point c'est obsolète. De mon côté, j'ai réussi à décompiler le EBOOT.BIN avec Ghidra en suivant ce tuto (pour PSVita) : https://forum.devchroma.nl/index.php?topic=88.0
Mais le code obtenu était trop difficile pour moi même si j'ai pu trouver des chaines de caractères

Avatar de l’utilisateur
Inexpugnable
Dieu Suprême du flood
Messages : 959
Inscription : 30 avr. 2010, 22:11
Re: [PS3] Atelier Ayesha - Comment extraire et injecter texte ou désassembler-assembler fichier SELF?

Message non lu par Inexpugnable »

Plus qu'un type de fichier précis, il s'agit d'une compétence clef en rétro-ingénierie, l'analyse.

Comprendre suffisamment la structure d'une archive/ image/compression/etc. pour pouvoir implémenter de quoi l'extraire/désarchiver/réinsérer/recompiler.

Ça ne s'apprend pas en un claquement de doigts et je n'ai malheureusement pas réussi moi-même à atteindre cette étape... Les outils magiques n'existent pas en rétro-ingénierie de jeux-vidéos si ce n'est le debugger d'émulateurs assez avancés, mais encore faut-il savoir les utiliser.
Chaméléon. Est-ce que ne rien prendre. Ah oui mon coeur c'est vrai. Qu'est-ce que ça, qu'est-ce que c'est ? Donnez-moi ton argent. Donnez-moi ton fromage. Je donne tu mon amour et je allume ton chauffage.

https://www.youtube.com/watch?v=9eYAyYo5638

Avatar de l’utilisateur
RyleFury
Maître Suprême Floodeur
Messages : 464
Inscription : 16 janv. 2012, 12:48
Contact :
Re: [PS3] Atelier Ayesha - Comment extraire et injecter texte ou désassembler-assembler fichier SELF?

Message non lu par RyleFury »

EDIT : Je viens de voir que la PS3 utilisait le Big endian, attention à ça.
La PS3 utilise aussi une architecture 64 bits à l'inverse de la PS Vita qui utilise du 32 bits. Ca veut dire que tous les pointeurs seront stockés sur 8 octets au lieu de 4. Il faudra t'adapter par rapport à ce que j'ai mis plus bas.
Cette page devrait t'aider pour les headers du fichier ELF sur PS3 légèrement structurés différemment :
https://www.psdevwiki.com/ps3/SELF_-_SPRX#fSELF

Ca fait un moment que je voulais répondre à ce sujet, désolé pour le retard mais fallait que je me prépare psychologiquement à faire un Lyan (pavé) :D.

Pour commencer, je n'ai jamais touché à la PS3 mais la PS Vita devrait être très similaire. Il pourrait donc y avoir quelques légères différences.

Je vois que tu as "décrypté" (on dit "déchiffré" quand il s'agit d'informatique ;)) l'eboot, donc tu devrais avoir le fichier SELF en clair contenant lui-même le fichier ELF. C'est lui qui nous importe ici car il comporte un header standard qui va nous permettre de comprendre sa structure. C'est toujours la première chose à comprendre.

Commence déjà par supprimer les 0x1000 premiers octets correspondant au header du fichier SELF qui nous sont complètement inutiles. Ils ne sont importants que pour le reconstruire. Ca nous donne un fichier ELF standard. Tu devrais alors avoir les octets "7F 45 4C 46" ou " ELF". Si ce n'est pas le cas, c'est que ton fichier SELF n'est pas déchiffré. Nous avons donc devant nous le fichier exécutable principal du jeu comportant la programmation principale du jeu ainsi que ses variables et constantes générales. Il comporte aussi souvent les textes des menus et textes système comme c'est souvent le cas pour les jeux GUST.

Tu as d'attaché à ce message le Graal te permettant de décoder entièrement ce fichier : "ELF_Format.pdf". Pour te mettre sur la piste, les structures importantes sont le "ELF Header", le "Program Header" et le "Section Header" (ce dernier devrait être absent je pense).

Les informations importantes du "ELF Header" sont celles-ci :

- e_phoff : L'adresse du "Program Header" dans le fichier (habituellement 0x34). Il est placé juste après le "ELF Header".
- e_phnum : Le nombre d'entrées du "Program Header".

Une entrée du "Program Header" définit une zone du fichier ELF copiée directement dans la RAM au lancement du jeu. Cela va nous permettre d'obtenir les zones effectives et l'offset entre l'adresse dans le fichier ELF et dans la RAM. Ca va donc nous permettre de trouver les pointeurs des textes et de les modifier. C'est en vérité un peu plus compliqué, mais chaque chose en son temps, tu t'es attaqué à quelque chose de bien complexe pour ton premier projet. Certaines de ces zones sont spéciales et servent à un autre but que d'être copiés dans la RAM.

C'est le moment de décoder le "Program Header" afin d'obtenir les différentes zones copiées dans la RAM. Chaque entrée du header fait 0x20 octets.
Les informations importantes du "Program Header" sont celles-ci :

- p_type : Tu devrais normalement toujours avoir 0x01 (PT_LOAD). Cela signifie que la zone est copiée dans la RAM au lancement du jeu.
- p_offset : L'adresse dans le fichier de la zone à copier dans la RAM.
- p_vaddr : L'adresse dans la RAM où la zone sera copiée. (p_vaddr - p_offset) donne l'offset entre l'adresse de la RAM et du fichier permettant de trouver et modifier les pointeurs.
- p_filesz : La taille de la zone copiée dans la RAM.
- p_memsz : La taille de la zone réservée dans la RAM. Si elle est nulle, rien n'est copié dans la RAM.
Si elle est égale à p_filesz, la zone réservée fait la même taille que ce qui est copié dans la RAM. Ce sera très certainement une zone Read-only.
Si elle est supérieure à p_filesz, cela signifie que le reste de la zone dans la RAM contient une section contenant des variables non initialisées (et donc non présentes dans le fichier ELF). Ce sera donc forcément une zone où on a la permission d'écrire.
- p_flags :

PF_X : 0x1 : Execute
PF_W : 0x2 : Write
PF_R : 0x4 : Read
PF_MASKPROC : 0xF0000000 : Unspecified

"Execute" signifie que la zone contient une partie ASM, la première zone est censée contenir tout l'ASM principal du jeu mais pas que.
"Write" signifie que la zone contient des données modifiées pendant le jeu.
"Read" signifie que la zone contient des données lues pendant le jeu.

Ce sont des flags, ça fonctionne donc en masquant la valeur. Par exemple, si tu as la valeur 0x05, on effectue les opération suivantes :
0x05 | 0x01 = 1 (Execute présent)
0x05 | 0x02 = 0 (Write absent)
0x05 | 0x04 = 1 (Read présent)

| étant un OU. Donc ici les flags "Execute" et "Read" sont actifs.

Jusque-là tout va bien. Je vais te donner un exemple avec l'eboot de Ciel Nosurge sur PS Vita où ça devrait être assez similaire.

Je commence à le "ELF Header", j'obtiens ces valeurs :

- e_phoff : 0x34
- e_phnum : 0x05

On aura donc 5 zones du fichier ELF dont les 2 premières copiées dans la RAM (p_type = PT_LOAD). Passons à la première entrée du "Program Header" :

- p_type : 0x01 (PT_LOAD). La zone sera bien copiée dans la RAM.
- p_offset : 0xE0. La zone commence à cette adresse du fichier.
- p_vaddr : 0x81000000. Adresse typique de la RAM de la PS Vita. L'offset ELF-RAM sera donc 0x80FFFF20.
- p_filesz : 0x53CE8C. Taille de la zone dans le fichier ELF.
- p_memsz : 0x53CE8C. Taille de la zone dans la RAM. Ce sera très certainement une zone Read-only.
- p_flags : 0x05. Cette zone contient les flags "Execute" et "Read" mais pas "Write". Cette zone est donc Read-only et contient entre autre du code ASM toujours placé au début. Il peut très bien contenir autre chose à la suite du code ASM, dont le texte à traduire.

La zone à l'adresse 0xE0 avec une taille de 0x53CE8C sera donc copiée dans la RAM et il sera interdit d'écrire dans cette zone en jeu. A la moindre écriture, il y aura une erreur. Afin de trouver les pointeurs pour cette zone, il faudra prendre l'adresse dans le fichier du premier caractère du texte et ajouter l'offset ELF-RAM.

Voyons voir la seconde entrée du "Program Header" qui est à la suite :

- p_type : 0x01 (PT_LOAD).
- p_offset : 0x53CF80.
- p_vaddr : 0x8153D000. L'offset ELF-RAM sera donc 0x81000080 (différent de l'offset de l'autre zone, il faut donc faire attention).
- p_filesz : 0x1F36C. Taille de la zone dans le fichier ELF.
- p_memsz : 0x348AB8. Taille de la zone dans la RAM. Le reste des données est donc non initialisé. Cette zone sera forcément modifiée en jeu.
- p_flags : 0x06. Cette zone contient les flags "Write" et "Read" mais pas "Execute". Cette zone est donc modifiée en jeu et ne contient pas de code ASM. Le texte peut aussi être ici, mais il est plus souvent dans des zones Read-only.

Ici, on a fait la partie la plus simple... La partie compliquée commence maintenant. Suite dans un autre message.
Pièces jointes
ELF_Format.rar
(116.46 Kio) Téléchargé 5 fois
Dernière modification par RyleFury le 05 août 2020, 20:51, modifié 9 fois.

Avatar de l’utilisateur
RyleFury
Maître Suprême Floodeur
Messages : 464
Inscription : 16 janv. 2012, 12:48
Contact :
Re: [PS3] Atelier Ayesha - Comment extraire et injecter texte ou désassembler-assembler fichier SELF?

Message non lu par RyleFury »

Maintenant qu'on a toutes les infos sur les zones écrites dans la RAM, il va nous falloir trouver chaque pointeur de chaque texte afin de les modifier. On va prendre un texte en exemple avec Ciel Nosurge une fois de plus.

Je trouve un texte à l'adresse 0x4B0EC8 du fichier. Le texte fait donc partie de la première zone copiée dans la RAM qui je le rappelle commence à l'adresse 0xE0 avec une taille de 0x53CE53 octets. On ajoute l'offset ELF-RAM afin de trouver son adresse dans la RAM et on aura donc la valeur du pointeur :
0x4B0EC8 + 0x80FFFF20 = 0x814B0DE8.

Maintenant, il faut savoir qu'il existe deux façons de pointer une donnée :
- Soit par un pointeur standard. Il suffit de chercher la valeur en little endian (E8 0D 4B 81).
- Soit c'est pointé directement en ASM, auquel cas c'est plus compliqué à trouver.

Si le texte n'est pas trouvé en cherchant "E8 0D 4B 81", c'est donc que c'est directement pointé en ASM. Et ici c'est le cas.

Avant d'aller plus loin, il faut que j'aborde quelque chose de primordial. Si c'est comme sur PS Vita, les zones du fichier ne sont pas copiées à une adresse absolue de la RAM. Cela veut dire que les zones peuvent être copiées n'importe où dans la RAM. Cependant, nous avons ici des adresses absolues pour ces zones : 0x81000000 et 0x8153D000.

C'est là où ça devient compliqué. Avant de copier ces zones, le jeu va fournir une adresse de la RAM à laquelle ces zones vont être copiées. Par exemple, au lieu que ce soit copié à l'adresse 0x81000000, ça pourrait très bien être copié à l'adresse 0x81900000 à la place. Cette adresse change à chaque lancement de jeu. Cependant, le fichier ELF contient des pointeurs absolus standards et des pointeurs absolus définis en ASM. Ce que va effectuer le système, c'est remplacer TOUS ces pointeurs absolus par les nouveaux fournis. Le pointeur 0x81000000 sera donc réécrit 0x81900000, 0x81100000 sera réécrit 0x81A00000, etc.

Les pointeurs absolus de base ne sont jamais lus et sont toujours écrasés en début de jeu, il est donc inutile de les modifier (sauf si on veut faire quelque chose de vraiment propre). Mais alors, comment le système sait où trouver ces pointeurs pour les modifier ? Il va utiliser une table spécifique à la fin du fichier ELF appelée "Dynamic reallocation table". Il y a une table par zone effective, donc deux ici. Ce sont ces tables qu'il va falloir modifier à chaque fois qu'on cherchera à modifier le pointeur d'un texte.

Bien que cette table peut être chiante à décoder, elle est en vérité extrêmement pratique car elle évite d'avoir à trouver les pointeurs ASM nous-mêmes.

Sur PS Vita, ces tables sont définis dans le "Program Header", et elles sont prises en compte par e_phnum (comme on déchiffre le fichier proprement). Elles sont normalement définies juste après les entrées effectives du Program Header. Sur Ciel Nosurge, nous en avons bien deux autres après les entrées de base. Allons décoder la première entrée :

- p_type : 0x60000000 (PT_LOOS). Cette valeur indique un type spécifique au système. Ici ça veut dire que c'est une "Dynamic reallocation table". Je ne suis pas sûr que ce soit la même valeur sur PS3.
- p_offset : 0x5605D0.
- p_vaddr : 0. Cette table n'existe que dans l'ELF et ne sera pas copiée dans la RAM.
- p_filesz : 0xD5504. Taille de la table.
- p_memsz : 0.
- p_flags : 0.

La table de réallocation de la première zone est donc stockée à l'adresse 0x5605D0 du fichier ELF avec une taille de 0xD5504 octets. C'est tout ce qui nous intéresse. Tous les pointeurs à modifier dans la première zone seront donc dans cette table.

Ensuite, il faut comprendre comment est structurée cette table, ce qui n'est pas forcément simple. Néanmoins, si c'est juste pour changer des pointeurs de texte, on n'aura pas à s'en soucier car les valeurs seront normalement écrites en clair.

Reprenons le pointeur que nous cherchions dans notre exemple : 0x814B0DE8.
Ce pointeur est absolu car nous avons rajouté l'adresse de la zone qui est 0x81000000. Cependant, nous avons dit tout à l'heure que l'adresse de la zone 0x81000000 est inutile car la zone peut être copiée n'importe où dans la RAM. Reprenons donc l'adresse dans le fichier ELF du texte : 0x4B0EC8.

Ici, nous devons obtenir l'adresse relative du texte dans la zone. C'est celle qui sera inscrite dans la "Dynamic reallocation table". La zone commençant à l'adresse 0xE0 dans l'ELF, nous allons donc effectuer l'opération suivante :
0x4B0EC8 - 0xE0 = 0x4B0DE8.

Au final, l'offset ELF-RAM est inutile ici, nous allons plutôt définir un offset ELF-Zone qui sera -0xE0.

On cherche dans la "Dynamic reallocation table" cette valeur en little endian : E8 0D 4B 00. On la trouve un endroit et cela définit un pointeur ASM.

Il peut très bien y avoir qu'une seule valeur ou plusieurs. Il faut modifier toutes ces valeurs quand on souhaite modifier le pointeur. Si c'est comme sur PS Vita, la valeur à 4 octets juste après définit l'adresse relative dans la zone où ce pointeur est stocké et sera écrasé. Si c'est dans la zone ASM, cela modifiera un pointeur ASM, sinon ce sera un pointeur standard. Les 4 octets d'avant définissent le type de pointeur, si c'est ASM, standard ou même une table de pointeurs.

Dans tous les cas, seules les valeurs définissant les pointeurs sont importantes ici.

J'espère que c'est similaire à la PS Vita dans tous les cas. Je t'ai fourni toutes les pistes nécessaires pour que tu puisses appréhender sainement le fichier SELF, maintenant c'est à toi de jouer. J'accepte bien sûr toutes les questions, mais je ne ferai pas le travail à ta place.

Etant moi-même fan des Atelier, je te souhaite bon courage ;)

EDIT : J'ai modifié un peu les valeurs que j'avais mises car j'avais pris une version dumpée par Mai Dump Tool, ce qui n'est pas une référence. Maintenant les nouvelles valeurs et explications correspondent à un fichier déchiffré proprement avec exactement les bonne valeurs. Je rajoute aussi le fichier eboot.elf pour ceux qui veulent vérifier avec le tuto :

http://rylelafurie.free.fr/Ciel_nosurge_eboot.rar
Dernière modification par RyleFury le 05 août 2020, 20:48, modifié 3 fois.

Avatar de l’utilisateur
Maybach
Nouveau Floodeur
Messages : 21
Inscription : 26 mars 2017, 14:17
Re: [PS3] Atelier Ayesha - Comment extraire et injecter texte ou désassembler-assembler fichier SELF?

Message non lu par Maybach »

Quelle réponse incroyable, j'ai honte de répondre par si peu de caractères et de ne pas me prosterner devant tant de connaissance, mais merci car je tenterai d'appliquer cette méthode à mon projet en cours sur PS Vita.


Répondre