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

Ec9465c5a5f2ea26a80db56f9d2f99b0?s=128

Drumato

July 24, 2021
Tweet

Transcript

  1. eBPF disassemblerを作る Drumato

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

  3. 背景

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

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

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

  7. 書く

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

  9. あとは頑張って書く

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

  11. ELF Header

  12. eBPF object file#ELF Header

  13. eBPF object file#ELF Header

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

  15. Section Header Table

  16. eBPF object file#SHT

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

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

  19. eBPF object file#SHT eBPF mapsもsectionに Entry sizeは Programで決まっていて, Shdr.sh_entsizeを読んでも わからない

    Key + valueのどちらも可変なので entsizeは使えないか(linkとinfoは?)
  20. eBPF object file#SHT これは単に"GPL\0"という文字列が 入っているだけ

  21. Symbol table

  22. eBPF object file#symtab

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

  24. eBPF object file#summary • なんとなく以下を満たすsectionをdisasすれば良さそう ◦ Shdr.sh_type == SHT_PROGBITS ◦

    Shdr.sh_flags & (SHF_ALLOC | SHF_EXECINSTR) != 0 ◦ Shdr.sh_size > 0
  25. eBPF instruction architecture

  26. eBPF instruction architecture#overview

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

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

  29. eBPF instruction format ArithOrJump Memory

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

  31. eBPF instruction format ArithOrJump Memory Use src field as register

    If S bit is up
  32. eBPF instruction format ArithOrJump Memory ALU/ALU64/JMP/JMP64

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

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

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

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

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

  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に変換する感覚
  39. disasm#summary

  40. disasm#summary

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

  42. references • Linux Socket Filtering aka Berkeley Packet Filter (BPF)

    - www.kernel.org • Drumato/ebpf-disasm … 実装 ◦ 完全じゃないよ(Memory InstClassは適当)
  43. Thanks!