Author Topic: Linux programming  (Read 20614 times)

Offline dbfn

  • Jr. Member
  • *
  • Posts: 17
Linux programming
« on: April 16, 2010, 01:30:06 AM »
I'd like to know some libs that would help me developing for Linux.
Like,some lib or file with the networking/X11 functions necessary structs (like socketcall connect).
I'll begin improving my Linux nasm assembly skills for now on... D:

Offline QUASAR

  • Jr. Member
  • *
  • Posts: 4
Re: Linux programming
« Reply #1 on: April 16, 2010, 07:54:56 PM »
Try:
- Assembly Programmin Journal
- linuxassembly.net
- nasmx
- http://linuxasmtools.net/download.html

Offline lukus001

  • Jr. Member
  • *
  • Posts: 16
Re: Linux programming
« Reply #2 on: April 17, 2010, 12:49:09 AM »
Hi dbfn,

As per Socket programming in linux, there doesn't seem to be many resources or examples for assembly based methods that are easily found because this is exactly what I'm doing at the moment.  There must be some libraries floating about, although I havn't really found any but have not really attempted to look either.

Sys_socket is:

mov      eax, 102 ; <-- Sys socket
mov      ebx, #    ; <-- Sub call "socket" (create) or bind / listen / connect / accept.
mov      ecx, ??? ; <-- Pointer to values

int      0x80 ; kernel interrupt

Socket is: ebx, 1 (create)
Bind is:     ebx, 2
Listen is:   ebx, 4
Accept is: ebx, 5

Linux's "man" pages on sockets(2) will give the basic structure for the call, but it's c++ orientated. To make things more complicated, the source code (in C++) is horribly undocumented; for bind "sockaddr" is simply an empty shell, and there are no direct references to the actual structures that you want to use so it's a bit of a needle in a haystack affair...

Socket: http://linuxmanpages.com/man2/socket.2.php
Bind: http://linuxmanpages.com/man2/bind.2.php
Listen: http://linuxmanpages.com/man2/listen.2.php
Accept: http://linuxmanpages.com/man2/accept.2.php

I could post you my source and add some note explaining it but I know for a fact my Bind is wrong (although the rest is correct, as per TCP/IPv4 though I should just change it to Ipv6.

It seems linux has mutilated the sockets though :(.

Offline Keith Kanios

  • Full Member
  • **
  • Posts: 383
  • Country: us
    • Personal Homepage
Re: Linux programming
« Reply #3 on: April 17, 2010, 02:04:50 AM »
Perhaps another piece to the puzzle may help: ASM (GAS) Socket Example @ asm.sourceforge.net

Offline lukus001

  • Jr. Member
  • *
  • Posts: 16
Re: Linux programming
« Reply #4 on: April 18, 2010, 04:03:43 PM »
Well I finally managed to get my "bind" working (a simple case of forgetting to put [ ] around my label :3) so maybe the following code will be of use to you:

This is not X11 system /related as far as im aware

Using the normal int 0x80 linux interrupt:
  • eax has the value 102 (for sys_socket)
  • ebx contains a socket sub-call (socket, bind, listen, connect, accept and a couple of others)
  • ecx is a pointer to values.

The first sub-call (ebx, 1) is socket(), which provides us with a socket-based file descriptor. Socket() is listed as:
  • int socket(int domain, int type, int protocol)

For a IPv4 socket run as TCP then Socket() is:
  • Socket (AF_INET, SOCK_STREAM, TCP)
  • Socket (2, 1, 6)

Socket() returns a 32bit (dword) file descriptor (sockfd) in eax

Our second sub-call ebx, 2 is bind(), which associates our socket (sockfd) with a local address (IP:port basically for IPv4).  Bind() is listed as:
  • int bind(int sockfd, struct sockaddr *my_addr, socklen_t addrlen)
i.e.
  • int bind(sockfd, pointer to sockaddr, length of sockaddr)

  • sockfd is the file descriptor passed into eax from the linux kernel after socket().
  • 'pointer' is a 32bit pointer to the sockaddr structure
  • 'length' is 32bit value representing the number of bytes the sockaddr structure is made of (which should be 16 for IPv4)

sockaddr for IPv4 (sockaddr_in) is:
  • sin_family
  • sin_port
  • sin_addr
  • padding
i.e.:
  • (16bit) AF_INET
  • 16bit port number, network byte order
  • 32bit IP address, network byte order
  • 64bit of 0's for padding
implimented for me as:
  • 2
  • 0x5000
  • 0x2717155E
  • 0x0000000000000000
translated:
  • AF_INET address family (IPv4)
  • Port 80 (HTTP)
  • 94.23.21.39 (my server's IP)
  • 00000000 padding for future proofing

So the above which is implimented in the source (in bold) would set sockaddr for the IP:port pair 94.23.21.39:80 under AF_INET (IPv4) with padding (which is mostly unnecessary /not implimented)

We push sockaddr to the stack first, save the current location of esp since this is our pointer in bind():
as per my source bind() is:
  • socket
  • [socket_address]
  • 16

^ Names are labels since i stored them into memory.  "socket" is therefore where i stored sockfd and sock_address is where i stored the stack pointer (esp) after pushing the sockaddr structure onto the stack.

Listen() and accept() should be easy enough to understand if you read the manual pages i linked to before (if not, just ask! ;))  You do not use listen on the client side (use connect() for that).   You then just read/write to the sockfd as you would do normally.  You get a new sockfd from accept (since listen()/accep() is server orientated and there are multiple clients connecting to one server so there needs to be some form of isolating each one)

Network byte order (big endian) is important and worth a read, the IP and port needs to be in network byte order and is generally best done with hex values :)

Pushing to the stack is done "backwards" because it will be read in the opposit direction (last in, first out) and will therefore be read in the 'correct' direction by th linux kernel. So where socket() is : AF_INET, SOCK_STREAM, TCP you push it on the stack in this order: TCP, SOCK_STREAM, AF_INET.

note that none of this has error checking ! port 80 is restricted to root user (effective user ID 0) so it will complain if you try running the source on a normal user.





Code: [Select]
global _start

section .text

_start:

;------------------------------------------
;socket()

push dword        6
push dword 1
push dword 2

;system call socket

mov eax, 102
mov ebx, 1
mov ecx, esp

int 0x80

;------------------------------------------

section .bss

socket: resd 1
connection: resd 1
socket_address: resd 2

;------------------------------------------

section .text

mov Dword [socket],eax

;------------------------------------------
;sockaddr

push qword 0
push dword 0x2717155E ; network byte order
push word 0x5000 ;network byte order
push word 2

;pointer to sockaddr

mov [socket_address],esp

;bind()

push dword 16
push dword [socket_address]
push dword [socket]

;systemcall bind()

mov eax, 102
mov ebx, 2
mov ecx, esp

int 0x80

;------------------------------------------
;listen()

push byte 20
push dword [socket]

;systemcall listen()

mov eax, 102
mov ebx, 4
mov ecx, esp

int 0x80
;------------------------------------------
;accept()

push 0
push 0
push dword [socket]

;systemcall accept()

mov eax, 102
mov ebx, 5
mov ecx, esp

int 0x80


« Last Edit: April 18, 2010, 04:18:52 PM by lukus001 »