Ho scritto un programma "pericoloso" in C++ che salta avanti e indietro da uno stack ad un altro. L'obiettivo è quello di passare dal livello più basso di uno stack di chiamate a un chiamante, fare qualcosa e poi tornare indietro di nuovo, ogni volta saltando tutte le chiamate tra di loro.Cosa fa il registro PIC (% ebx)?
Effettuare questa operazione modificando manualmente l'indirizzo di base dello stack (impostazione %ebp
) e passando a un indirizzo di etichetta. Funziona completamente, con gcc e icc entrambi, senza alcuna corruzione dello stack. Il giorno in cui ha funzionato è stata una bella giornata.
Ora sto prendendo lo stesso programma e lo riscrivo in C, e non funziona. In particolare, non funziona con gcc v4.0.1 (Mac OS). Una volta saltato sul nuovo stack frame (con il puntatore di base dello stack impostato correttamente), vengono eseguite le seguenti istruzioni, appena prima di una chiamata a fprintf
. L'ultima istruzione elencati qui si blocca, NULL dereferenziazione:
lea 0x18b8(%ebx), %eax
mov (%eax), %eax
mov (%eax), %eax
Ho fatto qualche debug, e ho capito che impostando manualmente il registro %ebx
quando passo stack frame (utilizzando un valore ho osservato prima di partire la funzione in primo luogo), risolvo il bug. Ho letto che questo registro si occupa di "codice indipendente dalla posizione" in gcc.
Che cos'è il codice indipendente dalla posizione? Come funziona il codice indipendente dalla posizione? A che cosa sta puntando questo registro?
Si può prendere in considerazione setjmp/longjmp per ottenere questa funzionalità senza mucking con% ebx direttamente. –
In generale, sì, hai ragione. In questo caso, devo essere in grado di passare a un chiamante, eseguire qualche altra funzione e poi tornare indietro al callee. Con setjmp/longjmp, la pila del callee verrebbe sovrascritta dall'altra funzione. –