GNU/Linux >> Belajar Linux >  >> Linux

Majelis yang dikompilasi dapat dieksekusi menggunakan INT 0x80 di Ubuntu pada Subsistem Windows untuk Linux tidak menghasilkan keluaran

Masalahnya adalah dengan Ubuntu untuk Windows (Subsistem Windows untuk Linux). Ini hanya mendukung syscall 64-bit antarmuka dan tidak x86 32-bit int 0x80 mekanisme panggilan sistem.

Selain tidak bisa menggunakan int 0x80 (kompatibilitas 32-bit) dalam binari 64-bit, Ubuntu di Windows (WSL) juga tidak mendukung menjalankan executable 32-bit.

Anda perlu mengonversi menggunakan int 0x80 ke syscall . Itu tidak sulit. Kumpulan register yang berbeda digunakan untuk syscall dan nomor panggilan sistem berbeda dari rekan 32-bit mereka. Blog Ryan Chapman memiliki informasi tentang syscall antarmuka, panggilan sistem, dan parameternya. Sys_write dan Sys_exit didefinisikan dengan cara ini:

%rax  System call  %rdi               %rsi              %rdx          %r10 %r8 %r9
----------------------------------------------------------------------------------
0     sys_read     unsigned int fd    char *buf         size_t count          
1     sys_write    unsigned int fd    const char *buf   size_t count
60    sys_exit     int error_code     

Menggunakan syscall juga mengalahkan RCX dan R11 register. Mereka dianggap fluktuatif. Jangan mengandalkan nilai yang sama setelah syscall .

Kode Anda dapat dimodifikasi menjadi:

section .text
    global _start     ;must be declared for linker (ld)

_start:             ;tells linker entry point
    mov edx,len     ;message length
    mov rsi,msg     ;message to write
    mov edi,1       ;file descriptor (stdout)
    mov eax,edi     ;system call number (sys_write)
    syscall         ;call kernel

    xor edi, edi    ;Return value = 0
    mov eax,60      ;system call number (sys_exit)
    syscall         ;call kernel

section .data
    msg db 'Hello, world!', 0xa  ;string to be printed
    len equ $ - msg     ;length of the string

Catatan:dalam kode 64-bit jika tujuan daftar instruksi adalah 32-bit (seperti EAX , EBX , EDI , ESI dll) nol prosesor memperluas hasilnya ke 32-bit atas dari register 64-bit. mov edi,1 memiliki efek yang sama dengan mov rdi,1 .

Jawaban ini bukan dasar untuk menulis kode 64-bit, hanya tentang penggunaan syscall antarmuka. Jika Anda tertarik dengan nuansa penulisan kode yang memanggil C perpustakaan, dan sesuai dengan 64-bit System V ABI ada tutorial yang masuk akal untuk Anda mulai seperti tutorial NASM Ray Toal. Dia membahas penyelarasan tumpukan, zona merah, penggunaan register, dan ikhtisar dasar konvensi pemanggilan Sistem V 64-bit.


Seperti yang telah ditunjukkan dalam komentar oleh Ross Ridge, jangan gunakan pemanggilan fungsi kernel 32-bit saat Anda mengompilasi 64bit.

Kompilasi untuk 32bit atau "terjemahkan" kode ke syscalls 64 bit. Berikut tampilannya:

section .text
    global _start     ;must be declared for linker (ld)

_start:             ;tells linker entry point
    mov rdx,len     ;message length
    mov rsi,msg     ;message to write
    mov rdi,1       ;file descriptor (stdout)
    mov rax,1       ;system call number (sys_write)
    syscall         ;call kernel

    mov rax,60      ;system call number (sys_exit)
    mov rdi,0       ;add this to output error code 0(to indicate program terminated without errors)
    syscall         ;call kernel

section .data
    msg db 'Hello, world!', 0xa  ;string to be printed
    len equ $ - msg     ;length of the string

Linux
  1. Membatasi akses syscall untuk aplikasi Linux

  2. Menginstal Oracle JDK pada subsistem Windows untuk Linux

  3. Masalah pengaturan $PATH di Bash di Ubuntu di Windows (Linux Subsystem)

  1. Subsistem Windows untuk Linux Dijelaskan, WSL &WSL2

  2. Kali di Subsistem Windows untuk Linux

  3. Wget error bash Subsistem Windows untuk Linux

  1. Apa yang lebih baik int 0x80 atau syscall dalam kode 32-bit di Linux?

  2. Menggunakan Windows Subsystem for Linux (WSL) dari Sublime Text

  3. Memasang share windows di Subsistem Windows untuk Linux