2017-12-20 13 views
0

私はasmを初めて使い、/ bin/bashにsyscallを実行しようとしています。しかし、私は現在、次のような問題に遭遇しています:アセンブリexecve/bin/bash(x64)

私のコードは、その第一引数の長さが8バイト未満、すなわち「/ binに/ SH」または「/ binに/ LS」で任意のexecveの呼び出しのために働く:

.section .data 

    name: .string "/bin/sh" 

.section .text 

.globl _start 

_start: 
    #third argument of execve, set to NULL 
    xor %rdx, %rdx 

    #push nullbyte to the stack 
    pushq %rdx 

    #push /bin/sh to the stack 
    pushq name 

    #copy stack to rdi, 1st arg of execve 
    mov %rsp, %rdi 

    #copy 59 to rax, defining syscall number for execve 
    movq $59, %rax 

    #3rd arg of execve set to NULL 
    movq $0, %rsi 

    syscall 

何を私に困惑することは、私がスタックにし、「/ binに」「/ bashの」pushqし、部品に文字列を分割しようとした私はそれが

name: .string "/bin/bash" 

で動作するように得ることができないということです、何も私を可能にするようですそれを動作させるために、毎回「不正な命令」エラーが出ます。私は間違って何をしていますか?

ノンワーキングコード:

.section .data 

    name: .string "/bin/bash" 

.section .text 

.globl _start 

_start: 
    #third argument of execve, set to NULL 
    xor %rdx, %rdx 

    #push nullbyte to the stack 
    pushq %rdx 

    #push /bin/sh to the stack 
    pushq name 

    #copy stack to rdi, 1st arg of execve 
    mov %rsp, %rdi 

    #copy 59 to rax, defining syscall number for execve 
    movq $59, %rax 

    #3rd arg of execve set to NULL 
    movq $0, %rsi 

    syscall 

その他の非作業コード:

.section .data 

.section .text 

.globl _start 

_start: 
    #third argument of execve, set to NULL 
    xor %rdx, %rdx 

    #push nullbyte to the stack 
    pushq %rdx 

    #push /bin/bash to the stack 
    pushq $0x68 
    pushq $0x7361622f 
    pushq $0x6e69622f 

    #copy stack to rdi, 1st arg of execve 
    mov %rsp, %rdi 

    #copy 59 to rax, defining syscall number for execve 
    movq $59, %rax 

    #3rd arg of execve set to NULL 
    movq $0, %rsi 

    syscall 
+1

あなたは**非を表示するために忘れてしまいましたワーキング**コード。また、デバッガの使用を忘れてしまった。スタックが逆に動作することを忘れているかもしれません。そして、おそらく、 'push' **は常に8バイトを書き込むことを忘れていました。したがって、最後の部分(最初に押す部分)を除いて、文字列を8バイト部分に分割する必要があります。 – Jester

+0

明らかに '.data'に文字列がある場合、それをスタックにコピーする必要はありません。そのアドレスを直接使用して、それを使って完了することができます。 – Jester

+0

関数のX86_64 ABI呼び出し規約を見てきましたか?それは、物事が間違って起こっている場所を把握するのに役立ちます。 –

答えて

4

あなたはすべてのエラーのリストを表示するにはあまりにも多くの、完全に混乱しているようです。それにもかかわらず、ここでの不完全なリストは次のとおりです。

  1. あなたがゼロの意味にESI設定argvNULL
  2. push nullbyte to the stackが実際にargv配列を(それは文字列を終端しないゼロバイトです)終了させるためのNULLポインタです。
  3. ファイル名のアドレスをargv[0]とする必要があります。文字列をスタックにコピーする必要はありません。ここで

修正バージョンです:

.section .data 

    name: .string "/bin/bash" 

.section .text 

.globl _start 

_start: 
    # third argument of execve is envp, set to NULL 
    xor %rdx, %rdx 

    # push NULL to the stack, argv terminator 
    pushq %rdx 

    # first argument to execve is the file name 
    leaq name, %rdi 

    # also argv[0] 
    push %rdi 

    # second argument to execve is argv 
    mov %rsp, %rsi 

    #copy 59 to rax, defining syscall number for execve 
    movq $59, %rax 
    syscall 

そして、ゼロバイトせずに、コードからスタック上の文字列を作成したバージョン:

.section .text 

.globl _start 

_start: 
    # third argument of execve is envp, set to NULL 
    xor %rdx, %rdx 

    # zero terminator 
    push %rdx 

    # space for string 
    sub $16, %rsp 

    # end is aligned to the zero terminator 
    movb $0x2f, 7(%rsp)  #/
    movl $0x2f6e6962, 8(%rsp) # bin/ 
    movl $0x68736162, 12(%rsp) # bash 

    # first argument to execve is the file name 
    leaq 7(%rsp), %rdi 

    # push NULL to the stack, argv terminator 
    pushq %rdx 

    # also argv[0] 
    push %rdi 

    # second argument to execve is argv 
    mov %rsp, %rsi 

    # copy 59 to rax, defining syscall number for execve 
    # avoid zero byte 
    xor %eax, %eax 
    movb $59, %al 
    syscall 
+0

あなたは正しいです、私は混乱しています、私の質問に記載されているとおり、私はASMに全く新しいです:)。とにかく、あなたの助けと私の過ちを訂正してくれてありがとう、それは今働いています。もう1つの質問ですが、.dataセクションを避けたい場合、どうすればいいですか? – Goujon

+0

@Goujon:文字列をスタック –

+0

@Jesterにプッシュする必要があります。これはシェルコードを対象としているので、 'movq $ 59、%rax'に対しては0x00バイトを導入することをお勧めします。おそらく 'xor%eax、%eax'' mov $ 59、%al'が望ましいでしょうか? –

関連する問題