2013-06-10 15 views
5

czytałem artykuł x86 API hooking demystified o x86 zahaczanie i natknąłem się na ten kod:Funkcja opcode w C

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

Wydaje się, że ten kod sprawdza czy kod operacji funkcji jest skok. Moje pytanie dotyczy składni *function_A. jaka jest ta składnia? Czy zwraca kod operacji funkcji w C? Zrobiłem wiele badań, ale nie mogę znaleźć żadnej dokumentacji na tej funkcji

EDIT

myślałem dodałem link do artykułu, ale po prostu zauważyłem, że zapomniałem go dodać. Link dodany w razie potrzeby.

+1

Jaki jest typ "function_A"? Skąd wzięła się jego wartość? – interjay

+0

To jest prototypowa 'void function_A (int value, int value2); ' – Mansuro

+2

Następnie ten kod jest nieprawidłowy, porównuje wskaźnik funkcji, a nie kod operacyjny. – interjay

Odpowiedz

5

Nie, nie można wykluczyć wskaźnika funkcji, aby uzyskać kod źródłowy.

Jest to prawdopodobnie robione poprzez wprowadzenie innego wskaźnika i poleganie na konkretnej platformie "robienie właściwych rzeczy", gdzie "prawo" oznacza "co chcę zrobić".

Coś jak:

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

To nie jest przenośny i będzie generować ostrzeżenia kompilatora od funkcji i danych wskaźniki nie są kompatybilne. Na przykład x86, prawdopodobnie "zadziała".

+0

No cóż, gdzie ABI mówi coś innego niż Standard, czy powinniśmy nadal pozostać prawnikami i nalegać, że to nie jest poprawne? (Znaczy, ludzie piszą kod powłoki, który działa z rozsądnym wyjaśnieniem.) (I nie próbuję tu być trollingu, tylko zainteresowałem się). –

+2

I +1 mimo to. Z innego punktu widzenia: pod POSIX 'void *' jest kompatybilny zarówno ze wskaźnikami danych i funkcji. Oznacza to, że 'void * tmp = & printf; const unsigned char * funcPtr = tmp; 'działa bez ostrzeżenia. –

+0

Przypisanie może zadziałać bez ostrzeżenia, ale czy wykona, co czytelnik kodu uważa, że ​​powinien zrobić? – Devolus

3

Jeśli zrobisz coś takiego:

unsigned char *pf; 

pf = (unsigned char *)function_A; 

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

wtedy można uzyskać taki efekt (zakładając, że architektura umożliwia odczyt kodu w ogóle, a kompilator robi niezdefiniowanej zachowanie właściwej do osiągnięcia tego celu).

Jednak, jeśli nie zeskanujesz całej funkcji w kodzie, można z łatwością ominąć taki schemat wykrywania, umieszczając instrukcję skoku (0xe9 jest skokiem do względnego adresu) gdzie indziej lub używając innej formy skoku instrukcja (0x66 0xe9 i 16 lub 32-bitowe przesunięcie w architekturze 32-bit 16-bitowej, na przykład). I oczywiście, jeśli chcesz tylko zastąpić funkcję oceniania w dłuższej funkcji, modyfikowanie kilku bajtów w tej funkcji w celu zmiany score += 10 na score += 120 nie będzie zbyt trudne. Możliwe, że zmiana na score += 10000 może być trudniejsza, ponieważ często występują "małe liczby" i "duże liczby" wariantów instrukcji dodawania i odejmowania.