4


3

Linux 64ビットのプロセスコマンドライン

Linux 64ビットアセンブリプログラムからプロセスコマンドラインへのアクセスに問題があります。 これを最小限のコードで再現するために、プログラム名の最初の5文字を​​出力するこの32ビットプログラムを作成しました。

.section .text

.globl _start
_start:
 movl  %esp, %ebp

 movl $4, %eax        # write
 movl $1, %ebx        # stdout
 movl 4(%ebp), %ecx   # program name address (argv[0])
 movl $5, %edx        # hard-coded length
 int  $0x80

 movl $1, %eax
 movl $0, %ebx
 int  $0x80

このプログラムは機能しています。 64ビットに変換してLinux 64で実行すると、何も出力されません。

.section .text

.globl _start
_start:
 movq  %rsp, %rbp

 movq $4, %rax
 movq $1, %rbx
 movq 8(%rbp), %rcx       # program name address ?
 movq $5, %rdx
 int  $0x80

 movq $1, %rax
 movq $0, %rbx
 int  $0x80

私の間違いはどこにありますか?

2 Answer


10


正しいアドレスを `%rcx`にロードしています。

次に、 int 0x80`は32ビットのsyscallインターフェイスを呼び出します。 これにより、アドレスが32ビットに切り捨てられ、誤ったアドレスになります。 (デバッガを使用し、最初の `int 0x80`の直後にブレークポイントを設定すると、 -eFAULT`である `%eax`に-14が返されることがわかります。)

2番目のsyscallである「exit」は正常に機能します。32ビットへの切り捨てはその場合に害を及ぼさないからです。

'' '' '

システムコールに64ビットアドレスを渡す場合は、64ビットsyscallインターフェイスを使用する必要があります。

コードの作業バージョンは次のとおりです。

.section .text

.globl _start
_start:
 movq  %rsp, %rbp

 movq $1, %rax
 movq $1, %rdi
 movq 8(%rbp), %rsi       # program name address ?
 movq $5, %rdx
 syscall

 movq $60, %rax
 movq $0, %rdi
 syscall


3


X86_64 ABIで述べられているように、「int $ 0x80」の代わりに「syscall」命令を使用します。 カーネルは、64ビットの異なるレジスタをsyscall引数として使用し、syscall関数に割り当てられた番号もi386とx86_64の間で異なります。

例-ドイツ語でごめんなさい-ここにあります:+ http://zygentoma.de/codez/linux_assembler.php