RustのライブラリであるGoblinを使って、バイナリファイルを解析のプログラムを作成している。Rustの構造はなかなか慣れないので、進めるのが大変だ。
Goblinを使った場合、Sectionを一つずつ解析して、バイナリの入っている部分を取り出していく必要がある。
for section in &elf.section_headers { println!("elf.section_headers = {:#?}, file_offset = {:#x}, size = {:#x}", &shdr_strtab[section.sh_name], section.sh_offset, section.sh_size ); for idx in 0..section.sh_size { let mut offset = idx+section.sh_offset; print!("{:02x}", buffer[offset as usize]); if idx % 4 == 3 { print!("\n"); } } }
上記のようにして、elfのバッファ(そのままelfファイルをバイナリとして配列で格納したもの)があるので、各セクションのヘッダ部分をオフセットで計算する。それがsection.sh_offset
だ。
このような実装で、とりあえず各セクションからバイナリの情報を引き出すプログラムを構築した。
cargo run ~/work/rocket-chip-msyksphinz/riscv-tools/riscv-tests/benchmarks/qsort.riscv elf.section_headers = "", file_offset = 0x0, size = 0x0 elf.section_headers = ".text.init", file_offset = 0x1000, size = 0x1c5 81400141 81410142 81420143 81430144 81440145 81450146 ... 4e7fee7f 51617300 20300000 00elf.section_headers = ".tohost", file_offset = 0x2000, size = 0x48 00000000 00000000 00000000 ... 00000000 00000000 00000000 elf.section_headers = ".text", file_offset = 0x2048, size = 0x8c0 aa871737 00001307 e7ae0145 0c4303a8 ... elf.symbol = "" 0x80005b38 elf.symbol = "" 0x80005b80 elf.symbol = "" 0x0 elf.symbol = "/tmp/cc9WJ5Mg.o" 0x0 elf.symbol = "trap_entry" 0x80000120 elf.symbol = "qsort_main.c" 0x0 elf.symbol = "verify.constprop.1" 0x80001048 elf.symbol = "syscalls.c" 0x0 elf.symbol = "vprintfmt" 0x800011ba