wperes.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 326 行
C
326 行
/****************************************************************************
*
* 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: PE resources dump routines.
*
****************************************************************************/
#include <stdio.h>
#include <setjmp.h>
#include "wdglb.h"
#include "wdfunc.h"
static char *pe_resource_msg[] = {
"4 resource flags = ",
"4 time/date stamp = ",
"2 major version number = ",
"2 minor version number = ",
"2 number of name entries = ",
"2 number of ID integer entries = ",
NULL
};
static char *pe_fixup_msg[] = {
"4 page rva = ",
"4 number of bytes in fixup block = ",
NULL
};
/*
* Dump the type and offsets.
*/
static void dmp_type_offset( unsigned_32 bsize )
/**********************************************/
{
unsigned_32 i;
unsigned prev;
pe_fixup_entry entry;
Wdputslc( "type:offset type --\n" );
Wdputslc( "0 = ABSOLUTE, 1 = LOW, 2 = HIGH, 3 = HIGHLOW, 4 = HIGHADJUST, 5 = MIPSJMPADDR\n" );
prev = 0;
for( i = 0; i < bsize; i++ ) {
Wread( &entry, sizeof( pe_fixup_entry ) );
if( i != 0 ) {
if( (i) % 8 == 0 ) {
Wdputslc( "\n" );
} else {
Wdputs( " " );
}
}
if( prev == 4 ) {
Wdputc( ' ' );
Puthex( entry, 4 );
prev = 0;
} else {
prev = entry >> 12;
Puthex( prev, 1 );
Wdputc( ':' );
Puthex( entry, 3 );
}
}
Wdputslc( "\n" );
}
/*
* Dump the Fixup Table.
*/
void Dmp_fixups( void )
/*********************/
{
pe_fixup_header pe_fixup;
unsigned_32 offset;
offset = Fix_off;
Wdputslc( "\n" );
Banner( "Fixup Block Tables" );
for( ;; ) {
Wlseek( offset );
Wread( &pe_fixup, sizeof( pe_fixup_header ) );
offset += pe_fixup.block_size;
if( pe_fixup.page_rva == NULL ) break;
Dump_header( (char *)&pe_fixup.page_rva, pe_fixup_msg );
if( Options_dmp & FIX_DMP ) {
dmp_type_offset( ( pe_fixup.block_size -
sizeof( pe_fixup_header ) ) / 2 );
}
Wdputslc( "\n" );
}
}
/*
* Get the Resource Name.
*/
static res_name get_name( unsigned_32 offset )
/********************************************/
{
unsigned_16 i;
char name[2*SLEN];
unsigned_16 uniname[SLEN];
res_name lname;
Wlseek( offset );
Wread( &lname.len, sizeof( unsigned_16 ) );
if( lname.len > SLEN ) {
lname.len = SLEN;
}
Wread( uniname, lname.len*2 );
for( i = 0; i < lname.len; i++ ) {
name[i] = uniname[i];
}
lname.rname = name;
lname.rname[lname.len] = 0;
return( lname );
}
/*
* Dump the Resource Names.
*/
static void dmp_name_id( unsigned_32 offset, bool is_name )
/*********************************************************/
{
unsigned_16 i, j, cnt;
resource_dir_entry pe_res_dir, tmp_dir;
resource_dir_header pe_res_lang;
res_name name;
Wlseek( offset );
Wread( &pe_res_dir, sizeof( resource_dir_entry ) );
offset = Res_off +( pe_res_dir.id_name & PE_RESOURCE_MASK );
if( is_name ) {
name = get_name( offset );
Wdputs( name.rname );
for( j = name.len; j <= SLEN; j++ ) {
Wdputc( ' ' );
}
} else {
Puthex( pe_res_dir.id_name, 8 );
Wdputs( " " );
}
offset = Res_off +( pe_res_dir.entry_rva & PE_RESOURCE_MASK );
if( pe_res_dir.entry_rva & PE_RESOURCE_MASK_ON ) {
Wlseek( offset );
Wread( &pe_res_lang, sizeof( resource_dir_header ) );
offset += sizeof( resource_dir_header );
Wlseek( offset );
cnt = pe_res_lang.num_id_entries;
for( i = 0; i < cnt; i++ ) {
Wread( &tmp_dir, sizeof( resource_dir_entry ) );
Puthex( tmp_dir.id_name, 8 );
if( i != cnt - 1 ) {
Wdputslc( "\n " );
}
}
offset = Res_off +( tmp_dir.entry_rva & PE_RESOURCE_MASK );
}
if( Data_off == 0 ) {
Data_off = offset;
}
}
/*
* Dump the Resource Id's.
*/
static void dmp_res_name_id( unsigned_16 count, bool is_name )
/***********************************************************/
{
unsigned_16 i, j, cnt;
unsigned_32 offset, tmp_off;
resource_dir_header pe_res_name;
resource_dir_entry pe_res_dir;
res_name name;
if( count == 0 ) return;
offset = Res_off + sizeof( resource_dir_header );
for( i = 0; i < count; i++ ) {
Wlseek( offset );
Wread( &pe_res_dir, sizeof( resource_dir_entry ) );
offset += sizeof( resource_dir_entry );
tmp_off = Res_off +( pe_res_dir.id_name & PE_RESOURCE_MASK );
if( is_name ) {
name = get_name( tmp_off );
}
tmp_off = Res_off +( pe_res_dir.entry_rva & PE_RESOURCE_MASK );
Wlseek( tmp_off );
Wread( &pe_res_name, sizeof( resource_dir_header ) );
tmp_off += sizeof( resource_dir_header );
cnt = pe_res_name.num_name_entries + pe_res_name.num_id_entries;
for( j = 0; j < cnt; j++ ) {
if( is_name ) {
Wdputs( name.rname );
for( j = name.len; j <= SLEN; j++ ) {
Wdputc( ' ' );
}
} else {
Puthex( pe_res_dir.id_name, 8 );
Wdputs( " " );
}
if( j >= pe_res_name.num_name_entries ) {
dmp_name_id( tmp_off, FALSE );
} else {
dmp_name_id( tmp_off, TRUE );
}
tmp_off += sizeof( resource_dir_entry );
Wdputslc( "\n" );
}
}
}
/*
* Dump the Resource Directory.
*/
static void dmp_res_dir( void )
/*****************************/
{
resource_dir_header res_head;
resource_dir_entry res_dir;
unsigned_16 count, i;
Wdputslc( "\n" );
Wdputslc( "80000000H = name rva, else integer id\n" );
Wdputslc( "80000000H = sudirectory rva, else data entry rva\n" );
Wdputslc( " #id ents #name ents name rva/id data/subdir rva\n" );
Wdputslc( " ==== ==== ======== ========\n" );
Wlseek( Res_off );
for( ;; ) {
Wread( &res_head, sizeof( resource_dir_header ) );
count = res_head.num_name_entries + res_head.num_id_entries;
if( count == 0 ) break;
Wdputs( " " );
Puthex( res_head.num_id_entries, 4 );
Wdputs( " " );
Puthex( res_head.num_name_entries, 4 );
Wdputs( " " );
for( i = 0; i < count; i++ ) {
Wread( &res_dir, sizeof( resource_dir_entry ) );
if( i != 0 ) {
Wdputs( " " );
}
Puthex( res_dir.id_name, 8 );
Wdputs( " " );
Puthex( res_dir.entry_rva, 8 );
Wdputslc( "\n" );
}
}
}
/*
* Dump the Resource Data.
*/
static void dmp_res_data( void )
/******************************/
{
resource_entry res_data;
unsigned_16 i;
Wdputslc( "\n" );
Wdputslc( " data rva data size codepage reserved\n" );
Wdputslc( " ======== ======== ======== ========\n" );
Wlseek( Data_off );
for( i = 0; ; i++ ) {
Wread( &res_data, sizeof( resource_entry ) );
if( res_data.rsvd != NULL ) break;
Putdecl( i, 3 );
Wdputs( ": " );
Puthex( res_data.data_rva, 8 );
Wdputs( " " );
Puthex( res_data.size, 8 );
Wdputs( " " );
Puthex( res_data.code_page, 8 );
Wdputs( " " );
Puthex( res_data.rsvd, 8 );
Wdputslc( "\n" );
}
}
/*
* Dump the Resource Table.
*/
void Dmp_resources( void )
/************************/
{
resource_dir_header pe_res_type;
Data_off = 0;
Wlseek( Res_off );
Wread( &pe_res_type, sizeof( resource_dir_header ) );
Banner( "Resource Directory Table" );
Dump_header( (char *)&pe_res_type.flags, pe_resource_msg );
Wdputslc( "\n" );
Wdputslc( "type id/string name id/string language id\n" );
Wdputslc( "============== ============== ===========\n" );
dmp_res_name_id( pe_res_type.num_name_entries, TRUE );
dmp_res_name_id( pe_res_type.num_id_entries, FALSE );
if( Options_dmp & RESRC_DMP ) {
dmp_res_dir();
dmp_res_data();
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?