2010-07-13 8 views
4

J'ai un code qui change la fonction que l'on appelle, à ma nouvelle fonction, mais je ne veux pas appeler seulement ma nouvelle fonction, je veux aussi appeler l'ancienne . Ce est un exemple, afin que vous puissiez comprendre ce que je dis:Appelez une fonction deux fois avec Assembly et C++

Si je démonte mon .exe, je vais regarder cette partie:

L0: 
     mov eax, [L00654321] //doesn't matter 
     mov ecx, [eax+1Ch] //doesn't matter 
     push esi    //the only parameter 
0x123 call SUB_L00999999 //this is the function I wanna overwrite 
     //... 

(0x123 est l'adresse de cette ligne) donc, j'utilisé ce code:

DWORD old; 
DWORD from = 0x123; 
DWORD to = MyNewFunction; 
VirtualProtect(from, 5, PAGE_EXECUTE_READWRITE, &old); 

DWORD disp = to - (from + 5); 
*(BYTE *)(from) = 0xE8; 
*(DWORD *)(from + 1) = (DWORD)disp; 

maintenant, au lieu d'appeler SUB_L00999999, il appelle MyNewFunction ...

Alors ... des idées sur comment puis-je appelle toujours l'ancienne fonction?

J'ai essayé des choses comme ça (à bien des égards), mais il se bloque ma demande:

int MyNewFunction(int parameter) 
{ 
    DWORD oldfunction = 0x00999999; 
    _asm push parameter 
    _asm call oldfunction 
} 

Remarques: J'utilise Visual Studio C++ 2010 et ces codes sont dans un .dll chargé dans un fichier .exe.

Merci.

Répondre

2

J'ai eu un problème comme ça il y a un certain temps. Quoi qu'il en soit, _asm call dword ptr [oldfunction] a travaillé pour moi.

+0

Merci mec, ça a bien fonctionné, je ne me rappelais pas avoir utilisé ça il y a quelque temps ... –

2

ret s'attend à ce que l'argument de la pile supérieure soit l'adresse à laquelle retourner. Vous pouvez exploiter cela en poussant l'ancienne adresse de la fonction sur la pile immédiatement avant votre instruction ret dans votre nouvelle fonction. Lorsque l'appel revient (ou plutôt, ramène à l'ancienne fonction), le pointeur de la pile se décale pour laisser l'adresse de retour d'origine (0x128 ici) sur le dessus, de sorte que la pile n'apparaisse pas endommagée. (comme cela aurait dû être si vous n'aviez pas fait de détour).

+0

Pouvez-vous me donner un exemple de code en utilisant "ret"? Je vous remercie. –

+1

Essayez '_asm {push oldfunction; ret 4} 'et vérifiez votre sortie avec un débogueur. Je ne suis pas sûr que le compilateur C puisse ajouter/enlever n'importe quoi d'autre qui pourrait bouleverser la pile. La pile devrait avoir l'air identique lorsqu'elle entre dans la fonction ancienne comme elle l'a été lorsqu'elle est entrée dans une nouvelle fonction. (Oh, et certains registres doivent être identiques, vous devrez peut-être les régler avant de retenter). –

+0

Votre réponse devrait fonctionner aussi, mais c'est plus compliqué du fait qu'au lieu de simplement appeler la fonction avec mes paramètres, nous retournerions à l'ancienne pile et ensuite nous appellerions la fonction. J'ai vu cela dans un fichier de projet et j'ai essayé de le faire de cette façon, mais c'est plus dur que @myeviltacos. Merci d'avoir aidé. –

Questions connexes