首页
社区
课程
招聘
[求助]如何遍历系统的函数库以及函数库的APi地址
2023-4-19 13:55 8517

[求助]如何遍历系统的函数库以及函数库的APi地址

2023-4-19 13:55
8517
收藏
点赞0
打赏
分享
最新回复 (4)
雪    币: 2927
活跃值: (2530)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
caocaofff 2023-4-19 15:30
2
1

要遍历系统的函数库以及函数库中的API地址,可以通过使用Windows API中的EnumProcessModulesEx、GetModuleInformation和EnumDependentModules函数实现。

以下是演示如何遍历系统函数库并获取函数API地址的示例C++代码:


#include <windows.h>
#include <psapi.h>
#include <tchar.h>
#include <iostream>
#include <string>
#include <vector>
#pragma comment (lib, "psapi.lib")

using namespace std;

void EnumerateProcessModules(DWORD dwPID) {
    HANDLE hProcess;
    HMODULE hMods[1024];
    DWORD cbNeeded;

    // 先打开进程
    hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, dwPID);
    if (NULL == hProcess) {
        cout << "Failed to open process" << endl;
        return;
    }

    // 确定进程中所有模块的编号。
    if (EnumProcessModulesEx(hProcess, hMods, sizeof(hMods), &cbNeeded, LIST_MODULES_ALL)) {
        // 模块句柄
        HMODULE hModule;

        // 模块信息结构体
        MODULEINFO mi;

        DWORD nModules = cbNeeded / sizeof(HMODULE);
        for (size_t i = 0; i < nModules; i++) {
            // 获取模块句柄
            hModule = hMods[i];

            // 获取模块信息
            if (GetModuleInformation(hProcess, hModule, &mi, sizeof(mi))) {
                TCHAR szModName[MAX_PATH] = { 0 };

                // 获取模块名称
                if (GetModuleFileNameEx(hProcess, hModule, szModName, MAX_PATH)) {
                    wstring strModName(szModName);

                    // 显示模块名称和基地址
                    wcout << L"模块名称: " << strModName << L",模块基地址: " << mi.lpBaseOfDll << endl;

                    // 得到模块的export table,遍历其中的函数结构体
                    DWORD dwExportsSize;
                    PIMAGE_EXPORT_DIRECTORY pExports = (PIMAGE_EXPORT_DIRECTORY)ImageDirectoryEntryToData(hModule, TRUE, IMAGE_DIRECTORY_ENTRY_EXPORT, &dwExportsSize);
                    if (pExports) {
                        PDWORD pAddressOfFunctions = (PDWORD)((DWORD_PTR)hModule + pExports->AddressOfFunctions);
                        PDWORD pAddressOfNames = (PDWORD)((DWORD_PTR)hModule + pExports->AddressOfNames);
                        PWORD pAddressOfNameOrdinals = (PWORD)((DWORD_PTR)hModule + pExports->AddressOfNameOrdinals);

                        for (size_t j = 0; j < pExports->NumberOfNames; j++) {
                            DWORD_PTR funcRva = pAddressOfFunctions[pAddressOfNameOrdinals[j]];
                            TCHAR* funcName = (TCHAR*)((DWORD_PTR)hModule + pAddressOfNames[j]);
                            DWORD_PTR funcAddress = (DWORD_PTR)hModule + funcRva;
                            wcout << L"  函数名称: " << funcName << L", 函数地址: " << funcAddress << endl;
                        }    
                    }
                }
            }
        }

    }

    CloseHandle(hProcess);
    return;
}

int main() {
    // 获取进程ID
    DWORD aProcesses[1024], cbNeeded, cProcesses;
    if (!EnumProcesses(aProcesses, sizeof(aProcesses), &cbNeeded)) return 0;

    // 计算进程数量
    cProcesses = cbNeeded / sizeof(DWORD);
    for (size_t i = 0; i < cProcesses; i++) {
        // 进程ID
        DWORD dwPID = aProcesses[i];
        if (dwPID != 0) {
            // 列出进程模块
            EnumerateProcessModules(dwPID);
        }
    }

    return 0;
}


 在此示例中,我们使用了Windows API中的三个函数,首先使用EnumProcessModulesEx枚举指定进程的所有模块,并使用GetModuleInformation获取每个模块的信息。然后,我们使用GetModuleFileNameEx从模块的路径名获取模块的名称和基本地址。接下来,我们使用ImageDirectoryEntryToData和IMAGE_EXPORT_DIRECTORY结构体来获取模块中的导出表,并从导出表中获取模块的函数名称和地址。 请注意,在此示例中,我们只枚举了所有进程及其模块中的函数,如果要查找特定函数,请添加相应的过滤器以过滤模块和函数名称。 如有需要,您可以将此示例代码进行修改,以适应您的具体需求。

雪    币: 264
活跃值: (654)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
lainswork 2023-4-21 09:05
3
1
从PEB拿LDR,之后遍历LDR,遍历每个模块的导出表,中间要注意过滤转发函数。https://poe.com/s/dyZW14oe9UH4AZEjkqTg
雪    币: 21
活跃值: (75)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
zngsai 2023-6-16 15:50
4
0
Failed to open process
Failed to open process
Failed to open process
Failed to open process
Failed to open process
Failed to open process
Failed to open process
Failed to open process
Failed to open process
Failed to open process
Failed to open process
Failed to open process
Failed to open process
Failed to open process
Failed to open process
Failed to open process
Failed to open process
Failed to open process
Failed to open process
Failed to open process
Failed to open process
Failed to open process
Failed to open process
Failed to open process
Failed to open process
雪    币: 667
活跃值: (317)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
www明天 2023-9-4 20:50
5
0
谢谢大佬的指点
游客
登录 | 注册 方可回帖
返回