Beispiel #1
0
def write_segment(va_start, va_end, segm_name, data):
    ida_segment.add_segm(0, va_start, va_end, segm_name, None, 0xe)
    va = va_start
    for b in data:
        ida_bytes.patch_byte(va, ord(b))
        va += 1
    print("wrote 0x%x bytes to 0x%x [%s]" % (len(data), va_start, segm_name))
Beispiel #2
0
def create_rom_segment():
    success = add_segm(0, ROM_START_ADDRESS, ROM_START_ADDRESS + ROM_SIZE,
                       "ROM", "CODE") == 1
    msg("creating ROM segment..%s" % ("ok!\n" if success else "failure!\n"))
    if (not success):
        return
    set_segm_addressing(getseg(ROM_START_ADDRESS), 0)
Beispiel #3
0
def create_ram_segment():
    success = add_segm(0, RAM_START_ADDRESS, RAM_START_ADDRESS + RAM_SIZE,
                       "RAM", None) == 1
    msg("creating RAM segment..%s" % ("ok!\n" if success else "failure!\n"))
    if (not success):
        return
    set_segm_addressing(getseg(RAM_START_ADDRESS), 0)
Beispiel #4
0
def create_exprom_segment():
    success = add_segm(0, EXPROM_START_ADDRESS,
                       EXPROM_START_ADDRESS + EXPROM_SIZE, "EXP_ROM",
                       None) == 1
    msg("creating EXP_ROM segment..%s" %
        ("ok!\n" if success else "failure!\n"))
    if (not success):
        return
    set_segm_addressing(getseg(EXPROM_START_ADDRESS), 0)
Beispiel #5
0
def load_trainer(li):
    if (not INES_MASK_SRAM(hdr.rom_control_byte_0)):
        success = add_segm(0, TRAINER_START_ADDRESS,
                           TRAINER_START_ADDRESS + TRAINER_SIZE, "TRAINER",
                           "CODE") == 1
        msg("creating TRAINER segment..%s",
            "ok!\n" if success else "failure!\n")
        set_segm_addressing(getseg(TRAINER_START_ADDRESS), 0)
    li.file2base(INES_HDR_SIZE, TRAINER_START_ADDRESS,
                 TRAINER_START_ADDRESS + TRAINER_SIZE, FILEREG_PATCHABLE)
Beispiel #6
0
def add_segment(ea, size, seg_class, debug=False):
    # align page size
    ea = ea & 0xFFFFF000
    end_ea = ea + size
    is_changed = False
    if ea == 0:
        return False
    while ea < end_ea:
        cur_seg = ida_segment.getseg(ea)
        next_seg = ida_segment.get_next_seg(ea)

        if debug:
            print("=" * 30)
            if cur_seg:
                print("cur_seg: %x - %x" % (cur_seg.start_ea, cur_seg.end_ea))
            if next_seg:
                print("next_seg: %x - %x" %
                      (next_seg.start_ea, next_seg.end_ea))
            print("new_seg: %x - %x" % (ea, end_ea))

        # if there is no segment, so create new segment
        if not cur_seg:
            if not next_seg:
                ida_segment.add_segm(0, ea, end_ea, "", seg_class)
                is_changed = True
                break

            # if next_seg exists
            if end_ea <= next_seg.start_ea:
                ida_segment.add_segm(0, ea, end_ea, "", seg_class)
                is_changed = True
                break

            # end_ea > next_seg.start_ea, need to create more segments
            ida_segment.add_segm(0, ea, next_seg.start_ea, "", seg_class)

        # if segment already exists, we extend current segment
        else:
            if end_ea <= cur_seg.end_ea:
                break

            if not next_seg:
                ida_segment.set_segm_end(ea, end_ea, 0)
                ida_segment.set_segm_class(cur_seg, seg_class)
                is_changed = True
                break

            # if next_seg exists
            if end_ea <= next_seg.start_ea:
                ida_segment.set_segm_end(ea, end_ea, 0)
                ida_segment.set_segm_class(cur_seg, seg_class)
                is_changed = True
                break

            # end_ea > next_seg.start_ea, need to create more segments
            if cur_seg.end_ea < next_seg.start_ea:
                ida_segment.set_segm_end(ea, next_seg.start_ea, 0)
                ida_segment.set_segm_class(cur_seg, seg_class)
                is_changed = True

        ea = next_seg.start_ea

    return is_changed
