cs_viva
Messages postés11Date d'inscriptionvendredi 20 juin 2003StatutMembreDernière intervention25 mai 2009
-
31 juil. 2006 à 13:12
cs_Nasman
Messages postés202Date d'inscriptionmardi 17 mai 2005StatutMembreDernière intervention29 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 !
_dune2_
Messages postés141Date d'inscriptionmercredi 19 juillet 2006StatutMembreDernière intervention20 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_
Messages postés141Date d'inscriptionmercredi 19 juillet 2006StatutMembreDernière intervention20 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...
cs_Nasman
Messages postés202Date d'inscriptionmardi 17 mai 2005StatutMembreDernière intervention29 septembre 20083 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+
_dune2_
Messages postés141Date d'inscriptionmercredi 19 juillet 2006StatutMembreDernière intervention20 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 ...
Vous n’avez pas trouvé la réponse que vous recherchez ?
cs_viva
Messages postés11Date d'inscriptionvendredi 20 juin 2003StatutMembreDernière intervention25 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
cs_Nasman
Messages postés202Date d'inscriptionmardi 17 mai 2005StatutMembreDernière intervention29 septembre 20083 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.