Ejemplo n.º 1
0
def make_head(ea):
  flags = idc.get_full_flags(ea)
  if not idc.is_head(flags):
    # idc.SetFlags(ea, flags | idc.FF_DATA)
    idc.create_data(ea, idc.FF_BYTE, 1, idc.BADADDR)
    idaapi.auto_wait()
    return is_head(ea)
  return True
Ejemplo n.º 2
0
def make_head(ea):
    flags = idc.get_full_flags(ea)
    if not idc.is_head(flags):
        # idc.SetFlags(ea, flags | idc.FF_DATA)
        idc.create_data(ea, idc.FF_BYTE, 1, idc.BADADDR)
        idaapi.auto_wait()
        return is_head(ea)
    return True
Ejemplo n.º 3
0
def make_xref(from_ea, to_ea, data_type, xref_size):
    """Force the data at `from_ea` to reference the data at `to_ea`."""
    if not idc.get_full_flags(to_ea) or is_invalid_ea(to_ea):
        DEBUG("  Not making reference (A) from {:x} to {:x}".format(
            from_ea, to_ea))
        return False

    make_head(from_ea)

    if is_code(from_ea):
        _CREFS_FROM[from_ea].add(to_ea)
        _CREFS_TO[to_ea].add(from_ea)
    else:
        _DREFS_FROM[from_ea].add(to_ea)
        _DREFS_TO[to_ea].add(from_ea)

    # If we can't make a head, then it probably means that we're at the
    # end of the binary, e.g. the last thing in the `.extern` segment.
    # or in the middle of structure. Return False in such case
    #
    # NOTE(artem): Commenting out since this breaks recovery of C++ applications
    # with IDA7. The failure occurs when processign references in .init_array
    # when the below code is enabled, those references are not treated as
    # references because make_head fails.
    #
    #if not make_head(from_ea + xref_size):
    #  return False

    ida_bytes.del_items(from_ea, idc.DELIT_EXPAND, xref_size)

    if data_type == idc.FF_QWORD:
        data_size = 8
    elif data_type == idc.FF_DWORD:
        data_size = 4
    else:
        raise ValueError("Invalid data type")

    idc.create_data(from_ea, data_type, data_size, idaapi.BADADDR)
    if not is_code_by_flags(from_ea):
        idc.add_dref(from_ea, to_ea, idc.XREF_USER | idc.dr_O)
    else:
        DEBUG("  Not making reference (B) from {:x} to {:x}".format(
            from_ea, to_ea))

    return True
Ejemplo n.º 4
0
def znullptr(address, end, search, struct):

    magic = idaapi.find_binary(address, end, search, 0x10, idc.SEARCH_DOWN)
    pattern = '%02X %02X %02X %02X FF FF FF FF' % (magic & 0xFF,
                                                   ((magic >> 0x8) & 0xFF),
                                                   ((magic >> 0x10) & 0xFF),
                                                   ((magic >> 0x18) & 0xFF))

    sysvec = idaapi.find_binary(address, cvar.inf.maxEA, pattern, 0x10,
                                idc.SEARCH_UP) - 0x60
    idaapi.set_name(sysvec, 'sysentvec', SN_NOCHECK | SN_NOWARN | SN_FORCE)

    sysent = idaapi.get_qword(sysvec + 0x8)
    idaapi.set_name(sysent, 'sv_table', SN_NOCHECK | SN_NOWARN | SN_FORCE)

    sysnames = idaapi.get_qword(sysvec + 0xD0)
    idaapi.set_name(sysnames, 'sv_syscallnames',
                    SN_NOCHECK | SN_NOWARN | SN_FORCE)

    # Get the list of syscalls
    offset = idaapi.find_binary(address, cvar.inf.maxEA,
                                '73 79 73 63 61 6C 6C 00 65 78 69 74 00', 0x10,
                                SEARCH_DOWN)

    numsyscalls = idaapi.get_qword(sysvec)
    for entry in xrange(numsyscalls):
        initial = sysnames + (entry * 0x8)
        idc.create_data(initial, FF_QWORD, 0x8, BADNODE)
        offset = idaapi.get_qword(initial)

        length = idaapi.get_max_strlit_length(offset, STRTYPE_C)
        name = idaapi.get_strlit_contents(offset, length, STRTYPE_C)

        sysentoffset = sysent + 0x8 + (entry * 0x30)
        idaapi.do_unknown_range(sysentoffset - 0x8, 0x30, 0)
        idaapi.create_struct(sysentoffset - 0x8, 0x30, struct)
        idc.set_cmt(sysentoffset - 0x8, '#%i' % entry, False)

        if '{' in name:
            continue

        # Rename the functions
        function = idaapi.get_qword(sysentoffset)
        idaapi.set_name(function, name.replace('#', 'sys_'),
                        SN_NOCHECK | SN_NOWARN | SN_FORCE)
Ejemplo n.º 5
0
def make_xref(from_ea, to_ea, data_type, xref_size):
  """Force the data at `from_ea` to reference the data at `to_ea`."""
  if not idc.get_full_flags(to_ea) or is_invalid_ea(to_ea):
    DEBUG("  Not making reference (A) from {:x} to {:x}".format(from_ea, to_ea))
    return False

  make_head(from_ea)

  if is_code(from_ea):
    _CREFS_FROM[from_ea].add(to_ea)
    _CREFS_TO[to_ea].add(from_ea)
  else:
    _DREFS_FROM[from_ea].add(to_ea)
    _DREFS_TO[to_ea].add(from_ea)

  # If we can't make a head, then it probably means that we're at the
  # end of the binary, e.g. the last thing in the `.extern` segment.
  # or in the middle of structure. Return False in such case
  #
  # NOTE(artem): Commenting out since this breaks recovery of C++ applications
  # with IDA7. The failure occurs when processign references in .init_array
  # when the below code is enabled, those references are not treated as
  # references because make_head fails.
  #
  #if not make_head(from_ea + xref_size):
  #  return False

  ida_bytes.del_items(from_ea, idc.DELIT_EXPAND, xref_size)

  if data_type == idc.FF_QWORD:
    data_size = 8
  elif data_type == idc.FF_DWORD:
    data_size = 4
  else:
    raise ValueError("Invalid data type")

  idc.create_data(from_ea, data_type, data_size, idaapi.BADADDR)
  if not is_code_by_flags(from_ea):
    idc.add_dref(from_ea, to_ea, idc.XREF_USER|idc.dr_O)
  else: 
    DEBUG("  Not making reference (B) from {:x} to {:x}".format(from_ea, to_ea))

  return True
