#include        "defs.h"

FARPROC getprocaddress(__in PVOID hModule, __in LPSTR szApiName){
        PIMAGE_DOS_HEADER       pmz;
        PPEHEADER32             pe32;
        PIMAGE_EXPORT_DIRECTORY c_export;
        DWORD                   *AddressOfNames;
        DWORD                   *AddressOfFunctions;
        PUSHORT                 AddressOfNameOrdinals;
        ULONG                   index;
        ULONG_PTR               dwExportStart, dwExportEnd;
        ULONG_PTR               api;
        CHAR                    szfDllName[MAX_PATH];
        CHAR                    szfApiName[MAX_PATH];
        char                    *search;
        
        pmz  = (PIMAGE_DOS_HEADER)hModule;
      
        pe32 = (PPEHEADER32)((ULONG_PTR)hModule + pmz->e_lfanew);       
        /************************************************************
         * Not handling forwarded ordinals, only forwarded APIs if
         * there is forwarded API...
         ************************************************************/       
        
        if (!pe32->pe_export)
                return NULL;
        
        c_export = (PIMAGE_EXPORT_DIRECTORY)((ULONG_PTR)hModule + pe32->pe_export);
        
        dwExportStart = (ULONG_PTR)hModule + pe32->pe_export;
        dwExportEnd   = dwExportStart + pe32->pe_exportsize;
        
        AddressOfFunctions    = (DWORD *)((ULONG_PTR)hModule + c_export->AddressOfFunctions);
        AddressOfNames        = (DWORD *)((ULONG_PTR)hModule + c_export->AddressOfNames);
        AddressOfNameOrdinals = (PUSHORT)((ULONG_PTR)hModule + c_export->AddressOfNameOrdinals);
        
        if ((ULONG_PTR)szApiName < 0xFFFF)
                return (FARPROC)(AddressOfFunctions[(ULONG_PTR)szApiName - c_export->Base] + (ULONG_PTR)hModule);
        
        
        for (index = 0; index < c_export->NumberOfNames; index++){
                if (!strcmp((LPSTR)((ULONG_PTR)hModule + AddressOfNames[index]), szApiName)){
                        api = (ULONG_PTR)hModule + AddressOfFunctions[AddressOfNameOrdinals[index]];
                                return (FARPROC)api;            
                }
        }
                 
        return NULL;
        
}