2009-10-11 14 views
2

J'ai un compilateur qui compile le langage assembleur en langage machine (en mémoire). Mon projet est en C# .net. Existe-t-il un moyen d'exécuter la mémoire sur un thread? Comment le DEP peut-il l'empêcher?comment exécuter du code en mémoire?

byte[] a: 
01010101 10111010 00111010 10101011 ... 

Répondre

2

Je doute qu'il existe une méthode supportée. Je ne sais pas et je ne l'ai pas recherché, mais voici quelques suppositions:

Le moyen le plus simple pourrait être de le lancer en tant que processus: écrivez-le dans un *.com file puis dites au système d'exploitation d'exécuter cet exécutable . Vous pouvez également passer la mémoire en tant que paramètre au CreateThread function (mais vous devrez vous préoccuper du code ayant les bonnes conventions d'appel, en attendant les paramètres spécifiés, en conservant les registres et en étant en mémoire qui est exécutable).

Une autre possibilité consiste à écrire les opcodes dans la mémoire qui est déjà en cours d'exécution (par exemple remplacer le code existant dans une DLL récemment chargée).

+1

Un fichier .com est limité au code DOS 16 bits, et bien que cela puisse suffire à certaines fins, il ne s'agit pas d'une solution générale. Il supporte le coût de chargement de NTVDM pour exécuter le code 16 bits. –

+0

La réponse de JulianR semble bonne. – ChrisW

3

Il est possible d'exécuter octets code:

Inline x86 ASM in C#

Il ne nécessite l'utilisation du code unsafe.

Je pensais que cela était juste un fait amusant, mais inutile dans la pratique, mais peut-être que votre demande a en fait une utilisation pour cette :)

+1

Non recommandé - n'est pas pris en charge dans les applications x64. –

+0

De quelle façon pas? Est-il intrinsèquement cassé, ou juste que l'exemple n'est pas très portable? – JulianR

+0

Le compilateur C++ de Microsoft n'a jamais fait le travail pour le supporter en 64 bits. Au moment où 64 bits est devenu populaire, il n'était pas aussi important pour les gens de programmer dans l'assemblage comme il l'avait été. –

7

La clé est de mettre le code exécutable dans un bloc de mémoire allouée avec VirtualAlloc de sorte que le tampon est marqué comme exécutable.

IntPtr pExecutableBuffer = VirtualAlloc(
    IntPtr.Zero, 
    new IntPtr(byteCount), 
    AllocationType.MEM_COMMIT | AllocationType.MEM_RESERVE, 
    MemoryProtection.PAGE_EXECUTE_READWRITE); 

(utilisez ensuite VirtualFree pour nettoyer après vous-même).

Ceci indique à Windows que la mémoire doit être marquée comme code exécutable afin qu'elle ne déclenche pas de vérification DEP.

+0

+1 Probablement moins hacky que ma méthode: p – JulianR

Questions connexes