获取目标进程导入DLL模块地址的方法

以下是一些常用的方法,可以用于获取目标进程导入DLL模块的地址。根据具体情况选择合适的方法,并注意安全性和稳定性:

1、使用 LoadLibrary 函数和 GetModuleHandle 函数:
#include 

// 获取目标进程中某个 DLL 模块的地址
HMODULE GetRemoteModuleAddress(DWORD pid, LPCSTR moduleName) {
    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
    if (hProcess == NULL) {
        // 处理错误
        return NULL;
    }

    HMODULE hModule = NULL;
    HMODULE hKernel32 = GetModuleHandleA("kernel32.dll");
    FARPROC loadLibraryAddr = GetProcAddress(hKernel32, "LoadLibraryA");

    if (loadLibraryAddr != NULL) {
        // 在目标进程中调用 LoadLibrary 加载指定的 DLL 模块
        LPVOID remoteString = VirtualAllocEx(hProcess, NULL, strlen(moduleName), MEM_COMMIT, PAGE_READWRITE);
        WriteProcessMemory(hProcess, remoteString, moduleName, strlen(moduleName), NULL);
        HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)loadLibraryAddr, remoteString, 0, NULL);
        WaitForSingleObject(hThread, INFINITE);
        VirtualFreeEx(hProcess, remoteString, 0, MEM_RELEASE);

        // 获取加载的模块句柄
        GetExitCodeThread(hThread, (LPDWORD)&hModule);
        CloseHandle(hThread);
    }

    CloseHandle(hProcess);
    return hModule;
}
2、使用 CreateRemoteThread 函数和 LoadLibrary 函数:
#include 

// 获取目标进程中某个 DLL 模块的地址
HMODULE GetRemoteModuleAddress(DWORD pid, LPCSTR moduleName) {
    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
    if (hProcess == NULL) {
        // 处理错误
        return NULL;
    }

    HMODULE hModule = NULL;

    LPVOID remoteString = VirtualAllocEx(hProcess, NULL, strlen(moduleName), MEM_COMMIT, PAGE_READWRITE);
    WriteProcessMemory(hProcess, remoteString, moduleName, strlen(moduleName), NULL);

    // 在目标进程中创建远程线程,调用 LoadLibrary 加载指定的 DLL 模块
    HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)LoadLibraryA, remoteString, 0, NULL);
    WaitForSingleObject(hThread, INFINITE);

    // 获取加载的模块句柄
    GetExitCodeThread(hThread, (LPDWORD)&hModule);

    VirtualFreeEx(hProcess, remoteString, 0, MEM_RELEASE);
    CloseHandle(hThread);
    CloseHandle(hProcess);

    return hModule;
}
3、使用 EnumProcessModules 函数和 GetModuleBaseName 函数:
#include 
#include 

// 获取目标进程中某个 DLL 模块的地址
HMODULE GetRemoteModuleAddress(DWORD pid, LPCSTR moduleName) {
    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
    if (hProcess == NULL) {
        // 处理错误
        return NULL;
    }

    HMODULE hModule = NULL;
    HMODULE hModules[1024];
    DWORD cbNeeded;

    if (EnumProcessModules(hProcess, hModules, sizeof(hModules), &cbNeeded)) {
        int moduleCount = cbNeeded / sizeof(HMODULE);
        char szModuleName[MAX_PATH];

        for (int i = 0; i < moduleCount; i++) {
            if (GetModuleBaseNameA(hProcess, hModules[i], szModuleName, sizeof(szModuleName)) > 0) {
                if (_stricmp(szModuleName, moduleName) == 0) {
                    hModule = hModules[i];
                    break;
                }
            }
        }
    }

    CloseHandle(hProcess);
    return hModule;
}
4、使用 CreateToolhelp32Snapshot 函数和 Module32First 函数:
#include 
#include 

// 获取目标进程中某个 DLL 模块的地址
HMODULE GetRemoteModuleAddress(DWORD pid, LPCSTR moduleName) {
    HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pid);
    if (hSnapshot == INVALID_HANDLE_VALUE) {
        // 处理错误
        return NULL;
    }

    HMODULE hModule = NULL;
    MODULEENTRY32 me32;
    me32.dwSize = sizeof(MODULEENTRY32);

    if (Module32First(hSnapshot, &me32)) {
        do {
            if (_stricmp(me32.szModule, moduleName) == 0) {
                hModule = me32.hModule;
                break;
            }
        } while (Module32Next(hSnapshot, &me32));
    }

    CloseHandle(hSnapshot);
    return hModule;
}
5、使用 NtQuerySystemInformation 函数和 EnumProcessModulesEx 函数:
#include 
#include 
#include 

