• 记录控制台版的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);
        }
    }
    
    
    
  • 相关阅读:
    超级好用的excel导出方法,比phpexcel快n倍,并且无乱码
    PHP生成随机数;订单号唯一
    php判断检测一个数组里有没有重复的值
    修改git 提交的用户名和用户Email命令
    利用 PHP CURL zip压缩文件上传
    Linux 重启 PHP-FPM 命令
    Postgresql 时间串转换格式
    rollup node.js 打包工具
    PHP正则表达式提取html超链接中的href地址
    解决Ubuntu系统下 mysql 远程连接失败的问题 ERROR 2003 (HY000): Can't connect to MySQL server on 'xxx.xxx.xx.xx' (110)
  • 原文地址:https://www.cnblogs.com/dayq/p/16078808.html
Copyright © 2020-2023  润新知