RustのライブラリであるGoblinを使って、バイナリファイルを解析のプログラムを作成している。Rustの構造はなかなか慣れないので、進めるのが大変だ。
Goblinを使った場合、Sectionを一つずつ解析して、バイナリの入っている部分を取り出していく必要がある。
github.com
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