Question

Je suis en train de coder un packer exe / protecteur comme un moyen d'en apprendre davantage sur assembleur, c ++, et comment fonctionnent les fichiers PE. Je suis actuellement obtenu ce travail de sorte que la section contenant le PE est XORed avec une clé et une nouvelle section est créée qui contient mon code de décryptage. Tout fonctionne très bien, sauf quand je tente de JMP au PE d'origine après le déchiffrement.

En fait, je fais ceci:

DWORD originalEntryPoint = optionalHeader->AddressOfEntryPoint;
// -- snip -- //
    crypted.put(0xE9);
 crypted.write((char*)&orginalEntryPoint, sizeof(DWORD)); 

Mais au lieu de sauter au point d'entrée, ollydbg montre que ce code désassemble à:

00404030   .-E9 00100000    JMP 00405035 ; should be 00401000 =[

et quand je tente de le changer manuellement Olly la nouvelle opcode apparaît comme

00404030    -E9 CBCFFFFF    JMP crypted.00401000

D'où 0xCBCFFFFF vient? Comment puis-je générer que du côté C ++?

Était-ce utile?

La solution

Je pense que E9 est un opcode pour un saut relatif:. Opérande spécifie une distance par rapport à sauter, plus ou moins depuis le début de l'instruction suivante

Si vous voulez que l'opérande pour spécifier une adresse absolue, vous auriez besoin d'un autre opcode.

Autres conseils

vous pouvez utiliser:

mov eax,DESTINATION_VA
jmp eax                ; pick any register the destination doesn't care about

ou

push DESTINATION_VA
ret                    ; not recommended for performance

et les instructions suivantes mise à 16 ret remontant l'arbre d'appel supérieur à cette profondeur sera mispredict, à moins qu'ils ont été poussés hors du prédicteur adresse de retour pile par une profondeur d'appel plus profond. (CPU actuels ont généralement une pile de prédiction de 16 l'entrée).


E9 href="http://felixcloutier.com/x86/JMP.html" rel="nofollow noreferrer"> jmp codage est utilisé comme suit:

CURRENT_RVA: jmp (DESTINATION_RVA - CURRENT_RVA - 5 [sizeof(E9 xx xx xx xx)])

+ poussée ret est la plus petite solution si vous avez l'adresse VA et l'image n'est pas relocalisé, mais il est encore 6 octets il est donc plus grand qu'une jmp rel32 directe.

Inscrivez-indirect est probablement le plus efficace si vous ne pouvez pas utiliser une jmp directe normale.

opcode pour saut indirect est absolu adresse FF + 4byte. Ceci est le plus souvent utilisé pour jumptables d'adresses stockées dans les données.

adresses absolues ne nécessitent la réinstallation lorsqu'ils ne sont pas chargés à l'adresse prévue, les adresses relatives sont généralement préférées. Code pour les sauts relatifs est également de 2 octets plus petit.

optimisation Intel états manuels que le cpu appel et attend ret à utiliser par paires, de sorte que le ret sans appel proposé en réponse 2 causerait ce qu'ils appellent une « pénalité de performance ».

En outre, si le code n'a pas été chargé à la même adresse que le compilateur supposé, le ret serait probablement planter le programme. Il serait plus prudent de calculer une adresse relative.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top