PE文件入门(二)

导出表

一、使用程序打印出导出表里的三张表:函数地址表,函数名称地址表,函数序数表,并且通过函数序数表来查找函数地址或用函数名字来查找函数地址

导出表数据结构

IMAGE_EXPORT_DIRECTORY STRUCT
     Characteristics        DWORD?; 未使用,总是定义为0
     TimeDateStamp      DWORD?       ; 文件生成时间
     MajorVersion          WORD? ; 未使用,总是定义为0
     MinorVersion          WORD? ; 未使用,总是定义为0
     Name                      DWORD?; 模块的真实名称
     Base                       DWORD?; 基数,加上序数就是函数地址数组的索引值,一般为1
     NumberOfFunctions              DWORD?; 导出函数的总数(序号不推荐)
     NumberOfNames                  DWORD? ; 以名称方式导出的函数的总数
     AddressOfFunctions              DWORD?; 指向输出函数地址的RVA
     AddressOfNames                  DWORD?; 指向输出函数名字的RVA
     AddressOfNameOrdinals      DWORD?; 指向输出函数序号的RVA

IMAGE_EXPORT_DIRECTORY ENDS
  1 #define _CRT_SECURE_NO_WARNINGS
  2 #include<Windows.h>
  3 #include<stdio.h>
  4 #include<iostream>
  5 using namespace std;
  6 //RVA到FOA的转换
  7 DWORD RVAToFOA(PIMAGE_SECTION_HEADER SectionHeader,IMAGE_OPTIONAL_HEADER OptionHeader,DWORD address,DWORD NumberOfSectionHeader)
  8 {
  9     int i;
 10     DWORD FOA = 0;
 11     if (address< OptionHeader.SectionAlignment)
 12         return address;
 13     for (i = 0; i < NumberOfSectionHeader; i++)
 14     {
 15         if (address >= SectionHeader->VirtualAddress && address <= SectionHeader->VirtualAddress + (SectionHeader->Misc.VirtualSize / OptionHeader.SectionAlignment + 1) * OptionHeader.SectionAlignment)
 16         {
 17             FOA = address - SectionHeader->VirtualAddress+SectionHeader->PointerToRawData;
 18             
 19             return FOA;
 20         }
 21         SectionHeader++;
 22     }
 23     
 24 }
 25 //打印导出表信息
 26 VOID PrintExportTable(PVOID FileBuffer)
 27 {
 28     PIMAGE_DOS_HEADER pDosHeader;
 29     PIMAGE_NT_HEADERS pNTHeader;
 30     PIMAGE_FILE_HEADER pFileHeader;
 31     PIMAGE_OPTIONAL_HEADER pOptionHeader;
 32     PIMAGE_SECTION_HEADER pSectionHeader;
 33     PIMAGE_DATA_DIRECTORY pDataDir;
 34 
 35     pDosHeader = (PIMAGE_DOS_HEADER)FileBuffer;
 36     pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader+pDosHeader->e_lfanew);
 37     pFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 4);
 38     pOptionHeader = (PIMAGE_OPTIONAL_HEADER)(DWORD(pFileHeader) + IMAGE_SIZEOF_FILE_HEADER);
 39     pDataDir = (PIMAGE_DATA_DIRECTORY)((DWORD)pOptionHeader + pFileHeader->SizeOfOptionalHeader - 128);
 40     pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader + pFileHeader->SizeOfOptionalHeader);
 41     
 42     PIMAGE_EXPORT_DIRECTORY pExportDir = (PIMAGE_EXPORT_DIRECTORY)(RVAToFOA(pSectionHeader,*pOptionHeader,pDataDir->VirtualAddress,pFileHeader->NumberOfSections)+(DWORD)FileBuffer);
 43     
 44     
 45     PDWORD AddressOfFunctions = (PDWORD)(RVAToFOA(pSectionHeader, *pOptionHeader, pExportDir->AddressOfFunctions, pFileHeader->NumberOfSections)+ (DWORD)FileBuffer);
 46     PDWORD AddressOfNameOrdinals = (PDWORD)(RVAToFOA(pSectionHeader, *pOptionHeader, pExportDir->AddressOfNameOrdinals, pFileHeader->NumberOfSections) + (DWORD)FileBuffer);
 47     PVOID AddressOfNames = (PVOID)(RVAToFOA(pSectionHeader, *pOptionHeader, pExportDir->AddressOfNames, pFileHeader->NumberOfSections) + (DWORD)FileBuffer);
 48 
 49     printf("Name:%s
", (PSTR)(RVAToFOA(pSectionHeader, *pOptionHeader, pExportDir->Name, pFileHeader->NumberOfSections) + (DWORD)FileBuffer));
 50     printf("Base:%d
", pExportDir->Base);
 51     printf("NumberOfFunctions:%d
", pExportDir->NumberOfFunctions);
 52     printf("NumberOfFunctionNames:%d
", pExportDir->NumberOfNames);
 53     printf("AddressOfFunctions(偏移地址):%x
", pExportDir->AddressOfFunctions);
 54     printf("AddressOfNames(偏移地址):%x
", RVAToFOA(pSectionHeader, *pOptionHeader, pExportDir->AddressOfNames, pFileHeader->NumberOfSections));
 55     printf("AddressOfNameOrdinals(偏移地址):%x
", RVAToFOA(pSectionHeader, *pOptionHeader, pExportDir->AddressOfNameOrdinals, pFileHeader->NumberOfSections));
 56     printf("
*******************************函数地址表*******************************");
 57     for (int i = 0; i < pExportDir->NumberOfFunctions; i++)
 58     {
 59         printf("
函数地址RVA:%x
",*(AddressOfFunctions + i));
 60         printf("
函数地址FOA:%x
", RVAToFOA(pSectionHeader, *pOptionHeader, *(AddressOfFunctions + i), pFileHeader->NumberOfSections));
 61     }
 62     printf("
*****************************函数名称地址表*****************************");
 63     for (int i = 0; i < pExportDir->NumberOfNames; i++)
 64     {
 65         printf("
函数地址名称地址:%x
", *((PDWORD)((DWORD)AddressOfNames + i * 4)));
 66         printf("
函数名称:%s
", (PSTR)((RVAToFOA(pSectionHeader, *pOptionHeader, *((PDWORD)((DWORD)AddressOfNames + i * 4)), pFileHeader->NumberOfSections) + (DWORD)FileBuffer)));
 67     }
 68     printf("
*******************************函数序号表*******************************");
 69     for (int i = 0; i < pExportDir->NumberOfNames; i++)
 70     {
 71         if(*(PSHORT)((DWORD)AddressOfNameOrdinals + i * 2) !=0)
 72             printf("
函数序号:%d", *(PSHORT)((DWORD)AddressOfNameOrdinals+ i*2));
 73     }
 74 }
 75 //读取函数到filebuffer中
 76 LPVOID pReadFile(LPSTR lpszFile)
 77 {
 78     FILE* pFile = NULL;
 79     DWORD filesize = 0;
 80     LPVOID FileBuffer = NULL;
 81 
 82     pFile = fopen(lpszFile, "rb+");
 83     if (!pFile) {
 84         cout << "读取文件失败" << endl;
 85         return NULL;
 86     }
 87 
 88     fseek(pFile, NULL, SEEK_END);
 89     filesize = ftell(pFile);
 90     fseek(pFile, NULL, SEEK_SET);
 91 
 92     FileBuffer = malloc(filesize);
 93     if (!FileBuffer)
 94     {
 95         cout << "内存分配失败" << endl;
 96         fclose(pFile);
 97         return NULL;
 98     }
 99 
100     size_t size = fread(FileBuffer, 1, filesize, pFile);
101     if (!size)
102     {
103         cout << "读取数据失败" << endl;
104         fclose(pFile);
105         return NULL;
106     }
107     fclose(pFile);
108     return FileBuffer;
109 }
110 //通过函数名称来找到函数地址
111 PDWORD GetFunctionAddrByName(PVOID FileBuffer, PSTR FunctionName)
112 {
113     PIMAGE_DOS_HEADER pDosHeader;
114     PIMAGE_NT_HEADERS pNTHeader;
115     PIMAGE_FILE_HEADER pFileHeader;
116     PIMAGE_OPTIONAL_HEADER pOptionHeader;
117     PIMAGE_SECTION_HEADER pSectionHeader;
118     PIMAGE_DATA_DIRECTORY pDataDir;
119 
120     pDosHeader = (PIMAGE_DOS_HEADER)FileBuffer;
121     pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew);
122     pFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 4);
123     pOptionHeader = (PIMAGE_OPTIONAL_HEADER)(DWORD(pFileHeader) + IMAGE_SIZEOF_FILE_HEADER);
124     pDataDir = (PIMAGE_DATA_DIRECTORY)((DWORD)pOptionHeader + pFileHeader->SizeOfOptionalHeader - 128);
125     pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader + pFileHeader->SizeOfOptionalHeader);
126 
127     PIMAGE_EXPORT_DIRECTORY pExportDir = (PIMAGE_EXPORT_DIRECTORY)(RVAToFOA(pSectionHeader, *pOptionHeader, pDataDir->VirtualAddress, pFileHeader->NumberOfSections) + (DWORD)FileBuffer);
128     PVOID AddressOfFunctions = (PVOID)(RVAToFOA(pSectionHeader, *pOptionHeader, pExportDir->AddressOfFunctions, pFileHeader->NumberOfSections) + (DWORD)FileBuffer);
129     PDWORD AddressOfNameOrdinals = (PDWORD)(RVAToFOA(pSectionHeader, *pOptionHeader, pExportDir->AddressOfNameOrdinals, pFileHeader->NumberOfSections) + (DWORD)FileBuffer);
130     PVOID AddressOfNames = (PVOID)(RVAToFOA(pSectionHeader, *pOptionHeader, pExportDir->AddressOfNames, pFileHeader->NumberOfSections) + (DWORD)FileBuffer);
131 
132 
133     int j,i;
134     for (i = 0; i < pExportDir->NumberOfFunctions; i++)
135     {
136         PSTR FunctionOfName = (PSTR)(RVAToFOA(pSectionHeader, *pOptionHeader, *(PDWORD)((DWORD)AddressOfNames + i * 4), pFileHeader->NumberOfSections) + (DWORD)FileBuffer);
137         printf("
Function:%s
", FunctionOfName);
138         for (j = 0; strlen(FunctionOfName) == strlen(FunctionName) && j < strlen(FunctionOfName) && FunctionOfName[j] == FunctionName[j]; j++);
139         if (j == strlen(FunctionOfName))
140             break;
141         else
142             j = 0;
143     }
144 
145     PDWORD addr=NULL;
146     short index=0;
147     printf("
FunctionIndex:%d", i);
148     if (j) {
149         index = *(PSHORT)((DWORD)AddressOfNameOrdinals + 2 * i);
150         printf("
index:%hd
",index);
151         addr = (PDWORD)((DWORD)AddressOfFunctions + index * 4);
152     }
153     return addr;
154 }
155 //通过序数来查找到函数的地址
156 PDWORD GetFunctionAddrByOrdinals(PVOID FileBuffer, int Number)
157 {
158     PIMAGE_DOS_HEADER pDosHeader;
159     PIMAGE_NT_HEADERS pNTHeader;
160     PIMAGE_FILE_HEADER pFileHeader;
161     PIMAGE_OPTIONAL_HEADER pOptionHeader;
162     PIMAGE_SECTION_HEADER pSectionHeader;
163     PIMAGE_DATA_DIRECTORY pDataDir;
164 
165     pDosHeader = (PIMAGE_DOS_HEADER)FileBuffer;
166     pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew);
167     pFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 4);
168     pOptionHeader = (PIMAGE_OPTIONAL_HEADER)(DWORD(pFileHeader) + IMAGE_SIZEOF_FILE_HEADER);
169     pDataDir = (PIMAGE_DATA_DIRECTORY)((DWORD)pOptionHeader + pFileHeader->SizeOfOptionalHeader - 128);
170     pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader + pFileHeader->SizeOfOptionalHeader);
171 
172     PIMAGE_EXPORT_DIRECTORY pExportDir = (PIMAGE_EXPORT_DIRECTORY)(RVAToFOA(pSectionHeader, *pOptionHeader, pDataDir->VirtualAddress, pFileHeader->NumberOfSections) + (DWORD)FileBuffer);
173 
174 
175     PDWORD AddressOfFunctions = (PDWORD)(RVAToFOA(pSectionHeader, *pOptionHeader, pExportDir->AddressOfFunctions, pFileHeader->NumberOfSections) + (DWORD)FileBuffer);
176     PDWORD AddressOfNameOrdinals = (PDWORD)(RVAToFOA(pSectionHeader, *pOptionHeader, pExportDir->AddressOfNameOrdinals, pFileHeader->NumberOfSections) + (DWORD)FileBuffer);
177     PVOID AddressOfNames = (PVOID)(RVAToFOA(pSectionHeader, *pOptionHeader, pExportDir->AddressOfNames, pFileHeader->NumberOfSections) + (DWORD)FileBuffer);
178 
179 
180     return AddressOfFunctions+Number-pExportDir->Base;
181 }
182 
183 int main()
184 {
185     LPSTR lpszFile = (LPSTR)"winResult.dll";
186     LPVOID pFileBuffer = pReadFile(lpszFile);
187     if (!pFileBuffer) {
188         std::cout << "读取文件失败";
189         return 0;
190     }
191     PrintExportTable(pFileBuffer);
192     PDWORD Myneedfun=GetFunctionAddrByName(pFileBuffer, (PSTR)"AnimateClose");
193     printf("
You need Function1:%x
", *Myneedfun);
194     Myneedfun = GetFunctionAddrByOrdinals(pFileBuffer, 2);
195     printf("
You need Function2:%x", *Myneedfun);
196 }

 二、使用新增节把导出表转移到新增节中,并且程序可以正常运行

导入步骤如下:

第一步:添加转移函数地址表

第二步:在后面添加转移函数序号表

第三步:转移函数名称地址表

第四步:转移该导出表的名称

第五步:转移函数名称地址表里的字符串

第六步:转移导出表数据结构

第七步:修复里面的值,并且修复数据目录

#define _CRT_SECURE_NO_WARNINGS
#include<Windows.h>
#include<iostream>
using namespace std;
DWORD filesize = 0;
DWORD newfilesize = 0;
DWORD RVAToFOA(PIMAGE_SECTION_HEADER SectionHeader, IMAGE_OPTIONAL_HEADER OptionHeader, DWORD address, DWORD NumberOfSectionHeader)
{
    int i;
    DWORD FOA = 0;
    //printf("%x", address);
    if (address < OptionHeader.SectionAlignment)
        return address;
    for (i = 0; i < NumberOfSectionHeader; i++)
    {
        if (address >= SectionHeader->VirtualAddress && address < SectionHeader->VirtualAddress + (SectionHeader->Misc.VirtualSize / OptionHeader.SectionAlignment + 1) * OptionHeader.SectionAlignment)
        {
            FOA = address - SectionHeader->VirtualAddress + SectionHeader->PointerToRawData;
            return FOA;
        }
        SectionHeader++;
    }
}


PVOID pReadFile(LPSTR lpszFile)
{
    FILE* pFile = NULL;
    
    LPVOID FileBuffer = NULL;

    pFile = fopen(lpszFile, "rb+");
    if (!pFile) {
        cout << "读取文件失败" << endl;
        return NULL;
    }

    fseek(pFile, NULL, SEEK_END);
    filesize = ftell(pFile);
    fseek(pFile, NULL, SEEK_SET);

    FileBuffer = malloc(filesize);
    if (!FileBuffer)
    {
        cout << "内存分配失败" << endl;
        fclose(pFile);
        return NULL;
    }

    size_t size = fread(FileBuffer, 1, filesize, pFile);
    if (!size)
    {
        cout << "读取数据失败" << endl;
        fclose(pFile);
        return NULL;
    }
    fclose(pFile);
    return FileBuffer;
}

PVOID ExtendSection(PVOID FileBuffer)
{
    PIMAGE_DOS_HEADER pDosHeader;
    PIMAGE_NT_HEADERS pNTHeader;
    PIMAGE_FILE_HEADER pFileHeader;
    PIMAGE_OPTIONAL_HEADER pOptionHeader;
    PIMAGE_SECTION_HEADER pSectionHeader;
    PIMAGE_DATA_DIRECTORY pDataDir;

    pDosHeader = (PIMAGE_DOS_HEADER)FileBuffer;
    pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew);
    pFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 4);
    pOptionHeader = (PIMAGE_OPTIONAL_HEADER)(DWORD(pFileHeader) + IMAGE_SIZEOF_FILE_HEADER);
    pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader + pFileHeader->SizeOfOptionalHeader);

    

    DWORD lastSection = ((pSectionHeader + pFileHeader->NumberOfSections)->PointerToRawData);
    PVOID NewFileBuffer = malloc(filesize + pOptionHeader->FileAlignment * 2);
    newfilesize = filesize + pOptionHeader->FileAlignment * 2;
    memset(NewFileBuffer, 0, filesize + pOptionHeader->FileAlignment * 2);
    memcpy(NewFileBuffer, FileBuffer, filesize);

    pDosHeader = (PIMAGE_DOS_HEADER)NewFileBuffer;
    pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew);
    pFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 4);
    pOptionHeader = (PIMAGE_OPTIONAL_HEADER)(DWORD(pFileHeader) + IMAGE_SIZEOF_FILE_HEADER);

    
    
    pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader + pFileHeader->SizeOfOptionalHeader);

    

    pFileHeader->NumberOfSections++;
    pOptionHeader->SizeOfHeaders = pOptionHeader->SizeOfHeaders + sizeof(IMAGE_SECTION_HEADER);
    pOptionHeader->SizeOfImage = pOptionHeader->SizeOfImage + pOptionHeader->SectionAlignment + sizeof(IMAGE_SECTION_HEADER);
    pSectionHeader = pSectionHeader + pFileHeader->NumberOfSections - 1;
    pSectionHeader->Name[0] = 'M';
    pSectionHeader->Name[1] = 'y';
    pSectionHeader->Name[2] = 'S';
    pSectionHeader->Name[3] = 'e';
    pSectionHeader->Name[4] = 'c';

    pSectionHeader->Misc.VirtualSize = pSectionHeader->SizeOfRawData = pOptionHeader->FileAlignment * 2;
    pSectionHeader->Characteristics |= (pSectionHeader - 1)->Characteristics;
    pSectionHeader->VirtualAddress = (pSectionHeader - 1)->VirtualAddress + pOptionHeader->SectionAlignment;
    pSectionHeader->PointerToRawData = (pSectionHeader - 1)->PointerToRawData + (pSectionHeader - 1)->SizeOfRawData;
    
    

    return NewFileBuffer;
    
}

PVOID AddOfSectionInDll(PVOID FileBuffer)
{
    PIMAGE_DOS_HEADER pDosHeader;
    PIMAGE_NT_HEADERS pNTHeader;
    PIMAGE_FILE_HEADER pFileHeader;
    PIMAGE_OPTIONAL_HEADER pOptionHeader;
    PIMAGE_SECTION_HEADER pSectionHeader;
    PIMAGE_DATA_DIRECTORY pDataDir;

    PVOID NewFileBuffer = ExtendSection(FileBuffer);
    
    pDosHeader = (PIMAGE_DOS_HEADER)NewFileBuffer;
    pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew);
    pFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 4);
    pOptionHeader = (PIMAGE_OPTIONAL_HEADER)(DWORD(pFileHeader) + IMAGE_SIZEOF_FILE_HEADER);
    pDataDir = (PIMAGE_DATA_DIRECTORY)((DWORD)pOptionHeader + pFileHeader->SizeOfOptionalHeader - 128);
    pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader + pFileHeader->SizeOfOptionalHeader);

    PIMAGE_EXPORT_DIRECTORY pExportDir = (PIMAGE_EXPORT_DIRECTORY)(RVAToFOA(pSectionHeader, *pOptionHeader, pDataDir->VirtualAddress, pFileHeader->NumberOfSections) + (DWORD)NewFileBuffer);
    
    memcpy((PVOID)((DWORD)NewFileBuffer + (pSectionHeader + pFileHeader->NumberOfSections - 1)->PointerToRawData), (PVOID)((DWORD)NewFileBuffer + RVAToFOA(pSectionHeader, *pOptionHeader, pExportDir->AddressOfFunctions, pFileHeader->NumberOfSections)), 4 * pExportDir->NumberOfFunctions);
    
    memcpy((PVOID)((DWORD)NewFileBuffer + (pSectionHeader + pFileHeader->NumberOfSections - 1)->PointerToRawData + 4 * pExportDir->NumberOfFunctions), (PVOID)((DWORD)NewFileBuffer + RVAToFOA(pSectionHeader, *pOptionHeader, pExportDir->AddressOfNameOrdinals, pFileHeader->NumberOfSections)), 2 * pExportDir->NumberOfNames);
    
    memcpy((PVOID)((DWORD)NewFileBuffer + (pSectionHeader + pFileHeader->NumberOfSections - 1)->PointerToRawData + 4 * pExportDir->NumberOfFunctions + 2 * pExportDir->NumberOfNames), 
        (PVOID)((DWORD)NewFileBuffer + RVAToFOA(pSectionHeader, *pOptionHeader, pExportDir->AddressOfNames, pFileHeader->NumberOfSections)), 4 * pExportDir->NumberOfNames);
    
    size_t Basesize = (DWORD)NewFileBuffer + (pSectionHeader + pFileHeader->NumberOfSections - 1)->PointerToRawData + 4 * pExportDir->NumberOfFunctions + 2 * pExportDir->NumberOfNames+ 4 * pExportDir->NumberOfNames;
    


    PVOID AddressOfName = (PVOID)(RVAToFOA(pSectionHeader, *pOptionHeader, ((DWORD)pExportDir->AddressOfNames), pFileHeader->NumberOfSections) + (DWORD)NewFileBuffer);

    printf("HHHHHHH
");
    printf("%x", strlen((PSTR)(RVAToFOA(pSectionHeader, *pOptionHeader, pExportDir->Name, pFileHeader->NumberOfSections) + (DWORD)NewFileBuffer)));
    memcpy((PVOID)Basesize, (PVOID)(RVAToFOA(pSectionHeader, *pOptionHeader, pExportDir->Name, pFileHeader->NumberOfSections) + 
        (DWORD)NewFileBuffer),
        strlen((PSTR)(RVAToFOA(pSectionHeader, *pOptionHeader, pExportDir->Name, pFileHeader->NumberOfSections) + (DWORD)NewFileBuffer)));

    pExportDir->Name = Basesize - (DWORD)NewFileBuffer + (pSectionHeader + pFileHeader->NumberOfSections - 1)->VirtualAddress - (pSectionHeader + pFileHeader->NumberOfSections - 1)->PointerToRawData;
    Basesize += strlen((PSTR)(RVAToFOA(pSectionHeader, *pOptionHeader, pExportDir->Name, pFileHeader->NumberOfSections) + (DWORD)NewFileBuffer)) + 1;

    for (int i = 0; i < pExportDir->NumberOfNames; i++)
    {
        memcpy((PVOID)Basesize, (PVOID)(RVAToFOA(pSectionHeader, *pOptionHeader, (*(PDWORD)((DWORD)AddressOfName + i * 4)), pFileHeader->NumberOfSections) + (DWORD)NewFileBuffer), strlen((PSTR)((RVAToFOA(pSectionHeader, *pOptionHeader, (*(PDWORD)((DWORD)AddressOfName + i * 4)), pFileHeader->NumberOfSections) + (DWORD)NewFileBuffer)))+1);
        Basesize += strlen((PSTR)((RVAToFOA(pSectionHeader, *pOptionHeader, (*(PDWORD)((DWORD)AddressOfName + i * 4)), pFileHeader->NumberOfSections) + (DWORD)NewFileBuffer))) + 1;
    }

    pExportDir->AddressOfFunctions = (pSectionHeader + pFileHeader->NumberOfSections - 1)->VirtualAddress- (pSectionHeader + pFileHeader->NumberOfSections - 1)->PointerToRawData +(pSectionHeader + pFileHeader->NumberOfSections - 1)->PointerToRawData;
    
    pExportDir->AddressOfNameOrdinals = (pSectionHeader + pFileHeader->NumberOfSections - 1)->VirtualAddress - (pSectionHeader + pFileHeader->NumberOfSections - 1)->PointerToRawData + (pSectionHeader + pFileHeader->NumberOfSections - 1)->PointerToRawData + 4 * pExportDir->NumberOfFunctions;
    pExportDir->AddressOfNames = (pSectionHeader + pFileHeader->NumberOfSections - 1)->VirtualAddress - (pSectionHeader + pFileHeader->NumberOfSections - 1)->PointerToRawData + (pSectionHeader + pFileHeader->NumberOfSections - 1)->PointerToRawData + 4 * pExportDir->NumberOfFunctions + 2 * pExportDir->NumberOfNames;
    Basesize=Basesize - (DWORD)NewFileBuffer;
    printf("%x", pExportDir->AddressOfFunctions);
    memcpy((PVOID)((Basesize % 16 == 0 ? Basesize : (1 + Basesize / 16) * 16)+(DWORD)NewFileBuffer), pExportDir, sizeof(IMAGE_EXPORT_DIRECTORY));
    Basesize = Basesize % 16 == 0 ? Basesize : ((1 + Basesize / 16) * 16);
    pDataDir->VirtualAddress = (pSectionHeader + pFileHeader->NumberOfSections - 1)->VirtualAddress+Basesize- (pSectionHeader + pFileHeader->NumberOfSections - 1)->PointerToRawData;

    return NewFileBuffer;
}

int main()
{
    LPSTR lpszFile = (LPSTR)"RealwinResult.dll";
    FILE* wp = fopen("winResult_to.dll", "wb+");
    LPVOID pFileBuffer = pReadFile(lpszFile);
    if (!pFileBuffer) {
        std::cout << "读取文件失败";
        return 0;
    }
    LPVOID NewFileBuffer=AddOfSectionInDll(pFileBuffer);
    fwrite(NewFileBuffer, 1, newfilesize, wp);
}
原文地址:https://www.cnblogs.com/pppyyyzzz/p/13268076.html