Ejemplo n.º 6
0
def make_xref(from_ea, to_ea, data_type, xref_size):
    """Force the data at `from_ea` to reference the data at `to_ea`."""
    if not idc.get_full_flags(to_ea) or is_invalid_ea(to_ea):
        DEBUG("  Not making reference (A) from {:x} to {:x}".format(
            from_ea, to_ea))
        return False

    make_head(from_ea)

    if is_code(from_ea):
        _CREFS_FROM[from_ea].add(to_ea)
        _CREFS_TO[to_ea].add(from_ea)
    else:
        _DREFS_FROM[from_ea].add(to_ea)
        _DREFS_TO[to_ea].add(from_ea)

    # If we can't make a head, then it probably means that we're at the
    # end of the binary, e.g. the last thing in the `.extern` segment.
    # or in the middle of structure. Return False in such case
    if not make_head(from_ea + xref_size):
        return False

    ida_bytes.del_items(from_ea, idc.DELIT_EXPAND, xref_size)

    if data_type == idc.FF_QWORD:
        data_size = 8
    elif data_type == idc.FF_DWORD:
        data_size = 4
    else:
        raise ValueError("Invalid data type")

    idc.create_data(from_ea, data_type, data_size, idaapi.BADADDR)
    if not is_code_by_flags(from_ea):
        idc.add_dref(from_ea, to_ea, idc.XREF_USER | idc.dr_O)
    else:
        DEBUG("  Not making reference (B) from {:x} to {:x}".format(
            from_ea, to_ea))

    return True
Ejemplo n.º 7
0
def xex_load_imports(li):
    global directory_entry_headers

    li.seek(directory_entry_headers[XEX_HEADER_IMPORTS])
    import_desc = read_struct(li, XEXImportDescriptor)

    # seperate the library names in the name table
    import_libnames = []
    cur_lib = ""
    for i in range(0, import_desc.NameTableSize):
        name_char = li.read(1)

        if name_char == '\0' or name_char == '\xCD':
            if cur_lib != "":
                import_libnames.append(cur_lib)
                cur_lib = ""
        else:
            cur_lib += name_char

    # read each import library table
    for i in range(0, import_desc.ModuleCount):
        table_addr = li.tell()
        table_header = read_struct(li, XEXImportTable)
        libname = import_libnames[table_header.ModuleIndex]
        variables = {}
        for i in range(0, table_header.ImportCount):
            record_addr = read_dwordBE(li)

            record_value = ida_bytes.get_dword(record_addr)
            record_type = (record_value & 0xFF000000) >> 24
            ordinal = record_value & 0xFFFF

            import_name = x360_imports.DoNameGen(libname, 0, ordinal)
            if record_type == 0:
                # variable
                idc.create_data(record_addr, idc.FF_WORD, 2, idc.BADADDR)
                idc.create_data(record_addr + 2, idc.FF_WORD, 2, idc.BADADDR)
                idc.make_array(record_addr, 2)
                idc.set_name(record_addr, "__imp__" + import_name)
                variables[ordinal] = record_addr

            elif record_type == 1:
                # thunk
                # have to rewrite code to set r3 & r4 like xorlosers loader does
                # r3 = module index afaik
                # r4 = ordinal
                # important to note that basefiles extracted via xextool have this rewrite done already, but raw basefile from XEX doesn't!
                # todo: find out how to add to imports window like xorloser loader...

                ida_bytes.put_dword(record_addr + 0,
                                    0x38600000 | table_header.ModuleIndex)
                ida_bytes.put_dword(record_addr + 4, 0x38800000 | ordinal)
                idc.add_func(record_addr, record_addr + 0x10)
                idc.set_name(record_addr, import_name)

                # add comment to thunk like xorloser's loader
                idc.set_cmt(
                    record_addr + 4,
                    "%s :: %s" % (libname.rsplit('.', 1)[0], import_name), 1)

                # this should mark the func as a library function, but it doesn't do anything for some reason
                # tried a bunch of things like idaapi.autoWait() before running it, just crashes IDA with internal errors...
                idc.set_func_flags(
                    record_addr,
                    idc.get_func_flags(record_addr) | idc.FUNC_LIB)

                # thunk means it's not a variable, so remove from variables dict
                if ordinal in variables:
                    variables.pop(ordinal)

            else:
                print(
                    "[+] %s import %d (%s) (@ 0x%X) unknown type %d!" %
                    (libname, ordinal, import_name, record_addr, record_type))

        # remove "__imp__" part from variable import names
        for ordinal in variables:
            import_name = x360_imports.DoNameGen(libname, 0, ordinal)
            idc.set_name(variables[ordinal], import_name)

        # Seek to end of this import table
        li.seek(table_addr + table_header.TableSize)

    return
