update to ida 7.6, add builds
This commit is contained in:
46
idasdk76/ldr/intelomf/common.cpp
Normal file
46
idasdk76/ldr/intelomf/common.cpp
Normal file
@@ -0,0 +1,46 @@
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
bool is_intelomf_file(linput_t *li)
|
||||
{
|
||||
uchar magic;
|
||||
lmh h;
|
||||
qlseek(li, 0);
|
||||
if ( qlread(li, &magic, sizeof(magic)) != sizeof(magic)
|
||||
|| qlread(li, &h, sizeof(h)) != sizeof(h) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
int64 fsize = qlsize(li);
|
||||
return magic == INTELOMF_MAGIC_BYTE
|
||||
&& h.tot_length < fsize;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
static int read_pstring(linput_t *li, char *name, int size)
|
||||
{
|
||||
char buf[256];
|
||||
uchar nlen;
|
||||
lread(li, &nlen, sizeof(nlen));
|
||||
lread(li, buf, nlen);
|
||||
buf[nlen] = '\0';
|
||||
qstrncpy(name, buf, size);
|
||||
return nlen;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
static uint32 readdw(const uchar *&ptr, bool wide)
|
||||
{
|
||||
uint32 x;
|
||||
if ( wide )
|
||||
{
|
||||
x = *(uint32 *)ptr;
|
||||
ptr += sizeof(uint32);
|
||||
}
|
||||
else
|
||||
{
|
||||
x = *(uint16 *)ptr;
|
||||
ptr += sizeof(uint16);
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
439
idasdk76/ldr/intelomf/intelomf.cpp
Normal file
439
idasdk76/ldr/intelomf/intelomf.cpp
Normal file
@@ -0,0 +1,439 @@
|
||||
/*
|
||||
* Interactive disassembler (IDA).
|
||||
* Version 4.20
|
||||
* Copyright (c) 2002 by Ilfak Guilfanov. (ig@datarescue.com)
|
||||
* ALL RIGHTS RESERVED.
|
||||
*
|
||||
* Intel OMF386
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "../idaldr.h"
|
||||
#include "intelomf.hpp"
|
||||
#include "common.cpp"
|
||||
|
||||
static lmh h;
|
||||
static ea_t xea;
|
||||
static sel_t dsel = BADSEL;
|
||||
//--------------------------------------------------------------------------
|
||||
static void create32(
|
||||
sel_t sel,
|
||||
ea_t start_ea,
|
||||
ea_t end_ea,
|
||||
const char *name,
|
||||
const char *sclass)
|
||||
{
|
||||
set_selector(sel, 0);
|
||||
|
||||
segment_t s;
|
||||
s.sel = sel;
|
||||
s.start_ea = start_ea;
|
||||
s.end_ea = end_ea;
|
||||
s.align = saRelByte;
|
||||
s.comb = sclass != NULL && streq(sclass, "STACK") ? scStack : scPub;
|
||||
s.bitness = 1; // 32-bit
|
||||
|
||||
if ( !add_segm_ex(&s, name, sclass, ADDSEG_NOSREG|ADDSEG_SPARSE) )
|
||||
loader_failure();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
static void show_segdefs(linput_t *li, uint32 offset, uint32 length)
|
||||
{
|
||||
if ( offset == 0 || length == 0 )
|
||||
return;
|
||||
qlseek(li, offset);
|
||||
int n = 0;
|
||||
for ( int i=0; i < length; )
|
||||
{
|
||||
if ( qltell(li) >= qlsize(li) )
|
||||
BAD_FILE:
|
||||
loader_failure("Corrupted segmentation info");
|
||||
segdef s;
|
||||
const int size = offsetof(segdef, combine_name);
|
||||
lread(li, &s, size);
|
||||
int nlen = read_pstring(li, s.combine_name, sizeof(s.combine_name));
|
||||
i += size + 1 + nlen;
|
||||
n++;
|
||||
|
||||
const char *sname = s.combine_name;
|
||||
const char *sclas = sname;
|
||||
if ( strnicmp(sname, "CODE", 4) == 0 )
|
||||
sclas = "CODE";
|
||||
if ( strnicmp(sname, "DATA", 4) == 0 )
|
||||
sclas = "DATA";
|
||||
if ( strnicmp(sname, "CONST", 5) == 0 )
|
||||
sclas = "CONST";
|
||||
if ( stricmp(sname, "STACK") == 0 )
|
||||
sclas = "STACK";
|
||||
if ( strchr(sname, ':') != NULL )
|
||||
continue;
|
||||
|
||||
int segsize = s.slimit + 1;
|
||||
if ( segsize < 0 || qltell(li) >= qlsize(li) )
|
||||
goto BAD_FILE;
|
||||
|
||||
if ( strcmp(sname, "DATA") == 0 )
|
||||
dsel = n;
|
||||
set_selector(n, 0);
|
||||
ea_t ea = free_chunk(inf_get_max_ea(), segsize, -(1<<s.align));
|
||||
create32(n, ea, ea+segsize, sname, sclas);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
static ea_t getsea(ushort i)
|
||||
{
|
||||
segment_t *s = get_segm_by_sel(i & 0xFF);
|
||||
return s ? s->start_ea : BADADDR;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
static void show_pubdefs(linput_t *li, uint32 offset, uint32 length)
|
||||
{
|
||||
if ( offset == 0 || length == 0 )
|
||||
return;
|
||||
qlseek(li, offset);
|
||||
for ( int i=0; i < length; )
|
||||
{
|
||||
pubdef p;
|
||||
const int size = offsetof(pubdef, sym_name);
|
||||
if ( qlread(li, &p, size) != size )
|
||||
loader_failure("Corrupted pubdefs");
|
||||
int nlen = read_pstring(li, p.sym_name, sizeof(p.sym_name));
|
||||
i += size + 1 + nlen;
|
||||
|
||||
ea_t sea = getsea(p.PUB_segment);
|
||||
if ( sea != BADADDR )
|
||||
{
|
||||
sea += p.PUB_offset;
|
||||
add_entry(sea, sea, p.sym_name, segtype(sea) == SEG_CODE, AEF_IDBENC);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
static void show_extdefs(linput_t *li, uint32 offset, uint32 length)
|
||||
{
|
||||
if ( offset == 0 || length == 0 )
|
||||
return;
|
||||
qlseek(li, offset);
|
||||
|
||||
uchar ss = inf_is_64bit() ? 8 : 4;
|
||||
inf_set_specsegs(ss);
|
||||
int16 segsize = ss * h.num_externals;
|
||||
if ( !is_mul_ok(uint16(ss), uint16(h.num_externals))
|
||||
|| segsize < 0
|
||||
|| segsize < h.num_externals )
|
||||
{
|
||||
BAD_EXTDEFS:
|
||||
loader_failure("Corrupted extdefs");
|
||||
}
|
||||
sel_t sel = h.num_segs+1;
|
||||
set_selector(sel, 0);
|
||||
xea = free_chunk(inf_get_max_ea(), segsize, -15);
|
||||
create32(sel, xea, xea+segsize, "XTRN", "XTRN");
|
||||
|
||||
int n = 0;
|
||||
for ( int i=0; i < length; )
|
||||
{
|
||||
extdef p;
|
||||
const int size = offsetof(extdef, allocate_len);
|
||||
if ( qlread(li, &p, size) != size )
|
||||
goto BAD_EXTDEFS;
|
||||
p.allocate_len.len_4 = 0;
|
||||
if ( p.allocate != 0 )
|
||||
{
|
||||
ask_for_feedback("extdef.allocate\n");
|
||||
lread(li, &p.allocate_len.len_4, sizeof(p.allocate_len.len_4));
|
||||
}
|
||||
int nlen = read_pstring(li, p.sym_name, sizeof(p.sym_name));
|
||||
i += size + 1 + nlen;
|
||||
|
||||
ea_t a = xea + 4 * n++;
|
||||
set_name(a, p.sym_name, SN_IDBENC);
|
||||
if ( p.allocate )
|
||||
put_dword(a, p.allocate_len.len_4);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
static void read_text(linput_t *li)
|
||||
{
|
||||
text txt;
|
||||
const int size = offsetof(text, segment);
|
||||
if ( qlread(li, &txt, size) != size || txt.length < 0 )
|
||||
loader_failure("Corrupted text data");
|
||||
if ( txt.length != 0 )
|
||||
{
|
||||
qoff64_t fptr = qltell(li);
|
||||
ea_t sea = getsea(txt.txt_IN);
|
||||
if ( sea != BADADDR )
|
||||
{
|
||||
ea_t start = sea + txt.txt_offset;
|
||||
ea_t end = start + txt.length;
|
||||
uint64 fsize = qlsize(li);
|
||||
segment_t *s = getseg(start);
|
||||
if ( start < sea
|
||||
|| end < start
|
||||
|| fptr > fsize
|
||||
|| fsize-fptr < txt.length
|
||||
|| s == NULL
|
||||
|| s->end_ea < end )
|
||||
{
|
||||
loader_failure("Corrupted text data");
|
||||
}
|
||||
if ( change_storage_type(start, end, STT_VA) != eOk )
|
||||
INTERR(20060);
|
||||
file2base(li, fptr, start, end, FILEREG_PATCHABLE);
|
||||
}
|
||||
qlseek(li, fptr+txt.length);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
static void read_fixup(linput_t *li)
|
||||
{
|
||||
fixup fix;
|
||||
const int size = offsetof(fixup, fixups);
|
||||
if ( qlread(li, &fix, size) != size || fix.length < 0 )
|
||||
loader_failure("Corrupted fixups");
|
||||
qoff64_t fptr = qltell(li);
|
||||
ea_t sea = getsea(fix.where_IN);
|
||||
if ( sea != BADADDR )
|
||||
{
|
||||
validate_array_count(li, &fix.length, 1, "Fixup count");
|
||||
uchar *b = (uchar *)qalloc(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 )
|
||||
{
|
||||
uint32 where_offset = 0;
|
||||
uint32 what_offset = 0;
|
||||
ushort what_in = 9;
|
||||
bool selfrel = false;
|
||||
bool isfar = false;
|
||||
fixup_data_t fd(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.set_extdef();
|
||||
break;
|
||||
default:
|
||||
ask_for_feedback("Unknown relocation target %04X", what_in);
|
||||
add_pgm_cmt("!!! Unknown relocation target %04X", what_in);
|
||||
break;
|
||||
}
|
||||
fd.set_target_sel();
|
||||
if ( !fd.is_extdef() )
|
||||
{
|
||||
target += what_offset;
|
||||
what_offset = 0;
|
||||
}
|
||||
fd.off = target - fd.get_base();
|
||||
fd.displacement = what_offset;
|
||||
target += what_offset;
|
||||
if ( selfrel )
|
||||
target -= source + 4;
|
||||
fd.set(source);
|
||||
put_dword(source, target);
|
||||
if ( isfar )
|
||||
{
|
||||
fd.set_type_and_flags(FIXUP_SEG16);
|
||||
fd.set(source+4);
|
||||
put_word(source+4, fd.sel);
|
||||
}
|
||||
}
|
||||
qfree(b);
|
||||
}
|
||||
qlseek(li, fptr + fix.length);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
static void read_iterat(linput_t *li)
|
||||
{
|
||||
iterat itr;
|
||||
const int size = offsetof(iterat, text) + offsetof(temp, value);
|
||||
lread(li, &itr, size);
|
||||
itr.text.value = NULL;
|
||||
if ( itr.text.length != 0 )
|
||||
{
|
||||
if ( itr.text.length < 0 || itr.it_count < 0 )
|
||||
BAD_FILE:
|
||||
loader_failure("Corrupted iterated data");
|
||||
qoff64_t fptr = qltell(li);
|
||||
ea_t sea = getsea(itr.it_segment);
|
||||
if ( sea != BADADDR )
|
||||
{
|
||||
uint64 fsize = qlsize(li);
|
||||
ea_t start = sea + itr.it_offset;
|
||||
segment_t *s = getseg(start);
|
||||
if ( start < sea
|
||||
|| fptr > fsize
|
||||
|| fsize-fptr < itr.text.length
|
||||
|| !is_mul_ok(uint32(itr.text.length), uint32(itr.it_count))
|
||||
|| s == NULL )
|
||||
{
|
||||
goto BAD_FILE;
|
||||
}
|
||||
uint32 total = itr.text.length * itr.it_count;
|
||||
ea_t final_end = start + total;
|
||||
if ( final_end < start || final_end > s->end_ea )
|
||||
goto BAD_FILE;
|
||||
if ( change_storage_type(start, final_end, STT_VA) != eOk )
|
||||
INTERR(20061);
|
||||
for ( int i=0; i < itr.it_count; i++ )
|
||||
{
|
||||
ea_t end = start + itr.text.length;
|
||||
file2base(li, fptr, start, end, FILEREG_PATCHABLE);
|
||||
start = end;
|
||||
}
|
||||
}
|
||||
qlseek(li, fptr+itr.text.length);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
static void show_txtfixs(linput_t *li, uint32 offset, uint32 length)
|
||||
{
|
||||
if ( offset == 0 || length == 0 )
|
||||
return;
|
||||
uint64 fsize = qlsize(li);
|
||||
uint64 eoff = offset + length;
|
||||
if ( eoff < offset || offset > fsize || eoff > fsize )
|
||||
loader_failure("Corrupted fixups");
|
||||
qlseek(li, offset);
|
||||
while ( qltell(li) < eoff )
|
||||
{
|
||||
char type;
|
||||
lread(li, &type, sizeof(type));
|
||||
switch ( type )
|
||||
{
|
||||
case 0:
|
||||
read_text(li);
|
||||
break;
|
||||
case 1:
|
||||
read_fixup(li);
|
||||
break;
|
||||
case 2:
|
||||
read_iterat(li);
|
||||
break;
|
||||
default:
|
||||
ask_for_feedback("txtfix.blk_type == %d!\n", type);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
static int idaapi accept_file(
|
||||
qstring *fileformatname,
|
||||
qstring *processor,
|
||||
linput_t *li,
|
||||
const char *)
|
||||
{
|
||||
if ( is_intelomf_file(li) )
|
||||
{
|
||||
*fileformatname = "Intel OMF386";
|
||||
*processor = "metapc";
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void idaapi load_file(linput_t *li, ushort /*neflag*/, const char * /*fileformatname*/)
|
||||
{
|
||||
set_processor_type("metapc", SETPROC_LOADER);
|
||||
|
||||
qlseek(li, 1);
|
||||
lread(li, &h, sizeof(h));
|
||||
|
||||
toc_p1 toc;
|
||||
lread(li, &toc, sizeof(toc));
|
||||
|
||||
// we add one to skip the magic byte
|
||||
show_segdefs(li, toc.SEGDEF_loc+1, toc.SEGDEF_len);
|
||||
show_pubdefs(li, toc.PUBDEF_loc+1, toc.PUBDEF_len);
|
||||
show_extdefs(li, toc.EXTDEF_loc+1, toc.EXTDEF_len);
|
||||
show_txtfixs(li, toc.TXTFIX_loc+1, toc.TXTFIX_len);
|
||||
|
||||
if ( dsel != BADSEL )
|
||||
set_default_dataseg(dsel);
|
||||
add_pgm_cmt("Module: %*.*s", h.mod_name[0], uchar(h.mod_name[0]), &h.mod_name[1]);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
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,
|
||||
NULL,
|
||||
NULL,
|
||||
};
|
||||
397
idasdk76/ldr/intelomf/intelomf.hpp
Normal file
397
idasdk76/ldr/intelomf/intelomf.hpp
Normal file
@@ -0,0 +1,397 @@
|
||||
/*
|
||||
* Interactive disassembler (IDA).
|
||||
* Version 4.20
|
||||
* Copyright (c) 2002 by Ilfak Guilfanov. (ig@datarescue.com)
|
||||
* ALL RIGHTS RESERVED.
|
||||
*
|
||||
*/
|
||||
|
||||
//
|
||||
// Intel OMF386
|
||||
//
|
||||
|
||||
#ifndef INTELOMF_HPP
|
||||
#define INTELOMF_HPP
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
||||
#define INTELOMF_MAGIC_BYTE 0xB0 // The first byte of the file
|
||||
// must have this value
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// Linkable Module Header
|
||||
// A linkable object file contains one or more linkable modules
|
||||
//-----------------------------------------------------------------------
|
||||
struct lmh /* linkable module header */
|
||||
{
|
||||
uint32 tot_length; /* total length of the module on disk in bytes */
|
||||
int16 num_segs; /* number of SEGDEF sections in the module */
|
||||
int16 num_gates; /* number of GATDEF sections in the module */
|
||||
int16 num_publics; /* number of PUBDEF sections in the module */
|
||||
int16 num_externals; /* number of EXTDEF sections in the module */
|
||||
char linked; /* linked = 0, if the module was produced by a translator */
|
||||
char date[8]; /* the creation date, written in the form MM/DD/YY */
|
||||
char time[8]; /* the creation time, written in the form HH:MM:SS */
|
||||
char mod_name[41]; /* name of the module, the first char is the string's length */
|
||||
char creator[41]; /* the name of the program which created the module */
|
||||
char src_path[46]; /* the path to the source file which produced the module */
|
||||
char trans_id; /* translator id, mainly for debugger */
|
||||
char trans_vers[4]; /* translator version (ASCII) */
|
||||
char OMF_vers; /* OMF version */
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
struct toc_p1 /* Table of contents for first partition */
|
||||
{
|
||||
int32 SEGDEF_loc; /* all the following _loc represents location of the first byte */
|
||||
int32 SEGDEF_len; /* of the section in current module, unit is byte; */
|
||||
int32 GATDEF_loc; /* all the following _len represents the length of the section */
|
||||
int32 GATDEF_len; /* also the unit is byte. */
|
||||
int32 TYPDEF_loc;
|
||||
int32 TYPDEF_len;
|
||||
int32 PUBDEF_loc;
|
||||
int32 PUBDEF_len;
|
||||
int32 EXTDEF_loc;
|
||||
int32 EXTDEF_len;
|
||||
int32 TXTFIX_loc;
|
||||
int32 TXTFIX_len;
|
||||
int32 REGINT_loc;
|
||||
int32 REGINT_len;
|
||||
int32 next_partition;
|
||||
int32 reserved;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
struct segdef /* segment definition */
|
||||
{
|
||||
int16 attributes; /* need to be separated into bits to get bitwise info(cf. [1]) */
|
||||
int32 slimit; /* the length of the segment minus one, in bytes */
|
||||
int32 dlength; /* the number of data bytes in the segment, only for dsc seg*/
|
||||
int32 speclength; /* the total number of bytes in the segment */
|
||||
int16 ldt_position; /* the position in LDT that this segment must occupy */
|
||||
char align; /* alignment requirements of the segment */
|
||||
char combine_name[41]; /* first char is the length of the string in byte,
|
||||
rest is name */
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// The GATDEF section defines an entry for each gate occurring in the module.
|
||||
// There is a 1-byte field in the data structure which is used to identify type
|
||||
// of gate from call gate, task gate, interrupt gate or trap gate. (cf. [1])
|
||||
|
||||
struct gatdef /* Gate definition */
|
||||
{
|
||||
char privilege; /* privilege of gate */
|
||||
char present;
|
||||
char gate_type;
|
||||
int32 GA_offset; /* gate entry GA consists of GA_offset and GA_segment */
|
||||
int16 GA_segment;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// The TYPDEF section serves two purposes: to allow Relocation and Linkage
|
||||
// software to check the validity of sharing data across external linkages,
|
||||
// and to provide type information to debuggers to interpret data correct.
|
||||
// [2] provides storage size equivalence tables and lists the syntactical
|
||||
// constructs for high level languages PL/M, PASCAL, FORTRAN and C.
|
||||
|
||||
struct leaf
|
||||
{
|
||||
char type; /* an 8-bit number defines the type of the leaf */
|
||||
union /* following are different kind of leaves */
|
||||
{
|
||||
char *string;
|
||||
int16 num_2;
|
||||
int32 num_4;
|
||||
uint64 num_8;
|
||||
int64 s_8;
|
||||
int16 s_2;
|
||||
int32 s_4;
|
||||
} content;
|
||||
struct leaf *next; /* points to next leaf */
|
||||
};
|
||||
|
||||
struct typdef /* type definition */
|
||||
{
|
||||
char linkage; /* is TRUE, if for public-external linkage; is FALSE, if only for debug symbols. */
|
||||
int16 length; /* the length in bytes of all the leaves in it */
|
||||
struct leaf leaves; /* all different leaves format */
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// PUBDEF section contains a list of public names with their general
|
||||
// addresses for the public symbols. The 2-byte field type_IN specifies
|
||||
// an internal name for a segment, gate, GDT selector or the special
|
||||
// CONST$IN. This section serves to define symbols to be exported to
|
||||
// other modules.
|
||||
|
||||
struct pubdef /* public definition */
|
||||
{
|
||||
int32 PUB_offset; /* gen addr consists of PUB_offset and PUB_segment */
|
||||
int16 PUB_segment;
|
||||
int16 type_IN; /* internal name for the type of the public of symbol */
|
||||
char wordcount; /* the total # of 16-bit entities of stacked parameters */
|
||||
char sym_name[256];
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// EXTDEF section lists all external symbols, which are then referenced
|
||||
// elsewhere in the module by means of their internal name. The 2-byte
|
||||
// field seg_IN specifies the segment that is assumed to contain the
|
||||
// matching public symbol and the 2-byte value of type_IN defines the
|
||||
// type of the external symbol. (cf. [1])
|
||||
|
||||
struct extdef /* external definition */
|
||||
{
|
||||
int16 seg_IN; /* internal name of segment having matched public symbol */
|
||||
int16 type_IN; /* internal name for the type of the external symbol */
|
||||
char allocate; /* not zero, if R&L needs allocate space for external symbol*/
|
||||
union
|
||||
{
|
||||
int16 len_2;
|
||||
int32 len_4;
|
||||
} allocate_len; /* number of bytes needed allocated for the external symbol */
|
||||
char sym_name[256]; /* the 1st char is length , the rest are name of the symbol*/
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// text block contains binaries for code segment and data segment.
|
||||
// These segments are relocatable. Other than that, all the SLD information
|
||||
// is also implemented in this block by a translator under debug option.
|
||||
// Segment MODULES in the text block is designed with the purpose of
|
||||
// providing general information about the current module. Segment MBOLS
|
||||
// provides entries for each symbol used in the module, including stack
|
||||
// symbols, local symbols and symbols that are used as procedure or block
|
||||
// start entries. Segment LINES consists of line offset values, each line
|
||||
// offset is the byte offset of the start of a line in the code segment.
|
||||
// Segment SRCLINES consists of line offsets of the source files.
|
||||
|
||||
struct mod /* MODULES segment */
|
||||
{
|
||||
int16 ldt_sel; /* a selector into the GDT for an LDT which contains the segments in this module */
|
||||
int32 code_offset; /* code segment GA consists of code_offset and code_IN */
|
||||
int16 code_IN;
|
||||
int32 types_offset; /* TYPES GA consists of types_offset and types_IN */
|
||||
int16 types_IN;
|
||||
int32 sym_offset; /* MBOLS GA consists of sym_coffset and sym_IN */
|
||||
int16 sym_IN;
|
||||
int32 lines_offset; /* LINES GA consists of lines_offset and lines_IN */
|
||||
int16 lines_IN;
|
||||
int32 pub_offset; /* PUBLICS GA consists of pub_offset and pub_IN */
|
||||
int16 pub_IN;
|
||||
int32 ext_offset; /* EXTERNAL GA consists of ext_offset and ext_IN */
|
||||
int16 ext_IN;
|
||||
int32 src_offset; /* SRCLINES GA consists of src_offset and src_IN */
|
||||
int16 src_IN;
|
||||
int16 first_line; /* first line number */
|
||||
char kind; /* 0 value for 286, 1 value for 386 format */
|
||||
char trans_id; /* same as lmh */
|
||||
char trans_vers[4]; /* same as lmh */
|
||||
char *mod_name; /* same as lmh */
|
||||
};
|
||||
|
||||
struct blk /* block start entry */
|
||||
{
|
||||
int32 offset; /* offset in code segment */
|
||||
int32 blk_len; /* block length */
|
||||
char *blk_name; /* block name, note that first byte is the length of string */
|
||||
};
|
||||
|
||||
struct proc /* procedure start entry */
|
||||
{
|
||||
int32 offset; /* offset in code segment */
|
||||
int16 type_IN; /* internal name of the typdef associated with the proc */
|
||||
char kind; /* specifying 16-bit or 32-bit */
|
||||
int32 ebp_offset; /* offset of return address from EBP */
|
||||
int32 proc_len; /* procedure length */
|
||||
char *proc_name; /* procedure name, as always, the 1st char is string length */
|
||||
};
|
||||
|
||||
struct sbase /* symbol base entry */
|
||||
{
|
||||
int32 offset;
|
||||
int16 s_IN;
|
||||
};
|
||||
|
||||
struct symbol /* symbol entry */
|
||||
{
|
||||
int32 offset;
|
||||
int16 type_IN;
|
||||
char *sym_name;
|
||||
};
|
||||
|
||||
struct sym /* MBOLS segment */
|
||||
{
|
||||
char kind; /* kind of entries */
|
||||
union
|
||||
{
|
||||
struct blk blk_start; /* block start entry */
|
||||
struct proc prc_start; /* procedure start entry */
|
||||
struct sbase sym_base; /* symbol base entry */
|
||||
struct symbol s_ent; /* symbol entry */
|
||||
} entry;
|
||||
struct sym *next;
|
||||
};
|
||||
|
||||
struct line /* LINES segment */
|
||||
{
|
||||
int32 offset;
|
||||
struct lines *next;
|
||||
};
|
||||
|
||||
struct src /* SRCLINES segment */
|
||||
{
|
||||
char *src_file; /* source file name */
|
||||
int16 count;
|
||||
struct lines *src_line;
|
||||
struct srclines *next;
|
||||
};
|
||||
|
||||
struct text /* text block */
|
||||
{
|
||||
int32 txt_offset; /* gen addr consists of txt_offset and txt_IN */
|
||||
int16 txt_IN; /* internal segment name */
|
||||
int32 length; /* the length of the text content, in byte */
|
||||
union
|
||||
{
|
||||
char *code; /* CODE segment */
|
||||
char *data; /* DATA segment */
|
||||
struct mod modules; /* MODULES segment */
|
||||
struct sym symbols; /* MBOLS segment */
|
||||
struct line lines; /* LINES segment */
|
||||
struct src srclines;/* SRCLINES segment */
|
||||
} segment;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// block contains information that allows the binder or linker to resolve
|
||||
// (fix up) and eventually relocate references between object modules.
|
||||
// The attributes where_IN and where_offset in the following data structures
|
||||
// make a generalized address specifying the target for the fixup. Similarly,
|
||||
// the attributes what_IN and what_offset make a generalized address
|
||||
// specifying the target to which the fixup is to be applied.
|
||||
|
||||
// There are four kinds of fixups for Intel linkable object modules.
|
||||
// They are:
|
||||
// general fixup,
|
||||
// intra-segment fixup,
|
||||
// call fixup
|
||||
// addition fixup.
|
||||
// The general fixup and the addition fixup have the same data structure,
|
||||
// both provide general addresses for where_IN, where_offset, and what_IN,
|
||||
// what_offset. The intra-segment fixup is equivalent to a general fixup
|
||||
// with what_IN = where_IN, and the call fixup is also equivalent to a
|
||||
// general fixup with what_offset = 0. (cf. [1])
|
||||
|
||||
struct gen /* for general fixup */
|
||||
{
|
||||
char kind; /* specifying the kind of fixup */
|
||||
union
|
||||
{
|
||||
int16 num2;
|
||||
int32 num4;
|
||||
} where_offset; /* 2- or 4- byte where_offset */
|
||||
union
|
||||
{
|
||||
int16 num2;
|
||||
int32 num4;
|
||||
} what_offset; /* 2- or 4- byte what_offset */
|
||||
int16 what_IN; /* what_IN & what_offset specify the target for the fixup*/
|
||||
union fixups *next;
|
||||
};
|
||||
|
||||
struct intra /* for intra-segment fixup */
|
||||
{
|
||||
char kind; /* specifying the kind of fixup */
|
||||
union
|
||||
{
|
||||
int16 num2;
|
||||
int32 num4;
|
||||
} where_offset; /* 2- or 4- byte where_offset */
|
||||
union
|
||||
{
|
||||
int16 num2;
|
||||
int32 num4;
|
||||
} what_offset; /* 2- or 4- byte what_offset */
|
||||
union fixups *next;
|
||||
};
|
||||
|
||||
struct cal /* for call fixup */
|
||||
{
|
||||
char kind; /* specifying the kind of fixup */
|
||||
union
|
||||
{
|
||||
int16 num2;
|
||||
int32 num4;
|
||||
} where_offset; /* 2- or 4- byte where-offset */
|
||||
int16 what_IN;
|
||||
union fixups *next;
|
||||
};
|
||||
|
||||
struct ad /* for addition fixup */
|
||||
{
|
||||
char kind; /* specifying the kind of fixup */
|
||||
union
|
||||
{
|
||||
int16 num2;
|
||||
int32 num4;
|
||||
} where_offset; /* specifying the target to which the fixup is to be applied */
|
||||
union
|
||||
{
|
||||
int16 num2;
|
||||
int32 num4;
|
||||
} what_offset;
|
||||
int16 what_IN;
|
||||
union fixups *next;
|
||||
};
|
||||
|
||||
struct temp /* for the text template in the iterated text block */
|
||||
{
|
||||
int32 length; /* the length, in bytes, of a single mem blk to be initialized */
|
||||
char *value; /* the text or data to be used to initialize any single mem blk*/
|
||||
};
|
||||
|
||||
struct iterat /* for iterated text block */
|
||||
{
|
||||
int32 it_offset;
|
||||
int16 it_segment; /* above two specify a gen addr to put 1st byte of the text */
|
||||
int32 it_count; /* the # of times the text template is to be repeated */
|
||||
struct temp text; /* the text template */
|
||||
};
|
||||
|
||||
struct fixup /* fixup block */
|
||||
{
|
||||
int16 where_IN; /* specifying the segment to which fixups should be applied*/
|
||||
int16 length; /* the length in bytes of the fixups */
|
||||
union
|
||||
{
|
||||
struct gen general; /* for general fixup */
|
||||
struct intra in_seg; /* for intra-segment fixup */
|
||||
struct cal call_fix; /* call fixup */
|
||||
struct ad addition; /* addition fixup */
|
||||
} fixups;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// The TXTFIX section consists of intermixed text block, fixup block and
|
||||
// iterated text block. As one can see, it is the TXTFIX section that
|
||||
// records the binaries for machine codes, initialized data and
|
||||
// uninitialized data. TXTFIX section output by a translator under debug
|
||||
// option will also contain SLD information.
|
||||
|
||||
struct txtfix /* text, iterated text and fixup block */
|
||||
{
|
||||
char blk_type; /* 0 for text blk; 1 for fixup blk and 2 for iterated text blk */
|
||||
union
|
||||
{
|
||||
struct text text_blk; /* text block */
|
||||
struct fixup fixup_blk; /* fixup block */
|
||||
struct iterat it_text_blk; /* iterated text block */
|
||||
} block;
|
||||
struct txtfix *next;
|
||||
};
|
||||
|
||||
// The file ends with a checksum byte
|
||||
|
||||
#pragma pack(pop)
|
||||
#endif
|
||||
14
idasdk76/ldr/intelomf/makefile
Normal file
14
idasdk76/ldr/intelomf/makefile
Normal file
@@ -0,0 +1,14 @@
|
||||
PROC=intelomf
|
||||
|
||||
include ../loader.mak
|
||||
|
||||
# MAKEDEP dependency list ------------------
|
||||
$(F)intelomf$(O): $(I)auto.hpp $(I)bitrange.hpp $(I)bytes.hpp \
|
||||
$(I)config.hpp $(I)diskio.hpp $(I)entry.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)ua.hpp \
|
||||
$(I)xref.hpp ../idaldr.h common.cpp intelomf.cpp \
|
||||
intelomf.hpp
|
||||
Reference in New Issue
Block a user