打印 PE导入导出表

#include<Windows.h>
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<commdlg.h>
using namespace std;
DWORD dwFileSize;
BYTE* g_pFileImageBase = 0;
PIMAGE_NT_HEADERS g_pNt = 0;

DWORD RVAtoFOA(DWORD dwRVA);

//显示pe头
//参数为内存映射首地址
void myPE() {
        OPENFILENAME stOF;
        HANDLE hFile, hMapFile;
        DWORD totalSize;        //文件大小
        LPVOID lpMemory;        //内存映像文件在内存的起始位置
        char szFileName[MAX_PATH] = { 0 };  //要打开的文件路径及名称名
        char bufTemp1[10];                  //每个字符的十六进制字节码
        char bufTemp2[20];                  //第一列
        char lpServicesBuffer[100];     //一行的所有内容
        char bufDisplay[50];                //第三列ASCII码字符
        DWORD dwCount;                      //计数,逢16则重新计
        DWORD dwCount1;                     //地址顺号
        DWORD dwBlanks;                     //最后一行空格数
        char szExtPe[] = TEXT("PE Files\0*.exe;*.dll;*.scr;*.fon;*.drv\0All Files(*.*)\0*.*\0\0");
        RtlZeroMemory(&stOF, sizeof(stOF));
        stOF.lStructSize = sizeof(stOF);
        //stOF.hwndOwner = (HWND)GetModuleHandle(NULL);
        stOF.lpstrFilter = szExtPe;
        stOF.lpstrFile = szFileName;
        stOF.nMaxFile = MAX_PATH;
        stOF.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
    if (GetOpenFileName(&stOF))     //让用户选择打开的文件
    {
        hFile = CreateFile(szFileName, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
                    NULL, OPEN_EXISTING, FILE_ATTRIBUTE_ARCHIVE, NULL);
        //如果是无效的句柄
        if (hFile == INVALID_HANDLE_VALUE) {
            printf("文件打开失败\n");
            return;
        }
        //获取文件大小
        dwFileSize = GetFileSize(hFile, NULL);
        g_pFileImageBase = new BYTE[dwFileSize]{};
        DWORD dwRead;
        //将文件读取到内存中
        bool bRet =ReadFile(hFile, g_pFileImageBase, dwFileSize, &dwRead, NULL);
        //如果读取失败就返回
        if (!bRet)
        {
            delete[] g_pFileImageBase;
        }
        //关闭句柄
        CloseHandle(hFile);
/////////////////////////////////dos头///////////////////////////////////////////////
        //typedef struct _IMAGE_DOS_HEADER {      // DOS .EXE header
        //  WORD   e_magic;                     // Magic number
        //  WORD   e_cblp;                      // Bytes on last page of file
        //  WORD   e_cp;                        // Pages in file
        //  WORD   e_crlc;                      // Relocations
        //  WORD   e_cparhdr;                   // Size of header in paragraphs
        //  WORD   e_minalloc;                  // Minimum extra paragraphs needed
        //  WORD   e_maxalloc;                  // Maximum extra paragraphs needed
        //  WORD   e_ss;                        // Initial (relative) SS value
        //  WORD   e_sp;                        // Initial SP value
        //  WORD   e_csum;                      // Checksum
        //  WORD   e_ip;                        // Initial IP value
        //  WORD   e_cs;                        // Initial (relative) CS value
        //  WORD   e_lfarlc;                    // File address of relocation table
        //  WORD   e_ovno;                      // Overlay number
        //  WORD   e_res[4];                    // Reserved words
        //  WORD   e_oemid;                     // OEM identifier (for e_oeminfo)
        //  WORD   e_oeminfo;                   // OEM information; e_oemid specific
        //  WORD   e_res2[10];                  // Reserved words
        //  LONG   e_lfanew;                    // File address of new exe header
        //} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;
/////////////////////////////////dos头///////////////////////////////////////////////
        //使用PIMAGE_DOS_HEADER(占64字节)解释前64个字节
        PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)g_pFileImageBase;
        //判断PE文件的标识是否正确,有一个不对,那么它就不是PE文件
        if (pDos->e_magic != IMAGE_DOS_SIGNATURE)//0x5A4D(‘MZ‘)
        {
            return ;
        }
        cout << "---------------------------DOS头(_IMAGE_DOS_HEADER)------------------------------- "<< endl;
        cout << hex << "WORD   e_magic:     " << pDos->e_magic << endl;
        cout << hex << "WORD   e_cblp:      " << pDos->e_cblp << endl;
        cout << hex << "WORD   e_cp:        " << pDos->e_cp << endl;
        cout << hex << "WORD   e_cblp:      " << pDos->e_cblp << endl;
        cout << hex << "WORD   e_cparhdr:   " << pDos->e_cparhdr << endl;
        cout << hex << "WORD   e_minalloc:  " << pDos->e_minalloc << endl;
        cout << hex << "WORD   e_ss:        " << pDos->e_ss << endl;
        cout << hex << "WORD   e_sp:        " << pDos->e_sp << endl;
        cout << hex << "WORD   e_csum:      " << pDos->e_csum << endl;
        cout << hex << "WORD   e_ip:        " << pDos->e_ip << endl;
        cout << hex << "WORD   e_cs:        " << pDos->e_cs << endl;
        cout << hex << "WORD   e_lfarlc:    " << pDos->e_lfarlc << endl;
        cout << hex << "WORD   e_ovno:      " << pDos->e_ovno << endl;
        cout << hex << "WORD   e_res[4]:    " << *(pDos->e_res) << endl;
        cout << hex << "WORD   e_oemid:     " << pDos->e_oemid << endl;
        cout << hex << "WORD   e_oeminfo:   " << pDos->e_oeminfo << endl;
        cout << hex << "WORD   e_res2[10]:  " << *(pDos->e_res2) << endl;
        cout << hex << "WORD   e_lfanew:    " << pDos->e_lfanew << endl;

/////////////////////////////////NT头///////////////////////////////////////////////

        /*typedef struct _IMAGE_NT_HEADERS {
            DWORD Signature;
            IMAGE_FILE_HEADER FileHeader;
            IMAGE_OPTIONAL_HEADER32 OptionalHeader;
        } IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;*/
        g_pNt = (PIMAGE_NT_HEADERS)(pDos->e_lfanew + g_pFileImageBase);
        if (g_pNt->Signature != IMAGE_NT_SIGNATURE)//0x00004550(‘PE‘)
        {
            return ;
        }
        cout << "---------------------------NT头(PIMAGE_NT_HEADERS)------------------------------- " << endl;
        cout << hex << "DWORD Signature;                              " << g_pNt->Signature << endl;
        cout << hex << "IMAGE_FILE_HEADER FileHeader;                 " << &g_pNt->OptionalHeader << endl;
        cout << hex << "IMAGE_OPTIONAL_HEADER32 OptionalHeader;       " << &g_pNt->OptionalHeader << endl;
/////////////////////////////////FILE头///////////////////////////////////////////////
        /*typedef struct _IMAGE_FILE_HEADER {
            WORD    Machine;
            WORD    NumberOfSections;
            DWORD   TimeDateStamp;
            DWORD   PointerToSymbolTable;
            DWORD   NumberOfSymbols;
            WORD    SizeOfOptionalHeader;
            WORD    Characteristics;
        } IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;*/
        PIMAGE_FILE_HEADER mytmf = &(g_pNt->FileHeader);
        cout << "---------------------------FILE头(IMAGE_FILE_HEADER )----------------------------- " << endl;
        cout << hex << "WORD    Machine;                              " << mytmf->Machine << endl;
        cout << hex << "WORD    NumberOfSections;                     " << mytmf->NumberOfSections << endl;
        cout << hex << "DWORD   TimeDateStamp;                        " << mytmf->TimeDateStamp << endl;
        cout << hex << "DWORD   PointerToSymbolTable;                 " << mytmf->PointerToSymbolTable << endl;
        cout << hex << "DWORD   NumberOfSymbols;                      " << mytmf->NumberOfSymbols << endl;
        cout << hex << "WORD    SizeOfOptionalHeader;                 " << mytmf->SizeOfOptionalHeader << endl;
        cout << hex << "WORD    Characteristics;                      " << mytmf->Characteristics << endl;
        /////////////////////////////////Optional头///////////////////////////////////////////////

        //
        // Optional header format.
        //

        //typedef struct _IMAGE_OPTIONAL_HEADER {
        //  //
        //  // Standard fields.
        //  //

        //  WORD    Magic;
        //  BYTE    MajorLinkerVersion;
        //  BYTE    MinorLinkerVersion;
        //  DWORD   SizeOfCode;
        //  DWORD   SizeOfInitializedData;
        //  DWORD   SizeOfUninitializedData;
        //  DWORD   AddressOfEntryPoint;
        //  DWORD   BaseOfCode;
        //  DWORD   BaseOfData;

        //  //
        //  // NT additional fields.
        //  //

        //  DWORD   ImageBase;
        //  DWORD   SectionAlignment;
        //  DWORD   FileAlignment;
        //  WORD    MajorOperatingSystemVersion;
        //  WORD    MinorOperatingSystemVersion;
        //  WORD    MajorImageVersion;
        //  WORD    MinorImageVersion;
        //  WORD    MajorSubsystemVersion;
        //  WORD    MinorSubsystemVersion;
        //  DWORD   Win32VersionValue;
        //  DWORD   SizeOfImage;
        //  DWORD   SizeOfHeaders;
        //  DWORD   CheckSum;
        //  WORD    Subsystem;
        //  WORD    DllCharacteristics;
        //  DWORD   SizeOfStackReserve;
        //  DWORD   SizeOfStackCommit;
        //  DWORD   SizeOfHeapReserve;
        //  DWORD   SizeOfHeapCommit;
        //  DWORD   LoaderFlags;
        //  DWORD   NumberOfRvaAndSizes;
        //  IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
        //} IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;
        PIMAGE_OPTIONAL_HEADER32 myoption = &(g_pNt->OptionalHeader);
        cout << "---------------------------OPTIONAL头(PIMAGE_OPTIONAL_HEADER32 )-------------------------------------------------- " << endl;

        cout << "---------------------------------------Standard fields.------------------------------------------------------------- " << endl;
        cout << hex << "WORD    Magic;                                     " << myoption->Magic << endl;
        cout << hex << "BYTE    MajorLinkerVersion;                        " << myoption->MajorLinkerVersion << endl;
        cout << hex << "BYTE    MinorLinkerVersion;                        " << myoption->MinorLinkerVersion << endl;
        cout << hex << "DWORD   SizeOfCode;                                " << myoption->SizeOfCode << endl;
        cout << hex << "DWORD   SizeOfInitializedData;                     " << myoption->SizeOfInitializedData << endl;
        cout << hex << "DWORD   SizeOfUninitializedData;                   " << myoption->SizeOfUninitializedData << endl;
        cout << hex << "DWORD   AddressOfEntryPoint;                       " << myoption->AddressOfEntryPoint << endl;
        cout << hex << "DWORD   BaseOfCode;                                " << myoption->BaseOfCode << endl;
        cout << hex << "DWORD   BaseOfData;                                " << myoption->BaseOfData << endl;
        cout << "----------------------------------------- NT additional fields.----------------------------------------------------- " << endl;
        cout << hex << "DWORD   ImageBase;                                 " << myoption->ImageBase << endl;
        cout << hex << "DWORD   SectionAlignment;                          " << myoption->SectionAlignment << endl;
        cout << hex << "DWORD   FileAlignment;                             " << myoption->FileAlignment << endl;
        cout << hex << "WORD    MajorOperatingSystemVersion;               " << myoption->MajorOperatingSystemVersion << endl;
        cout << hex << "WORD    MinorOperatingSystemVersion;               " << myoption->MinorOperatingSystemVersion << endl;
        cout << hex << "WORD    MajorImageVersion;                         " << myoption->MajorImageVersion << endl;
        cout << hex << "DWORD   SectionAlignment;                          " << myoption->SectionAlignment << endl;
        cout << hex << "WORD    MinorImageVersion;                         " << myoption->MinorImageVersion << endl;
        cout << hex << "WORD    MajorSubsystemVersion;                     " << myoption->MajorSubsystemVersion << endl;
        cout << hex << "WORD    MinorSubsystemVersion;                     " << myoption->MinorSubsystemVersion << endl;
        cout << hex << "DWORD   Win32VersionValue;                         " << myoption->Win32VersionValue << endl;
        cout << hex << "DWORD   SizeOfImage;                               " << myoption->SizeOfImage << endl;
        cout << hex << "DWORD   SizeOfHeaders;                             " << myoption->SizeOfHeaders << endl;
        cout << hex << "DWORD   CheckSum;                                  " << myoption->CheckSum << endl;
        cout << hex << "WORD    Subsystem;                                 " << myoption->Subsystem << endl;
        cout << hex << "WORD    DllCharacteristics;                        " << myoption->DllCharacteristics << endl;
        cout << hex << "DWORD   SizeOfStackReserve;                        " << myoption->SizeOfStackReserve << endl;
        cout << hex << "DWORD   SizeOfStackCommit;                         " << myoption->SizeOfStackCommit << endl;
        cout << hex << "DWORD   SizeOfHeapReserve;                         " << myoption->SizeOfHeapReserve << endl;
        cout << hex << "DWORD   SizeOfHeapCommit;                          " << myoption->SizeOfHeapCommit << endl;
        cout << hex << "DWORD   LoaderFlags;                               " << myoption->LoaderFlags << endl;
        cout << hex << "DWORD   NumberOfRvaAndSizes;                       " << myoption->NumberOfRvaAndSizes << endl;
        cout << hex << "IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];" << &(myoption->DataDirectory) << endl;
        /////////////////////////////////////////////所有区段表头////////////////////////////////////////////////////
        /*typedef struct _IMAGE_SECTION_HEADER {
            BYTE    Name[IMAGE_SIZEOF_SHORT_NAME];
            union {
                DWORD   PhysicalAddress;
                DWORD   VirtualSize;
            } Misc;
            DWORD   VirtualAddress;
            DWORD   SizeOfRawData;
            DWORD   PointerToRawData;
            DWORD   PointerToRelocations;
            DWORD   PointerToLinenumbers;
            WORD    NumberOfRelocations;
            WORD    NumberOfLinenumbers;
            DWORD   Characteristics;
        } IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;*/
        //所有区表头都在一起
        //大文件头中找区段数
        int nCountOfSection = g_pNt->FileHeader.NumberOfSections;
        //取第一个区表头
        PIMAGE_SECTION_HEADER pSec = IMAGE_FIRST_SECTION(g_pNt);
        //循环
        for (int i = 0; i < nCountOfSection; i++)
        {
        cout << "----------------------第"<<i<<"个-----PIMAGE_SECTION_HEADER头(PIMAGE_OPTIONAL_HEADER32 )----------------------------- " << endl;
        cout << "BYTE    Name[IMAGE_SIZEOF_SHORT_NAME];                    " << pSec->Name << endl;
        cout << hex << "DWORD   PhysicalAddress;                           " << pSec->Misc.PhysicalAddress << endl;
        cout << hex << "DWORD   VirtualSize;                               " << pSec->Misc.VirtualSize << endl;
        cout << hex << "DWORD   VirtualAddress;                            " << pSec->VirtualAddress << endl;
        cout << hex << "DWORD   SizeOfRawData;                             " << pSec->SizeOfRawData << endl;
        cout << hex << "DWORD   PointerToRawData;                          " << pSec->PointerToRawData << endl;
        cout << hex << "DWORD   PointerToRelocations;                      " << pSec->PointerToRelocations << endl;
        cout << hex << "WORD    PointerToLinenumbers;                      " << pSec->PointerToLinenumbers << endl;
        cout << hex << "WORD    NumberOfRelocations;                       " << pSec->NumberOfRelocations << endl;
        cout << hex << "DWORD   NumberOfLinenumbers;                       " << pSec->NumberOfLinenumbers << endl;
        cout << hex << "DWORD   Characteristics;                           " << pSec->Characteristics << endl;
        cout << hex << "在文件中相对文件偏移;                            " << RVAtoFOA(pSec->VirtualAddress) << endl;

            //下一个区表头首地址
            ++pSec;
        }
        /////////////////////////////////////////////导出表///////////////////////////////////////////////////////////
        //typedef struct _IMAGE_EXPORT_DIRECTORY {
        //  DWORD   Characteristics;
        //  DWORD   TimeDateStamp;
        //  WORD    MajorVersion;
        //  WORD    MinorVersion;
        //  DWORD   Name;
        //  DWORD   Base;
        //  DWORD   NumberOfFunctions;
        //  DWORD   NumberOfNames;
        //  DWORD   AddressOfFunctions;     // RVA from base of image
        //  DWORD   AddressOfNames;         // RVA from base of image
        //  DWORD   AddressOfNameOrdinals;  // RVA from base of image
        //} IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY;
        //找到导出表  也就是第一个表下标为0
        DWORD dwExportRVA =g_pNt->OptionalHeader.DataDirectory[0].VirtualAddress;
        //获取在文件中的位置
        PIMAGE_EXPORT_DIRECTORY pExport =(PIMAGE_EXPORT_DIRECTORY)(RVAtoFOA(dwExportRVA) + g_pFileImageBase);
        //模块名字
        char* pName = (char*)(RVAtoFOA(pExport->Name) + g_pFileImageBase);
        printf("%s\n", pName);
        //地址表中的个数
        DWORD dwCountOfFuntions = pExport->NumberOfFunctions;
        //名称表中的个数
        DWORD dwCountOfNames = pExport->NumberOfNames;
        //地址表地址
        PDWORD pAddrOfFuntion = (PDWORD)(RVAtoFOA(pExport->AddressOfFunctions) + g_pFileImageBase);
        //名称表地址
        PDWORD pAddrOfName = (PDWORD)(RVAtoFOA(pExport->AddressOfNames) + g_pFileImageBase);
        //序号表地址
        PWORD pAddrOfOrdial = (PWORD)(RVAtoFOA(pExport->AddressOfNameOrdinals) + g_pFileImageBase);
        //base值
        DWORD dwBase = pExport->Base;
        //遍历地址表中的元素
        cout << "-----------------------------------------导出表中的导出函数与导出序号-------------------------------------------------- " << endl;
        if (dwExportRVA == 0) {
            printf("没有导出表\n");
            //return;
        }
        else {
            for (int i = 0; i < dwCountOfFuntions;i++)
            {
                //地址表中可能存在无用的值(就是为0的值)
                if (pAddrOfFuntion[i] == 0)
                {
                    continue;
                }
                //根据序号表中是否有值(地址表的下标值),
                //来判断是否是名称导出
                bool bRet = false;
                for (int j = 0; j < dwCountOfNames;j++)
                {
                    //i为地址表下标j为序号表的下标(值为地址表下标)
                    //判断是否在序号表中
                    if (i == pAddrOfOrdial[j])
                    {
                        //因为序号表与名称表的位置一一对应
                        //取出名称表中的名称地址RVA
                        DWORD dwNameRVA = pAddrOfName[j];
                        char* pFunName = (char*)(RVAtoFOA(dwNameRVA) + g_pFileImageBase);
                        printf("%04d  %s  0x%08x\n", i + dwBase, pFunName, pAddrOfFuntion[i]);
                        bRet = true;
                        break;
                    }
                }
                if (!bRet)
                {
                    //序号表中没有,说明是以序号导出的
                    printf("%04d           %08X\n", i + dwBase, pAddrOfFuntion[i]);
                }

            }
        }
        /////////////////////////////////////////////导出表///////////////////////////////////////////////////////////
        //typedef struct _IMAGE_IMPORT_DESCRIPTOR {
        //  union {
        //      DWORD   Characteristics;            // 0 for terminating null import descriptor
        //      DWORD   OriginalFirstThunk;         // RVA to original unbound IAT (PIMAGE_THUNK_DATA)
        //  } DUMMYUNIONNAME;
        //  DWORD   TimeDateStamp;                  // 0 if not bound,
        //                                          // -1 if bound, and real date\time stamp
        //                                          //     in IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT (new BIND)
        //                                          // O.W. date/time stamp of DLL bound to (Old BIND)

        //  DWORD   ForwarderChain;                 // -1 if no forwarders
        //  DWORD   Name;
        //  DWORD   FirstThunk;                     // RVA to IAT (if bound this IAT has actual addresses)
        //} IMAGE_IMPORT_DESCRIPTOR;
        //typedef IMAGE_IMPORT_DESCRIPTOR UNALIGNED *PIMAGE_IMPORT_DESCRIPTOR;
        cout << "-----------------------------------------导入表中的导入函数与导入模块-------------------------------------------------- " << endl;

        //找到导入表  也就是第二个下标为1
        DWORD dwImpotRVA = g_pNt->OptionalHeader.DataDirectory[1].VirtualAddress;
        //在文件中的位置
        DWORD dwImportInFile = (DWORD)(RVAtoFOA(dwImpotRVA) + g_pFileImageBase);
        PIMAGE_IMPORT_DESCRIPTOR pImport = (PIMAGE_IMPORT_DESCRIPTOR)dwImportInFile;
        //遍历每一个导入表  通过最后一个为0作为判断条件
        if (dwImpotRVA == 0) {
            printf("没有导入表\n");
            return;
        }
        else {
            while (pImport->Name)
            {
                //函数名称地址
                PIMAGE_THUNK_DATA pFirsThunk =
                    (PIMAGE_THUNK_DATA)(RVAtoFOA(pImport->FirstThunk) + g_pFileImageBase);
                //模块名
                char* pName = (char*)(RVAtoFOA(pImport->Name) + g_pFileImageBase);
                printf("导入模块名字%s\n", pName);
                //也是通过最后一个为0作为判断条件
                while (pFirsThunk->u1.AddressOfData)
                {
                    //判断导入方式
                    if (IMAGE_SNAP_BY_ORDINAL32(pFirsThunk->u1.AddressOfData))
                    {
                        //说明是序号导入(低16位是其序号)
                        printf("\t\t%04X \n", pFirsThunk->u1.Ordinal & 0xFFFF);
                    }
                    else
                    {
                        //名称导入
                        PIMAGE_IMPORT_BY_NAME pImportName =
                            (PIMAGE_IMPORT_BY_NAME)(RVAtoFOA(pFirsThunk->u1.AddressOfData) + g_pFileImageBase);
                        printf("\t\t%04X %s \n", pImportName->Hint, pImportName->Name);
                    }
                    //
                    pFirsThunk++;
                }
                pImport++;
            }
        }
        return ;
    }

}
//void _openFile();
DWORD RVAtoFOA(DWORD dwRVA)
{
    //此RVA落在哪个区段中
    //找到所在区段后,
    //减去所在区段的起始位置,加上在文件中的起始位置
    //大文件头中找区段数
    int nCountOfSection = g_pNt->FileHeader.NumberOfSections;
    //区段表头
    PIMAGE_SECTION_HEADER pSec = IMAGE_FIRST_SECTION(g_pNt);
    //在扩展头中找到块对齐数
    DWORD dwSecAligment = g_pNt->OptionalHeader.SectionAlignment;
    //循环
    for (int i = 0; i < nCountOfSection; i++)
    {
        //求在内存中的真实大小
        //Misc.VirtualSize % dwSecAligment如果是0代表刚好对齐否则就先对齐(非0就是真)
        //Misc.VirtualSize / dwSecAligment * dwSecAligment   + dwSecAligment     //最后加上余数的对齐
        DWORD dwRealVirSize = pSec->Misc.VirtualSize % dwSecAligment ?
            pSec->Misc.VirtualSize / dwSecAligment * dwSecAligment + dwSecAligment
            : pSec->Misc.VirtualSize;
        //区段中的相对虚拟地址转文件偏移  思路是 用要转换的地址与各个区
        //段起始地址做比较如果落在一个区段中(大于起始地址小于起始地址加区段最大偏移和),
        //就用要转换的相对虚拟地址减去区段的起始地址的相对虚拟地址,
        //得到了这个地址相对这个区段偏移,再用得到的这个偏移加上区段在文件中的偏移的起始位置
        //(pointerToRawData字段)就是他在文件中的文件偏移
        if (dwRVA >= pSec->VirtualAddress &&
            dwRVA < pSec->VirtualAddress + dwRealVirSize)
        {
            //FOA = RVA - 内存中区段的起始位置 + 在文件中区段的起始位置
            return dwRVA - pSec->VirtualAddress + pSec->PointerToRawData;
        }
        //下一个区段地址
        pSec++;
    }
}
int main() {

    myPE();
    cin.get();
}

