获得PE文件输入表和输出表

来源:互联网 发布:潍坊行知学校录取标准 编辑:程序博客网 时间:2024/05/29 03:07
#include <windows.h>
#include <iostream>
#include<ImageHlp.h>
#pragma comment(lib,"imagehlp.lib")
using namespace std;
int main()
{
    char* strExePath="C:\\Windows\\System32\\kernel32.dll";
    //打开文件
    HANDLE hFile=::CreateFile(strExePath,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
    if(NULL==hFile)
    {
        cout<<"CreateFile error:"<<GetLastError()<<endl;
        return 0;
    }
    cout<<"CreateFile successfully\n";
    //创建内存映像
    HANDLE hMap=CreateFileMappingA(hFile,NULL,PAGE_READONLY,0,0,NULL);
    if(NULL==hMap)
    {
        cout<<"CreateFileMappingA error:"<<GetLastError()<<endl;
        return 0;
    }
    cout<<"CreateFilemappingA successfully\n";
    //获得文件基地址
    LPVOID lpImageBase=MapViewOfFile(hMap,FILE_MAP_READ,0,0,0);
    if(NULL==lpImageBase)
    {
        cout<<"MapViewOfFile error:"<<GetLastError()<<endl;
        return 0;
    }
    cout<<"MapViewOfFile successfully\n";
    //获得DOS头部指针
    PIMAGE_DOS_HEADER pDos=(PIMAGE_DOS_HEADER)lpImageBase;
    if(pDos->e_magic==IMAGE_DOS_SIGNATURE)
        cout<<"DOS 头部检测成功\n";
    else    
    {
        cout<<"并非exe文件\n";
    }
    //获得NT文件头
    PIMAGE_NT_HEADERS pNtHeader;
    pNtHeader = (PIMAGE_NT_HEADERS)((DWORD)pDos + pDos->e_lfanew);
    if(pNtHeader->Signature==IMAGE_NT_SIGNATURE)
    {
        cout<<"可用exe文件\n";
    }

    //获得文件头部
    PIMAGE_FILE_HEADER pFile=(PIMAGE_FILE_HEADER)(&pNtHeader->FileHeader);
    //获得可选头部
    PIMAGE_OPTIONAL_HEADER pOptionalHeader=(PIMAGE_OPTIONAL_HEADER)(&pNtHeader->OptionalHeader);
    //获得区段头
    PIMAGE_SECTION_HEADER pSectionHeader;     
    pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionalHeader + pFile->SizeOfOptionalHeader);
    PIMAGE_SECTION_HEADER pSectionUse=pSectionHeader;
    for(int i=0;i<pFile->NumberOfSections;i++)
    {
        char tmp[256]={0};
        wsprintf(tmp,"%s",pSectionUse->Name);
        cout<<tmp<<endl;                                
        //pSectionHeader+=sizeof(PIMAGE_SECTION_HEADER);
        pSectionUse++;
    }
    //获得输出表
    PIMAGE_EXPORT_DIRECTORY pExportDir=(PIMAGE_EXPORT_DIRECTORY)ImageRvaToVa(pNtHeader,lpImageBase,pOptionalHeader->DataDirectory[0].VirtualAddress,&pSectionHeader);
    cout<<"输出函数个数是:"<<pExportDir->NumberOfNames<<endl;
    DWORD **ppdwNames = (DWORD **)pExportDir->AddressOfNames;
    ppdwNames = (PDWORD*)ImageRvaToVa(pNtHeader,
            lpImageBase, (DWORD)ppdwNames, 0);
    DWORD ppdwFunc = (DWORD )pExportDir->AddressOfFunctions;
    for(int i=0;i<1;i++)
    {
       char *szFunc=(PSTR)ImageRvaToVa(pNtHeader, lpImageBase, (DWORD)*ppdwNames, 0);
       DWORD dwAddress=(DWORD)ImageRvaToVa(pNtHeader, lpImageBase, (DWORD)ppdwFunc, 0);
       cout<<szFunc<<"::"<<dwAddress<<endl;  
       ppdwNames++;
    }
    DWORD* pFuncAddress=(DWORD*)pExportDir->AddressOfNameOrdinals;



    
    //获得输入表
    PIMAGE_IMPORT_DESCRIPTOR pImportDir ;
    cout<<"通过寻找OrignalFirstThunk\n";
    pImportDir = (PIMAGE_IMPORT_DESCRIPTOR)ImageRvaToVa(pNtHeader,lpImageBase,(DWORD)pOptionalHeader->DataDirectory[1].VirtualAddress,&pSectionHeader);
    while((pImportDir->Name)!=NULL)
    {

    cout<<(char*)ImageRvaToVa(pNtHeader,lpImageBase,pImportDir->Name,&pSectionHeader)<<endl<<endl;;
    PIMAGE_THUNK_DATA thunk_data=(PIMAGE_THUNK_DATA)ImageRvaToVa(pNtHeader,lpImageBase,pImportDir->OriginalFirstThunk,&pSectionHeader);
    while((thunk_data->u1.AddressOfData)!=NULL)
    {
    PIMAGE_IMPORT_BY_NAME he=(PIMAGE_IMPORT_BY_NAME)ImageRvaToVa(pNtHeader,lpImageBase,thunk_data->u1.AddressOfData,&pSectionHeader);     
    cout<<he->Hint<<":"<<he->Name<<endl;
    thunk_data++;
    }
    pImportDir++;
    cout<<endl;
    }        

    
    return 0;

}