//------------------------------------------------------------------------ static void describe_all(DatabaseHdrType &h) { create_filename_cmt(); add_pgm_cmt("Version : %04X",h.version); add_pgm_cmt("DatabaseType: %4.4s",(char*)&h.type); add_pgm_cmt("\n appl \"%s\", '%4.4s'", h.name, (char*)&h.id); }
//----------------------------------------------------------------------------- // write comments. static void mas_write_comments(void) { create_filename_cmt(); char entry_point_str[20]; if (entry_point == -1) qstrncpy(entry_point_str, "NOT DETECTED", sizeof(entry_point_str)); else qsnprintf(entry_point_str, sizeof entry_point_str, "0x%X", entry_point); // write name of the creator program add_pgm_cmt("Creator program : %s", creator); // write address of the entry point add_pgm_cmt("Entry point : %s", entry_point_str); }
//-------------------------------------------------------------------------- static void describe_app(const GEOSappheader &ah, const uint32 *segea) { char buf[MAXSTR]; char *end = buf + sizeof(buf); char *ptr = buf + qsnprintf(buf, sizeof(buf), "Pgm attrs :"); if ( ah.attr & GA_PROCESS ) APPEND(ptr, end, " GA_PROCESS"); if ( ah.attr & GA_LIBRARY ) APPEND(ptr, end, " GA_LIBRARY"); if ( ah.attr & GA_DRIVER ) APPEND(ptr, end, " GA_DRIVER"); if ( ah.attr & GA_KEEP_FILE_OPEN ) APPEND(ptr, end, " GA_KEEP_FILE_OPEN"); if ( ah.attr & GA_SYSTEM ) APPEND(ptr, end, " GA_SYSTEM"); if ( ah.attr & GA_MULTI_LAUNCHABLE ) APPEND(ptr, end, " GA_MULTI_LAUNCHABLE"); if ( ah.attr & GA_APPLICATION ) APPEND(ptr, end, " GA_APPLICATION"); if ( ah.attr & GA_DRIVER_INITIALIZED ) APPEND(ptr, end, " GA_DRIVER_INITIALIZED"); if ( ah.attr & GA_LIBRARY_INITIALIZED ) APPEND(ptr, end, " GA_LIBRARY_INITIALIZED"); if ( ah.attr & GA_GEODE_INITIALIZED ) APPEND(ptr, end, " GA_GEODE_INITIALIZED"); if ( ah.attr & GA_USES_COPROC ) APPEND(ptr, end, " GA_USES_COPROC"); if ( ah.attr & GA_REQUIRES_COPROC ) APPEND(ptr, end, " GA_REQUIRES_COPROC"); if ( ah.attr & GA_HAS_GENERAL_CONSUMER_MODE ) APPEND(ptr, end, " GA_HAS_GENERAL_CONSUMER_MODE"); if ( ah.attr & GA_ENTRY_POINTS_IN_C ) APPEND(ptr, end, " GA_ENTRY_POINTS_IN_C"); add_pgm_cmt("%s", buf); if ( ah.attr & GA_PROCESS) { ea_t entry = get_segea(ah, segea, ah.classptr_seg) + ah.classptr_ofs; set_name(entry, "ProcessClass", SN_NOWARN); declare_class(entry, "ProcessClass"); // inf.start_cs = get_segea(ah,segea,ah.classptr_seg) >> 4; // inf.startIP = ah.classptr_ofs; entry = get_segea(ah, segea, ah.tokenres_seg) + ah.tokenres_item; set_name(entry, "ApplicationObject"); add_pgm_cmt("ProcessClass: %d:%04X", ah.classptr_seg, ah.classptr_ofs); add_pgm_cmt("App object : %d:%04X", ah.tokenres_seg, ah.tokenres_item); } if ( ah.attr & GA_LIBRARY && ah.initseg != 0 ) { inf.start_cs = get_segea(ah, segea, ah.initseg) >> 4; inf.startIP = ah.initofs; add_pgm_cmt("Library init: %d:%04X", ah.initseg, ah.initofs); }
//----------------------------------------------------------------------- static void read_fixup(linput_t *li) { fixup fix; const int size = offsetof(fixup, fixups); lread(li, &fix, size); uint32 fptr = qltell(li); ea_t sea = getsea(fix.where_IN); if ( sea != BADADDR ) { uchar *b = qnewarray(uchar, fix.length); if ( b == NULL ) nomem("read_fixup"); lread(li, b, fix.length); // show_hex(b, fix.length, "\nFIXUP SEG %04X, %04X BYTES, KIND %02X\n", // fix.where_IN, // fix.length, // b[0]); const uchar *ptr = b; const uchar *end = b + fix.length; while ( ptr < end ) { fixup_data_t fd; uint32 where_offset = 0; uint32 what_offset = 0; ushort what_in = 9; bool selfrel = false; bool isfar = false; fd.type = FIXUP_OFF32; switch ( *ptr++ ) { case 0x2C: // GEN isfar = true; ask_for_feedback("Untested relocation type"); case 0x24: // GEN where_offset = readdw(ptr, false); what_offset = readdw(ptr, false); what_in = (ushort)readdw(ptr, false); break; case 0x2D: isfar = true; case 0x25: // INTRA where_offset = readdw(ptr, false); what_offset = readdw(ptr, false); what_in = fix.where_IN; break; case 0x2A: // CALL where_offset = readdw(ptr, false); what_offset = 0; what_in = (ushort)readdw(ptr, false); selfrel = true; break; case 0x2E: // OFF32? isfar = true; case 0x26: where_offset = readdw(ptr, false); what_offset = 0; what_in = (ushort)readdw(ptr, false); break; default: ask_for_feedback("Unknown relocation type %02X", ptr[-1]); add_pgm_cmt("!!! Unknown relocation type %02X", ptr[-1]); break; } ea_t source = sea + where_offset; ea_t target = BADADDR; switch ( what_in >> 12 ) { case 0x02: // segments target = getsea(what_in); break; case 0x06: // externs target = xea + 4 * ((what_in & 0xFFF) - 1); fd.type |= FIXUP_EXTDEF; break; default: ask_for_feedback("Unknown relocation target %04X", what_in); add_pgm_cmt("!!! Unknown relocation target %04X", what_in); break; } segment_t *ts = getseg(target); fd.sel = ts ? (ushort)ts->sel : 0; if ( (fd.type & FIXUP_EXTDEF) == 0 ) { target += what_offset; what_offset = 0; } fd.off = target; fd.displacement = what_offset; target += what_offset; if ( selfrel ) { fd.type |= FIXUP_SELFREL; target -= source + 4; } set_fixup(source, &fd); put_long(source, target); if ( isfar ) { fd.type = FIXUP_SEG16; set_fixup(source+4, &fd); put_word(source+4, fd.sel); } } qfree(b); }
//-------------------------------------------------------------------------- // Process debugging information item and try to incorporate it into // the database. // NOTE: This function does not process all debugging information. // It knows only about some types of debugingo. static size_t process_item(uchar *di, size_t disize, section_t *sect) { uchar *const end = di + disize; uint32 fw = *(uint32 *)di; if ( mf ) fw = swap32(fw); size_t len = fw >> 16; if ( len == 0 || len > disize ) return 0; switch ( fw & 0xFFFF ) { case AIF_DEB_SECT: // section if ( disize < sizeof(section_t) ) return 0; sect = (section_t *)di; if ( mf ) swap_section(sect); if ( sect->debugsize != 0 ) len = sect->debugsize; switch ( sect->lang ) { case LANG_C: add_long_cmt(sect->codestart,1,"C source level debugging data is present"); break; case LANG_PASCAL: add_long_cmt(sect->codestart,1,"Pascal source level debugging data is present"); break; case LANG_FORTRAN: add_long_cmt(sect->codestart,1,"Fortran-77 source level debugging data is present"); break; case LANG_ASM: add_long_cmt(sect->codestart,1,"ARM assembler line number data is present"); break; } if ( sect->lang == LANG_NONE ) { size_t nsyms = size_t(sect->name); dsym_t *ds = (dsym_t *)(sect+1); char *str = (char *)(ds+nsyms); if ( str >= (char *)end ) return 0; bool use_pascal = swap_symbols(ds, str, end, nsyms); for ( int i=0; i < nsyms; i++,ds++ ) { if ( ds->sym & ASD_16BITSYM ) continue; size_t off = size_t(ds->sym & ASD_SYMOFF); char *name = str + off + use_pascal; if ( name < str || name >= (char *)end ) continue; if ( special_name(name) ) continue; if ( ds->sym & ASD_ABSSYM ) // if the symbol is absolute { add_pgm_cmt("%s = 0x%X", name, ds->value); } else if ( isEnabled(ds->value) ) { if ( ds->sym & ASD_GLOBSYM ) { add_entry(ds->value, ds->value, name, is_true_text_symbol(ds, name)); } else { do_name_anyway(ds->value, name); if ( is_true_text_symbol(ds, name) ) auto_make_code(ds->value); } } } } else { char name[64]; const uchar *nptr = (const uchar *)§->name; size_t namelen = *nptr++; namelen = qmin(namelen, sizeof(name) - 1); namelen = qmin(namelen, end - nptr); memcpy(name, nptr, namelen); //lint !e670 name[namelen] = '\0'; if ( sect->codestart != 0 ) add_long_cmt(sect->codestart,1,"Section \"%s\", size 0x%X",name,sect->codesize); if ( sect->datastart != 0 ) add_long_cmt(sect->datastart,1,"Section \"%s\", size 0x%X",name,sect->datasize); } #if 0 if ( sect->fileinfo != 0 ) { // fileinfo is present? process_item(di+size_t(sect->fileinfo),sect); } #endif break; case AIF_DEB_FDEF: // procedure/function definition deb(IDA_DEBUG_LDR, "procedure/function definition\n"); break; case AIF_DEB_ENDP: // endproc deb(IDA_DEBUG_LDR, "endproc\n"); break; case AIF_DEB_VAR: // variable deb(IDA_DEBUG_LDR, "variable\n"); break; case AIF_DEB_TYPE: // type deb(IDA_DEBUG_LDR, "type\n"); break; case AIF_DEB_STRU: // struct deb(IDA_DEBUG_LDR, "struct\n"); break; case AIF_DEB_ARRAY: // array deb(IDA_DEBUG_LDR, "array\n"); break; case AIF_DEB_RANGE: // subrange deb(IDA_DEBUG_LDR, "subrange\n"); break; case AIF_DEB_SET: // set deb(IDA_DEBUG_LDR, "set\n"); break; case AIF_DEB_FILE: // fileinfo deb(IDA_DEBUG_LDR, "fileinfo\n"); break; case AIF_DEB_CENUM: // contiguous enumeration deb(IDA_DEBUG_LDR, "contiguous enumeration\n"); break; case AIF_DEB_DENUM: // discontiguous enumeration deb(IDA_DEBUG_LDR, "discontiguous enumeration\n"); break; case AIF_DEB_FDCL: // procedure/function declaration deb(IDA_DEBUG_LDR, "procedure/function declaration\n"); break; case AIF_DEB_SCOPE: // begin naming scope deb(IDA_DEBUG_LDR, "begin naming scope\n"); break; case AIF_DEB_ENDS: // end naming scope deb(IDA_DEBUG_LDR, "end naming scope\n"); break; case AIF_DEB_BITF: // bitfield deb(IDA_DEBUG_LDR, "bitfield\n"); break; case AIF_DEB_MACRO: // macro definition deb(IDA_DEBUG_LDR, "macro definition\n"); break; case AIF_DEB_ENDM: // macro undefinition deb(IDA_DEBUG_LDR, "macro undefinition\n"); break; case AIF_DEB_CLASS: // class deb(IDA_DEBUG_LDR, "class\n"); break; case AIF_DEB_UNION: // union deb(IDA_DEBUG_LDR, "union\n"); break; case AIF_DEB_FPMAP: // FP map fragment deb(IDA_DEBUG_LDR, "FP map fragment\n"); break; default: msg("unknown (0x%d.)!!!\n", fw & 0xFFFF); break; } return len; }