Поток из ядра

Тема в разделе "WASM.NT.KERNEL", создана пользователем test555, 1 авг 2011.

  1. test555

    test555 New Member

    Публикаций:
    0
    Регистрация:
    7 дек 2007
    Сообщения:
    241
    Добрый день. Темы по форуму изучил, но есть неопределенности.

    Драйвер, мне нужно запустить поток в процессе (известен PID, процесс уже давно работает)
    Для этого:
    1. ZwOpenProcess
    2. VirtualAlloc (выделяем в целевойм процессе память)
    3. Пишем туда свой "шел-код" (для примера - цепочка nop )
    (это все ОК)

    Далее по логике создания потока в Ринг3 нужно сделать CreateRemoteThread.
    В ядре есть функция
    Код (Text):
    1. NTSYSAPI
    2.  NTSTATUS
    3.  NTAPI ZwCreateThread(
    4.  OUT PHANDLE ThreadHandle, //понятно
    5.  IN ACCESS_MASK DesiredAccess, //понятно
    6.  IN POBJECT_ATTRIBUTES ObjectAttributes, //понятно
    7.  IN HANDLE ProcessHandle, //понятно
    8.  OUT PCLIENT_ID ClientId, //понятно
    9.  IN PCONTEXT ThreadContext,
    10.  IN PUSER_STACK UserStack,
    11.  IN BOOLEAN CreateSuspended //понятно
    12.  );
    Интересуют параметры
    IN PCONTEXT ThreadContext,
    IN PUSER_STACK UserStack,
    А точнее как их заполнить. Но предварительно мне нужно выделить память для стека?
    Как заполнить структуры?
    Читал Руссиновича и Неббета, немного неясно...
     
  2. shchetinin

    shchetinin Member

    Публикаций:
    0
    Регистрация:
    27 май 2011
    Сообщения:
    715
    Код (Text):
    1. CONTEXT context = {CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS | CONTEXT_FLOATING_POINT};
    2.  
    3.         /* set the Eip for the child process to our child function */
    4.         ZwGetContextThread(NtCurrentThread(), &context);
    5.         context.Eip = (ULONG)child_entry;
    6.  
    7.         MEMORY_BASIC_INFORMATION mbi;
    8.         ZwQueryVirtualMemory(NtCurrentProcess(), (PVOID)context.Esp, MemoryBasicInformation, &mbi, sizeof mbi, 0);
    9.  
    10.         USER_STACK stack = {0, 0, (PCHAR)mbi.BaseAddress + mbi.RegionSize, mbi.BaseAddress, mbi.AllocationBase};
    11.         CLIENT_ID cid;
    12.  
    13.         /* create thread using the modified context and stack */
    14.         ZwCreateThread(&hThread, THREAD_ALL_ACCESS, &oa, hProcess, &cid, &context, &stack, TRUE);
    15.  
    16.  THREAD_BASIC_INFORMATION tbi;
    17.         ZwQueryInformationThread(NtCurrentThread(), ThreadBasicInformation, &tbi, sizeof tbi, 0);
    18.         PNT_TIB tib = (PNT_TIB)tbi.TebBaseAddress;
    19.         ZwQueryInformationThread(hThread, ThreadBasicInformation, &tbi, sizeof tbi, 0);
    20.         ZwWriteVirtualMemory(hProcess, tbi.TebBaseAddress, &tib->ExceptionList, sizeof tib->ExceptionList, 0);
    21.  
    22. ZwResumeThread(hThread, 0);
    При желании переписываешь в кернел.
     
  3. test555

    test555 New Member

    Публикаций:
    0
    Регистрация:
    7 дек 2007
    Сообщения:
    241
    сенк.
     
  4. test555

    test555 New Member

    Публикаций:
    0
    Регистрация:
    7 дек 2007
    Сообщения:
    241
    Смотри, новый поток должен иметь свой стек?
    Тут что-то не так, либо я не понимаю..
     
  5. shchetinin

    shchetinin Member

    Публикаций:
    0
    Регистрация:
    27 май 2011
    Сообщения:
    715
    Да желательно что бы у него был свой стек.:):)
     
  6. x64

    x64 New Member

    Публикаций:
    0
    Регистрация:
    29 июл 2008
    Сообщения:
    1.370
    Адрес:
    Россия
    Если регистрация в CSR не нужна, то более чем хватит и этого (из ntdll.dll):

    Код (Text):
    1. NTSTATUS
    2. RtlCreateUserThread (
    3.     IN HANDLE Process,
    4.     IN PSECURITY_DESCRIPTOR ThreadSecurityDescriptor OPTIONAL,
    5.     IN BOOLEAN CreateSuspended,
    6.     IN ULONG ZeroBits OPTIONAL,
    7.     IN SIZE_T MaximumStackSize OPTIONAL,
    8.     IN SIZE_T CommittedStackSize OPTIONAL,
    9.     IN PUSER_THREAD_START_ROUTINE StartAddress,
    10.     IN PVOID Parameter OPTIONAL,
    11.     OUT PHANDLE Thread OPTIONAL,
    12.     OUT PCLIENT_ID ClientId OPTIONAL);
     
  7. test555

    test555 New Member

    Публикаций:
    0
    Регистрация:
    7 дек 2007
    Сообщения:
    241
    А для чего нужна регистрация в CSR?

    Всмысле если ее нет, будет ли мой поток нормально работать в юзермодном приложении?
    (например цикл )
    for (;;) Sleep(1000);
     
  8. x64

    x64 New Member

    Публикаций:
    0
    Регистрация:
    29 июл 2008
    Сообщения:
    1.370
    Адрес:
    Россия
    Да, вполне. Без регистрации в CSR не сможешь использовать такие вещи как CreateProcess(), CreateThread(), CreateRemoteThread() и ещё что-то там, сейчас не помню уже, в общем, всё то, что через вызов CSR выполняется.
     
  9. test555

    test555 New Member

    Публикаций:
    0
    Регистрация:
    7 дек 2007
    Сообщения:
    241
    Ясно, а эти вещи как раз нужны.
     
  10. x64

    x64 New Member

    Публикаций:
    0
    Регистрация:
    29 июл 2008
    Сообщения:
    1.370
    Адрес:
    Россия
    Ну как бы по регистрации потока в CSR информации вполне достаточно на форумах, так что не думаю, что с этим будут какие-то проблемы у тебя.
     
  11. TermoSINteZ

    TermoSINteZ Синоби даоса Команда форума

    Публикаций:
    2
    Регистрация:
    11 июн 2004
    Сообщения:
    3.552
    Адрес:
    Russia
    test555
    Гуглите как минимум по "CsrClientCallServer"
     
  12. test555

    test555 New Member

    Публикаций:
    0
    Регистрация:
    7 дек 2007
    Сообщения:
    241
    Погуглил, CsrClientCallServer (использую пример из Неббета номер 6.2).
    Но проблема в том, что я создаю поток из драйвера, а эта штука в ntdll.dll
     
  13. x64

    x64 New Member

    Публикаций:
    0
    Регистрация:
    29 июл 2008
    Сообщения:
    1.370
    Адрес:
    Россия
    Библиотека ntdll.dll совершенно также доступна и в ядре.
    Если не ошибаюсь, она всегда идёт вторым модулем в списке.
     
  14. test555

    test555 New Member

    Публикаций:
    0
    Регистрация:
    7 дек 2007
    Сообщения:
    241
    ОК!! Сенкс )
     
  15. test555

    test555 New Member

    Публикаций:
    0
    Регистрация:
    7 дек 2007
    Сообщения:
    241
    Итак, проблема - CsrClientCallServer мне дает 0хС0000008 (STATUS_INVALID_HANDLE)

    Делаю так:
    Код (Text):
    1. ZwOpenProcess(&hProcess,PROCESS_ALL_ACCESS,&oa, &cid); // получаю хендл целевого процесса
    2. ..
    3. ZwAllocateVirtualMemory(hProcess,
    4.                                      &stack.ExpandableStackBottom,
    5.                                      0,
    6.                                      &AllocSize,
    7.                                      MEM_RESERVE,
    8.                                      PAGE_READWRITE);
    9. ...// и другие операции со стеком и тд...
    10.  
    11.                 status = TrueZwCreateThread(&hThread,
    12.                                         THREAD_ALL_ACCESS,
    13.                                         NULL,
    14.                                         hProcess,
    15.                                         cid,
    16.                                         &context,
    17.                                         &stack,
    18.                                         TRUE);
    19. // Поток создается. Если поставить простейший цикл и последний флаг False - то поток работает.
    20.                 InformCsrss(hProcess, hThread, cid );
    21.             //  status = TrueZwResumeThread(hThread, 0);
    Функция информатирования InformCsrss:
    Код (Text):
    1. typedef struct _BASE_CREATETHREAD_MSG {
    2.     HANDLE ThreadHandle;
    3.     CLIENT_ID ClientId;
    4. } BASE_CREATETHREAD_MSG, *PBASE_CREATETHREAD_MSG;
    5.  
    6. typedef ULONG CSR_API_NUMBER;
    7.  
    8.  typedef struct _CSR_CLIENTCONNECT_MSG {
    9.     IN ULONG ServerDllIndex;
    10.     IN OUT PVOID ConnectionInformation;
    11.     IN OUT ULONG ConnectionInformationLength;
    12. } CSR_CLIENTCONNECT_MSG, *PCSR_CLIENTCONNECT_MSG;
    13.  
    14. typedef struct _BASE_CREATEPROCESS_MSG {
    15.     HANDLE ProcessHandle;
    16.     HANDLE ThreadHandle;
    17.     CLIENT_ID ClientId;
    18.     ULONG Machine;
    19.     CLIENT_ID DebuggerClientId;
    20.     ULONG CreationFlags;
    21.     ULONG VdmBinaryType;
    22. } BASE_CREATEPROCESS_MSG, *PBASE_CREATEPROCESS_MSG;
    23.  
    24. typedef struct _BASE_API_MSG {
    25.     PORT_MESSAGE h;
    26.     union {
    27.         CSR_API_CONNECTINFO ConnectionRequest;
    28.         struct {
    29.             PCSR_CAPTURE_HEADER CaptureBuffer;
    30.             CSR_API_NUMBER ApiNumber;
    31.             ULONG ReturnValue;
    32.             ULONG Reserved;
    33.             union {
    34.                 CSR_CLIENTCONNECT_MSG   ClientConnect;
    35.                 BASE_CREATEPROCESS_MSG  CreateProcess;
    36.                 BASE_CREATETHREAD_MSG   CreateThread;
    37.                 ULONG ApiMessageData[0x98];
    38.             } u;
    39.         };
    40.     };
    41. } BASE_API_MSG, *PBASE_API_MSG;
    42.  
    43. VOID InformCsrss(HANDLE hProcess, HANDLE hThread, PCLIENT_ID pcid)
    44. {
    45.  
    46.  
    47.  
    48.     BASE_API_MSG BaseApiMsg;
    49.     PBASE_CREATETHREAD_MSG pBaseCreateThread;
    50.     RtlZeroMemory(&BaseApiMsg,sizeof(BASE_API_MSG));
    51.    
    52.     pBaseCreateThread = (PBASE_CREATETHREAD_MSG)&BaseApiMsg.u.CreateThread;
    53.     pBaseCreateThread->ThreadHandle = hThread;
    54.     pBaseCreateThread->ClientId.UniqueProcess = pcid->UniqueProcess;   
    55.     pBaseCreateThread->ClientId.UniqueThread = pcid->UniqueThread;
    56.  
    57.  DPRINT("CsrClientCallServer %x ",CsrClientCallServer(&BaseApiMsg, 0, 0x10001, 0x0C) );
    58. }
    Где копать - не понятно. Смотрел DbgPrint-ом смещение pBaseCreateThread такие же (0х28). Заполняется так же - хеднл, PID, TID.
    Сделал юзермодную программку CreateRemoteThread (...), отлови в олли CsrClientCallServer. Константы такие же, первые 0х28 байт непонятно что, но если их обнулить то CsrClientCallServer все равно возвращает 0.
    Далее в буфере по смещению 0х28 идут хендл потока, PID, TID.

    Почему у меня в драйвере CsrClientCallServer возвращает STATUS_INVALID_HANDLE? Я подсовываю ему hThread...
     
  16. x64

    x64 New Member

    Публикаций:
    0
    Регистрация:
    29 июл 2008
    Сообщения:
    1.370
    Адрес:
    Россия
    Не уверен, но мне кажется проблема в том, что переменная под хендл у тебя в а.п. ядра расположена (стек ядра), а CSR её пытается использовать в контексте своего процесса. В общем, не знаю, попробуй выделить память под хендл потока в целевом процессе и аттачься к его а.п. на время вызова CSR. Других идей пока нет.