Ejemplo n.º 8
0
def load_file(f, neflags, format):
    
    print('# PS4 Kernel Loader')
    ps = Binary(f)
    
    # PS4 Processor, Compiler, Library
    bitness = ps.procomp('metapc', CM_N64 | CM_M_NN | CM_CC_FASTCALL, 'gnulnx_x64')
    
    # Segment Loading...
    for segm in ps.E_SEGMENTS:
        if segm.name() == 'PHDR':
            kASLR = False if segm.FILE_SIZE == 0x118 else True
        
        # Process Loadable Segments...
        if segm.name() in ['CODE', 'DATA', 'SCE_RELRO']:
            address = segm.MEM_ADDR
            size = segm.MEM_SIZE
            
            # Dumped Kernel Fix-ups
            if segm.name() in ['DATA', 'SCE_RELRO'] and (idaapi.get_segm_by_name('CODE').start_ea != 0xFFFFFFFF82200000 or not kASLR):
                offset = address - idaapi.get_segm_by_name('CODE').start_ea
                dumped = segm.MEM_SIZE
            else:
                offset = segm.OFFSET
                dumped = segm.FILE_SIZE
            
            print('# Creating %s Segment...' % segm.name())
            f.file2base(offset, address, address + dumped, FILEREG_PATCHABLE)
            
            idaapi.add_segm(0, address, address + size, segm.name(), segm.type(), ADDSEG_NOTRUNC | ADDSEG_FILLGAP)
            
            # Processor Specific Segment Details
            idc.set_segm_addressing(address, bitness)
            idc.set_segm_alignment(address, segm.alignment())
            idc.set_segm_attr(address, SEGATTR_PERM, segm.flags())
        
        # Process Dynamic Segment...
        elif segm.name() == 'DYNAMIC':
            code = idaapi.get_segm_by_name('CODE')
            data = idaapi.get_segm_by_name('DATA')
            relro = idaapi.get_segm_by_name('SCE_RELRO')
            
            # ------------------------------------------------------------------------------------------------------------
            # Dynamic Tag Entry Structure
            members = [('tag', 'Tag', 0x8),
                       ('value', 'Value', 0x8)]
            struct = segm.struct('Tag', members)
            
            # Dynamic Tag Table
            stubs = {}
            modules = {}
            location = segm.MEM_ADDR
            
            # Dumps are offset by a small amount
            if code.start_ea != 0xFFFFFFFF82200000:
                dumped = code.start_ea - 0xFFFFFFFF82200000
            else:
                dumped = 0
            
            f.seek(location - code.start_ea)
            for entry in xrange(segm.MEM_SIZE / 0x10):
                idaapi.create_struct(location + (entry * 0x10), 0x10, struct)
                idc.set_cmt(location + (entry * 0x10), Dynamic(f).process(dumped, stubs, modules), False)
            
            # ------------------------------------------------------------------------------------------------------------
            # Hash Entry Structure
            members = [('bucket', 'Bucket', 0x2),
                       ('chain', 'Chain', 0x2),
                       ('buckets', 'Buckets', 0x2),
                       ('chains', 'Chains', 0x2)]
            struct = segm.struct('Hash', members)
            
            # Hash Table
            try:
                location = Dynamic.HASHTAB
                size = Dynamic.HASHTABSZ
            
            except:
                location = Dynamic.HASH
                size = Dynamic.SYMTAB - location
            
            f.seek(location - code.start_ea)
            for entry in xrange(size / 0x8):
                idaapi.create_struct(location + (entry * 0x8), 0x8, struct)
            
            if kASLR:
                # --------------------------------------------------------------------------------------------------------
                # Relocation Entry Structure (with specific addends)
                members = [('offset', 'Offset (String Index)', 0x8),
                           ('info', 'Info (Symbol Index : Relocation Code)', 0x8),
                           ('addend', 'AddEnd', 0x8)]
                struct = segm.struct('Relocation', members)
                
                # Relocation Table (with specific addends)
                location = Dynamic.RELATAB
                
                f.seek(location - code.start_ea)
                for entry in xrange(Dynamic.RELATABSZ / 0x18):
                    idaapi.create_struct(location + (entry * 0x18), 0x18, struct)
                    idc.set_cmt(location + (entry * 0x18), Relocation(f).process(dumped, code.end_ea), False)
                
                # Initialization Function
                idc.add_entry(Dynamic.INIT, Dynamic.INIT, '.init', True)
            
            else:
                # --------------------------------------------------------------------------------------------------------
                # Symbol Entry Structure
                members = [('name', 'Name (String Index)', 0x4),
                           ('info', 'Info (Binding : Type)', 0x1),
                           ('other', 'Other', 0x1),
                           ('shtndx', 'Section Index', 0x2),
                           ('offset', 'Value', 0x8),
                           ('size', 'Size', 0x8)]
                struct = segm.struct('Symbol', members)
                
                # Symbol Table
                location = Dynamic.SYMTAB
                f.seek(location - code.start_ea)
                functions = {}
                
                # .symtab
                idc.add_entry(location, location, '.symtab', False)
                
                for entry in xrange((Dynamic.STRTAB - location) / 0x18):
                    idaapi.create_struct(location + (entry * 0x18), 0x18, struct)
                    idc.set_cmt(location + (entry * 0x18), Symbol(f).process(functions), False)
                
                # --------------------------------------------------------------------------------------------------------
                # Dynamic String Table
                location = Dynamic.STRTAB
                
                # .strtab
                idc.add_entry(location, location, '.strtab', False)
                
                # Functions
                for key in functions:
                    idc.create_strlit(location + key, BADADDR)
                    functions[key] = idc.get_strlit_contents(location + key, BADADDR)
                    idc.set_cmt(location + key, 'Function', False)
                
                functions = sorted(functions.iteritems(), key = operator.itemgetter(0))
                #print('Functions: %s' % functions)
                
                # Resolve Functions
                location = Dynamic.SYMTAB
                f.seek(location - code.start_ea + 0x18)
                
                for entry in xrange((Dynamic.STRTAB - location - 0x18) / 0x18):
                    Symbol(f).resolve(functions[entry][1])
    
    # Fix-up
    if kASLR:
        address = relro.start_ea
        del_items(address, DELIT_SIMPLE, relro.end_ea - address)
        
        while address < relro.end_ea:
            create_data(address, FF_QWORD, 0x8, BADNODE)
            address += 0x8
    
    address = code.start_ea
    
    # ELF Header Structure
    members = [('File format', 0x4),
               ('File class', 0x1),
               ('Data encoding', 0x1),
               ('File version', 0x1),
               ('OS/ABI', 0x1),
               ('ABI version', 0x1),
               ('Padding', 0x7),
               ('File type', 0x2),
               ('Machine', 0x2),
               ('File version', 0x4),
               ('Entry point', 0x8),
               ('PHT file offset', 0x8),
               ('SHT file offset', 0x8),
               ('Processor-specific flags', 0x4),
               ('ELF header size', 0x2),
               ('PHT entry size', 0x2),
               ('Number of entries in PHT', 0x2),
               ('SHT entry size', 0x2),
               ('Number of entries in SHT', 0x2),
               ('SHT entry index for string table\n', 0x2)]
    
    for (comment, size) in members:
        flags = idaapi.get_flags_by_size(size)
        idc.create_data(address, flags if flags != 0 else FF_STRLIT, size, BADNODE)
        idc.set_cmt(address, comment, False)
        address += size
    
    for index, entry in enumerate(ps.E_SEGMENTS):
        # ELF Program Header Structure
        members = [('Type: %s' % entry.name(), 0x4),
                   ('Flags', 0x4),
                   ('File offset', 0x8),
                   ('Virtual address', 0x8),
                   ('Physical address', 0x8),
                   ('Size in file image', 0x8),
                   ('Size in memory image', 0x8),
                   ('Alignment\n', 0x8)]
        
        for (comment, size) in members:
            flags = idaapi.get_flags_by_size(size)
            
            idc.create_data(address, flags if flags != 0 else FF_STRLIT, size, BADNODE)
            idc.set_cmt(address, comment, False)
            address += size
    
    # Wait for the AutoAnalyzer to Complete...
    print('# Waiting for the AutoAnalyzer to Complete...')
    idaapi.auto_wait()
    
    if kASLR:
        # Start Function
        idc.add_entry(ps.E_START_ADDR, ps.E_START_ADDR, 'start', True)
        
        # Xfast_syscall
        address = idaapi.find_binary(code.start_ea, code.end_ea, '0F 01 F8 65 48 89 24 25 A8 02 00 00 65 48 8B 24', 0x10, SEARCH_DOWN)
        idaapi.do_unknown(address, 0)
        idaapi.create_insn(address)
        idaapi.add_func(address, BADADDR)
        idaapi.set_name(address, 'Xfast_syscall', SN_NOCHECK | SN_NOWARN)
        
        # --------------------------------------------------------------------------------------------------------
        # Znullptr's syscalls
        print('# Processing Znullptr\'s Syscalls...')
        
        # Syscall Entry Structure
        members = [('narg', 'Number of Arguments', 0x4),
                   ('_pad', 'Padding', 0x4),
                   ('function', 'Function', 0x8),
                   ('auevent', 'Augmented Event?', 0x2),
                   ('_pad1', 'Padding', 0x2),
                   ('_pad2', 'Padding', 0x4),
                   ('trace_args_func', 'Trace Arguments Function', 0x8),
                   ('entry', 'Entry', 0x4),
                   ('return', 'Return', 0x4),
                   ('flags', 'Flags', 0x4),
                   ('thrcnt', 'Thread Count?', 0x4)]
        struct = segm.struct('Syscall', members)
        
        znullptr(code.start_ea, code.end_ea, '4F 52 42 49 53 20 6B 65 72 6E 65 6C 20 53 45 4C 46', struct)
        
        # --------------------------------------------------------------------------------------------------------
        # Chendo's cdevsw con-struct-or
        print('# Processing Chendo\'s cdevsw structs...')
        
        # cdevsw Entry Structure
        members = [('d_version', 'Version', 0x4),
                   ('d_flags', 'Flags', 0x4),
                   ('d_name', 'Name', 0x8),
                   ('d_open', 'Open', 0x8),
                   ('d_fdopen', 'File Descriptor Open', 0x8),
                   ('d_close', 'Close', 0x8),
                   ('d_read', 'Read', 0x8),
                   ('d_write', 'Write', 0x8),
                   ('d_ioctl', 'Input/Ouput Control', 0x8),
                   ('d_poll', 'Poll', 0x8),
                   ('d_mmap', 'Memory Mapping', 0x8),
                   ('d_strategy', 'Strategy', 0x8),
                   ('d_dump', 'Dump', 0x8),
                   ('d_kqfilter', 'KQFilter', 0x8),
                   ('d_purge', 'Purge', 0x8),
                   ('d_mmap_single', 'Single Memory Mapping', 0x8),
                   ('d_spare0', 'Spare0', 0x8),
                   ('d_spare1', 'Spare1', 0x8),
                   ('d_spare2', 'Spare2', 0x8),
                   ('d_spare3', 'Spare3', 0x8),
                   ('d_spare4', 'Spare4', 0x8),
                   ('d_spare5', 'Spare5', 0x8),
                   ('d_spare6', 'Spare6', 0x4),
                   ('d_spare7', 'Spare7', 0x4)]
        struct = segm.struct('cdevsw', members)
        
        chendo(data.start_ea, data.end_ea, '09 20 12 17', struct)
    
    # --------------------------------------------------------------------------------------------------------
    # Pablo's IDC
    try:
        print('# Processing Pablo\'s Push IDC...')
        
        # Script 1) Push it real good...
        pablo(code.start_ea, code.end_ea, 'C5 FA 5A C0 C5 F2 5A C9 C5 EA 5A D2 C5 FB 59 C1')
        pablo(code.start_ea, code.end_ea, 'C5 F9 7E C0 31 C9')
        pablo(code.start_ea, code.end_ea, '48 89 E0 55 53')
        pablo(code.start_ea, code.end_ea, 'B8 2D 00 00 00 C3')
        pablo(code.start_ea, code.end_ea, '31 C0 C3')
        pablo(code.start_ea, code.end_ea, '55 48 89')
        pablo(code.start_ea, code.end_ea, '48 81 EC A0 00 00 00 C7')
        pablo(code.start_ea, code.end_ea, '48 81 EC A8 00 00 00')
        
        # Script 2) Fix-up Dumped Data Pointers...
        if dumped or not kASLR:
            print('# Processing Pablo\'s Dumped Data Pointers IDC...')
            pablo(data.start_ea, data.end_ea, '?? FF FF FF FF')
    
    except:
        pass
    
    # --------------------------------------------------------------------------------------------------------
    # Kiwidog's __stack_chk_fail
    if kASLR:
        print('# Processing Kiwidog\'s Stack Functions...')
        
        kiwidog(code.start_ea, code.end_ea, '73 74 61 63 6B 20 6F 76 65 72 66 6C 6F 77 20 64 65 74 65 63 74 65 64 3B')
    
    # --------------------------------------------------------------------------------------------------------
    # Final Pass
    print('# Performing Final Pass...')
    address = code.start_ea
    while address < code.end_ea:
        address = idaapi.find_not_func(address, SEARCH_DOWN)
        
        if idaapi.isUnknown(idaapi.getFlags(address)):
            idaapi.create_insn(address)
        else:
            idc.add_func(address)
        
        address += 4
    
    print('# Done!')
    return 1
