Hi ;>
Problem brzmi nastepujaco: jak otrzymac liczbe parametrow podanych do funkcji przyjmujacej wiele parametrow? (platforma zgodna z Intel x386)
Chodzi mi ofc o funkcje typu:
int func( costam a, ... )
gdzie "costam", dowolny typ max 4 bajty, ktory w sumie bardziej ma sluzyc bezproblemowemu otrzymaniu adresu na pierwszy parametr funkcji niz czemu kolwiek innemu ;>...
warunki w sumie sa takie: nie moze byc w zaden sposob podana liczba parametrow ;> chodzi o to zeby funkcja jakims sposobem sama sprawdzila ile jest parametrow ;>
i powiedzmy zwrocila liczbe parametrow ;>
np
func( 12, 3, 5, 1, 2 );
powinna zwrocic 5 ;>
Jakies pomysly ?
aa.. prosil bym o nie pisanie postow typu "nie da sie" ;> nawet jesli sie nie da to takie rozwazania sa bardzo pouczajace ;>
ponizej przedstawie dwa swoje ;>
Zkompilowany kod wywolania funkcji wyglada zazwyczaj (gcc/vc++) nastepujaco (BEZ OPTYMALIZACJI!):
func( 1, 2, 3, 4 ); <=- to wywolywane:
</c`code>`
push 4 <=- wrzucenie ostatniego parametru na stos
push 3
push 2
push 1 <=- wrzucenie pierwszego parametru
call func <=- wywolanie funkcji
add esp, 0x10 <=- korekcja stack pointera
Adres powrotny uzyskac jest w miare latwo:
int func(int a, ... )
{
int *ret = &a - 1;
// lub int a, *b = &a + 2;
...
po powrocie kolejnym rozkazem jest add, a jego parametrem 4 * ilosc parametrow wrzucona na stos, wystarczy wiec w sumie pobrac parametr add, podzielic przez 4 i mamy liczbe parametrow...
jednak sprawa sie komplikuje w przypadku kompilacji z optymalizacja, jako ze korekcja stosu nie jest robiona po kazdym call, a co iles tam wywolan, co powoduje ze w sumie nie mamy dostepu do add esp, XXX...
drugim pomyslem natomiast jest policzenie pushy ktore sa przed call'em.. jednak ta metoda ma rowniez sporo wad
- nie wiadomo z ktorym opcodem pusha mamy do czynienia, jako ze push 1, push 12937714 i push eax maja troche rozne opcody, do tego nie wiemy jaka jest wielkosc opcodu, i mozliwe jest pomylenie push eax z parametrem dlugiego pusha np....
- zaczami program przeplata pushe jakimis lea ;> co jeszcze bardziej utrudnia sprawe
wiec ta metoda w sumie odpada ;>
czekam na propozycje ;>