?? exedump.c
字號(hào):
//==================================
// PEDUMP - Matt Pietrek 1995
// FILE: EXEDUMP.C
//==================================
#include <windows.h>
#include <stdio.h>
#pragma hdrstop
#include "common.h"
#include "extrnvar.h"
void DumpExeDebugDirectory(DWORD base, PIMAGE_NT_HEADERS pNTHeader)
{
PIMAGE_DEBUG_DIRECTORY debugDir;
PIMAGE_SECTION_HEADER header;
DWORD offsetInto_rdata;
DWORD va_debug_dir;
DWORD size;
// This line was so long that we had to break it up
va_debug_dir = pNTHeader->OptionalHeader.
DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].
VirtualAddress;
if ( va_debug_dir == 0 )
return;
// If we found a .debug section, and the debug directory is at the
// beginning of this section, it looks like a Borland file
header = GetSectionHeader(".debug", pNTHeader);
if ( header && (header->VirtualAddress == va_debug_dir) )
{
debugDir = (PIMAGE_DEBUG_DIRECTORY)(header->PointerToRawData+base);
size = pNTHeader->OptionalHeader.
DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].Size *
sizeof(IMAGE_DEBUG_DIRECTORY);
}
else // Look for microsoft debug directory in the .rdata section
{
header = GetSectionHeader(".rdata", pNTHeader);
if ( !header )
return;
size = pNTHeader->OptionalHeader.
DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].Size;
offsetInto_rdata = va_debug_dir - header->VirtualAddress;
debugDir = MakePtr(PIMAGE_DEBUG_DIRECTORY, base,
header->PointerToRawData + offsetInto_rdata);
}
DumpDebugDirectory( debugDir, size, base );
}
// Function prototype (necessary because two functions recurse)
void DumpResourceDirectory
(
PIMAGE_RESOURCE_DIRECTORY resDir, DWORD resourceBase,
DWORD level, DWORD resourceType
);
// The predefined resource types
char *SzResourceTypes[] = {
"???_0", "CURSOR", "BITMAP", "ICON", "MENU", "DIALOG", "STRING", "FONTDIR",
"FONT", "ACCELERATORS", "RCDATA", "MESSAGETABLE", "GROUP_CURSOR",
"???_13", "GROUP_ICON", "???_15", "VERSION"
};
// Get an ASCII string representing a resource type
void GetResourceTypeName(DWORD type, PSTR buffer, UINT cBytes)
{
if ( type <= 16 )
strncpy(buffer, SzResourceTypes[type], cBytes);
else
sprintf(buffer, "%X", type);
}
//
// If a resource entry has a string name (rather than an ID), go find
// the string and convert it from unicode to ascii.
//
void GetResourceNameFromId
(
DWORD id, DWORD resourceBase, PSTR buffer, UINT cBytes
)
{
PIMAGE_RESOURCE_DIR_STRING_U prdsu;
// If it's a regular ID, just format it.
if ( !(id & IMAGE_RESOURCE_NAME_IS_STRING) )
{
sprintf(buffer, "%X", id);
return;
}
id &= 0x7FFFFFFF;
prdsu = (PIMAGE_RESOURCE_DIR_STRING_U)(resourceBase + id);
// prdsu->Length is the number of unicode characters
WideCharToMultiByte(CP_ACP, 0, prdsu->NameString, prdsu->Length,
buffer, cBytes, 0, 0);
buffer[ min(cBytes-1,prdsu->Length) ] = 0; // Null terminate it!!!
}
//
// Dump the information about one resource directory entry. If the
// entry is for a subdirectory, call the directory dumping routine
// instead of printing information in this routine.
//
void DumpResourceEntry
(
PIMAGE_RESOURCE_DIRECTORY_ENTRY resDirEntry,
DWORD resourceBase,
DWORD level
)
{
UINT i;
char nameBuffer[128];
PIMAGE_RESOURCE_DATA_ENTRY pResDataEntry;
if ( resDirEntry->OffsetToData & IMAGE_RESOURCE_DATA_IS_DIRECTORY )
{
DumpResourceDirectory( (PIMAGE_RESOURCE_DIRECTORY)
((resDirEntry->OffsetToData & 0x7FFFFFFF) + resourceBase),
resourceBase, level, resDirEntry->Name);
return;
}
// Spit out the spacing for the level indentation
for ( i=0; i < level; i++ )
printf(" ");
if ( resDirEntry->Name & IMAGE_RESOURCE_NAME_IS_STRING )
{
GetResourceNameFromId(resDirEntry->Name, resourceBase, nameBuffer,
sizeof(nameBuffer));
printf("Name: %s DataEntryOffs: %08X\n",
nameBuffer, resDirEntry->OffsetToData);
}
else
{
printf("ID: %08X DataEntryOffs: %08X\n",
resDirEntry->Name, resDirEntry->OffsetToData);
}
// the resDirEntry->OffsetToData is a pointer to an
// IMAGE_RESOURCE_DATA_ENTRY. Go dump out that information. First,
// spit out the proper indentation
for ( i=0; i < level; i++ )
printf(" ");
pResDataEntry = (PIMAGE_RESOURCE_DATA_ENTRY)
(resourceBase + resDirEntry->OffsetToData);
printf("Offset: %05X Size: %05X CodePage: %X\n",
pResDataEntry->OffsetToData, pResDataEntry->Size,
pResDataEntry->CodePage);
}
//
// Dump the information about one resource directory.
//
void DumpResourceDirectory
(
PIMAGE_RESOURCE_DIRECTORY resDir,
DWORD resourceBase,
DWORD level,
DWORD resourceType
)
{
PIMAGE_RESOURCE_DIRECTORY_ENTRY resDirEntry;
char szType[64];
UINT i;
// Spit out the spacing for the level indentation
for ( i=0; i < level; i++ )
printf(" ");
// Level 1 resources are the resource types
if ( level == 1 && !(resourceType & IMAGE_RESOURCE_NAME_IS_STRING) )
{
GetResourceTypeName( resourceType, szType, sizeof(szType) );
}
else // Just print out the regular id or name
{
GetResourceNameFromId( resourceType, resourceBase, szType,
sizeof(szType) );
}
printf(
"ResDir (%s) Named:%02X ID:%02X TimeDate:%08X Vers:%u.%02u Char:%X\n",
szType, resDir->NumberOfNamedEntries, resDir->NumberOfIdEntries,
resDir->TimeDateStamp, resDir->MajorVersion,
resDir->MinorVersion,resDir->Characteristics);
resDirEntry = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(resDir+1);
for ( i=0; i < resDir->NumberOfNamedEntries; i++, resDirEntry++ )
DumpResourceEntry(resDirEntry, resourceBase, level+1);
for ( i=0; i < resDir->NumberOfIdEntries; i++, resDirEntry++ )
DumpResourceEntry(resDirEntry, resourceBase, level+1);
}
//
// Top level routine called to dump out the entire resource hierarchy
//
void DumpResourceSection(DWORD base, PIMAGE_NT_HEADERS pNTHeader)
{
PIMAGE_RESOURCE_DIRECTORY resDir;
resDir = GetSectionPtr(".rsrc", pNTHeader, (DWORD)base);
if ( !resDir )
return;
printf("Resources\n");
DumpResourceDirectory(resDir, (DWORD)resDir, 0, 0);
}
//
// Dump the imports table (the .idata section) of a PE file
//
void DumpImportsSection(DWORD base, PIMAGE_NT_HEADERS pNTHeader)
{
PIMAGE_IMPORT_DESCRIPTOR importDesc;
PIMAGE_SECTION_HEADER pSection;
PIMAGE_THUNK_DATA thunk, thunkIAT=0;
PIMAGE_IMPORT_BY_NAME pOrdinalName;
DWORD importsStartRVA;
INT delta = -1;
// Look up where the imports section is (normally in the .idata section)
// but not necessarily so. Therefore, grab the RVA from the data dir.
importsStartRVA = pNTHeader->OptionalHeader.DataDirectory
[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
if ( !importsStartRVA )
return;
// Get the IMAGE_SECTION_HEADER that contains the imports. This is
// usually the .idata section, but doesn't have to be.
pSection = GetEnclosingSectionHeader( importsStartRVA, pNTHeader );
if ( !pSection )
return;
delta = (INT)(pSection->VirtualAddress-pSection->PointerToRawData);
importDesc = (PIMAGE_IMPORT_DESCRIPTOR) (importsStartRVA - delta + base);
printf("Imports Table:\n");
while ( 1 )
{
// See if we've reached an empty IMAGE_IMPORT_DESCRIPTOR
if ( (importDesc->TimeDateStamp==0 ) && (importDesc->Name==0) )
break;
printf(" %s\n", (PBYTE)(importDesc->Name) - delta + base);
printf(" Hint/Name Table: %08X\n", importDesc->Characteristics);
printf(" TimeDateStamp: %08X\n", importDesc->TimeDateStamp);
printf(" ForwarderChain: %08X\n", importDesc->ForwarderChain);
printf(" First thunk RVA: %08X\n", importDesc->FirstThunk);
thunk = (PIMAGE_THUNK_DATA)importDesc->Characteristics;
thunkIAT = (PIMAGE_THUNK_DATA)importDesc->FirstThunk;
if ( thunk == 0 ) // No Characteristics field?
{
// Yes! Gotta have a non-zero FirstThunk field then.
thunk = thunkIAT;
if ( thunk == 0 ) // No FirstThunk field? Ooops!!!
return;
}
// Adjust the pointer to point where the tables are in the
// mem mapped file.
thunk = (PIMAGE_THUNK_DATA)( (PBYTE)thunk - delta + base);
thunkIAT = (PIMAGE_THUNK_DATA)( (PBYTE)thunkIAT - delta + base);
printf(" Ordn Name\n");
while ( 1 ) // Loop forever (or until we break out)
{
if ( thunk->u1.AddressOfData == 0 )
break;
if ( thunk->u1.Ordinal & IMAGE_ORDINAL_FLAG )
{
printf( " %4u", IMAGE_ORDINAL(thunk->u1.Ordinal) );
}
else
{
pOrdinalName = thunk->u1.AddressOfData;
pOrdinalName = (PIMAGE_IMPORT_BY_NAME)
((PBYTE)pOrdinalName - delta + base);
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -