-
Автор темы
- #1
Это код получает модуль, загруженного в процесс, с помощью функции `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;
}