Hello.
I try to parse PE export table, but it crashes every time. Where I can get good sample in C to parse Pe file? EXEDUMP from Matt Pietrek also fails..
Crashes in AddressOfNames Array.
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <windows.h>
#define MakePtr(Type, Base, Offset) ((Type)(DWORD(Base) + (DWORD)(Offset)))
#define offsetof(st, m) ((size_t)&(((st *)0)->m))
void Err(char *err)
{
printf("%s\n",err);
}
void inf(char *inf)
{
printf("%s\n",inf);
}
LPBYTE OpenPEFileA(LPCSTR lpszFileName)
{
HANDLE hMapping,hFile;
LPBYTE pBase = NULL;
hFile = CreateFileA(lpszFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if (hFile == INVALID_HANDLE_VALUE)
{
Err("Cannot open file (CreateFile)");
return NULL;
}
hMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
CloseHandle(hFile);
if (hMapping != NULL)
{
pBase = (LPBYTE)MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0);
CloseHandle(hMapping);
}
return pBase;
}
void ClosePEFile(LPBYTE pBase)
{
if (pBase != NULL)
UnmapViewOfFile(pBase);
}
char * mem_alloc()
{
char *lpMem = NULL;
lpMem = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,256);
if (lpMem == NULL)
Err("HeapAlloc err");
return lpMem;
}
DWORD Rva2Raw(LPVOID pe, DWORD_PTR dwRVA)
{
DWORD dwRawRvaAddr = 0;
PIMAGE_DOS_HEADER dos;
PIMAGE_NT_HEADERS nt;
dos = (PIMAGE_DOS_HEADER)pe;
nt = (PIMAGE_NT_HEADERS)(((DWORD_PTR)pe) + dos->e_lfanew);
PIMAGE_SECTION_HEADER pSections = IMAGE_FIRST_SECTION(nt);
if (!pSections)
{
return dwRawRvaAddr;
}
while (pSections->VirtualAddress != 0)
{
if (dwRVA >= pSections->VirtualAddress && dwRVA < pSections->VirtualAddress + pSections->SizeOfRawData)
{
dwRawRvaAddr = (dwRVA - pSections->VirtualAddress) + pSections->PointerToRawData;
break;
}
pSections++;
}
return dwRawRvaAddr;
}
int main(int argc,char *argv[])
{
LPBYTE PE = NULL;
IMAGE_DOS_HEADER* pDosHeader;
IMAGE_NT_HEADERS* pNtHeader;
int tmp = 0;
char file_name[64] = {0};
char *pe_magic,*pe_cblp,*pe_lfanew;
char *pSignature,*pMachine,*pMagic,*pTimeDateStamp;
goto X;
if (argc < 2)
{
printf("Error usage: %s xyz.pe\n",argv[0]);
return 1;
}
X:
//PE = OpenPEFileA(argv[1]);
PE = OpenPEFileA("1.dll");
pDosHeader = (IMAGE_DOS_HEADER*)PE;
if (pDosHeader->e_lfarlc >= 0x40)
{
inf("This is PE file");
}
pNtHeader = (IMAGE_NT_HEADERS*)(PE + pDosHeader->e_lfanew);
DWORD dwRva = Rva2Raw(PE,pNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
PIMAGE_EXPORT_DIRECTORY pIED = (PIMAGE_EXPORT_DIRECTORY)(PE + dwRva);
PDWORD functions,names;
PWORD ordinals;
unsigned char *name;
DWORD base = (DWORD)pDosHeader;
//DebugBreak();
PSTR filename = (PSTR)(pIED->Name + base);
printf("rva is %x FN is %d %d!!!\n",dwRva,pIED->NumberOfFunctions,base);
DWORD nSize = pIED->Name;
functions = (PDWORD)(PE + Rva2Raw(PE,pIED->AddressOfFunctions));
ordinals = (PWORD)(PE + Rva2Raw(PE,pIED->AddressOfNameOrdinals));
names = (PDWORD)(PE + Rva2Raw(PE,pIED->AddressOfNames));
name = (PCHAR)(PE + Rva2Raw(PE,pIED->AddressOfNames));
//HERE fails! in name array
for (int i=0; i < pIED->NumberOfNames; i++ )
{
printf(" %08X %4u %s \n", *functions, *ordinals + pIED->Base,*name);
names++; // Bump each pointer to the next array element
ordinals++;
functions++;
}
ClosePEFile(PE);
return 0;
}