Traduction de routine ASM en C

Des soucis pour hacker votre jeu ? C'est ici qu'il faut exposer votre problème.
Avatar de l’utilisateur
rid
Dieu Suprême du flood
Messages : 2046
Inscription : 04 janv. 2005, 22:17
Contact :
Traduction de routine ASM en C

Message non lu par rid »

Bonjour à tous!
J'écris ce post à la suite de la lecture d'un tutorial sur l'ASM PSX écrit par Skeud.
Il y est écrit (en gros) qu'une des meilleures façons d'écrire une routine de décompression similaire à celle d'un jeu X est de la traduire directement de l'ASM vers un autre langage de plus haut niveau (eg : le C, mais n'entrons pas dans le sujet du choix de tel ou tel langage 8) ).

Sur le principe, je suis d'accord avec cette affirmation, et en serait un grand partisan, le seul problème que je rencontre, c'est sa mise en pratique. Je m'explique (enfin, je vais essayer):

Dans une routine ASM (je bosse sur une routine NES, bref) il y a souvent des accès à la RAM, des manipulations de registres, etc... Ces actions se font selon moi 'in vivo', c'est à dire lorsque le code s'exécute depuis un émulateur, ou une machine. Bref, il y a des actions qui ne peuvent se calculer et se gérer uniquement que lorsque les jeux est en marche.
De là vient mon problème : comme l'on va retranscrire du code ASM en un autre langage, comment peut-on arriver à gérer tout ces accès de manière à ce que l'ensemble fonctionne correctement et que l'on obtienne le résultat désiré?

La seule réponse que j'ai trouvé pour l'instant est de créer une sorte d'interpréteur de code, mais là on rejoint le côté "je monte mon propre émulateur", côté qui ne me convient pas vraiment :mad:

Donc si quelqu'un pouvait m'éclaircir sur ce point, je lui en serait infiniment reconnaissant, et aura une descendance féconde jusqu'à la IXème génération (non, ce n'est pas un message subliminal :d)

Avatar de l’utilisateur
Skeud
Oook ?
Messages : 3809
Inscription : 25 févr. 2002, 22:01
Localisation : Loompaland
Contact :

Message non lu par Skeud »

Le mieux serait de poster un extrait de ton code. L'aide viendra ensuite :D
Si tu ressens l'envie de travailler, assieds-toi, et attends qu'elle te passe....
A mon niveau, on ne croit pas, on sait. (Docteur Helmut Perchut)

Avatar de l’utilisateur
rid
Dieu Suprême du flood
Messages : 2046
Inscription : 04 janv. 2005, 22:17
Contact :

Message non lu par rid »

Désolé, je ne posterai pas d'extrait de code car :
- ça prendrai de la place inutilement;
- ça n'est pas nécessaire selon moi;
(- je n'en ai pas sous la main actuellement :D)

Par contre je peux rapidement t'expliquer le truc.
La routine du jeu "Destiny Of An Emperor" démarre à l'adresse $D173 (adresse NES) (à force du lire du code, on s'en rappelle).
Donc à partir de là, plein d'instructions sont exécutées, saut dans une autre partie de la rom, changement des registres,...

Mon problème se sont toutes les petites instructions du type :
LDY $0056
STX $0319,Y
...
Fondamentalement, je les comprends et peu m'en tirer lors de l'exécution du code, par contre, pour traduire ce genre de truc, je sèche...

Voilà tout ce que je peux fournir pour l'instant.
Si ça permet pas d'avancer, je ferai ce soir une trace du code lors d'une décompression, mais ça me fait mal d'attendre jusqu'à ce soir pour avoir une réponse :/

Avatar de l’utilisateur
Loki
Dieu Suprême du flood
Messages : 1624
Inscription : 03 juil. 2006, 10:06
Localisation : Mer des Sarcasmes

Message non lu par Loki »

Ca serait pas plus facile de convertir l'ASM 6502 en ASM 80x86 (PC),
il y aurait beaucoup moins d'interprétation et certainement des instructions que tu pourrais faire correspondre.

