RtlCreateUserThread и LoadLibrary

Тема в разделе "WASM.NT.KERNEL", создана пользователем katrus, 12 янв 2009.

  1. katrus

    katrus New Member

    Публикаций:
    0
    Регистрация:
    7 мар 2007
    Сообщения:
    612
    Обнаружил странное поведение потока запущенного в user mode из драйвера через RtlCreateUserThread (или создание контекста потока вручную плюс ZwCreateThread). В новом потоке LoadLibrary для dll который еще не был загружен в процесс не работает. LastError = 1 (incorrect function). Пробовал сравнить ТЕВ потоков созданных из ядра и user mode: соответствие полное. На что еще можно посмотреть.

    P.S. пробовал из потока созданного из ядра создать еще один поток и сделать LoadLibrary в нем - не работает.

    После небольшой сессии отладки, обнаружил, что в процессе LoadLibrary вызывается CsrClientCallServer которая собственно и заваливается. Как я понимаю поток созданный из ядра не зарегистрирован у csrss и это создает проблемы. Есть ли какой обходной путь?
     
  2. SlyBit

    SlyBit New Member

    Публикаций:
    0
    Регистрация:
    4 июл 2008
    Сообщения:
    43
    katrus

    В потоках, созданных вручную, можно вызывать только функции из ntdll.dll. Так как ядро об этом потоке ничего не знает.
     
  3. katrus

    katrus New Member

    Публикаций:
    0
    Регистрация:
    7 мар 2007
    Сообщения:
    612
    А как же жить? :) В смысле, как притащить свою dll'ку в такой ситуации?
     
  4. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    katrus
    Так Вы пытаетесь подгузить свою копию kernel32 в чужой процесс? Тогда постановка задачи недостаточно подробная. Рассказывайте о конкретных целях содеянного.
    SlyBit
    ИМХО ерунда полная. Что значит "вручную", и что значит "ядро не знает"? Единственное, что иногда стоит сделать, - это настроить SEH.
     
  5. katrus

    katrus New Member

    Публикаций:
    0
    Регистрация:
    7 мар 2007
    Сообщения:
    612
    Нет. Цель - из ядра загрузить в контекст процесса свою собственную dll. Т.е. идея примерно такая:
    1. В памяти процесса создать регион, скопировать туда функцию которая вызывает LoadLibrary.
    2. Вызвать аналог RtlCreateUserThread.

    Пункт 2. никаких затруднений не вызывает. Но оказалось, что созаданный таким образом поток не обладет всеми возможностями.
     
  6. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    SlyBit
    Извиняюсь... слегка прогнал похоже.
     
  7. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    katrus
    Нет... всё таки что это за такая "своя собственная dll", которая в DllMain CsrClientCallServer вызывает?
     
  8. katrus

    katrus New Member

    Публикаций:
    0
    Регистрация:
    7 мар 2007
    Сообщения:
    612
    Моя dll сама по себе никаких CsrClientCallServer не вызывает. Более того сейчас это просто пустышка в которой DllMain всегда возвращает TRUE. Фокус в том, что существует следующая последоватгельность вызовов:
    LoadLibrary -> ... -> LdrpLoadLibrary -> LdrpWalkImportDescriptors -> LdrpManifestProbeRoutine -> CreateActCtx -> BasepCreateActCtx -> CsrBaseCreateActCtx -> CsrClientCallServer.

    Вот последняя CsrClientCallServer и заваливается.

    Попробовал "зарегистрировать" уже существующий поток в Csr. Не получается...
     
  9. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    katrus
    У меня вызов LoadLibrary не сводится к CsrClientCallServer, если только в DllMain нету вызова никаких функций типа CreateThread, которые уже в свою очередь вызывают CsrClientCallServer.
     
  10. SlyBit

    SlyBit New Member

    Публикаций:
    0
    Регистрация:
    4 июл 2008
    Сообщения:
    43
    у меня вызов LoadLibraryA() в потоке, созданном через NtCreateThread(), нормально загружает библиотеку.
     
  11. katrus

    katrus New Member

    Публикаций:
    0
    Регистрация:
    7 мар 2007
    Сообщения:
    612
    Странно, а поток создан из ядра?
     
  12. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    манифест решает
     
  13. katrus

    katrus New Member

    Публикаций:
    0
    Регистрация:
    7 мар 2007
    Сообщения:
    612
    не понял, что манифест решает?
     
  14. SlyBit

    SlyBit New Member

    Публикаций:
    0
    Регистрация:
    4 июл 2008
    Сообщения:
    43
    katrus
    да
     
  15. katrus

    katrus New Member

    Публикаций:
    0
    Регистрация:
    7 мар 2007
    Сообщения:
    612
    SlyBit

    Может у тебя поток, созданный из ядра, загружает библиотеку которая уже присутствует в контексте процесса? В такой ситуации LoadLibrary работает и у меня.

    Еще раз проверил на самом простейшем примере. В user space:
    Код (Text):
    1. DWORD WINAPI test(LPVOID param_)
    2. {
    3.     printf("%x", LoadLibrary("empty_dll.dll")); // по настоящему пустая dll. Единственная функция DllMain всегда возвращает TRUE.
    4.    return 0;
    5. }
    В ядре
    Код (Text):
    1. RtlCreateUserThread(  // адрес RtlCreateUserThread подсмотрел в дизассемблере
    2.     NtCurrentProcess(),
    3.     NULL,
    4.     FALSE,
    5.     0,
    6.     0,
    7.     0,
    8.     (PVOID)0x00418B20, // адресс test в user mode
    9.     (PVOID)0x1234,
    10.     NULL,
    11.     NULL);
    RtlCreateUserThread вызывается в обработчике DeviceIoControl. В отладчике явно видно, что LoadLibrary всегда доходит до CsrClientCallServer и в ситуации когда поток создан из ядра, эта функция неуспешна.
     
  16. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    будет ли обращение к csrss при LoadLibrary, если есть манифест тогда включается в работу csrss.exe
     
  17. katrus

    katrus New Member

    Публикаций:
    0
    Регистрация:
    7 мар 2007
    Сообщения:
    612
    А можно ли как нибудь "нейтрализовать" это обращение? Нужно определить собственный манифест?
     
  18. katrus

    katrus New Member

    Публикаций:
    0
    Регистрация:
    7 мар 2007
    Сообщения:
    612
    Обнаружил еще один интересный момент: LoadLibrary библиотеки из windows/system32 работает.

    Пытаюсь поковырять манифесты...

    P.S. еще обнаружил, что CreteProcess также не работает, по той же причине.
     
  19. katrus

    katrus New Member

    Публикаций:
    0
    Регистрация:
    7 мар 2007
    Сообщения:
    612
    Вобщем с LoadLibrary все стало понятно (спасибо SlyBit). Достаточно убрать манифест из загружаемого dll. Но проблема с CreateProcess остается открытой.

    Ни поток открытый из ядра ни любой новый поток открутый из него нe в состоянии сделать CreateProcess
     
  20. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    само собой. тебе уже писали почему.
    Решение - можешь зарегать вручную (от версии винды отличаться будут реализации), или создать поток создающий процесс из созданного потока в csrss.exe