Beispiel #7
0
def load_file(f: ida_idaapi.loader_input_t, neflags: Any, format: Any) -> int:
    """
    load the given file into the current IDA Pro database.

    Args:
      f (file): the file-like object to load.
      neflags (Any): unused
      format (Any): unused

    Returns:
      int: 1 on success, 0 on failure
    """

    # compute file size, then read the entire contents
    f.seek(0x0, os.SEEK_END)
    flen = f.tell()
    f.seek(0x0)
    buf = f.read(flen)

    # mark the proc type, so IDA can invoke the correct disassembler/processor.
    # this must match `processor.wasm_processor_t.psnames`
    ida_idp.set_processor_type('wasm', ida_idp.SETPROC_LOADER_NON_FATAL)

    f.seek(0x0)
    # load the entire file directly at address zero.
    f.file2base(0, 0, len(buf), True)

    p = 0
    sections = wasm.decode_module(buf)
    for i, section in enumerate(sections):
        if i == 0:
            sname = 'header'
        else:
            if section.data.id == wasm.wasmtypes.SEC_UNK:
                if section.data.name:
                    sname = section.data.name.tobytes().decode('utf-8')
                else:
                    sname = ''
            else:
                sname = idawasm.const.WASM_SECTION_NAMES.get(
                    section.data.id, 'unknown')

        if sname != 'header' and section.data.id in (
                wasm.wasmtypes.SEC_CODE, wasm.wasmtypes.SEC_GLOBAL):
            stype = 'CODE'
        else:
            stype = 'DATA'

        # add IDA segment with type, name, size as appropriate
        slen = sum(section.data.get_decoder_meta()['lengths'].values())
        ida_segment.add_segm(0, p, p + slen, sname, stype)

        if sname != 'header':
            loader = SECTION_LOADERS.get(section.data.id)
            if loader is not None:
                loader(section, p)

            load_section(section, p)

        p += slen

    # magic
    ida_bytes.create_data(0x0, ida_bytes.FF_DWORD, 4, ida_idaapi.BADADDR)
    ida_name.set_name(0x0, 'WASM_MAGIC', ida_name.SN_CHECK)
    # version
    ida_bytes.create_data(0x4, ida_bytes.FF_DWORD, 4, ida_idaapi.BADADDR)
    ida_name.set_name(0x4, 'WASM_VERSION', ida_name.SN_CHECK)

    return 1
Beispiel #8
0
def load_file(li, neflags, format):
    li.seek(0)

    text_offset = []
    text_addr = []
    text_size = []

    data_offset = []
    data_addr = []
    data_size = []

    print('Reading offsets...')

    for x in range(0, 7):
        text_offset.append(read_int(li))
        print(hex(text_offset[x]))

    for x in range(0, 11):
        data_offset.append(read_int(li))
        print(hex(data_offset[x]))

    print('Reading addresses...')

    for x in range(0, 7):
        text_addr.append(read_int(li))

    for x in range(0, 11):
        data_addr.append(read_int(li))

    print('Reading sizes...')

    for x in range(0, 7):
        text_size.append(read_int(li))

    for x in range(0, 11):
        data_size.append(read_int(li))

    print('Reading bss info...')

    bss_addr = read_int(li)
    bss_size = read_int(li)

    print('Reading entry point...')

    entry_point = read_int(li)

    print('Setting processor type...')

    idaapi.set_processor_type('ppc', SETPROC_LOADER)

    print('Adding text segments...')

    for x in range(0, 7):
        if text_size[x] == 0:
            continue
        end_addr = text_addr[x] + text_size[x]
        ida_segment.add_segm(0, text_addr[x], end_addr, 'Text' + str(x),
                             'CODE')
        li.file2base(text_offset[x], text_addr[x], end_addr, 1)

    print('Adding data segments...')

    for x in range(0, 11):
        if data_size[x] == 0:
            continue
        end_addr = data_addr[x] + data_size[x]
        ida_segment.add_segm(0, data_addr[x], end_addr, 'Data' + str(x),
                             'DATA')
        li.file2base(data_offset[x], data_addr[x], end_addr, 1)

    print('Adding bss segment...')

    if bss_size != 0:
        ida_segment.add_segm(0, bss_addr, bss_addr + bss_size, 'bss', 'BSS')

    ida_entry.add_entry(entry_point, entry_point, 'entry', 1)

    return 1
