2015-05-16 13 views
8

Więc mam ten kod c:Tajemniczy printf argumentem podczas demontażu c programu

#include <stdio.h> 

int main(void) 
{ 
    int a; 
    int b; 
    int c; 

    a=b=c=5; 

    printf("Hi%d%d%dHi",a,b,c); 
} 

Skompilowałem go na ubuntu z:

gcc program.c -o program -ggdb -m32 -O2 

A następnie rozłożyć go:

objdump -M intel program -d 

I w głównym printf() zostaje wywołany w ten sposób:

mov DWORD PTR [esp+0x10],0x5 
mov DWORD PTR [esp+0xc],0x5 
mov DWORD PTR [esp+0x8],0x5 
mov DWORD PTR [esp+0x4],0x8048500 
mov DWORD PTR [esp],0x1 
call 8048330 <[email protected]> 

Co Zastanawiam się teraz, co to oznacza:

mov DWORD PTR [esp],0x1 

wiem co pierwsze 4 instrukcje mov są za, ale po prostu nie mogę zrozumieć, dlaczego „1” zostanie nasunięty stos. Również ten ruch występuje tylko po włączeniu optymalizacji. Jakieś pomysły?

Odpowiedz

6

Biblioteka GNU C (glibc) użyje __printf_chk zamiast printf, jeśli (lub kompilator) zdefiniowano _FORTIFY_SOURCE i włączona jest optymalizacja. Wersja _chk zachowuje się podobnie jak funkcja, którą zastępuje, z wyjątkiem tego, że ma ona wartość check for stack overflow i może sprawdzać poprawność argumentów. Dodatkowy pierwszy argument wskazuje, jakie powinno być sprawdzenie i zatwierdzenie.

Patrząc na actual glibc implmenation okazuje się, że nie robi żadnych dodatkowych kontroli stosu nad tym, co zapewnia kompilator automatycznie (a więc nie powinno być konieczne), a walidacja argumentów jest bardzo minimalna. Sprawdza, czy %n pojawia się tylko w ciągach w formacie tylko do odczytu, i sprawdza, czy używane są specjalne specyfikatory argumentów , które są używane dla wszystkich argumentów bez żadnych przerw.