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\n", (PSTR)(RVAToFOA(pSectionHeader, *pOptionHeader, pExportDir->Name, pFileHeader->NumberOfSections) + (DWORD)FileBuffer)); 50 printf("Base:%d\n", pExportDir->Base); 51 printf("NumberOfFunctions:%d\n", pExportDir->NumberOfFunctions); 52 printf("NumberOfFunctionNames:%d\n", pExportDir->NumberOfNames); 53 printf("AddressOfFunctions(偏移地址):%x\n", pExportDir->AddressOfFunctions); 54 printf("AddressOfNames(偏移地址):%x\n", RVAToFOA(pSectionHeader, *pOptionHeader, pExportDir->AddressOfNames, pFileHeader->NumberOfSections)); 55 printf("AddressOfNameOrdinals(偏移地址):%x\n", RVAToFOA(pSectionHeader, *pOptionHeader, pExportDir->AddressOfNameOrdinals, pFileHeader->NumberOfSections)); 56 printf("\n*******************************函数地址表*******************************"); 57 for (int i = 0; i < pExportDir->NumberOfFunctions; i++) 58 { 59 printf("\n函数地址RVA:%x\n",*(AddressOfFunctions + i)); 60 printf("\n函数地址FOA:%x\n", RVAToFOA(pSectionHeader, *pOptionHeader, *(AddressOfFunctions + i), pFileHeader->NumberOfSections)); 61 } 62 printf("\n*****************************函数名称地址表*****************************"); 63 for (int i = 0; i < pExportDir->NumberOfNames; i++) 64 { 65 printf("\n函数地址名称地址:%x\n", *((PDWORD)((DWORD)AddressOfNames + i * 4))); 66 printf("\n函数名称:%s\n", (PSTR)((RVAToFOA(pSectionHeader, *pOptionHeader, *((PDWORD)((DWORD)AddressOfNames + i * 4)), pFileHeader->NumberOfSections) + (DWORD)FileBuffer))); 67 } 68 printf("\n*******************************函数序号表*******************************"); 69 for (int i = 0; i < pExportDir->NumberOfNames; i++) 70 { 71 if(*(PSHORT)((DWORD)AddressOfNameOrdinals + i * 2) !=0) 72 printf("\n函数序号:%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("\nFunction:%s\n", 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("\nFunctionIndex:%d", i); 148 if (j) { 149 index = *(PSHORT)((DWORD)AddressOfNameOrdinals + 2 * i); 150 printf("\nindex:%hd\n",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("\nYou need Function1:%x\n", *Myneedfun); 194 Myneedfun = GetFunctionAddrByOrdinals(pFileBuffer, 2); 195 printf("\nYou 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\n"); 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); }