Stamattina ho provato a mettere a punto al volo un piccolo client HTTP in Assembly su Linux usando le syscall...facendolo mi sono reso conto che sfruttare i socket in Assembly non è poi così complesso come sembra usando le syscall, se si hanno giàconoscenze di C. Per compilarlo:
Codice (semplicemente, come prova, crea una connessione con www.milw0rm.com e richiede l'home page per poi stamparla su stdout):
Codice:
gcc -o http http.s
Codice (semplicemente, come prova, crea una connessione con www.milw0rm.com e richiede l'home page per poi stamparla su stdout):
Codice:
.data
sock_ko_str: .string "Socket KO\n"
sock_ko_str_l = .-sock_ko_str
conn_ko_str: .string "Connect KO\n"
conn_ko_str_l = .-conn_ko_str
# struct sockaddr server
server: .space 128
sizeof_server = .-server
http_request: .string "GET /\r\nUser-Agent: BlackLight ASM HTTP Client\r\n\r\n"
http_request_l = .-http_request
sd: .long 0
resp: .byte 0
ret: .long 0
AF_INET = 0x2
SOCK_STREAM = 0x1
IPPROTO_TCP = 0x6
port = 80
host = 0x12094a4c # IP host in network byte order
# Macro per la stampa su stdout
.macro __write str,len
movl $4,%eax
movl $1,%ebx
movl \str,%ecx
movl \len,%edx
int $0x80
.endm
.text
.global main
main:
movl $0x66,%eax
movl $1,%ebx # socket()
pushl $IPPROTO_TCP # sd=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
pushl $SOCK_STREAM
pushl $AF_INET
movl %esp,%ecx
int $0x80
addl $0xc,%esp
movl %eax,sd
cmpl $-1,sd # if (sd!=-1) ok();
jne sock_ok
sock_ko:
__write $sock_ko_str,$sock_ko_str_l
jmp end
sock_ok:
movw $AF_INET,server # server->sin_family=AF_INET;
movw $((port & 0xff00) >> 8 | (port & 0xff) << 8),server+2
# server->sin_port = htons ((u_short) port);
movl $host,server+4 # server->sin_addr.s_addr=inet_addr(host);
movl $0x66,%eax # connect()
movl $3,%ebx
pushl $sizeof_server # connect (sd,&server,sizeof_server);
pushl $server
pushl sd
movl %esp,%ecx
int $0x80
addl $0x10,%esp
cmpl $-1,%eax
jne conn_ok
conn_ko:
__write $conn_ko_str,$conn_ko_str_l
jmp end
conn_ok:
movl $4,%eax # write (sd,http_request,sizeof(http_request));
movl sd,%ebx
movl $http_request,%ecx
movl $http_request_l,%edx
int $0x80
loop:
movl $3,%eax # ret=read(sd,resp,1);
movl sd,%ebx
movl $resp,%ecx
movl $1,%edx
int $0x80
movl %eax,ret
__write $resp,$1
movl ret,%eax # if (ret>0) goto loop;
cmpl $0,%eax
jg loop
movl $6,%eax # close(sd);
movl sd,%ebx
int $0x80
end:
movl $1,%eax # exit(0);
movl $0,%ebx
int $0x80
leave
ret