Qu'est ce que tu veux changer dans la routine exactement?

Postes ton code ça sera plus facile.

Avatar de l’utilisateur
rid
Dieu Suprême du flood
Messages : 2046
Inscription : 04 janv. 2005, 22:17
Contact :

Message non lu par rid »

Le principe de la chose est de retranscrire le code ASM en C (ou du moins son équivalent) de manière à extraire le script du jeu.
Je ne souhaite pas changer la routine, seulement copier son mode opératoire.

Avatar de l’utilisateur
Loki
Dieu Suprême du flood
Messages : 1624
Inscription : 03 juil. 2006, 10:06
Localisation : Mer des Sarcasmes

Message non lu par Loki »

Alors le plus simple est de partir de zéro, et de ne pas t'occuper du code
dans la ROM, une fois que tu as trouvé les codes spéciaux comme les
sauts de lignes et autres, tu peux écrire ta propre routine.

Avatar de l’utilisateur
Orphis
Yo-Plait
Yo-Plait
Messages : 737
Inscription : 21 févr. 2002, 19:08
Localisation : ICI
Contact :

Message non lu par Orphis »

Le plus simple c'est d'avoir un buffer en C qui contienne une copie de la mémoire NES. Ce qui donne :
LDY $0056 => Y = mem[0x56];
STX $0319,Y => mem[0x319 + Y] = X;

Etc...
Ton code pour extraire devra "juste" initialiser la mémoire comme elle l'est dans le jeu NES. Faut juste identifier les bonnes adresses essentielles ^^

Avatar de l’utilisateur
Skeud
Oook ?
Messages : 3809
Inscription : 25 févr. 2002, 22:01
Localisation : Loompaland
Contact :

Message non lu par Skeud »

Sinon, tu peux créer une variable par zone mémoire. L'avantage sur la solution de niorphis est que tu évites le mélange des tailles (du genre des données de 8 bits et de 16 bits). Cela n'a pas d'importance sur la NES, mais en a sur la SNES.
Si tu ressens l'envie de travailler, assieds-toi, et attends qu'elle te passe....
A mon niveau, on ne croit pas, on sait. (Docteur Helmut Perchut)

Avatar de l’utilisateur
Jes
Pom pom pom
Messages : 5822
Inscription : 24 févr. 2002, 14:05
Localisation : Siège social de BessaB
Contact :

Message non lu par Jes »

Mais c'est quoi cette méthode à la mords-moi-le-noeud o_O

Tu veux faire un décompresseur pour ton jeu? Fort bien, analyse le code et déduis-en l'algorithme générale. Après, implémente l'algo en C. Traduire le code directement en C sans l'avoir compris, c'est vraiment une très très très très mauvaise façon de faire et de programmer. De toute façon, tu dois avoir compris l'algorithme de décompression pour pouvoir faire un compresseur plus tard. Tu peux t'aider du code source assembleur pour faire ton décompresseur en C bien sûr (les deux se ressembleront forcément) mais ne fais pas un interpréteur!!

Ce que j'ai vu là:

Code : Tout sélectionner

LDY $0056 => Y = mem[0x56]; 
STX $0319,Y => mem[0x319 + Y] = X
C'est vraiment, mais alors VRAIMENT, immonde o_O

Avatar de l’utilisateur
rid
Dieu Suprême du flood
Messages : 2046
Inscription : 04 janv. 2005, 22:17
Contact :

Message non lu par rid »

Lol, tu dis que ce code est immonde, mais celui de mon jeu est pire :D

J'avais pensé à la solution d'Orphis, mais voilà je buggais au niveau de l'initialisation des valeurs clés.

Je pense que je vais passer quelques heures de plus à essayer d'extirper de cet amas de codes hexadécimal, l'ombre d'une logique depuis longtemps oubliée 8)

Avatar de l’utilisateur
Jes
Pom pom pom
Messages : 5822
Inscription : 24 févr. 2002, 14:05
Localisation : Siège social de BessaB
Contact :

