web-dev-qa-db-ja.com

なぜstraceがシェルコードで行われたシステムコールを表示しないのですか?

シェルコーディングは初めてです。アセンブリコードを記述しました。

section .text
global _start

_start:
 jmp end

start:
  ;open file
  pop ebx ; get address of filename
  xor eax,eax
  mov [ebx+3], al
  mov al,5
  xor ecx,ecx
  mov edx,777
  int 80h
  ;exit

  xor eax,eax
  mov al,1
  mov ebx,1
  int 80h

end:
   call start
   db "AAAA"

ただし、「sys_open」システムコールが行われているか、「strace」ツールを使用していないかを確認すると、ファイルのオープンに関連するシステムコールが表示されません。

私のシェルコードの何が問題になっていますか?

「strace」出力:

rakesh@rakesh-VirtualBox:~/shellcode$ strace ./a.out 



execve("./a.out", ["./a.out"], [/* 21 vars */]) = 0
brk(0)                                  = 0x6cf000
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7c53efe000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=62357, ...}) = 0
mmap(NULL, 62357, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f7c53eee000
close(3)                                = 0
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\240\30\2\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=1815224, ...}) = 0
mmap(NULL, 3929304, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f7c5391e000
mprotect(0x7f7c53ad3000, 2097152, PROT_NONE) = 0
mmap(0x7f7c53cd3000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1b5000) = 0x7f7c53cd3000
mmap(0x7f7c53cd9000, 17624, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f7c53cd9000
close(3)                                = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7c53eed000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7c53eec000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7c53eeb000
Arch_prctl(Arch_SET_FS, 0x7f7c53eec700) = 0
mprotect(0x7f7c53cd3000, 16384, PROT_READ) = 0
mprotect(0x600000, 4096, PROT_READ)     = 0
mprotect(0x7f7c53f00000, 4096, PROT_READ) = 0
munmap(0x7f7c53eee000, 62357)           = 0
fstat(1, {st_mode=03260764276, st_size=140733642434881, ...}) = 3
write(1, "\242\350\303\32\377\177\0\0\0\0\0\0\0\0\0\0\252\350\303\32\377\177\0\0\276\350\303\32\377\177\0\0"..., 777 <unfinished ... exit status 1>
4
Rakesh Mane

私は解決策を得ました。実際、私は誤ってシェルコードテストプログラムを64ビット実行可能ファイルとしてコンパイルしました。そのため、シェルコードが64ビットモードで実行され、64ビットモードではsyscall no 5は「fstat」用であり、straceツールが表示していたものです。

3
Rakesh Mane

-e openに関する混乱を解消するために、この回答を編集しています。 -eはフィルタリングのみを行い、straceログに追加情報を追加しません。 straceがログを記録していない唯一のケースopen syscallsは、フォークされたサブプロセスがそれらを呼び出しており、-fパラメータが設定されていない場合です。

3
Rápli András

AMD64アーキテクチャでは、さらに新しいx86 CPUでも、システムコールはsysenterオペコードで発生し、int 80hでは発生しません。 strace出力は、x86命令と32ビットレジスタのみを使用したにもかかわらず、コードをAMD64にコンパイルしたことを明確に示しています(32ビット以上のポインターを使用していることがわかります)。

違いは、カーネルによってユーザースペース(libvdso)にマップされた単一ページの共有ライブラリで処理されます。アプリは、通常の関数と同じように、このlibvdsoのみを呼び出す必要があります。

最小限のCコードを静的にコンパイルして逆アセンブルする場合(glibcも使用したくない場合)は、その形式を見つける最も簡単な方法です。