#assembly #containers #64-bit #intel
#сборка #контейнеры #64-разрядный #intel
Вопрос:
Я не был уверен, будет ли это лучше при переполнении стека безопасности, но поскольку это связано с кодом, и я потенциально ожидаю кодового ответа, я напишу здесь.
Я написал некоторую сборку для Linux , которая отправит DNS — запрос и получит ответ . Версия x86 работает везде, но когда я сделал версию x64 для этого, и она работает везде, кроме как в контейнерах.
Я решил углубиться в подробности и заметил, что если я изменю тип запроса на TCP, он также будет делать то, что мне нужно, просто отлично.
Я отладил и вижу, что все настроено в стеке правильно, но ни один запрос на самом деле никогда не отправляется. Должен ли код быть написан по-другому, несмотря на то, что он работает на машинах baremetal? Или существует ли ограничение, которое обычно применяется для предотвращения отправки вызовов UDP.
Редактировать: я работаю над Linux x64 ubuntu. Я могу показать дамп TCP, когда он работает, но проблема в том, что когда он не работает, трафик вообще отсутствует; Пакеты не отправляются.
Редактирование 2:
Вот регистры в контейнере, которые содержат возврат после отправки .
rax 0xffffffffffffffa1 -95
rbx 0x0 0
rcx 0xffffffffffffffff -1
rdx 0x20 32
rsi 0x7fffffffe2b8 140737488347832
rdi 0x7 7
rbp 0x0 0x0
rsp 0x7fffffffe2b0 0x7fffffffe2b0
r8 0x7fffffffe2b0 140737488347824
r9 0x10 16
r10 0xd 13
r11 0x346 838
r12 0x5555555544f0 93824992232688
r13 0x7fffffffe3b0 140737488348080
r14 0x0 0
r15 0x0 0
rip 0x555555554668 0x555555554668 <main 104>
eflags 0x246 [ PF ZF IF ]
cs 0x33 51
ss 0x2b 43
ds 0x0 0
es 0x0 0
fs 0x0 0
gs 0x0 0
На физической машине после отправки системного вызова.
(gdb) info registers
rax 0x20 32
rbx 0x0 0
rcx 0x555555554668 93824992233064
rdx 0x20 32
rsi 0x7fffffffdda8 140737488346536
rdi 0x3 3
rbp 0x5555555546e0 0x5555555546e0 <__libc_csu_init>
rsp 0x7fffffffdda0 0x7fffffffdda0
r8 0x7fffffffdda0 140737488346528
r9 0x10 16
r10 0x2 2
r11 0x246 582
r12 0x5555555544f0 93824992232688
r13 0x7fffffffdea0 140737488346784
r14 0x0 0
r15 0x0 0
rip 0x555555554668 0x555555554668 <main 104>
eflags 0x246 [ PF ZF IF ]
cs 0x33 51
ss 0x2b 43
ds 0x0 0
es 0x0 0
fs 0x0 0
gs 0x0 0
>
section .text
global main ;must be declared for linker (ld)
;The Message We want to send.
;AA AA 01 00 00 01 00 00 00 00 00 00 0A 72 6f 6f 74 6b 69 74 64 65 76 03 63 6f 6d 00 00 01 00 01
;DNS HEADER;
; AA AA - ID
; 01 00 - Query parameters
; 00 01 - Number of questions
; 00 00 - Number of answers
; 00 00 - Number of authority records
; 00 00 - Number of additional records
; DNS QUESTION --
; 07 - 'example' has length 7, ;so change this to be the length of domain ; keep in mind there are not '.' in the question.
; 65 - e
; 78 - x
; 61 - a
; 6D - m
; 70 - p
; 6C - l
; 65 - e
; 03 - subdomain '.com' length 03 ; change this to be the length of type.
; 63 - c
; 6F - o
; 6D - m
; 00 - zero byte to end the QNAME
; 00 01 - QTYPE
; 00 01 - QCLASS
; DNS ANSWER!
; aa aa
; 81 80
; 00 01
; 00 01
; 00 00
; 00 00
; 07 65
; 78 61
; 6d 70
; 6c 65
; 03 63
; 6f 6d
; 00 00
; 01 00
; 01 c0
; 0c 00
; 01 00
; 01 00
; 00 12
; 8d 00
; 04
; IP ADDRESS IN HEX -- 93.184.216.34
; 5d
; b8
; d8
; 22
main:
mov rax, 41 ;Create Socket
mov rdi, 2 ;AF_INET
mov rsi, 2 ;Sock_DGRAM
mov rdx, 0 ;flags
syscall ;CALL SYSCALL CREATE SOCKET ; Looks good!
mov rdi, rax ; sockfd
; ####################### DNS REQUEST
mov rax, 0x0000000100010000
push rax
mov rax, 0x6d6f6303656c706d
push rax
mov rax, 0x6178650700000000
push rax
mov rax, 0x000001000001AAAA
push rax
; ###############################
mov rsi ,rsp
mov rdx, 32 ; len of bytes ; Google IP port 53 INET Family
mov rax, 0x0101010135000002 ; 8.8.8.8.8 - 0x35 - 00 00 02
push rax
mov rax, 44 ; Send Syscall
mov r8, rsp
mov r9, 16
syscall ; This never Actually sends in containers for some reason.
; Now need to read the response!
xor rax, rax ; read syscall == 0x00
push 100 ; Set out bytes to response to be higher!
pop rdx ; rdx = input size
sub rsp, rdx
mov rsi, rsp ; rsi => buffer
syscall
add rsp, rax ; This will give us the top of the stack where the answer is stored.
sub rsp, 0x4 ;
mov rax, [rsp]
mov ebx, eax
mov rax, rbx
Комментарии:
1. Вы забыли упомянуть, какой контейнер и какая операционная система. Также предоставьте strace и журнал wireshark.
2. Я могу получить некоторую трассировку дампа gdb, если это поможет.
3. @Jester возможно, это мне очень помогло бы. Вы знаете, что такое код ошибки -95? Я смотрю на коды ошибок, но численно указаны только -1 и -2. Другие указаны по имени.
4. Системные вызовы Linux возвращают errno как отрицательное число при ошибках. Итак, это «Операция EOPNOTSUPP 95 / * не поддерживается на конечной точке транспорта */».
5. Кроме того, если вы использовали
strace
в своей программе, как сказал Jester, вам будет показан код ошибки по имени. И что используемый вами IP-адрес 1.1.1.1, а не 8.8.8.8.