Routine inversée...

cs_viva Messages postés 11 Date d'inscription vendredi 20 juin 2003 Statut Membre Dernière intervention 25 mai 2009 - 31 juil. 2006 à 13:12
cs_Nasman Messages postés 202 Date d'inscription mardi 17 mai 2005 Statut Membre Dernière intervention 29 septembre 2008 - 1 août 2006 à 08:33
salut,
peutons inversé cette routine. je débute en asm je sais lire ces instructions mais j'ai des limites.
 
MOV ESI, valeur   
  MOV BL,BYTE PTR DS:[ESI]


@R001:
  CMP BL,30h
  JL SHORT 0040122Ch // s'assurer que c'est un entier (integer) (0...9) val hex (30...39)
  CMP BL,39h
  JG SHORT 0040122Ch // s'assurer que c'est un entier (integer)  (0...9) val hex (30...39)
  MOV CL,0Ah
  MUL ECX
  MOV CL,BYTE PTR DS:[ESI]
  ADD EAX,ECX
  ADD EDX,ECX
  INC ESI
  MOV BL,BYTE PTR DS:[ESI]
  CMP BL,0h
  JE @R002            // fin du traitement
merci !

6 réponses

_dune2_ Messages postés 141 Date d'inscription mercredi 19 juillet 2006 Statut Membre Dernière intervention 20 avril 2011
31 juil. 2006 à 16:12
salut !


Je ne comprends pas vraiment le sens de ta question.

Qu'entends-tu par 'inverser' la routine ?


Peux-tu aussi preciser tes sauts conditionnels avec des labels et non
avec des adresses ("JL SHORT 0040122Ch" , "JG SHORT 0040122Ch") car
sans le contexte de compilation, il nous est difficile de comprendre ce
code.

Même remarque pour la fin: la fin du traitement se fait sur une
condition de BL null, mais si celui-ci n'est pas null (et que donc le
traitement n'est terminé), je doute fort que l'instruction suivante
soit "merci" .


Bref, le code, ci présent, sorti de son contexte est un peu juste pour obtenir une aide je pense.


dune2.

Gentoo... que du bonheur ...
0
_dune2_ Messages postés 141 Date d'inscription mercredi 19 juillet 2006 Statut Membre Dernière intervention 20 avril 2011
31 juil. 2006 à 16:46
Première analyse sommaire du code présent :


je pense qu'on peut considerer que la suite valeur sur 1 octet à analyser se trouve pointé par DS:[ESI].

Donc on charge le 1er octet.


** MOV BL,BYTE PTR DS:[ESI]


Si cet octet n'est pas un caractère chiffre [0..9] (30h -> 39h) on va @0040122Ch (quelque part dans la mémoire ).


**  CMP BL,30h

**  JL SHORT 0040122Ch // s'assurer que c'est un entier (integer) (0...9) val hex (30...39)

**  CMP BL,39h

**  JG SHORT 0040122Ch // s'assurer que c'est un entier (integer)  (0...9) val hex (30...39)


On charge CL avec la valeur 10.


**  MOV CL,0Ah


Puis on multiplie ECX (32bits) dont on ne connais pas les 24bits MSB,
par EAX dont on ne connais pas non plus le contenu pour mettre le
résultat dans EDX:EAX.


**  MUL ECX


Ensuite on recharge de nouveau l'octet de la chaine dans CL


**  MOV CL,BYTE PTR DS:[ESI]


Et on ajoute ECX (24bits MSB non connus) à EAX et EDX résultant je le
rappelle de la multiplication ECX par EAX tous 2 non déterminés à part
les 8bits de poids faibles de ECX (ce qui ne représente pas grand chose
sur le résultat du produit de 2 nombres de 32bits).


**  ADD EAX,ECX

**  ADD EDX,ECX


On se décale dans la chaine d'un octet, puis on charge ce nouvel octet dans BL.


**  INC ESI

**  MOV BL,BYTE PTR DS:[ESI]


Si on tombe sur l'octet null, c'est fini.


**  CMP BL,0h

**  JE @R002            // fin du traitement


Voilà l'analyse ... maintenant les questions :


1) que vaut EAX lors de la 1ere itération ? (par la suite on peut
évidemment dire que la valeur EAX est connue et je suppose qu'il vaut
0).

2) le contenu des MSB de ECX est indeterminé ... je pense qu'il doit y
avoir une initialisation de ECX à 0 au début du code, non ?

3) Je suppose qu'il manque un "JMP @R001" à la fin du code.


Je pense commencer à comprendre ton code en supposant que ECX soit nul et un autre ajout que j'expliquerai aprés :

Il réalise la conversion d'une suite de chiffre en résultat numérique.

ex: "324" -> valeur numérique 324.

Mais pour que ça fonctionne , il manque un "SUB CL,30h" juste avant "ADD EAX,ECX"