原文地址:http://blog.51cto.com/haidragon/2104466

时间: 2024-11-02 06:00:26

打印 PE导入导出表的相关文章

PE知识复习之PE的导出表

PE知识复习之PE的导出表 一丶简介 在说明PE导出表之前.我们要理解.一个PE可执行程序.是由一个文件组成的吗. 答案: 不是.是由很多PE文件组成.DLL也是PE文件.如果我们PE文件运行.那么就需要依赖DLL.系统DLL就是Kerner32.dll user32.dll等等.这些都是PE文件. 什么是导出表: 导出表就是当前的PE文件提供了那些函数.给别人用. 举个例子: PE文件相当于一个饭店.那么菜单就是导出表. 导出表解盲: 有人认为exe可执行文件.没有导出表.而DLL有导出表.这

【数据库】Oracle 11g使用命令导入导出表,导出结果集

[数据库]Oracle 11g使用命令导入导出表,导出结果集 很久没敲命令进行Oracle数据库表的导入(imp),导出(exp)了,今天猛一敲,发现有些命令居然忘了,顺手写下这篇博文,记录一下! exp本地导出命令: 1 exp username/[email protected] file=d:\demo.dmpfull=y 2 exp username/[email protected] file=d:\demo.dmpowner=(xx) 3 exp username/[email pr

《初识PE》导出表

转自:http://www.blogfshare.com/pe-export.html (二).导出表 当PE文件被执行的时候,Windows装载器将文件装入内存并将导入表中登记的DLL文件一并装入,再根据DLL文件中的函数导出信息对被执行文件的IAT表进行修正. Windows 在加载一个程序后就在内存中为该程序开辟一个单独的虚拟地址空间,这样的话在各个程序自己看来,自己就拥有几乎任意地址的支配权,所以他自身的函数想放在哪个地址自己说了算.有一些函数很多程序都会用到,为每一个程序写一个相同的函

PE文件结构详解(四)PE导入表

PE文件结构详解(二)可执行文件头的最后展示了一个数组,PE文件结构详解(三)PE导出表中解释了其中第一项的格式,本篇文章来揭示这个数组中的第二项:IMAGE_DIRECTORY_ENTRY_IMPORT,即导入表. 也许大家注意到过,在IMAGE_DATA_DIRECTORY中,有几项的名字都和导入表有关系,其中包括:IMAGE_DIRECTORY_ENTRY_IMPORT,IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT,IMAGE_DIRECTORY_ENTRY_IAT

使用Navicat导入导出表的数据做测试(转载)

当我们对MySQL数据库进行了误操作,造成某个数据表中的部分数据丢失时,肯定就要利用备份的数据库,对丢失部分的数据进行导出.导入操作了.Navicat工具正好给我们提供了一个数据表的导入导出功能. 1.导出数据表 Navicat导出数据表的格式很多,增加了对Excel2007以上版本的支持,当设计完一个表后,如果有上百条或更多的数据需要导入mysql数据库时,我们可以先把设计好的数据导出到一个Excel表中,然后按照格式去填充,最后把这些填充完的数据再导入到mysql数据库中. 步骤1:点击[导

plsql导入导出表数据

导出表结构: Tools(工具)-->Export User Objects(导出用户对象) -->选择要导出的表(包括Sequence等)-->.sql文件,导出的都为sql文件 导出表数据: Tools(工具)-->Export Tables(导出表)-->选择表,选择SQL Inserts(SQL 插入)-->.sql文件 导入表结构: 执行刚刚导出的sql文件,记住要删掉table前的用户名,比如以前这表名为sys.tablename,必须删除sys 导入表数据

控制台程序,打印pe头信息

#include "stdafx.h" #include <stdio.h> #include <string.h> #include <iostream.h> #include <math.h> #include <stdlib.h> #define DWORD unsigned long #define LPVOID void* #define VOID void #define WORD unsigned short #

plsql导入导出表

原来总是直接 tools->import talbes->Oracle Import结果发现有的时候会出错:有的表不能正确导入, baidu+googel解决办法如下: 导出步骤: 1 tools ->export user object 选择选项,导出.sql文件 2 tools ->export tables-> Oracle Export 选择选项导出.dmp文件 导入步骤: 1 tools->import tables->SQL Inserts 导入.sq

PLSQL导入导出表的正确步骤

导出步骤: 1. tools ->export user object 选择选项,导出.sql文件 2. tools ->export tables-> Oracle Export 选择选项导出.dmp文件 导入步骤: 1. tools->import tables->SQL Inserts 导入.sql文件 2. tools->import talbes->Oracle Import然后再导入dmp文件 数据库的导入导出成功 ==================