C++ Получение модуля с помощью `ReadProcessMemory`

Начинающий
Статус
Оффлайн
Регистрация
8 Июн 2019
Сообщения
147
Реакции[?]
21
Поинты[?]
0
Это код получает модуль, загруженного в процесс, с помощью функции `ReadProcessMemory`.
Затем он получает таблицу экспорта
По идее он должен работать кто хочет дополняйте
C++:
#include <Windows.h>
#include <TlHelp32.h>
#include <Psapi.h>
#include <fstream>
#include <iostream>

int main()
{
    // Название процесса
    const char* processName = "RustClient.exe";
    // Название модуля
    const char* moduleName = "GameAssembly.dll";

    // Получаем идентификатор процесса по названию
    DWORD processId = 0;
    HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    PROCESSENTRY32 processEntry;
    processEntry.dwSize = sizeof(PROCESSENTRY32);

    if (Process32First(hSnapshot, &processEntry))
    {
        do
        {
            if (strcmp(processEntry.szExeFile, processName) == 0)
            {
                processId = processEntry.th32ProcessID;
                break;
            }
        } while (Process32Next(hSnapshot, &processEntry));
    }

    CloseHandle(hSnapshot);

    if (processId == 0)
    {
        std::cout << "Процесс не найден." << std::endl;
        return 1;
    }

    // Получаем дескриптор процесса
    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processId);

    if (hProcess == NULL)
    {
        std::cout << "Не удалось открыть процесс." << std::endl;
        return 1;
    }

    // Получаем адрес модуля
    HMODULE hModule;
    DWORD cbNeeded;
    if (!EnumProcessModules(hProcess, &hModule, sizeof(hModule), &cbNeeded))
    {
        std::cout << "Не удалось получить модуль." << std::endl;
        CloseHandle(hProcess);
        return 1;
    }

    // Получаем имя модуля
    char moduleNameBuffer[MAX_PATH];
    if (!GetModuleBaseNameA(hProcess, hModule, moduleNameBuffer, sizeof(moduleNameBuffer)))
    {
        std::cout << "Не удалось получить имя модуля." << std::endl;
        CloseHandle(hProcess);
        return 1;
    }

    if (strcmp(moduleNameBuffer, moduleName) != 0)
    {
        std::cout << "Модуль не найден." << std::endl;
        CloseHandle(hProcess);
        return 1;
    }

    // Получаем информацию о модуле
    MODULEINFO moduleInfo;
    if (!GetModuleInformation(hProcess, hModule, &moduleInfo, sizeof(moduleInfo)))
    {
        std::cout << "Не удалось получить информацию о модуле." << std::endl;
        CloseHandle(hProcess);
        return 1;
    }

    // Получаем адрес начала и конца модуля
    LPVOID moduleBaseAddress = moduleInfo.lpBaseOfDll;
    LPVOID moduleEndAddress = (LPBYTE)moduleBaseAddress + moduleInfo.SizeOfImage;

    // Получаем информацию о функциях и полях модуля
    IMAGE_DOS_HEADER dosHeader;
    IMAGE_NT_HEADERS ntHeader;
    IMAGE_SECTION_HEADER sectionHeader;
    // Получаем DOS-заголовок
    ReadProcessMemory(hProcess, moduleBaseAddress, &dosHeader, sizeof(dosHeader), NULL);

    // Получаем NT-заголовок
    ReadProcessMemory(hProcess, (LPVOID)((LPBYTE)moduleBaseAddress + dosHeader.e_lfanew), &ntHeader, sizeof(ntHeader), NULL);

    // Получаем секции
    IMAGE_SECTION_HEADER* sectionHeaders = new IMAGE_SECTION_HEADER[ntHeader.FileHeader.NumberOfSections];
    ReadProcessMemory(hProcess, (LPVOID)((LPBYTE)moduleBaseAddress + dosHeader.e_lfanew + sizeof(ntHeader)), sectionHeaders, sizeof(IMAGE_SECTION_HEADER) * ntHeader.FileHeader.NumberOfSections, NULL);

    // Получаем таблицу экспорта
    DWORD exportDirectoryRva = ntHeader.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
    DWORD exportDirectorySize = ntHeader.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size;

    if (exportDirectoryRva == 0 || exportDirectorySize == 0)
    {
        std::cout << "Таблица экспорта не найдена." << std::endl;
        CloseHandle(hProcess);
        delete[] sectionHeaders;
        return 1;
    }

    IMAGE_EXPORT_DIRECTORY exportDirectory;
    ReadProcessMemory(hProcess, (LPVOID)((LPBYTE)moduleBaseAddress + exportDirectoryRva), &exportDirectory, sizeof(exportDirectory), NULL);

    // Получаем адреса имен функций
    DWORD* functionNameAddresses = new DWORD[exportDirectory.NumberOfFunctions];
    ReadProcessMemory(hProcess, (LPVOID)((LPBYTE)moduleBaseAddress + exportDirectory.AddressOfFunctions), functionNameAddresses, sizeof(DWORD) * exportDirectory.NumberOfFunctions, NULL);

    // Получаем адреса имен функций
    DWORD* functionAddresses = new DWORD[exportDirectory.NumberOfFunctions];
    ReadProcessMemory(hProcess, (LPVOID)((LPBYTE)moduleBaseAddress + exportDirectory.AddressOfFunctions), functionAddresses, sizeof(DWORD) * exportDirectory.NumberOfFunctions, NULL);

    // Получаем адреса имен функций
    WORD* functionOrdinals = new WORD[exportDirectory.NumberOfFunctions];
    ReadProcessMemory(hProcess, (LPVOID)((LPBYTE)moduleBaseAddress + exportDirectory.AddressOfNameOrdinals), functionOrdinals, sizeof(WORD) * exportDirectory.NumberOfFunctions, NULL);

    // Получаем адреса имен функций
    DWORD* functionNameOffsets = new DWORD[exportDirectory.NumberOfFunctions];
    ReadProcessMemory(hProcess, (LPVOID)((LPBYTE)moduleBaseAddress + exportDirectory.AddressOfNames), functionNameOffsets, sizeof(DWORD) * exportDirectory.NumberOfFunctions, NULL);

    // Открываем файл для записи информации
    std::ofstream outputFile("output.txt");

    if (!outputFile.is_open())
    {
        std::cout << "Не удалось открыть файл для записи." << std::endl;
        CloseHandle(hProcess);
        delete[] sectionHeaders;
        delete[] functionNameAddresses;
        delete[] functionAddresses;
        delete[] functionOrdinals;
        delete[] functionNameOffsets;
        return 1;
    }

    // Записываем информацию о функциях в файл
    for (DWORD i = 0; i < exportDirectory.NumberOfFunctions; i++)
    {
        DWORD functionNameAddress = functionNameAddresses[i];
        DWORD functionAddress = functionAddresses[i];
        WORD functionOrdinal = functionOrdinals[i];
        DWORD functionNameOffset = functionNameOffsets[i];

        // Получаем имя функции
        char functionName[256];
        ReadProcessMemory(hProcess, (LPVOID)((LPBYTE)moduleBaseAddress + functionNameOffset), functionName, 256, NULL);

        // Записываем информацию о функции в файл
        outputFile << "Имя: " << functionName << std::endl;
        outputFile << "Адрес: " << std::hex << functionAddress << std::endl;
        outputFile << "Ординал: " << std::dec << functionOrdinal << std::endl << std::endl;
    }

    // Закрываем файл и освобождаем память
    outputFile.close();
    CloseHandle(hProcess);
    delete[] sectionHeaders;
    delete[] functionNameAddresses;
    delete[] functionAddresses;
    delete[] functionOrdinals;
    delete[] functionNameOffsets;

    return 0;
}
 
  • Мне нравится
Реакции: mj12
Начинающий
Статус
Оффлайн
Регистрация
27 Дек 2020
Сообщения
50
Реакции[?]
18
Поинты[?]
0
Грязненько, но практично, спасибо :)
 
Сверху Снизу