Message non lu par Jes »

Je parlais de la traduction C, pas du code assembleur (évidemment).

Mais si tu veux qu'on t'aide, copie-colle la routine et on en parle plus.

Avatar de l’utilisateur
rid
Dieu Suprême du flood
Messages : 2046
Inscription : 04 janv. 2005, 22:17
Contact :

Message non lu par rid »

Ok, je vais préparer ça par contre pour des raisons de commodités, comment le présenter ?

Car en fait, la routine de décompression est très, très longue (changement de bank en fonction de l'octet lu, variation des instructions en fonction de l'octet lu,...).

Bref, si j'assemble l'ensemble des chemins possibles et imaginables (j'ai oublié de dire que la routine en elle-même je l'ai comprise quand même), ça nous fait plusieurs extraits de codes variant de 6Ko, à 45Ko!

Avatar de l’utilisateur
Moogle
Gloire au Grand Moogourou !
Messages : 546
Inscription : 21 févr. 2002, 21:44
Localisation : Bikini Bottom
Contact :

Message non lu par Moogle »

asm {
[ton code ASM ici]
}

(bah quoi ca marche :D )

Avatar de l’utilisateur
Orphis
Yo-Plait
Yo-Plait
Messages : 737
Inscription : 21 févr. 2002, 19:08
Localisation : ICI
Contact :

Message non lu par Orphis »

C'est une méthode immonde mais au moins ça permet d'obtenir des données avec lesquelles on peut bosser. Quand j'ai bossé sur le décompresseur de ToD, Skeud m'avait passé la routine traduite en C et l'adresse mémoire de la routine dans le jeu. J'ai donc pu décompresser quelques textes avec mon décompresseur que j'ai obtenu en analysant le code et comparer avec la référence sortie de l'ASM traduit en C. Ce fut vraiment très pratique pour corriger des bugs quand à l'époque, je connaissais pas trop le domaine.

Avatar de l’utilisateur
Jes
Pom pom pom
Messages : 5822
Inscription : 24 févr. 2002, 14:05
Localisation : Siège social de BessaB
Contact :

Message non lu par Jes »

Moogle a écrit :asm {
[ton code ASM ici]
}

(bah quoi ca marche :D )
Mouahahahahahaha :D
Ridculle a écrit :Ok, je vais préparer ça par contre pour des raisons de commodités, comment le présenter ?

Car en fait, la routine de décompression est très, très longue (changement de bank en fonction de l'octet lu, variation des instructions en fonction de l'octet lu,...).

Bref, si j'assemble l'ensemble des chemins possibles et imaginables (j'ai oublié de dire que la routine en elle-même je l'ai comprise quand même), ça nous fait plusieurs extraits de codes variant de 6Ko, à 45Ko!
Bein en gros, rassemble toutes les infos que tu as sur le jeu: tables, pointeurs, routines. Tu fous ça dans un fichier txt que tu uploades quelque part. Mais en fait, y a des chances que tu aies mal découpé la routine de décompression, parce qu'elles sont généralement assez courtes. Tu sais quel type de compression est utilisé pour ce jeu?

Avatar de l’utilisateur
rid
Dieu Suprême du flood
Messages : 2046
Inscription : 04 janv. 2005, 22:17
Contact :

Message non lu par rid »

C'est pas vraiment de la compression maintenant que j'y pense, mais plutôt un script avec des références.

Du style, on lit le script, octet par octet.
Si l'octet lu est supérieur à 0x7F, alors il va falloir extraire une chaine dans un endroit particulier de la rom (dans une autre bank).
Le problème, c'est que ce texte à aller chercher est disséminé un peu partout dans la rom est en fonction de l'octet lu, il y a plusieurs cas possibles.

C'est donc pas vraiment de la décompression... mais c'est aussi chiant à gérer :tetemur:

