Недавно я написал DLL-Injector на C ++, для которого требовались следующие условия:
- ПРОЦЕСС ВПРЫСКА (назовем его «Инжектор»)в качестве DLL, подлежащей инъекции (инъекция) существует в 64- и 32-битном вариантах.В зависимости от цели, пытаются ввести соответствующую версию инъекции.
- Должна быть возможность внедрять целевые процессы, которые являются 32-битными (WOW64), даже если Инжектор работает в 64-битном
Я быстро заметил, что вызов GetProcAddress ("LoadLibraryA") в Injector возвращает «непригодный» дескриптор, так как 32-битная цель загружает еще один kernel32.dll иадрес функции там другой, поэтому внедрение не удается (удаленный поток не может быть запущен с использованием возвращенного адреса / дескриптора).Кроме того, 32-битный процесс загружает kernel32.dll по другому базовому адресу, что делает создание удаленного потока еще более невозможным.
Чтобы прояснить, что я имею в виду, происходит следующее:
- Инжектор имеет 64-битную версию kernel32.dll , загруженную с 0x12340000
- Инжектор получает дескриптор для LoadLibraryA 0x00005678 из этого ядра32.dll
- Target имеет 32-битную версию kernel32.dll , загруженную в 0xABCD0000
- Дескриптор LoadLibrary этого kernel32.dll, как ожидается, будет 0x0000EFAB
- Инжектор пытается запустить удаленный поток в цели с помощью функции 0x12345678, но ожидается 0xABCDEFAB
При внедрении 64-битного процесса из 64-битного процесса и 32-битного из 32-битного обычно нетпроблема, поскольку kernel32.dll (скорее всего) загружается по одному и тому же базовому адресу, и можно использовать один и тот же адрес функции - это мое понимание до сих пор.Однако в этом случае условия различаются.
Чтобы решить эту проблему, я сделал следующие шаги:
- 64-битный Инжектор получает адрес kernel32.dll, загруженного 32-битной целью, используя * 1044.* EnumProcessModulesEx () (должно быть 0xABCD000)
- Получить имя файла этого kernel32.dll , проанализировать PE-заголовок и получить RVA LoadLibraryA (долженбыть 0x000EFAB)
- На данный момент, мы знаем, где kernel32.dll загружается в 32-битном целевом объекте и адрес функции из этой DLL.
- 64 битИнжектор запускает удаленную нить в 32-битном целевом объекте с ImageBase + функцией RVA , в этом случае магическим 0xABCDEFAB
Этот подход на самом деле работает очень хорошо, но я не могу избавиться отмысль о том, что это полная нагрузка, и должно быть более простое решение для внедрения 32-битных целей из 64-битных инжекторов.
У меня есть два вопроса, за которые я очень благодарен, если на них можно будет ответить, онre:
- Есть ли более простой способ добиться такого рода инъекций?
- Есть ли возможные проблемы с подходом, о котором я говорил, о котором я не думал?
Любые ответы очень приветствуются, спасибо!
РЕДАКТИРОВАТЬ: Боже мой ... Я только что понял, что я неправильно описал ситуацию в моем первоначальном посте.INJECTOR является 64-битным, а TARGET - 32-битным (изначально все было наоборот, но я уже исправил это).Ниже приводятся комментарии Бена Фойгта, которые полностью верны, и вызов EnumProcessModulesEx не удался.Большой большой большой извините за эту путаницу: (