百度已收录
//************************************
// 函数名: GetProcAddressA
// 返回值: 函数在模块中的地址
// 功能:  查找函数在模块中的地址
// 参数1: 模块地址
// 参数2: 函数名称
//************************************
PVOID GetProcAddressA(HANDLE Module, PCHAR ProcName)
{
    if (!Module)
    {
        return NULL;
    }
    PIMAGE_DOS_HEADER ImageDosHeader = (PIMAGE_DOS_HEADER)Module;
    if (ImageDosHeader->e_magic != IMAGE_DOS_SIGNATURE)
    {
        return NULL;
    }

    PIMAGE_NT_HEADERS32 ImageNtHeader32 = (PIMAGE_NT_HEADERS32)((DWORD_PTR)Module + ImageDosHeader->e_lfanew);
    PIMAGE_NT_HEADERS64 ImageNtHeader64 = (PIMAGE_NT_HEADERS64)((DWORD_PTR)Module + ImageDosHeader->e_lfanew);
    if (ImageNtHeader64->Signature != IMAGE_NT_SIGNATURE)
    {
        return NULL;
    }
    PIMAGE_DATA_DIRECTORY ImageDataDirectory = NULL;
    if (ImageNtHeader64->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC)
    {
        ImageDataDirectory = &ImageNtHeader64->OptionalHeader.
            DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];
    }
    else if (ImageNtHeader64->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC)
    {
        ImageDataDirectory = &ImageNtHeader32->OptionalHeader.
            DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];
    }
    else
    {
        return NULL;
    }

    PIMAGE_EXPORT_DIRECTORY ImageExportDirectory = (PIMAGE_EXPORT_DIRECTORY)((DWORD_PTR)Module + ImageDataDirectory->VirtualAddress);
    ULONG ImageExportDirectorySize = ImageDataDirectory->Size;
    if (ImageExportDirectory == NULL)
    {
        return NULL;
    }

    // 函数地址数组
    PULONG AddressOfFunctions = (PULONG)((DWORD_PTR)Module + ImageExportDirectory->AddressOfFunctions);
    // 名称方式导出函数名称数组
    PULONG AddressOfNames = (PULONG)((DWORD_PTR)Module + ImageExportDirectory->AddressOfNames);
    // 名称方式导出函数序号数组
    PUSHORT AddressOfNameOrdinals = (PUSHORT)((DWORD_PTR)Module + ImageExportDirectory->AddressOfNameOrdinals);

    PVOID ProcAddress = NULL;
    if ((DWORD_PTR)ProcName >> 16 == 0)
    {
        WORD Ordinal = LOWORD(ProcName);
        ULONG OrdinalBase = ImageExportDirectory->Base;
        if (Ordinal < OrdinalBase || Ordinal >= OrdinalBase + ImageExportDirectory->NumberOfFunctions)
        {
            return NULL;
        }
        ProcAddress = (PVOID)((DWORD_PTR)Module + AddressOfFunctions[Ordinal - OrdinalBase]);
    }
    else
    {
        for (size_t i = 0; i < ImageExportDirectory->NumberOfNames; i++)
        {
            char* FunctionName = (char*)((DWORD_PTR)Module + AddressOfNames[i]);
            if (strcmp(ProcName, FunctionName) == 0)
            {
                ProcAddress = (PVOID)((DWORD_PTR)Module + AddressOfFunctions[AddressOfNameOrdinals[i]]);
                break;
            }
        }
    }

    // 转发函数
    if ((ULONG_PTR)ProcAddress >= (ULONG_PTR)ImageExportDirectory && (ULONG_PTR)ProcAddress <= (ULONG_PTR)ImageExportDirectory + ImageExportDirectorySize)
    {
        char LibraryName[MAX_PATH] = { 0 };
        char FunctionName[MAX_PATH] = { 0 };
        strcpy(LibraryName, ProcAddress);
        char* p = strchr(LibraryName, '.');
        if (!p)
        {
            return NULL;
        }
        *p = 0;
        strcpy(FunctionName, p + 1);
        strcat(LibraryName, ".dll");
        HMODULE Library = LoadLibraryA(LibraryName);
        if (Library == NULL)
        {
            return NULL;
        }
        return  GetProcAddressA(Library, FunctionName);
    }
    return ProcAddress;
}