Question

Imaginez que je fais quelque chose comme ceci:

void *p = malloc (1000);
*((char*)p) = some_opcode;
*((char*)p+1) = another_opcode; // for the sake of the example: the opcodes are ok

....
etc...

Comment puis-je définir un pointeur de fonction à appeler p comme si elle était une fonction? (J'utilise VC express 2008).

Merci

Était-ce utile?

La solution

Un commentaire n'a pas assez d'espace. Joe_Muc est correcte. Vous ne devriez pas bourrer le code dans la mémoire obtenue par malloc ou new. Vous rencontrez des problèmes si vous modifiez les propriétés de la page des pages que Windows attribue.

Ce n'est pas un problème en utilisant becuase VirtualAlloc () et les API WIN32 liées est chaque facile: appeler VirtualAlloc () et régler la flProtect à [PAGE_EXECUTE_READWRITE][2]

Note, vous devriez probablement faire trois allocations, une page de garde, les pages dont vous avez besoin pour votre code, puis une autre page de garde. Cela vous donnera un peu de protection contre le mauvais code.

enveloppez également des appels à votre code généré avec structuré la gestion des exceptions .

Ensuite, Windows X86 ABI (conventions d'appel) ne sont pas bien documentées (je sais, je l'ai regardé). Il y a quelques informations , ici , ici la meilleure façon de voir comment les choses est de regarder le code généré par le compilateur. Ceci est facile à faire avec le \FA commutateurs ( il y a quatre d'entre eux).

Vous pouvez trouver les 64 bits conventions d'appel .

, vous pouvez également obtenir encore Macro Assembleur de Microsoft MASM . Je recommande d'écrire votre code machine à MASM et regarder sa sortie, puis demandez à votre générateur de code de la machine faire des choses semblables.

Intel et les manuels de processeur AMD sont bonnes références - les obtenir si vous ne les avez pas <. / p>

Autres conseils

En fait, malloc probablement ne sera pas coupé. Sous Windows, vous avez probablement besoin d'appeler quelque chose comme [VirtualAlloc] ( http://msdn.microsoft.com/en-us/library/aa366887 (VS.85) .aspx) afin d'obtenir une page de la mémoire exécutable.

Démarrage petit:

void main(void)
{
    char* p = (char*)VirtualAlloc(NULL, 4096, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    p[0] = (char)0xC3;  // ret

    typedef void (*functype)();
    functype func = (functype)p;
    (*func)();
}

L'étape suivante pour jouer bien avec votre code est de préserver le registre EBP. Ceci est laissé comme un exercice. : -)

Après avoir écrit cela, je l'ai couru avec malloc et cela a fonctionné aussi. Cela peut être parce que je suis en cours d'exécution d'un compte administrateur sur Windows 2000 Server. D'autres versions de Windows peuvent effectivement besoin de l'appel VirtualAlloc. Qui sait.

Si vous avez les opcodes en place, appelant peut être aussi simple que la coulée d'un pointeur de fonction et de l'appeler.

typedef void (*voidFunc)();

char *p = malloc (1000);
p[0] = some_opcode;
p[1] = another_opcode; // for the sake of the example: the opcodes are ok
p[n] = // return opcode...

((voidFunc)p)();

Notez cependant que si vous marquez la page comme exécutable, votre processeur ne peut pas vous laisser exécuter du code généré sur le tas.

Je suis aussi actuellement à la recherche dans l'exécution de code généré, et alors que les réponses ici ne me donne pas précisément ce que je avais besoin, vous les gars m'a envoyé sur la bonne voie.

Si vous devez marquer une page exécutable sur les systèmes POSIX (Linux, BSD, etc.), consultez la page function mmap (2) .

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