#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
void Start(void);
void Usage(void);
BOOL ShowHeaders(PIMAGE_NT_HEADERS);
BOOL ShowSections(PIMAGE_NT_HEADERS);
BOOL ShowImport(LPVOID, PIMAGE_NT_HEADERS);
BOOL ShowExport(LPVOID, PIMAGE_NT_HEADERS);
BOOL ShowRelocation(LPVOID, PIMAGE_NT_HEADERS);
DWORD RVA2Offset(DWORD,PIMAGE_NT_HEADERS);
BOOL ShowHeaders(PIMAGE_NT_HEADERS pNTHeaders)
{
PIMAGE_FILE_HEADER pFileHeader;
PIMAGE_OPTIONAL_HEADER pOptiHeader;
pFileHeader = (PIMAGE_FILE_HEADER)&pNTHeaders->FileHeader;
pOptiHeader = (PIMAGE_OPTIONAL_HEADER)&pNTHeaders->OptionalHeader;
printf("\n=== File Header Value ===\n\n");
printf("Machine:\t\t %.4X: ",pFileHeader->Machine);
switch(pFileHeader->Machine)
{
case IMAGE_FILE_MACHINE_I386:
printf("Intel 386\n");
break;
case 0x014d:
printf("Intel 486\n");
break;
case 0x014e:
printf("Intel Pentium\n");
break;
case 0x0160:
printf("R3000 big endian\n");
break;
case IMAGE_FILE_MACHINE_R3000:
printf("R3000 little endian\n");
break;
case IMAGE_FILE_MACHINE_R4000:
printf("R4000 little endian\n");
break;
case IMAGE_FILE_MACHINE_R10000:
printf("R10000 little endian)\n");
break;
case IMAGE_FILE_MACHINE_ALPHA:
printf("DEC Alpha_AXP\n");
break;
case IMAGE_FILE_MACHINE_POWERPC:
printf("Power PC\n");
break;
default:
printf("Unknown Machine Type\n");
break;
}
printf("NumberOfSections:\t %X\n",pFileHeader->NumberOfSections);
printf("TimeDateStamp:\t\t %X: ",pFileHeader->TimeDateStamp);
printf("%s",asctime(gmtime((const __int64 *)&pFileHeader->TimeDateStamp)));
printf("PointerToSymbolTable:\t %X\n",pFileHeader->PointerToSymbolTable);
printf("NumberOfSymbols:\t %X\n",pFileHeader->NumberOfSections);
printf("SizeOfOptionalHeader:\t %.4X\n",pFileHeader->SizeOfOptionalHeader);
printf("Characteristics:\t %.4X\n",pFileHeader->Characteristics);
if(pFileHeader->Characteristics & IMAGE_FILE_SYSTEM)
printf("\t\t\t System File\n");
if(pFileHeader->Characteristics & IMAGE_FILE_DLL)
printf("\t\t\t DLL File\n");
if(pFileHeader->Characteristics & IMAGE_FILE_EXECUTABLE_IMAGE)
printf("\t\t\t Executable\n");
if(pFileHeader->Characteristics & IMAGE_FILE_32BIT_MACHINE)
printf("\t\t\t 32 bit word machine\n");
if(pFileHeader->Characteristics & IMAGE_FILE_DEBUG_STRIPPED)
printf("\t\t\t Debugging stripped\n");
if(pFileHeader->Characteristics & IMAGE_FILE_RELOCS_STRIPPED)
printf("\t\t\t Relocation stripped\n");
if(pFileHeader->Characteristics & IMAGE_FILE_LINE_NUMS_STRIPPED)
printf("\t\t\t Line nunbers stripped\n");
if(pFileHeader->Characteristics & IMAGE_FILE_LOCAL_SYMS_STRIPPED)
printf("\t\t\t Local symbols stripped\n");
if(pFileHeader->Characteristics & IMAGE_FILE_AGGRESIVE_WS_TRIM)
printf("\t\t\t Agressively trim working set\n");
if(pFileHeader->Characteristics & IMAGE_FILE_LARGE_ADDRESS_AWARE)
printf("\t\t\t App can handle >2GB addresses\n");
if(pFileHeader->Characteristics & IMAGE_FILE_BYTES_REVERSED_LO)
printf("\t\t\t Bytes of machine word are reversed\n");
if(pFileHeader->Characteristics & IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP)
printf("\t\t\t If Image is on removable media, copy and run from the swap file\n");
if(pFileHeader->Characteristics & IMAGE_FILE_NET_RUN_FROM_SWAP)
printf("\t\t\t If Image is on Net, copy and run from the swap file.\n");
if(pFileHeader->Characteristics & IMAGE_FILE_UP_SYSTEM_ONLY)
printf("\t\t\t Run on a UP machine\n");
if(pFileHeader->Characteristics & IMAGE_FILE_BYTES_REVERSED_HI)
printf("\t\t\t Bytes of machine word are reversed\n");
printf("\n");
printf("=== Optional Header Value ===\n\n");
printf("Magic:\t\t\t %.4X\n",pOptiHeader->Magic);
printf("LinkVersion:\t\t %d.%d\n",pOptiHeader->MajorLinkerVersion,pOptiHeader->MinorLinkerVersion);
printf("SizeOfCode:\t\t %.8X\n",pOptiHeader->SizeOfCode);
printf("SizeOfInitializedData:\t %.8X\n",pOptiHeader->SizeOfInitializedData);
printf("SizeOfUninitializedData: %.8X\n",pOptiHeader->SizeOfUninitializedData);
printf("AddressOfEntryPoint:\t %.8X\n",pOptiHeader->AddressOfEntryPoint);
printf("BaseOfCode:\t\t %.8X\n",pOptiHeader->BaseOfCode);
printf("BaseOfData:\t\t %.8X\n",pOptiHeader->BaseOfData);
printf("ImageBase:\t\t %.8X\n",pOptiHeader->ImageBase);
printf("SizeOfImage:\t\t %.8X\n",pOptiHeader->SizeOfImage);
printf("SizeOfHeaders:\t\t %.8X\n",pOptiHeader->SizeOfHeaders);
printf("SectionAlignment:\t %.8X\n",pOptiHeader->SectionAlignment);
printf("FileAlignment:\t\t %.8X\n",pOptiHeader->FileAlignment);
printf("OperatingSystemVersion:\t %d.%d\n",pOptiHeader->MajorOperatingSystemVersion,pOptiHeader->MinorOperatingSystemVersion);
printf("ImageVersion:\t\t %d.%d\n",pOptiHeader->MajorImageVersion,pOptiHeader->MinorImageVersion);
printf("SubSystemVersion:\t %d.%d\n",pOptiHeader->MajorSubsystemVersion,pOptiHeader->MinorSubsystemVersion);
printf("SubSystem:\t\t %.4X: ",pOptiHeader->Subsystem);
switch(pOptiHeader->Subsystem)
{
case IMAGE_SUBSYSTEM_NATIVE:
puts("Native");
break;
case IMAGE_SUBSYSTEM_WINDOWS_GUI:
puts("Win32 Graphical (GUI)");
break;
case IMAGE_SUBSYSTEM_WINDOWS_CUI:
puts("Win32 Console (CUI)");
break;
case IMAGE_SUBSYSTEM_OS2_CUI:
puts("OS/2 Console");
break;
case IMAGE_SUBSYSTEM_POSIX_CUI:
puts("Posix Console");
break;
default:
puts("Unknown");
break;
}
printf("DllCharacteristics:\t %.4X\n",pOptiHeader->DllCharacteristics);
printf("CheckSum:\t\t %.8X\n",pOptiHeader->CheckSum);
printf("SizeOfStackReserve:\t %.8X\n",pOptiHeader->SizeOfStackReserve);
printf("SizeOfStackCommit:\t %.8X\n",pOptiHeader->SizeOfStackCommit);
printf("SizeOfHeapReserve:\t %.8X\n",pOptiHeader->SizeOfHeapReserve);
printf("SizeOfHeapCommit:\t %.8X\n",pOptiHeader->SizeOfHeapCommit);
printf("LoaderFlags:\t\t %.8X\n",pOptiHeader->LoaderFlags);
printf("NumberOfRvaAndSizes:\t %.8X\n",pOptiHeader->NumberOfRvaAndSizes);
printf("DataDirectory:\t\t %-20s%-12s%-12s\n","Name","Size","RVA");
printf("\t\t\t %-20s%.8X\t %.8X\n","Export",pOptiHeader->DataDirectory[0].Size,pOptiHeader->DataDirectory[0].VirtualAddress);
printf("\t\t\t %-20s%.8X\t %.8X\n","Import",pOptiHeader->DataDirectory[1].Size,pOptiHeader->DataDirectory[1].VirtualAddress);
printf("\t\t\t %-20s%.8X\t %.8X\n","Resource",pOptiHeader->DataDirectory[2].Size,pOptiHeader->DataDirectory[2].VirtualAddress);
printf("\t\t\t %-20s%.8X\t %.8X\n","Exception",pOptiHeader->DataDirectory[3].Size,pOptiHeader->DataDirectory[3].VirtualAddress);
printf("\t\t\t %-20s%.8X\t %.8X\n","Security",pOptiHeader->DataDirectory[4].Size,pOptiHeader->DataDirectory[4].VirtualAddress);
printf("\t\t\t %-20s%.8X\t %.8X\n","BaseRelocate",pOptiHeader->DataDirectory[5].Size,pOptiHeader->DataDirectory[5].VirtualAddress);
printf("\t\t\t %-20s%.8X\t %.8X\n","Debug",pOptiHeader->DataDirectory[6].Size,pOptiHeader->DataDirectory[6].VirtualAddress);
printf("\t\t\t %-20s%.8X\t %.8X\n","Architecture",pOptiHeader->DataDirectory[7].Size,pOptiHeader->DataDirectory[7].VirtualAddress);
printf("\t\t\t %-20s%.8X\t %.8X\n","GlobalPtr",pOptiHeader->DataDirectory[8].Size,pOptiHeader->DataDirectory[8].VirtualAddress);
printf("\t\t\t %-20s%.8X\t %.8X\n","TLS",pOptiHeader->DataDirectory[9].Size,pOptiHeader->DataDirectory[9].VirtualAddress);
printf("\t\t\t %-20s%.8X\t %.8X\n","LoadConfig",pOptiHeader->DataDirectory[10].Size,pOptiHeader->DataDirectory[10].VirtualAddress);
printf("\t\t\t %-20s%.8X\t %.8X\n","Bound",pOptiHeader->DataDirectory[11].Size,pOptiHeader->DataDirectory[1].VirtualAddress);
printf("\t\t\t %-20s%.8X\t %.8X\n","ImportAddress",pOptiHeader->DataDirectory[12].Size,pOptiHeader->DataDirectory[12].VirtualAddress);
printf("\t\t\t %-20s%.8X\t %.8X\n","DelayLoadImport",pOptiHeader->DataDirectory[13].Size,pOptiHeader->DataDirectory[13].VirtualAddress);
printf("\t\t\t %-20s%.8X\t %.8X\n","COM",pOptiHeader->DataDirectory[14].Size,pOptiHeader->DataDirectory[14].VirtualAddress);
printf("\t\t\t %-20s%.8X\t %.8X\n","Reserved",pOptiHeader->DataDirectory[15].Size,pOptiHeader->DataDirectory[15].VirtualAddress);
return TRUE;
}
BOOL ShowSections(PIMAGE_NT_HEADERS pNTHeaders)
{
PIMAGE_SECTION_HEADER pSectionHeader;
WORD dwNumOfSection;
WORD i;
printf("\n=== Section Table ===\n");
dwNumOfSection = pNTHeaders->FileHeader.NumberOfSections;
for(i=0; i < dwNumOfSection; i++)
{
pSectionHeader = (PIMAGE_SECTION_HEADER)((char *)pNTHeaders + sizeof(IMAGE_NT_HEADERS) + i*sizeof(IMAGE_SECTION_HEADER));
printf("\nSection %-2d (%s):\n",i+1,pSectionHeader->Name);
printf("VirtualAddress:\t\t %.8X\n",pSectionHeader->VirtualAddress);
printf("SizeOfRawData:\t\t %.8X\n",pSectionHeader->SizeOfRawData);
printf("PointerToRawData:\t %.8X\n",pSectionHeader->PointerToRawData);
printf("PointerToRelocations:\t %.8X\n",pSectionHeader->PointerToRelocations);
printf("PointerToLinenumbers:\t %.8X\n",pSectionHeader->PointerToLinenumbers);
printf("NumberOfRelocations:\t %.8X\n",pSectionHeader->NumberOfRelocations);
printf("NumberOfLinenumbers:\t %.8X\n",pSectionHeader->NumberOfLinenumbers);
printf("Characteristics:\t %.8X\n",pSectionHeader->Characteristics);
}
return TRUE;
}
BOOL ShowImport(LPVOID pBasePointer,PIMAGE_NT_HEADERS pNTHeaders)
{
DWORD dwThunk;
DWORD dwRVA;
DWORD dwOffset;
PIMAGE_IMPORT_DESCRIPTOR pImportDescriptor;
PIMAGE_THUNK_DATA pThunkData;
PIMAGE_IMPORT_BY_NAME pImportByName;
printf("\n=== Import Table ===\n");
dwOffset = 0;
pImportDescriptor = NULL;
dwRVA = pNTHeaders->OptionalHeader.DataDirectory[1].VirtualAddress;
dwOffset = RVA2Offset(dwRVA, pNTHeaders);
if(dwOffset == 0)
{
printf("Can't get the Offset for Import Descriptor\n");
return FALSE;
}
else
{
pImportDescriptor = (PIMAGE_IMPORT_DESCRIPTOR)((char *)pBasePointer + dwOffset);
}
while( pImportDescriptor->Characteristics
|| pImportDescriptor->TimeDateStamp
|| pImportDescriptor->ForwarderChain
|| pImportDescriptor->FirstThunk
|| pImportDescriptor->Name)
{
dwRVA = pImportDescriptor->Name;
dwOffset = RVA2Offset(dwRVA, pNTHeaders);
if(dwOffset == 0)
{
printf("Can't get the offset for Name\n");
return FALSE;
}
else
{
printf("\n** %s **\n\n",(char *)pBasePointer + dwOffset);
}
printf("Characteristics:\t %.8X\n",pImportDescriptor->Characteristics);
printf("TimeDateStamp:\t\t %.8X\n",pImportDescriptor->TimeDateStamp);
printf("ForwarderChain:\t\t %.8X\n",pImportDescriptor->ForwarderChain);
printf("FirstThunk:\t\t %.8X\n",pImportDescriptor->FirstThunk);
printf("OrigianlFirstThunk:\t %.8X\n",pImportDescriptor->OriginalFirstThunk);
printf("Name RVA:\t\t %.8X\n\n",pImportDescriptor->Name);
dwThunk = (DWORD)pImportDescriptor->OriginalFirstThunk;
if(dwThunk == 0)
{
dwThunk = (DWORD)pImportDescriptor->FirstThunk;
}
while(TRUE)
{
dwRVA = dwThunk;
dwOffset = RVA2Offset(dwRVA,pNTHeaders);
pThunkData = (PIMAGE_THUNK_DATA)((char *)pBasePointer + dwOffset);
if(IMAGE_ORDINAL_FLAG32 & (DWORD)pThunkData)
{
printf("Ordinal: %x\t",(WORD)pThunkData);
}
else
{
dwRVA = *(DWORD *)pThunkData;
dwOffset = RVA2Offset(dwRVA,pNTHeaders);
if(dwOffset == 0)
{
break;
}
pImportByName = (PIMAGE_IMPORT_BY_NAME)((char *)pBasePointer + dwOffset);
printf("Ordinal:\t %.4X\t ",pImportByName->Hint);
printf("Name:\t %s\n",pImportByName->Name);
}
dwThunk += sizeof(IMAGE_THUNK_DATA);
}
pImportDescriptor = (PIMAGE_IMPORT_DESCRIPTOR)((char *)pImportDescriptor + sizeof(IMAGE_IMPORT_DESCRIPTOR));
}
return TRUE;
}
BOOL ShowExport(LPVOID pBasePointer,PIMAGE_NT_HEADERS pNTHeaders)
{
DWORD dwBase;
DWORD dwRVA;
DWORD dwOffset;
WORD wIndex;
DWORD dwIndex;
DWORD dwNumberOfNames;
PIMAGE_EXPORT_DIRECTORY pExportDirectory;
dwRVA = pNTHeaders->OptionalHeader.DataDirectory[0].VirtualAddress;
if(dwRVA == 0)
{
return FALSE;
}
dwOffset = RVA2Offset(dwRVA,pNTHeaders);
pExportDirectory = (PIMAGE_EXPORT_DIRECTORY)((char *)pBasePointer + dwOffset);
dwRVA = pExportDirectory->Name;
dwOffset = RVA2Offset(dwRVA,pNTHeaders);
printf("\n=== Export Table ===\n\n");
printf("** %s **\n\n",(char *)pBasePointer + dwOffset);
printf("Characteristics:\t %.8X\n",pExportDirectory->Characteristics);
printf("TimeDateStamp:\t\t %.8X\n",pExportDirectory->TimeDateStamp);
printf("DLL Version:\t\t %d.%d\n",pExportDirectory->MajorVersion,pExportDirectory->MinorVersion);
printf("Base:\t\t\t %.8X\n",pExportDirectory->Base);
printf("Name RVA:\t\t %.8X\n",pExportDirectory->Name);
printf("NumberOfFunctions:\t %.8X (%d)\n",pExportDirectory->NumberOfFunctions,pExportDirectory->NumberOfFunctions);
printf("NumberOfNames:\t\t %.8X (%d)\n",pExportDirectory->NumberOfNames,pExportDirectory->NumberOfNames);
printf("AddressOfFunctions:\t %.8X\n",pExportDirectory->AddressOfFunctions);
printf("AddressOfNames:\t\t %.8X\n",pExportDirectory->AddressOfNames);
printf("AddressOfNameOrdinals:\t %.8X\n\n",pExportDirectory->AddressOfNameOrdinals);
dwBase = pExportDirectory->Base;
dwNumberOfNames = pExportDirectory->NumberOfNames;
for(dwIndex = 0; dwIndex <= dwNumberOfNames; dwIndex ++)
{
dwRVA = pExportDirectory->AddressOfNameOrdinals + dwIndex * sizeof(WORD);
dwOffset = RVA2Offset(dwRVA,pNTHeaders);
if(dwOffset == 0)
{
break;
}
wIndex = *(WORD *)((char *)pBasePointer + dwOffset);
dwRVA = pExportDirectory->AddressOfFunctions + wIndex * sizeof(DWORD);
dwOffset = RVA2Offset(dwRVA,pNTHeaders);
if(dwOffset == 0)
{
break;
}
printf("Ordinal: %.4d ",wIndex + dwBase);
printf("RVA: %.8X ",*(DWORD *)((char *)pBasePointer + dwOffset));
dwRVA = pExportDirectory->AddressOfNames + dwIndex * sizeof(DWORD);
dwOffset = RVA2Offset(dwRVA,pNTHeaders);
if(dwOffset == 0)
{
break;
}
dwRVA = *(DWORD *)((char *)pBasePointer + dwOffset);
dwOffset = RVA2Offset(dwRVA,pNTHeaders);
if(dwOffset == 0)
{
break;
}
printf("Name: %.8X %s\n",dwOffset,(char *)pBasePointer + dwOffset);
}
return TRUE;
}
BOOL ShowRelocation(LPVOID pBasePointer, PIMAGE_NT_HEADERS pNTHeaders)
{
DWORD dwIndex;
DWORD dwRVA;
DWORD dwOffset;
DWORD dwTotalBlock;
DWORD dwTotalRelocation;
DWORD dwRelocation;
PIMAGE_BASE_RELOCATION pBaseRelocation;
dwRVA = pNTHeaders->OptionalHeader.DataDirectory[5].VirtualAddress;
dwOffset = RVA2Offset(dwRVA,pNTHeaders);
if(dwOffset == 0)
{
return FALSE;
}
printf("\n=== Base Relocation ===\n\n");
dwTotalBlock = 0;
dwTotalRelocation = 0;
pBaseRelocation = (PIMAGE_BASE_RELOCATION)((char *)pBasePointer + dwOffset);
while(pBaseRelocation->VirtualAddress != 0)
{
dwRelocation = (pBaseRelocation->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION))/2;
printf("VirtualAddress:\t\t %.8X\n",pBaseRelocation->VirtualAddress);
printf("SizeOfBlock:\t\t %.8X\n",pBaseRelocation->SizeOfBlock);
printf("NumberOfBlock:\t\t %.8X\n",dwRelocation);
dwRVA = pBaseRelocation->VirtualAddress;
dwOffset = RVA2Offset(dwRVA,pNTHeaders);
for(dwIndex = 0; dwIndex < dwRelocation; dwIndex++)
{
printf("%.8X\t\t",*(WORD *)((char *)pBasePointer + dwOffset + dwIndex * sizeof(WORD)));
printf("\n");
}
dwTotalBlock += 1;
dwTotalRelocation += dwRelocation;
pBaseRelocation += sizeof(IMAGE_BASE_RELOCATION) + 2 * pBaseRelocation->SizeOfBlock;
}
printf("\n");
printf("TotalBlock:\t\t %.8X\n",dwTotalBlock);
printf("TotalRelocation:\t %.8X\n",dwRelocation);
return TRUE;
}
DWORD RVA2Offset(DWORD dwRVA,PIMAGE_NT_HEADERS pNTHeaders)
{
DWORD dwIndex;
DWORD dwSectionNumber;
DWORD dwStart;
DWORD dwEnd;
DWORD dwOffset;
PIMAGE_SECTION_HEADER pSectionHeader;
dwOffset = 0;
dwIndex = 0;
dwSectionNumber = pNTHeaders->FileHeader.NumberOfSections;
while(dwIndex < dwSectionNumber)
{
pSectionHeader = (PIMAGE_SECTION_HEADER)((char *)pNTHeaders
+ sizeof(IMAGE_NT_HEADERS)
+ dwIndex * sizeof(IMAGE_SECTION_HEADER));
dwStart = pSectionHeader->VirtualAddress;
dwEnd = pSectionHeader->SizeOfRawData + dwStart;
if(dwRVA <= dwEnd && dwRVA >= dwStart)
{
dwOffset = pSectionHeader->PointerToRawData + dwRVA - dwStart;
break;
}
else
{
dwIndex ++;
continue;
}
}
return dwOffset;
}
void Start()
{
printf("\n");
printf("\t\t---[ T-PE Analyst, by Brief ]---\n");
printf("\t\t---[ E-mail: awayawell@sina.com ]---\n");
printf("\t\t---[ HomePage: away.xinwen520.com ]---\n");
printf("\t\t---[ Date: 03-15-2003 ]---\n\n");
return ;
}
void Usage()
{
printf("Usage: T-PE [-a|-h|-s|-i|-e] CmdName\n");
printf(" -a\tShow All information\n");
printf(" -h\tShow Header information\n");
printf(" -s\tShow Section information\n");
printf(" -i\tShow Imports information\n");
printf(" -e\tShow Exports information\n");
return ;
}
|