抛砖引玉2-PE64简单解析DLL导出表
#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("创建文件失败.\n");
return ;
}
HANDLE hFileMapping = CreateFileMapping(hfile, NULL, PAGE_READONLY, 0, 0, NULL);
if (hFileMapping == NULL || hFileMapping == INVALID_HANDLE_VALUE)
{
printf("创建共享内存失败 (%d).\n", GetLastError());
return ;
}
LPBYTE lpBaseAddress = (LPBYTE)MapViewOfFile(hFileMapping, FILE_MAP_READ, 0, 0, 0);
if (lpBaseAddress == NULL)
{
printf("内存映射失败 (%d).\n", GetLastError());
return ;
}
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)lpBaseAddress;
// 验证PE合法性
if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE)
{
printf("--非PE文件!\n");
// 自行清理现场。。。
return;
}
PIMAGE_NT_HEADERS pNtHeaders = (PIMAGE_NT_HEADERS)(lpBaseAddress + pDosHeader->e_lfanew);
// 继续验证PE合法性
if(pNtHeaders->Signature != IMAGE_NT_SIGNATURE)
{
printf("--非PE文件!\n");
// 自行清理现场。。。
return;
}
int dwExportOffset = RVA2Offset(pNtHeaders, pNtHeaders->OptionalHeader.DataDirectory.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("文件名: %s\n", dwFunctionNameOffset);
printf("导出函数总数: %X\n", pExport->NumberOfFunctions);
printf("名称函数总数: %X\n\n", pExport->NumberOfNames);
printf("名称导出:\n\n");
for(int i = 0; i < dwNumberOfNames; i++)
{
DWORD dwFunctionAddress = pdwFunctionAddress];
DWORD pdwFunNameOffset = (DWORD)lpBaseAddress + RVA2Offset(pNtHeaders, pdwNamesAddress);
printf("[序号]: %-4X[名称]: %-30s: 0x%08X\n", pExport->Base + i/* + 1*/, pdwFunNameOffset, dwFunctionAddress);
}
printf("\n序号导出:\n\n");
for(int i = 0; i < pExport->NumberOfFunctions - dwNumberOfNames; i++)
{
printf("[序号]: %-4d: 0x%08X\n", pExport->Base + i/* + 1*/, pdwFunctionAddress);
}
}else
printf("\n\t---------- 未找到导出表! ----------\n");
UnmapViewOfFile(lpBaseAddress);
CloseHandle(hFileMapping);
CloseHandle(hfile);
}
void main()
{
char szFileName;
printf("请输入文件路径:\n");
scanf("%s", szFileName);
PE64_DLL(szFileName);
system("pause");
}
学习了,感谢小鹏
[快捷回复]-感谢楼主热心分享!
[快捷回复]-软件反汇编逆向分析,软件安全必不可少! 感谢楼主分享。 看起来有点复杂,收藏先,有空研究一下 666,学到了
楼主,牛逼啊! C也太厉害了
页:
[1]