#include "windows.h"
#include "stdio.h"
DWORD RVA2Offset(PIMAGE_NT_HEADERS pNTHeader, DWORD dwRVA)
{
PIMAGE_SECTION_HEADER pSection = (PIMAGE_SECTION_HEADER)((DWORD)pNTHeader + sizeof(IMAGE_NT_HEADERS));
for(int i = 0; i < pNTHeader->FileHeader.NumberOfSections; i++)
{
if(dwRVA >= pSection.VirtualAddress && dwRVA < (pSection.VirtualAddress + pSection.SizeOfRawData))
{
return pSection.PointerToRawData + (dwRVA - pSection.VirtualAddress);
}
}
return 0;
}
void PE64_DLL(PCHAR lpFileName)
{
HANDLE hfile = CreateFileA(lpFileName,
GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if(hfile == INVALID_HANDLE_VALUE)
{
printf("[P.Y.G]创建文件失败.\n");
return ;
}
HANDLE hFileMapping = CreateFileMapping(hfile, NULL, PAGE_READONLY, 0, 0, NULL);
if (hFileMapping == NULL || hFileMapping == INVALID_HANDLE_VALUE)
{
printf("[P.Y.G]创建共享内存失败 (%d).\n", GetLastError());
return ;
}
LPBYTE lpBaseAddress = (LPBYTE)MapViewOfFile(hFileMapping, FILE_MAP_READ, 0, 0, 0);
if (lpBaseAddress == NULL)
{
printf("[P.Y.G]内存映射失败 (%d).\n", GetLastError());
return ;
}
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)lpBaseAddress;
// 验证PE合法性
if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE)
{
printf("[PYG]--非PE文件!\n");
// 自行清理现场。。。
return;
}
PIMAGE_NT_HEADERS pNtHeaders = (PIMAGE_NT_HEADERS)(lpBaseAddress + pDosHeader->e_lfanew);
// 继续验证PE合法性
if(pNtHeaders->Signature != IMAGE_NT_SIGNATURE)
{
printf("[PYG]--非PE文件!\n");
// 自行清理现场。。。
return;
}
int dwExportOffset = RVA2Offset(pNtHeaders, pNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
PIMAGE_EXPORT_DIRECTORY pExport = (PIMAGE_EXPORT_DIRECTORY)((DWORD)lpBaseAddress + dwExportOffset);
DWORD dwFunctionNameOffset = (DWORD)lpBaseAddress + RVA2Offset(pNtHeaders, pExport->Name);
DWORD* pdwNamesAddress = (DWORD*)((DWORD)lpBaseAddress + RVA2Offset(pNtHeaders, pExport->AddressOfNames));
DWORD* pdwFunctionAddress = (DWORD*)((DWORD)lpBaseAddress + RVA2Offset(pNtHeaders, pExport->AddressOfFunctions));
WORD* pwOrdinals = (WORD*)((DWORD)lpBaseAddress + RVA2Offset(pNtHeaders, pExport->AddressOfNameOrdinals));
DWORD dwNumberOfNames = pExport->NumberOfNames;
if(dwNumberOfNames > 0)
{
printf("[P.Y.G]文件名: %s\n", dwFunctionNameOffset);
printf("[P.Y.G]导出函数总数: %X\n", pExport->NumberOfFunctions);
printf("[P.Y.G]名称函数总数: %X\n\n", pExport->NumberOfNames);
printf("名称导出:\n\n");
for(int i = 0; i < dwNumberOfNames; i++)
{
DWORD dwFunctionAddress = pdwFunctionAddress[pwOrdinals];
DWORD pdwFunNameOffset = (DWORD)lpBaseAddress + RVA2Offset(pNtHeaders, pdwNamesAddress);
printf("[P.Y.G][序号]: %-4X [名称]: %-30s [RVA]: 0x%08X\n", pExport->Base + i/* + 1*/, pdwFunNameOffset, dwFunctionAddress);
}
printf("\n序号导出:\n\n");
for(int i = 0; i < pExport->NumberOfFunctions - dwNumberOfNames; i++)
{
printf("[P.Y.G][序号]: %-4d [RVA]: 0x%08X\n", pExport->Base + i/* + 1*/, pdwFunctionAddress);
}
}else
printf("\n\t---------- [P.Y.G]未找到导出表! ----------\n");
UnmapViewOfFile(lpBaseAddress);
CloseHandle(hFileMapping);
CloseHandle(hfile);
}
void main()
{
char szFileName[MAX_PATH];
printf("请输入文件路径:\n");
scanf("%s", szFileName);
PE64_DLL(szFileName);
system("pause");
}
|