typedef NTSTATUS(WINAPI* PNT_QUERY_SYSTEM_INFORMATION)(
    ULONG SystemInformationClass,
    PVOID SystemInformation,
    ULONG SystemInformationLength,
    PULONG ReturnLength);

#pragma pack(push, 1)
typedef struct _SYSTEM_MODULE_INFORMATION_ENTRY {
    HANDLE Section;
    PVOID MappedBase;
    PVOID Base;
    ULONG Size;
    ULONG Flags;
    USHORT LoadOrderIndex;
    USHORT InitOrderIndex;
    USHORT LoadCount;
    USHORT PathLength;
    CHAR ImageName[256];
} SYSTEM_MODULE_INFORMATION_ENTRY, * PSYSTEM_MODULE_INFORMATION_ENTRY;

typedef struct _SYSTEM_MODULE_INFORMATION {
    ULONG NumberOfModules;
    SYSTEM_MODULE_INFORMATION_ENTRY Module[1];
} SYSTEM_MODULE_INFORMATION, * PSYSTEM_MODULE_INFORMATION;
#pragma pack(pop)

// 获取目标进程中某个 DLL 模块的地址
HMODULE GetRemoteModuleAddress(DWORD pid, LPCSTR moduleName) {
    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
    if (hProcess == NULL) {
        // 处理错误
        return NULL;
    }

    HMODULE hModule = NULL;
    HMODULE hModules[1024];
    DWORD cbNeeded;

    // 调用 NtQuerySystemInformation 函数查询系统模块信息
    HMODULE hNtDll = GetModuleHandleA("ntdll.dll");
    PNT_QUERY_SYSTEM_INFORMATION pNtQuerySystemInformation = (PNT_QUERY_SYSTEM_INFORMATION)GetProcAddress(hNtDll, "NtQuerySystemInformation");
    ULONG ulSize = 0;
    pNtQuerySystemInformation(11, NULL, 0, &ulSize);
    PSYSTEM_MODULE_INFORMATION pModuleInfo = (PSYSTEM_MODULE_INFORMATION)VirtualAlloc(NULL, ulSize, MEM_COMMIT, PAGE_READWRITE);
    pNtQuerySystemInformation(11, pModuleInfo, ulSize, &ulSize);

    // 枚举目标进程中的模块,查找指定的 DLL 模块
    HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pid);
    if (hSnapshot == INVALID_HANDLE_VALUE) {
        VirtualFree(pModuleInfo, 0, MEM_RELEASE);
        CloseHandle(hProcess);
        return NULL;
    }

    MODULEENTRY32 me32;
    me32.dwSize = sizeof(MODULEENTRY32);

    if (Module32First(hSnapshot, &me32)) {
        do {
            for (int i = 0; i < pModuleInfo->NumberOfModules; i++) {
                if (_stricmp(me32.szModule, moduleName) == 0 &&
                    (DWORD_PTR)me32.hModule == (DWORD_PTR)pModuleInfo->Module[i].MappedBase) {
                    hModule = me32.hModule;
                    break;
                }
            }
        } while (Module32Next(hSnapshot, &me32) && hModule == NULL);
    }

    VirtualFree(pModuleInfo, 0, MEM_RELEASE);
    CloseHandle(hSnapshot);
    CloseHandle(hProcess);
    return hModule;
}
6、使用 GetProcAddress 函数和 VirtualQueryEx 函数:
#include 

