具体流程参考:Revival_S
#include<stdio.h>
#include<windows.h>
DWORD Rva2Foa(PVOID pFileBuffer, DWORD dwRva);
DWORD Align(int add, int alignment);
DWORD printExportTable(PVOID pFileBuffer);
DWORD getFuncAddrByName(PVOID pFileBuffer, PSTR name);
DWORD getFuncAddrByOrdinal(PVOID pFileBuffer, DWORD ord);
DWORD toLoardPE(PVOID* pFileBuffer, PSTR file_path){
FILE *fp;
DWORD FileSize;
PVOID pFileBufferTemp;
fp = fopen(file_path, "rb");
if(!fp){
printf("读取文件失败!\n");
return 0;
}
fseek(fp, 0, SEEK_END);
FileSize = ftell(fp);
fseek(fp, 0, SEEK_SET);
pFileBufferTemp = malloc(FileSize);
if(!pFileBufferTemp){
printf("读取文件开辟内存失败\n");
return 0;
}
DWORD n = fread(pFileBufferTemp, FileSize, 1, fp);
*pFileBuffer = pFileBufferTemp;
pFileBufferTemp = NULL;
fclose(fp);
return FileSize;
}
DWORD Align(int add, int alignment){
if(add % alignment == 0){
return add;
}
return ((add / alignment) + 1) * alignment;
}
DWORD Rva2Foa(PVOID pFileBuffer, DWORD dwRva){
PIMAGE_DOS_HEADER pDosHeader = NULL;
PIMAGE_NT_HEADERS pNTHeader = NULL;
PIMAGE_FILE_HEADER pPEHeader = NULL;
PIMAGE_OPTIONAL_HEADER pOptionHeader = NULL;
PIMAGE_SECTION_HEADER pSectionHeader = NULL;
if(!pFileBuffer){
printf("从磁盘读取文件为空!\n");
return 0;
}
if(*((PWORD)pFileBuffer) != IMAGE_DOS_SIGNATURE){
printf("(Rva2Foa)没有MZ标志!\n");
return 0;
}
pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
if(*(PDWORD)((DWORD)pDosHeader + pDosHeader->e_lfanew) != IMAGE_NT_SIGNATURE){
printf("(Rva2Foa)没有PE标志!\n");
return 0;
}
pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew);
pPEHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 4);
pOptionHeader = (PIMAGE_OPTIONAL_HEADER)((DWORD)pPEHeader + IMAGE_SIZEOF_FILE_HEADER);
pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader + pPEHeader->SizeOfOptionalHeader);
PIMAGE_SECTION_HEADER pSectionHeaderTemp = pSectionHeader;
PIMAGE_SECTION_HEADER pNextSectionHeaderTemp = pSectionHeader + 1;
if(dwRva <= pOptionHeader->SizeOfHeaders){
return dwRva;
}else{
for(int n=1; n < pPEHeader->NumberOfSections; n++, pSectionHeaderTemp++, pNextSectionHeaderTemp++){
if((dwRva >= pSectionHeaderTemp->VirtualAddress) && (dwRva < (pNextSectionHeaderTemp->VirtualAddress)))
return dwRva - pSectionHeaderTemp->VirtualAddress + pSectionHeaderTemp->PointerToRawData;
}
}
if (dwRva >= pSectionHeader->VirtualAddress && dwRva < pOptionHeader->SizeOfImage)
{
return pSectionHeader->PointerToRawData + dwRva - pSectionHeader->VirtualAddress;
}
printf("RVA TO FOA Failed!\n");
return 0;
}
DWORD printExportTable(PVOID pFileBuffer){
if(!pFileBuffer){
printf("文件不存在!\n");
return 0;
}
PIMAGE_DOS_HEADER pDosHeader = NULL;
PIMAGE_NT_HEADERS pNTHeader = NULL;
PIMAGE_FILE_HEADER pPEHeader = NULL;
PIMAGE_OPTIONAL_HEADER pOptionHeader = NULL;
PIMAGE_SECTION_HEADER pSectionHeader = NULL;
PIMAGE_DATA_DIRECTORY pDataDirectory = NULL;
PIMAGE_EXPORT_DIRECTORY pExportDirectory = NULL;
pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
printf("%x\n",pDosHeader->e_magic);
if(pDosHeader->e_magic != IMAGE_DOS_SIGNATURE){
printf("(printExportTable)没有MZ标志!\n");
return 0;
}
pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pFileBuffer + pDosHeader->e_lfanew);
if(pNTHeader->Signature != IMAGE_NT_SIGNATURE){
printf("(printExportTable)没有PE标志!\n");
return 0;
}
pPEHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 4);
pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader + IMAGE_SIZEOF_FILE_HEADER);
pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader + pPEHeader->SizeOfOptionalHeader);
pDataDirectory = (PIMAGE_DATA_DIRECTORY)pOptionHeader->DataDirectory;
if(!pDataDirectory->VirtualAddress){
printf("没有导出表!\n");
return 0;
}
printf("导出表的RVA:%x\n", pDataDirectory->VirtualAddress);
DWORD exportFoa = Rva2Foa(pFileBuffer, pDataDirectory->VirtualAddress);
printf("导出表的FOA:%x\n", exportFoa);
pExportDirectory = (PIMAGE_EXPORT_DIRECTORY)((DWORD)pFileBuffer + exportFoa);
/*
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;
*/
printf("=================导出表=================\n");
printf("Characteristics:%#x\n", pExportDirectory->Characteristics);
printf("TimeDateStamp:%#x\n", pExportDirectory->TimeDateStamp);
printf("MajorVersion:%#x\n", pExportDirectory->MajorVersion);
printf("MinorVersion:%#x\n", pExportDirectory->MinorVersion);
DWORD namefoa = Rva2Foa(pFileBuffer, pExportDirectory->Name);
printf("Name:%s\n", (PVOID)((DWORD)pFileBuffer + namefoa));
printf("Base:%#x\n", pExportDirectory->Base);
printf("NumberOfFunctions:%#x\n", pExportDirectory->NumberOfFunctions);
printf("NumberOfNames:%#x\n", pExportDirectory->NumberOfNames);
printf("AddressOfFunctions(RVA):%#x\n", pExportDirectory->AddressOfFunctions);
printf("AddressOfNames(RVA):%#x\n", pExportDirectory->AddressOfNames);
printf("AddressOfNameOrdinals(RVA):%#x\n", pExportDirectory->AddressOfNameOrdinals);
printf("=================导出函数地址表=================\n");
DWORD addrFuncFoa = Rva2Foa(pFileBuffer, pExportDirectory->AddressOfFunctions);
printf("函数地址表的FOA:%#x\n", addrFuncFoa);
for(size_t i=0; i < pExportDirectory->NumberOfFunctions; i++){
DWORD addrfunc = *(PDWORD)((DWORD)pFileBuffer + addrFuncFoa + i * 4);
printf("下标:%#x 函数地址:%#x\n", i, addrfunc);
}
printf("=================导出函数名称表=================\n");
DWORD nameFoa = Rva2Foa(pFileBuffer, pExportDirectory->AddressOfNames);
printf("函数名称表的FOA:%#x\n", nameFoa);
for(i=0; i < pExportDirectory->NumberOfNames; i++){
DWORD funcName = Rva2Foa(pFileBuffer, *(PDWORD)((DWORD)pFileBuffer + nameFoa + i*4));
PCHAR name = (PCHAR)((DWORD)pFileBuffer + funcName);
printf("下标:%#x 函数名称:%s\n", i, name);
}
printf("=================导出函数序号表=================\n");
DWORD ordinalNumberFoa = Rva2Foa(pFileBuffer, pExportDirectory->AddressOfNameOrdinals);
printf("函数序号表的FOA:%#x\n", ordinalNumberFoa);
for(i=0; i < pExportDirectory->NumberOfNames; i++){
WORD funcOrdinal = *(PWORD)((DWORD)pFileBuffer + ordinalNumberFoa + i*2);
printf("下标:%#x 函数序号:%#x\n",i, funcOrdinal);
}
return 0;
}
DWORD getFuncAddrByName(PVOID pFileBuffer, PSTR byname){
PIMAGE_DOS_HEADER pDosHeader = NULL;
PIMAGE_NT_HEADERS pNTHeader = NULL;
PIMAGE_FILE_HEADER pPEHeader = NULL;
PIMAGE_OPTIONAL_HEADER pOptionHeader = NULL;
PIMAGE_SECTION_HEADER pSectionHeader = NULL;
PIMAGE_DATA_DIRECTORY pDataDirectory = NULL;
PIMAGE_EXPORT_DIRECTORY pExportDirectory = NULL;
pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pFileBuffer + pDosHeader->e_lfanew);
pPEHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 4);
pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader + IMAGE_SIZEOF_FILE_HEADER);
pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader + pPEHeader->SizeOfOptionalHeader);
pDataDirectory = (PIMAGE_DATA_DIRECTORY)pOptionHeader->DataDirectory;
DWORD exportFoa = Rva2Foa(pFileBuffer, pDataDirectory->VirtualAddress);
pExportDirectory = (PIMAGE_EXPORT_DIRECTORY)((DWORD)pFileBuffer + exportFoa);
printf("=================函数名称查找函数地址=================\n");
DWORD nameFoa = Rva2Foa(pFileBuffer, pExportDirectory->AddressOfNames);
for(size_t i=0; i < pExportDirectory->NumberOfNames; i++){
DWORD funcName = Rva2Foa(pFileBuffer, *(PWORD)((DWORD)pFileBuffer + nameFoa + i*4));
PCHAR name = (PCHAR)((DWORD)pFileBuffer + funcName);
if(!strcmp(byname, name)){
printf("找到相同函数名称\n");
break;
}
}
if(i == pExportDirectory->NumberOfNames){
printf("不存在该函数名称\n");
return 0;
}
DWORD ordinalNumberFoa = Rva2Foa(pFileBuffer, pExportDirectory->AddressOfNameOrdinals);
WORD funcOrdinal = *(PWORD)((DWORD)pFileBuffer + ordinalNumberFoa + i*2);
DWORD addrFuncFoa = Rva2Foa(pFileBuffer, pExportDirectory->AddressOfFunctions);
DWORD addrfunc = *(PDWORD)((DWORD)pFileBuffer + addrFuncFoa + funcOrdinal * 4);
return addrfunc;
}
DWORD getFuncAddrByOrdinal(PVOID pFileBuffer, DWORD ord){
PIMAGE_DOS_HEADER pDosHeader = NULL;
PIMAGE_NT_HEADERS pNTHeader = NULL;
PIMAGE_FILE_HEADER pPEHeader = NULL;
PIMAGE_OPTIONAL_HEADER pOptionHeader = NULL;
PIMAGE_SECTION_HEADER pSectionHeader = NULL;
PIMAGE_DATA_DIRECTORY pDataDirectory = NULL;
PIMAGE_EXPORT_DIRECTORY pExportDirectory = NULL;
pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pFileBuffer + pDosHeader->e_lfanew);
pPEHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 4);
pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader + IMAGE_SIZEOF_FILE_HEADER);
pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader + pPEHeader->SizeOfOptionalHeader);
pDataDirectory = (PIMAGE_DATA_DIRECTORY)pOptionHeader->DataDirectory;
DWORD exportFoa = Rva2Foa(pFileBuffer, pDataDirectory->VirtualAddress);
pExportDirectory = (PIMAGE_EXPORT_DIRECTORY)((DWORD)pFileBuffer + exportFoa);
printf("=================函数序号查找函数地址=================\n");
if(ord - pExportDirectory->Base > pExportDirectory->NumberOfFunctions || ord - pExportDirectory->Base < 0){
printf("找不到序号对应的函数地址\n");
return 0;
}
DWORD funcAddrFoa = Rva2Foa(pFileBuffer, pExportDirectory->AddressOfFunctions);
DWORD funcAddr = *(PDWORD)((DWORD)pFileBuffer + funcAddrFoa + (ord - pExportDirectory->Base) * 4);
printf("%d\n",pExportDirectory->Base);
return funcAddr;
}
int main(){
PSTR file_path = "C:\\Users\\lolol\\Desktop\\11.dll";
PSTR write_path = "";
PVOID pFileBuffer = NULL;
PVOID pImageBuffer = NULL;
DWORD FileSize = toLoardPE(&pFileBuffer, file_path);
//printf("%x\n",((char*)pFileBuffer)[0]);
//printf("%x\n",pFileBuffer);
printExportTable(pFileBuffer);
DWORD addrfunc = getFuncAddrByName(pFileBuffer, "CreateFile2");
printf("根据函数名查询结果:%x\n",addrfunc);
DWORD funcAddrByord = getFuncAddrByOrdinal(pFileBuffer, 3);
printf("根据序号查询结果:%x\n",funcAddrByord);
return 0;
}