Eric Pouech afe309b7d9 winedump: Changed PE, NE, LE dumping so that they are consistent in terms of dump function signatures.
Avoid passing around the base of the module, but use instead the PRD function.
2006-11-30 12:34:50 +01:00

360 lines
12 KiB
C

/*
* Dumping of LE binaries
*
* Copyright 2004 Robert Reif
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "config.h"
#include "wine/port.h"
#include <fcntl.h>
#include <stdarg.h>
#include <stdio.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include "windef.h"
#include "winbase.h"
#include "winedump.h"
struct o32_obj
{
unsigned long o32_size;
unsigned long o32_base;
unsigned long o32_flags;
unsigned long o32_pagemap;
unsigned long o32_mapsize;
char o32_name[4];
};
struct o32_map
{
unsigned short o32_pagedataoffset;
unsigned char o32_pagesize;
unsigned char o32_pageflags;
};
struct b32_bundle
{
unsigned char b32_cnt;
unsigned char b32_type;
};
struct vxd_descriptor
{
unsigned long next;
unsigned short sdk_version;
unsigned short device_number;
unsigned char version_major;
unsigned char version_minor;
unsigned short flags;
char name[8];
unsigned long init_order;
unsigned long ctrl_ofs;
unsigned long v86_ctrl_ofs;
unsigned long pm_ctrl_ofs;
unsigned long v86_ctrl_csip;
unsigned long pm_ctrl_csip;
unsigned long rm_ref_data;
unsigned long service_table_ofs;
unsigned long service_table_size;
unsigned long win32_service_table_ofs;
unsigned long prev;
unsigned long size;
unsigned long reserved0;
unsigned long reserved1;
unsigned long reserved2;
};
static inline WORD get_word( const BYTE *ptr )
{
return ptr[0] | (ptr[1] << 8);
}
static void dump_le_header( const IMAGE_VXD_HEADER *le )
{
printf( "File header:\n" );
printf( " Magic: %04x (%c%c)\n",
le->e32_magic, LOBYTE(le->e32_magic), HIBYTE(le->e32_magic));
printf( " Byte order: %s\n",
le->e32_border == 0 ? "little-indian" : "big-endian");
printf( " Word order: %s\n",
le->e32_worder == 0 ? "little-indian" : "big-endian");
printf( " Executable format level: %d\n",
le->e32_level);
printf( " CPU type: %s\n",
le->e32_cpu == 0x01 ? "Intel 80286" :
le->e32_cpu == 0x02 ? "Intel 80386" :
le->e32_cpu == 0x03 ? "Intel 80486" :
le->e32_cpu == 0x04 ? "Intel 80586" :
le->e32_cpu == 0x20 ? "Intel i860 (N10)" :
le->e32_cpu == 0x21 ? "Intel i860 (N11)" :
le->e32_cpu == 0x40 ? "MIPS Mark I" :
le->e32_cpu == 0x41 ? "MIPS Mark II" :
le->e32_cpu == 0x42 ? "MIPS Mark III" :
"Unknown");
printf( " Target operating system: %s\n",
le->e32_os == 0x01 ? "OS/2" :
le->e32_os == 0x02 ? "Windows" :
le->e32_os == 0x03 ? "DOS 4.x" :
le->e32_os == 0x04 ? "Windows 386" :
"Unknown");
printf( " Module version: %d\n",
le->e32_ver);
printf( " Module type flags: %08x\n",
le->e32_mflags);
if (le->e32_mflags & 0x8000)
{
if (le->e32_mflags & 0x0004)
printf( " Global initialization\n");
else
printf( " Per-Process initialization\n");
if (le->e32_mflags & 0x0010)
printf( " No internal fixup\n");
if (le->e32_mflags & 0x0020)
printf( " No external fixup\n");
if ((le->e32_mflags & 0x0700) == 0x0100)
printf( " Incompatible with PM windowing\n");
else if ((le->e32_mflags & 0x0700) == 0x0200)
printf( " Compatible with PM windowing\n");
else if ((le->e32_mflags & 0x0700) == 0x0300)
printf( " Uses PM windowing API\n");
if (le->e32_mflags & 0x2000)
printf( " Module not loadable\n");
if (le->e32_mflags & 0x8000)
printf( " Module is DLL\n");
}
printf( " Number of memory pages: %d\n",
le->e32_mpages);
printf( " Initial object CS number: %08x\n",
le->e32_startobj);
printf( " Initial EIP: %08x\n",
le->e32_eip);
printf( " Initial object SS number: %08x\n",
le->e32_stackobj);
printf( " Initial ESP: %08x\n",
le->e32_esp);
printf( " Memory page size: %d\n",
le->e32_pagesize);
printf( " Bytes on last page: %d\n",
le->e32_lastpagesize);
printf( " Fix-up section size: %d\n",
le->e32_fixupsize);
printf( " Fix-up section checksum: %08x\n",
le->e32_fixupsum);
printf( " Loader section size: %d\n",
le->e32_ldrsize);
printf( " Loader section checksum: %08x\n",
le->e32_ldrsum);
printf( " Offset of object table: %08x\n",
le->e32_objtab);
printf( " Object table entries: %d\n",
le->e32_objcnt);
printf( " Object page map offset: %08x\n",
le->e32_objmap);
printf( " Object iterate data map offset: %08x\n",
le->e32_itermap);
printf( " Resource table offset: %08x\n",
le->e32_rsrctab);
printf( " Resource table entries: %d\n",
le->e32_rsrccnt);
printf( " Resident names table offset: %08x\n",
le->e32_restab);
printf( " Entry table offset: %08x\n",
le->e32_enttab);
printf( " Module directives table offset: %08x\n",
le->e32_dirtab);
printf( " Module directives entries: %d\n",
le->e32_dircnt);
printf( " Fix-up page table offset: %08x\n",
le->e32_fpagetab);
printf( " Fix-up record table offset: %08x\n",
le->e32_frectab);
printf( " Imported modules name table offset: %08x\n",
le->e32_impmod);
printf( " Imported modules count: %d\n",
le->e32_impmodcnt);
printf( " Imported procedure name table offset: %08x\n",
le->e32_impproc);
printf( " Per-page checksum table offset: %08x\n",
le->e32_pagesum);
printf( " Data pages offset from top of table: %08x\n",
le->e32_datapage);
printf( " Preload page count: %08x\n",
le->e32_preload);
printf( " Non-resident names table offset: %08x\n",
le->e32_nrestab);
printf( " Non-resident names table length: %d\n",
le->e32_cbnrestab);
printf( " Non-resident names table checksum: %08x\n",
le->e32_nressum);
printf( " Automatic data object: %08x\n",
le->e32_autodata);
printf( " Debug information offset: %08x\n",
le->e32_debuginfo);
printf( " Debug information length: %d\n",
le->e32_debuglen);
printf( " Preload instance pages number: %d\n",
le->e32_instpreload);
printf( " Demand instance pages number: %d\n",
le->e32_instdemand);
printf( " Extra heap allocation: %d\n",
le->e32_heapsize);
printf( " VxD resource table offset: %08x\n",
le->e32_winresoff);
printf( " Size of VxD resource table: %d\n",
le->e32_winreslen);
printf( " VxD identifier: %x\n",
le->e32_devid);
printf( " VxD DDK version: %x\n",
le->e32_ddkver);
}
static void dump_le_objects( const IMAGE_VXD_HEADER *le )
{
const struct o32_obj *pobj;
unsigned int i;
printf("\nObject table:\n");
pobj = (const struct o32_obj *)((const unsigned char *)le + le->e32_objtab);
for (i = 0; i < le->e32_objcnt; i++)
{
unsigned int j;
const struct o32_map *pmap=0;
printf(" Obj. Rel.Base Codesize Flags Tableidx Tablesize Name\n");
printf(" %04X %08lx %08lx %08lx %08lx %08lx ", i + 1,
pobj->o32_base, pobj->o32_size, pobj->o32_flags,
pobj->o32_pagemap, pobj->o32_mapsize);
for (j = 0; j < 4; j++)
{
if (isprint(pobj->o32_name[j]))
printf("%c", pobj->o32_name[j]);
else
printf(".");
}
printf("\n");
if(pobj->o32_flags & 0x0001)
printf("\tReadable\n");
if(pobj->o32_flags & 0x0002)
printf("\tWriteable\n");
if(pobj->o32_flags & 0x0004)
printf("\tExecutable\n");
if(pobj->o32_flags & 0x0008)
printf("\tResource\n");
if(pobj->o32_flags & 0x0010)
printf("\tDiscardable\n");
if(pobj->o32_flags & 0x0020)
printf("\tShared\n");
if(pobj->o32_flags & 0x0040)
printf("\tPreloaded\n");
if(pobj->o32_flags & 0x0080)
printf("\tInvalid\n");
if(pobj->o32_flags & 0x2000)
printf("\tUse 32\n");
printf(" Page tables:\n");
printf(" Tableidx Offset Flags\n");
pmap = (const struct o32_map *)((const unsigned char *)le + le->e32_objmap);
pmap = &(pmap[pobj->o32_pagemap - 1]);
for (j = 0; j < pobj->o32_mapsize; j++)
{
printf(" %08lx %06x %02x\n",
pobj->o32_pagemap + j,
(pmap->o32_pagedataoffset << 8) + pmap->o32_pagesize,
(int)pmap->o32_pageflags);
pmap++;
}
pobj++;
}
}
static void dump_le_names( const IMAGE_VXD_HEADER *le )
{
const unsigned char *pstr = (const unsigned char *)le + le->e32_restab;
printf( "\nResident name table:\n" );
while (*pstr)
{
printf( " %4d: %*.*s\n", get_word(pstr + *pstr + 1), *pstr, *pstr,
pstr + 1 );
pstr += *pstr + 1 + sizeof(WORD);
}
if (le->e32_cbnrestab)
{
printf( "\nNon-resident name table:\n" );
pstr = PRD(le->e32_nrestab, 0);
while (*pstr)
{
printf( " %4d: %*.*s\n", get_word(pstr + *pstr + 1), *pstr, *pstr,
pstr + 1 );
pstr += *pstr + 1 + sizeof(WORD);
}
}
}
static void dump_le_resources( const IMAGE_VXD_HEADER *le )
{
printf( "\nResources:\n" );
printf( " Not Implemented\n" );
}
static void dump_le_modules( const IMAGE_VXD_HEADER *le )
{
printf( "\nImported modulename table:\n" );
printf( " Not Implemented\n" );
}
static void dump_le_entries( const IMAGE_VXD_HEADER *le )
{
printf( "\nEntry table:\n" );
printf( " Not Implemented\n" );
}
static void dump_le_fixups( const IMAGE_VXD_HEADER *le )
{
printf( "\nFixup table:\n" );
printf( " Not Implemented\n" );
}
static void dump_le_VxD( const IMAGE_VXD_HEADER *le )
{
printf( "\nVxD descriptor:\n" );
printf( " Not Implemented\n" );
}
void le_dump( void )
{
const IMAGE_DOS_HEADER *dos;
const IMAGE_VXD_HEADER *le;
dos = PRD(0, sizeof(*dos));
if (!dos) return;
le = PRD(dos->e_lfanew, sizeof(*le));
dump_le_header( le );
dump_le_objects( le );
dump_le_resources( le );
dump_le_names( le );
dump_le_entries( le );
dump_le_modules( le );
dump_le_fixups( le );
dump_le_VxD( le );
}