update to ida 7.6, add builds

This commit is contained in:
2021-10-31 21:20:46 +02:00
parent e0e0f2be99
commit b1809fe2d9
1408 changed files with 279193 additions and 302468 deletions

View File

@@ -0,0 +1,69 @@
//--------------------------------------------------------------------------
static char *token2str(char *buf, size_t bufsize, GEOStoken &t)
{
if ( t.str[0] )
qsnprintf(buf, bufsize, "%4.4s/%u", t.str, t.num);
else
qstrncpy(buf, "-", bufsize);
return buf;
}
//--------------------------------------------------------------------------
static const unsigned char _GeosXlate[] =
{
0x8E, 0x8F, 0x80, 0x90, 0xA5, 0x99, 0x9A, 0xA0,
0x85, 0x83, 0x84, 0x20, 0x86, 0x87, 0x82, 0x8A,
0x88, 0x89, 0xA1, 0x8D, 0x8C, 0x8B, 0xA4, 0xA2,
0x95, 0x93, 0x94, 0x20, 0xA3, 0x97, 0x96, 0x81,
0x20, 0xF8, 0x9B, 0x9C, 0x15, 0xF9, 0x14, 0xE1,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x92, 0x20,
0xEC, 0xF1, 0xF3, 0xF2, 0x9D, 0xE6, 0xEB, 0xE4,
0x20, 0x20, 0xF4, 0xA6, 0xA7, 0xEA, 0x91, 0xED,
0xA8, 0xAD, 0xAA, 0xFB, 0x9F, 0xF7, 0x20, 0xAE,
0xAF, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xF6, 0x04,
0x98, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20
};
static const unsigned char _GeosXlapp[] =
{
0x8E, 0x8F, 0x80, 0x90, 0xA5, 0x99, 0x9A, 0xA0,
0x85, 0x83, 0x84, 0x61, 0x86, 0x87, 0x82, 0x8A,
0x88, 0x89, 0xA1, 0x8D, 0x8C, 0x8B, 0xA4, 0xA2,
0x95, 0x93, 0x94, 0x6F, 0xA3, 0x97, 0x96, 0x81,
0x2B, 0xF8, 0x9B, 0x9C, 0x15, 0xF9, 0x14, 0xE1,
0x52, 0x43, 0x7E, 0x27, 0x22, 0xD8, 0x92, 0x30,
0xEC, 0xF1, 0xF3, 0xF2, 0x9D, 0xE6, 0xEB, 0xE4,
0xE3, 0xE3, 0xF4, 0xA6, 0xA7, 0xEA, 0x91, 0xED,
0xA8, 0xAD, 0xAA, 0xFB, 0x9F, 0xF7, 0x1E, 0xAE,
0xAF, 0x5F, 0x20, 0x41, 0x41, 0x4F, 0x99, 0x94,
0x2D, 0xC4, 0x22, 0x22, 0x60, 0x27, 0xF6, 0x04,
0x98, 0x59, 0x2F, 0xE8, 0x3C, 0x3E, 0x79, 0x59,
0x2B, 0xFA, 0x2C, 0x22, 0x70, 0x41, 0x45, 0x41,
0x45, 0x45, 0x49, 0x49, 0x49, 0x49, 0x4F, 0x4F,
0x20, 0x4F, 0x55, 0x55, 0x55, 0x2C, 0x5E, 0x7E,
0x2D, 0x60, 0xF8, 0xF8, 0x2C, 0x22, 0x2C, 0x27
};
static char *geos2ibm(char *out, char *in, size_t insize)
{
char *saved = out;
for ( int i=0; i < insize; i++ )
{
uchar c = *in++;
if ( !c )
break;
if ( c & 0x80 )
c = _GeosXlapp[c & 0x7F];
*out++ = c;
}
*out = '\0';
return saved;
}

795
idasdk76/ldr/geos/geos.cpp Normal file
View File

