RtlCreateUserThread и LoadLibrary

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

  1. katrus

    katrus New Member

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

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

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

    SlyBit New Member

    Публикаций:
    0
    katrus

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

    katrus New Member

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

    l_inc New Member

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

    katrus New Member

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

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

    l_inc New Member

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

    l_inc New Member

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

    katrus New Member

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

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

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

    l_inc New Member

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

    SlyBit New Member

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

    katrus New Member

    Публикаций:
    0
    Странно, а поток создан из ядра?
     
  12. n0name

    n0name New Member

    Публикаций:
    0
    манифест решает
     
  13. katrus

    katrus New Member

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

    SlyBit New Member

    Публикаций:
    0
    katrus
    да
     
  15. katrus

    katrus New Member

    Публикаций:
    0
    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
    будет ли обращение к csrss при LoadLibrary, если есть манифест тогда включается в работу csrss.exe
     
  17. katrus

    katrus New Member

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

    katrus New Member

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

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

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

    katrus New Member

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

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

    n0name New Member

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