Assembleur Jmp E9 Ff Calcul Offset

Calculateur assembleur JMP E9 / FF – calcul d’offset x86

Calculez rapidement le déplacement relatif d’un saut assembleur, générez les octets little-endian, vérifiez la plage signée et comprenez la différence fondamentale entre E9, EB et FF /4.

Le mode FF /4 utilise une adresse indirecte via registre ou mémoire. Il ne code pas un offset relatif immédiat comme E9.
Utile si vous forcez un cas de patching particulier. Sinon, la longueur par défaut dépend de l’opcode sélectionné.
Champ informatif affiché dans le résultat quand vous choisissez FF /4.
Renseignez les champs puis cliquez sur « Calculer l’offset JMP ».

Guide expert: comprendre le calcul d’offset pour assembleur JMP E9 FF

Quand on recherche assembleur jmp e9 ff calcul offset, on tombe souvent sur deux besoins très concrets: d’une part calculer correctement le déplacement relatif d’un saut machine pour l’opcode E9, et d’autre part comprendre pourquoi le cas FF ne se traite pas avec la même formule. Cette différence est capitale en reverse engineering, en création de patchs binaires, en instrumentation de code et en développement de loaders ou de trampolines. Une erreur de quelques octets suffit à provoquer un crash, un saut dans une zone invalide, ou un comportement impossible à déboguer. Le but de cette page est de rendre ce calcul fiable, rapide et compréhensible.

Sur architecture x86, l’instruction JMP existe sous plusieurs encodages. Le plus connu pour les modifications binaires est E9, qui représente un saut relatif near. Cela signifie que l’opérande n’est pas une adresse absolue stockée telle quelle, mais un déplacement signé calculé par rapport à l’adresse de l’instruction suivante. C’est exactement ce point qui piège les débutants: on ne fait pas destination – source, mais destination – (source + longueur_instruction).

La formule correcte pour E9

Pour un saut E9 rel32, la formule standard est:

offset = adresse_cible – (adresse_jmp + 5)

Pourquoi 5? Parce que l’instruction fait 1 octet d’opcode plus 4 octets de déplacement signé. Le processeur ajoute d’abord la longueur de l’instruction au pointeur d’instruction, puis applique le déplacement. Pour un cas réel, si le JMP commence à 0x401000 et que la cible est 0x401250, alors:

  1. Adresse de l’instruction suivante: 0x401000 + 5 = 0x401005
  2. Déplacement: 0x401250 – 0x401005 = 0x24B
  3. Octets machine: E9 4B 02 00 00

Les 4 octets de déplacement sont écrits en little-endian. C’est un autre point important. La valeur logique est 0x0000024B, mais les octets sont stockés sous la forme 4B 02 00 00.

Que signifie FF dans un JMP x86?

L’opcode FF couvre plusieurs instructions selon le champ ModR/M. Dans le cas FF /4, on parle d’un JMP near absolu indirect. En clair, le processeur ne lit pas un déplacement immédiat placé après l’opcode, mais va chercher la destination dans un registre ou en mémoire. Par exemple:

  • jmp eax
  • jmp dword ptr [0x00402000]
  • jmp qword ptr [rip+disp32] en x86-64 selon le contexte d’assemblage

Dans ce cas, il n’existe pas d’offset immédiat équivalent à celui de E9. C’est pourquoi un calculateur sérieux doit distinguer ces familles d’encodage. Si vous avez besoin d’écrire un patch de 5 octets avec un saut direct, E9 rel32 est généralement l’outil adapté. Si vous utilisez FF /4, vous êtes dans une logique d’indirection, souvent choisie pour contourner des limites de portée ou pour sauter vers une destination résolue dynamiquement.

Encodage Taille typique Type d’adressage Plage signée / portée Usage principal
E9 rel32 5 octets Relatif -2 147 483 648 à +2 147 483 647 Patching, detours, trampolines, saut inter-fonctions dans la même portée 32 bits
E9 rel16 3 octets Relatif -32 768 à +32 767 Cas historiques ou contextes spécifiques 16 bits
EB rel8 2 octets Relatif -128 à +127 Sauts courts, optimisation de taille
FF /4 Variable Absolu indirect Pas d’offset immédiat direct Appui sur registre ou mémoire pour la cible

Statistiques pratiques qui comptent vraiment

Les chiffres de portée ci-dessus ne sont pas théoriques au sens vague du terme: ce sont les bornes exactes imposées par la taille du champ signé. En pratique, cela a des conséquences immédiates sur les stratégies de hooking. Un EB rel8 n’offre qu’une fenêtre de 256 valeurs possibles, soit 128 en arrière et 127 en avant si l’on raisonne en signé. Un E9 rel32, lui, ouvre une portée de plus de 4,29 milliards de positions possibles au total. Cet écart colossal explique pourquoi E9 est la solution dominante pour les redirections dans les binaires 32 bits et pour de nombreux patchs 64 bits quand la cible reste dans une portée compatible.

