peexe.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 403 行
C
403 行
/****************************************************************************
*
* Open Watcom Project
*
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
* ========================================================================
*
* This file contains Original Code and/or Modifications of Original
* Code as defined in and that are subject to the Sybase Open Watcom
* Public License version 1.0 (the 'License'). You may not use this file
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
* provided with the Original Code and Modifications, and is also
* available at www.sybase.com/developer/opensource.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
* NON-INFRINGEMENT. Please see the License for the specific language
* governing rights and limitations under the License.
*
* ========================================================================
*
* Description: Portable Executable dumping routines.
*
****************************************************************************/
#include <stdio.h>
#include <setjmp.h>
#include <string.h>
#include <stdlib.h>
#include <stddef.h>
#include "wdglb.h"
#include "wdfunc.h"
static char *pe_exe_msg[] = {
"2cpu type = ",
"2number of object entries = ",
"4time/date stamp = ",
"4symbol table = ",
"4number of symbols = ",
"2no. of bytes in nt header following flags field = ",
"2flags = ",
"2reserved = ",
"1link major version number = ",
"1link minor version number = ",
"4code size = ",
"4initialized data size = ",
"4uninititialized data size = ",
"4entrypoint rva = ",
"4code base = ",
"4data base = ",
"4image base = ",
"4object alignment: power of 2, 512 to 256M = ",
"4file alignment factor to align image pages = ",
"2os major version number = ",
"2os minor version number = ",
"2user major version number = ",
"2user minor version number = ",
"2subsystem major version number = ",
"2subsystem minor version number = ",
"4reserved1 = ",
"4virtual size of the image = ",
"4total header size = ",
"4file checksum = ",
"2nt subsystem = ",
"2dll flags = ",
"4stack reserve size = ",
"4stack commit size = ",
"4size of local heap to reserve = ",
"4heap commit size = ",
"4address of tls index = ",
"4number of tables = ",
NULL
};
static char *pe_obj_msg[] = {
"4 virtual memory size = ",
"4 relative virtual address = ",
"4 physical size of initialized data = ",
"4 physical offset for obj's 1st page = ",
"4 relocs rva = ",
"4 linnum rva = ",
"2 number of relocs = ",
"2 number of linnums = ",
NULL
};
static char *PEHeadFlags[] = {
"RELOCS_STRIPPED",
"EXECUTABLE",
"LINES_STRIPPED",
"LOCALS_STRIPPED",
"MINIMAL",
"UPDATE",
"16BIT",
"LITTLE_ENDIAN",
"32BIT",
"DEBUG_STRIPPED",
"PATCH",
NULL,
"SYSTEM",
"DLL",
NULL,
"BIG_ENDIAN"
};
static char *PEObjFlags[] = {
"DUMMY",
"NOLOAD",
"GROUPED",
"NOPAD",
"COPY",
"CODE",
"INIT_DATA",
"UNINIT_DATA",
"OTHER",
"LINK_INFO",
"OVERLAY",
"REMOVE",
"COMDAT",
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
"DISCARDABLE",
"NOT_CACHED",
"NOT_PAGED",
"SHARED",
"EXECUTABLE",
"READABLE",
"WRITABLE"
};
#define IN_RANGE( tbl, pe_obj ) \
(Pe_head.table[ tbl ].rva >= (pe_obj).rva \
&& Pe_head.table[ tbl ].rva < ((pe_obj).rva+(pe_obj).physical_size))
#define PHYS_OFFSET( tbl, pe_obj ) \
((pe_obj).physical_offset + Pe_head.table[tbl].rva - (pe_obj).rva)
/*
* Dump the NT Executable Header, if any.
*/
bool Dmp_pe_head( void )
/**********************/
{
unsigned_16 i;
Exp_off = 0;
Imp_off = 0;
Res_off = 0;
Fix_off = 0;
Wlseek( New_exe_off );
Wread( &Pe_head, sizeof( pe_header ) );
switch( Pe_head.signature ) {
case PE_SIGNATURE:
Banner( "Windows NT EXE Header" );
break;
case PL_SIGNATURE:
Banner( "PharLap TNT DosStyle Header" );
break;
default:
return( 0 );
}
Wdputs( "file offset = " );
Puthex( New_exe_off, 8 );
Wdputslc( "H\n" );
Wdputslc( "\n" );
Dump_header( (char *)&Pe_head.cpu_type, pe_exe_msg );
DumpCoffHdrFlags( Pe_head.flags );
for( i = 0; i < Pe_head.num_tables; i++ ) {
Wdputs( " Table Entry " );
Putdecl( i, 2 );
Wdputs( " rva = " );
Puthex( Pe_head.table[i].rva, 8 );
Wdputs( "H size = " );
Puthex( Pe_head.table[i].size, 8 );
Wdputslc( "H\n" );
}
Wdputslc( "\n" );
Wlseek( New_exe_off + offsetof( pe_header, magic ) + Pe_head.nt_hdr_size );
dmp_objects( Pe_head.num_objects );
if( Exp_off != 0 ) {
Dmp_exports();
}
if( Imp_off != 0 ) {
Dmp_imports();
}
if( Res_off != 0 ) {
Dmp_resources();
}
if( Fix_off != 0 ) {
Dmp_fixups();
}
return( 1 );
}
static void DumpSection( pe_object *hdr )
/***************************************/
{
coff_reloc reloc;
coff_line_num linnum;
int i;
Wdputs( "Section data size = " );
Puthex( hdr->physical_size, 8 );
Wdputslc( "H\n" );
if( Options_dmp & OS2_SEG_DMP ) {
if( hdr->physical_offset != 0 ) {
Dmp_seg_data( Coff_off + hdr->physical_offset, hdr->physical_size );
}
if( hdr->num_linnums > 0 ) {
Wdputs( "Number of lines = " );
Puthex( hdr->num_linnums, 8 );
Wdputslc( "H\n" );
Wlseek( Coff_off + hdr->linnum_rva );
Wdputslc( "Idx/RVA Num Idx/RVA Num Idx/RVA Num Idx/RVA Num Idx/RVA Num\n" );
for( i = 0; i < hdr->num_linnums; i++ ) {
Wread( &linnum, sizeof(coff_line_num) );
Puthex( linnum.RVA, 8 );
Wdputc( ' ' );
Putdecbz( linnum.line_number, 5 );
if( i % 5 == 4 ) {
Wdputslc( "\n" );
} else {
Wdputc( ' ' );
}
}
if( i % 5 != 0 ) {
Wdputslc( "\n" );
}
}
}
if( Options_dmp & FIX_DMP ) {
Wlseek( Coff_off + hdr->relocs_rva );
Wdputs( "Number of relocations = " );
Puthex( hdr->num_relocs, 8 );
Wdputslc( "H\n" );
if( hdr->num_relocs != 0 ) {
Wdputslc( "Offset Sym Idx Type Offset Sym Idx Type Offset Sym Idx Type\n" );
}
for( i = 0; i < hdr->num_relocs; i++ ) {
Wread( &reloc, sizeof( coff_reloc ) );
Puthex( reloc.offset, 8 );
Wdputc( ' ' );
Puthex( reloc.sym_tab_index, 8 );
Wdputc( ' ' );
Putdecbz( reloc.type, 5 );
if( i % 3 == 2 ) {
Wdputslc( "\n" );
} else {
Wdputc( ' ' );
}
}
if( i % 3 != 0 ) {
Wdputslc( "\n" );
}
Wdputslc( "\n" );
}
}
extern void DumpCoffHdrFlags( unsigned_16 flags )
/***********************************************/
{
DumpFlags( flags, 0, PEHeadFlags, "" );
}
static void DumpPEObjFlags( unsigned_32 flags )
/*********************************************/
{
unsigned alignval;
char buf[8];
alignval = (flags & PE_OBJ_ALIGN_MASK) >> PE_OBJ_ALIGN_SHIFT;
if( alignval != 0 ) {
memcpy( buf, "ALIGN", 5 );
utoa( 1 << (alignval - 1), buf + 5, 10 );
} else {
buf[0] = '\0';
}
DumpFlags( flags, PE_OBJ_ALIGN_MASK, PEObjFlags, buf );
}
/*
* Dump the Object Table.
*/
extern void dmp_objects( unsigned num_objects )
/*********************************************/
{
unsigned_16 i;
pe_object * pe_obj;
pe_object * start;
char save;
if( num_objects == 0 ) return;
Banner( "Section Table" );
pe_obj = Wmalloc( num_objects * sizeof(pe_object) );
Wread( pe_obj, num_objects * sizeof(pe_object) );
start = pe_obj;
for( i = 1; i <= num_objects; i++ ) {
Wdputs( "object " );
Putdec( i );
Wdputs( ": name = " );
save = pe_obj->name[8];
pe_obj->name[8] = '\0';
Wdputs( pe_obj->name );
if( pe_obj->name[0] == '/' ) {
Wdputs( " (" );
Wdputs( Coff_obj_name( pe_obj->name ) );
Wdputs( ")" );
}
Wdputslc( "\n" );
pe_obj->name[8] = save;
Dump_header( (char *)&pe_obj->virtual_size, pe_obj_msg );
DumpPEObjFlags( pe_obj->flags );
Wdputslc( "\n" );
if( Options_dmp & (OS2_SEG_DMP|FIX_DMP) ) {
DumpSection( pe_obj );
}
if( pe_obj->physical_size != 0 ) {
if( IN_RANGE( PE_TBL_EXPORT, *pe_obj ) ) {
Exp_off = PHYS_OFFSET( PE_TBL_EXPORT, *pe_obj );
}
if( IN_RANGE( PE_TBL_IMPORT, *pe_obj ) ) {
Imp_off = PHYS_OFFSET( PE_TBL_IMPORT, *pe_obj );
}
if( IN_RANGE( PE_TBL_RESOURCE, *pe_obj ) ) {
Res_off = PHYS_OFFSET( PE_TBL_RESOURCE, *pe_obj );
}
if( IN_RANGE( PE_TBL_FIXUP, *pe_obj ) ) {
Fix_off = PHYS_OFFSET( PE_TBL_FIXUP, *pe_obj );
}
}
pe_obj++;
}
free( start );
}
/*
* Dump the Pe export table (for .dll), if any.
*/
bool Dmp_pe_tab( void )
/*********************/
{
unsigned_32 cur_pos; /* current offset position */
unsigned_16 i;
pe_object pe_obj;
Wread( &Dos_head, sizeof( Dos_head ) );
if( Dos_head.signature != DOS_SIGNATURE ) {
return( 0 );
}
if( Dos_head.reloc_offset != OS2_EXE_HEADER_FOLLOWS ) {
return( 0 );
}
Wlseek( OS2_NE_OFFSET );
Wread( &New_exe_off, sizeof( New_exe_off ) );
Wlseek( New_exe_off );
Wread( &Pe_head, sizeof( pe_header ) );
switch( Pe_head.signature ) {
case PE_SIGNATURE:
case PL_SIGNATURE:
break;
default:
return( 0 );
}
Exp_off = 0;
cur_pos = New_exe_off + sizeof( Pe_head );
for( i = 0; i < Pe_head.num_objects; i++ ) {
Wlseek( cur_pos );
Wread( &pe_obj, sizeof( pe_object ) );
cur_pos += sizeof( pe_object );
if( Pe_head.table[ PE_TBL_EXPORT ].rva >= pe_obj.rva
&& Pe_head.table[ PE_TBL_EXPORT ].rva < (pe_obj.rva+pe_obj.physical_size) ) {
Exp_off = pe_obj.physical_offset
+ Pe_head.table[PE_TBL_EXPORT].rva - pe_obj.rva;
}
}
if( Exp_off != 0 ) {
Dmp_exp_tab();
} else {
Wdputslc( "no export table\n" );
}
return( 1 );
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?