记录一下控制台版的PeInfo
开发环境:MinGW Dev-C++
代码:
//#include "widget.h"
//#include <QApplication>
//int main(int argc, char *argv[])
//{
// QApplication a(argc, argv);
// Widget w;
// w.show();
// return a.exec();
//}
#include<iostream>
#include<windows.h>
#include<winnt.h>
#include<time.h>
using namespace std;
const static char* tableName[IMAGE_NUMBEROF_DIRECTORY_ENTRIES] = {"导出表","导入表","资源表","异常表",\
"安全表","重定位表",\
"调试表","版权表","全局指针表","线程本地存储",\
"加载配置表","绑定导入表","IAT表",\
"延迟导入表","CLR表","保留未用"};
DWORD RvaToFva(LPVOID base,DWORD Va)
{
int sectionNum = ((PIMAGE_NT_HEADERS32)(base + ((PIMAGE_DOS_HEADER)base)->e_lfanew))->FileHeader.NumberOfSections;
PIMAGE_SECTION_HEADER sectionTable = IMAGE_FIRST_SECTION((PIMAGE_NT_HEADERS32)(base + ((PIMAGE_DOS_HEADER)base)->e_lfanew));
for(int i=0;i<sectionNum;i++)
{
if((sectionTable[i].VirtualAddress + sectionTable[i].SizeOfRawData)>Va)//考虑是一个内存中的VA而不是PE里面的VA
{
return sectionTable[i].PointerToRawData + (Va - sectionTable[i].VirtualAddress);
}
}
return NULL;
}
void searchResource(LPVOID base,PIMAGE_RESOURCE_DIRECTORY beginEntry,PIMAGE_RESOURCE_DIRECTORY entry,int level = 1)
{
int totalNum = entry->NumberOfNamedEntries + entry->NumberOfIdEntries;
string tab = "";
for(int i=0;i<level;i++)
{
tab+=" ";
}
if(level==3)
{
tab+=" ";
}
printf("%sThis is %d Level Directory.起始文件偏移:0x%-X\n",tab.c_str(),level,(char*)entry-(char*)base);
printf("%s\t提示信息 \t信息\n",tab.c_str());
printf("%s\t%-s\t%-d\n",tab.c_str(),"名称入口数量",entry->NumberOfNamedEntries);
printf("%s\t%-s\t%-d\n",tab.c_str(),"ID入口数量",entry->NumberOfIdEntries);
printf("%s\t%-s\t%-d\n",tab.c_str(),"总的入口数量",totalNum);
PIMAGE_RESOURCE_DIRECTORY_ENTRY firstEntry = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)((unsigned char*)entry + sizeof(IMAGE_RESOURCE_DIRECTORY));
printf("%s\tID/Name\t起始内存偏移\t资源长度\t文件偏移\t指向文件偏移\n",tab.c_str());
for(int i=0;i<totalNum;i++)
{
IMAGE_RESOURCE_DIRECTORY_ENTRY temp = firstEntry[i];
if(temp.DataIsDirectory)
{
PIMAGE_RESOURCE_DIRECTORY newentry = (PIMAGE_RESOURCE_DIRECTORY)((unsigned char*)beginEntry + temp.OffsetToDirectory);
if(temp.NameIsString)
{
DWORD offset = temp.Name^(0x80000000);
PIMAGE_RESOURCE_DIR_STRING_U str = (PIMAGE_RESOURCE_DIR_STRING_U)((char*)beginEntry + offset);
printf("%-s\t%-7X\t%-12X\t%-8X\t%-8X\t0x%-12X",tab.c_str(),offset,0,str->Length,2,(char*)beginEntry-(char*)base+offset);
// return;
}
else
{
printf("%s\t%-7d\t",tab.c_str(),temp.Id);
}
cout<<endl;
searchResource(base,beginEntry,newentry,level+1);
}
else
{
PIMAGE_RESOURCE_DATA_ENTRY dataEntry = (PIMAGE_RESOURCE_DATA_ENTRY)((unsigned char*)beginEntry + temp.OffsetToDirectory);
if(temp.NameIsString)
{
// printf("%s\t%-X\t",tab.c_str(),temp.Name);
// printf("%s\t%X\t%X\t%X\t%X\t%X",tab.c_str(),temp.Name,0,1,2,3,4);
DWORD offset = temp.Name^(0x80000000);
PIMAGE_RESOURCE_DIR_STRING_U str = (PIMAGE_RESOURCE_DIR_STRING_U)((char*)beginEntry + offset);
printf("%-s\t%-7X\t%-12X\t%-8X\t%-8X\t0x%-12X",tab.c_str(),offset,0,str->Length,2,(char*)beginEntry-(char*)base+offset);
}
else
{
printf("%s\t%-7d\t",tab.c_str(),temp.Id);
}
printf("0x%-12X\t0x%-8X\t0x%-8X\t0x%-X\n",dataEntry->OffsetToData,dataEntry->Size,((char*)dataEntry - (char*)base),RvaToFva(base,dataEntry->OffsetToData)/*((char*)dataEntry - (char*)base)*/);
}
}
}
void showPeExt(LPVOID base)
{
PIMAGE_DOS_HEADER dosHeader;
dosHeader = (PIMAGE_DOS_HEADER)base;
PIMAGE_NT_HEADERS64 nth = (PIMAGE_NT_HEADERS64)(base + dosHeader->e_lfanew);
PIMAGE_FILE_HEADER fileh = (PIMAGE_FILE_HEADER)&(nth->FileHeader);
char str[100];
string attr = "unknown";
if(fileh->Machine==IMAGE_FILE_MACHINE_I386)
{
attr = "Intel 386处理器";
}
else if(fileh->Machine==IMAGE_FILE_MACHINE_AMD64)
{
attr = "x64处理器";
}
else if(fileh->Machine==IMAGE_FILE_MACHINE_ARM)
{
attr = "ARM小尾处理器";
}
else if(fileh->Machine==IMAGE_FILE_MACHINE_ARMV7)
{
attr = "ARMv7处理器的Thumb模式";
}
else if(fileh->Machine==IMAGE_FILE_MACHINE_IA64)
{
attr = "Intel Itanium处理器";
}
else if(fileh->Machine==IMAGE_FILE_MACHINE_POWERPC)
{
attr = "Power PC小尾处理器";
}
else if(fileh->Machine==IMAGE_FILE_MACHINE_THUMB)
{
attr = "ARM或Thumb处理器";
}
cout<<"IMAGE_FILE_HEADER----------------------------------------------------------\n";
cout<<"属性名称\t属性 \t文件偏移\t大小\t转换属性\n";
printf("%-8s\t%-8d\t0x%-8X\t%-4d\n","节区数量",fileh->NumberOfSections,((char*)&fileh->NumberOfSections - (char*)base),sizeof(IMAGE_FILE_HEADER::NumberOfSections));
printf("%-8s\t0x%-8X\t%-8X\t%-4d\t%s\n","机器类别",fileh->Machine,((char*)&fileh->Machine - (char*)base),sizeof(IMAGE_FILE_HEADER::Machine),attr.c_str());
time_t time = fileh->TimeDateStamp;
struct tm* ttime;
ttime = localtime(&time);
char now[24];
strftime(now,24,"%Y-%m-%d %H:%M:%S",ttime);
printf("%-8s\t%-8X\t%-8X\t%-4d\t%-s\n","时间戳",fileh->TimeDateStamp,((char*)&fileh->TimeDateStamp - (char*)base),sizeof(IMAGE_FILE_HEADER::TimeDateStamp),now);
printf("%-8s\t0x%-8X\t%-8X\t%-4d\t%-d\n","可选大小",fileh->SizeOfOptionalHeader,((char*)&fileh->SizeOfOptionalHeader - (char*)base),sizeof(IMAGE_FILE_HEADER::SizeOfOptionalHeader),fileh->SizeOfOptionalHeader);
attr = "";
bool attrTable[16];
memset(attrTable,0,16);
int count = 0;
WORD num = 1;
WORD sx = fileh->Characteristics;
while(num){
if(sx&num)
{
attrTable[count] = true;
}
num<<=1;
count++;
}
if(attrTable[0])
{
attr = attr + "[无重定位]";
}
if(attrTable[1])
{
attr = attr + "[可执行]";
}
if(attrTable[8])
{
attr = attr + "[只能32位]";
}
if(attrTable[10])
{
attr = attr + "[不能从U盘]";
}
if(attrTable[11])
{
attr = attr + "[不能从网络]";
}
if(attrTable[12])
{
attr = attr + "[系统文件]";
}
if(attrTable[13])
{
attr = attr + "[dll文件]";
}
if(attrTable[14])
{
attr = attr + "[不能在多cpu计算机]";
}
printf("%-8s\t0x%-8X\t0x%-8X\t%-4d\t%s\n","文件属性",fileh->Characteristics,((char*)&fileh->Characteristics - (char*)base),sizeof(IMAGE_FILE_HEADER::Characteristics),attr.c_str());
cout<<"---------------------------------------------------------------------------\n\n";
cout<<"IMAGE_OPTIONAL_HEADER64-----------------------------------------\n";
cout<<"属性名称 \t属性 \t文件偏移\t大小\t补充\n";
PIMAGE_OPTIONAL_HEADER64 ophead= (PIMAGE_OPTIONAL_HEADER64)&(nth->OptionalHeader);
attr = "";
if(ophead->Magic==0x10B)
{
attr="PE32";
}
else if(ophead->Magic==0x107)
{
attr=="ROM";
}
else if(ophead->Magic==0x20B)
{
attr=="PE32+";
}
printf("%-20s\t0x%-8X\t0x%-8X\t%-4d\t%s\n","Magic",ophead->Magic,((char*)&ophead->Magic - (char*)base),sizeof(IMAGE_OPTIONAL_HEADER64::Magic),attr.c_str());
printf("%-20s\t0x%-8X\t0x%-8X\t%-4d\t%s\n","CheckSum",ophead->CheckSum,((char*)&ophead->CheckSum - (char*)base),sizeof(IMAGE_OPTIONAL_HEADER64::CheckSum),"可为0");
printf("%-20s\t0x%-8X\t0x%-8X\t%-4d\t%s\n","NumberOfRvaAndSizes",ophead->NumberOfRvaAndSizes,((char*)&ophead->NumberOfRvaAndSizes - (char*)base),sizeof(IMAGE_OPTIONAL_HEADER64::NumberOfRvaAndSizes),"一般等同于数据目录表的数目");
printf("%-20s\t0x%-8llX\t0x%-8X\t%-4d\t%s\n","ImageBase",ophead->ImageBase,((char*)&ophead->ImageBase - (char*)base),sizeof(IMAGE_OPTIONAL_HEADER64::ImageBase),"0x10000H字节的整数倍");
printf("%-20s\t0x%-8X\t0x%-8X\t%d\n","AddressOfEntryPoint",ophead->AddressOfEntryPoint,((char*)&ophead->AddressOfEntryPoint - (char*)base),sizeof(IMAGE_OPTIONAL_HEADER64::AddressOfEntryPoint));
printf("%-20s\t0x%-8X\t0x%-8X\t%d\n","SectionAlignment",ophead->SectionAlignment,((char*)&ophead->SectionAlignment - (char*)base),sizeof(IMAGE_OPTIONAL_HEADER64::SectionAlignment));
printf("%-20s\t0x%-8X\t0x%-8X\t%d\n","FileAlignment",ophead->FileAlignment,((char*)&ophead->FileAlignment - (char*)base),sizeof(IMAGE_OPTIONAL_HEADER64::FileAlignment));
// printf("%-20s\t0x%-8X\t0x%-8X\t%-4d\t%s\n","SizeOfInitializedData",ophead->SizeOfInitializedData,((char*)&ophead->SizeOfInitializedData - (char*)base),sizeof(IMAGE_OPTIONAL_HEADER64::SizeOfInitializedData));
// printf("%-20s\t0x%-8X\t0x%-8X\t%-4d\t%s\n","SizeOfUninitializedData",ophead->SizeOfUninitializedData,((char*)&ophead->SizeOfUninitializedData - (char*)base),sizeof(IMAGE_OPTIONAL_HEADER64::SizeOfUninitializedData));
attr = "";
if(ophead->Subsystem==1)
{
attr = "设备驱动和Native系统进程";
}
else if(ophead->Subsystem==2)
{
attr = "windows图形用户界面";
}
else if(ophead->Subsystem==3)
{
attr = "windows控制台程序";
}
else if(ophead->Subsystem==7)
{
attr = "posix控制台程序";
}
else if(ophead->Subsystem==9)
{
attr = "WindowsCE图形用户界面";
}
else
{
attr = "unknown";
}
printf("%-20s\t0x%-8X\t0x%-8X\t%-4d\t%s\n","Subsystem",ophead->Subsystem,((char*)&ophead->Subsystem - (char*)base),sizeof(IMAGE_OPTIONAL_HEADER64::Subsystem),attr.c_str());
// printf("%-20s\t0x%-8X\t0x%-8X\t%-4d\t%s\n","BaseOfData",ophead->BaseOfData,((char*)&ophead->BaseOfData - (char*)base),sizeof(IMAGE_OPTIONAL_HEADER64::BaseOfData),"一般为.data段起始内存偏移");
printf("%-20s\t0x%-8X\t0x%-8X\t%-4d\t%s\n","BaseOfCode",ophead->BaseOfCode,((char*)&ophead->BaseOfCode - (char*)base),sizeof(IMAGE_OPTIONAL_HEADER64::BaseOfCode),"一般为.text段起始内存偏移");
printf("%-20s\t0x%-8X\t0x%-8X\t%-4d\t%s\n","SizeOfCode",ophead->SizeOfCode,((char*)&ophead->SizeOfCode - (char*)base),sizeof(IMAGE_OPTIONAL_HEADER64::SizeOfCode),"所有代码对齐后的大小");
printf("%-20s\t0x%-8X\t0x%-8X\t%-4d\t%s\n","SizeOfImage",ophead->SizeOfImage,((char*)&ophead->SizeOfImage - (char*)base),sizeof(IMAGE_OPTIONAL_HEADER64::SizeOfImage),"内存中PE映像大小");
printf("%-20s\t0x%-8X\t0x%-8X\t%-4d\t%s\n","SizeOfHeaders",ophead->SizeOfHeaders,((char*)&ophead->SizeOfHeaders - (char*)base),sizeof(IMAGE_OPTIONAL_HEADER64::SizeOfHeaders),"一般情况下等同于第一个节区的起始偏移");
printf("%-20s\t0x%-8X\t0x%-8X\t%-4d\t%s\n","DllCharacteristics",ophead->DllCharacteristics,((char*)&ophead->DllCharacteristics - (char*)base),sizeof(IMAGE_OPTIONAL_HEADER64::DllCharacteristics));
cout<<"------------------------------------------------------------\n";
cout<<"\n数据目录表----------------------------------------------\n";
cout<<"名称 \t内存偏移\t数据大小\t文件偏移\t指向文件偏移\n";
for(int i=0;i<IMAGE_NUMBEROF_DIRECTORY_ENTRIES;i++)
{
printf("%-12s\t0x%-8X\t0x%-8X\t0x%-8X\t0x%-8X\n",tableName[i],ophead->DataDirectory[i].VirtualAddress,ophead->DataDirectory[i].Size,((char*)&ophead->DataDirectory[i] - (char*)base),ophead->DataDirectory[i].VirtualAddress==0?0:RvaToFva(base,ophead->DataDirectory[i].VirtualAddress));
// if(ophead->DataDirectory[i].VirtualAddress==0)
// continue;
// sprintf(str,"%12s:%08XH,%08XH FVA: 0x%08X\n",tableName[i],ophead->DataDirectory[i].VirtualAddress,ophead->DataDirectory[i].Size,((char*)&ophead->DataDirectory[i] - (char*)base));
// cout<<str;
}
cout<<"--------------------------------------------------------\n";
cout<<endl;
PIMAGE_SECTION_HEADER sectionTable = IMAGE_FIRST_SECTION(nth);
cout<<"节区表----------------------------------------------------------------------------------\n";
cout<<"节区名称\t节区文件偏移\t节区内存偏移\t节区大小\t节区对齐大小\t节区属性\t属性解释\n";
sprintf(str,"%-8X\t%-12X\t%-12X\t%-8X\t%-12X\t%-8X\n",sizeof(IMAGE_SECTION_HEADER::Name),sizeof(IMAGE_SECTION_HEADER::PointerToRawData),sizeof(IMAGE_SECTION_HEADER::VirtualAddress),sizeof(IMAGE_SECTION_HEADER::VirtualAddress),sizeof(IMAGE_SECTION_HEADER::SizeOfRawData),sizeof(IMAGE_SECTION_HEADER::Characteristics));
cout<<str;
for(int i=0;i<fileh->NumberOfSections;i++)
{
if(true)
{
IMAGE_SECTION_HEADER data = sectionTable[i];
attr = "";
if((data.Characteristics&0x20000000)==0x20000000)
{
attr+="E";
}
if((data.Characteristics&0x40000000)==0x40000000)
{
attr+="R";
}
if((data.Characteristics&0x80000000)==0x80000000)
{
attr+="W";
}
if((data.Characteristics&0x20)==0x20)
{
attr+="C";
}
if((data.Characteristics&0x10000000)==0x10000000)
{
attr+="S";
}
if((data.Characteristics&0x8000000)==0x8000000)
{
attr+=" no up";
}
if((data.Characteristics&0x4000000)==0x4000000)
{
attr+=" no chche";
}
if((data.Characteristics&0x2000000)==0x2000000)
{
attr+=" reloc";
}
if((data.Characteristics&0x80)==0x80)
{
attr+=" uninitdata";
}
if((data.Characteristics&0x40)==0x40)
{
attr+=" initdata";
}
}
sprintf(str,"%-8s\t0x%-12X\t%-12X\t%-8X\t%-12X\t%-8X\t%-s\n",sectionTable[i].Name,sectionTable[i].PointerToRawData,sectionTable[i].VirtualAddress,sectionTable[i].Misc.VirtualSize,sectionTable[i].SizeOfRawData,sectionTable[i].Characteristics,attr.c_str());
cout<<str;
}
cout<<"指向文件偏移--------------------------------------------------------------------------\n";
for(int i=0;i<fileh->NumberOfSections;i++)
{
sprintf(str,"FVA:0x%-8X\t0x%-12X\t0x%-12X\t0x%-8X\t0x%-12X\t0x%-8X\n",((char*)§ionTable[i] - (char*)base),((char*)§ionTable[i].PointerToRawData - (char*)base),((char*)§ionTable[i].VirtualAddress - (char*)base),((char*)§ionTable[i].Misc.VirtualSize - (char*)base),((char*)§ionTable[i].SizeOfRawData - (char*)base),((char*)§ionTable[i].Characteristics - (char*)base) );
cout<<str;
}
cout<<"----------------------------------------------------------------------------------------\n";
// goto test;
//导入表
if(ophead->DataDirectory[1].VirtualAddress!=0)
{
cout<<"导入表---------------------------------------------------------------\n";
DWORD importAddrBegin = RvaToFva(base,ophead->DataDirectory[1].VirtualAddress);
int importDllNum = ophead->DataDirectory[1].Size/sizeof(IMAGE_IMPORT_DESCRIPTOR);//最后多20个字节的NULL,但是也可能是别人手动修改的
PIMAGE_IMPORT_DESCRIPTOR importTable = (PIMAGE_IMPORT_DESCRIPTOR)((unsigned char*)base + importAddrBegin) ;
// printf("%X\n",(importTable[0])->Name);
for(int i=0;i<importDllNum;i++)
{
if(importTable[i].Name==0||importTable[i].Characteristics==0)
{
break;
}
cout<<"属性名称 \t属性 \t文件偏移\t指向文件偏移\n";
printf("%-20s\t0x%-8X\t0x%-8X\t0x%-8X\n","OriginalFirstThunk",importTable[i].OriginalFirstThunk,((char*)&importTable[i].OriginalFirstThunk - (char*)base),RvaToFva(base,importTable[i].OriginalFirstThunk));
printf("%-20s\t0x%-8X\t0x%-8X\n","TimeDateStamp",importTable[i].TimeDateStamp,((char*)&importTable[i].TimeDateStamp - (char*)base));
printf("%-20s\t0x%-8X\t0x%-8X\t0x%-8X\n","Name",importTable[i].Name,((char*)&importTable[i].Name - (char*)base),RvaToFva(base,importTable[i].Name));
printf("%-20s\t0x%-8X\t0x%-8X\t0x%-8X\n","FirstThunk",importTable[i].FirstThunk,((char*)&importTable[i].FirstThunk - (char*)base),RvaToFva(base,importTable[i].FirstThunk));
// printf("Name:%X\n",importTable[i].Name);//使用[i]只能用.,因为数组类似于实体数据
// printf("FirstThunk:%X\n",importTable[i].FirstThunk);
cout<<"dllname: "<<(char*)(base + RvaToFva(base,importTable[i].Name))<<endl;
PIMAGE_THUNK_DATA64 thunkData = (PIMAGE_THUNK_DATA64)((unsigned char*)base + RvaToFva(base,importTable[i].OriginalFirstThunk));
cout<<"\n文件偏移 \tHint \tName\n";
while(!(thunkData->u1.AddressOfData&0x8000000000000000)&&(thunkData->u1.AddressOfData))
{
DWORD funcBegin = RvaToFva(base,thunkData->u1.AddressOfData);
PIMAGE_IMPORT_BY_NAME func = (PIMAGE_IMPORT_BY_NAME)((unsigned char*)base + funcBegin);
printf("0x%-18X\t0x%-8X\t%s\n",funcBegin,func->Hint,func->Name);
// printf("rva: %-8X\n",funcBegin);
// printf("Hint:%X %s\n",func->Hint,func->Name);
thunkData++;
}
cout<<"----------------------------------\n";
}
}
if(ophead->DataDirectory[0].VirtualAddress!=0)
{
cout<<"导出表----------------------------------------------------------------\n";
DWORD exportBegin = RvaToFva(base,ophead->DataDirectory[0].VirtualAddress);
cout<<"属性名称 \t属性 \t文件偏移\t指向文件偏移\n";
PIMAGE_EXPORT_DIRECTORY exportTable = (PIMAGE_EXPORT_DIRECTORY)((char*)base + exportBegin);
// printf("MajorVersion:%X\nMinorVersion:%X\n",exportTable->MajorVersion,exportTable->MinorVersion);
// printf("TimeDateStamp:%X\n",exportTable->TimeDateStamp);
// printf("Base:%X\n",exportTable->Base);
// printf("NumberOfFunctions = %d\n",exportTable->NumberOfFunctions);
// printf("NumberOfNames = %d\n",exportTable->NumberOfNames);
// printf("Characteristics = %X\n",exportTable->Characteristics);
time_t time = exportTable->TimeDateStamp;
struct tm* ttime;
ttime = localtime(&time);
char now[24];
strftime(now,24,"%Y-%m-%d %H:%M:%S",ttime);
printf("%-20s\t0x%-8X\t0x%-8X\n","Characteristics",exportTable->Characteristics,((char*)&exportTable->Characteristics - (char*)base));
printf("%-20s\t0x%-8X\t0x%-8X\t%s\n","TimeDateStamp",exportTable->TimeDateStamp,((char*)&exportTable->TimeDateStamp - (char*)base),now);
printf("%-20s\t0x%-8X\t0x%-8X\t0x%-8X\n","Name",exportTable->Name,((char*)&exportTable->Name - (char*)base),RvaToFva(base,exportTable->Name));
printf("%-20s\t0x%-8X\t0x%-8X\n","Base",exportTable->Base,((char*)&exportTable->Base - (char*)base));
printf("%-20s\t%-8d\t0x%-8X\n","NumberOfFunctions",exportTable->NumberOfFunctions,((char*)&exportTable->NumberOfFunctions - (char*)base));
printf("%-20s\t%-8d\t0x%-8X\n","NumberOfNames",exportTable->NumberOfNames,((char*)&exportTable->NumberOfNames - (char*)base));
printf("%-20s\t0x%-8X\t0x%-8X\t0x%-8X\n","AddressOfFunctions",exportTable->AddressOfFunctions,((char*)&exportTable->AddressOfFunctions - (char*)base),RvaToFva(base,exportTable->AddressOfFunctions));
printf("%-20s\t0x%-8X\t0x%-8X\t0x%-8X\n","AddressOfNames",exportTable->AddressOfNames,((char*)&exportTable->AddressOfNames - (char*)base),RvaToFva(base,exportTable->AddressOfNames));
printf("%-20s\t0x%-8X\t0x%-8X\t0x%-8X\n","AddressOfNameOrdinals",exportTable->AddressOfNameOrdinals,((char*)&exportTable->AddressOfNameOrdinals - (char*)base),RvaToFva(base,exportTable->AddressOfNameOrdinals));
cout<<"dllName = "<<(char*)(base + RvaToFva(base,exportTable->Name))<<endl;
int nameNum = exportTable->NumberOfNames;
int funcNum = exportTable->NumberOfFunctions;
// printf("AddressOfFunctions = %X\n",exportTable->AddressOfFunctions);
// printf("AddressOfNames = %X\n",exportTable->AddressOfNames);
// printf("AddressOfNameOrdinals = %X\n",exportTable->AddressOfNameOrdinals);
WORD* hint = (WORD*)((char*)base + RvaToFva(base,exportTable->AddressOfNameOrdinals));
DWORD* names = (DWORD*)((char*)base + RvaToFva(base,exportTable->AddressOfNames));
DWORD* funcs = (DWORD*)((char*)base + RvaToFva(base,exportTable->AddressOfFunctions));
bool noName[funcNum] = {true};
memset(noName,1,funcNum);
cout<<"内存偏移\t文件偏移\tHint\t访问标号\tName\n";
for(int i=0;i<nameNum;i++)
{
// printf("hint:%d name:%s %X\n",hint[i],((char*)base + RvaToFva(base,names[i])),funcs[i]);
printf("0x%-8X\t0x%-8X\t0x%-4X\t%-8d\t%s\n",funcs[i],RvaToFva(base,funcs[i]),hint[i],(exportTable->Base + hint[i]),((char*)base + RvaToFva(base,names[i])));
noName[hint[i]] = false;
}
cout<<"内存偏移\t文件偏移\t访问标号\n";
bool haveNoName = false;
for(int i=0;i<funcNum;i++)
{
if(noName[i])
{
printf("0x%-8X\t0x%-8X\t%d\n",funcs[i],RvaToFva(base,funcs[i]),(exportTable->Base+i));
haveNoName = true;
}
}
if(!haveNoName)
{
cout<<"没有无名函数\n";
}
cout<<"----------------------------------------------------------------------\n";
}
//延迟导入表
if(ophead->DataDirectory[13].VirtualAddress!=0)
{
cout<<"延迟导入表\n";
DWORD delayBegin = RvaToFva(base,ophead->DataDirectory[13].VirtualAddress);
PIMAGE_DELAYLOAD_DESCRIPTOR delayTable = (PIMAGE_DELAYLOAD_DESCRIPTOR)((char*)base + delayBegin);
int delayDllNum = ophead->DataDirectory[13].Size/sizeof(IMAGE_DELAYLOAD_DESCRIPTOR);
while(delayTable->DllNameRVA!=0)
{
printf("dllName = %s\n",((char*)base + RvaToFva(base,delayTable->DllNameRVA)));
cout<<"属性 \t内存偏移\t文件偏移\t指向文件偏移\n";
printf("%-22s\t0x%-8X\t0x%-8X\t0x%-8X\n","DllNameRVA",delayTable->DllNameRVA,((char*)&delayTable->DllNameRVA - (char*)base),RvaToFva(base,delayTable->DllNameRVA));
printf("%-22s\t0x%-8X\t0x%-8X\t0x%-8X\n","ModuleHandleRVA",delayTable->ModuleHandleRVA,((char*)&delayTable->ModuleHandleRVA - (char*)base),RvaToFva(base,delayTable->ModuleHandleRVA));
printf("%-22s\t0x%-8X\t0x%-8X\t0x%-8X\n","ImportAddressTableRVA",delayTable->ImportAddressTableRVA,((char*)&delayTable->ImportAddressTableRVA - (char*)base),RvaToFva(base,delayTable->ImportAddressTableRVA));
printf("%-22s\t0x%-8X\t0x%-8X\t0x%-8X\n","ImportNameTableRVA",delayTable->ImportNameTableRVA,((char*)&delayTable->ImportNameTableRVA - (char*)base),RvaToFva(base,delayTable->ImportNameTableRVA));
printf("%-22s\t0x%-8X\t0x%-8X\n","TimeDateStamp",delayTable->TimeDateStamp,((char*)&delayTable->TimeDateStamp - (char*)base));
// printf("ModuleHandleRVA = %X\n",delayTable->ModuleHandleRVA);
// printf("TimeDateStamp = %X\n",delayTable->TimeDateStamp);
// printf("ImportNameTableRVA = %X\n",delayTable->ImportNameTableRVA);
// printf("ImportAddressTableRVA = %X\n",delayTable->ImportAddressTableRVA);
DWORD* importTable = (DWORD*)((char*)base + RvaToFva(base,delayTable->ImportNameTableRVA));
cout<<"文件偏移 \t标号 \t名称\n";
while(*importTable)
{
DWORD funcBegin = RvaToFva(base,*importTable);
PIMAGE_IMPORT_BY_NAME func = (PIMAGE_IMPORT_BY_NAME)((unsigned char*)base + funcBegin);
// printf("Hint:%X %s\n",func->Hint,func->Name);
printf("0x%-20X\t%-8d\t%s\n",funcBegin,func->Hint,func->Name);
importTable++;
}
cout<<endl;
delayTable++;
}
}
// test:
//资源数据
if(ophead->DataDirectory[2].VirtualAddress)
{
DWORD rescBegin = RvaToFva(base,ophead->DataDirectory[2].VirtualAddress);
PIMAGE_RESOURCE_DIRECTORY firstEntry = (PIMAGE_RESOURCE_DIRECTORY)((unsigned char*)base + rescBegin);
searchResource(base,firstEntry,firstEntry);
}
}
//void jiexiResource(LPVOID base,PIMAGE_OPTIONAL_HEADER32 ophead)
//{
// cout<<"开始解析"<<endl;
// DWORD begin = RvaToFva(base,ophead->DataDirectory[2].VirtualAddress);
// PIMAGE_RESOURCE_DIRECTORY entry = (PIMAGE_RESOURCE_DIRECTORY)((unsigned char*)base + begin);
// blEntry(base,entry,entry);
//}
void showPe(LPVOID base)
{
PIMAGE_DOS_HEADER dosHeader;
dosHeader = (PIMAGE_DOS_HEADER)base;
PIMAGE_NT_HEADERS32 nth = (PIMAGE_NT_HEADERS32)(base + dosHeader->e_lfanew);
PIMAGE_FILE_HEADER fileh = (PIMAGE_FILE_HEADER)&(nth->FileHeader);
char str[100];
string attr = "unknown";
if(fileh->Machine==IMAGE_FILE_MACHINE_I386)
{
attr = "Intel 386处理器";
}
else if(fileh->Machine==IMAGE_FILE_MACHINE_AMD64)
{
attr = "x64处理器";
}
else if(fileh->Machine==IMAGE_FILE_MACHINE_ARM)
{
attr = "ARM小尾处理器";
}
else if(fileh->Machine==IMAGE_FILE_MACHINE_ARMV7)
{
attr = "ARMv7处理器的Thumb模式";
}
else if(fileh->Machine==IMAGE_FILE_MACHINE_IA64)
{
attr = "Intel Itanium处理器";
}
else if(fileh->Machine==IMAGE_FILE_MACHINE_POWERPC)
{
attr = "Power PC小尾处理器";
}
else if(fileh->Machine==IMAGE_FILE_MACHINE_THUMB)
{
attr = "ARM或Thumb处理器";
}
cout<<"IMAGE_FILE_HEADER----------------------------------------------------------\n";
cout<<"属性名称\t属性 \t文件偏移\t大小\t转换属性\n";
printf("%-8s\t%-8d\t0x%-8X\t%-4d\n","节区数量",fileh->NumberOfSections,((char*)&fileh->NumberOfSections - (char*)base),sizeof(IMAGE_FILE_HEADER::NumberOfSections));
printf("%-8s\t0x%-8X\t%-8X\t%-4d\t%s\n","机器类别",fileh->Machine,((char*)&fileh->Machine - (char*)base),sizeof(IMAGE_FILE_HEADER::Machine),attr.c_str());
time_t time = fileh->TimeDateStamp;
struct tm* ttime;
ttime = localtime(&time);
char now[24];
strftime(now,24,"%Y-%m-%d %H:%M:%S",ttime);
printf("%-8s\t%-8X\t%-8X\t%-4d\t%-s\n","时间戳",fileh->TimeDateStamp,((char*)&fileh->TimeDateStamp - (char*)base),sizeof(IMAGE_FILE_HEADER::TimeDateStamp),now);
printf("%-8s\t0x%-8X\t%-8X\t%-4d\t%-d\n","可选大小",fileh->SizeOfOptionalHeader,((char*)&fileh->SizeOfOptionalHeader - (char*)base),sizeof(IMAGE_FILE_HEADER::SizeOfOptionalHeader),fileh->SizeOfOptionalHeader);
attr = "";
bool attrTable[16];
memset(attrTable,0,16);
int count = 0;
WORD num = 1;
WORD sx = fileh->Characteristics;
while(num){
if(sx&num)
{
attrTable[count] = true;
}
num<<=1;
count++;
}
if(attrTable[0])
{
attr = attr + "[无重定位]";
}
if(attrTable[1])
{
attr = attr + "[可执行]";
}
if(attrTable[8])
{
attr = attr + "[只能32位]";
}
if(attrTable[10])
{
attr = attr + "[不能从U盘]";
}
if(attrTable[11])
{
attr = attr + "[不能从网络]";
}
if(attrTable[12])
{
attr = attr + "[系统文件]";
}
if(attrTable[13])
{
attr = attr + "[dll文件]";
}
if(attrTable[14])
{
attr = attr + "[不能在多cpu计算机]";
}
printf("%-8s\t0x%-8X\t0x%-8X\t%-4d\t%s\n","文件属性",fileh->Characteristics,((char*)&fileh->Characteristics - (char*)base),sizeof(IMAGE_FILE_HEADER::Characteristics),attr.c_str());
// sprintf(str,"Characteristics: %08X\n",fileh->Characteristics);
// cout<<str;
cout<<"---------------------------------------------------------------------------\n\n";
cout<<"IMAGE_OPTIONAL_HEADER32-----------------------------------------\n";
cout<<"属性名称 \t属性 \t文件偏移\t大小\t补充\n";
PIMAGE_OPTIONAL_HEADER32 ophead= (PIMAGE_OPTIONAL_HEADER32)&(nth->OptionalHeader);
attr = "";
if(ophead->Magic==0x10B)
{
attr="PE32";
}
else if(ophead->Magic==0x107)
{
attr=="ROM";
}
else if(ophead->Magic==0x20B)
{
attr=="PE32+";
}
printf("%-20s\t0x%-8X\t0x%-8X\t%-4d\t%s\n","Magic",ophead->Magic,((char*)&ophead->Magic - (char*)base),sizeof(IMAGE_OPTIONAL_HEADER32::Magic),attr.c_str());
printf("%-20s\t0x%-8X\t0x%-8X\t%-4d\t%s\n","CheckSum",ophead->CheckSum,((char*)&ophead->CheckSum - (char*)base),sizeof(IMAGE_OPTIONAL_HEADER32::CheckSum),"可为0");
printf("%-20s\t0x%-8X\t0x%-8X\t%-4d\t%s\n","NumberOfRvaAndSizes",ophead->NumberOfRvaAndSizes,((char*)&ophead->NumberOfRvaAndSizes - (char*)base),sizeof(IMAGE_OPTIONAL_HEADER32::NumberOfRvaAndSizes),"一般等同于数据目录表的数目");
printf("%-20s\t0x%-8X\t0x%-8X\t%-4d\t%s\n","ImageBase",ophead->ImageBase,((char*)&ophead->ImageBase - (char*)base),sizeof(IMAGE_OPTIONAL_HEADER32::ImageBase),"0x10000H字节的整数倍");
printf("%-20s\t0x%-8X\t0x%-8X\t%d\n","AddressOfEntryPoint",ophead->AddressOfEntryPoint,((char*)&ophead->AddressOfEntryPoint - (char*)base),sizeof(IMAGE_OPTIONAL_HEADER32::AddressOfEntryPoint));
printf("%-20s\t0x%-8X\t0x%-8X\t%d\n","SectionAlignment",ophead->SectionAlignment,((char*)&ophead->SectionAlignment - (char*)base),sizeof(IMAGE_OPTIONAL_HEADER32::SectionAlignment));
printf("%-20s\t0x%-8X\t0x%-8X\t%d\n","FileAlignment",ophead->FileAlignment,((char*)&ophead->FileAlignment - (char*)base),sizeof(IMAGE_OPTIONAL_HEADER32::FileAlignment));
// printf("%-20s\t0x%-8X\t0x%-8X\t%-4d\t%s\n","SizeOfInitializedData",ophead->SizeOfInitializedData,((char*)&ophead->SizeOfInitializedData - (char*)base),sizeof(IMAGE_OPTIONAL_HEADER32::SizeOfInitializedData));
// printf("%-20s\t0x%-8X\t0x%-8X\t%-4d\t%s\n","SizeOfUninitializedData",ophead->SizeOfUninitializedData,((char*)&ophead->SizeOfUninitializedData - (char*)base),sizeof(IMAGE_OPTIONAL_HEADER32::SizeOfUninitializedData));
attr = "";
if(ophead->Subsystem==1)
{
attr = "设备驱动和Native系统进程";
}
else if(ophead->Subsystem==2)
{
attr = "windows图形用户界面";
}
else if(ophead->Subsystem==3)
{
attr = "windows控制台程序";
}
else if(ophead->Subsystem==7)
{
attr = "posix控制台程序";
}
else if(ophead->Subsystem==9)
{
attr = "WindowsCE图形用户界面";
}
else
{
attr = "unknown";
}
printf("%-20s\t0x%-8X\t0x%-8X\t%-4d\t%s\n","Subsystem",ophead->Subsystem,((char*)&ophead->Subsystem - (char*)base),sizeof(IMAGE_OPTIONAL_HEADER32::Subsystem),attr.c_str());
printf("%-20s\t0x%-8X\t0x%-8X\t%-4d\t%s\n","BaseOfData",ophead->BaseOfData,((char*)&ophead->BaseOfData - (char*)base),sizeof(IMAGE_OPTIONAL_HEADER32::BaseOfData),"一般为.data段起始内存偏移");
printf("%-20s\t0x%-8X\t0x%-8X\t%-4d\t%s\n","BaseOfCode",ophead->BaseOfCode,((char*)&ophead->BaseOfCode - (char*)base),sizeof(IMAGE_OPTIONAL_HEADER32::BaseOfCode),"一般为.text段起始内存偏移");
printf("%-20s\t0x%-8X\t0x%-8X\t%-4d\t%s\n","SizeOfCode",ophead->SizeOfCode,((char*)&ophead->SizeOfCode - (char*)base),sizeof(IMAGE_OPTIONAL_HEADER32::SizeOfCode),"所有代码对齐后的大小");
printf("%-20s\t0x%-8X\t0x%-8X\t%-4d\t%s\n","SizeOfImage",ophead->SizeOfImage,((char*)&ophead->SizeOfImage - (char*)base),sizeof(IMAGE_OPTIONAL_HEADER32::SizeOfImage),"内存中PE映像大小");
printf("%-20s\t0x%-8X\t0x%-8X\t%-4d\t%s\n","SizeOfHeaders",ophead->SizeOfHeaders,((char*)&ophead->SizeOfHeaders - (char*)base),sizeof(IMAGE_OPTIONAL_HEADER32::SizeOfHeaders),"一般情况下等同于第一个节区的起始偏移");
printf("%-20s\t0x%-8X\t0x%-8X\t%-4d\t%s\n","DllCharacteristics",ophead->DllCharacteristics,((char*)&ophead->DllCharacteristics - (char*)base),sizeof(IMAGE_OPTIONAL_HEADER32::DllCharacteristics));
cout<<"------------------------------------------------------------\n";
cout<<"\n数据目录表----------------------------------------------\n";
cout<<"名称 \t内存偏移\t数据大小\t文件偏移\t指向文件偏移\n";
for(int i=0;i<IMAGE_NUMBEROF_DIRECTORY_ENTRIES;i++)
{
printf("%-12s\t0x%-8X\t0x%-8X\t0x%-8X\t0x%-8X\n",tableName[i],ophead->DataDirectory[i].VirtualAddress,ophead->DataDirectory[i].Size,((char*)&ophead->DataDirectory[i] - (char*)base),ophead->DataDirectory[i].VirtualAddress==0?0:RvaToFva(base,ophead->DataDirectory[i].VirtualAddress));
// if(ophead->DataDirectory[i].VirtualAddress==0)
// continue;
// sprintf(str,"%12s:%08XH,%08XH FVA: 0x%08X\n",tableName[i],ophead->DataDirectory[i].VirtualAddress,ophead->DataDirectory[i].Size,((char*)&ophead->DataDirectory[i] - (char*)base));
// cout<<str;
}
cout<<"--------------------------------------------------------\n";
cout<<endl;
PIMAGE_SECTION_HEADER sectionTable = IMAGE_FIRST_SECTION(nth);
cout<<"节区表----------------------------------------------------------------------------------\n";
cout<<"节区名称\t节区文件偏移\t节区内存偏移\t节区大小\t节区对齐大小\t节区属性\t属性解释\n";
sprintf(str,"%-8X\t%-12X\t%-12X\t%-8X\t%-12X\t%-8X\n",sizeof(IMAGE_SECTION_HEADER::Name),sizeof(IMAGE_SECTION_HEADER::PointerToRawData),sizeof(IMAGE_SECTION_HEADER::VirtualAddress),sizeof(IMAGE_SECTION_HEADER::VirtualAddress),sizeof(IMAGE_SECTION_HEADER::SizeOfRawData),sizeof(IMAGE_SECTION_HEADER::Characteristics));
cout<<str;
for(int i=0;i<fileh->NumberOfSections;i++)
{
if(true)
{
IMAGE_SECTION_HEADER data = sectionTable[i];
attr = "";
if((data.Characteristics&0x20000000)==0x20000000)
{
attr+="E";
}
if((data.Characteristics&0x40000000)==0x40000000)
{
attr+="R";
}
if((data.Characteristics&0x80000000)==0x80000000)
{
attr+="W";
}
if((data.Characteristics&0x20)==0x20)
{
attr+="C";
}
if((data.Characteristics&0x10000000)==0x10000000)
{
attr+="S";
}
if((data.Characteristics&0x8000000)==0x8000000)
{
attr+=" no up";
}
if((data.Characteristics&0x4000000)==0x4000000)
{
attr+=" no chche";
}
if((data.Characteristics&0x2000000)==0x2000000)
{
attr+=" reloc";
}
if((data.Characteristics&0x80)==0x80)
{
attr+=" uninitdata";
}
if((data.Characteristics&0x40)==0x40)
{
attr+=" initdata";
}
}
sprintf(str,"%-8s\t0x%-12X\t%-12X\t%-8X\t%-12X\t%-8X\t%-s\n",sectionTable[i].Name,sectionTable[i].PointerToRawData,sectionTable[i].VirtualAddress,sectionTable[i].Misc.VirtualSize,sectionTable[i].SizeOfRawData,sectionTable[i].Characteristics,attr.c_str());
cout<<str;
}
cout<<"指向文件偏移--------------------------------------------------------------------------\n";
for(int i=0;i<fileh->NumberOfSections;i++)
{
sprintf(str,"FVA:0x%-8X\t0x%-12X\t0x%-12X\t0x%-8X\t0x%-12X\t0x%-8X\n",((char*)§ionTable[i] - (char*)base),((char*)§ionTable[i].PointerToRawData - (char*)base),((char*)§ionTable[i].VirtualAddress - (char*)base),((char*)§ionTable[i].Misc.VirtualSize - (char*)base),((char*)§ionTable[i].SizeOfRawData - (char*)base),((char*)§ionTable[i].Characteristics - (char*)base) );
cout<<str;
}
cout<<"----------------------------------------------------------------------------------------\n";
//导入表
if(ophead->DataDirectory[1].VirtualAddress)
{
cout<<"导入表---------------------------------------------------------------\n";
DWORD importAddrBegin = RvaToFva(base,ophead->DataDirectory[1].VirtualAddress);
int importDllNum = ophead->DataDirectory[1].Size/sizeof(IMAGE_IMPORT_DESCRIPTOR);//最后多20个字节的NULL,但是也可能是别人手动修改的
PIMAGE_IMPORT_DESCRIPTOR importTable = (PIMAGE_IMPORT_DESCRIPTOR)((unsigned char*)base + importAddrBegin) ;
// printf("%X\n",(importTable[0])->Name);
for(int i=0;i<importDllNum;i++)
{
if(importTable[i].Name==0||importTable[i].Characteristics==0)
{
break;
}
cout<<"属性名称 \t属性 \t文件偏移\t指向文件偏移\n";
printf("%-20s\t0x%-8X\t0x%-8X\t0x%-8X\n","OriginalFirstThunk",importTable[i].OriginalFirstThunk,((char*)&importTable[i].OriginalFirstThunk - (char*)base),RvaToFva(base,importTable[i].OriginalFirstThunk));
printf("%-20s\t0x%-8X\t0x%-8X\n","TimeDateStamp",importTable[i].TimeDateStamp,((char*)&importTable[i].TimeDateStamp - (char*)base));
printf("%-20s\t0x%-8X\t0x%-8X\t0x%-8X\n","Name",importTable[i].Name,((char*)&importTable[i].Name - (char*)base),RvaToFva(base,importTable[i].Name));
printf("%-20s\t0x%-8X\t0x%-8X\t0x%-8X\n","FirstThunk",importTable[i].FirstThunk,((char*)&importTable[i].FirstThunk - (char*)base),RvaToFva(base,importTable[i].FirstThunk));
// printf("Name:%X\n",importTable[i].Name);//使用[i]只能用.,因为数组类似于实体数据
// printf("FirstThunk:%X\n",importTable[i].FirstThunk);
cout<<"dllname: "<<(char*)(base + RvaToFva(base,importTable[i].Name))<<endl;
PIMAGE_THUNK_DATA32 thunkData = (PIMAGE_THUNK_DATA32)((unsigned char*)base + RvaToFva(base,importTable[i].OriginalFirstThunk));
cout<<"\n文件偏移 \tHint \tName\n";
while(!(thunkData->u1.AddressOfData&0x80000000)&&(thunkData->u1.AddressOfData))
{
DWORD funcBegin = RvaToFva(base,thunkData->u1.AddressOfData);
PIMAGE_IMPORT_BY_NAME func = (PIMAGE_IMPORT_BY_NAME)((unsigned char*)base + funcBegin);
printf("0x%-18X\t0x%-8X\t%s\n",funcBegin,func->Hint,func->Name);
// printf("rva: %-8X\n",funcBegin);
// printf("Hint:%X %s\n",func->Hint,func->Name);
thunkData++;
}
cout<<"----------------------------------\n";
}
}
if(ophead->DataDirectory[0].VirtualAddress)
{
cout<<"导出表----------------------------------------------------------------\n";
DWORD exportBegin = RvaToFva(base,ophead->DataDirectory[0].VirtualAddress);
cout<<"属性名称 \t属性 \t文件偏移\t指向文件偏移\n";
PIMAGE_EXPORT_DIRECTORY exportTable = (PIMAGE_EXPORT_DIRECTORY)((char*)base + exportBegin);
// printf("MajorVersion:%X\nMinorVersion:%X\n",exportTable->MajorVersion,exportTable->MinorVersion);
// printf("TimeDateStamp:%X\n",exportTable->TimeDateStamp);
// printf("Base:%X\n",exportTable->Base);
// printf("NumberOfFunctions = %d\n",exportTable->NumberOfFunctions);
// printf("NumberOfNames = %d\n",exportTable->NumberOfNames);
// printf("Characteristics = %X\n",exportTable->Characteristics);
time_t time = exportTable->TimeDateStamp;
struct tm* ttime;
ttime = localtime(&time);
char now[24];
strftime(now,24,"%Y-%m-%d %H:%M:%S",ttime);
printf("%-20s\t0x%-8X\t0x%-8X\n","Characteristics",exportTable->Characteristics,((char*)&exportTable->Characteristics - (char*)base));
printf("%-20s\t0x%-8X\t0x%-8X\t%s\n","TimeDateStamp",exportTable->TimeDateStamp,((char*)&exportTable->TimeDateStamp - (char*)base),now);
printf("%-20s\t0x%-8X\t0x%-8X\t0x%-8X\n","Name",exportTable->Name,((char*)&exportTable->Name - (char*)base),RvaToFva(base,exportTable->Name));
printf("%-20s\t0x%-8X\t0x%-8X\n","Base",exportTable->Base,((char*)&exportTable->Base - (char*)base));
printf("%-20s\t%-8d\t0x%-8X\n","NumberOfFunctions",exportTable->NumberOfFunctions,((char*)&exportTable->NumberOfFunctions - (char*)base));
printf("%-20s\t%-8d\t0x%-8X\n","NumberOfNames",exportTable->NumberOfNames,((char*)&exportTable->NumberOfNames - (char*)base));
printf("%-20s\t0x%-8X\t0x%-8X\t0x%-8X\n","AddressOfFunctions",exportTable->AddressOfFunctions,((char*)&exportTable->AddressOfFunctions - (char*)base),RvaToFva(base,exportTable->AddressOfFunctions));
printf("%-20s\t0x%-8X\t0x%-8X\t0x%-8X\n","AddressOfNames",exportTable->AddressOfNames,((char*)&exportTable->AddressOfNames - (char*)base),RvaToFva(base,exportTable->AddressOfNames));
printf("%-20s\t0x%-8X\t0x%-8X\t0x%-8X\n","AddressOfNameOrdinals",exportTable->AddressOfNameOrdinals,((char*)&exportTable->AddressOfNameOrdinals - (char*)base),RvaToFva(base,exportTable->AddressOfNameOrdinals));
cout<<"dllName = "<<(char*)(base + RvaToFva(base,exportTable->Name))<<endl;
int nameNum = exportTable->NumberOfNames;
int funcNum = exportTable->NumberOfFunctions;
// printf("AddressOfFunctions = %X\n",exportTable->AddressOfFunctions);
// printf("AddressOfNames = %X\n",exportTable->AddressOfNames);
// printf("AddressOfNameOrdinals = %X\n",exportTable->AddressOfNameOrdinals);
WORD* hint = (WORD*)((char*)base + RvaToFva(base,exportTable->AddressOfNameOrdinals));
DWORD* names = (DWORD*)((char*)base + RvaToFva(base,exportTable->AddressOfNames));
DWORD* funcs = (DWORD*)((char*)base + RvaToFva(base,exportTable->AddressOfFunctions));
bool noName[funcNum] = {true};
memset(noName,1,funcNum);
cout<<"内存偏移\t文件偏移\tHint\t访问标号\tName\n";
for(int i=0;i<nameNum;i++)
{
// printf("hint:%d name:%s %X\n",hint[i],((char*)base + RvaToFva(base,names[i])),funcs[i]);
printf("0x%-8X\t0x%-8X\t0x%-4X\t%-8d\t%s\n",funcs[i],RvaToFva(base,funcs[i]),hint[i],(exportTable->Base +hint[i] ),((char*)base + RvaToFva(base,names[i])));
noName[hint[i]] = false;
}
cout<<"内存偏移\t文件偏移\t访问标号\n";
bool haveNoName = false;
for(int i=0;i<funcNum;i++)
{
if(noName[i])
{
printf("0x%-8X\t0x%-8X\t%d\n",funcs[i],RvaToFva(base,funcs[i]),(exportTable->Base + i));
haveNoName = true;
}
}
if(!haveNoName)
{
cout<<"没有无名函数\n";
}
cout<<"----------------------------------------------------------------------\n";
}
if(ophead->DataDirectory[13].VirtualAddress)
{
cout<<"延迟导入表\n";
DWORD delayBegin = RvaToFva(base,ophead->DataDirectory[13].VirtualAddress);
PIMAGE_DELAYLOAD_DESCRIPTOR delayTable = (PIMAGE_DELAYLOAD_DESCRIPTOR)((char*)base + delayBegin);
int delayDllNum = ophead->DataDirectory[13].Size/sizeof(IMAGE_DELAYLOAD_DESCRIPTOR);
while(delayTable->DllNameRVA!=0)
{
printf("dllName = %s\n",((char*)base + RvaToFva(base,delayTable->DllNameRVA)));
cout<<"属性 \t内存偏移\t文件偏移\t指向文件偏移\n";
printf("%-22s\t0x%-8X\t0x%-8X\t0x%-8X\n","DllNameRVA",delayTable->DllNameRVA,((char*)&delayTable->DllNameRVA - (char*)base),RvaToFva(base,delayTable->DllNameRVA));
printf("%-22s\t0x%-8X\t0x%-8X\t0x%-8X\n","ModuleHandleRVA",delayTable->ModuleHandleRVA,((char*)&delayTable->ModuleHandleRVA - (char*)base),RvaToFva(base,delayTable->ModuleHandleRVA));
printf("%-22s\t0x%-8X\t0x%-8X\t0x%-8X\n","ImportAddressTableRVA",delayTable->ImportAddressTableRVA,((char*)&delayTable->ImportAddressTableRVA - (char*)base),RvaToFva(base,delayTable->ImportAddressTableRVA));
printf("%-22s\t0x%-8X\t0x%-8X\t0x%-8X\n","ImportNameTableRVA",delayTable->ImportNameTableRVA,((char*)&delayTable->ImportNameTableRVA - (char*)base),RvaToFva(base,delayTable->ImportNameTableRVA));
printf("%-22s\t0x%-8X\t0x%-8X\n","TimeDateStamp",delayTable->TimeDateStamp,((char*)&delayTable->TimeDateStamp - (char*)base));
// printf("ModuleHandleRVA = %X\n",delayTable->ModuleHandleRVA);
// printf("TimeDateStamp = %X\n",delayTable->TimeDateStamp);
// printf("ImportNameTableRVA = %X\n",delayTable->ImportNameTableRVA);
// printf("ImportAddressTableRVA = %X\n",delayTable->ImportAddressTableRVA);
DWORD* importTable = (DWORD*)((char*)base + RvaToFva(base,delayTable->ImportNameTableRVA));
cout<<"文件偏移 \t标号 \t名称\n";
while(*importTable)
{
DWORD funcBegin = RvaToFva(base,*importTable);
PIMAGE_IMPORT_BY_NAME func = (PIMAGE_IMPORT_BY_NAME)((unsigned char*)base + funcBegin);
// printf("Hint:%X %s\n",func->Hint,func->Name);
printf("0x%-20X\t%-8d\t%s\n",funcBegin,func->Hint,func->Name);
importTable++;
}
cout<<endl;
delayTable++;
}
}
//资源数据表
if(ophead->DataDirectory[2].VirtualAddress)
{
DWORD rescBegin = RvaToFva(base,ophead->DataDirectory[2].VirtualAddress);
PIMAGE_RESOURCE_DIRECTORY firstEntry = (PIMAGE_RESOURCE_DIRECTORY)((unsigned char*)base + rescBegin);
searchResource(base,firstEntry,firstEntry);
}
}
int isPEfile(LPVOID imageBase)
{
PIMAGE_DOS_HEADER dosHeader;
dosHeader = (PIMAGE_DOS_HEADER)imageBase;
if(dosHeader->e_magic!=IMAGE_DOS_SIGNATURE)
{
cout<<"不是MZ文件头\n";
return 0;
}
PIMAGE_NT_HEADERS32 ntHeader;
ntHeader = (PIMAGE_NT_HEADERS32)(imageBase+dosHeader->e_lfanew);
if(ntHeader->Signature!=IMAGE_NT_SIGNATURE)
{
cout<<"是MZ,但不是PE\n";
return 0;
}
if(ntHeader->FileHeader.SizeOfOptionalHeader==0xf0)
{
cout<<"可选头大小为F0,判断为PE32+\n";
return 2;
}
else
{
cout<<"根据可选头大小,判断为PE32\n";
return 1;
}
return 3;
}
void LoadFile(string filename)
{
HANDLE hfile = CreateFileA(filename.c_str(),GENERIC_READ|GENERIC_WRITE,FILE_SHARE_DELETE|FILE_SHARE_READ|FILE_SHARE_WRITE,\
NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
// cout<<"hfile = "<<hfile<<endl; //不存在的文件,则为0xffffffff
if(GetLastError())
{
cout<<GetLastError()<<endl;
cout<<"打开文件失败\n";
CloseHandle(hfile);
return;
}
HANDLE hmap = CreateFileMapping(hfile,NULL,PAGE_READWRITE,0,0,NULL);
if(!hmap)
{
cout<<GetLastError()<<endl;
cout<<"创建文件映射失败\n";
CloseHandle(hfile);
CloseHandle(hmap);
return;
}
LPVOID laddr = MapViewOfFile(hmap,FILE_MAP_ALL_ACCESS,0,0,0);
if(!laddr)
{
cout<<"映射内存失败\n";
CloseHandle(hfile);
CloseHandle(hmap);
return;
}
int fileType = isPEfile(laddr);
if(fileType==0)
{
cout<<"不是PE文件\n";
CloseHandle(hfile);
CloseHandle(hfile);
UnmapViewOfFile(laddr);
return;
}
// cout<<"filetype = "<<fileType<<endl;
if(fileType==1||fileType==3)
{
if(fileType==3)
{
cout<<"可选头大小不是标准的E0或F0,按照PE32文件处理\n";
}
showPe(laddr);
}
else if(fileType==2)
{
showPeExt(laddr);
}
CloseHandle(hfile);
CloseHandle(hfile);
UnmapViewOfFile(laddr);
}
int main()
{
while(true)
{
string filename;
cout<<"请输入文件名称\n";
// cin>>filename;
filename = "C:\\Users\\DELL\\Desktop\\323\\pe.exe";
if(filename=="cls")
{
system("cls");
}
else
{
system("cls");
LoadFile(filename);
}
while(1);
}
}