Created
January 28, 2017 01:15
-
-
Save justdionysus/c8693981025287ea858d2ca5a93ec103 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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