Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Writing an experimental eBPF disassembler

Writing an experimental eBPF disassembler

適当にLTネタになるかな,と思って作った話.
https://github.com/Drumato/ebpf-disasm

Drumato

July 24, 2021
Tweet

More Decks by Drumato

Other Decks in Programming

Transcript

  1. eBPF disassemblerを作る
    Drumato

    View Slide

  2. Attention!
    ● 完全準拠ではない
    ● torvalds/linux/samples/bpfのkernel side sourceがそれっぽくなればOKまで
    をやった

    View Slide

  3. 背景

    View Slide

  4. なんとなくeBPFについての記事を読んでた

    View Slide

  5. "基本的に命令長は64bit固定"
    という記述を見る

    View Slide

  6. 素敵!
    disasm書きたい!
    (x64を想いつつ)

    View Slide

  7. 書く

    View Slide

  8. 身につける必要があった知識
    ● Object file上でeBPF functionがどのように表現されているか
    ● Opcode encoding/immediateの形式を知る

    View Slide

  9. あとは頑張って書く

    View Slide

  10. これはassembler自作と大して変わらない

    View Slide

  11. ELF Header

    View Slide

  12. eBPF object file#ELF Header

    View Slide

  13. eBPF object file#ELF Header

    View Slide

  14. E_machine以外は普通のrelocに見える

    View Slide

  15. Section Header Table

    View Slide

  16. eBPF object file#SHT

    View Slide

  17. eBPF object file#SHT
    .textはあるけど
    中身は空

    View Slide

  18. eBPF object file#SHT
    SEC("socket1")のように
    書いたsymbolが
    sectionに

    View Slide

  19. eBPF object file#SHT
    eBPF mapsもsectionに
    Entry sizeは
    Programで決まっていて,
    Shdr.sh_entsizeを読んでも
    わからない
    Key + valueのどちらも可変なので
    entsizeは使えないか(linkとinfoは?)

    View Slide

  20. eBPF object file#SHT
    これは単に"GPL\0"という文字列が
    入っているだけ

    View Slide

  21. Symbol table

    View Slide

  22. eBPF object file#symtab

    View Slide

  23. ぱっと見特に気になる点はなし

    View Slide

  24. eBPF object file#summary
    ● なんとなく以下を満たすsectionをdisasすれば良さそう
    ○ Shdr.sh_type == SHT_PROGBITS
    ○ Shdr.sh_flags & (SHF_ALLOC | SHF_EXECINSTR) != 0
    ○ Shdr.sh_size > 0

    View Slide

  25. eBPF instruction architecture

    View Slide

  26. eBPF instruction architecture#overview

    View Slide

  27. eBPF instruction architecture#overview
    OpcodeEncoding
    head byteをどう解釈するか

    View Slide

  28. eBPF instruction architecture#overview
    InstructionClass
    Opcodeをどう解釈するか
    Ex1.
    ic=0x04ならopcode=0x00はAdd
    ic=0x05ならopcode=0x00はJA

    View Slide

  29. eBPF instruction format
    ArithOrJump
    Memory

    View Slide

  30. eBPF instruction format
    ArithOrJump
    Memory
    ADD/SUB/MUL/DIV/MOD/LSH etc..
    JA/JEQ/JGT/JSLT/ etc...

    View Slide

  31. eBPF instruction format
    ArithOrJump
    Memory
    Use src field as register
    If S bit is up

    View Slide

  32. eBPF instruction format
    ArithOrJump
    Memory
    ALU/ALU64/JMP/JMP64

    View Slide

  33. eBPF instruction format
    ArithOrJump
    Memory
    IMM/MEM/IND/ABS etc

    View Slide

  34. eBPF instruction format
    ArithOrJump
    Memory
    Byte/Half word/Word/Double Word

    View Slide

  35. eBPF instruction format
    ArithOrJump
    Memory
    LD/LDX/ST/STX

    View Slide

  36. わかったら書く!書く!

    View Slide

  37. 機械語programmingは手動かす!

    View Slide

  38. disasm#tips
    ● Building block的に作ると良い
    ○ Opcode type/InstClass typeを作ってEncoding typeを作る
    ■ それぞれのdecoderを書く
    ○ それら(とsrc/dst/offset/imm)をまとめてInstruction typeを作る
    ■ decoderを次々呼ぶだけ
    ● srcは ooooxxxx のようになっているけど,4bit rshすると使いやすい
    ○ Register numberに変換する感覚

    View Slide

  39. disasm#summary

    View Slide

  40. disasm#summary

    View Slide

  41. このくらいのしょぼ完成度なら
    サクッと数時間で作れる

    View Slide

  42. references
    ● Linux Socket Filtering aka Berkeley Packet Filter (BPF) - www.kernel.org
    ● Drumato/ebpf-disasm … 実装
    ○ 完全じゃないよ(Memory InstClassは適当)

    View Slide

  43. Thanks!

    View Slide