Привет, сегодня напишем простой инжектор с выгрузкой, с использованием функций LoadLibraryA и FreeLibrary
- ожидаем завершения выполнения DllMain DLL_PROCESS_ATTACHАлгоритм инжекта:
- получаем хэндл процесса в который будем инжектить
- получаем путь до нашей dll
- выделяем память для нашего пути
- записываем его
- получаем адрес LoadLibraryA и вызываем его через CreateRemoteThread
- получаем хэндл процесса в который будем инжектить
- получаем путь до нашей dll
- выделяем память для нашего пути
- записываем его
- получаем адрес LoadLibraryA и вызываем его через CreateRemoteThread
получаем id процесса:
C++:
DWORD GetProcId(const char* procname)
{
PROCESSENTRY32 pe;
HANDLE hSnap;
pe.dwSize = sizeof(PROCESSENTRY32);
hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
if (Process32First(hSnap, &pe)) {
do {
if (strcmp(pe.szExeFile, procname) == 0)
break;
} while (Process32Next(hSnap, &pe));
}
return pe.th32ProcessID;
}
C++:
// получаем хэндл процесса
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, GetProcId("gta_sa.exe"));
// Указываем путь до нашей dll
const char* DllPath = "C:\\test.dll";
// получаем размер строки нашего пути
size_t SizePatch = strlen(DllPath) + 1;
// выделяем память в gta_sa с размером нашей строки
LPVOID pDllPath = VirtualAllocEx(hProcess, NULL, SizePatch, MEM_COMMIT, PAGE_READWRITE);
// записываем наш путь в выделенную память
WriteProcessMemory(hProcess, pDllPath, (LPVOID)DllPath, SizePatch, NULL);
HMODULE kernel = GetModuleHandleA("Kernel32.dll"); // Получаем адрес kernel32
DWORD Adr = (DWORD)GetProcAddress(kernel, "LoadLibraryA"); // получаем адрес функции LoadLibraryA
// Вызываем LoadLibraryA в gta_sa.exe с аргументом "C:\\test.dll" и возвращаем адрес нашего потока
HANDLE hThread = CreateRemoteThread(hProcess, 0, 0,(LPTHREAD_START_ROUTINE)Adr, pDllPath, 0, 0);
// Ожидаем завершение нашего потока(ждем завершения DllMain с аргументом DLL_PROCESS_ATTACH)
WaitForSingleObject(hThread, INFINITE);
// Закрываем дескриптор потока
CloseHandle(hThread);
// Освобождаем выделенную память
VirtualFreeEx(hProcess, pDllPath, SizePatch, MEM_RELEASE);
// Закрываем дескриптор процесса
CloseHandle(hProcess);
Алгоритм выгрузки:
- получаем хэндл процесса в который будем инжектить
- получаем адрес нашей загруженной библиотеки
- получаем адрес FreeLibrary и вызываем его через CreateRemoteThread
- ожидаем завершения выполнения DllMain DLL_PROCESS_DETACH
функция для получения адреса dll в другом процессе:
C++:
HMODULE GetModuleHandleExtern(const char *szModuleName, DWORD dwProcessId)
{
if (!szModuleName || !dwProcessId) { return NULL; }
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwProcessId);
if (hSnap == INVALID_HANDLE_VALUE) { return NULL; }
MODULEENTRY32 me;
me.dwSize = sizeof(MODULEENTRY32);
if (Module32First(hSnap, &me))
{
while (Module32Next(hSnap, &me))
{
if (!strcmp(me.szModule, szModuleName))
{
CloseHandle(hSnap);
return me.hModule;
}
}
}
CloseHandle(hSnap);
return NULL;
}
C++:
// получаем хэндл процесса
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, GetProcId("gta_sa.exe"));
// получаем адрес нашей загруженной библиотеки
HMODULE module = GetModuleHandleExtern("test.dll", GetProcId("gta_sa.exe"));
HMODULE kernel = GetModuleHandleA("Kernel32.dll"); // Получаем адрес kernel32
DWORD Adr = (DWORD)GetProcAddress(kernel, "FreeLibrary"); // получаем адрес функции FreeLibrary
// Вызываем FreeLibrary в gta_sa.exe с адресом нашей библиотеки и возвращаем адрес нашего потока
HANDLE hThread = CreateRemoteThread(hProcess, 0, 0, (LPTHREAD_START_ROUTINE)Adr, module, 0, 0);
// Ожидаем завершение нашего потока(ждем завершения DllMain с аргументом DLL_PROCESS_DETACH)
WaitForSingleObject(hThread, INFINITE);
// Закрываем дескриптор потока
CloseHandle(hThread);
// Закрываем дескриптор процесса
CloseHandle(hProcess);