Ejemplo n.º 9
0
 def __call__(self):
     idc.create_data(self.ea, self.flags, self.size, self.tid)
Ejemplo n.º 10
0
 def cmd_make_qword(self, a):
     return str(
         idc.create_data(int(a, 0), idc.FF_QWORD, 8, ida_idaapi.BADADDR))
Ejemplo n.º 11
0
 def cmd_make_byte(self, a):
     return str(
         idc.create_data(int(a, 0), idc.FF_BYTE, 1, ida_idaapi.BADADDR))
Ejemplo n.º 12
0
def io_naming():
    idc.set_name(0x04000000, "LCDControl", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x04000000, idc.FF_WORD, 2, idaapi.BADADDR)
    idc.set_name(0x04000002, "Undocumented-GreenSwap", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x04000002, idc.FF_WORD, 2, idaapi.BADADDR)
    idc.set_name(0x04000004, "GeneralLCDStatus(STAT,LYC)", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x04000004, idc.FF_WORD, 2, idaapi.BADADDR)
    idc.set_name(0x04000006, "VerticalCounter(LY)", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x04000006, idc.FF_WORD, 2, idaapi.BADADDR)
    idc.set_name(0x04000008, "BG0Control", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x04000008, idc.FF_WORD, 2, idaapi.BADADDR)
    idc.set_name(0x0400000A, "BG1Control", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x0400000A, idc.FF_WORD, 2, idaapi.BADADDR)
    idc.set_name(0x0400000C, "BG2Control", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x0400000C, idc.FF_WORD, 2, idaapi.BADADDR)
    idc.set_name(0x0400000E, "BG3Control", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x0400000E, idc.FF_WORD, 2, idaapi.BADADDR)
    idc.set_name(0x04000010, "BG0X-Offset", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x04000010, idc.FF_WORD, 2, idaapi.BADADDR)
    idc.set_name(0x04000012, "BG0Y-Offset", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x04000012, idc.FF_WORD, 2, idaapi.BADADDR)
    idc.set_name(0x04000014, "BG1X-Offset", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x04000014, idc.FF_WORD, 2, idaapi.BADADDR)
    idc.set_name(0x04000016, "BG1Y-Offset", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x04000016, idc.FF_WORD, 2, idaapi.BADADDR)
    idc.set_name(0x04000018, "BG2X-Offset", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x04000018, idc.FF_WORD, 2, idaapi.BADADDR)
    idc.set_name(0x0400001A, "BG2Y-Offset", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x0400001A, idc.FF_WORD, 2, idaapi.BADADDR)
    idc.set_name(0x0400001C, "BG3X-Offset", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x0400001C, idc.FF_WORD, 2, idaapi.BADADDR)
    idc.set_name(0x0400001E, "BG3Y-Offset", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x0400001E, idc.FF_WORD, 2, idaapi.BADADDR)
    idc.set_name(0x04000020, "BG2Rotation/ScalingParameterA(dx)", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x04000020, idc.FF_WORD, 2, idaapi.BADADDR)
    idc.set_name(0x04000022, "BG2Rotation/ScalingParameterB(dmx)", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x04000022, idc.FF_WORD, 2, idaapi.BADADDR)
    idc.set_name(0x04000024, "BG2Rotation/ScalingParameterC(dy)", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x04000024, idc.FF_WORD, 2, idaapi.BADADDR)
    idc.set_name(0x04000026, "BG2Rotation/ScalingParameterD(dmy)", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x04000026, idc.FF_WORD, 2, idaapi.BADADDR)
    idc.set_name(0x04000028, "BG2ReferencePointX-Coordinate", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x04000028, idc.FF_DWORD, 4, idaapi.BADADDR)
    idc.set_name(0x0400002C, "BG2ReferencePointY-Coordinate", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x0400002C, idc.FF_DWORD, 4, idaapi.BADADDR)
    idc.set_name(0x04000030, "BG3Rotation/ScalingParameterA(dx)", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x04000030, idc.FF_WORD, 2, idaapi.BADADDR)
    idc.set_name(0x04000032, "BG3Rotation/ScalingParameterB(dmx)", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x04000032, idc.FF_WORD, 2, idaapi.BADADDR)
    idc.set_name(0x04000034, "BG3Rotation/ScalingParameterC(dy)", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x04000034, idc.FF_WORD, 2, idaapi.BADADDR)
    idc.set_name(0x04000036, "BG3Rotation/ScalingParameterD(dmy)", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x04000036, idc.FF_WORD, 2, idaapi.BADADDR)
    idc.set_name(0x04000038, "BG3ReferencePointX-Coordinate", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x04000038, idc.FF_DWORD, 4, idaapi.BADADDR)
    idc.set_name(0x0400003C, "BG3ReferencePointY-Coordinate", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x0400003C, idc.FF_DWORD, 4, idaapi.BADADDR)
    idc.set_name(0x04000040, "Window0HorizontalDimensions", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x04000040, idc.FF_WORD, 2, idaapi.BADADDR)
    idc.set_name(0x04000042, "Window1HorizontalDimensions", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x04000042, idc.FF_WORD, 2, idaapi.BADADDR)
    idc.set_name(0x04000044, "Window0VerticalDimensions", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x04000044, idc.FF_WORD, 2, idaapi.BADADDR)
    idc.set_name(0x04000046, "Window1VerticalDimensions", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x04000046, idc.FF_WORD, 2, idaapi.BADADDR)
    idc.set_name(0x04000048, "InsideofWindow0and1", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x04000048, idc.FF_WORD, 2, idaapi.BADADDR)
    idc.set_name(0x0400004A, "InsideofOBJWindow&OutsideofWindows", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x0400004A, idc.FF_WORD, 2, idaapi.BADADDR)
    idc.set_name(0x0400004C, "MosaicSize", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x0400004C, idc.FF_WORD, 2, idaapi.BADADDR)
    idc.set_name(0x0400004E, "Notused", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.set_name(0x04000050, "ColorSpecialEffectsSelection", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x04000050, idc.FF_WORD, 2, idaapi.BADADDR)
    idc.set_name(0x04000052, "AlphaBlendingCoefficients", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x04000052, idc.FF_WORD, 2, idaapi.BADADDR)
    idc.set_name(0x04000054, "Brightness(Fade-In/Out)Coefficient", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x04000054, idc.FF_WORD, 2, idaapi.BADADDR)
    idc.set_name(0x04000056, "Notused", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.set_name(0x04000060, "Channel1Sweepregister(NR10)", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x04000060, idc.FF_WORD, 2, idaapi.BADADDR)
    idc.set_name(0x04000062, "Channel1Duty/Length/Envelope(NR11,NR12)", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x04000062, idc.FF_WORD, 2, idaapi.BADADDR)
    idc.set_name(0x04000064, "Channel1Frequency/Control(NR13,NR14)", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x04000064, idc.FF_WORD, 2, idaapi.BADADDR)
    idc.set_name(0x04000066, "Notused", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.set_name(0x04000068, "Channel2Duty/Length/Envelope(NR21,NR22)", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x04000068, idc.FF_WORD, 2, idaapi.BADADDR)
    idc.set_name(0x0400006A, "Notused", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.set_name(0x0400006C, "Channel2Frequency/Control(NR23,NR24)", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x0400006C, idc.FF_WORD, 2, idaapi.BADADDR)
    idc.set_name(0x0400006E, "Notused", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.set_name(0x04000070, "Channel3Stop/WaveRAMselect(NR30)", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x04000070, idc.FF_WORD, 2, idaapi.BADADDR)
    idc.set_name(0x04000072, "Channel3Length/Volume(NR31,NR32)", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x04000072, idc.FF_WORD, 2, idaapi.BADADDR)
    idc.set_name(0x04000074, "Channel3Frequency/Control(NR33,NR34)", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x04000074, idc.FF_WORD, 2, idaapi.BADADDR)
    idc.set_name(0x04000076, "Notused", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.set_name(0x04000078, "Channel4Length/Envelope(NR41,NR42)", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x04000078, idc.FF_WORD, 2, idaapi.BADADDR)
    idc.set_name(0x0400007A, "Notused", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.set_name(0x0400007C, "Channel4Frequency/Control(NR43,NR44)", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x0400007C, idc.FF_WORD, 2, idaapi.BADADDR)
    idc.set_name(0x0400007E, "Notused", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.set_name(0x04000080, "ControlStereo/Volume/Enable(NR50,NR51)", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x04000080, idc.FF_WORD, 2, idaapi.BADADDR)
    idc.set_name(0x04000082, "ControlMixing/DMAControl", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x04000082, idc.FF_WORD, 2, idaapi.BADADDR)
    idc.set_name(0x04000084, "ControlSoundon/off(NR52)", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x04000084, idc.FF_WORD, 2, idaapi.BADADDR)
    idc.set_name(0x04000086, "Notused", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.set_name(0x04000088, "SoundPWMControl", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x04000088, idc.FF_WORD, 2, idaapi.BADADDR)
    idc.set_name(0x0400008A, "Notused", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.set_name(0x04000090, "Channel3WavePatternRAM(2banks!!)", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.set_name(0x040000A0, "ChannelAFIFO,Data0-3", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x040000A0, idc.FF_DWORD, 4, idaapi.BADADDR)
    idc.set_name(0x040000A4, "ChannelBFIFO,Data0-3", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x040000A4, idc.FF_DWORD, 4, idaapi.BADADDR)
    idc.set_name(0x040000A8, "Notused", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.set_name(0x040000B0, "DMA0SourceAddress", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x040000B0, idc.FF_DWORD, 4, idaapi.BADADDR)
    idc.set_name(0x040000B4, "DMA0DestinationAddress", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x040000B4, idc.FF_DWORD, 4, idaapi.BADADDR)
    idc.set_name(0x040000B8, "DMA0WordCount", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x040000B8, idc.FF_WORD, 2, idaapi.BADADDR)
    idc.set_name(0x040000BA, "DMA0Control", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x040000BA, idc.FF_WORD, 2, idaapi.BADADDR)
    idc.set_name(0x040000BC, "DMA1SourceAddress", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x040000BC, idc.FF_DWORD, 4, idaapi.BADADDR)
    idc.set_name(0x040000C0, "DMA1DestinationAddress", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x040000C0, idc.FF_DWORD, 4, idaapi.BADADDR)
    idc.set_name(0x040000C4, "DMA1WordCount", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x040000C4, idc.FF_WORD, 2, idaapi.BADADDR)
    idc.set_name(0x040000C6, "DMA1Control", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x040000C6, idc.FF_WORD, 2, idaapi.BADADDR)
    idc.set_name(0x040000C8, "DMA2SourceAddress", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x040000C8, idc.FF_DWORD, 4, idaapi.BADADDR)
    idc.set_name(0x040000CC, "DMA2DestinationAddress", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x040000CC, idc.FF_DWORD, 4, idaapi.BADADDR)
    idc.set_name(0x040000D0, "DMA2WordCount", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x040000D0, idc.FF_WORD, 2, idaapi.BADADDR)
    idc.set_name(0x040000D2, "DMA2Control", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x040000D2, idc.FF_WORD, 2, idaapi.BADADDR)
    idc.set_name(0x040000D4, "DMA3SourceAddress", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x040000D4, idc.FF_DWORD, 4, idaapi.BADADDR)
    idc.set_name(0x040000D8, "DMA3DestinationAddress", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x040000D8, idc.FF_DWORD, 4, idaapi.BADADDR)
    idc.set_name(0x040000DC, "DMA3WordCount", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x040000DC, idc.FF_WORD, 2, idaapi.BADADDR)
    idc.set_name(0x040000DE, "DMA3Control", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x040000DE, idc.FF_WORD, 2, idaapi.BADADDR)
    idc.set_name(0x040000E0, "Notused", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.set_name(0x04000100, "Timer0Counter/Reload", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x04000100, idc.FF_WORD, 2, idaapi.BADADDR)
    idc.set_name(0x04000102, "Timer0Control", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x04000102, idc.FF_WORD, 2, idaapi.BADADDR)
    idc.set_name(0x04000104, "Timer1Counter/Reload", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x04000104, idc.FF_WORD, 2, idaapi.BADADDR)
    idc.set_name(0x04000106, "Timer1Control", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x04000106, idc.FF_WORD, 2, idaapi.BADADDR)
    idc.set_name(0x04000108, "Timer2Counter/Reload", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x04000108, idc.FF_WORD, 2, idaapi.BADADDR)
    idc.set_name(0x0400010A, "Timer2Control", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x0400010A, idc.FF_WORD, 2, idaapi.BADADDR)
    idc.set_name(0x0400010C, "Timer3Counter/Reload", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x0400010C, idc.FF_WORD, 2, idaapi.BADADDR)
    idc.set_name(0x0400010E, "Timer3Control", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x0400010E, idc.FF_WORD, 2, idaapi.BADADDR)
    idc.set_name(0x04000110, "Notused", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.set_name(0x04000120, "SIOData(Normal-32bitMode)(sharedwithbelow!)", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x04000120, idc.FF_DWORD, 4, idaapi.BADADDR)
    idc.set_name(0x04000120, "SIOData0(Parent)(Multi-PlayerMode)", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x04000120, idc.FF_WORD, 2, idaapi.BADADDR)
    idc.set_name(0x04000122, "SIOData1(1stChild)(Multi-PlayerMode)", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x04000122, idc.FF_WORD, 2, idaapi.BADADDR)
    idc.set_name(0x04000124, "SIOData2(2ndChild)(Multi-PlayerMode)", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x04000124, idc.FF_WORD, 2, idaapi.BADADDR)
    idc.set_name(0x04000126, "SIOData3(3rdChild)(Multi-PlayerMode)", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x04000126, idc.FF_WORD, 2, idaapi.BADADDR)
    idc.set_name(0x04000128, "SIOControlRegister", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x04000128, idc.FF_WORD, 2, idaapi.BADADDR)
    idc.set_name(0x0400012A, "SIOData(LocalofMulti-Player)(sharedbelow)", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x0400012A, idc.FF_WORD, 2, idaapi.BADADDR)
    idc.set_name(0x0400012A, "SIOData(Normal-8bitandUARTMode)", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x0400012A, idc.FF_WORD, 2, idaapi.BADADDR)
    idc.set_name(0x0400012C, "Notused", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.set_name(0x04000130, "KeyStatus", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x04000130, idc.FF_WORD, 2, idaapi.BADADDR)
    idc.set_name(0x04000132, "KeyInterruptControl", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x04000132, idc.FF_WORD, 2, idaapi.BADADDR)
    idc.set_name(0x04000134, "SIOModeSelect/GeneralPurposeData", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x04000134, idc.FF_WORD, 2, idaapi.BADADDR)
    idc.set_name(0x04000136, "IRAncient-InfraredRegister(Prototypesonly)", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.set_name(0x04000138, "Notused", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.set_name(0x04000140, "SIOJOYBusControl", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x04000140, idc.FF_WORD, 2, idaapi.BADADDR)
    idc.set_name(0x04000142, "Notused", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.set_name(0x04000150, "SIOJOYBusReceiveData", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x04000150, idc.FF_DWORD, 4, idaapi.BADADDR)
    idc.set_name(0x04000154, "SIOJOYBusTransmitData", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x04000154, idc.FF_DWORD, 4, idaapi.BADADDR)
    idc.set_name(0x04000158, "SIOJOYBusReceiveStatus", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x04000158, idc.FF_WORD, 2, idaapi.BADADDR)
    idc.set_name(0x0400015A, "Notused", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.set_name(0x04000200, "InterruptEnableRegister", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x04000200, idc.FF_WORD, 2, idaapi.BADADDR)
    idc.set_name(0x04000202, "InterruptRequestFlags/IRQAcknowledge", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x04000202, idc.FF_WORD, 2, idaapi.BADADDR)
    idc.set_name(0x04000204, "GamePakWaitstateControl", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x04000204, idc.FF_WORD, 2, idaapi.BADADDR)
    idc.set_name(0x04000206, "Notused", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.set_name(0x04000208, "InterruptMasterEnableRegister", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x04000208, idc.FF_WORD, 2, idaapi.BADADDR)
    idc.set_name(0x0400020A, "Notused", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.set_name(0x04000300, "Undocumented-PostBootFlag", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x04000300, idc.FF_BYTE, 1, idaapi.BADADDR)
    idc.set_name(0x04000301, "Undocumented-PowerDownControl", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x04000301, idc.FF_BYTE, 1, idaapi.BADADDR)
    idc.set_name(0x04000302, "Notused", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.set_name(0x04000411, "Notused", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.set_name(0x04000800, "Undocumented-InternalMemoryControl(R/W)", idc.SN_NOCHECK | idc.SN_NOWARN)
    idc.create_data(0x04000800, idc.FF_DWORD, 4, idaapi.BADADDR)
    idc.set_name(0x04000804, "Notused", idc.SN_NOCHECK | idc.SN_NOWARN)
Ejemplo n.º 13
0
def load_file(f, neflags, format):

    print('# PS4 Kernel Loader')
    ps4 = Binary(f)

    # PS4 Processor, Compiler, Library
    bitness = ps4.procomp('metapc', CM_N64 | CM_M_NN | CM_CC_FASTCALL,
                          'gnulnx_x64')

    # Segment Loading...
    for segm in ps4.E_SEGMENTS:

        # Process Loadable Segments...
        if segm.name() in ['CODE', 'DATA', 'SCE_RELRO']:
            address = segm.MEM_ADDR
            size = segm.MEM_SIZE

            # Dumped Kernel Fix-ups
            if segm.name() in ['DATA', 'SCE_RELRO'
                               ] and idaapi.get_segm_by_name(
                                   'CODE').start_ea != 0xFFFFFFFF82200000:
                offset = address - idaapi.get_segm_by_name('CODE').start_ea
                dumped = segm.MEM_SIZE
            else:
                offset = segm.OFFSET
                dumped = segm.FILE_SIZE

            print('# Creating %s Segment...' % segm.name())
            f.file2base(offset, address, address + dumped, FILEREG_PATCHABLE)

            idaapi.add_segm(0, address, address + size, segm.name(),
                            segm.type(), ADDSEG_NOTRUNC | ADDSEG_FILLGAP)

            # Processor Specific Segment Details
            idc.set_segm_addressing(address, bitness)
            idc.set_segm_alignment(address, segm.alignment())
            idc.set_segm_attr(address, SEGATTR_PERM, segm.flags())

        # Process Dynamic Segment...
        elif segm.name() == 'DYNAMIC':
            code = idaapi.get_segm_by_name('CODE')
            data = idaapi.get_segm_by_name('DATA')
            relro = idaapi.get_segm_by_name('SCE_RELRO')

            # ------------------------------------------------------------------------------------------------------------
            # Dynamic Tag Entry Structure
            members = [('tag', 'Tag', 0x8), ('value', 'Value', 0x8)]
            struct = segm.struct('Tag', members)

            # Dynamic Tag Table
            stubs = {}
            modules = {}
            location = segm.MEM_ADDR

            # Dumps are offset by a small amount
            if code.start_ea != 0xFFFFFFFF82200000:
                dumped = code.start_ea - 0xFFFFFFFF82200000
            else:
                dumped = 0

            f.seek(location - code.start_ea)
            for entry in xrange(segm.MEM_SIZE / 0x10):
                idaapi.create_struct(location + (entry * 0x10), 0x10, struct)
                idc.set_cmt(location + (entry * 0x10),
                            Dynamic(f).process(dumped, stubs, modules), False)

            # ------------------------------------------------------------------------------------------------------------
            # Hash Entry Structure
            members = [('bucket', 'Bucket', 0x2), ('chain', 'Chain', 0x2),
                       ('buckets', 'Buckets', 0x2), ('chains', 'Chains', 0x2)]
            struct = segm.struct('Hash', members)

            # Hash Table
            try:
                location = Dynamic.HASHTAB
                size = Dynamic.HASHTABSZ

            except:
                location = Dynamic.HASH
                size = Dynamic.SYMTAB - location

            f.seek(location - code.start_ea)
            for entry in xrange(size / 0x8):
                idaapi.create_struct(location + (entry * 0x8), 0x8, struct)

            # --------------------------------------------------------------------------------------------------------
            # Relocation Entry Structure (with specific addends)
            members = [('offset', 'Offset (String Index)', 0x8),
                       ('info', 'Info (Symbol Index : Relocation Code)', 0x8),
                       ('addend', 'AddEnd', 0x8)]
            struct = segm.struct('Relocation', members)

            # Relocation Table (with specific addends)
            location = Dynamic.RELATAB

            f.seek(location - code.start_ea)
            for entry in xrange(Dynamic.RELATABSZ / 0x18):
                idaapi.create_struct(location + (entry * 0x18), 0x18, struct)
                idc.set_cmt(location + (entry * 0x18),
                            Relocation(f).process(dumped, code.end_ea), False)

            # Initialization Function
            idc.add_entry(Dynamic.INIT, Dynamic.INIT, '.init', True)

    address = code.start_ea

    # ELF Header Structure
    members = [('File format', 0x4), ('File class', 0x1),
               ('Data encoding', 0x1), ('File version', 0x1), ('OS/ABI', 0x1),
               ('ABI version', 0x1), ('Padding', 0x7), ('File type', 0x2),
               ('Machine', 0x2), ('File version', 0x4), ('Entry point', 0x8),
               ('PHT file offset', 0x8), ('SHT file offset', 0x8),
               ('Processor-specific flags', 0x4), ('ELF header size', 0x2),
               ('PHT entry size', 0x2), ('Number of entries in PHT', 0x2),
               ('SHT entry size', 0x2), ('Number of entries in SHT', 0x2),
               ('SHT entry index for string table\n', 0x2)]

    for (comment, size) in members:
        flags = idaapi.get_flags_by_size(size)
        idc.create_data(address, flags if flags != 0 else FF_STRLIT, size,
                        BADNODE)
        idc.set_cmt(address, comment, False)
        address += size

    for index, entry in enumerate(ps4.E_SEGMENTS):
        # ELF Program Header Structure
        members = [('Type: %s' % entry.name(), 0x4), ('Flags', 0x4),
                   ('File offset', 0x8), ('Virtual address', 0x8),
                   ('Physical address', 0x8), ('Size in file image', 0x8),
                   ('Size in memory image', 0x8), ('Alignment\n', 0x8)]

        for (comment, size) in members:
            flags = idaapi.get_flags_by_size(size)

            idc.create_data(address, flags if flags != 0 else FF_STRLIT, size,
                            BADNODE)
            idc.set_cmt(address, comment, False)
            address += size

    # Start Function
    idc.add_entry(ps4.E_START_ADDR, ps4.E_START_ADDR, 'start', True)

    # Xfast_syscall
    address = idaapi.find_binary(
        code.start_ea, code.end_ea,
        '0F 01 F8 65 48 89 24 25 A8 02 00 00 65 48 8B 24', 0x10, SEARCH_DOWN)
    idaapi.do_unknown(address, 0)
    idaapi.create_insn(address)
    idaapi.add_func(address, BADADDR)
    idaapi.set_name(address, 'Xfast_syscall',
                    SN_NOCHECK | SN_NOWARN | SN_FORCE)

    # --------------------------------------------------------------------------------------------------------
    # Znullptr's syscalls
    print('# Processing Znullptr\'s Syscalls...')

    # Syscall Entry Structure
    members = [('narg', 'Number of Arguments', 0x4), ('_pad', 'Padding', 0x4),
               ('function', 'Function', 0x8),
               ('auevent', 'Augmented Event?', 0x2), ('_pad1', 'Padding', 0x2),
               ('_pad2', 'Padding', 0x4),
               ('trace_args_func', 'Trace Arguments Function', 0x8),
               ('entry', 'Entry', 0x4), ('return', 'Return', 0x4),
               ('flags', 'Flags', 0x4), ('thrcnt', 'Thread Count?', 0x4)]
    struct = segm.struct('Syscall', members)

    znullptr(code.start_ea, code.end_ea,
             '4F 52 42 49 53 20 6B 65 72 6E 65 6C 20 53 45 4C 46', struct)

    # --------------------------------------------------------------------------------------------------------
    # Chendo's cdevsw con-struct-or
    print('# Processing Chendo\'s Structures...')

    # cdevsw Entry Structure
    members = [('d_version', 'Version', 0x4), ('d_flags', 'Flags', 0x4),
               ('d_name', 'Name', 0x8), ('d_open', 'Open', 0x8),
               ('d_fdopen', 'File Descriptor Open', 0x8),
               ('d_close', 'Close', 0x8), ('d_read', 'Read', 0x8),
               ('d_write', 'Write', 0x8),
               ('d_ioctl', 'Input/Ouput Control', 0x8),
               ('d_poll', 'Poll', 0x8), ('d_mmap', 'Memory Mapping', 0x8),
               ('d_strategy', 'Strategy', 0x8), ('d_dump', 'Dump', 0x8),
               ('d_kqfilter', 'KQFilter', 0x8), ('d_purge', 'Purge', 0x8),
               ('d_mmap_single', 'Single Memory Mapping', 0x8),
               ('d_spare0', 'Spare0', 0x8), ('d_spare1', 'Spare1', 0x8),
               ('d_spare2', 'Spare2', 0x8), ('d_spare3', 'Spare3', 0x8),
               ('d_spare4', 'Spare4', 0x8), ('d_spare5', 'Spare5', 0x8),
               ('d_spare6', 'Spare6', 0x4), ('d_spare7', 'Spare7', 0x4)]
    struct = segm.struct('cdevsw', members)

    chendo(data.start_ea, data.end_ea, '09 20 12 17', struct)

    # --------------------------------------------------------------------------------------------------------
    # Pablo's IDC
    try:
        print('# Processing Pablo\'s Push IDC...')

        # Script 1) Push it real good...
        # Default patterns set
        pablo(0, code.start_ea, 0x10, '55 48 89')
        pablo(2, code.start_ea, code.end_ea, '90 90 55 48 ??')
        pablo(2, code.start_ea, code.end_ea, 'C3 90 55 48 ??')
        pablo(2, code.start_ea, code.end_ea, '66 90 55 48 ??')
        pablo(2, code.start_ea, code.end_ea, 'C9 C3 55 48 ??')
        pablo(2, code.start_ea, code.end_ea, '0F 0B 55 48 ??')
        pablo(2, code.start_ea, code.end_ea, 'EB ?? 55 48 ??')
        pablo(2, code.start_ea, code.end_ea, '5D C3 55 48 ??')
        pablo(2, code.start_ea, code.end_ea, '5B C3 55 48 ??')
        pablo(2, code.start_ea, code.end_ea, '90 90 55 41 ?? 41 ??')
        pablo(2, code.start_ea, code.end_ea, '66 90 48 81 EC ?? 00 00 00')
        pablo(2, code.start_ea, code.end_ea,
              '0F 0B 48 89 9D ?? ?? FF FF 49 89')
        pablo(2, code.start_ea, code.end_ea, '90 90 53 4C 8B 54 24 20')
        pablo(2, code.start_ea, code.end_ea, '90 90 55 41 56 53')
        pablo(2, code.start_ea, code.end_ea, '90 90 53 48 89')
        pablo(2, code.start_ea, code.end_ea, '90 90 41 ?? 41 ??')
        pablo(3, code.start_ea, code.end_ea, '0F 0B 90 55 48 ??')
        pablo(3, code.start_ea, code.end_ea, 'EB ?? 90 55 48 ??')
        pablo(3, code.start_ea, code.end_ea, '41 5F C3 55 48 ??')
        pablo(3, code.start_ea, code.end_ea, '41 5C C3 55 48 ??')
        pablo(3, code.start_ea, code.end_ea, '31 C0 C3 55 48 ??')
        pablo(3, code.start_ea, code.end_ea, '41 5D C3 55 48 ??')
        pablo(3, code.start_ea, code.end_ea, '41 5E C3 55 48 ??')
        pablo(3, code.start_ea, code.end_ea, '66 66 90 55 48 ??')
        pablo(3, code.start_ea, code.end_ea, '0F 1F 00 55 48 ??')
        pablo(3, code.start_ea, code.end_ea, '41 ?? C3 53 48')
        pablo(3, code.start_ea, code.end_ea, '0F 1F 00 48 81 EC ?? 00 00 00')
        pablo(4, code.start_ea, code.end_ea, '0F 1F 40 00 55 48 ??')
        pablo(4, code.start_ea, code.end_ea,
              '0F 1F 40 00 48 81 EC ?? 00 00 00')
        pablo(5, code.start_ea, code.end_ea, 'E9 ?? ?? ?? ?? 55 48 ??')
        pablo(5, code.start_ea, code.end_ea, 'E8 ?? ?? ?? ?? 55 48 ??')
        pablo(5, code.start_ea, code.end_ea, '48 83 C4 ?? C3 55 48 ??')
        pablo(5, code.start_ea, code.end_ea, '0F 1F 44 00 00 55 48 ??')
        pablo(5, code.start_ea, code.end_ea,
              '0F 1F 44 00 00 48 81 EC ?? 00 00 00')
        pablo(6, code.start_ea, code.end_ea, 'E9 ?? ?? ?? ?? 90 55 48 ??')
        pablo(6, code.start_ea, code.end_ea, 'E8 ?? ?? ?? ?? 90 55 48 ??')
        pablo(6, code.start_ea, code.end_ea, '66 0F 1F 44 00 00 55 48 ??')
        pablo(7, code.start_ea, code.end_ea, '0F 1F 80 00 00 00 00 55 48 ??')
        pablo(8, code.start_ea, code.end_ea,
              '0F 1F 84 00 00 00 00 00 55 48 ??')
        pablo(8, code.start_ea, code.end_ea, 'C3 0F 1F 80 00 00 00 00 48')
        pablo(8, code.start_ea, code.end_ea,
              '0F 1F 84 00 00 00 00 00 53 48 83 EC')

        # Special cases patterns set
        pablo(13, code.start_ea, code.end_ea,
              'C3 90 90 90 90 90 90 90 90 90 90 90 90 48')
        pablo(13, code.start_ea, code.end_ea,
              'C3 90 90 90 90 90 90 90 90 90 90 90 90 55')
        pablo(17, code.start_ea, code.end_ea,
              'E9 ?? ?? ?? ?? 90 90 90 90 90 90 90 90 90 90 90 90 48')
        pablo(19, code.start_ea, code.end_ea,
              'E9 ?? ?? ?? ?? 90 90 90 90 90 90 90 90 90 90 90 90 90 90 48')
        pablo(19, code.start_ea, code.end_ea,
              'E8 ?? ?? ?? ?? 90 90 90 90 90 90 90 90 90 90 90 90 90 90 48')
        pablo(
            20, code.start_ea, code.end_ea,
            'E9 ?? ?? ?? ?? 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 48')
        pablo(
            20, code.start_ea, code.end_ea,
            'E9 ?? ?? ?? ?? 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 48')

        # Script 2) Fix-up Dumped Data Pointers...
        if dumped:
            print('# Processing Pablo\'s Dumped Data Pointers IDC...')
            pablo(0, data.start_ea, data.end_ea, '?? FF FF FF FF')

    except:
        pass

    # --------------------------------------------------------------------------------------------------------
    # Kiwidog's __stack_chk_fail
    print('# Processing Kiwidog\'s Stack Functions...')

    kiwidog(
        code.start_ea, code.end_ea,
        '73 74 61 63 6B 20 6F 76 65 72 66 6C 6F 77 20 64 65 74 65 63 74 65 64 3B'
    )

    print('# Done!')
    return 1