Avatar de l’utilisateur
Jes
Pom pom pom
Messages : 5822
Inscription : 24 févr. 2002, 14:05
Localisation : Siège social de BessaB
Contact :

Message non lu par Jes »

Bah c'est une variante de MTE donc :)

Avatar de l’utilisateur
rid
Dieu Suprême du flood
Messages : 2046
Inscription : 04 janv. 2005, 22:17
Contact :

Message non lu par rid »

Lol, je sais pas ce que c'est, mais en tout cas j'aime pas ça du tout.

Avatar de l’utilisateur
Loki
Dieu Suprême du flood
Messages : 1624
Inscription : 03 juil. 2006, 10:06
Localisation : Mer des Sarcasmes

Message non lu par Loki »

Jes a écrit :Bah c'est une variante de MTE donc :)
Tu ne trouvera pas ça dans la littérature spécialisé, on a des mots en français et on appele ça un dictionnaire! :D

Avatar de l’utilisateur
Skeud
Oook ?
Messages : 3809
Inscription : 25 févr. 2002, 22:01
Localisation : Loompaland
Contact :

Message non lu par Skeud »

Tu nous la balance ta routine? :p
Colle-là quelquepart où on peut mettre du code.

Sinon, comme le disait Orphis, traduire directement et "bêtement" l'algorithme permet de l'étudier plus facilement, et surtout, d'avoir une version extrêmement fidèle au code originel (normal).
Ensuite, si on doit faire l'opération inverse, il est évident qu'une maitrise totale de l'algo est nécessaire, et cette première approche le permet plus facilement.
Si tu ressens l'envie de travailler, assieds-toi, et attends qu'elle te passe....
A mon niveau, on ne croit pas, on sait. (Docteur Helmut Perchut)

Avatar de l’utilisateur
Jes
Pom pom pom
Messages : 5822
Inscription : 24 févr. 2002, 14:05
Localisation : Siège social de BessaB
Contact :

Message non lu par Jes »

Loki a écrit :
Jes a écrit :Bah c'est une variante de MTE donc :)
Tu ne trouvera pas ça dans la littérature spécialisé, on a des mots en français et on appele ça un dictionnaire! :D
Tu trouveras ça dans la littérature spécialisée dites du "romhacking" mais effectivement je n'ai jamais entendu parlé de DTE/MTE autre part, même dans la documentation anglaise. Vu le contexte l'usage du mot "MTE" est bien pertinent. De toute manière, on s'en fout :P
Skeud a écrit :Sinon, comme le disait Orphis, traduire directement et "bêtement" l'algorithme permet de l'étudier plus facilement, et surtout, d'avoir une version extrêmement fidèle au code originel (normal).
Je ne savais pas qu'une traduction conforme en C d'une routine assembleur pouvait aider à sa compréhension (faut croire que la notation C est plus facile?). Du reste, les debuggers sont justement là pour pouvoir étudier facilement le déroulement d'une routine ingame, donc pour moi ça constitue une perte de temps plus qu'autre chose. Maintenant à chacun sa méthode, mais je ne conseillerai jamais ça à un débutant (ni même à quelqu'un d'autre en fait).

Avatar de l’utilisateur
Skeud
Oook ?
Messages : 3809
Inscription : 25 févr. 2002, 22:01
Localisation : Loompaland
Contact :

Message non lu par Skeud »

Jes a écrit : Je ne savais pas qu'une traduction conforme en C d'une routine assembleur pouvait aider à sa compréhension (faut croire que la notation C est plus facile?). Du reste, les debuggers sont justement là pour pouvoir étudier facilement le déroulement d'une routine ingame, donc pour moi ça constitue une perte de temps plus qu'autre chose. Maintenant à chacun sa méthode, mais je ne conseillerai jamais ça à un débutant (ni même à quelqu'un d'autre en fait).
J'ai écrit permettait de l'étudier. Les debuggers de compilateurs C seront toujours plus faciles à manipuler que snes9x version debug. Par exemple, avoir dans une seule fenêtre deux emplacements mémoires différents. Ca permet aussi de travailler sur différentes zones du jeu qui utilisent la même routine, sans avoir à lancer le jeu.
Après, si tu arrives à comprendre le code rien qu'en regardant la routine, ou en passant des heures à lancer/relancer l'emu et le jeu, tant mieux :p, mais je pense vraiment que notre méthode à Orphis & moi est utile pour un débutant.