@@ -0,0 +1,795 @@
/*
* Interactive disassembler (IDA).
* Copyright (c) 1990-2000 by Ilfak Guilfanov.
* ALL RIGHTS RESERVED.
* E-mail: ig@datarescue.com
*
*/
#include "../idaldr.h"
#include "geos2.h"
#include "common.cpp"
#include <struct.hpp>
#include <enum.hpp>
#include <typeinf.hpp>
//--------------------------------------------------------------------------
static int create_seg(
ea_t base,
ea_t start,
ea_t end,
const char *name,
const char *sclass)
{
if ( start != BADADDR && end < start )
return 0;
segment_t s;
s.sel = setup_selector(base);
s.start_ea = start;
s.end_ea = end;
s.align = saRelByte;
s.comb = (sclass != NULL && strcmp(sclass,"STACK") == 0) ? scStack : scPub;
s.bitness = 0;
return add_segm_ex(&s, name, sclass, ADDSEG_NOSREG|ADDSEG_SPARSE);
}
//--------------------------------------------------------------------------
static int idaapi accept_file(
qstring *fileformatname,
qstring *processor,
linput_t *li,
const char *)
{
union
{
GEOSheader h1;
GEOS2header h2;
} h;
qlseek(li, 0);
if ( qlread(li, &h, sizeof(h)) != sizeof(h) )
return 0;
qoff64_t apppos;
int version;
if ( h.h1.ID == GEOS_ID && h.h1.fclass == 0 )
{
apppos = 0xC8;
version = 1;
}
else if ( h.h2.ID == GEOS2_ID && h.h2.fclass == 1 )
{
apppos = sizeof(GEOS2header);
version = 2;
}
else
{
return 0;
}
GEOSappheader ah;
qlseek(li, apppos, SEEK_SET);
if ( qlread(li, &ah, sizeof(ah)) != sizeof(ah) )
return 0;
const char *stype;
switch ( ah.type )
{
case 1: stype = "Application"; break;
case 2: stype = "Library"; break;
case 3: stype = "Driver"; break;
default: stype = "Unknown type";break;
}
fileformatname->sprnt("GEOS%d %s", version, stype);
*processor = "metapc";
return 1;
}
//--------------------------------------------------------------------------
static ea_t get_segea(const GEOSappheader &ah, const uint32 *segea, uint16 s)
{
if ( s >= ah.numseg )
{
ask_for_feedback("Bad segment number %d", s);
return BADADDR;
}
return segea[s] == uint32(BADADDR) ? BADADDR : segea[s];
}
//--------------------------------------------------------------------------
static netnode get_node(const GEOSappheader &ah, const netnode *modnode, uint16 libn)
{
if ( libn >= ah.numlib )
{
ask_for_feedback("Bad library number %d", libn);
return BADNODE;
}
return modnode[libn];
}
//--------------------------------------------------------------------------
static tid_t get_class_struct_flags_enum()
{
static const char enum_name[] = "ClassFlags";
enum_t id = get_enum(enum_name);
if ( id != BADNODE )
return id;
id = add_enum(-1, enum_name, hex_flag());
set_enum_bf(id, true);
add_enum_member(id, "CLASSF_HAS_DEFAULT", (1<<0), (1<<0));
add_enum_member(id, "CLASSF_MASTER_CLASS", (1<<1), (1<<1));
add_enum_member(id, "CLASSF_VARIANT_CLASS", (1<<2), (1<<2));
add_enum_member(id, "CLASSF_DISCARD_ON_SAVE", (1<<3), (1<<3));
add_enum_member(id, "CLASSF_NEVER_SAVED", (1<<4), (1<<4));
add_enum_member(id, "CLASSF_HAS_RELOC", (1<<5), (1<<5));
add_enum_member(id, "CLASSF_C_HANDLERS", (1<<6), (1<<6));
return id;
}
//--------------------------------------------------------------------------
#if 0
static void declare_parameter_types(ea_t ea, int count)
{
static const char class_name[] = "CMethodDef";
struc_t *sptr = get_struc(get_struc_id(class_name));
if ( sptr == NULL )
{
sptr = get_struc(add_struc(-1, class_name));
if ( sptr == NULL )
return;
add_struc_member(sptr, "methodParameterDef", -1, word_flag(), NULL, 2);
add_struc_member(sptr, "handlerTypeDef", -1, byte_flag(), NULL, 1);
}
size_t size = get_struc_size(sptr);
create_struct(ea, size*count, sptr->id);
}
#endif
//--------------------------------------------------------------------------
static void declare_class(ea_t ea, const char *entryname)
{
static const char class_name[] = "ClassStruct";
struc_t *sptr = get_struc(get_struc_id(class_name));
if ( sptr == NULL )
{
sptr = get_struc(add_struc(BADADDR, class_name));
if ( sptr == NULL )
return;
opinfo_t mt;
mt.ri.flags = REF_OFF32;
mt.ri.target = BADADDR;
mt.ri.base = 0;
mt.ri.tdelta = 0;
add_struc_member(sptr, "superClass", BADADDR, off_flag()|dword_flag(), &mt, 4);
add_struc_member(sptr, "masterOffset", BADADDR, word_flag(), NULL, 2);
add_struc_member(sptr, "methodCount", BADADDR, dec_flag()|word_flag(), NULL, 2);
add_struc_member(sptr, "instanceSize", BADADDR, dec_flag()|word_flag(), NULL, 2);
add_struc_member(sptr, "vdRelocTable", BADADDR, word_flag(), NULL, 2);
add_struc_member(sptr, "relocTable", BADADDR, word_flag(), NULL, 2);
mt.ec.tid = get_class_struct_flags_enum();
mt.ec.serial = 0;
add_struc_member(sptr, "flags", BADADDR, enum_flag()|byte_flag(), &mt, 1);
add_struc_member(sptr, "masterMethods",BADADDR, byte_flag(), NULL, 1);
}
asize_t size = get_struc_size(sptr);
create_struct(ea, size, sptr->id);
segment_t *s = getseg(ea);
if ( s == NULL )
return;
int count = get_word(ea+6);
// bool c_handlers = get_byte(ea+14) & (1<<6);
ea += size;
if ( ea+2*count >= s->end_ea )
return;
ea_t messages = ea;
create_word(ea, count*2);
op_dec(ea, 0);
ea += 2*count;
if ( ea+4*count > s->end_ea )
return;
create_dword(ea, count*4);
op_plain_offset(ea, 0, 0);
for ( int i=0; i < count; i++ )
{
ea_t idx = ea + 4*i;
ea_t pea = to_ea(get_word(idx+2), get_word(idx));
auto_make_proc(pea);
char name[MAXSTR];
qsnprintf(name, sizeof(name), "%s_%u", entryname, get_word(messages+2*i));
add_entry(pea, pea, name, true, AEF_IDBENC);
}
// commented out because it doesn't work properly
// see geoplan.geo, entry number 1 for example
// if ( c_handlers )
// declare_parameter_types(ea+count*4, count);
}
//--------------------------------------------------------------------------
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_NOCHECK|SN_NOWARN);
declare_class(entry, "ProcessClass");
// inf_set_start_cs(get_segea(ah,segea,ah.classptr_seg) >> 4);
// inf_set_start_ip (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_set_start_cs(get_segea(ah, segea, ah.initseg) >> 4);
inf_set_start_ip(ah.initofs);
add_pgm_cmt("Library init: %d:%04X", ah.initseg, ah.initofs);
}
if ( ah.attr & GA_DRIVER && ah.startseg != 0 )
{
ea_t entry = get_segea(ah, segea, ah.startseg) + ah.startofs;
set_name(entry, "DriverTable");
// inf_set_start_cs(get_segea(ah, segea, ah.startseg) >> 4);
// inf_set_start_ip (ah.startofs);
add_pgm_cmt("Driver Table: %d:%04X", ah.startseg, ah.startofs);
// add_jmplist(ah.startseg,ah.startofs,4,4);
// Add entry point as "jmplist"
}
}
//--------------------------------------------------------------------------
static void bad_lib_reloc(int i, uint16 off)
{
ask_for_feedback("Strange library relocation at %d:%04X", i, off);
}
//--------------------------------------------------------------------------
static void create_fixup(ea_t ea, fixup_data_t &fd, ea_t target)
{
segment_t *s = getseg(target);
if ( s != NULL )
{
fd.sel = s->sel;
fd.off = target - get_segm_base(s);
}
else
{
fd.sel = sel_t(target >> 4);
fd.off = target & 0xF;
}
fd.displacement = 0;
fd.set(ea);
if ( fd.get_type() == FIXUP_PTR16 )
{
put_word(ea, fd.off);
put_word(ea+2, fd.sel);
}
else if ( fd.get_type() == FIXUP_OFF16 )
{
put_word(ea, fd.off);
}
else // SEG16
{
put_word(ea, fd.sel);
}
}
//--------------------------------------------------------------------------
static void apply_relocations(
linput_t *li,
const GEOSappheader &ah,
const netnode *modnode,
const uint16 *seglen,
const int32 *segpos,
const uint16 *segfix,
const uint32 *segea)
{
// apply relocation information
for ( int i=0; i < ah.numseg; i++ )
{
if ( segfix[i] == 0 )
continue;
GEOSfixup *fix = (GEOSfixup *)qalloc(segfix[i]);
if ( fix == NULL )
nomem("fix");
qlseek(li, segpos[i]+((seglen[i]+0xF)&~0xF));
lread(li, fix, segfix[i]);
int n = segfix[i]/sizeof(GEOSfixup);
sel_t oldsel = BADSEL;
sel_t oldoff = BADSEL;
ea_t oldea = BADADDR;
for ( int j=0; j < n; j++ )
{
ea_t ea = get_segea(ah, segea, (uint16)i) + fix[j].ofs;
int ftype = fix[j].type & 0xF0;
if ( ftype != 0x10 && ftype != 0x20 )
ask_for_feedback("Unknown fixup type %02X", ftype);
netnode libnode = BADNODE;
if ( ftype == 0x10 )
libnode = get_node(ah, modnode, fix[j].type>>8);
uint16 w1 = get_word(ea);
ea_t target = BADADDR;
fixup_data_t fd(FIXUP_SEG16);
switch ( fix[j].type & 0x0F )
{
case 0x0: case 0x4:
fd.set_type_and_flags(FIXUP_PTR16);
if ( ftype == 0x20 ) // program
target = get_segea(ah, segea, w1) + get_word(ea+2);
else // library
{
target = node2ea(libnode.altval(w1+1));
fd.set_extdef();
}
break;
case 0x1: // off
if ( ftype == 0x20 ) // program
{
ask_for_feedback("Program offset relocation encountered");
continue;
}
oldoff = w1;
if ( oldsel != BADSEL )
{
LIB_PTR:
target = node2ea(libnode.altval(oldoff+1));
if ( oldea == ea+2 )
{
fd.set_type_and_flags(FIXUP_PTR16, FIXUPF_EXTDEF);
}
else
{
fd.set_type_and_flags(FIXUP_SEG16, FIXUPF_EXTDEF);
create_fixup(oldea, fd, target);
fd.set_type_and_flags(FIXUP_OFF16, FIXUPF_EXTDEF);
}
oldsel = BADSEL;
oldoff = BADSEL;
oldea = BADSEL;
break;
}
oldea = ea;
continue;
case 0x2: case 0x3:
if ( ftype == 0x20 ) // program
target = get_segea(ah, segea, w1);
else
{
oldsel = w1;
if ( oldoff != BADSEL )
{
ea_t tmp = ea;
ea = oldea;
oldea = tmp;
goto LIB_PTR;
}
oldea = ea;
continue;
}
break;
default:
ask_for_feedback("Unknown relocation type %02X", fix[j].type);
}
create_fixup(ea, fd, target);
}
qfree(fix);
}
}
//--------------------------------------------------------------------------
static void find_imports_in_relocations(
linput_t *li,
const GEOSappheader &ah,
const netnode *modnode,
const uint16 *seglen,
const int32 *segpos,
const uint16 *segfix)
{
for ( int i=0; i < ah.numseg; i++ )
{
if ( segfix[i] == 0 )
continue;
GEOSfixup *fix = (GEOSfixup *)qalloc(segfix[i]);
if ( fix == NULL )
nomem("fix");
qlseek(li, segpos[i]+((seglen[i]+0xF)&~0xF));
lread(li, fix, segfix[i]);
// i don't understand why this should be done
// besides, if we uncomment it, the library fixups are
// not handled properly
// if ( fix[0].ofs == 0 )
// fix[0].ofs = 0xFFFF;
int num = segfix[i]/sizeof(GEOSfixup);
sel_t oldseg = BADSEL;
sel_t oldoff = BADSEL;
sel_t oldlib = BADSEL;
for ( int j=0; j < num; j++ )
{
if ( fix[j].ofs == 0xFFFF )
continue;
if ( (fix[j].type & 0xF0) != 0x10 )
continue; // only library!
int libn = fix[j].type>>8;
if ( libn >= ah.numlib )
{
ask_for_feedback("Illegal library number in relocations");
continue;
}
netnode n = modnode[libn];
uint16 ofs = fix[j].ofs;
qlseek(li, segpos[i]+ofs);
uint16 w1;
lread(li, &w1, sizeof(w1));
switch ( fix[j].type & 0x0F )
{
case 0x0: case 0x4: // exported entry
n.altset(w1+1, 1);
oldseg = BADSEL;
oldoff = BADSEL;
oldlib = BADSEL;
break;
case 0x1: // off
if ( oldseg != BADSEL )
{
if ( libn != oldlib || oldseg != w1 )
bad_lib_reloc(i, ofs);
n.altset(w1+1, 1);
oldseg = BADSEL;
break;
}
oldoff = w1;
oldlib = libn;
break;
case 0x2: case 0x3: // seg #
if ( oldoff != BADSEL )
{
if ( libn != oldlib || oldoff != w1 )
bad_lib_reloc(i, ofs);
n.altset(w1+1, 1);
oldoff = BADSEL;
break;
}
oldseg = w1;
oldlib = libn;
break;
default:
ask_for_feedback("Unknown relocation type %02X", fix[j].type);
}
}
if ( oldseg != BADSEL && oldoff != BADSEL )
ask_for_feedback("Some library relocations are strange");
qfree(fix);
}
}
//--------------------------------------------------------------------------
static void create_extern_segments(
const GEOSappheader &ah,
const GEOSliblist *lib,
const netnode *modnode)
{
inf_set_specsegs(inf_is_64bit() ? 8 : 4);
for ( int i=0; i < ah.numlib; i++ )
{
char libname[8+1];
qstrncpy(libname, lib[i].name, sizeof(libname));
trim(libname);
netnode n = modnode[i];
uval_t x;
int nimps = 0;
for ( x=n.altfirst(); x != BADNODE; x=n.altnext(x) )
nimps++;
if ( nimps == 0 )
continue;
ea_t ea = free_chunk(inf_get_max_ea(), nimps*4, -15);
ea_t end = ea + nimps*4;
create_seg(ea>>4, ea, end, libname, "XTRN");
for ( x=n.altfirst(); x != BADNODE; x=n.altnext(x),ea+=4 )
{
char buf[MAXSTR];
qsnprintf(buf, sizeof(buf), "%s_%u", libname, uint16(x)-1);
put_dword(ea, 0xCB);
create_insn(ea);
force_name(ea, buf, SN_IDBENC);
nodeidx_t ndx = ea2node(ea);
n.altset(x, ndx);
}
import_module(libname, NULL /*windir*/, n, NULL, "geos");
}
}
//--------------------------------------------------------------------------
static void create_exports(
const GEOSappheader &ah,
const GEOSexplist *explist,
const uint32 *segea,
const char *modname)
{
int i;
netnode n;
n.create();
for ( i=0; i < ah.numexp; i++ )
{
ea_t ea = get_segea(ah, segea, explist[i].seg) + explist[i].ofs;
add_extra_cmt(ea, true, "Exported entry %d", i);
nodeidx_t ndx = ea2node(ea);
n.altset(i+1, ndx);
}
import_module(modname, NULL /*windir*/, n, NULL, "geos");
for ( i=0; i < ah.numexp; i++ )
{
ea_t ea = get_segea(ah, segea, explist[i].seg) + explist[i].ofs;
qstring name;
if ( get_name(&name, ea, GN_NOT_DUMMY) <= 0 )
name.sprnt("%s_%d", modname, i);
bool makecode = segtype(ea) == SEG_CODE;
add_entry(i, ea, name.begin(), makecode, AEF_IDBENC);
if ( !makecode )
declare_class(ea, name.begin());
}
}
//--------------------------------------------------------------------------
void load_application(linput_t *li, int32 fpos, int32 fdelta)
{
GEOSappheader ah;
qlseek(li, fpos);
lread(li, &ah, sizeof(ah));
// build our name
char modname[sizeof(ah.name)+1];
qstrncpy(modname, ah.name, sizeof(ah.name));
trim(modname);
// read in library information
GEOSliblist *lib = NULL;
netnode *modnode = NULL;
validate_array_count(li, &ah.numlib, sizeof(GEOSliblist), "The library count");
if ( ah.numlib != 0 )
{
lib = qalloc_array<GEOSliblist>(ah.numlib);
if ( lib == NULL )
nomem("libs");
lread(li, lib, ah.numlib*sizeof(GEOSliblist));
modnode = qalloc_array<netnode>(ah.numlib);
if ( modnode == NULL )
nomem("libnode");
for ( int i=0; i < ah.numlib; i++ )
{
char libname[8+1];
qstrncpy(libname, lib[i].name, sizeof(libname));
trim(libname);
char buf[20];
qsnprintf(buf, sizeof(buf), "$lib %.8s", libname);
modnode[i].create(buf);
}
}
// read in export information
GEOSexplist *explist = NULL;
validate_array_count(li, &ah.numexp, sizeof(GEOSexplist), "Number of exports");
if ( ah.numexp != 0 )
{
explist = qalloc_array<GEOSexplist>(ah.numexp);
if ( explist == NULL )
nomem("exp");
lread(li, explist, ah.numexp*sizeof(GEOSexplist));
}
// read in segment information
void *segd = NULL;
uint16 *seglen = NULL;
int32 *segpos = NULL;
uint16 *segfix = NULL;
uint16 *segflg;
sel_t ds_sel = BADSEL;
uint32 *segea = NULL;
validate_array_count(li, &ah.numseg, 14, "Number of segments");
if ( ah.numseg != 0 )
{
if ( !is_mul_ok<ushort>(ah.numseg, 14) )
NOMEM:
nomem("geos_segments");
segd = qalloc(ah.numseg*14);
if ( segd == NULL )
goto NOMEM;
lread(li, segd, ah.numseg*10);
seglen = (uint16 *)segd;
segpos = (int32 *)(seglen + ah.numseg);
segfix = (uint16 *)(segpos + ah.numseg);
segflg = (uint16 *)(segfix + ah.numseg);
segea = (uint32 *)(segflg + ah.numseg);
ea_t ea = to_ea(inf_get_baseaddr(), 0);
for ( int i=0; i < ah.numseg; i++ )
{
uint16 f = segflg[i];
segpos[i] += fdelta;
segea[i] = uint32(BADADDR);
if ( seglen[i] == 0 )
continue;
size_t bss_size = 0;
// if this is the data segment, increase its size by stacksize.
// i'm not aware of a reliable way to find it, so use heuristics
bool found_data_segment = false;
if ( ds_sel == BADSEL
&& (f & (HF_READ_ONLY|HF_SHARABLE|HF_CODE)) == 0
&& (f & HF_FIXED) != 0 )
{
found_data_segment = true;
bss_size = ah.stacksize;
}
ea = free_chunk(ea, bss_size + seglen[i], -15);
ea_t endea = ea + seglen[i] + bss_size;
if ( (f & HF_ZERO_INIT) == 0 )
file2base(li, segpos[i], ea, endea - bss_size, FILEREG_PATCHABLE);
create_seg(ea>>4, ea, endea, NULL, (f & HF_CODE) ? "CODE" : "DATA");
if ( found_data_segment )
ds_sel = find_selector(ea>>4);
char buf[MAXSTR];
char *end = buf + sizeof(buf);
char *ptr = buf + qsnprintf(buf, sizeof(buf), "Segm attrs :");
if ( f & HF_ZERO_INIT ) APPEND(ptr, end, " ZEROINIT");
if ( f & HF_LOCK ) APPEND(ptr, end, " LOCK");
if ( f & HF_NO_ERR ) APPEND(ptr, end, " NO_ERR");
if ( f & HF_UI ) APPEND(ptr, end, " UI");
if ( f & HF_READ_ONLY ) APPEND(ptr, end, " RONLY");
if ( f & HF_OBJECT_RESOURCE ) APPEND(ptr, end, " OBJ_RES");
if ( f & HF_CODE ) APPEND(ptr, end, " CODE");
if ( f & HF_CONFORMING ) APPEND(ptr, end, " CONFORMING");
if ( f & HF_FIXED ) APPEND(ptr, end, " FIXED");
if ( f & HF_SHARABLE ) APPEND(ptr, end, " SHARABLE");
if ( f & HF_DISCARDABLE ) APPEND(ptr, end, " DISCARDABLE");
if ( f & HF_SWAPABLE ) APPEND(ptr, end, " SWAPABLE");
if ( f & HF_LMEM ) APPEND(ptr, end, " LMEM");
if ( f & HF_DEBUG ) APPEND(ptr, end, " DEBUG");
if ( f & HF_DISCARDED ) APPEND(ptr, end, " DISCARDED");
if ( f & HF_SWAPPED ) APPEND(ptr, end, " SWAPPED");
add_extra_cmt(ea, true, "%s", buf);
segea[i] = (uint32)ea;
ea = endea;
}
}
find_imports_in_relocations(li, ah, modnode, seglen, segpos, segfix);
create_extern_segments(ah, lib, modnode);
set_default_dataseg(ds_sel);
if ( !qgetenv("IDA_NORELOC") )
apply_relocations(li, ah, modnode, seglen, segpos, segfix, segea);
create_exports(ah, explist, segea, modname);
describe_app(ah, segea);
qfree(lib);
qfree(modnode);
qfree(explist);
qfree(segd);
}
//--------------------------------------------------------------------------
static void show_geos1(GEOSheader &h)
{
char buf[MAXSTR];
add_pgm_cmt("Name : %s", geos2ibm(buf, h.name, sizeof(h.name)));
add_pgm_cmt("Token : %s", token2str(buf, sizeof(buf), h.token));
add_pgm_cmt("Creator : %s", token2str(buf, sizeof(buf), h.appl));
add_pgm_cmt("Release : %u.%u.%u.%u",
h.release.versmaj,
h.release.versmin,
h.release.revmaj,
h.release.revmin);
add_pgm_cmt("Protocol : %u.%03u",
h.protocol.vers,
h.protocol.rev);
add_pgm_cmt("Flags : %04X", h.flags);
add_pgm_cmt("User info : %s", geos2ibm(buf, h.info, sizeof(h.info)));
add_pgm_cmt("Copyright : %s", geos2ibm(buf, h._copyright, sizeof(h._copyright)));
}
//--------------------------------------------------------------------------
static void show_geos2(GEOS2header &h)
{
char buf[MAXSTR];
add_pgm_cmt("Name : %s", geos2ibm(buf, h.name, sizeof(h.name)));
add_pgm_cmt("Token : %s", token2str(buf, sizeof(buf), h.token));
add_pgm_cmt("Creator : %s", token2str(buf, sizeof(buf), h.appl));
add_pgm_cmt("Release : %u.%u.%u.%u",
h.release.versmaj,
h.release.versmin,
h.release.revmaj,
h.release.revmin);
add_pgm_cmt("Protocol : %u.%03u",
h.protocol.vers,
h.protocol.rev);
add_pgm_cmt("Flags : %04X", h.flags);
add_pgm_cmt("Password : %.*s", int(sizeof(h.password)), h.password);
add_pgm_cmt("User info : %s", geos2ibm(buf, h.info, sizeof(h.info)));
add_pgm_cmt("Copyright : %s", geos2ibm(buf, h._copyright, sizeof(h._copyright)));
}
//--------------------------------------------------------------------------
void idaapi load_file(linput_t *li, uint16 /*neflag*/, const char * /*fileformatname*/)
{
set_processor_type("metapc", SETPROC_LOADER);
union
{
GEOSheader h1;
GEOS2header h2;
} h;
qlseek(li, 0);
lread(li, &h, sizeof(h));
int32 apppos;
int32 fdelta;
if ( h.h1.ID == GEOS_ID )
{
apppos = 0xC8;
fdelta = 0;
}
else
{
apppos = sizeof(GEOS2header);
fdelta = apppos;
}
load_application(li, apppos, fdelta);
create_filename_cmt();
if ( h.h1.ID == GEOS_ID )
show_geos1(h.h1);
else
show_geos2(h.h2);
inf_set_cc_cm(inf_get_cc_cm() | C_PC_LARGE);
add_til("geos", ADDTIL_DEFAULT);
}
//--------------------------------------------------------------------------
loader_t LDSC =
{
IDP_INTERFACE_VERSION,
0, // loader flags
//
// check input file format. if recognized, then return 1
// and fill 'fileformatname'.
// otherwise return 0
//
accept_file,
//
// load file into the database.
//
load_file,
//
// create output file from the database.
// this function may be absent.
//
NULL,
// take care of a moved segment (fix up relocations, for example)
NULL,
NULL,
};

