diff options
| author | Rusty Wagner <rusty@vector35.com> | 2016-10-10 21:28:16 -0400 |
|---|---|---|
| committer | Rusty Wagner <rusty@vector35.com> | 2016-10-10 21:28:16 -0400 |
| commit | 7e4cbbbf09e8dcda20f552a937b458aa09c28cf9 (patch) | |
| tree | 95e0ef73cddbf83936d772a3f0bec64ce6d8c8a3 /python/examples | |
| parent | 70dd487931d7bcd75e10753a741fba3299488327 (diff) | |
| parent | cf7832b8025c9acee11304bec0540f8896d56299 (diff) | |
Merge branch 'segments' into dev
Diffstat (limited to 'python/examples')
| -rw-r--r-- | python/examples/nds.py | 88 | ||||
| -rw-r--r-- | python/examples/nes.py | 114 |
2 files changed, 102 insertions, 100 deletions
diff --git a/python/examples/nds.py b/python/examples/nds.py new file mode 100644 index 00000000..5300018c --- /dev/null +++ b/python/examples/nds.py @@ -0,0 +1,88 @@ +from binaryninja import *
+import struct
+import traceback
+import os
+
+def crc16(data):
+ crc = 0xffff
+ for ch in data:
+ crc ^= ord(ch)
+ for bit in xrange(0, 8):
+ if (crc & 1) == 1:
+ crc = (crc >> 1) ^ 0xa001
+ else:
+ crc >>= 1
+ return crc
+
+class DSView(BinaryView):
+ def __init__(self, data):
+ BinaryView.__init__(self, file_metadata = data.file, parent_view = data)
+ self.raw = data
+
+ @classmethod
+ def is_valid_for_data(self, data):
+ hdr = data.read(0, 0x160)
+ if len(hdr) < 0x160:
+ return False
+ if struct.unpack("<H", hdr[0x15e:0x160])[0] != crc16(hdr[0:0x15e]):
+ return False
+ if struct.unpack("<H", hdr[0x15c:0x15e])[0] != crc16(hdr[0xc0:0x15c]):
+ return False
+ return True
+
+ def init_common(self):
+ self.platform = Architecture["armv7"].standalone_platform
+ self.hdr = self.raw.read(0, 0x160)
+
+ def init_arm9(self):
+ try:
+ self.init_common()
+ self.arm9_offset = struct.unpack("<L", self.hdr[0x20:0x24])[0]
+ self.arm_entry_addr = struct.unpack("<L", self.hdr[0x24:0x28])[0]
+ self.arm9_load_addr = struct.unpack("<L", self.hdr[0x28:0x2C])[0]
+ self.arm9_size = struct.unpack("<L", self.hdr[0x2C:0x30])[0]
+ self.add_auto_segment(self.arm9_load_addr, self.arm9_size, self.arm9_offset, self.arm9_size,
+ SegmentReadable | SegmentExecutable)
+ self.add_entry_point(Architecture['armv7'].standalone_platform, self.arm_entry_addr)
+ return True
+ except:
+ log_error(traceback.format_exc())
+ return False
+
+ def init_arm7(self):
+ try:
+ self.init_common()
+ self.arm7_offset = struct.unpack("<L", self.hdr[0x30:0x34])[0]
+ self.arm_entry_addr = struct.unpack("<L", self.hdr[0x34:0x38])[0]
+ self.arm7_load_addr = struct.unpack("<L", self.hdr[0x38:0x3C])[0]
+ self.arm7_size = struct.unpack("<L", self.hdr[0x3C:0x40])[0]
+ self.add_auto_segment(self.arm7_load_addr, self.arm7_size, self.arm7_offset, self.arm7_size,
+ SegmentReadable | SegmentExecutable)
+ self.add_entry_point(Architecture['armv7'].standalone_platform, self.arm_entry_addr)
+ return True
+ except:
+ log_error(traceback.format_exc())
+ return False
+
+ def perform_is_executable(self):
+ return True
+
+ def perform_get_entry_point(self):
+ return self.arm_entry_addr
+
+class DSARM9View(DSView):
+ name = "DSARM9"
+ long_name = "DS ARM9 ROM"
+
+ def init(self):
+ return self.init_arm9()
+
+class DSARM7View(DSView):
+ name = "DSARM7"
+ long_name = "DS ARM7 ROM"
+
+ def init(self):
+ return self.init_arm7()
+
+DSARM9View.register()
+DSARM7View.register()
diff --git a/python/examples/nes.py b/python/examples/nes.py index 00f9d8eb..23f5f3d8 100644 --- a/python/examples/nes.py +++ b/python/examples/nes.py @@ -488,42 +488,12 @@ class M6502(Architecture): return None return "\xa9" + chr(value & 0xff) + "\xea" -class NESViewUpdateNotification(BinaryDataNotification): - def __init__(self, view): - self.view = view - - def data_written(self, view, offset, length): - addr = offset - self.view.rom_offset - while length > 0: - bank_ofs = addr & 0x3fff - if (bank_ofs + length) > 0x4000: - to_read = 0x4000 - bank_ofs - else: - to_read = length - if length < to_read: - to_read = length - if (addr >= (bank_ofs + (self.view.__class__.bank * 0x4000))) and (addr < (bank_ofs + ((self.view.__class__.bank + 1) * 0x4000))): - self.view.notify_data_written(0x8000 + bank_ofs, to_read) - elif (addr >= (bank_ofs + (self.view.rom_length - 0x4000))) and (addr < (bank_ofs + self.view.rom_length)): - self.view.notify_data_written(0xc000 + bank_ofs, to_read) - length -= to_read - addr += to_read - - def data_inserted(self, view, offset, length): - self.view.notify_data_written(0x8000, 0x8000) - - def data_removed(self, view, offset, length): - self.view.notify_data_written(0x8000, 0x8000) - class NESView(BinaryView): name = "NES" long_name = "NES ROM" def __init__(self, data): - BinaryView.__init__(self, data.file) - self.raw = data - self.notification = NESViewUpdateNotification(self) - self.raw.register_notification(self.notification) + BinaryView.__init__(self, parent_view = data, file_metadata = data.file) @classmethod def is_valid_for_data(self, data): @@ -539,7 +509,7 @@ class NESView(BinaryView): def init(self): try: - hdr = self.raw.read(0, 16) + hdr = self.parent_view.read(0, 16) self.rom_banks = struct.unpack("B", hdr[4])[0] self.vrom_banks = struct.unpack("B", hdr[5])[0] self.rom_flags = struct.unpack("B", hdr[6])[0] @@ -550,6 +520,15 @@ class NESView(BinaryView): self.rom_offset += 512 self.rom_length = self.rom_banks * 0x4000 + # Add mapping for RAM and hardware registers, not backed by file contents + self.add_auto_segment(0, 0x8000, 0, 0, SegmentReadable | SegmentWritable | SegmentExecutable) + + # Add ROM mappings + self.add_auto_segment(0x8000, 0x4000, self.rom_offset + (self.__class__.bank * 0x4000), 0x4000, + SegmentReadable | SegmentExecutable) + self.add_auto_segment(0xc000, 0x4000, self.rom_offset + self.rom_length - 0x4000, 0x4000, + SegmentReadable | SegmentExecutable) + nmi = struct.unpack("<H", self.read(0xfffa, 2))[0] start = struct.unpack("<H", self.read(0xfffc, 2))[0] irq = struct.unpack("<H", self.read(0xfffe, 2))[0] @@ -592,9 +571,9 @@ class NESView(BinaryView): self.define_auto_symbol(Symbol(DataSymbol, 0x4016, "JOY1")) self.define_auto_symbol(Symbol(DataSymbol, 0x4017, "JOY2")) - sym_files = [self.raw.file.filename + ".%x.nl" % self.__class__.bank, - self.raw.file.filename + ".ram.nl", - self.raw.file.filename + ".%x.nl" % (self.rom_banks - 1)] + sym_files = [self.file.filename + ".%x.nl" % self.__class__.bank, + self.file.filename + ".ram.nl", + self.file.filename + ".%x.nl" % (self.rom_banks - 1)] for f in sym_files: if os.path.exists(f): sym_contents = open(f, "r").read() @@ -614,71 +593,6 @@ class NESView(BinaryView): log_error(traceback.format_exc()) return False - def perform_is_valid_offset(self, addr): - if (addr >= 0x8000) and (addr < 0x10000): - return True - return False - - def perform_read(self, addr, length): - if addr < 0x8000: - return None - if addr >= (0x8000 + self.rom_length): - return None - if (addr + length) > 0x10000: - length = 0x10000 - addr - result = "" - while length > 0: - bank_ofs = addr & 0x3fff - if (bank_ofs + length) > 0x4000: - to_read = 0x4000 - bank_ofs - else: - to_read = length - if addr < 0xc000: - data = self.raw.read(self.rom_offset + bank_ofs + (self.__class__.bank * 0x4000), to_read) - else: - data = self.raw.read(self.rom_offset + bank_ofs + self.rom_length - 0x4000, to_read) - result += data - if len(data) < to_read: - break - length -= to_read - addr += to_read - return result - - def perform_write(self, addr, value): - if addr < 0x8000: - return 0 - if addr >= (0x8000 + self.rom_length): - return 0 - if (addr + len(value)) > (0x8000 + self.rom_length): - length = (0x8000 + self.rom_length) - addr - else: - length = len(value) - if (addr + length) > 0x10000: - length = 0x10000 - addr - offset = 0 - while length > 0: - bank_ofs = addr & 0x3fff - if (bank_ofs + length) > 0x4000: - to_write = 0x4000 - bank_ofs - else: - to_write = length - if addr < 0xc000: - written = self.raw.write(self.rom_offset + bank_ofs + (self.__class__.bank * 0x4000), value[offset : offset + to_write]) - else: - written = self.raw.write(self.rom_offset + bank_ofs + self.rom_length - 0x4000, value[offset : offset + to_write]) - if written < to_write: - break - length -= to_write - addr += to_write - offset += to_write - return offset - - def perform_get_start(self): - return 0 - - def perform_get_length(self): - return 0x10000 - def perform_is_executable(self): return True |
