2013-02-25 1 views
0

Mon programme redirige une fonction vers une autre fonction en écrivant une instruction jmp sur les premiers octets de la fonction (uniquement i386). Cela fonctionne comme prévu mais cela signifie que je ne peux plus appeler la fonction d'origine, car elle va toujours passer à la nouvelle.rediriger une fonction c à l'exécution et appeler la fonction d'origine

Il existe deux solutions de contournement possibles que je pouvais penser:

  1. créer une nouvelle fonction qui remplace l'instruction jmp de la fonction cible et l'appeler. Ensuite, la fonction réécrit l'instruction jmp. Mais je ne suis pas sûr de savoir comment passer les arguments car il peut y avoir un certain nombre d'entre eux. Et je me demande si la fonction cible peut jmp quelque part ailleurs et sauter l'écriture de l'instruction jmp (comme lancer catch?).

  2. Créez une nouvelle fonction qui exécute le code que j'ai écrasé avec l'instruction jmp. Mais je ne peux pas être sûr que les données écrasées sont une instruction complète. Je devrais savoir combien d'octets je dois copier pour des instructions complètes.

Alors, enfin, mes questions:

  1. Y at-il une autre façon, je ne pensais pas?

  2. Comment trouver la taille d'une instruction? J'ai déjà regardé binutils et trouvé this mais je ne sais pas comment l'interpréter.

Voici un exemple:

mov, 2, 0xa0, None, 1, Cpu64, D|W|CheckRegSize|No_sSuf|No_ldSuf, { Disp64|Unspecified|Byte|Word|Dword|Qword, Acc|Byte|Word|Dword|Qword } 

la 2e colonne indique le nombre d'opérandes (2) et la dernière colonne contient des informations sur les opérandes, séparés par une virgule

J'ai aussi trouvé cette question qui est à peu près la même mais je ne peux pas être sûr que les 7 octets contiennent une instruction entière. Writing a Trampoline Function

Toute aide est appréciée! Merci.

+4

Essayez-vous de faire quelque chose qui ne pouvait pas être fait beaucoup plus simple (et plus portable) avec un pointeur de fonction? – MatthewD

+0

Je n'ai pas de conférence sur le code qui appelle la fonction, donc, non. Je ne peux pas le faire avec un pointeur de fonction. –

+2

Peut-être que vous devriez donner plus d'informations à votre problème afin que nous puissions comprendre pourquoi vous avez choisi cette solution. Ensuite, nous pouvons vous aider ou suggérer quelque chose de mieux. – MatthewD

Répondre

0

Que diriez-vous quelque chose comme ceci:

Disons que c'est la fonction originale:

Instruction1 
Instruction2 
Instruction3 
... 
RET 

convertir à ceci:

JMP new_stuff 
old: 
Instruction2 
Instruction3 
... 
RET 
... 
new_stuff: 
CMP call_my_function,0 
JNZ my_function 
Instruction1 
JMP old 
my_function: 
... 

Bien sûr, vous auriez à prendre la taille des instructions d'origine en compte (vous pouvez le trouver en démontant avec objdump, par exemple) de sorte que le premier JMP s'intègre parfaitement (p annonce avec NOP s si le JMP est plus court que l'instruction (s) d'origine).

+0

Merci qui a aidé. Obtenir la taille de l'instruction originale semble être très difficile. Je ne peux pas utiliser objdump car je devais connaître le nom de la fonction ou l'adresse dans le binaire. L'adresse dans le processus et dans le binaire peut différer afaik. edit: J'ai essayé d'utiliser libopcodes mais j'échoue lamentablement. –

1

Sebastian, vous pouvez utiliser la fonction exe_load_symbols() dans hotpatch pour obtenir une liste des symboles et leur emplacement dans l'exe existant, puis voir si vous pouvez l'écraser en mémoire. Je ne l'ai pas encore essayé. Vous pouvez également le faire avec la variable d'environnement LD_PRELOAD au lieu de hotpatch.

--Vikas

Questions connexes