173
idasdk76/ldr/geos/geos.h Normal file
View File

@@ -0,0 +1,173 @@
/*
GEOS.H
by Marcus Groeber 1992-95
Include file for the PC/GEOS file format
20.06.00: Modified by Ilfak Guilfanov <ig@datarescue.com>
*/
#if !defined(_GEOS_H)
#define _GEOS_H
#pragma pack(push, 1)
#define GEOS_TOKENLEN 4
struct GEOStoken
{ /*** ID for file types/icons */
char str[GEOS_TOKENLEN]; // 4 byte string
ushort num; // additional id number (?)
};
struct GEOSprotocol
{ /*** Protocol/version number */
ushort vers; // protocol
ushort rev; // sub revision
};
struct GEOSrelease
{ /*** "Release" */
ushort versmaj,versmin; // "release" x.y
ushort revmaj,revmin; // value "a-b" behind "release"
};
/******************************************************************************
* GEOS standard file header (all file types) *
******************************************************************************/
#define GEOS_LONGNAME 36 // length of filename
#define GEOS_INFO 100 // length of user file info
#define GEOS_ID 0x53CF45C7 // GEOS file identification "magic"
struct GEOSheader
{ /*** Standard-Dateikof */
int32 ID; // GEOS id magic: C7 45 CF 53
ushort fclass; // 00=applciation, 01=VM file
ushort flags; // flags ??? (always seen 0000h)
GEOSrelease release; // "release"
GEOSprotocol protocol; // protocol/version
GEOStoken token; // file type/icon
GEOStoken appl; // "token" of creator application
char name[GEOS_LONGNAME]; // long filename
char info[GEOS_INFO]; // user file info
char _copyright[24]; // original files: Copyright notice
};
/******************************************************************************
* GEOS program files ("geodes") *
******************************************************************************/
#define GEOS_FNAME 8 // Length of internale filename/ext
#define GEOS_FEXT 4
struct GEOSappheader
{ /*** Additional geode file header */
ushort _attr; // attribute (see below)
#define GA_PROCESS 0x8000
#define GA_LIBRARY 0x4000
#define GA_DRIVER 0x2000
#define GA_KEEP_FILE_OPEN 0x1000
#define GA_SYSTEM 0x0800
#define GA_MULTI_LAUNCHABLE 0x0400
#define GA_APPLICATION 0x0200
#define GA_DRIVER_INITIALIZED 0x0100
#define GA_LIBRARY_INITIALIZED 0x0080
#define GA_GEODE_INITIALIZED 0x0040
#define GA_USES_COPROC 0x0020
#define GA_REQUIRES_COPROC 0x0010
#define GA_HAS_GENERAL_CONSUMER_MODE 0x0008
#define GA_ENTRY_POINTS_IN_C 0x0004
ushort _type; // program type (see below)
GEOSprotocol kernelprot; // expected kernel protocoll
ushort resourceCount; // number of segments
ushort importLibraryCount; // number of included libraries
ushort exportEntryCount; // number of exported locations
ushort stacksize; // default stack size (or udataSize)
ushort classptr_ofs; // if application: segment/offset of ???
ushort classptr_seg;
ushort tokenres_item; // if application: segment/item of
ushort tokenres_seg; // ressource with application token
char _x21[2];
// GEOS2 header start here:
ushort attr; // attribute
ushort type; // program type: 01=application
// 02=library
// 03=device driver
GEOSrelease release; // "release"
GEOSprotocol protocol; // protocol/version
ushort timestamp; // time stamp (SWAT uniqueness)
char name[GEOS_FNAME],ext[GEOS_FEXT]; // internal filename/ext (blank padded)
GEOStoken token; // file type/icon
char _x3[2];
ushort startofs; // if driver: entry location
ushort startseg; // " "
ushort initofs; // if library: init location (?)
ushort initseg; // " "
char _x33[2];
ushort numexp; // number of exports
ushort numlib; // number of included libraries
char _x4[2];
ushort numseg; // Number of program segments
char _x5[6];
};
struct GEOSexplist
{ /*** Base type of "exported" array */
ushort ofs; // Routine entry location
ushort seg; // " " "
};
struct GEOSliblist
{ /*** Base typ of library array */
char name[GEOS_FNAME]; // library name
ushort type; // library type: 2000h=driver
// 4000h=library
GEOSprotocol protocol; // required lib protocol/version
};
typedef ushort GEOSseglen; /*** Base type of segment size array */
typedef int32 GEOSsegpos; /*** Base type of segment loc array */
typedef ushort GEOSsegfix; /*** Base type of fixup tab size ary */
typedef ushort GEOSsegflags; /*** Base type of flag array:
xxxx xxxx xxxx xxxxb
*/
#define HF_ZERO_INIT 0x8000
#define HF_LOCK 0x4000
#define HF_NO_ERR 0x2000
#define HF_UI 0x1000
#define HF_READ_ONLY 0x0800
#define HF_OBJECT_RESOURCE 0x0400
#define HF_CODE 0x0200
#define HF_CONFORMING 0x0100
#define HF_FIXED 0x0080
#define HF_SHARABLE 0x0040
#define HF_DISCARDABLE 0x0020
#define HF_SWAPABLE 0x0010
#define HF_LMEM 0x0008
#define HF_DEBUG 0x0004
#define HF_DISCARDED 0x0002
#define HF_SWAPPED 0x0001
struct GEOSfixup
{ /*** Base typ of segment fixup table */
ushort type; // Type of fixup:
// xxxxh
// +|||
// | |0 = 16/16 pointer to routine #
// | |1 = 16 offset to routine #
// | |2 = 16 segment of routine #
// | |3 = 16 segment
// | |4 = 16/16 pointer (seg,ofs!)
// | 0 = kernel
// | 1 = library
// | 2 = program
// xx = if library: library ord #
ushort ofs; // Offset relative to segment
};
#pragma pack(pop)
#endif

