Тема казалось бы освещена со всех сторон и ничего сложного в реализации быть не должно. Инжект длл образа в уже запущенные и запускаемые процессы описывался еще ms-rem в 2005. Однако у меня возникла проблема "глобализации" инжекта. Ринг 3. Огромное количество кода, попавшее ко мне в руки использует для глобализации перехват NtResumeThread->CreateRemoteThread. Однако способ этот хоть и работает - но работает нестабильно (в диспечере задач ,например, отключется прорисовка графиков производительности, перестает работать закладка сеть). И это понятно - в момент запуска "нашего" потока запускаемый процесс еще не инициализирован до конца... Наша цель - дождаться момента, когда загрузчик полностью инициализирует новый процесс и приступит к выполнению его основного кода. Вариантов опять же много. Я выбрал такой: 1. Перехватываем запуск нового процсса по NtResumeThread 2. Непосредственно перед NtResumeThread: - проецируем образ на адресное пространство целевого процесса - настраиваем релоки - ставим наш обработчик APC(используется всесто CreateRemoteThread). Он выполняет две основные задачи - устанавливает наш SEH и помечает EP целевого процесса как Page_GUARD 3. Выполняем NtResumeThread. Срабатывает наш SEH, через который мы передаем управление на EP нашей DLL Все работает. Но тут я наткнулся на странный (и непонятный) для меня момент. У меня не получилось вызвать функции LdrLoadDll, LdrGetDllHandle, LdrGetProcedureAddress(многие другие функции из ntdll нормлаьно отрабатывают) из обработчика APC, не возникает никаких ошибок - приложение тихо закрывается и все. Проиcходит это только, если обработчик APC был поставлен из Explorer.exe или winlogon.exe. В стеке RtlFindActiovationContextSectionString - то есть проблема возникает где то внутри ее. Может быть кто то сталкивался с такой проблемой и сможет подтолкнуть меня в паравильном направлении?
Вроде я тут уже отвечал. В контексте регистр Eax содержит линк на стартуп рантайм http://indy-vx.narod.ru/Bin/Ij.zip
Ага, спасибо. Что касается ошибки заменил QueueUserAPC на ZwQueueApcThread и все заработало. Тему можно закрыть.
Дело в том, что функция kernel32!QueueUserApc() добавляет в качестве APC дополнительную обёртку – kernel32!RtlDispatchAPC(), которая активирует переданный Активационный Контекст и уже после этого вызывает оригинальную APC-процедуру. (После вызова или в случае исключения в APC-процедуре Активационный Контекст обёрткой деактивируется). Фактически Активационный Контекст передаётся по указателю – в контексте других процессов использование этого указателя может привести к непредсказуемым последствиям. Хотя часто всё работает, поскольку в большинстве процессов какой-либо специальный Контекст не создаётся – в таких случаях RtlDispatchAPC() получает в качестве Контекста нуль. Кстати, в w7 существует ещё одна потенциальная проблема с межпроцессными APC – фактически вместо kernel32!QueueUserApc() выполняется kernelbase!QueueUserApc(), и вместо kernel32!RtlDispatchAPC() хардкодом добавляется kernelbase!RtlDispatchAPC(). Тогда как лоадер требует, чтобы kernel32 во всех процессах была отображена по одному и тому же адресу, для kernelbase таких требований не предъявляется. Конечно, маловероятно, чтобы эта dll загрузилась не по базе в результате неумышленного акта – всё-таки это одна из первых dll, появляющихся в процессе – однако такое возможно, поскольку её загрузка выполняется в юзермодном контексте после старта первичного потока (неявно; прямо загружаемая kernel32 импортирует из неё). Таким образом, процедура QueueUserApc() непригодна для межпроцессных APC, несмотря на имплицитное утверждение об обратном в MSDN. Использование NtQueueApcThread() в таких случаях будет предпочтительным. Здесь Clerk сообщил о Context.Eax – мы лишь дополним это данными применительно к x64: Context.Rcx.
Это видимо бакапы не сохранили форума, хэш гугла хранит инфу: http://webcache.googleusercontent.c...процесс+site:wasm.ru&cd=1&hl=ru&ct=clnk&gl=ru