2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

システムコールを手書きするLinuxアセンブリ

Posted at

"ユーザー空間で見えているものは、すべて幻想である。現実は、割り込み命令とカーネルの向こうにある。"

現代のプログラミングでは、ファイル操作も画面出力も、すべて「ライブラリ」や「API」を通じて行われている。

しかし、その奥にある本質的な操作は、すべて
カーネルに対する「システムコール(System Call)」という儀式を経て実現されている。

この章では、アセンブリを用いて、
Linuxにおける「手書きシステムコール」実装の実例を通し、
人間とカーネルの最も根源的な接点を明らかにする。


システムコールとは何か?

ユーザー空間のプロセスは、
直接ハードウェアやリソースにアクセスすることはできない。

代わりに、OSカーネルに対して特権操作の“依頼”を行う
これが、**システムコール(syscall)**である。

例:

  • write(fd, buffer, size)
  • open(path, flags)
  • exit(status)

これらは、実際には以下のようなフローで処理される:

  1. ユーザー空間でレジスタに引数をセット
  2. 特定の割り込みや命令(int 0x80, syscall)を発行
  3. カーネル空間へ制御移譲
  4. カーネルが処理し、結果を返す

x86_64におけるシステムコール規約

Linuxの64bit環境では、syscall命令と特定レジスタへの引数配置が必要。

引数位置 使用レジスタ
syscall番号 rax
第1引数 rdi
第2引数 rsi
第3引数 rdx
第4引数 r10
第5引数 r8
第6引数 r9
戻り値 rax

このルールを知っていれば、ライブラリなしでも直接システムコールを発行できる。


例:write(1, message, 13) を手書きで行う

section .data
    msg db "Hello, syscalls", 0xA
    len equ $ - msg

section .text
    global _start

_start:
    mov rax, 1          ; syscall番号 1 = write
    mov rdi, 1          ; fd = stdout
    mov rsi, msg        ; バッファのアドレス
    mov rdx, len        ; バイト数
    syscall             ; カーネルに呼び出し

    ; exit(0)
    mov rax, 60         ; syscall番号 60 = exit
    xor rdi, rdi        ; exit code = 0
    syscall

ビルドと実行:

nasm -f elf64 syscall.asm -o syscall.o
ld syscall.o -o syscall_demo
./syscall_demo

このプログラムは、Cライブラリなしでwrite()を直叩きしている。
つまり、OSに最も近いレイヤーで「Hello, syscalls」と叫んでいる。


なぜ手書きするのか?

1. ランタイムの理解

普段呼んでいる関数が、
どのようにOSと対話しているかを正確に理解できる。

2. リンクレスなバイナリを作れる

libc不要の超小型プログラムが構築できる。
これは、静的解析・攻撃回避・OS自作などに有効

3. セキュリティ/逆アセンブル観点で必須の知識

マルウェア、シェルコード、ROPチェーンなどは、
この「手書きsyscall」で実装される。

つまり、最も純粋な形式の“設計”でもある。


他の代表的なシステムコール番号(x86_64)

機能 syscall番号
read 0
write 1
open 2
close 3
exit 60
getpid 39
execve 59

ソース:/usr/include/x86_64-linux-gnu/asm/unistd_64.h

これらの知識があると、
任意のプログラムをシステムレベルで「再構築」できる


syscall命令の裏側:なぜそれで「切り替わる」のか?

syscall命令は:

  • カーネルが用意した**MSR(Model-Specific Registers)**に従い
  • CPUリングレベル(ユーザー: Ring 3 → カーネル: Ring 0)を移行
  • CS, SS, RSP などが強制的に切り替わる

つまり、これは単なる関数呼び出しではなく、CPU特権の変更=世界の境界線なのだ。


結語:システムコールは設計者の祈りである

手書きのシステムコールは、
一見してプリミティブで、時代遅れに見えるかもしれない。

だがそこには:

  • 制御を委ねるという信頼
  • 知識で抽象を貫く力
  • 世界に“直接”語りかける設計者の声

が宿っている。

"高級言語は世界を隠すが、システムコールは世界の境界を指し示す。設計者が世界を知ろうとするなら、最初の一声は、このsyscallであるべきだ。"

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?