Dans ce cas (avec toutes ces suppositions), il est évidant que si tu
inverses la routine (en considérant que tu penses à linversion de
l'ordre de lecture des octets), le résultat inversera les
unités,dizaines,centaines,etc...


Chris.

Gentoo... que du bonheur ...
0
cs_Nasman Messages postés 202 Date d'inscription mardi 17 mai 2005 Statut Membre Dernière intervention 29 septembre 2008 3
31 juil. 2006 à 17:11
Bonjour,

Comme le mentionne _dune2_, il est difficile de répondre à ta question faute de disposer de plus de code.
Apparemment la routine multiplie la valeur mise dans eax par 10 et ajoute l'octet pointé par DS:ESI à chacun des dword résultants de la multiplication. Le résultat est dans edx:eax soit un résultat valant:
2^32.(edx+x)+(eax+x) où x est la valeur de l'octet et edx:eax est le produit de 10 par l'ancienne valeur de eax.
Tout celà ressemble à une routine de cryptage ou la génération de clé à partir d'une chaine numérique. Le test du zéro correspondrait à la fin de la chaine
Par exemple la chaine "12345" traduite en assembleur par 31h,32h,33h,34h,35h,0

Par exemple si eax=ABCD1234 alors tou pourrait avoir:
edx=6 eax=B602B608 auquels il faut ajouter ecx (dont seul l'octet bas est modifié - les autres sont peut être non nuls)
edx=6+1=7 eax=B602B608+1=B602B609
Si le cryptage continue il faut multiplier la valeur de eax par 10
edx=7 eax=1C1B1C5A
Après ajout de 2
edx=9 eax=1C1B1C5C
Ensuite
edx=1 eax=190F1B98 ajouter 3
edx=4 eax=190F1B9A
Ensuite
edx=0 eax=FA971404 ajouter 4
edx=4 eax=FA971408
Ensuite
edx=9 eax=C9E6C850 ajouter 5
edx=E eax=C9E6C855
Traitement terminé
Si les autres octets de ecx ne sont pas nuls alors le cryptage sera différent.

A priori la routine doit avoir pour paramètres ecx,eax et la chaine numérique, au retour on peut exploiter les registres edx et eax. Trouver le cryptage inverse me parait pas évident du tout.
A+
0
_dune2_ Messages postés 141 Date d'inscription mercredi 19 juillet 2006 Statut Membre Dernière intervention 20 avril 2011
31 juil. 2006 à 17:34
re,


C'est effectivement une autre interpretation du code possible. Mais je
l'aurais privilégié que si il n'y avait pas eu la restriction de la
chaine d'entrée, à savoir des valeurs uniquement numériques. Pour
calculer une signature sur un texte par exemple.


Nasman: dans ton exemple, tu supposes que la valeur de ecx passe du
code ASCII (31h,32h,33h,34h,35h) à la valeur numérique (1,2,3,4,5) au
moment de l'addition avec edx et eax. Or pour celà, il manque un "sub
cl,30h".


Par contre, je ne vois toujours pas l'interêt du "add edx,ecx" .... vu
que edx est écrasé par le produit suivant ... (si ce n'est de récuperer
la somme du dernier octets avec la partie 32bits poids fort du dernier
produit).


dune2.

Gentoo... que du bonheur ...
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
cs_viva Messages postés 11 Date d'inscription vendredi 20 juin 2003 Statut Membre Dernière intervention 25 mai 2009
31 juil. 2006 à 20:43
Salut,<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /??>





Avant de continuer je tiens à vous dire merci pour vos réponses!






 






Voilà le code complet, mais avant est-il possible d'étudier un KeyGenMe
proposé sur un défi totalement légal car ça ne touche en aucun cas la propriété intellectuelle. Je code en Delphi et j'ai jugé que la routine de vérif du serial est intéressante. Car elle calcule le serial saisi et le name saisi et après passage par les deux routines le résultat du couple serial et name doit être identique.






 






Exemple : bonjour  après traitement devient :  0DB85ED0 et le serial saisi  xxxxxxx après traitement doit donner le même résultat : 0DB85ED0






 







  MOV ESI, 

Serial


















  MOV BL,BYTE PTR DS:[ESI]






 














@L002:

















 


          
 CMP BL,30h

















 
          JL
@BadBoy

















 


          
 CMP BL,39h

















 
          JG
@BadBoy

















 


          
 MOV CL, 0Ah

















 


          
 MUL ECX

















 


          
 MOV CL,BYTE PTR DS:[ESI]

















 
          ADD EAX,ECX

















 


          
 ADD EDX,ECX

















 


          
 INC ESI

















 


          
 MOV BL,BYTE PTR DS:[ESI]

















 
          CMP BL,0h

















  JE
@L016

















 


          
 JMP
@L002








Résultat du serial
1234567

0340A3D7
















@L016:

















 


          
 MOV ESI,

Name


















 


          
 XOR EBX,EBX

















 


          
 XOR ECX,ECX

















 
          MOV BL,BYTE PTR DS:[ESI]






 














@L020:

















 


          
 ADD CL,BL

















  ROL ECX,3h

















 


          
 INC ESI

















  MOV BL,BYTE PTR DS:[ESI]

















  CMP BL,0h

















  JNZ
@L020









                                  Résultat du name bonjour  = 
0DB85ED0

















  XOR ECX,EDX     Résultat du  après le xor  name bonjour  = 
0DB85EE7






 















 


          
 CMP ECX,EAX      si le name et le serial ne sont pas égaux  alors Badboy

















 


          
 JNZ
@BadBoy
















@BadBoy:





Message de BadBoy
0
cs_Nasman Messages postés 202 Date d'inscription mardi 17 mai 2005 Statut Membre Dernière intervention 29 septembre 2008 3
1 août 2006 à 08:33
Bonjour,

Effectivement dans mon exemple j'ai oublié que les octets lus sont des caractères et non pas des valeurs de 0 à 9, les calculs sont donc faux mais le principe demeure.
L'instruction add edx,ecx ne présente d'interrêt que dans la mesure où la valeur d'edx est récupérée à la fin (pour les calculs intermédiaires la valeur est écrasée) - elle pourrait être mise que dans le but de compliquer le programme et donc d'induire en erreur les curieux.

A+
0
Rejoignez-nous