2013-06-10 4 views
5

stavo leggendo un articolo su x86 API hooking demystified aggancio x86, e mi sono imbattuto in questo codice:Funzione codice operativo in C

if(*function_A == 0xe9) { 
    printf("Hook detected in function A.\n"); 
} 

sembra che questo codice verifica se il codice operativo della funzione è un salto. La mia domanda riguarda la sintassi *function_A. qual è questa sintassi? Restituisce l'opcode di una funzione in C? Ho fatto un sacco di ricerca, ma non ho trovato alcuna documentazione su questa funzione

EDIT

ho pensato che ho aggiunto il link per l'articolo, ma ho appena notato che ho dimenticato di aggiungerlo. Link aggiunto nel caso in cui aiuta.

+1

Qual è il tipo di 'function_A'? Da dove viene il suo valore? – interjay

+0

Questo è il prototipo 'void function_A (int value, int value2);' – Mansuro

+2

Quindi quel codice è sbagliato, confronterà il puntatore della funzione e non l'opcode. – interjay

risposta

5

No, non è possibile annullare il riferimento a un puntatore a funzione per ottenere il codice sottostante.

Questo è probabilmente fatto introducendo un puntatore diverso, e basandosi sulla particolare piattaforma "facendo la cosa giusta", dove "giusto" significa "cosa voglio fare".

Qualcosa di simile:

const unsigned char *function_A = (unsigned char *) printf; /* Any function. */ 

Questo non è portatile, e genererà avvisi del compilatore poiché la funzione di dati e puntatori non sono compatibili. Ad es. x86, probabilmente "funzionerà".

+0

Bene, dove l'ABI dice qualcosa di diverso dallo standard, dovremmo rimanere ancora avvocati linguistici e insistere sul fatto che non è corretto? (Voglio dire, le persone stanno scrivendo il codice shell che funziona con una spiegazione ragionevole.) (E non sto cercando di essere trolling qui, solo interessato.) –

+2

E +1 comunque. Da un altro punto di vista: sotto POSIX, 'void *' è compatibile con i puntatori di dati e funzioni. Ciò significa che void * tmp = & printf; const unsigned char * funcPtr = tmp; 'funziona senza un avviso. –

+0

Il compito può funzionare senza avvertimento, ma funzionerà, cosa pensa che dovrebbe fare un lettore del codice? – Devolus

3

Se si fa qualcosa di simile:

unsigned char *pf; 

pf = (unsigned char *)function_A; 

if (*pf == 0xE9) 
{ 
... 
} 

allora si otterrebbe in tal senso (supponendo che l'architettura consente la lettura del codice in generale, e il compilatore fa il comportamento non definito giusta per raggiungere questo obiettivo).

Tuttavia, a meno di non eseguire la scansione dell'intera funzione nel codice, è possibile ignorare facilmente tale schema di rilevamento inserendo l'istruzione di salto (0xe9 è un salto in un indirizzo relativo) da qualche altra parte o utilizzando una diversa forma di salto istruzione (0x66 0xe9 e un offset a 16 o 32 bit in un'architettura a 32 rispettivamente a 16 bit, ad esempio). E, naturalmente, se ti piace solo scavalcare la funzione di punteggio all'interno di una funzione più lunga, la modifica di alcuni byte all'interno di quella funzione per modificare score += 10 a score += 120 non sarebbe troppo difficile. È possibile che la modifica a score += 10000 potrebbe essere più difficile, dal momento che ci sono spesso varianti "piccolo numero" e "numero elevato" delle istruzioni di aggiunta e sottrazione.