Domanda

Immaginate che sto facendo qualcosa di simile:

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

....
etc...

Come posso definire un puntatore a funzione di chiamare p come se fosse una funzione? (Sto usando VC ++ 2008 Express).

Grazie

È stato utile?

Soluzione

Un commento non è stato sufficiente spazio. Joe_Muc è corretto. Non si dovrebbe roba del codice nella memoria ottenuto con malloc o new. Si incorrere in problemi se si modificano le proprietà della pagina di pagine che di Windows assegna.

Questo non è un problema becuase utilizzando VirtualAlloc () ed i relativi API Win32 è ogni semplice: chiamare VirtualAlloc () e impostare il flProtect a [PAGE_EXECUTE_READWRITE][2]

Si noti, probabilmente si dovrebbe fare tre allocazioni, una pagina di guardia, le pagine necessarie per il codice, quindi un'altra pagina di guardia. Questo vi darà un po 'di protezione dal male codice.

avvolgere anche chiamate dirette al proprio codice generato con la gestione delle eccezioni strutturata .

Avanti, Windows X86 ABI (convenzioni di chiamata) non sono ben documentate (lo so, ho guardato). V'è una certa Info qui , qui , qui il modo migliore per vedere come funzionano le cose è quello di guardare il codice generato dal compilatore. Questo è facile da fare con la \FA interruttori ( ci sono quattro di loro).

È possibile trovare i convenzioni di chiamata a 64 bit qui .

Inoltre, è comunque possibile ottenere di Microsoft Macro Assembler MASM qui . Vi consiglio di scrivere il codice macchina in MASM e guardare alla sua uscita, quindi avere il generatore di codice macchina fare cose simili.

di Intel e manuali processore di AMD sono buone referenze - farli se non li avete <. / p>

Altri suggerimenti

In realtà, malloc probabilmente non è tagliato. Su Windows, probabilmente è necessario chiamare qualcosa come [VirtualAlloc] ( http://msdn.microsoft.com/en-us/library/aa366887 (VS.85) aspx) al fine di ottenere una pagina eseguibile di memoria.

A partire piccola:

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)();
}

Il prossimo passo per il gioco piacevole con il codice è quello di preservare il registro EBP. Questo è lasciata come esercizio. : -)

Dopo aver scritto questo, mi sono imbattuto con malloc e anche lavorato. Questo può essere perché sto correndo un account amministratore in Windows 2000 Server. Altre versioni di Windows possono effettivamente bisogno la chiamata VirtualAlloc. Chi lo sa.

Se avete i codici operativi giuste luogo, chiamando può essere semplice come la fusione di un puntatore a funzione e chiamarlo.

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)();

Si noti però che se non si contrassegna la pagina come file eseguibile, il processore non può lasciare che si esegue codice generato sul mucchio.

Sono inoltre attualmente esaminando l'esecuzione di codice generato, e mentre le risposte qui non mi ha dato esattamente ciò di cui avevo bisogno, voi ragazzi mi ha mandato sulla strada giusta.

Se avete bisogno di marcare una pagina come eseguibile su sistemi POSIX (Linux, BSD, ecc), controlla la mmap (2) funzione .

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top