0

私は、文字を変更するなどの簡単なことを行って文字列を変更し、それを印刷できるようにするシェルコードの単純なチャンクを作成しようとしています。

_start:
        jmp short ender
starter:
        xor ecx, ecx            ;clear out registers
        xor eax, eax
        xor ebx, ebx
        xor edx, edx
        pop esi                 ;pop address of string into esi register

        mov byte [esi+1], 41    ;try and put an ASCII 'A' into the second letter of the string
                                ;at the address ESI+1

        mov ecx, esi            ;move our string into the ecx register for the write syscall
        mov al, 4               ;write syscall number
        mov bl, 1               ;write to STDOUT
        mov dl, 11              ;string length
        int 0x80                ;interrupt call
ender:
        call starter
        db 'hello world'

「ハローワールド」をプリントアウトすることになっています。movこのようなコマンドでメモリのバイトを変更しようとすると、問題が発生します(セグメンテーション違反) 。

mov byte [esi+1], 41

GDBでプログラムを実行しましたが、pop esiコマンドは正しく機能しesi、文字列のアドレスが読み込まれ、すべてが有効です。しかし、なぜ有効なアドレスのバイト値を変更できないのか理解できません。NASMとldによって生成された実行可能ファイルを実行するだけで、この「シェルコード」をテストしています。Cプログラムなどにはまだ入れていないため、アセンブリにバグが存在します。

追加情報

次のビルドコマンドでx64Linuxを使用しています。

nasm -f elf64 shellcode.asm -o shellcode.o
ld -o shellcode shellcode.o
./shellcode

ここに完全なコードを貼り付けました。

4

1 に答える 1

2

推測するに、dbhello world はデータではなくコードとしてコンパイルされているため、読み取りと実行のアクセス許可はありますが、書き込みのアクセス許可はありません。したがって、実際にはページ保護に違反しています。

これを変更するには、文字列をsection .dataセクションに配置し、nasm の変数構文を使用して検索する必要があります。データをそのまま変更するには、mprotect呼び出しを行ってページのアクセス許可を変更し、それらに書き込む必要があります。注: これらは実行可能ファイルに永続化されませmmap()MAP_PRIVATE

于 2012-11-04T20:34:01.200 に答える