Figure 1: Extracts from pehelper.cpp
Excerpts from PeHelper.cpp /*----------------------------------------------------------------- FUNCTION: bGetModuleFileName PURPOSE: Get module name by the base address and PE headed PARAMETERS: . void * p_pBaseAddress - base address PIMAGE_NT_HEADERS p_pNTHeader - PE header char * p_pszReturnName - return module name int p_iSizeName - size of the buffer RETURN VALUE: bool true on success, false on failure -----------------------------------------------------------------*/ bool bGetModuleFileName ( void * p_pBaseAddress, PVOID p_pNTHeader, char * p_pszReturnName, int p_iSizeName ) { *p_pszReturnName = 0; if (!MmIsAddressValid(p_pNTHeader)) return false; ULONG l_dwExpTableRVAOffset = ((PIMAGE_NT_HEADERS)p_pNTHeader)->OptionalHeader. DataDirectory[0].VirtualAddress; if(!l_dwExpTableRVAOffset) return false; PIMAGE_EXPORT_DIRECTORY l_pExportDir = (PIMAGE_EXPORT_DIRECTORY) (((char*)p_pBaseAddress) + l_dwExpTableRVAOffset); if (!MmIsAddressValid(l_pExportDir)) return false; ULONG l_dwNameRVA = l_pExportDir->Name; if(!l_dwNameRVA) return false; char * p_pszName = ((char*)p_pBaseAddress) + l_dwNameRVA; if (!MmIsAddressValid(p_pszName)) return false; strncpy(p_pszReturnName, p_pszName, p_iSizeName); return true; }//bool bGetModuleFileName /*----------------------------------------------------------------- FUNCTION: pdwGetSlotInExportTable PURPOSE: Look for the exported function and return the address of the slot in the module export table correspondent to this function. The value in this slot is the address of this function. PARAMETERS: . void * p_pBaseAddress - module base address const char * p_pszFunctionName - name of the function void * p_pNTHeader - location of NT header for this module. It can be obtained from p_pBaseAddress, but should be provided by the called for efficiency. RETURN VALUE: ULONG * - pointer to the slot or NULL -----------------------------------------------------------------*/ ULONG * pdwGetSlotInExportTable ( void * p_pBaseAddress, const char * p_pszFunctionName, void * p_pNTHeader ) { PIMAGE_SECTION_HEADER l_ExpSectHeader = pGetSectionHeader(".edata", (PIMAGE_NT_HEADERS)p_pNTHeader); if ( !l_ExpSectHeader ) return NULL; PIMAGE_EXPORT_DIRECTORY l_pExpDir = (PIMAGE_EXPORT_DIRECTORY) (ULONG(p_pBaseAddress) +l_ExpSectHeader->PointerToRawData); PULONG l_pdwFunctions = (PULONG)((ULONG) l_pExpDir->AddressOfFunctions + ULONG(p_pBaseAddress)); PCSTR *l_ppszName = (PCSTR*)((ULONG) l_pExpDir->AddressOfNames + ULONG(p_pBaseAddress)); WORD * l_pwOrdinals = (WORD*)((ULONG) l_pExpDir->AddressOfNameOrdinals + ULONG(p_pBaseAddress)); int l_iNumNames = l_pExpDir->NumberOfNames; for (int i=0; i < l_iNumNames; i++ ) { if(!_stricmp(p_pszFunctionName, (*l_ppszName + ULONG(p_pBaseAddress)))) { WORD l_wOrdinal = *l_pwOrdinals; return l_pdwFunctions + l_wOrdinal; }//if(!stricmp(p_pszFunctionName, *l_ppszName)) l_ppszName++; l_pwOrdinals++; }//for (int i=0; i < l_iNumNames; i++ ) return NULL; }//ULONG * pdwGetSlotInExportTable /*----------------------------------------------------------------- FUNCTION: pGetProcAddress PURPOSE: The same functionality as Win32 GetProcAddress, but works for NT kernel mode PARAMETERS: . void * p_pBaseAddress - module base address const char * p_pszFunctionName - name of the function void * p_pNTHeader - location of NT header for this module. If it is NULL, the location will be obtained from p_pBaseAddress, but the caller may pass earlier obtained value for efficiency. RETURN VALUE: void * - pointer to the exported function -----------------------------------------------------------------*/ void * pGetProcAddress ( void * p_pBaseAddress, const char * p_pszFunctionName, void * p_pNTHeader ) { if(!p_pNTHeader) { p_pNTHeader = pCheckModuleHeader(p_pBaseAddress); if(!p_pNTHeader) return NULL; } ULONG * l_pdwSlot = pdwGetSlotInExportTable(p_pBaseAddress, p_pszFunctionName, p_pNTHeader); if(!l_pdwSlot) return NULL; return (void*)(*l_pdwSlot + ULONG(p_pBaseAddress)); }//void * pGetProcAddress