Skip to content

Instantly share code, notes, and snippets.

@justdionysus
Created January 28, 2017 01:15
Show Gist options
  • Save justdionysus/c8693981025287ea858d2ca5a93ec103 to your computer and use it in GitHub Desktop.
Save justdionysus/c8693981025287ea858d2ca5a93ec103 to your computer and use it in GitHub Desktop.
from binaryninja import BinaryView
from binaryninja import Architecture
from binaryninja import log_error, log_info
from binaryninja import Symbol, FunctionSymbol
from binaryninja import SegmentReadable, SegmentWritable, SegmentExecutable
import struct
import traceback
# Expects an uncompressed bFLT
#
# Via:
# - http://www.devttys0.com/2012/03/writing-a-bflt-loader-for-ida/
# - http://retired.beyondlogic.org/uClinux/bflt.htm
#
class BFLTView(BinaryView):
name = "bFLT"
long_name = "uCLinux bFLT Format"
def __init__(self, data):
BinaryView.__init__(self, parent_view=data, file_metadata=data.file)
self.platform = Architecture["armv7"].standalone_platform
@classmethod
def is_valid_for_data(self, data):
hdr = data.read(0, 4)
if len(hdr) < 4:
return False
if hdr != 'bFLT':
return False
return True
def init(self):
"""
struct bflt_header
{
uint8_t magic[4];
uint32_t version;
uint32_t entry;
uint32_t data_start;
uint32_t data_end;
uint32_t bss_end;
uint32_t stack_size;
uint32_t reloc_start;
uint32_t reloc_count;
uint32_t flags;
uint32_t build_date;
uint32_t filler[5];
};
"""
try:
hdr = self.parent_view.read(0, 64)
fields = struct.unpack('>IIIIIIIIIIIIIIII', hdr)
self.entry = fields[2]
self.data_start = fields[3]
self.data_end = fields[4]
self.bss_end = fields[5]
self.reloc_start = fields[7]
self.reloc_count = fields[8]
self.flags = fields[9]
self.add_auto_segment(self.entry, self.data_start - self.entry,
0x40, self.data_start - self.entry,
SegmentReadable | SegmentExecutable)
self.add_auto_segment(self.data_start,
self.data_end - self.data_start,
0x40 + self.data_start - self.entry,
self.data_end - self.data_start,
(SegmentReadable))
self.add_auto_segment(self.data_end,
self.bss_end - self.data_end,
0, 0,
(SegmentReadable | SegmentWritable))
self.define_auto_symbol(Symbol(FunctionSymbol, self.entry,
"_start"))
self.add_entry_point(Architecture['armv7'].standalone_platform,
self.entry)
for reloc_table_offset in range(self.reloc_count):
offset = self.reloc_start + 4 * reloc_table_offset
reloc_addr_data = self.parent_view.read(offset, 4)
reloc_addr = struct.unpack('>I', reloc_addr_data)[0] + 0x40
reloc_value_data = self.parent_view.read(reloc_addr, 4)
reloc_value = struct.unpack('>I', reloc_value_data)[0] + 0x40
self.parent_view.write(reloc_addr, struct.pack('<I', reloc_value))
return True
except:
log_error(traceback.format_exc())
return False
pass
def perform_is_executable(self):
return True
def perform_get_entry_point(self):
return self.entry
BFLTView.register()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment