Created
June 15, 2019 11:19
-
-
Save zznop/b14ceecda44c29a83dcaf15659e99107 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
# megadrive-loader.py | |
# zznop 2019 | |
# | |
# Load ROM as a flat binary, set processor to 68000, | |
# and run the script | |
import idc | |
import idautils | |
import ida_bytes | |
import ida_funcs | |
import ida_segment | |
import ida_name | |
def create_type_and_name(addr, name, _type): | |
'''Create a type and assign a name | |
''' | |
if _type == 'word': | |
idc.create_word(addr) | |
elif _type == 'dword': | |
idc.create_dword(addr) | |
elif _type == 'qword': | |
idc.create_qword(addr) | |
elif _type == 'byte': | |
idc.create_byte(addr) | |
else: | |
raise KeyError('unknown type: '.format(_type)) | |
ida_name.set_name(addr, name) | |
def create_string_and_name(addr, length, name): | |
'''Create a string literal of size 'length' and name it | |
''' | |
idc.create_strlit(addr, addr+length) | |
ida_name.set_name(addr, name) | |
def process_rom_vector_table(): | |
'''Annotate vector table and ROM header | |
''' | |
create_type_and_name(0, 'PtrInitialStack', 'dword') | |
create_type_and_name(4, 'PtrProgramStart', 'dword') | |
create_type_and_name(8, 'VectPtrBusError', 'dword') | |
create_type_and_name(12, 'VectPtrAddressError', 'dword') | |
create_type_and_name(16, 'VectPtrIllegalInstruction', 'dword') | |
create_type_and_name(20, 'VectPtrDivisionByZero', 'dword') | |
create_type_and_name(24, 'VectPtrChkException', 'dword') | |
create_type_and_name(28, 'VectPtrTrapVException', 'dword') | |
create_type_and_name(32, 'VectPtrPrivilegeViolation', 'dword') | |
create_type_and_name(36, 'VectPtrTraceException', 'dword') | |
create_type_and_name(40, 'VectPtrLineAEmulator', 'dword') | |
create_type_and_name(44, 'VectPtrLineFEmulator', 'dword') | |
create_type_and_name(48, 'VectUnused00', 'dword') | |
create_type_and_name(52, 'VectUnused01', 'dword') | |
create_type_and_name(56, 'VectUnused02', 'dword') | |
create_type_and_name(60, 'VectUnused03', 'dword') | |
create_type_and_name(64, 'VectUnused04', 'dword') | |
create_type_and_name(68, 'VectUnused05', 'dword') | |
create_type_and_name(72, 'VectUnused06', 'dword') | |
create_type_and_name(76, 'VectUnused07', 'dword') | |
create_type_and_name(80, 'VectUnused08', 'dword') | |
create_type_and_name(84, 'VectUnused09', 'dword') | |
create_type_and_name(88, 'VectUnused10', 'dword') | |
create_type_and_name(92, 'VectUnused11', 'dword') | |
create_type_and_name(96, 'VectPtrSpuriousException', 'dword') | |
create_type_and_name(100, 'VectPtrIrqL1', 'dword') | |
create_type_and_name(104, 'VectPtrIrqL2', 'dword') | |
create_type_and_name(108, 'VectPtrIrqL3', 'dword') | |
create_type_and_name(112, 'VectPtrIrqL4', 'dword') | |
create_type_and_name(116, 'VectPtrIrqL5', 'dword') | |
create_type_and_name(120, 'VectPtrIrqL6', 'dword') | |
create_type_and_name(124, 'VectPtrIrqL7', 'dword') | |
create_type_and_name(128, 'VectPtrTrap00', 'dword') | |
create_type_and_name(132, 'VectPtrTrap01', 'dword') | |
create_type_and_name(136, 'VectPtrTrap02', 'dword') | |
create_type_and_name(140, 'VectPtrTrap03', 'dword') | |
create_type_and_name(144, 'VectPtrTrap04', 'dword') | |
create_type_and_name(148, 'VectPtrTrap05', 'dword') | |
create_type_and_name(152, 'VectPtrTrap06', 'dword') | |
create_type_and_name(156, 'VectPtrTrap07', 'dword') | |
create_type_and_name(160, 'VectPtrTrap08', 'dword') | |
create_type_and_name(164, 'VectPtrTrap09', 'dword') | |
create_type_and_name(168, 'VectPtrTrap10', 'dword') | |
create_type_and_name(172, 'VectPtrTrap11', 'dword') | |
create_type_and_name(176, 'VectPtrTrap12', 'dword') | |
create_type_and_name(180, 'VectPtrTrap13', 'dword') | |
create_type_and_name(184, 'VectPtrTrap14', 'dword') | |
create_type_and_name(188, 'VectPtrTrap15', 'dword') | |
create_type_and_name(192, 'VectUnused12', 'dword') | |
create_type_and_name(196, 'VectUnused13', 'dword') | |
create_type_and_name(200, 'VectUnused14', 'dword') | |
create_type_and_name(204, 'VectUnused15', 'dword') | |
create_type_and_name(208, 'VectUnused16', 'dword') | |
create_type_and_name(212, 'VectUnused17', 'dword') | |
create_type_and_name(216, 'VectUnused18', 'dword') | |
create_type_and_name(220, 'VectUnused19', 'dword') | |
create_type_and_name(224, 'VectUnused20', 'dword') | |
create_type_and_name(228, 'VectUnused21', 'dword') | |
create_type_and_name(232, 'VectUnused22', 'dword') | |
create_type_and_name(236, 'VectUnused23', 'dword') | |
create_type_and_name(240, 'VectUnused24', 'dword') | |
create_type_and_name(244, 'VectUnused25', 'dword') | |
create_type_and_name(248, 'VectUnused26', 'dword') | |
create_type_and_name(252, 'VectUnused27', 'dword') | |
def process_rom_header(): | |
'''Annotate fields in the ROM header | |
''' | |
create_string_and_name(256, 16, 'ConsoleName') | |
create_string_and_name(272, 16, 'Copyright') | |
create_string_and_name(288, 48, 'DomesticName') | |
create_string_and_name(336, 48, 'InternationalName') | |
create_string_and_name(384, 14, 'SerialRevision') | |
create_type_and_name(398, 'Checksum', 'word') | |
create_string_and_name(400, 16, 'IoSupport') | |
create_type_and_name(416, 'RomStart', 'dword') | |
create_type_and_name(420, 'RomEnd', 'dword') | |
create_type_and_name(424, 'RamStart', 'dword') | |
create_type_and_name(428, 'RamEnd', 'dword') | |
create_string_and_name(432, 12, 'SramInfo') | |
create_string_and_name(444, 52, 'Notes') | |
create_string_and_name(496, 16, 'Region') | |
def create_functions(): | |
'''Disassemble at program start and exception handlers. And apply names | |
to functions we care about | |
''' | |
i = 4 | |
while i < 260: | |
addr = ida_bytes.get_32bit(i) | |
ida_funcs.add_func(addr) | |
if i == 4: | |
ida_name.set_name(addr, 'ProgramStart') | |
elif i == 112: | |
ida_name.set_name(addr, 'HBlank') | |
elif i == 120: | |
ida_name.set_name(addr, 'VBlank') | |
i += 4 | |
def create_segments(): | |
'''Create segments | |
''' | |
rom_start = ida_bytes.get_32bit(416) | |
rom_end = ida_bytes.get_32bit(420) | |
ram_start = ida_bytes.get_32bit(424) | |
ram_end = ida_bytes.get_32bit(428) | |
seg = ida_segment.getseg(rom_start) | |
if seg: | |
ida_segment.set_segm_name(seg, 'ROM') | |
else: | |
ida_segment.add_segm(0, rom_start, rom_end, 'ROM', 'CODE') | |
seg = ida_segment.getseg(ram_start) | |
if seg: | |
ida_segment.set_segm_name(seg, 'RAM') | |
else: | |
ida_segment.add_segm(0, ram_start, ram_end, 'RAM', 'DATA') | |
def main(): | |
create_segments() | |
process_rom_vector_table() | |
process_rom_header() | |
create_functions() | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment