Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Executable Format Dumper

1 view
Skip to first unread message

David Rowley

unread,
Nov 6, 1986, 10:21:28 AM11/6/86
to
*** REPLACE THIS LINE WITH YOUR MESSAGE ***

What follows is a simple program that dumps the format of an executable,
and displays the symbol table (if any). Both the standard and Mark Williams
symbol tables can be displayed. The dumper checks the integrity of various
aspects of the format, and can thus be used to see if a program has been
properly transmitted over the net.

I hope someone finds it useful. I use a modified version of the routine
to load and relocate my own .PRG's, my own Pexec() if you will.

The source compiles under Alcyon (v4.14) and Mark Williams, I have not
tried it under Megamax, but there shouldn't be any major problem.
(Of course, Megamax does not spit out ANY form of symbol table, since
everything is PC relative)


----------cut here---------------cut here---------------------------
/************************************************************************
*
* Executable Program Dumper - Nov. 6th / 1986
*
* David Rowley (..utzoo!watmath!looking!david)
*
* Thanks to the person who posted the header format of a .PRG
*
************************************************************************/

#include <stdio.h>
#include <ctype.h>

/* Select the appropriate define below: */

/* #define ALCYON 1 */
/* #define MarkWilliams 1 */


#ifdef ALCYON
extern FILE *fopenb();
#endif

#ifdef MarkWilliams
extern FILE *fopen();
#endif

extern long ftell();

#define FROM_CURRENT 1 /* Seek from current file pos */

typedef struct hdr {
int magic; /* Magic word, contains 601Ah */

long text_size; /* size of text segment */
long data_size; /* size of data segment */

long bss_size; /* Block storage segment size */
long sym_size; /* Symbol Table size */

long zero1; /* reserved, zero */
long zero2; /* reserved, zero */

int reloc; /* Flag - 0 - relocation info present */

} HEADER;

typedef struct symtab {

char name[8]; /* name padded to 8 chars */
int symtype; /* type */
long value; /* value */

} SYMTAB;

/*
* Mark Williams Symbol Table Info
*/

typedef struct _mark_hdr {
char mwc_hdr[48];
} MWC_HEADER;

typedef struct _mwc_sym {
char mwc_name[16];
unsigned char mwc_type[2];
unsigned char mwc_value[4];
} MWC_SYM;

#define DEFINED 0x8000
#define EQUATED 0x4000
#define GLOBAL 0x2000
#define EQUATED_REG 0x1000
#define EXTERN_REF 0x0800
#define DATA_RELOC 0x0400
#define TEXT_RELOC 0x0200
#define BSS_RELOC 0x0100

int show_sym = FALSE;
int show_end_bytes = FALSE;
int mark_williams = FALSE;

main( argc, argv )
int argc;
char *argv[];
{
char *str;

while( (argc--) > 1 ) {
str = argv[1];
if( str[0] == '-' ) {
switch( str[1] ) {
case 's':
case 'S':
show_sym = TRUE;
break;
case 'a':
case 'A':
show_end_bytes = TRUE;
break;
case 'm':
case 'M':
mark_williams = TRUE;
break;
default:
usage();
exit(1);
}
} else {

printf( "Dumping file '%s'\n", str );

dump_prg( str );

}
argv++;
}
}

usage()
{
printf( "dump [-sam] filenames...\n" );
printf( " -s displays symbol table (if any)\n" );
printf( " -a displays the surplus bytes at the end of file\n" );
printf( " -m displays a Mark Williams format symbol table\n" );
}

dump_prg( fname )
char *fname;
{
FILE *fp;
HEADER hdr;
long symsize, textsize, datasize;
long offset;
long txt_relocs, data_relocs;
long extra_bytes;
long total;
long reloc_size;
int InText = TRUE;
SYMTAB sym;
int c;
MWC_HEADER m_hdr; /* The 48 byte header of a MWC symtab */
MWC_SYM m_sym; /* A MWC symtab entry */

/*
* Read the header of a .TOS or .PRG file
*/

#ifdef ALCYON
fp = fopenb( fname, "r" );
#else
# ifdef MarkWilliams
fp = fopen( fname, "rb" );
# else
fp = fopen( fname, "r" );
# endif
#endif


if( fp == (FILE *)0 ) {
printf( "Can't open '%s'\n", fname );
return;
}

fread( &hdr, 1, sizeof( HEADER ), fp );

/*
* Now print out the values
*/

printf( "Magic Word: %4x\n\n", hdr.magic );

if( hdr.magic != 0x601a ) {
printf( "Unknown file type - Bad magic number\n" );
return;
}

total = hdr.text_size + hdr.data_size + hdr.bss_size;

printf( "Text size: %8lx %10ld\n", hdr.text_size, hdr.text_size );
printf( "Data size: %8lx %10ld\n", hdr.data_size, hdr.data_size );
printf( "Bss size: %8lx %10ld\n", hdr.bss_size, hdr.bss_size );
printf( "-----------------------------------\n" );
printf( "Total Size: %8lx %10ld\n", total, total );

printf( "\n" );
printf( "Sym size: %8lx %10ld\n", hdr.sym_size, hdr.sym_size );

printf( "\n" );
if( hdr.reloc != 0 )
printf( "No relocation information\n" );

/*
* Skip past the text segment info
*/

textsize = hdr.text_size;

/*
* Seek past the text segment
*/
if( fseek( fp, hdr.text_size, FROM_CURRENT ) != 0 ) {
printf( "Error - Premature end of file in text segment\n" );
return;
}

/*
* Skip past the data segment info
*/

datasize = hdr.data_size;

if( fseek( fp, hdr.data_size, FROM_CURRENT ) != 0 ) {
printf( "Error - Premature end of file in data segment\n" );
return;
}

/*
* Now print out the symbol table
*/
symsize = hdr.sym_size;
if( symsize )
printf( "%ld symbol table entries:\n", (long)symsize /
(long)sizeof( SYMTAB ) );

/*
* If we are to show the symbol table, then do it
*/
if( show_sym ) {

for( ;; ) {
if( symsize == 0L ) break;
if( symsize < sizeof( SYMTAB ) ) {
printf( "Corrupt symbol table size\n" );
return;
}
if( fread( &sym, 1, sizeof( SYMTAB ), fp ) != sizeof(SYMTAB)){
printf( "Corrupt Symbol Table\n" );
return;
}

symsize -= sizeof( SYMTAB );

/*
* Print out this symbol table entry
*/
print_sym( &sym );

}
} else {
/*
* Otherwise, skip it
*/
fseek( fp, hdr.sym_size, FROM_CURRENT );
}

/*
* Now there is the relocation info
* (if present)
*/
if( hdr.reloc == 0) {
fread( &offset, 1, sizeof( long ), fp );
reloc_size = 4L;

txt_relocs = 0L;
data_relocs = 0L;
if( offset > hdr.text_size ) {
data_relocs = 1;
InText = FALSE;
} else {
txt_relocs = 1;
InText = TRUE;
}

while( (c = fgetc( fp )) != 0 ) {

reloc_size++;

if( c == EOF ) {
printf( "Error - Premature end of file in relocation info\n" );
return;
}
/*
* We have an offset, if it is '1', add 254
*/
if( (offset & 1L) == 1L ) {
printf( "Error - relocation of odd address\n" );
printf( " at file location %lx\n",
ftell( fp ) );
}

if( c == 1 )
offset += 254;
else {
offset += c;

if( InText && (offset > hdr.text_size )) {
InText = FALSE;
}

if( InText )
txt_relocs++;
else
data_relocs++;

/*
* And relocate this location
*/
}
}
reloc_size++;

printf( "Text Relocs: %ld, Data Relocs: %ld\n", txt_relocs,
data_relocs );
printf( "Size of relocation info: %ld\n", reloc_size );
}

/*
* We should get EOF now
*/

/*
* If we think this file might be a MarkWilliams one, with a symbol
* table, then do dump it
*/
if( mark_williams ) {
/* Skip past the header */
fread( &m_hdr, 1, sizeof( MWC_HEADER ), fp );

printf( "Symbols:\n" );

while( fread( &m_sym, 1, sizeof( MWC_SYM ), fp ) ) {

print_mwc( &m_sym );

}
} else {
extra_bytes = 0;
while( (c = fgetc(fp)) != EOF ) {
if( show_end_bytes ) {
printf( "%2x ", c );
if( isprint( c ) ) printf( "(%c) ", c );
}
extra_bytes++;
}

if( extra_bytes ) {
printf( "Warning - %ld (%lx) extra bytes at end of file\n",
extra_bytes, extra_bytes );
}
}

fclose( fp );
}

/*
* Print out a MarkWilliams format symbol table entry
*/

print_mwc( s )
MWC_SYM *s;
{
int i;
int s_type;
unsigned long s_value;
char buf[17];

for( i=0; i<16; i++ )
buf[i] = s->mwc_name[i];
buf[16] = 0;

printf( "%20s ", buf );

s_type = (s->mwc_type[1] * 256) + s->mwc_type[0];
printf( "%4x ", s_type );

s_value = s->mwc_value[1];
s_value *= 256;
s_value |= s->mwc_value[0];
s_value *= 256;
s_value |= s->mwc_value[3];
s_value *= 256;
s_value |= s->mwc_value[2];

printf( "%8lx ", s_value );

printf( "\n" );
}

/*
* Print out a standard format symbol table entry (ALCYON, etc)
*/

print_sym( s )
SYMTAB *s;
{
char symname[9];
int i;
int s_type;

for( i=0; i<8; i++ ) symname[i] = s->name[i];
symname[8] = 0;

printf( "%8s - %8lx : ", symname, s->value );

s_type = s->symtype;

if( s_type & DEFINED )
printf( "defined " );

if( s_type & EQUATED )
printf( "equated " );

if( s_type & GLOBAL )
printf( "global " );

if( s_type & EQUATED_REG )
printf( "equated-reg " );

if( s_type & EXTERN_REF )
printf( "extern-ref " );

if( s_type & DATA_RELOC )
printf( "data-reloc " );

if( s_type & TEXT_RELOC )
printf( "text-reloc " );

if( s_type & BSS_RELOC )
printf( "bss-reloc " );

printf( "\n" );
}
----------and here-----------and here-------------and here----------------

David Rowley
Looking Glass Software
Waterloo, Ontario.
..utzoo!watmath!looking!david

0 new messages