Внедрение потока с codecave

Используя метод 'codecave' для внедрения кода в другой процесс; Можно ли внедрить код для создания нового потока (а также ввести код для нового потока) и позволить этому потоку выполняться параллельно с основным потоком целевого процесса?

Я могу справиться с этим с помощью dll-инъекции, но я хочу знать, возможно ли это только с помощью простого внедрения кода.

Цель состоит в том, чтобы прежде всего узнать о различных методах инъекций, но в конце концов создать функцию сердцебиения для случайных процессов, чтобы контролировать выполнение (высокая доступность). Windows - это целевая ОС, а язык - C/C++ (при необходимости используется встроенный ASM).

Благодарю.

5 ответов

При использовании загрузчика DLL-инъекций, такого как Winject (который вызывает CreateRemoteThread), очень легко создавать потоки, которые остаются до закрытия целевого процесса.

Просто создайте поток внутри функции:

void run_thread(void* ass)
{
  // do stuff until process terminates
}
BOOL APIENTRY DllMain(HMODULE hModule, DWORD result, LPVOID lpReserved)
{
  HANDLE handle = (HANDLE)_beginthread(run_thread, 0, 0);
}

С уважением, Майкл

Есть функция CreateRemoteThread.

Вы также можете использовать функцию RtlCreateUserThread для создания удаленного потока.

Конечно, но вы должны также ввести код для удаленного потока в процесс (например, функцию). Внедрение всей функции в удаленный процесс является трудной задачей, поскольку не существует четкого способа определения размера функции. Этот подход был бы гораздо более эффективным, если бы внедренный код был маленьким, и в этом случае вы просто вставили бы короткую заглушку сборки, а затем вызвали CreateRemoteThread.

Правда, какая польза от этого по сравнению с простой инъекцией DLL? Ваша функция "сердцебиение" может быть реализована так же легко с помощью внедренной DLL. (разве кто-нибудь скажет мне, что есть значительные накладные расходы?)

Проблема в том, что даже если вы внедрите свой код в процесс, если вы не создадите поток в начале введенного кода, он все равно не будет работать. Обычно для внедрения кода вы вводите полную DLL. Одним из популярных способов внедрения DLL является:

  • Получить дескриптор целевого процесса (EnumProcesses, CreateTool32Snapshot/Process32First/Process32Next, FindWindow/GetWindowThreadProcessId/OpenProcess и т. Д.)
  • Выделите память в целевом процессе такой же длины, что и строка, указывающая путь к вашей DLL (VirtualAllocEx)
  • Напишите строку, указывающую путь вашей DLL к этой выделенной памяти (WriteProcessMemory)
  • Создайте удаленный поток в подпрограмме LoadLibrary (получите адрес с помощью GetModuleHandle/GetProcAddress) и передайте указатель на выделенную память в качестве параметра (CreateRemoteThread)
  • Освободить выделенную память (VirtualFreeEx)
  • Закройте все открытые дескрипторы (дескрипторы процесса, дескрипторы снимков и т. Д. С помощью CloseHandle)

Если нет особой причины, по которой вы хотите избежать этого метода, гораздо предпочтительнее копировать в коде самостоятельно (WriteProcessMemory и, возможно, настроить защиту страниц (VirtualProtectEx)). Без загрузки библиотеки вам потребуется вручную отобразить переменные, переместить указатели на функции и все остальные функции, выполняемые LoadLibrary.

Вы спрашивали ранее о семантике CreateRemoteThread. Он создаст поток в другом процессе, который будет продолжать работать до тех пор, пока не прекратит сам или что-то еще (кто-то вызывает TerminateThread или процесс завершается и вызывает ExitProcess и т. Д.). Поток будет работать как параллель так же, как и законно созданный поток (переключение контекста).

Другие вопросы по тегам