Note à ceux qui prendrait l'etude du MF en cours de route.
N'hésitez pas à revenir sur le premier topic et y poser des questions. Je fais des topics séparés exprès.
Retournons à l’étude du code.
Cette fois ci nous nous intéresserons uniquement aux traitements des fichiers txt et à leur reconnaissance
Je ne fais pas de capture d’écran.
Je trouve que celle de Pralinor sont excellentes, cela permet de réexpliquer les choses par une autre personne, c’est très important et je suis certain que cela fonctionne mieux ainsi (en plus c’est une excuse en or pour mon coté feignant)
UTILISATION DU FICHIER TXT
009FEF89 57 PUSH EDI
009FEF8A E8 33B8F3FF CALL <JMP.&D2Common.#11147>
009FEF8F 85C0 TEST EAX,EAX
009FEF91 ^ 7C EB JL SHORT D2Game.009FEF7E |
CQVDSADC
Rien de nouveau
Analyse
C’est facile.
Essayez par vous-même avant de me lire.
Solution :
Appel de 11147(Item ID)
Si le résultat n’existe pas alors on entame la procédure de sortie.
Trivial pour vous maintenant.
Conclusions
Qu’est ce que j’obtiens
Pour mon Carquois = 6
Pour un ID d’objet donné, j’ai toujours le même nombre.
Par contre pour un même nombre je peux avoir plusieurs objets.
Ca dépend de l’objet (on passe l’item ID et on récupère toujours le même résultat pour un objet donné.)
Hypothèse que vous devez en tirer. C’est probablement une info tirée des fichiers Weapons Armors ou Misc.txt.
2 possibilités s’offrent à nous :
1) On trace la routine 11047 .c’est la plus complexe (c’est pourquoi nous l’évitions jusqu’à aujourdhui) mais elle donnera toujours le résultat de façon certaine, après à voir si nous le comprenons ou pas
2) On cherche le chiffre obtenu dans la ligne pour l’objet. Ca devient vite compliqué quand on cherche des 0,1 et tous les chiffres archi commun dans les MPQs.
2 Bis) On prépare un MOD pour simplifier la recherche de type 2 ou pour la confirmer.
Je vais forcer le drop de mon carquois (ID 210) et pour celui dans Misc.txt je vais modifier toutes valeurs par des valeurs uniques facilement identifiables pour mon carquois (le modifier pour tous les objets serait ingérable. Gd merci à la technique de modification.)
Exemple de 2 BIS No Jutsu
Sans MOD 11147(210) donne toujours 6
Si je change uniquement la valeur de la colonne AA en 85 sous Excel pour le carquois et que 11147(210) donne toujours 85 avec ce MOD, c’est que la fonction 11147 lis la colonne AA pour la ligne correspondant à l’ID passé en paramètre. CQFD
La méthode 2 ne donne rien rapidement.
Par contre si vous regardez le résultat pour toutes les armes / armures … vous devinerez surement très vite de quoi il s’agit.
Mais bon c’est assez long. Essayons pour une fois la méthode 1)
Je ne donnerais pas la démarche en détail comme d’habitude, cette procédure n’étant pas notre étude en soit.
Moi j’arrive ici avec un PUSH 210 avant l’appel de la fonction. Le 210 est mon unique paramètre (210 Toujours pour mon carquois)
6FDC141E CC INT3
6FDC141F CC INT3
6FDC1420 >/$ 8B4424 04 MOV EAX,DWORD PTR SS:[ESP+4]
EAX = Param1 pour moi 210 récupéré sur la pile
Cette fonction ca être courte et simple, cela se voit par l’absence de sauvegarde de registre
6FDC1424 |. 3B05 10FBDE6F CMP EAX,DWORD PTR DS:[6FDEFB10]
Param1 Versus Valeur prise dans un tableau dans la DLL (on reverra ca plus loin)ici c’est 28E.
C’est la qu’il faut revenir sur un point très important.
Si vous avez suivi mes conseils, ce chiffre 28E doit vous sauter aux yeux
On reverra la méthode en détail plus tard, je n’insiste pas.
C’est la dernière ligne du fichier WeapArmoMisc.bin.
6FDC142A |. 73 1B JNB SHORT D2Common.6FDC1447
Le CMP Compare si l’objet est bien dans le fichier
Si ce n’est pas le cas On saute à l’Assertion Error (Message d’erreur qui sera affichée au joueur)
On reverra cela plus tard également. Mais grâce à ces messages on apprend des choses très précises sur les variables et la fonction que l’on debug
6FDC142C |. 8B0D 14FBDE6F MOV ECX,DWORD PTR DS:[6FDEFB14]
6FDC1432 |. 85C9 TEST ECX,ECX
6FDC1434 |. 75 07 JNZ SHORT D2Common.6FDC143D
Dans ECX on charge le pointeur vers le début de WeapArmoMisc.bin
Le test valide que le pointeur pointe bien sur quelque chose
Si vous regarder les valeurs des registres analysées par ollydbg c’est le Premier de la liste flpHax (Hachette) qui apparaît.
Ca nous fait une confirmation que le fichier commence bien par le premier objet de Weapons.txt associé au 28E c’est certain, nous manipulons WeapArmoMisc.txt
6FDC1436 |. 68 EF010000 PUSH 1EF
6FDC143B |. EB 0F JMP SHORT D2Common.6FDC144C
Si le test que l’on viens de faire échoue alors on se branche sur le l’assertion ERROR 1EF (l’autre jump amenait sur l’erreur 68E)
6FDC143D |> 69C0 A8010000 IMUL EAX,EAX,1A8
EAX = Param1 * 1A8(taille de la ligne probablement)
Param1 = ID in WeapArmoMisc . bin c’est également la ligne puisque celles ci sont organisées par objet.
6FDC1443 |. 03C1 ADD EAX,ECX
Ajoute déplacement (Ligne multipliée par la taille de la ligne) au début de fichier
6FDC1445 |. 75 1F JNZ SHORT D2Common.6FDC1466
Assertion Error si le déplacement est nul
ASSERTION ERROR
6FDC1447 |> 68 8E060000 PUSH 68E
6FDC144C |> E8 AF7DF9FF CALL <JMP.&Fog.#10265>
6FDC1451 |. 50 PUSH EAX
6FDC1452 |. 68 F4A6DD6F PUSH D2Common.6FDDA6F4
6FDC1457 |. E8 9E7DF9FF CALL <JMP.&Fog.#10024>
6FDC145C |. 83C4 0C ADD ESP,0C
6FDC145F |. 6A FF PUSH -1
6FDC1461 |. E8 A706F9FF CALL D2Common.6FD51B0D
Je ne rentrerais pas dans les détail.
Mais ce morceaux de code prépare le message d’erreur à afficher dans la bonne langue et fait la demande d’affichage
Avant la 1.11 la structure fait qu’ollydbg donnait la syntaxe de l’assertion error. Maintenant il faut se brancher dessus exprès et lire le message d’erreur.
Ici j’obtient une fenêtre Daiblo2 Error
Le contenu est
Citation :
Halt
Location Line #495
Expression Unrecoverable Internal Error at 6FDC1451
|
ICI ca ne nous apprend pas grand chose. Mais ne vous inquiétez pas nous reparlerons des assertions le moment venus.
Par contre très intéressant. On voit que le message d’erreur nous renvoie la bonne adresse dans la DLL d’ou a été appelé la boite de message d’erreur.
6FDC1466 |> 0FBF80 1E0100>MOVSX EAX,WORD PTR DS:[EAX+11E]
EAX = 6 pour mon Bolt ???
Rappelez vous EAX contient le début de la ligne nous concernant.
On lit donc la position +11E sur la ligne.
C’est bien une information contenu dans WeapArmoMisc.bin. Mais cette information a subit une transformation entre le passage des fichiers TXT et la compilation en .bin puisque je ne retrouve pas la valeur dans les txt de départ.
On a vu un début d’explication d’ULMO, mais je ne reprendrais pas tout de suite la méthode.
Disons pour le moment, que nous n’avons rien appris de plus sur notre 6 associé aux carquois
6FDC146D \. C2 0400 RETN 4
6FDC1470 . 33C0 XOR EAX,EAX
6FDC1472 . C3 RETN
6FDC1473 CC INT3
6FDC1474 CC INT3
La fin classique d’une fonction.
CONCLUSION.
Nous ne savons toujours pas ce que signifie ce chiffre. Par contre on sait que le fonction retourne dans EAX la valeur en position +11E sur la ligne correspondant à l’objet dans le fichier weaparmomisc.bin
Je l’ai déjà dit. Nous pourrions aller plus loin et trouver l’info.
Mais je préfère vous montrez que ce n’est pas obligatoire de comprendre tout de suite, et que si cette infirmation est utile alors on découvrira rapidement à quoi elle sert par d’autres moyen.
Continuons.
UTILISATION DU FICHIER TXT – Autre méthode – nouvelle astuce
009FEF93 8B0D 8882A200 MOV ECX,DWORD PTR DS:[<&D2Common.sgptDat>; D2Common.sgptDataTables
009FEF99 8B09 MOV ECX,DWORD PTR DS:[ECX]
009FEF9B 3B81 FC0B0000 CMP EAX,DWORD PTR DS:[ECX+BFC]
009FEFA1 ^ 7D DB JGE SHORT D2Game.009FEF7E
|
CQVDSADC
2 MOV
Un CMP Suivi de JGE.
OK JGE c’est nouveau c’est Greater ou Equal, supérieur ou égal.
Tout ca c’est trivial
Par contre de nouveau on n’attaque pas des registres comme nous l’avions vu auparavant.
On récupère dans D2Common.dll une valeur (de la taille d’1 DWORD) qui est dans une section de D2COMMON qui est un tableau. DS:[<&D2Common.sgptDat>; D2Common.sgptDataTables
Peu importe la syntaxe, on comprend intuitivement. Nous n’avons pas besoin de devenir des experts en assembleur ni en dll.
ECX est un pointeur sur ce tableau
Analyse
ECX = Valeur lue dans une table de D2Common.dll (La deuxième ligne copie dans ECX la valeur en position +00 de ce Tableau)
Cette valeur est un pointeur
C’est complexe, et nous n’avons aucun besoin de comprendre ce type d’imbrication. On en reparlera Hors Topic ou le jour ou vous serez des experts en tracage de DLL de D2
Ensuite on compare EAX (Dont nous ignorons toujours la signification)
Avec la valeur en position +BFC dans le tableau (Le ECX+BFC ), normalement 103 (0x67)
Si le résultat que nous avons obtenu est supérieur à ce MAX alors on sort de la routine
CONCLUSION
On ne sait toujours pas ce qu’est notre valeur mais on sait que le maximum est 103
009FEFA3 8B91 F80B0000 MOV EDX,DWORD PTR DS:[ECX+BF8]
009FEFA9 69C0 E4000000 IMUL EAX,EAX,0E4
009FEFAF 03C2 ADD EAX,EDX
009FEFB1 85C0 TEST EAX,EAX
009FEFB3 894424 10 MOV DWORD PTR SS:[ESP+10],EAX
009FEFB7 ^ 74 C5 JE SHORT D2Game.009FEF7E
|
CQVDSADC
La nouveauté c’est IMUL
Ca signifie simplement multiplication.
Le format est un peu étrange puisqu’il y a trois opérandes.
Le but n’est pas de vous faire un cours d’assembleur mais je vais quand même donner l’explication.
Quand on multiplie 2 DWORD entre eux, il est peu probable que le résultat tienne dans un DWORD. C’est un paramètre qu’il faut indiquer
Commençons par un petit aparté Les registres ont chacun leur particularité.
Par exemple on a vu que EAX reçoit les résultats
Très souvent les pointeurs sur des structures utilisent les registres ESI et EDI
…
Quand les résultat sont sur 64 Bits, ils sont donnés dans EDX :EAX (Nous verrons plus tard la commande assembleur qui prépare ce super registre)
Ici on force le résultat à rester dans EAX seulement
IMUL EAX,EAX,0E4 signifie EAX = EAX * 0E4
IMUL EAX, 0E4 signifierait EDX :EAX = EAX * 0E4
C’est d’autant plus important que on est en train d’utiliser EDX pour autre chose.
Analyse
On récupère une valeur dans le tableau de D2Common.dll.
Etrangement on nous signale ASCII = « « Soit une case Vide ????
Ensuite on ajoute à cette valeur EAX*0E4 (Le IMUL suivi du ADD)
On test le résultat et on sort s’il est NUL
Ensuite on le sauvegarde sur la pile.
Si on regarde EDX (bouton droit Follow in Dump)on s’aperçoit rapidement qu’il s’agit d’un fichier .BIN
Si on observe le trace pour plusieurs objets on en déduit très facilement que
EAX est le numéro de la ligne. C’est aussi notre inconnue de toute à l’heure.
0E4 est la taille de la ligne
Nous l’avons vue rapidement tout à l’heure avec la fonction 11147
Pour calculer le pointeur sur la bonne ligne on fait le calcul suivant
Pointeur sur la ligne = Pointeur début de fichier + Numéro de la ligne * Taille de la ligne
C’est facile à comprendre, et en assembleur on retrouvera quasiment toujours ce schéma pour la gestion des fichier. Ce schéma que vous finirez par reconnaître facilement dans le code.
Du coup on peut même dire que le paramètre d’entrée qui est la valeur que nous ne connaissons pas est la ligne dans ce fichier .BIN.
Comment reconnaitr le fichier d’origine
Ma méthode est simple.
Je les connais très bien donc je les reconnais facilement. Mais cette méthode n’est pas très sure et n’est pas facile à transmettre
Ici on a une tonne d’information capitale qui nous permet de confirmer à coup sur quel est ce fichier.
- On sait que la ligne max est 103, donc le fichier .txt doit contenir 103 Lignes de valeurs.
- On a également la taille de la ligne une fois compilé (c’et moins simple, mais si vous extrayez les .bin au lieu des txts c’est assez facile à retrouver)
- On sait que la première ligne donne ASCII = « « donc que la première ligne commence probablement par NONE
C’est d’ailleurs la méthode que j’ai utilisée tout à l’heure avec notre 28E de weaparmomisc.bin.
Je pourrais vous laissez chercher, mais vous verrez très rapidement que le fichier en question est ItemTypes.txt.
Donc le 6 est l’ItemType de mon carquois.
Allons Vérifier. Ca marche pour mon bolt je trouve xboq pour l’ID 6 (Ligne 8)
A priori la première colonne (pour humain) n’est pas reprise dans le .bin
Pourquoi ligne 8 = ID 6
Les listes commencent toujours avec l’ID 0. Donc le premier NONE (2eme ligne) à l’ID Zéro.
Pourquoi 2 NONE ???
Souvent quand le déplacement est NUL (premier NONE) alors on considère que c’est un bug et on se retrouve avec une assertion error. Du moins c’est mon hypothèse.
Détail important. Que pensez vous qu’il se passe si je fais un mod ou je rajoute des lignes dans ces fichiers ??? L’objet est forcément non magique ??? Faite le test, on en reparle après
Conclusion
Je vous l’avais bien dit
Si la valeur est utilisée plus loin nous pourrons la reconnaître plus loin, en voici la preuve.
Avant de terminer, un conseil. N’oubliez pas de faire une photo de la pile, car nous venons d’y sauvegarder le pointeur sur la bonne ligne de itemtypes.bin
Je vous laisse le faire et me décrire ce que vous devriez y trouver
Utilisation de itemType.txt
009FEFB9 8A48 16 MOV CL,BYTE PTR DS:[EAX+16]
009FEFBC 84C9 TEST CL,CL
009FEFBE 74 0E JE SHORT D2Game.009FEFCE
009FEFC0 5F POP EDI
009FEFC1 5E POP ESI
009FEFC2 B8 02000000 MOV EAX,2
009FEFC7 5B POP EBX
009FEFC8 83C4 08 ADD ESP,8
009FEFCB C2 1000 RETN 10
|
CQVDSADC
Un MOV 1 TEST c’est trivial
Il faut noter 2 choses ICI
EAX contient le pointeur sur notre ligne dans ItemTypes.txt
CL est la version réduite de ECX
Explication
ECX est un DWORD format xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx
La version réduite est CX qui est un WORD xxxxxxxx xxxxxxxx
CX est lui-même divisé en 2 registres 8bits C :
CH(igh)- CL(ow) chacun de la taille d’un byte xxxxxxxx
Ensuite une celèbre procédure de sortie qui n’a plus rien à vous apprendre avec qualité = 2 = Normal
Analyse
Facile on se déplace de +16(bytes) sur la ligne et on place la valeur dans CL.
Ici je présente le résultat pour le drop d’un arc. (itemptype = Bow)
Test valeur en position EAX +16
$ ==> >62 6F 77 20 2F 00 00 00 00 01 04 05 05 00 00 00 bow /.... ...
$+10 >00 00 00 00 00 01 00 00 00 00 03 04 06 01 03 FF ..... .... ÿ
$+20 >00 FF 01 00 00 00 00 00 00 00 00 00 00 00 00 00 .ÿ ............. |
+16 = 00 pour mon BOW donc continue
Si la valeur est 0 on continue.
Autrement on sort avec la valeur 2 pour la qualité.
C’est facile à deviner, on regarde le chiffre dans la colonne Normal de itemTypes.txt (Colonne R sous Excel)
Mais rappelez vous ma méthode 2B) Modifier le fichier txt pour reconnaître qu’elle valeur est lue dans le .bin
C’est ce qu’il faut absolument faire ici et je vous invite vivement à réaliser la manipulation
Conclusion
Si l’objet à une valeur indiqué dans la colonne Normal dans ItemTypes.txt alors il est forcément dropper avec la qualité NORMAL
009FEFCE 8A8E 29010000 MOV CL,BYTE PTR DS:[ESI+129]
009FEFD4 84C9 TEST CL,CL
009FEFD6 74 0E JE SHORT D2Game.009FEFE6
009FEFD8 5F POP EDI
009FEFD9 5E POP ESI
009FEFDA B8 07000000 MOV EAX,7
009FEFDF 5B POP EBX
009FEFE0 83C4 08 ADD ESP,8
009FEFE3 C2 1000 RETN 10 |
CQVDSADC
Même structure que la dernière. Rien de nouveau
Rien mais vous devez absolument avoir testé dans la leçon précédente les qualités pour comprendre que 7 = Qualité Unique
Analyse
OK On test une condition qui amène forcément au résultat unique.
Attention on se déplace de +129 bytes dans ESI. Rappelez vous (plusieurs leçon en arrière) ESI est le résultat de la fonction 10262, pour laquelle notre hypothèse était C’est le pointeur sur la ligne de WeapArmoMisc.bin
C’est l’occasion de vérifier.
On pourrait deviner s’il s’agit de la colonne unique (Colonne BH sous Excel) Mais je vous invite vivement à faire la modification des .txt qui permettra de prouvez que c’est le cas
Conclusion
Si la valeur de la colonne (a vous de me le dire) est non nulle alors l’objet est forcément unique.
009FEFE6 8A48 14 MOV CL,BYTE PTR DS:[EAX+14]
009FEFE9 84C9 TEST CL,CL
009FEFEB 74 0A JE SHORT D2Game.009FEFF7
009FEFED 8A86 2A010000 MOV AL,BYTE PTR DS:[ESI+12A]
009FEFF3 84C0 TEST AL,AL
009FEFF5 ^ 75 E1 JNZ SHORT D2Game.009FEFD8 |
Voici un double test qui amène soit à
On continue
Soit l’objet est unique.
Un bon exercice.
A vous de me dire à quoi correspondent ces colonnes.
Ensuite à vous d’écrire le mécanisme d’utilisation des fichiers Weapons.txt Armor txt et itemtypes.txt pour déterminer la qualité des objets lors du drop.
REMARQUES et PUBLICITE
Si vous posez la question suivante à des experts des fichier txt :
Quelles sont les 2 conditions pour qu’un objet soit forcément unique à partir des fichiers Weapons.txt et ItemTypes.txt ?
je ne sais pas si vous trouverez quelqu’un pour répondre.
Bah très simple il suffit de répondre aux questions du topic
Normalement ce topic devrait amener des tas de question sur la gestion en particulier de itemTypes.txt. Des questions dont nous avons déjà débattues avec Ulmo.
J’en profite pour faire une remarque au passage. Il ne faut pas me croire sur parole, je me trompe régulièrement (Cf ;. Le ligne +2 de la dernière fois) et en plus parfois je fais exprès de glisser des fausses informations (assez évidentes quand même pour ne pas vous faire fuir
)
La prochaine fois, quand vous aurez terminé
nous verrons
Une autre utilisation d’un fichier TXT (au travers du .bin chargé en mémoire) Une révision ultra simple.
la fin de la procédure de calcul de la qualité avec l’archi classique
Est –ce un unique ?
NON alors est ce que c’est un objet de SET
NON alors est ce que c’est un objet RARE
…
NON alors c’est un objet de mauvaise qualité.
Message édité par Myrdinn le 28-01-2006 à 10:14:12
---------------
Le savoir ne vaut que s'il est partagé :Lien vers les posts techniques Diablo2/LOD