Beispiel #9
0
def load_file(f, neflags, format):
    f.seek(0)

    ida_idp.set_processor_type("metapc", ida_idp.SETPROC_LOADER)
    MGROUPStart = 0
    magic = f.read(2)

    if magic == MZ_HEADER_MAGIC:
        f.seek(0x22)
        MGROUPStart = DW(f) * 16
        f.seek(MGROUPStart)
        magic = f.read(2)

    headerSize = DW(f)
    segmentDataAlignment = DW(f)
    nextExeOff = DD(f)
    SegDataOff = DD(f)

    f.file2base(MGROUPStart, 0, SegDataOff, True)
    ida_segment.add_segm(0, 0, 0x50, "HEADER", "MODULE")
    f.seek(MGROUPStart + 2)

    headerSize = rnDW(f, "headerSize", MGROUPStart)
    segmentDataAlignment = rnDW(f, "segmentDataAlignment", MGROUPStart)
    nextExeOff = rnDD(f, "nextExeOff", MGROUPStart)
    SegDataOff = rnDD(f, "SegDataOff", MGROUPStart)

    ResDataOff = rnDD(f, "ResDataOff", MGROUPStart)
    flags = rnDW(f, "flags", MGROUPStart)
    version = rnDB(f, "version", MGROUPStart)
    revision = rnDB(f, "revision", MGROUPStart)
    AutoDataSegNo = rnDW(f, "AutoDataSegNo", MGROUPStart)
    HeapSize = rnDW(f, "HeapSize", MGROUPStart)
    StackSize = rnDW(f, "StackSize", MGROUPStart)
    StartProc = rnDD(f, "StartProc", MGROUPStart)
    LoadProc = rnDD(f, "LoadProc", MGROUPStart)
    FreeProc = rnDD(f, "FreeProc", MGROUPStart)
    nSegments = rnDW(f, "nSegments", MGROUPStart)
    pSegTable = rnDW(f, "pSegTable", MGROUPStart)
    cbResTab = rnDW(f, "cbResTab", MGROUPStart)
    pResTab = rnDW(f, "pResTab", MGROUPStart)
    cbEntTab = rnDW(f, "cbEntTab", MGROUPStart)
    pEntTab = rnDW(f, "pEntTab", MGROUPStart)
    cbNamTab = rnDW(f, "cbNamTab", MGROUPStart)
    pNamTab = rnDW(f, "pNamTab", MGROUPStart)
    cbStrTab = rnDW(f, "cbStrTab", MGROUPStart)
    pStrTab = rnDW(f, "pStrTab", MGROUPStart)
    cbNRNamTab = rnDW(f, "cbNRNamTab", MGROUPStart)
    pNRNamTab = rnDW(f, "pNRNamTab", MGROUPStart)

    ida_segment.add_segm(0, pSegTable,
                         pSegTable + (nSegments * SEG_STRUCT_SIZE), "SEGTABLE",
                         "MODULE")
    ida_segment.add_segm(0, pResTab, pResTab + cbResTab, "RESOURCES", "MODULE")
    ida_segment.add_segm(0, pEntTab, pEntTab + cbEntTab, "ENTTABLE", "MODULE")
    ida_segment.add_segm(0, pNamTab, pNamTab + cbNamTab, "ENTNAME", "MODULE")
    ida_segment.add_segm(0, pStrTab, pStrTab + cbStrTab, "IMPORTS", "MODULE")
    ida_segment.add_segm(0, pNRNamTab, pNRNamTab + cbNRNamTab, "NRENTNAME",
                         "MODULE")

    #parse segtable
    segentsid = defSEGENT()
    base = SegDataOff // 16

    importCount = 0
    for i in range(nSegments):
        segEntStart = pSegTable + i * SEG_STRUCT_SIZE
        ida_bytes.create_struct(segEntStart, SEG_STRUCT_SIZE, segentsid)
        segStart = ida_bytes.get_word(segEntStart + 2)
        segLen = ida_bytes.get_word(segEntStart + 4)
        segImports = ida_bytes.get_word(segEntStart + 6)
        importCount += segImports
        f.file2base(MGROUPStart + SegDataOff + segStart * 16,
                    SegDataOff + segStart * 16,
                    SegDataOff + (segStart + segLen) * 16, True)

        segBase = (base + segStart) * 16
        #segmentDef = ida_segment.segment_t()
        #segmentDef.start_ea = segBase
        #segmentDef.end_ea = (base+segStart+segLen)*16
        #ida_segment.set_selector()
        print(base + segStart)
        ida_segment.add_segm(base + segStart, segBase,
                             (base + segStart + segLen) * 16, "", "", 0)
        sel = ida_segment.find_selector(base + segStart)
        seg = ida_segment.getseg(segBase)
        ida_segment.set_segm_addressing(seg, 0)
        segtable[i] = seg
        segimportstable[i] = segImports
        if i + 1 == AutoDataSegNo:
            ida_segment.set_segm_name(seg, "DATA", 0)
            ida_segment.set_segm_class(seg, "DATA", 0)
            dataSel = sel
        else:
            ida_segment.set_segm_name(seg, "TEXT", 0)
            ida_segment.set_segm_class(seg, "CODE", 0)
            if AutoDataSegNo == 0:
                dataSel = sel
    ida_segregs.set_default_dataseg(dataSel)

    #parse enttable
    pENT = pEntTab
    currord = 1
    while pENT < pEntTab + cbEntTab:
        bundleCount = ida_bytes.get_byte(pENT)
        bundleFlags = ida_bytes.get_byte(pENT + 1)
        if bundleCount == 0 and bundleFlags == 0:
            break
        pENT += 2
        for i in range(bundleCount):
            if bundleFlags == 0xFF:
                ordFlags = ida_bytes.get_byte(pENT)
                if ordFlags & 0x80:
                    toexport.append(currord)
                segNo = ida_bytes.get_byte(pENT + 3)
                segOff = ida_bytes.get_word(pENT + 4)

                enttable[currord] = (segtable[segNo - 1].start_ea // 16,
                                     segOff)
                pENT += 6
            else:
                ordFlags = ida_bytes.get_byte(pENT)
                if ordFlags & 0x80:
                    toexport.append(currord)
                segOff = ida_bytes.get_word(pENT + 1)
                enttable[currord] = (segtable[bundleFlags - 1].start_ea // 16,
                                     segOff)
                pENT += 3

            currord += 1

    modulename = readPASSTR(pNamTab)

    make_entry(StartProc, modulename + "_start")
    make_entry(LoadProc, modulename + "_load")
    make_entry(FreeProc, modulename + "_free")

    #export named ordinals
    namedordtable = loadExportsF(f)

    for i in toexport:
        if i in namedordtable:
            name = namedordtable[i]
        else:
            name = "Ordinal" + str(i)
        (base, off) = enttable[i]
        addr = base * 16 + off
        ida_entry.add_entry(i, addr, name, 1)

    #process imports

    ida_segment.add_segm(0xF000, 0xF0000, 0xF0000 + importCount * 2, "IMPORTS",
                         "XTRN", 0)

    import_ea = 0xF0000

    for seg in segtable:
        segend = segtable[seg].end_ea
        f.seek(MGROUPStart + segend)

        for i in range(segimportstable[seg]):
            count = DB(f)
            mode = DB(f)
            relocStart = DW(f)
            module = DW(f)
            proc = DW(f)

            if (module == 0xFFFF):
                (base, off) = enttable[proc]
            else:
                modulestr = readPASSTR(pStrTab + module)
                if (proc & 0x8000) != 0:  # read by ord
                    ordinal = proc & 0x7FFF
                    procname = modulestr + "_Ordinal" + str(ordinal)
                    if not modulestr in importedmodules:
                        if os.path.isfile(modulestr + ".EXE"):
                            importedmodules[modulestr] = loadExports(
                                modulestr + ".EXE")
                        else:
                            filename = ida_kernwin.ask_file(
                                0, modulestr + ".EXE",
                                "Select file to name exports")
                            if filename is not None and os.path.isfile(
                                    filename):
                                importedmodules[modulestr] = loadExports(
                                    filename)
                            else:
                                importedmodules[modulestr] = None
                    if modulestr in importedmodules and (
                            importedmodules[modulestr] is not None
                    ) and ordinal in importedmodules[modulestr]:
                        procname = importedmodules[modulestr][ordinal]
                else:
                    procname = readPASSTR(pStrTab + proc)
                ida_bytes.create_data(import_ea, ida_bytes.FF_WORD, 2,
                                      ida_idaapi.BADADDR)
                ida_name.force_name(import_ea, procname)
                ida_bytes.set_cmt(import_ea, "Imported from " + modulestr, 1)
                base = 0xF000
                off = import_ea - 0xF0000
                import_ea += 2

            for xx in range(count):
                next = ida_bytes.get_word(segtable[seg].start_ea + relocStart)
                if mode == 0x20:
                    ida_bytes.put_word(segtable[seg].start_ea + relocStart + 2,
                                       base)
                    ida_bytes.put_word(segtable[seg].start_ea + relocStart,
                                       off)
                elif mode == 0x10:
                    ida_bytes.put_word(segtable[seg].start_ea + relocStart,
                                       off)
                elif mode == 0x0:
                    ida_bytes.put_word(segtable[seg].start_ea + relocStart,
                                       base)
                relocStart = next

            #print "import %d: seg %d mode %s count %d relocStart %s module %s proc %s" % (i, seg, hex(mode), count, hex(relocStart), modulestr, hex(proc))

    return 1
