А чем не устраивает запуск потока через LoadImage-нотификатор? В нотификаторе мониторишь загрузку нужного тебе образа (например, kernel32.dll если у тебя Win32/64 DLL или ntdll.dll если Native DLL) и в нужный момент создаёшь системный поток, в котором делаешь примерно то, что я уже описывал ранее в этой теме. Оно работает и работает стабильно, в общем-то, что ещё надо-то... Какова вообще конечная цель? Похукать API какие-нибудь? Свою DLL подгрузить туда? Или что-то другое?
См. в MSDN описание PsSetLoadImageNotifyRoutine, подробнее как бы уже некуда. Сие зависит от того, когда именно тебе нужно подгрузить DLL - в начале работы процесса или где-то потом (например, после загрузки определённой DLL). Если потом, тогда вот этот вот нотификатор тебе будет в самый раз: мониторишь загрузку нужного модуля (например, wininet.dll), запускаешь системный поток и в нём уже через CSR в два захода запускаешь поток в целевом процессе, адресом которого будет LoadLibrary. Тут проблем особо нет. Если же нужно подгрузить DLL в начале запуска процесса, тогда, думаю, лучше всего подойдут APC. Можно зашедулить APC прям сразу после инициализации первого потока процесса, адресом APC указать LoadLibraryEx - аккурат там тоже 3 аргумента. Здесь в качестве нотификатора использовать, соответственно, колбек PsSetCreateThreadNotifyRoutine. Хотя, в принципе, APC и для первого случая вполне подойдут. Только учти, что во втором случае к тому моменту, когда твоя DllMain будет вызвана, уже успеют отработать точки входа всех статически прилинкованных модулей. Если это важно и неприемлемо, тогда всё несколько сложнее и боюсь что без хуков и подмены контекста не обойтись будет. Например, в том же CreateThread-нотификаторе можно найти и перехватить точку входа ntdll.dll, это самая первая функция, которая выполняется в режиме пользователя для каждого процесса и именно она выполняет загрузку, инициализацию и вызов статических модулей.
x64 Если запустить тред сразу после создания процесса он упадёт на эксцепшине в лоадере, так как некоторые поля PEB не заполнены, их заполняет процесс-родитель уже после создания процесса, поэтому никакие нотификаторы тут не подходят. Я предложил вызвать MiProtectVirtualMemory(@ntdll, PAGE_GUARD) и обработать эксцепшин в KiDebugRoutine. Можно просто код записать перенаправить на свой хэндлер какойнибудь и выполняться в первом потоке. Или точки останова ставить..
В предложенных мною способах эта проблема отсутствует, а ты давай завязывай уже со всякими там хуками-перехватами.
x64 Создание потока через NtCreateThread, который еще нужно найти, а помимо него и еще некоторые функции, c магией в CSRSS ничем не надежнее чем установка грамотного перехвата в нужное место. По крайней мере на практике оно не очень стабильно работает. APC да, в работе по загрузке DLL оптимально, но тоже нужны некоторые хитрости, а именно подождать завершения инициализации процесса, что сделать не так трудно и без нотификаторов, достаточно разобрать виндовый загрузчик и посмотреть что он делает при завершении инициализации процесса
x64 Условие задачи - дождаться завершения работы загрузчика, в этот момент следует исполнить необходимый код. NotifyRoutines тут нисчем не связаны, так что без захвата данную задачу решить не возможно. Так как пользовательский код должен выполниться до исполнения какого либо кода из основного модуля и не системных модулей поддеоржки поэтому я предложил хорошее решение, темболее использование нотификаторов это древний кривой функционал, который уважающий себя кодер не станет применять. Если это не руткит, то лучше чем захват загрузчика тупо модификацией его кода ничего нет.
У меня есть работающий код, который реализует этот способ. Можно сколь угодно долго спорить об этом, но свою задачу этот код в своё время решил и решает вполне успешно по сей день на всех системах.
im1111 этим сейчас и займусь x64 метод PsSetLoadImageNotifyRoutine мне не подойдет, так как мне нужно дождаться окончания инициализации процесса, так как ранее написал Clerk идет эксцепшин (делал тупо: KeDelayExecutionThread на 1с - работает все как часы, но этот вариант - не есть гуд)
Напрямую - да, не связаны. Смотря какую именно задачу, их тут несколько звучало. Наверно, вся проблема как раз в том, что я не кодер.
je_ думаю уж луче NtCreateThread и создать список всех PEPROCESS и следить или это к нужному процессу создается поток, если да - то создать свой, но этот вариант думаю не очень хорош
У меня тоже есть такой рабочий код, который работает на всех системах, но есть и другие методы, мне есть чем сравнивать, поэтому я не спорю, а делаю заключение исходя из наблюдений.
x64 Да и вообще создание потока в csrss с целью создания потока, через шеллкод, в другом процессе это какая-то хитрая матрешка куда проще APC передать в csrss, он точно инициализирован.
если нужен захват до EIP, то найти EIP-вызов в к32.длл, там выше NtSetInformationThread, записываем address, и мониторим оттуда call-Ы