После не слишком удачной попытки сделать создать поток из ядра с помощью NtCreateThread (http://www.wasm.ru/forum/viewtopic.php?id=30655) решил поробовать APC. Сделал простейщий тест: нужный поток делаю aletable, KeInitializeApc, KeInsertQueueApc. Работает стабильно... НО, после нескольки итераций с посылкой APC в тот же самый поток user space процесс исчезает (!). Его полностью функциональная консоль остается на экране, но процесс пропадает из TaskManager. API функции также не видят этот процесс. Скажите, в общем случае, насколько APC подходит для инжекта. На какие подводные камни стоит обратить внимание?
katrus Когда я тестировал, таких побочных действий не видел. Возможно вы чтото намутили в KProcess . Хз ) Телепатов мало А вот про подводные камни: 1) Структура KPROCESS в разных версиях винды различается, поэтому внимательно проверяйте смещения 2) Правильно выделяйте и освобождайте память для APC. Для этого сделайте список, хранящий адреса АPC. в уведомлении о отработке устанавливайте флаг удаления и при следующей посылке допустим, освобождайте помеченые регионы. Можно и другой алгоритм придумать. Это повысит отказоустойчивость. Вот и все, вроде ничего такого больше не встречалось. Ну и APC не делайте слишком большую. Иногда это негативно сказывается. В 64 битной винде надо будет делать 2 вида APC, для 32 битных и для 64 битных процессов. Но это другая тема.
Да вроде пример прост как две копейки. В DriverEntry следующий код: Код (Text): tid = ... // id потока пишу вручную PsLookupThreadByThreadId(tid, &teb)) *((unsigned char *)teb + 0x4a) = 1; // make the thread alertable kapc = ExAllocatePoolWithTag(NonPagedPool, sizeof(KAPC), DRIVERTAG); KeInitializeApc(kapc, (PKTHREAD)teb, 0, (PKKERNEL_ROUTINE) &KernelApcCallBack, 0, (PKNORMAL_ROUTINE)0x00418D50, // адрес вызываемой функции UserMode, 0); KeInsertQueueApc(kapc, 0, 0, 0); ObDereferenceObject(teb); KernelApcCallBack - функцию пустышка. Функция вызываемая в user space также пуста.
Кстати, еще заметил, что если поток в котором выполняется APC, исполняет Sleep - Sleep моментально завершается. Полагаю, что в ряде случаев это может привести к проблемам. Верно?
katrus Дурацкая практика комбинировать 0 и именованные значения (так например UserMode вы написали в 3 параметре почемуб не написать OriginalApcEnvironment). Код легче читается. А по делу - на какой системе тестируете? И где ExFreePoolWithTag(kapc); (можно и без тега аллоцировать, зачем такой изврат..) Больше сказать по этому коду - нечего (учитывая что процесс делейтится , возможно адрес функции меняется, и в итоге оно падает) И что за консоль "Его полностью функциональная консоль остается на экране" может это ntvdm ?
katrus По поводу состояния потоков. Я посылаю не всем а только тем у кого стетйты не равны следующим значениям: StateTerminated, StateTransition, StateInitialized. От Sleep (то есть StateWait) это никак не повредит. Произойдет переключение контекстов, а потом вернется восвояси.