记录控制台版的peInfo

记录一下控制台版的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*)&sectionTable[i] - (char*)base),((char*)&sectionTable[i].PointerToRawData - (char*)base),((char*)&sectionTable[i].VirtualAddress - (char*)base),((char*)&sectionTable[i].Misc.VirtualSize - (char*)base),((char*)&sectionTable[i].SizeOfRawData - (char*)base),((char*)&sectionTable[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*)&sectionTable[i] - (char*)base),((char*)&sectionTable[i].PointerToRawData - (char*)base),((char*)&sectionTable[i].VirtualAddress - (char*)base),((char*)&sectionTable[i].Misc.VirtualSize - (char*)base),((char*)&sectionTable[i].SizeOfRawData - (char*)base),((char*)&sectionTable[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);
    }
}


posted @ 2022-03-30 19:56  念秋  阅读(27)  评论(0编辑  收藏  举报