неправильные данные в памяти
нашел ошибку в коде и очень странно что она есть. я указал на нее с помощью < --. дело в том, что я указал переменной sizeof_s 4 байта размер и число 16, что равно структуре sockaddr_in. но если в коде написать в той строке так mov edx, [sizeof_s] то запишется почему то перевернутый адрес порта, но почему? вот код.
;DEFAULT REL
global main
extern printf
extern inet_aton
extern perror
extern connect
section .text
shellcode:
mov rax, 59
mov rdi, [path]
mov rsi, 0
mov rdx, 0
syscall
exploit:
mov rax, 1
mov rdi, [sock]
lea rsi, [shellcode]
mov rdx, [size_of_shellcode]
syscall
ret
main:
;------ получаем сокет -------
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, 16 ; < ---------- вот здесь я присваивал [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, 1
call exploit
;---- выход из программы ----
exit:
mov rax, 60
syscall
ret
section .data
struc sockaddr_in
.family resw 1
.port resw 1
.s_addr resd 1
.data resb 8
endstruc
cant_socket db 'Не удалось получить сокет', 0xa, 0x0
cant_fill db 'Не удалось преобразовать ip', 0x0
cant_connect db 'Невозможно подключиться', 0x0
host db '127.0.0.1', 0x0
path dq '/bin/sh'
size dd $ - path
sock dd 0
s istruc sockaddr_in
sizeof_s dd 16
server_port dw 8020
PF_INET dw 2
SOCK_STREAM dw 1
size_of_shellcode dd exploit - shellcode
вот для компиляции.
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
Ответы (1 шт):
Скомпилировал код из вопроса и посмотрел под дизассемблером, оказалось, что метки s и sizeof_s совпадают в памяти. Нормально структура создается, если использовать такой код:
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
sizeof_s dd 16
Документация: ISTRUC, AT иIEND: Объявление экземпляров структур
Я предполагаю, что nasm считает, что все что идет ниже s istruc sockaddr_in - это часть этой структуры. Почему при этом не ругается на отсутствующий iend - не понятно. Но может так разработчиками задумано. Но в любом случае это объясняет, почему из sizeof_s читается порт - в первое поле структуры перед этим его и записали, а первое поле структуры у вас пересекается с s_size.