// 获取目标进程中某个 DLL 模块的地址
HMODULE GetRemoteModuleAddress(DWORD pid, LPCSTR moduleName) {
    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
    if (hProcess == NULL) {
        // 处理错误
        return NULL;
    }

    HMODULE hModule = NULL;
    HMODULE hKernel32 = GetModuleHandleA("kernel32.dll");
    FARPROC getProcAddressAddr = GetProcAddress(hKernel32, "GetProcAddress");

    // 在目标进程中调用 GetProcAddress 获取指定 DLL 模块的导出函数地址
    HMODULE hModuleKernel32 = GetModuleHandleA("kernel32.dll");
    LPVOID remoteString = VirtualAllocEx(hProcess, NULL, strlen(moduleName), MEM_COMMIT, PAGE_READWRITE);
    WriteProcessMemory(hProcess, remoteString, moduleName, strlen(moduleName), NULL);
    HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)getProcAddressAddr, (LPVOID)hModuleKernel32, 0, NULL);
    WaitForSingleObject(hThread, INFINITE);

    // 获取 GetProcAddress 函数返回的地址
    LPVOID lpRemoteProcAddress;
    GetExitCodeThread(hThread, (LPDWORD)&lpRemoteProcAddress);

    // 使用 VirtualQueryEx 函数获取返回地址所在的模块地址
    MEMORY_BASIC_INFORMATION mbi;
    VirtualQueryEx(hProcess, lpRemoteProcAddress, &mbi, sizeof(mbi));
    hModule = (HMODULE)mbi.AllocationBase;

    VirtualFreeEx(hProcess, remoteString, 0, MEM_RELEASE);
    CloseHandle(hThread);
    CloseHandle(hProcess);
    return hModule;
}
7、使用 CreateToolhelp32Snapshot 函数和 Module32First 函数:
#include 
#include 

// 获取目标进程中某个 DLL 模块的地址
HMODULE GetRemoteModuleAddress(DWORD pid, LPCSTR moduleName) {
    HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pid);
    if (hSnapshot == INVALID_HANDLE_VALUE) {
        // 处理错误
        return NULL;
    }

    HMODULE hModule = NULL;

    MODULEENTRY32 me32;
    me32.dwSize = sizeof(MODULEENTRY32);

    if (Module32First(hSnapshot, &me32)) {
        do {
            if (_stricmp(me32.szModule, moduleName) == 0) {
                hModule = me32.hModule;
                break;
            }
        } while (Module32Next(hSnapshot, &me32) && hModule == NULL);
    }

    CloseHandle(hSnapshot);
    return hModule;
}
8、使用 EnumProcessModules 函数和 GetModuleBaseName 函数:
#include 
#include 

// 获取目标进程中某个 DLL 模块的地址
HMODULE GetRemoteModuleAddress(DWORD pid, LPCSTR moduleName) {
    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
    if (hProcess == NULL) {
        // 处理错误
        return NULL;
    }

    HMODULE hModule = NULL;
    HMODULE hModules[1024];
    DWORD cbNeeded;

    if (!EnumProcessModules(hProcess, hModules, sizeof(hModules), &cbNeeded)) {
        // 处理错误
        CloseHandle(hProcess);
        return NULL;
    }

    for (int i = 0; i < (cbNeeded / sizeof(HMODULE)); i++) {
        CHAR szModuleName[MAX_PATH];
        if (GetModuleBaseNameA(hProcess, hModules[i], szModuleName, sizeof(szModuleName))) {
            if (_stricmp(szModuleName, moduleName) == 0) {
                hModule = hModules[i];
                break;
            }
        }
    }

    CloseHandle(hProcess);
    return hModule;
}
9、使用 EnumProcessModules 函数和 GetModuleFileNameEx 函数:
#include 
#include 

// 获取目标进程中某个 DLL 模块的地址
HMODULE GetRemoteModuleAddress(DWORD pid, LPCSTR moduleName) {
    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
    if (hProcess == NULL) {
        // 处理错误
        return NULL;
    }

    HMODULE hModule = NULL;
    HMODULE hModules[1024];
    DWORD cbNeeded;

    if (!EnumProcessModules(hProcess, hModules, sizeof(hModules), &cbNeeded)) {
        // 处理错误
        CloseHandle(hProcess);
        return NULL;
    }

    for (int i = 0; i < (cbNeeded / sizeof(HMODULE)); i++) {
        CHAR szModuleName[MAX_PATH];
        if (GetModuleFileNameExA(hProcess, hModules[i], szModuleName, sizeof(szModuleName))) {
            if (_stricmp(PathFindFileNameA(szModuleName), moduleName) == 0) {
                hModule = hModules[i];
                break;
            }
        }
    }

    CloseHandle(hProcess);
    return hModule;
}
10、使用远程线程注入技术,将一个自定义DLL注入到目标进程中,然后在自定义DLL中获取模块地址。这种方法需要对Windows进程注入技术有一定的了解,需要谨慎使用,并且要遵守相关法律法规。

你可能感兴趣的:(windows,dll,注入,library,load,process,cpp)