Et je rajoute encore : cette méthode est la meilleure quand on veut éviter les bugs!
Si tu ressens l'envie de travailler, assieds-toi, et attends qu'elle te passe....
A mon niveau, on ne croit pas, on sait. (Docteur Helmut Perchut)

Avatar de l’utilisateur
Jes
Pom pom pom
Messages : 5822
Inscription : 24 févr. 2002, 14:05
Localisation : Siège social de BessaB
Contact :

Message non lu par Jes »

Ca doit faire six ans que je fais de l'ingénurie inverse et je ne me suis jamais amusé à traduire un code assembleur directement en C. Selon moi, la méthode à suivre est relativement évidente: tracer le code, extraire la routine du log et commencer à l'étudier, avec une feuille de papier et un crayon. Sauf quelques rares cas, il n'y a pas besoin de relancer 50x l'émulateur et placer 32 points d'arrêt pour étudier la routine. Du moment que tu as le contenu des registres en regard (bein comme dans un log normal quoi) ça suffit. Je me répète mais je ne vois vraiment pas l'intérêt de traduire ça en C. Surtout pour une routine d'une centaine de ligne (et c'est quasi tout le temps le cas) qu'est-ce qu'un super méga debugger de la mort qui tue apporte vraiment? Voir deux zones mémoires différentes dans une même fenêtre? Euh ouais, t'es bien avancé avec ça. Perso quand j'étudie une routine, je me concentre sur le code et pas sur les données (d'où la non-nécessité de vérifier ingame le contenu d'une zone mémoire x ou y). A partir d'assez peu d'information sur l'état de la mémoire au début de la décompression, tu peux voir quelques zones-clés vont évoluer.

D'ailleurs, il y a quelques temps j'ai fais analyser à Bahabulle (qui débute en assembleur) une petite routine de 30-50 lignes (une décompression LZ). Je ne citerai pas le jeu, il n'a pas encoré été annoncé je pense. Il a fait ça sans debugger (d'ailleurs je pense pas qu'il savait comment s'en servir :D) et sans traduction C. Je l'ai juste aidé à "débrouissailler" le code et à déduire en français ce que faisait tel ou tel groupe d'instructions. Ca a duré quelques heures mais au final il s'en est tiré. Je suis vraiment curieux de connaître son avis sur l'utilité de faire une traduction C avant l'analyse. Baha, si tu nous écoutes... ;)

Avatar de l’utilisateur
Skeud
Oook ?
Messages : 3809
Inscription : 25 févr. 2002, 22:01
Localisation : Loompaland
Contact :

Message non lu par Skeud »

Chacun sa méthode :p
De toute façon on arrivera pas à convaincre l'autre :D (pis moi ça fait 8. Na! :razz: )
Si tu ressens l'envie de travailler, assieds-toi, et attends qu'elle te passe....
A mon niveau, on ne croit pas, on sait. (Docteur Helmut Perchut)

Avatar de l’utilisateur
BahaBulle
Bub'n'Bob Pawa!
Messages : 6496
Inscription : 06 août 2002, 09:34
Localisation : Sur une bulle
Contact :

Message non lu par BahaBulle »

Euh... personnellement, j'aurais jamais pensé à reprogrammer une routine en C (ou n'importe quoi d'autre) pour :D

Comme Jes l'a dit, j'ai pris la routine qu'il m'a donné, et écrit ce que faisait chaque ligne à côté. Après, avec un peu de réflexion (beaucoup beaucoup pour moi :D), tu comprends la routine. Et après, tu fais le décompresseur.

Je trouve que ça fait double emploi.


Répondre