Autre donnée importante: la taille occupée par l’instruction. En instrumentation, chaque octet compte. Remplacer un prologue par un E9 suppose en général d’avoir au moins 5 octets sûrs à écraser. Si le bloc à détourner ne fournit que 2 ou 3 octets avant une frontière critique, il faut désassembler précisément, déplacer des instructions complètes et construire un trampoline. Les outils de hooking robustes sont justement conçus pour garantir cette sécurité.

Exemples concrets de calcul d’offset

Voici plusieurs exemples pour éviter les confusions les plus fréquentes:

  1. Saut en avant avec E9 rel32
    Source: 0x1000
    Cible: 0x1100
    Instruction suivante: 0x1005
    Offset: 0x1100 – 0x1005 = 0xFB
    Octets: E9 FB 00 00 00
  2. Saut en arrière avec E9 rel32
    Source: 0x2000
    Cible: 0x1F00
    Instruction suivante: 0x2005
    Offset: 0x1F00 – 0x2005 = -0x105
    Le déplacement est encodé en complément à deux sur 32 bits.
  3. Saut court EB rel8
    Source: 0x3000
    Cible: 0x3070
    Instruction suivante: 0x3002
    Offset: 0x6E
    Valide car compris entre -128 et +127.
  4. Cas FF /4
    jmp dword ptr [0x00402000]
    Ici, la cible n’est pas déduite via destination – (source + longueur). Le processeur lit la valeur stockée à l’adresse mémoire indiquée ou dans le registre visé.
Scénario Adresse JMP Adresse suivante Cible Offset calculé Encodage type
Patch forward 0x401000 0x401005 0x401250 +0x24B E9 4B 02 00 00
Retour arrière 0x402000 0x402005 0x401F20 -0xE5 E9 1B FF FF FF
Short jump valide 0x5000 0x5002 0x5070 +0x6E EB 6E
Short jump invalide 0x5000 0x5002 0x5200 +0x1FE Hors plage rel8

Pourquoi les erreurs arrivent si souvent

La première cause d’erreur est l’oubli de la longueur de l’instruction. Beaucoup de personnes calculent cible – source alors que le processeur raisonne depuis l’adresse suivante. La deuxième cause est l’endianness. Une valeur hexadécimale juste peut produire des octets faux si l’ordre little-endian n’est pas respecté. La troisième cause est le mauvais choix d’encodage: on tente parfois un EB alors que la cible est hors plage, ou l’on croit qu’un FF se calcule comme un E9. Enfin, sur x86-64, la confusion entre adresse absolue, relative et indirecte via mémoire est encore plus fréquente.

Méthode fiable pour patcher un JMP E9

  • Identifiez l’adresse exacte du premier octet de l’instruction remplacée.
  • Déterminez la longueur réelle du saut encodé, en général 5 octets pour E9 rel32.
  • Calculez l’adresse de l’instruction suivante.
  • Soustrayez cette adresse de la cible.
  • Vérifiez que le résultat tient dans la taille signée voulue.
  • Encodez en little-endian.
  • Contrôlez au désassembleur que la destination reconstruite correspond bien à la cible attendue.

Quand choisir E9 plutôt que FF /4

Choisissez E9 quand vous voulez un saut direct compact, simple à calculer, stable et immédiat. C’est le meilleur choix pour de nombreux détournements de flux de contrôle. Choisissez FF /4 quand vous avez besoin d’une destination indirecte, par exemple stockée dans une table, calculée dynamiquement, ou chargée dans un registre. Dans certains systèmes de hooking avancés, l’indirection est utile pour gérer des cibles variables ou pour contourner certaines contraintes de portée.

Références académiques et techniques utiles

Pour approfondir la sémantique des instructions x86, vous pouvez consulter des ressources universitaires sérieuses comme le guide x86-64 de Stanford, le support d’introduction x86 de l’Université de Virginie, et des glossaires techniques gouvernementaux pour le vocabulaire machine code:

Bonnes pratiques finales

Si votre objectif est de calculer un offset assembleur JMP E9, retenez la règle d’or: destination – (adresse_instruction + taille_instruction). Si votre objectif concerne FF /4, ne cherchez pas un offset immédiat qui n’existe pas; analysez plutôt le registre ou l’opérande mémoire utilisé comme source de destination. En reverse engineering, cette distinction fait gagner un temps considérable. Elle permet aussi d’éviter des patchs instables, particulièrement dans les environnements où l’ASLR, les trampolines, les loaders personnalisés ou les mécanismes anti-tamper rendent les erreurs d’encodage très coûteuses.

Le calculateur ci-dessus automatise précisément cette logique. Il vérifie la plage selon le type de saut, affiche les octets attendus et rappelle le statut de validité. Vous pouvez vous en servir comme aide de vérification rapide avant d’écrire vos patchs, de documenter un rapport d’analyse binaire ou de préparer un exercice d’assembleur avancé.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top