Обнаружил странное поведение потока запущенного в user mode из драйвера через RtlCreateUserThread (или создание контекста потока вручную плюс ZwCreateThread). В новом потоке LoadLibrary для dll который еще не был загружен в процесс не работает. LastError = 1 (incorrect function). Пробовал сравнить ТЕВ потоков созданных из ядра и user mode: соответствие полное. На что еще можно посмотреть. P.S. пробовал из потока созданного из ядра создать еще один поток и сделать LoadLibrary в нем - не работает. После небольшой сессии отладки, обнаружил, что в процессе LoadLibrary вызывается CsrClientCallServer которая собственно и заваливается. Как я понимаю поток созданный из ядра не зарегистрирован у csrss и это создает проблемы. Есть ли какой обходной путь?
katrus В потоках, созданных вручную, можно вызывать только функции из ntdll.dll. Так как ядро об этом потоке ничего не знает.
katrus Так Вы пытаетесь подгузить свою копию kernel32 в чужой процесс? Тогда постановка задачи недостаточно подробная. Рассказывайте о конкретных целях содеянного. SlyBit ИМХО ерунда полная. Что значит "вручную", и что значит "ядро не знает"? Единственное, что иногда стоит сделать, - это настроить SEH.
Нет. Цель - из ядра загрузить в контекст процесса свою собственную dll. Т.е. идея примерно такая: 1. В памяти процесса создать регион, скопировать туда функцию которая вызывает LoadLibrary. 2. Вызвать аналог RtlCreateUserThread. Пункт 2. никаких затруднений не вызывает. Но оказалось, что созаданный таким образом поток не обладет всеми возможностями.
katrus Нет... всё таки что это за такая "своя собственная dll", которая в DllMain CsrClientCallServer вызывает?
Моя dll сама по себе никаких CsrClientCallServer не вызывает. Более того сейчас это просто пустышка в которой DllMain всегда возвращает TRUE. Фокус в том, что существует следующая последоватгельность вызовов: LoadLibrary -> ... -> LdrpLoadLibrary -> LdrpWalkImportDescriptors -> LdrpManifestProbeRoutine -> CreateActCtx -> BasepCreateActCtx -> CsrBaseCreateActCtx -> CsrClientCallServer. Вот последняя CsrClientCallServer и заваливается. Попробовал "зарегистрировать" уже существующий поток в Csr. Не получается...
katrus У меня вызов LoadLibrary не сводится к CsrClientCallServer, если только в DllMain нету вызова никаких функций типа CreateThread, которые уже в свою очередь вызывают CsrClientCallServer.
у меня вызов LoadLibraryA() в потоке, созданном через NtCreateThread(), нормально загружает библиотеку.
SlyBit Может у тебя поток, созданный из ядра, загружает библиотеку которая уже присутствует в контексте процесса? В такой ситуации LoadLibrary работает и у меня. Еще раз проверил на самом простейшем примере. В user space: Code (Text): DWORD WINAPI test(LPVOID param_) { printf("%x", LoadLibrary("empty_dll.dll")); // по настоящему пустая dll. Единственная функция DllMain всегда возвращает TRUE. return 0; } В ядре Code (Text): RtlCreateUserThread( // адрес RtlCreateUserThread подсмотрел в дизассемблере NtCurrentProcess(), NULL, FALSE, 0, 0, 0, (PVOID)0x00418B20, // адресс test в user mode (PVOID)0x1234, NULL, NULL); RtlCreateUserThread вызывается в обработчике DeviceIoControl. В отладчике явно видно, что LoadLibrary всегда доходит до CsrClientCallServer и в ситуации когда поток создан из ядра, эта функция неуспешна.
Обнаружил еще один интересный момент: LoadLibrary библиотеки из windows/system32 работает. Пытаюсь поковырять манифесты... P.S. еще обнаружил, что CreteProcess также не работает, по той же причине.
Вобщем с LoadLibrary все стало понятно (спасибо SlyBit). Достаточно убрать манифест из загружаемого dll. Но проблема с CreateProcess остается открытой. Ни поток открытый из ядра ни любой новый поток открутый из него нe в состоянии сделать CreateProcess
само собой. тебе уже писали почему. Решение - можешь зарегать вручную (от версии винды отличаться будут реализации), или создать поток создающий процесс из созданного потока в csrss.exe