REPNZ SCAS Instructions de Montage Détails
Je suis en train de désosser un binaire et de l'instruction suivante est source de confusion, moi, quelqu'un peut-il préciser exactement ce que cela fait?
=>0x804854e: repnz scas al,BYTE PTR es:[edi]
0x8048550: not ecx
Où:
EAX: 0x0
ECX: 0xffffffff
EDI: 0xbffff3dc ("aaaaaa\n")
ZF: 1
Je vois qu'il est en quelque sorte la décrémentation ECX de 1 à chaque itération, et que l'EDI est en incrémentant le long de la longueur de la chaîne. Je sais qu'il calcule la longueur de la chaîne, mais aussi loin que exactement COMMENT ça se passe, et pourquoi "al" est en cause, je ne suis pas tout à fait sûr.
Vous devez vous connecter pour publier un commentaire.
Je vais essayer de l'expliquer en inversant le code en C.
Intel Jeu d'Instructions de Référence (Volume 2 de Manuel de développement logiciel) est indispensable pour ce type de rétro-ingénierie.
REPNE SCASB
La logique de REPNE et SCASB combiné:
Ou plus simplement:
La Longueur De La Chaîne
Cependant, le ci-dessus est insuffisante pour expliquer comment il calcule la longueur d'une chaîne. Basé sur la présence de la
not ecx
dans votre question, je suis en supposant que le fragment appartient à cet idiome (ou similaire) pour le calcul de la longueur de la chaîne à l'aide deREPNE SCASB
:La traduction à C et à l'aide de notre logique à partir de la section précédente, nous obtenons:
Simplifiant à l'aide de
al = 0
etDF = 0
:Choses à noter:
ecx
est équivalent à-1 - ecx
.ecx
est décrémenté avant la boucle des pauses, de sorte qu'il décrémente parlength(edi) + 1
au total.ecx
ne peut jamais être nulle dans la boucle, depuis la chaîne devrait occuper la totalité de l'espace d'adressage.Donc après la boucle ci-dessus,
ecx
contient-1 - (length(edi) + 1)
qui est le même que-(length(edi) + 2)
, qui nous retourner les bits de donnerlength(edi) + 1
, et enfin de décrémentation pour donnerlength(edi)
.Ou du réaménagement de la boucle et la simplification:
Et d'inverser le comte:
qui est le
strlen
fonction de C:AL
est en cause, carscas
scanne la mémoire de la valeur deAL
.AL
a été remis à zéro, de sorte que l'instruction constate la résiliation de zéro à la fin de la chaîne.scas
lui-même incrémente (ou décrémente, en fonction de l'indicateur de direction)EDI
automatiquement. LeREPNZ
préfixe (qui est plus lisible enREPNE
forme) répète lescas
aussi longtemps que la comparaison est faux (REPmanger tout Not Equal) etECX > 0
. Il a également décrémenteECX
automatiquement à chaque itération.ECX
a été initialisé à la plus longue chaîne possible, afin de ne pas mettre fin à la boucle tôt.Depuis
ECX
compte à rebours à partir0xffffffff
(aussi connu comme -1), la longueur sera de-1-ECX
qui, en raison de la particularité de 2 complément arithmétique peut être calculée à l'aide d'unNOT
instruction.Il compare l'octet à
es:[edi]
à ce que dansal
est et répéter cette étape jusqu'à ce que soitecx
est à zéro ou à la valeur àes:[edi]
correspond à la valeur dansal
. Après chaque étape,edi
est incrémenté de sorte qu'il pointe vers le prochain octet en mémoire.Le programme s'applique
not
au compteur (ecx) par la suite, basé sur l'instruction suivante.repnz
signifie "répéter jusqu'à ce qu'indicateur de zéro n'est pas définie et cx n'est pas égal à zéro". Chaque itération décrémenteecx
.scas
ou plus précisémentscasb
compare la valeur dansal
à la mémoire de l'opérande (toujourses:[edi]
oues:[di]
en fonction de l'adresse de la taille), puis définit les drapeaux en conséquence (indicateur de zéro sera fixé si les deux valeurs sont égales) et incrémente (ou décrémente, basé sur l'indicateur de direction)edi
.