Bfdpie is a tiny wrapper library around binutils (more precisely, libbfd). The project draws code and concepts from pybfd.
Any setup that can successfully compile binutils as well as python modules should be able to install bfdpie. To install bfdpie, use
pip install bfdpieThe code was tested on Linux, OSX and Windows (cygwin). On Windows, the prerequisites in cygwin were make, zlib-devel, make, and difftools.
The libbfd is a complex beast, and bfdpie only exposes the binary loading and disassembling parts of it. The goal of this library is to provide a simple and clean means of loading and disassembling various binary formats, the likes of which are often encountered in CTF challanges. For example, we can print all the symbols of any binary file that libbfd supports by simply doing:
>>> from bfdpie import *
>>> b = Binary("/bin/ls")
>>> print b
Binary<'/bin/ls', 'mach', Arch<name:X86_64, bits:64, little_endian:1>>
>>> print b.symbols
{
'_strlen': Symbol<_strlen, 0x0>,
'__DATA.__got': Section<__DATA.__got, 0x5000>,
'__TEXT.__stub_helper': Section<__TEXT.__stub_helper, 0x45f8>,
...
}
>>> text_section = b.symbols[".text"]
>>> print text_section
Section<.text, 0xe94>
>>> print hex(text_section.vma)
0xe94
>>> print b.symbols["_strlen"]
Symbol<_strlen, 0x0>The b.symbols holds all the symbols the file has. If we need to know precisely where the symbols come from, we can access the different kinds through
b.static_symbols, b.dynamic_symbols, b.synthetic_symbols and b.relocs.
Using the disassembler is equally easy.
>>> b = Binary()
>>> dis = b.disassemble_simple(
... "\xba\x00\x04\x00\x00" +
... "\x48\x89\xc6" +
... "\xbf\x00\x00\x00\x00" +
... "\xb8\x00\x00\x00\x00",
... ARCH_X86_64
... )
mov edx,0x400
mov rsi,rax
mov edi,0x0
mov eax,0x0Adding new architectures is easy, as long as binutils supports them. Currently, the following architectures are supported
archs = [
ARCH_I686,
ARCH_X86_64,
ARCH_ARMEL,
ARCH_ARMEL_THUMB,
ARCH_ARMEB,
ARCH_ARMEB_THUMB,
ARCH_AARCH64,
ARCH_AARCH64_BE,
ARCH_MIPS,
ARCH_MIPSEL,
ARCH_MIPS64,
ARCH_MIPS64EL,
ARCH_PPC32,
ARCH_PPC64,
ARCH_SPARC,
ARCH_SPARC64,
ARCH_SH4,
ARCH_SH4EB,
ARCH_ALPHA,
ARCH_CRISV32,
ARCH_S390X,
ARCH_MICROBLAZE,
ARCH_MICROBLAZEEL,
]>>> b.disassemble_simple(
... "\xe3\x40\xf1\x10\x00\x04" +
... "\xeb\xcf\xf1\x00\x00\x04" +
... "\x07\xf4" +
... "\x07\x07",
... ARCH_S390X
... )
lg %r4,272(%r15)
lmg %r12,%r15,256(%r15)
br %r4
nopr %r7