2009年1月23日 星期五

在 Linux 下寫組語, 透過 int 0x80 使用 system call

使用環境:

  • Linux 2.6.24.1
  • yasm 0.7.1.2093
  • GNU ld 2.15.92.0.2 20040927

 

在 Linux 下,要使用 system call,可以透過 int 0x80 來完成。

首先,要先找出 system call 對應的號碼,後面會用到;號碼可以在 sys/syscall.h 中找到。如果看到 syscall.h 裡只有 include 其他 header file,請繼續追著這些 header file 往下找。例如,在我使用的機器上,sys/syscall.h include 了 asm/unistd.h,asm/unistd.h 又呼叫了 asm/unistd_32.h,最後在 asm/unistd_32.h 內找到了如下列的號碼

#define __NR_restart_syscall      0
#define __NR_exit                 1
#define __NR_fork                 2
#define __NR_read                 3
#define __NR_write                4
#define __NR_open                 5
#define __NR_close                6

..... (以下還有好多,省略)

如果你要使用 read() 的 system call,號碼就是 3 號,要用 open(),號碼就是 5 號,其他以此類推。

知道了號碼之後,正式進入如何透過 int 80 來使用 system call 的主題。

先來個 C 的簡單範例。

#include <unistd.h>

int main(int argc, char *argv[])
{
    char str[] = "Hello World!\n";

    write(1, str, sizeof(str));

    return 0;
}

上例中,我們使用了 write,將 str 字串寫到 standard output (就是 write() 的那個 1) ,也就是螢幕上。這個程式可以將字串內的內容顯示在螢幕上。

接著,一模一樣的事,我們使用 assembly code 來實現。

 

section .text
    global _start

_start:
        mov     edx,len ;message length
        mov     ecx,msg ;message to write
        mov     ebx,1   ;file descriptor (stdout)
        mov     eax,4   ;system call number (sys_write)
        int       0x80    ;call kernel

        mov     eax,1   ;system call number (sys_exit)
        int       0x80    ;call kernel

section .data

msg     db      'Hello, world!',0xa,0xd,0       ;our string
len       equ     $ - msg                 ;length of our dear string

 

在使用 int 0x80 之前,必須要將我們剛查出來的號碼填到 eax 內;填好後,只要一使用 int 0x80,相對應的 system call 就會被呼叫。

另外,system call 的參數要依序被放在 ebx, ecx, edx, esi, edi, ebp 等 register 內;以此例來說,一開始,我們使用 sys_write,查表得到號碼是 4 號,於是將此號碼填入 eax;接著,我們要將三個參數搬到對應的 register 內;參考 C 程式,write 有三個參數,分別是 1, string buffer 的位址,及 string buffer 的長度;這三個參數在呼叫 0x80 之後,也必須分別擺到 ebx, ecx, edx 內。全部擺好後,最後使用 int 0x80,噹啷~ Hello, World! 就顯示在螢幕上了。

最後,程式要離開,我們使用了 sys_exit,也就是 1 號的 system call,離開程式。

 

Reference: http://asm.sourceforge.net//intro/hello.html#AEN86