60
idasdk76/ldr/geos/geos2.h Normal file
View File

@@ -0,0 +1,60 @@
/*
GEOS2.H
by Marcus Groeber 1993-94
Include file for the PC/GEOS 2 file format
20.06.00: Modified by Ilfak Guilfanov <ig@datarescue.com>
*/
#ifndef GEOS2_H
#define GEOS2_H
#include "geos.h"
#pragma pack(push, 1)
/*
* Packed time and date structures; bitfield order is compiler dependant.
*/
struct PackedFileDate
{
ushort d:5;
ushort m:4;
ushort y:7;
};
struct PackedFileTime
{
ushort s_2:5;
ushort m:6;
ushort h:5;
};
/******************************************************************************
* GEOS standard file header (all file types) *
******************************************************************************/
#define GEOS2_ID 0x53C145C7 // GEOS2 file identification "magic"
struct GEOS2header
{ /*** GEOS2 standard header */
int32 ID; // GEOS2 id magic: C7 45 CF 53
char name[GEOS_LONGNAME]; // long filename
ushort fclass; // geos filetype, see SDK docs
// 1-executable
ushort flags; // attributes
GEOSrelease release; // "release"
GEOSprotocol protocol; // protocol/version
GEOStoken token; // file type/icon
GEOStoken appl; // "token" of creator application
char info[GEOS_INFO]; // user file info
char _copyright[24]; // original files: Copyright notice
char _x[8];
PackedFileDate create_date;
PackedFileTime create_time; // creation date/time in DOS format
char password[8]; // password, encrypted as hex string
char _x2[44]; // not yet decoded
};
#pragma pack(pop)
#endif // define GEOS2_H

View File

@@ -0,0 +1,14 @@
PROC=geos
include ../loader.mak
# MAKEDEP dependency list ------------------
$(F)geos$(O) : $(I)auto.hpp $(I)bitrange.hpp $(I)bytes.hpp \
$(I)config.hpp $(I)diskio.hpp $(I)entry.hpp $(I)enum.hpp \
$(I)fixup.hpp $(I)fpro.h $(I)funcs.hpp \
$(I)ida.hpp $(I)idp.hpp $(I)ieee.h $(I)kernwin.hpp \
$(I)lines.hpp $(I)llong.hpp $(I)loader.hpp $(I)nalt.hpp \
$(I)name.hpp $(I)netnode.hpp $(I)offset.hpp $(I)pro.h \
$(I)range.hpp $(I)segment.hpp $(I)segregs.hpp \
$(I)struct.hpp $(I)typeinf.hpp $(I)ua.hpp $(I)xref.hpp \
../idaldr.h common.cpp geos.cpp geos.h geos2.h