19 votes

Comment coder un jmp court relatif en x86 ?

Supposons que je veuille faire un saut court en utilisant l'opcode EB, jmp rel8 saut court
Entrée dans le manuel d'Intel :

EB CB ou JMP rel8

"En bref, RIP = RIP + signe de déplacement de 8 bits étendu à 64 bits"

(où CB est un octet valeur signée représentant le décalage relatif relatif à la direction dans PIE registre)

Peut-être que le décalage sera toujours décalage+2 parce que l'EIP dans le temps d'exécution (la direction de référence) dans ce saut court est la base de l'instruction de deux octets, mais l'addend se produit toujours

  • eb 30 = jmp 0x00000032 (+30)
  • eb e2 = jmp 0xffffffe4 (-30)

alors EIP peut être intentionnellement dans la même direction car fe + 2 est 00 o PIE .

  • eb fe = jmp 0x00000000

Je trouve surprenant que la surcompensation s'est produit une bifurcation bien que le nombre soit négatif. Mais dans l'Intel je ne trouve aucune mention (peut-être parce que 3000 pages).

Architectures Intel® 64 et IA-32 Manuel du développeur de logiciels : Vol. 2A 3-423

Un saut proche où la portée du saut est limitée à -128 à +127 de l'actuel Valeur EIP.

J'envisage alors trois possibilités :

  1. est +2 car c'est le valeur après/à l'avenir de l'EIP dans le temps d'exécution
  2. La valeur codée n'est pas un nombre signé codé en composante 2s.
  3. Cela figure dans le manuel mais je ne l'ai pas vu parce que je suis stupide.

23voto

JosephH Points 3668

Qu'il s'agisse d'un saut court ou non, il est toujours destination - (source + sizeof(instruction)) .

c'est-à-dire dst - end_of_jmp

Dans votre cas (saut court), sizeof(instruction) est de 2.

La raison de cet ajout est qu'une fois que le processeur a effectué l'étape de recherche d'instruction, le pointeur d'instruction pointe déjà vers l'instruction qui vient après la branche. Le déplacement de la branche rel8 ou rel32 est relatif à cette valeur EIP/RIP.

19voto

nrz Points 6599

En rel8 est relative à l'adresse mémoire de l'instruction suivante, comme on peut facilement le confirmer en créant deux exécutables et en les désassemblant :

@label:
    jmp @label
    nop

Il se désassemble comme suit (avec ndisasm, c'est la même chose en code 16 bits, 32 bits et 64 bits) :

EBFE jmp short 0x0
90   nop

Ensuite, un autre exécutable :

    jmp @label
@label:
    nop

EB00 jmp short 0x2
90   nop

Ainsi, le rel8 est toujours codée par rapport à l'instruction suivante après jmp . Désassembleurs (au moins ndisasm y udcli ), cependant, l'indiquent par rapport à la jmp l'instruction elle-même. Cela peut éventuellement prêter à confusion.

7voto

SecurityMatt Points 3467

Le court-circuit de saut prend un EIP par rapport au fin de l'instruction de saut (d'une longueur de deux octets) et prend un opérande d'un octet, qui est étendu en signe et ajouté à EIP.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X