Go でデバッガを自作する

343 Views

September 26, 24

スライド概要

デバッガの仕組みや、Go でどのように実装するのかを簡単に説明します。

profile-image

HireRooは、エンジニア採用のコーディング試験サービスです。🦘エンジニアの技術力を多角的かつ定量的に評価することで、候補者と企業のミスマッチを防ぎます。

シェア

またはPlayer版

埋め込む »CMSなどでJSが使えない場合

関連スライド

各ページのテキスト
1.

Go でデバッガを自作する okarin 1

2.

Go でデバッガを自作する 自己紹介 okarin (Kyota Okabe) 所属 ● 株式会社ハイヤールー エンジニアリング領域 ● バックエンド ● 認証・認可 ● (少しだけ)機械学習 Activities ● community: Ehime.go ● X: @okarin_dev 好きなもの ● ブロッコリー ● ランニング 2

3.

Go でデバッガを自作する 今回話すこと ● プログラムを追跡可能にする仕組み ● ブレークポイントの仕組み ● Go で実装するには? 3

4.

Go でデバッガを自作する プログラムを追跡可能にする仕組み ptrace によって子プロセスを追跡できる (※ Linux の場合) 4

5.

Go でデバッガを自作する ブレークポイントの仕組み 命令の書き換え(※ x86-64 アーキテクチャの場合) 0x ** ** ** ** 0x ** ** ** ** 0x 48 83 ec 78 48 c7 44 24 0x cc 83 ec 78 48 c7 44 24 0x ** ** ** ** 0x ** ** ** ** 命令の先頭1バイトを 0xcc (INT3) に書き換えると、 その命令に達したタイミングで子プロセスは停止、それを親プロセスが検知できる ブレークポイント 5

6.

Go でデバッガを自作する Go で実装するには? 使いやすいパッケージが すでに用意されている! ● ● ● sys/unix debug/dwarf debug/elf 6

7.
[beta]
Go でデバッガを自作する

コードの一例
breakpoint を設定するコード

●

(準)標準パッケージのおかげで書きやすい!
func (bp *Breakpoint) Enable() error {
_, err := sys.PtracePeekData(bp.pid, bp.addr, bp.originalInstruction)
if err != nil {
return err
}
data := binary.LittleEndian.Uint64(bp.originalInstruction)
// data & ^0xff => data & 11111111 … 11111111 00000000
newData := (data & ^uint64(0xff)) | Int3Instruction
newInstruction := make([]byte, 8)
binary.LittleEndian.PutUint64(newInstruction, newData)
_, err = sys.PtracePokeData(bp.pid, bp.addr, newInstruction)
if err != nil {
return err
}

}

bp.isEnabled = true
return nil

7

8.

Go でデバッガを自作する まとめ ● ptrace でプログラムを追跡する ● ブレークポイントは 0xcc (INT3) で設定 ● Go は便利な(準)標準パッケージがあるのでデバッガを作りやすい 参考資料 ● ● Writing a Linux Debugger ptrace(2) - Linux manual page 8