Guest User

exportDirectory.c

a guest
Jan 27th, 2023
130
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.00 KB | Source Code | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <windows.h>
  4.  
  5. struct _exportTable {
  6.         DWORD offset;
  7.         WORD ordinal;
  8.         DWORD *functionPtr;
  9.         DWORD *functionNameAddr;
  10.         char *functionName;
  11.         char *forwarderName;
  12. };
  13.  
  14. DWORD RVA2FileOffset(DWORD RVA, PIMAGE_SECTION_HEADER sectionHeader)
  15. {
  16.         return RVA - sectionHeader->VirtualAddress + sectionHeader->PointerToRawData;
  17. }
  18.  
  19. void printExportTable(struct _exportTable **exportTable, size_t len)
  20. {
  21.         printf("Offset%10sOrdinals%8sFunction RVA%8sName RVA%8s%-50s%-50s\n", " ", " ", " ", " ", "Name", "Forwarder");
  22.  
  23.         for (int i = 0; i < len; i++) {
  24.                 printf("%08x%8s%8x%8s%012x%8s%08x%8s%-50s%-50s\n",
  25.                 exportTable[i]->offset, " ",
  26.                 exportTable[i]->ordinal, " ",
  27.                 *(exportTable[i]->functionPtr), " ",
  28.                 *(exportTable[i]->functionNameAddr), " ",
  29.                 exportTable[i]->functionName,
  30.                 exportTable[i]->forwarderName);
  31.         }
  32.  
  33.         return;
  34. }
  35.  
  36. void findExportFunctions(char *fbuf)
  37. {
  38.         IMAGE_DOS_HEADER *dosHeader = (IMAGE_DOS_HEADER *)fbuf;
  39.         IMAGE_NT_HEADERS *ntHeaders = (IMAGE_NT_HEADERS *)((size_t)dosHeader + dosHeader->e_lfanew);
  40.  
  41.         PIMAGE_OPTIONAL_HEADER optHeader = &ntHeaders->OptionalHeader;
  42.         IMAGE_DATA_DIRECTORY exportDescriptor = optHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];
  43.  
  44.         PIMAGE_SECTION_HEADER sectionHeader = (PIMAGE_SECTION_HEADER)(((PBYTE)optHeader) + ntHeaders->FileHeader.SizeOfOptionalHeader);
  45.         WORD numberOfSections = ntHeaders->FileHeader.NumberOfSections;
  46.  
  47.         int i;
  48.         DWORD VirtualAddr, VirtualSize;
  49.         for (i = 0; i < numberOfSections; i++) {
  50.                 VirtualAddr = sectionHeader->VirtualAddress;
  51.                 VirtualSize = sectionHeader->Misc.VirtualSize;
  52.  
  53.                 if (VirtualAddr <= exportDescriptor.VirtualAddress &&
  54.                     exportDescriptor.VirtualAddress < VirtualAddr + VirtualSize) {
  55.                         break;
  56.                 }
  57.                 sectionHeader = (PIMAGE_SECTION_HEADER)(((PBYTE)sectionHeader) + sizeof(IMAGE_SECTION_HEADER));
  58.         }
  59.  
  60.         DWORD exportFileOffset = RVA2FileOffset(exportDescriptor.VirtualAddress, sectionHeader);
  61.         IMAGE_EXPORT_DIRECTORY *exportDirectory = (IMAGE_EXPORT_DIRECTORY *)((size_t)dosHeader + exportFileOffset);
  62.         DWORD *AddressOfFunctions = (DWORD *)((size_t)dosHeader + RVA2FileOffset(exportDirectory->AddressOfFunctions, sectionHeader));
  63.         // WORD *AddressOfOrdinals = (WORD *)((size_t)dosHeader + RVA2FileOffset(exportDirectory->AddressOfNameOrdinals, sectionHeader) + exportDirectory->Base * sizeof(WORD));
  64.         WORD *AddressOfOrdinals = (WORD *)((size_t)dosHeader + RVA2FileOffset(exportDirectory->AddressOfNameOrdinals, sectionHeader));
  65.         DWORD *AddressOfNames = (DWORD *)((size_t)dosHeader + RVA2FileOffset(exportDirectory->AddressOfNames, sectionHeader));
  66.        
  67.         printf("%s\n\n", ((size_t)dosHeader + exportDirectory->Name - sectionHeader->VirtualAddress + sectionHeader->PointerToRawData));
  68.  
  69.         printf("Virtual Address : %x\n", exportDescriptor.VirtualAddress);
  70.         printf("File Offset : %x\n", exportFileOffset);
  71.  
  72.         printf("\nExported Functions: %d\n\n", exportDirectory->NumberOfFunctions);
  73.  
  74.         struct _exportTable **exportTable = malloc(sizeof(struct _exportTable *) * exportDirectory->NumberOfFunctions);
  75.         for (i = 0; i < exportDirectory->NumberOfFunctions; i++) exportTable[i] = malloc(sizeof(struct _exportTable));
  76.  
  77.         for (i = 0; i < exportDirectory->NumberOfFunctions; i++) {
  78.                 char *functionName, *forwarderName;
  79.  
  80.                 functionName = (char *)((size_t)dosHeader + RVA2FileOffset(*(AddressOfNames + i), sectionHeader));
  81.  
  82.                 exportTable[i]->offset = RVA2FileOffset(exportDirectory->AddressOfFunctions + i * 4, sectionHeader);
  83.                 exportTable[i]->functionPtr = (AddressOfFunctions + i);
  84.  
  85.                 WORD _ordinal = *(AddressOfOrdinals + i) + exportDirectory->Base;
  86.                 exportTable[_ordinal - 1]->ordinal = _ordinal;
  87.                 exportTable[_ordinal - 1]->functionNameAddr = (AddressOfNames + i);
  88.                 exportTable[_ordinal - 1]->functionName = functionName;
  89.         }
  90.  
  91.         for (i = 0; i < exportDirectory->NumberOfFunctions - 1; i++) {
  92.                 int addrDiff;
  93.                 addrDiff = *(exportTable[i + 1]->functionNameAddr) - *(exportTable[i]->functionNameAddr);
  94.                 if (addrDiff != strlen(exportTable[i]->functionName) + 1) {
  95.                         exportTable[i]->forwarderName = exportTable[i]->functionName + strlen(exportTable[i]->functionName) + 1;
  96.                 } else {
  97.                         exportTable[i]->forwarderName = "";
  98.                 }
  99.         }
  100.         if (*(exportTable[i]->functionNameAddr) + strlen(exportTable[i]->functionName) + 1 != exportDescriptor.VirtualAddress + exportDescriptor.Size) {
  101.                 exportTable[i]->forwarderName = exportTable[i]->functionName + strlen(exportTable[i]->functionName) + 1;
  102.         } else {
  103.                 exportTable[i]->forwarderName = "";
  104.         }
  105.  
  106.         printExportTable(exportTable, exportDirectory->NumberOfFunctions);
  107.  
  108.         return;
  109. }
  110.  
  111. BOOL readFile(char *fname, char **fbuf, size_t *len)
  112. {
  113.         FILE *fd = fopen(fname, "rb");
  114.         if (fd) {
  115.                 fseek(fd, 0, SEEK_END);
  116.                 *len = ftell(fd);
  117.                 fseek(fd, 0, SEEK_SET);
  118.                 *fbuf = malloc(*len + 1);
  119.                 fread(*fbuf, *len, 1, fd);
  120.                 return 1;
  121.         }
  122.         return 0;
  123. }
  124.  
  125. int main(int argc, char **argv)
  126. {
  127.         if (argc != 2) {
  128.                 printf("Usage: %s <PE file>\n", argv[0]);
  129.         }
  130.  
  131.         char *fbuf; size_t len;
  132.         if (readFile(argv[1], &fbuf, &len)) {
  133.                 findExportFunctions(fbuf);
  134.         } else {
  135.                 printf("Failed to read file: %s\n", argv[1]);
  136.         }
  137.  
  138.         return 0;
  139. }
Advertisement
Add Comment
Please, Sign In to add comment