GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Assembly kompilierte ausführbare Datei mit INT 0x80 auf Ubuntu auf Windows-Subsystem für Linux erzeugt keine Ausgabe

Das Problem liegt bei Ubuntu für Windows (Windows-Subsystem für Linux). Es unterstützt nur die 64-Bit-Version von syscall Schnittstelle und nicht das 32-Bit x86 int 0x80 Systemaufrufmechanismus.

Abgesehen davon, dass int 0x80 nicht verwendet werden kann (32-Bit-Kompatibilität) in 64-Bit-Binärdateien unterstützt Ubuntu unter Windows (WSL) auch nicht die Ausführung von ausführbaren 32-Bit-Dateien.

Sie müssen von der Verwendung von int 0x80 konvertieren bis syscall . Es ist nicht schwer. Für syscall wird ein anderer Registersatz verwendet und die Systemrufnummern unterscheiden sich von ihren 32-Bit-Gegenstücken. Ryan Chapmans Blog enthält Informationen zu syscall Schnittstelle, die Systemaufrufe und ihre Parameter. Sys_write und Sys_exit sind folgendermaßen definiert:

%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     

Mit syscall verprügelt auch RCX und das R11 registriert. Sie gelten als volatil. Verlassen Sie sich nicht darauf, dass sie nach syscall denselben Wert haben .

Ihr Code könnte wie folgt geändert werden:

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

Hinweis:im 64-Bit-Code, wenn das Ziel Register einer Anweisung ist 32-Bit (wie EAX , EBX , EDI , ESI usw.) erweitert die Prozessor-Null das Ergebnis in die oberen 32 Bit des 64-Bit-Registers. mov edi,1 hat die gleiche Wirkung wie mov rdi,1 .

Diese Antwort ist keine Einführung in das Schreiben von 64-Bit-Code, sondern nur in die Verwendung von syscall Schnittstelle. Wenn Sie an den Nuancen des Schreibens von Code interessiert sind, der das C aufruft Bibliothek und entspricht dem 64-Bit-System V ABI gibt es vernünftige Tutorials, um Ihnen den Einstieg zu erleichtern, wie das NASM-Tutorial von Ray Toal. Er erläutert die Stack-Ausrichtung, die rote Zone, die Registernutzung und einen grundlegenden Überblick über die 64-Bit-System-V-Aufrufkonvention.


Wie bereits in Kommentaren von Ross Ridge erwähnt, verwenden Sie keine 32-Bit-Aufrufe von Kernel-Funktionen, wenn Sie 64-Bit kompilieren.

Kompilieren Sie entweder für 32-Bit oder "übersetzen" Sie den Code in 64-Bit-Systemaufrufe. So könnte das aussehen:

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. Was ist besser int 0x80 oder syscall in 32-Bit-Code unter Linux?

  2. Installieren von Oracle JDK auf einem Windows-Subsystem für Linux

  3. Verwendung des Windows-Subsystems für Linux (WSL) von Sublime Text

  4. Probleme beim Festlegen von $PATH auf Bash auf Ubuntu unter Windows (Linux-Subsystem)

  5. Wget error bash Windows-Subsystem für Linux

So installieren Sie das Windows-Subsystem für Linux

Der ultimative Leitfaden zum Windows-Subsystem für Linux (Windows WSL)

Verwenden von Ubuntu 18.04 im erweiterten Modus für Hyper-V unter Windows 10

Aufbau von 0verkill auf Windows 10 Subsystem für Linux – 2D-ASCII-Art-Deathmatch-Spiel

Schreiben und Debuggen von Linux-C++-Anwendungen aus Visual Studio mit dem Windows-Subsystem für Linux

So installieren und konfigurieren Sie das Windows-Subsystem für Linux