参考:Revival_S
头文件:
// toolfunc.h
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 >= pSectionHeaderTemp->VirtualAddress && dwRva < pOptionHeader->SizeOfImage)
{
return pSectionHeaderTemp->PointerToRawData + dwRva - pSectionHeaderTemp->VirtualAddress;
}
printf("RVA TO FOA Failed!\n");
return 0;
}
主程序:
#include<stdio.h>
#include<windows.h>
#include "toolfunc.h"
PSTR file_path = "C:\\Users\\lolol\\Desktop\\3.exe";
int main(){
PIMAGE_DOS_HEADER pDosHeader = NULL;
PIMAGE_FILE_HEADER pPEHeader = NULL;
PIMAGE_OPTIONAL_HEADER pOptionHeader = NULL;
PIMAGE_SECTION_HEADER pSectionHeader = NULL;
PIMAGE_DATA_DIRECTORY pDataDirectory = NULL;
PIMAGE_BASE_RELOCATION pRelocationTable = NULL;
PIMAGE_IMPORT_DESCRIPTOR pImportTable = NULL;
PIMAGE_IMPORT_BY_NAME pImportByName = NULL;
PVOID pFileBuffer = NULL;
BYTE zero[sizeof(IMAGE_IMPORT_DESCRIPTOR)] = {0};
DWORD FileSize = toLoardPE(&pFileBuffer, file_path);
printf("读入文件大小:%x\n",FileSize);
pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
pPEHeader = (PIMAGE_FILE_HEADER)((DWORD)pFileBuffer + pDosHeader->e_lfanew + 4);
pOptionHeader = (PIMAGE_OPTIONAL_HEADER)((DWORD)pPEHeader + IMAGE_SIZEOF_FILE_HEADER);
pDataDirectory = pOptionHeader->DataDirectory;
pDataDirectory = pDataDirectory + 1; // 重定位表的目录表
printf("导入表的地址:%#x\n",pDataDirectory->VirtualAddress);
if(!pDataDirectory->VirtualAddress){
printf("没有导入表\n");
return 0;
}
pImportTable = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD)pFileBuffer + Rva2Foa(pFileBuffer, pDataDirectory->VirtualAddress));
// 遍历所有导入表
for(size_t i=0; memcmp(zero, pImportTable, sizeof(zero)); i++){
printf("==========第%2d个导入表==========\n",i);
printf("被使用的DLL的名字:%s\n", (char*)((DWORD)pFileBuffer + Rva2Foa(pFileBuffer, pImportTable->Name)));
printf("INT地址:%#x\n", pImportTable->OriginalFirstThunk);
printf("时间戳:%#x\n", pImportTable->TimeDateStamp);
printf("IAT地址:%#x\n", pImportTable->FirstThunk);
// INT
printf("===============INT==============\n");
PDWORD pINTItem = NULL;
pINTItem = (PDWORD)((DWORD)pFileBuffer + Rva2Foa(pFileBuffer, pImportTable->OriginalFirstThunk));
for(int numINT = 0; *pINTItem; numINT++){ // 遍历每个IMAGE_THUNK_DATA
if((*pINTItem) & 0x80000000){// 存的是序号
//printf("1\n");
printf("第%d个函数的序号%#x\n", numINT, *pINTItem & 0x7fffffff);
}else{// 存的是RVA,指向IMAGE_IMPORT_BY_NAME
pImportByName = (PIMAGE_IMPORT_BY_NAME)((DWORD)pFileBuffer + Rva2Foa(pFileBuffer, *pINTItem));
printf("第%d个函数的名字%#x-%s\n", numINT, pImportByName->Hint, pImportByName->Name);
}
pINTItem++;
}
// IAT
printf("===============IAT==============\n");
PDWORD pIATItem = NULL;
pIATItem = (PDWORD)((DWORD)pFileBuffer + Rva2Foa(pFileBuffer, pImportTable->FirstThunk));
for(int numIAT = 0; *pIATItem; numIAT++){ // 遍历每个IMAGE_THUNK_DATA
if((*pIATItem) & 0x80000000){// 存的是序号
//printf("1\n");
printf("第%d个函数的序号%#x\n", numIAT, *pIATItem & 0x7fffffff);
}else{// 存的是RVA,指向IMAGE_IMPORT_BY_NAME
pImportByName = (PIMAGE_IMPORT_BY_NAME)((DWORD)pFileBuffer + Rva2Foa(pFileBuffer, *pIATItem));
printf("第%d个函数的名字%#x-%s\n", numIAT, pImportByName->Hint, pImportByName->Name);
}
pIATItem++;
}
pImportTable++;
}
return 0;
}