Shark_鹏 发表于 2015-3-24 22:26

抛砖引玉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");
}




Scar-疤痕 发表于 2015-3-25 06:51

学习了,感谢小鹏

hackysh 发表于 2022-2-21 17:25


[快捷回复]-感谢楼主热心分享!

zwj00544 发表于 2022-2-22 03:15


[快捷回复]-软件反汇编逆向分析,软件安全必不可少!

沙画 发表于 2022-3-9 12:44

感谢楼主分享。

别管我了行 发表于 2022-3-10 04:29

曾经沧海 发表于 2022-11-4 18:15

看起来有点复杂,收藏先,有空研究一下

曾经沧海 发表于 2022-11-23 20:34

666,学到了

曾经沧海 发表于 2023-4-17 09:13


楼主,牛逼啊!

一生逍遥 发表于 2023-5-13 18:39

C也太厉害了
页: [1]
查看完整版本: 抛砖引玉2-PE64简单解析DLL导出表