Skocz do zawartości
  • 👋 Witaj na MPCForum!

    Przeglądasz forum jako gość, co oznacza, że wiele świetnych funkcji jest jeszcze przed Tobą! 😎

    • Pełny dostęp do działów i ukrytych treści
    • Możliwość pisania i odpowiadania w tematach
    • System prywatnych wiadomości
    • Zbieranie reputacji i rozwijanie swojego profilu
    • Członkostwo w jednej z największych społeczności graczy

    👉 Dołączenie zajmie Ci mniej niż minutę – a zyskasz znacznie więcej!

    Zarejestruj się teraz

Dlugość funkcji w bajtach.


Rekomendowane odpowiedzi

Opublikowano

Szukałem sposobu żeby obliczyć długość funkcji i nic nie znalazłem. Zacząłem sam pisć.

 

Jak na razie uwzględniam:

pop dowolny_rejestr

retn

 

xor rejestr, rejestr

retn

 

retn

int 3

 

ret xxxx

 

pop

ret xxxx

 

 

 

Kod(if rozbity dla wygody): 

uunsigned int GetFunctionSize(void* func)
{
	unsigned int offset = 0;
	unsigned char* f = (unsigned char*)func;
	
	printf("%.8X\n", (DWORD)f);

	if(f[0] == 0xE9)
	{
		f = f + *(DWORD*)(f+1) + 5;
	}
	
	for(; offset < 0xFFFF; ++offset)
	{
		if(
			(
				(
					(f[offset] & 0xF0) == 0x50 ||
					f[offset-1] == 0x33
				) && 
				f[offset + 1] == 0xC3
			)
			||
			(
				f[offset] == 0xC3 &&
				f[offset + 1] == 0xCC
			)
			||
			(
				f[offset-1] == 0xC2 &&
				f[offset + 2] == 0x90
			)
			||
			(
				(f[offset-2] & 0xF0) == 0x50 &&
				f[offset-1] == 0xC2
			)
			
		  )
			break;
	}
	offset++;
	return offset;
}
No i teraz pytanie, co jeszcze może zwrócić kompilator?

Szukanie samego retn(0xC3) dużo nie da, może się trafić ze w adresie będzie ta wartość no i...

Może macie jakieś inne metody?

 

@edit, aktualizacja o jmp do importów.

Nie pomagam na PW, od tego macie forum!!!

 

#PHP-things

 

 

08FMpDu.png

 

Opublikowano

Według mnie to jest bez sensu.

Po kompilacji nie zawsze da się stwierdzić ile ta funkcja zajmuje, bo może jej w ogóle nie być w postaci charakterystycznej dla funkcji (tzn. mogła zostać zinlinowana lub inaczej zoptymalizowana).

Twój sposób z returnem jest zły, bo nie zawsze musi on być.

Napisz po co ci to w ogóle? Nie widzę potrzeby wiedzenia tego.

 

Ewentualnie znalazłem jedną opcję, która może działać (z pliku obiektowego)

http://stackoverflow.com/a/13782922/3763139

 

Post niżej jest wytłumaczone dlaczego to nie ma sensu i i tak może nie dać dobrych wyników.

Opublikowano

Tak dla testów:

inline void Test(int a, int 
{
	a += time(0);
	printf("a + time(0) + b = %d\n", a + ;
}

Test(10, 20);
GetFunctionLength(Test); //= 0x0060 i sie zgadza

Po kompilacji Test =

699011404943485961817.jpg

Pod jumpem:

948901404943486961817.jpg

 

Co do

 

Napisz po co ci to w ogóle? Nie widzę potrzeby wiedzenia tego.

Hmmmm... sam nie wiem, zacząłem o tym czytać, wszędzie pisali że się "nie da" i... powstała funkcja.

 

 

@edit, analizując funkcję Test znalazłem dziwne zachowanie kompilatora(Visual Studio 2010):
mov [ebp+08] eax
mov eax, [ebp+08]

Nie pomagam na PW, od tego macie forum!!!

 

#PHP-things

 

 

08FMpDu.png

 

Opublikowano

Mając punkt wejścia analizujesz instrukcje po kolei i szukasz wszystkich możliwych punktów wyjścia (zawsze może być więcej niż jeden retn w funkcji). Jak to osiągnąć? Nie jest to specjalnie trudne. Każdy j* może skoczyć do etykiety z możliwym kolejnym końcem. Zapisujesz sobie te etykiety w jakiś sposób i jak już wszystkie drogi przejdziesz sprawdzasz, który retn jest najdalej. By to zrobić poprawnie potrzebujesz disasm z pełną listą instrukcji, by ich długości się zgadzały. Szukanie konkretnych bajtów będzie zawodne, gdyż zawsze może trafić się np. wartość, która będzie zawierać dokładnie szukane bajty, co w konsekwencji da niepoprawny wynik. Poza tym, jak Sopelek wyżej wspomniał, masz różne scenariusze w kodzie wynikowym więc nie zawsze istnieje możliwość dokładnego podania długości funkcji. Szczególnie te pisane "ręcznie" w asm, gdzie jedynym ograniczeniem jest wyobraźnia. Zdarzają się też funkcje zaciemniane, np. zastępowanie jednej instrukcji kilkoma innymi, które w efekcie działają tak samo. Bez odpowiedniej analizy takiego kodu algorytm po prostu wysiądzie. Co do samego "nie da się" to jest w życiu bzdura totalna. Wszystko się da aczkolwiek jesteśmy ograniczeni do możliwości technologii, którą sami jesteśmy w stanie na chwilę obecną stworzyć.
No to może jakieś podsumowanie, bo się bałagan zrobił:
Analiza rozmiaru funkcji kodu wynikowego funkcji z języka HLL o określonych wzorcach i standardach kompilacji - jak najbardziej możliwa z kilkoma wyjątkami, np. funkcje inline, które trzeba sobie ręczne wyłuskać.
Analiza rozmiaru kodu funkcji pisanego "ręcznie" (assemblery wszelkiego rodzaju) - jest możliwa ale do pewnego stopnia, czyli gdy nie odbiega od wzorca kodu wynikowego funkcji kompilowanej z HLL.

YOU MUST DIE

- Ganon, Koridai

Opublikowano

Tak dla testów:

inline void Test(int a, int 
{
	a += time(0);
	printf("a + time(0) + b = %d\n", a + ;
}

Test(10, 20);
GetFunctionLength(Test); //= 0x0060 i sie zgadza

Po kompilacji Test =

699011404943485961817.jpg

Pod jumpem:

948901404943486961817.jpg

 

Co do

Hmmmm... sam nie wiem, zacząłem o tym czytać, wszędzie pisali że się "nie da" i... powstała funkcja.

 

 

@edit, analizując funkcję Test znalazłem dziwne zachowanie kompilatora(Visual Studio 2010):

mov [ebp+08] eax

mov eax, [ebp+08]

visual robi takie rzeczy jak kompilujesz w debug, przynajmniej taka jest moja teoria, gdy ogladalem kod asm aplikacji skompilowanych w trybie debug i release

Zarchiwizowany

Ten temat przebywa obecnie w archiwum. Dodawanie nowych odpowiedzi zostało zablokowane.

×
×
  • Dodaj nową pozycję...