记录控制台版的peInfo


记录一下控制台版的PeInfo

开发环境:MinGW Dev-C++

代码:

//#include "widget.h"

//#include 

//int main(int argc, char *argv[])
//{
//    QApplication a(argc, argv);
//    Widget w;
//    w.show();
//    return a.exec();
//}
#include
#include
#include
#include
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;iVa)//考虑是一个内存中的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;iNumberOfNamedEntries);
    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;iLength,2,(char*)beginEntry-(char*)base+offset);
//                return;
            }
            else
            {
                printf("%s\t%-7d\t",tab.c_str(),temp.Id);
            }
            cout<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;iDataDirectory[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<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<NumberOfSections;i++)
    {
        sprintf(str,"FVA:0x%-8X\t0x%-12X\t0x%-12X\t0x%-8X\t0x%-12X\t0x%-8X\n",((char*)§ionTable[i] - (char*)base),((char*)§ionTable[i].PointerToRawData - (char*)base),((char*)§ionTable[i].VirtualAddress - (char*)base),((char*)§ionTable[i].Misc.VirtualSize - (char*)base),((char*)§ionTable[i].SizeOfRawData - (char*)base),((char*)§ionTable[i].Characteristics - (char*)base) );
        cout<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;iu1.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))<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;iBase + hint[i]),((char*)base + RvaToFva(base,names[i])));
            noName[hint[i]] = false;
        }
        cout<<"内存偏移\t文件偏移\t访问标号\n";
        bool haveNoName = false;
        for(int i=0;iBase+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<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<<"开始解析"<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<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;iDataDirectory[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<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<NumberOfSections;i++)
    {
        sprintf(str,"FVA:0x%-8X\t0x%-12X\t0x%-12X\t0x%-8X\t0x%-12X\t0x%-8X\n",((char*)§ionTable[i] - (char*)base),((char*)§ionTable[i].PointerToRawData - (char*)base),((char*)§ionTable[i].VirtualAddress - (char*)base),((char*)§ionTable[i].Misc.VirtualSize - (char*)base),((char*)§ionTable[i].SizeOfRawData - (char*)base),((char*)§ionTable[i].Characteristics - (char*)base) );
        cout<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;iu1.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))<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;iBase +hint[i] ),((char*)base + RvaToFva(base,names[i])));
            noName[hint[i]] = false;
        }
        cout<<"内存偏移\t文件偏移\t访问标号\n";
        bool haveNoName = false;
        for(int i=0;iBase + 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<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 = "<>filename;
        filename = "C:\\Users\\DELL\\Desktop\\323\\pe.exe";
        if(filename=="cls")
        {
            system("cls");
        }
        else
        {
            system("cls");
            LoadFile(filename);
        }
        while(1);
    }
}


相关