Beispiel #10
0
def create_ioreg_segment():
    success = add_segm(0, IOREGS_START_ADDRESS,
                       IOREGS_START_ADDRESS + IOREGS_SIZE, "IO_REGS",
                       None) == 1
    msg("creating IO_REGS segment..%s" %
        ("ok!\n" if success else "failure!\n"))
    if (not success):
        return
    set_segm_addressing(getseg(IOREGS_START_ADDRESS), 0)

    define_item(PPU_CR_1_ADDRESS, PPU_CR_1_SIZE, PPU_CR_1_SHORT_DESCRIPTION,
                PPU_CR_1_COMMENT)
    define_item(PPU_CR_2_ADDRESS, PPU_CR_2_SIZE, PPU_CR_2_SHORT_DESCRIPTION,
                PPU_CR_2_COMMENT)
    define_item(PPU_SR_ADDRESS, PPU_SR_SIZE, PPU_SR_SHORT_DESCRIPTION,
                PPU_SR_COMMENT)

    define_item(SPR_RAM_AR_ADDRESS, SPR_RAM_AR_SIZE,
                SPR_RAM_AR_SHORT_DESCRIPTION, SPR_RAM_AR_COMMENT)
    define_item(SPR_RAM_IOR_ADDRESS, SPR_RAM_IOR_SIZE,
                SPR_RAM_IOR_SHORT_DESCRIPTION, SPR_RAM_IOR_COMMENT)

    define_item(VRAM_AR_1_ADDRESS, VRAM_AR_1_SIZE, VRAM_AR_1_SHORT_DESCRIPTION,
                VRAM_AR_1_COMMENT)
    define_item(VRAM_AR_2_ADDRESS, VRAM_AR_2_SIZE, VRAM_AR_2_SHORT_DESCRIPTION,
                VRAM_AR_2_COMMENT)
    define_item(VRAM_IOR_ADDRESS, VRAM_IOR_SIZE, VRAM_IOR_SHORT_DESCRIPTION,
                VRAM_IOR_COMMENT)

    define_item(PAPU_PULSE_1_CR_ADDRESS, PAPU_PULSE_1_CR_SIZE,
                PAPU_PULSE_1_CR_SHORT_DESCRIPTION, PAPU_PULSE_1_CR_COMMENT)
    define_item(PAPU_PULSE_1_RCR_ADDRESS, PAPU_PULSE_1_RCR_SIZE,
                PAPU_PULSE_1_RCR_SHORT_DESCRIPTION, PAPU_PULSE_1_RCR_COMMENT)
    define_item(PAPU_PULSE_1_FTR_ADDRESS, PAPU_PULSE_1_FTR_SIZE,
                PAPU_PULSE_1_FTR_SHORT_DESCRIPTION, PAPU_PULSE_1_FTR_COMMENT)
    define_item(PAPU_PULSE_1_CTR_ADDRESS, PAPU_PULSE_1_CTR_SIZE,
                PAPU_PULSE_1_CTR_SHORT_DESCRIPTION, PAPU_PULSE_1_CTR_COMMENT)

    define_item(PAPU_PULSE_2_CR_ADDRESS, PAPU_PULSE_2_CR_SIZE,
                PAPU_PULSE_2_CR_SHORT_DESCRIPTION, PAPU_PULSE_2_CR_COMMENT)
    define_item(PAPU_PULSE_2_RCR_ADDRESS, PAPU_PULSE_2_RCR_SIZE,
                PAPU_PULSE_2_RCR_SHORT_DESCRIPTION, PAPU_PULSE_2_RCR_COMMENT)
    define_item(PAPU_PULSE_2_FTR_ADDRESS, PAPU_PULSE_2_FTR_SIZE,
                PAPU_PULSE_2_FTR_SHORT_DESCRIPTION, PAPU_PULSE_2_FTR_COMMENT)
    define_item(PAPU_PULSE_2_CTR_ADDRESS, PAPU_PULSE_2_CTR_SIZE,
                PAPU_PULSE_2_CTR_SHORT_DESCRIPTION, PAPU_PULSE_2_CTR_COMMENT)

    define_item(PAPU_TRIANGLE_CR_1_ADDRESS, PAPU_TRIANGLE_CR_1_SIZE,
                PAPU_TRIANGLE_CR_1_SHORT_DESCRIPTION,
                PAPU_TRIANGLE_CR_1_COMMENT)
    define_item(PAPU_TRIANGLE_CR_2_ADDRESS, PAPU_TRIANGLE_CR_2_SIZE,
                PAPU_TRIANGLE_CR_2_SHORT_DESCRIPTION,
                PAPU_TRIANGLE_CR_2_COMMENT)
    define_item(PAPU_TRIANGLE_FR_1_ADDRESS, PAPU_TRIANGLE_FR_1_SIZE,
                PAPU_TRIANGLE_FR_1_SHORT_DESCRIPTION,
                PAPU_TRIANGLE_FR_1_COMMENT)
    define_item(PAPU_TRIANGLE_FR_2_ADDRESS, PAPU_TRIANGLE_FR_2_SIZE,
                PAPU_TRIANGLE_FR_2_SHORT_DESCRIPTION,
                PAPU_TRIANGLE_FR_2_COMMENT)

    define_item(PAPU_NOISE_CR_1_ADDRESS, PAPU_NOISE_CR_1_SIZE,
                PAPU_NOISE_CR_1_SHORT_DESCRIPTION, PAPU_NOISE_CR_1_COMMENT)
    define_item(PAPU_NOISE_CR_2_ADDRESS, PAPU_NOISE_CR_2_SIZE,
                PAPU_NOISE_CR_2_SHORT_DESCRIPTION, PAPU_NOISE_CR_2_COMMENT)
    define_item(PAPU_NOISE_FR_1_ADDRESS, PAPU_NOISE_FR_1_SIZE,
                PAPU_NOISE_FR_1_SHORT_DESCRIPTION, PAPU_NOISE_FR_1_COMMENT)
    define_item(PAPU_NOISE_FR_2_ADDRESS, PAPU_NOISE_FR_2_SIZE,
                PAPU_NOISE_FR_2_SHORT_DESCRIPTION, PAPU_NOISE_FR_2_COMMENT)

    define_item(PAPU_DM_CR_ADDRESS, PAPU_DM_CR_SIZE,
                PAPU_DM_CR_SHORT_DESCRIPTION, PAPU_DM_CR_COMMENT)
    define_item(PAPU_DM_DAR_ADDRESS, PAPU_DM_DAR_SIZE,
                PAPU_DM_DAR_SHORT_DESCRIPTION, PAPU_DM_DAR_COMMENT)
    define_item(PAPU_DM_AR_ADDRESS, PAPU_DM_AR_SIZE,
                PAPU_DM_AR_SHORT_DESCRIPTION, PAPU_DM_AR_COMMENT)
    define_item(PAPU_DM_DLR_ADDRESS, PAPU_DM_DLR_SIZE,
                PAPU_DM_DLR_SHORT_DESCRIPTION, PAPU_DM_DLR_COMMENT)

    define_item(PAPU_SV_CSR_ADDRESS, PAPU_SV_CSR_SIZE,
                PAPU_SV_CSR_SHORT_DESCRIPTION, PAPU_SV_CSR_COMMENT)

    define_item(SPRITE_DMAR_ADDRESS, SPRITE_DMAR_SIZE,
                SPRITE_DMAR_SHORT_DESCRIPTION, SPRITE_DMAR_COMMENT)

    define_item(JOYPAD_1_ADDRESS, JOYPAD_1_SIZE, JOYPAD_1_SHORT_DESCRIPTION,
                JOYPAD_1_COMMENT)
    define_item(JOYPAD_2_ADDRESS, JOYPAD_2_SIZE, JOYPAD_2_SHORT_DESCRIPTION,
                JOYPAD_2_COMMENT)