I'm trying to parse the PE files using C. The imports parsing is good but i have problem with the exports parsing. This is the code that I have wrote in order to parse the exports:
void PrintExports(DWORD imageBase) {
// Get the export section.
PIMAGE_DOS_HEADER ptrDosHeader = (PIMAGE_DOS_HEADER)imageBase;
PIMAGE_NT_HEADERS32 ptrNtHeaders = (PIMAGE_NT_HEADERS32)(ptrDosHeader->e_lfanew + imageBase);
DWORD exportsStartRVA = ptrNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
DWORD exportsEndRVA = exportsStartRVA + ptrNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size;
PIMAGE_SECTION_HEADER ptrExportsHeader = GetSectionHeaderByRVA(exportsStartRVA, ptrNtHeaders);
// Check it's not null..
if (!ptrExportsHeader)
return;
PIMAGE_EXPORT_DIRECTORY ptrExportsDirectory = (PIMAGE_EXPORT_DIRECTORY)(imageBase + exportsStartRVA );
printf("Exports\n");
printf(" Exports.section: %s\n", ptrExportsHeader->Name);
printf(" Exports.ordinalBase: %x\n", ptrExportsDirectory->Base);
printf(" Exports.NumberOfFunctions: %x (hex)\n", ptrExportsDirectory->NumberOfFunctions);
printf(" Exports.NumberOfNames: %x (hex)\n", ptrExportsDirectory->NumberOfNames);
PDWORD ptrExportsFunctions = (PDWORD)((DWORD)ptrExportsDirectory->AddressOfFunctions + imageBase);
PDWORD ptrExportsNamesOrdinals = (PDWORD)((DWORD)ptrExportsDirectory->AddressOfNameOrdinals + imageBase);
PDWORD * ptrExportsNames = (PDWORD *)((DWORD)ptrExportsDirectory->AddressOfNames + imageBase);
printf(" Exports.functions:\n");
printf(" EntryPoint Ordinal Name\n");
for (int i = 0; i < ptrExportsDirectory->NumberOfFunctions; i++) {
if (ptrExportsFunctions[i] == 0)
continue;
printf(" %010x %07x", ptrExportsFunctions[i], i + ptrExportsDirectory->Base);
if ((ptrExportsFunctions[i] >= exportsStartRVA) && (ptrExportsFunctions[i] <= exportsEndRVA))
printf(" (forwarder -> %s)", ptrExportsFunctions[i] + imageBase);
printf("\n");
}
return;
}
As a result of running this code, I get the ordinals and the addresses of the exports. The problem starts when I'm trying to get the names with the code below (this code should be inside the "for" loop). What happens is that I get access violation exception (the PE I'm trying to parse in this example is shell32.dll):
for (int j = 0; j < ptrExportsDirectory->NumberOfNames; j++) {
if (ptrExportsNamesOrdinals[j] == i + ptrExportsDirectory->Base) {
printf(" %s", ptrExportsNames[j]);
}
}
Moreover, in some cases (for example if the PE I'm trying to parse is user32.dll) the ptrExportsNamesOrdinal[j] has value that can never be equal to i + ptrExportsDirectory->Base. You can see the screenshot below:
What I did to fix it:
PDWORD ptrExportsFunctions = (PDWORD)(imageBase + ptrExportsDirectory->AddressOfFunctions);
PDWORD ptrExportsNames = (PDWORD)(imageBase + ptrExportsDirectory->AddressOfNames);
PWORD ptrExportsNamesOrdinals = (PWORD)(imageBase + ptrExportsDirectory->AddressOfNameOrdinals);
And than in the loop:
for (DWORD j = 0; j < ptrExportsDirectory->NumberOfNames; j++)
{
if(ptrExportsNamesOrdinals[j] == i){
printf("%s", (char*)imageBase + ptrExportsNames[j]);
}
}
Now Everything works well.