web-dev-qa-db-fra.com

Appeler une fonction via son adresse en mémoire en c / c ++

Étant donné la connaissance du prototype d'une fonction et de son adresse en mémoire, est-il possible d'appeler cette fonction à partir d'un autre processus ou d'un morceau de code qui ne connaît que le prototype et l'adresse mémoire? Si possible, comment un type retourné peut-il être traité dans le code?

29
dtech

Sur les systèmes d'exploitation modernes, chaque processus a son propre espace d'adressage et les adresses ne sont valides que dans un processus. Si vous souhaitez exécuter du code dans un autre processus, vous devez soit injecter une bibliothèque partagée ou attachez votre programme en tant que débogueur .

Une fois que vous êtes dans l'espace d'adressage de l'autre programme, ce code appelle une fonction à une adresse arbitraire :

typedef int func(void);
func* f = (func*)0xdeadbeef;
int i = f();
48
sbi

Oui - vous décrivez un pointeur de fonction. Voici un exemple simple;

int (*func)(void) = (int (*)(void))0x12345678;
int x = func();

Cela ne fonctionnera probablement pas entre les processus - dans la plupart des systèmes d'exploitation, les processus n'ont pas accès à la mémoire de l'autre.

14
Carl Norum

Lorsque vous avez besoin d'un appel direct:

((void(*)(void))0x1234)();
7
Ulfhetnar

Toutes les réponses précédentes sont agréables mais beaucoup trop longues ;-):

int i = ((int (*)(void))0xdeadbeef)();
2
Fuujuhi

Dans la plupart des OP, chaque processus a sa propre mémoire, vous ne pouvez donc pas.

Exemple de code: a.c:

#include <stdio.h>

int r() {return 2;}
int main() {
    printf("%p\n",r);
    while(1);
}

avant JC:

#include <stdio.h>

int main() {
int a,(*b)();
scanf("%p",&b);
a=b();
printf("%d\n",a);
return 0;
}

cela obtient une faute de segmentation.

1
asaelr

C'est certainement possible, mais il y a des restrictions. Chaque processus aura son propre bloc de mémoire avec lequel les autres processus ne peuvent pas interférer. Maintenant, vous remarquerez, j'ai écrit que c'est certainement possible, c'est par l'injection DLL (ou injection de code).

Nous pouvons utiliser le mot clé typedef pour y parvenir. Maintenant, je vois que vous avez marqué la réponse comme `` Répondue '' et il semble que vous vous soyez bien entendu, ceci n'est qu'un avis pour toute autre personne susceptible d'être intéressée.

0
XxMulti GamerxX