Когда я вызываю функцию, которая принимает аргументы, собственная функция очищает нажатые данные с помощью «add esp, n» и локальных переменных с POP, OK.Очистить локальные переменные
Когда я вызываю функцию, получающую указатели (адрес), или когда я вызываю syscall, который получает указатели ... Как эти функции/syscalls очищают параметры в стеке? Указанные данные могут быть в стеке или в куче. Например: например
push edx ; NULL ;
push 0x68732f6e ; "n/sh" ; "//bin/sh\0"
push 0x69622f2f ; "//bi" ;
mov ebx, esp ; ebx = &"//bin/sh\0"
push edx ; NULL
push ebx ; &"//bin/sh\0"
mov ecx, esp ; ecx = args[&"//bin/sh\0", NULL]
push edx ; NULL
mov edx, esp ; edx = envp[NULL]
int 0x80
Источник, который необходимо выполнить RET:
BITS 32
section .text
global _start
_start:
call Foo
; exit
mov ebx, 0
mov eax, 1
int 0x80
Foo:
push ebp
mov ebp, esp
; Create the socket file descriptor
; int socket(int domain, int type, int protocol)
mov al, 102 ; __NR_socketcall
mov bl, 1 ; __NR_socketcall type (socket)
; socket parameters
sub esp, 8 ; sin_zero
push 6 ; IPPROTO_TCP
push 1 ; SOCK_STREAM
push 2 ; AF_INET
mov ecx, esp ; &uargs
int 0x80 ; socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)
; add esp, 0
mov esp, ebp
pop ebp
ret
Я добавил источник в качестве примера. Стек не очищается. Эти данные трактуются как мусор и всегда находятся в стеке? Как ret знает, где прыгать? ret = jmp [ebp + 4]? – Rob
Только RET в этом примере вернется к инструкции ниже * вызвать Foo *. В действительности нет никакого волшебства стека. Каждый PUSH, сделанный ** внутри ** * Foo *, удаляется кодом epilog 'mov esp, ebp'. – Fifoernik
'ret 'в вашем коде получит адрес возврата из стека:' pop eip, [esp] 'и' add esp, 4'. В вашем коде этот [esp] будет адресом в команде «mov ebx, 0', который выполняется после вашего' вызова Foo'. Этот адрес был помещен в стек кодом операции 'cal' – Blechdose