I'm having problems enumerating function names in kernel32.dll
. I retrieved its IMAGE_EXPORT_DIRECTORY
structure and stored an array of pointers to char arrays of each function name: char** name_table = (char**)(image+pExp_dir->AddressOfNames); //pExp_dir is a pointer to the IMAGE_EXPORT_DIRECTORY structure
. I'm now trying to iterate through the function names and match them to a string containing the name of the function whom's RVA I need.
for(int i=0;i<pExp_dir->NumberOfNames;i++) //until i is 1 less than how many names there are to iterate through elements
{
printf("%s ", (char*)(image+(DWORD)(uintptr_t)name_table[i])); //print the name of each function iterated through, I went back and read through these names and didn't see GetProcAddress anywhere
if(proc_name == image+(DWORD)(uintptr_t)name_table[i]) //if(strcmp(proc_name, (const char*)image+(DWORD)(intptr_t)name_table[i]) == 0) //Is it the function we're looking for?
{
address = (DWORD)(uintptr_t)func_table[ord_table[i]];//If so convert the address of the function into a DWORD(hexadecimal)
system("pause");
system("CLS"); //Clear the screen
return address; //return the address of the function
}
But if it doesn't find the function then the program crashes. And after looking in the memory dump in the DBG debugger I can see that name_tables
contains all of the function names including the function I'm looking for but my program seems to skip several elements even though I'm iterating through its elements one at a time. User stijn suggested that I shouldn't use intptr_t
to cast char*
to DWORD
to use for pointer arithmetic. So my question is really about the correct way to iterate through name_table
because it seems as if this is a pointer arithmetic problem. Here's the function to get the file image and the function that actually gets the RVA:
void* GetFileImage(char path[]) //Get maps the image of the file into memory and returns the beginning virtual address of the file in memory
{
HANDLE hFile = CreateFile(path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL);//Get a handle to the dll with read rights
if(hFile == INVALID_HANDLE_VALUE){printf("Error getting file handle: %d", (int)GetLastError());return NULL;} //Check whether or not CreateFile succeeded
HANDLE file_map = CreateFileMapping(hFile, NULL, PAGE_READONLY|SEC_IMAGE, 0, 0, "KernelMap"); //Create file map
if(file_map == INVALID_HANDLE_VALUE){printf("Error mapping file: %d", (int)GetLastError());return NULL;} //Did it succeed
LPVOID file_image = MapViewOfFile(file_map, FILE_MAP_READ, 0, 0, 0); //Map it into the virtual address space of my program
if(file_image == 0){printf("Error getting mapped view: %d", (int)GetLastError());return NULL;} //Did it succeed
return file_image; //return the base address of the image
}
DWORD RVAddress(char* image, const char* proc_name) //Gets the relative virtual address of the function and returns a DWORD to be cast to void*.
{
DWORD address = 0xFFFFFFFF;
PIMAGE_DOS_HEADER pDos_hdr = (PIMAGE_DOS_HEADER)image; //Get dos header
PIMAGE_NT_HEADERS pNt_hdr = (PIMAGE_NT_HEADERS)(image+pDos_hdr->e_lfanew); //Get PE header by using the offset in dos header + the base address of the file image
IMAGE_OPTIONAL_HEADER opt_hdr = pNt_hdr->OptionalHeader; //Get the optional header
IMAGE_DATA_DIRECTORY exp_entry = opt_hdr.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];
PIMAGE_EXPORT_DIRECTORY pExp_dir = (PIMAGE_EXPORT_DIRECTORY)(image+exp_entry.VirtualAddress); //Get a pointer to the export directory
void** func_table = (void**)(image+pExp_dir->AddressOfFunctions); //Get an array of pointers to the functions
WORD* ord_table = (WORD*)(image+pExp_dir->AddressOfNameOrdinals); //Get an array of ordinals
char** name_table = (char**)(image+pExp_dir->AddressOfNames); //Get an array of function names
for(int i=0;i<pExp_dir->NumberOfNames;i++) //until i is 1 less than how many names there are to iterate through elements
{
printf("%s ", (char*)(image+(DWORD)(uintptr_t)name_table[i])); //print the name of each function iterated through, I went back and read through these names and didn't see GetProcAddress anywhere
if(proc_name == image+(DWORD)(uintptr_t)name_table[i]) //if(strcmp(proc_name, (const char*)image+(DWORD)(intptr_t)name_table[i]) == 0) //Is it the function we're looking for?
{
address = (DWORD)(uintptr_t)func_table[ord_table[i]];//If so convert the address of the function into a DWORD(hexadecimal)
system("pause");
system("CLS"); //Clear the screen
return address; //return the address of the function
}
}
return (DWORD)0; //Other wise return 0
}
Any help would be much appreciated!