[npb@localhost ~]$ cat fun.cppProgram nie korzysta z konkretnego błędu w kompilatorze, tylko z faktu że trochę oszukujemy kompilator. Widać że autor nie do końca sam wiedział co chciał zrobić. Udało mi się rozbudować program w taki sposób aby wykrywał również opcję -O3. Okazało się niestety że nie działa to na wszystkich kompilatorach g++; jednak kod przedstawię:
#include
int main(void)
{
unsigned long l = 0x00110011;
float f = *((float*)(&l));
char* c = (char*)(&f);
if (c[0] == 17) printf("-O1\n");
else printf("-O2\n");
return 0;
}
[npb@localhost ~]$ g++ -O1 -o funO1 fun.cpp
[npb@localhost ~]$ g++ -O2 -o funO2 fun.cpp
[npb@localhost ~]$ ./funO1
-O1
[npb@localhost ~]$ ./funO2
-O2
[npb@localhost ~]$
[npb@localhost ~]$ cat fun.cpp
#include
unsigned long long_it(unsigned long in)
{
return 0x00110011;
}
float float_it(float in)
{
unsigned long v = long_it(*((unsigned long*)(&in)));
return *((float*)(&v));
}
int main(void)
{
float notimportant = 10;
float retval = float_it(notimportant);
char *retvalP = (char*)(&retval);
if (retvalP[0] == 17) printf("-O1\n");
else if (retvalP[0] == 0) printf("-O2\n");
else printf("-O3\n");
return 0;
}
[npb@localhost ~]$ g++ -O1 -o funO1 fun.cpp
[npb@localhost ~]$ g++ -O2 -o funO2 fun.cpp
[npb@localhost ~]$ g++ -O3 -o funO3 fun.cpp
[npb@localhost ~]$ ./funO1
-O1
[npb@localhost ~]$ ./funO2
-O2
[npb@localhost ~]$ ./funO3
-O3
[npb@localhost ~]$
Postawie browara pierwszej osobie, której uda się ten sam trick z opcją -g :)
4 komentarze:
Najbardziej lubię piwo marki Żywiec :-)
W GCC 4.4 wprowadzono nowy atrybut: optimize. Korzystając z niego, można stworzyć 4 kopie funkcji: na 3 z nich wymusić optymalizację odpowiednio: O1, O2, O3, a na czwartej nic nie wymuszać, a następnie porównać kod ciał funkcji. Wymaga GCC >= 4.4. Oczywiście działa też z -g.
Kod: tutaj
Chyba nie wyraziłem zadania wystarczająco jasno. Chodzi o program, który wykryje czy był kompilowany z opcją -g czy nie. Zatem powinien wypisać na ekran coś innego gdy kompilujemy go normalnie, a co innego gdy kompilujemy go z flagą -g. Za kod źródłowy bardzo dziękuję ^^ postaram się go zrozumieć w najbliższy weekend.
No to teraz wykrywa -g:
Nowy kod: tutaj.
Można zrobić to samo nie korzystając z readelf, po prostu oglądając kod programu w pamięci i szukając danych w sekcji .debug_str - ale po co pisać własnego readelfa, skoro go mamy :-)
Rozwiązanie mi się nie podoba :-) No ale trudno - trzebało lepiej precyzować treść zadania - moja wina ;) Nagroda wkrótce ;)
Prześlij komentarz