созданые потока

Тема в разделе "WASM.NT.KERNEL", создана пользователем AntiB, 6 июл 2009.

  1. AntiB

    AntiB New Member

    Публикаций:
    0
    Регистрация:
    23 мар 2007
    Сообщения:
    393
    Доброе время суток, у меня следующая проблема:
    я хочу сделать создание потока с ядра в другом процессе и делаю это следующим кодом:
    Код (Text):
    1. RegionState = PTOCESS_THREAD_STACK_SIZE + sizeof(CONTEXT) + sizeof(USER_STACK) + sizeof(HANDLE) +
    2.                   sizeof(OBJECT_ATTRIBUTES) + sizeof(CLIENT_ID) + InjectCodeSize;
    3.  
    4.         status = ZwAllocateVirtualMemory( Process,
    5.                                           &Base,
    6.                                           0,
    7.                                           &RegionState,
    8.                                           MEM_COMMIT | MEM_RESERVE,
    9.                                           PAGE_EXECUTE_READWRITE );
    10.  
    11.         if (NT_SUCCESS( status )) {
    12.  
    13.             Context = (PCONTEXT)( (ULONG)Base + PTOCESS_THREAD_STACK_SIZE );
    14.  
    15.             UserStack = (PUSER_STACK)( (ULONG)Context + sizeof(CONTEXT) );
    16.  
    17.             ThreadHandle = (PHANDLE)( (ULONG)UserStack + sizeof(USER_STACK) );
    18.  
    19.             attributes = (POBJECT_ATTRIBUTES)( (ULONG)ThreadHandle + sizeof(HANDLE) );
    20.  
    21.             ClientId = (PCLIENT_ID)( (ULONG)attributes + sizeof(OBJECT_ATTRIBUTES) );
    22.  
    23.             CodeBase = (PVOID)( (ULONG)ClientId + sizeof(CLIENT_ID) );
    24.  
    25.  
    26.             status = ObReferenceObjectByHandle( Process,
    27.                                                 PROCESS_ALL_ACCESS,
    28.                                                 *PsProcessType,
    29.                                                 KernelMode,
    30.                                                 &EProcess,
    31.                                                 NULL );
    32.  
    33.             if (NT_SUCCESS( status )) {
    34.  
    35.                 KeStackAttachProcess( EProcess,
    36.                                       &ApcState );
    37.  
    38.                 UserStack->ExpandableStackBottom =
    39.                     UserStack->ExpandableStackLimit = Base;
    40.                 UserStack->ExpandableStackBase = (PVOID)( (ULONG)Base + PTOCESS_THREAD_STACK_SIZE );
    41.  
    42.                 Context->ContextFlags = CONTEXT_FULL;
    43.                 Context->SegGs = 0;
    44.                 Context->SegFs = 0x3B;
    45.                 Context->SegEs = 0x23;
    46.                 Context->SegDs = 0x23;
    47.                 Context->SegSs = 0x23;
    48.                 Context->SegCs = 0x1B;
    49.                 Context->EFlags = 0x3000;
    50.                 Context->Esp = (ULONG)UserStack->ExpandableStackBase - 4;
    51.                 Context->Eip = (ULONG)CodeBase;
    52.  
    53.                 RtlCopyMemory( CodeBase,
    54.                                InjectThreadProc,
    55.                                InjectCodeSize );
    56.  
    57.                 InitializeObjectAttributes( attributes,
    58.                                             NULL,
    59.                                             OBJ_KERNEL_HANDLE,
    60.                                             NULL,
    61.                                             NULL );
    62.  
    63.                 status = NtCreateThread( ThreadHandle,
    64.                                          THREAD_ALL_ACCESS,
    65.                                          attributes,
    66.                                          NtCurrentProcess(),
    67.                                          ClientId,
    68.                                          Context,
    69.                                          UserStack,
    70.                                          TRUE );
    71.  
    72.                 KeUnstackDetachProcess( &ApcState );
    вроде все хорошо, но система падает с ошибкой: INVALID_PROCESS_DETACH_ATTEMPT (0x6) как я понимаю что что-то с KeUnstackDetachProcess, но не могу понять что (мало опыта). Что я делаю не правильно?

    Заранее всем спасибо!
     
  2. TSS

    TSS New Member

    Публикаций:
    0
    Регистрация:
    13 апр 2009
    Сообщения:
    494
    Либо один из списков APC не пустой (юзермодный и/или ядерный), либо ядерная APC в стадии обработки, либо APC index равен нулю.
     
  3. AntiB

    AntiB New Member

    Публикаций:
    0
    Регистрация:
    23 мар 2007
    Сообщения:
    393
    если не делать NtCreateThread - все гуд, как эту проблему можно исправить?
     
  4. TSS

    TSS New Member

    Публикаций:
    0
    Регистрация:
    13 апр 2009
    Сообщения:
    494
    Для начала нужно понять какая тут проблема из 4х перечисленных мной, посмотри равна ли Thread->ApcStateIndex нулю, и равна ли Thread->ApcState.KernelApcInProgress true. Ну и есть ли APC в обоих списках Thread->ApcState.
     
  5. AntiB

    AntiB New Member

    Публикаций:
    0
    Регистрация:
    23 мар 2007
    Сообщения:
    393
    ApcState.KernelApcInProgress = 0 (false)
    ApcState. ApcListHead:
    [0]
    -Flink = 0xffffffff
    -Blink = 0x80581fe9

    [1]
    -Flink = 0xb21cada5
    -Blink = 0x0006d6cc
    извините что подал инфу в таком виде, я новичок в кернеле и точно не знаю или это вообще та инфа :dntknw:
     
  6. TSS

    TSS New Member

    Публикаций:
    0
    Регистрация:
    13 апр 2009
    Сообщения:
    494
    Thread->ApcStateIndex напиши.
    Чтобы проверить есть ли APC в очереди используй макрос IsListEmpty
     
  7. AntiB

    AntiB New Member

    Публикаций:
    0
    Регистрация:
    23 мар 2007
    Сообщения:
    393
    IsListEmpty( &ApcState.ApcListHead[0] ) - возвращает 0
    IsListEmpty( &ApcState.ApcListHead[1] ) - возвращает 0

    а как посмотреть ApcStateIndex ?
     
  8. TSS

    TSS New Member

    Публикаций:
    0
    Регистрация:
    13 апр 2009
    Сообщения:
    494
    Cмотреть надо не у своего процесса до аттача, а у того к кому приаттачился.
    KeGetCurrentThread() после аттача, а потом смотри уже.
     
  9. AntiB

    AntiB New Member

    Публикаций:
    0
    Регистрация:
    23 мар 2007
    Сообщения:
    393
    Спасибо, ошибся.
    сделал как ты говорил, результат:
    Код (Text):
    1. Thread = KeGetCurrentThread();
    2. Apc = (PKAPC_STATE)( (ULONG)Thread + 0x34 );
    3. IsListEmpty( &Apc->ApcListHead[0] ) = 1
    4. IsListEmpty( &Apc->ApcListHead[1] ) = 1
    это для ХП СП2, а как посмотреть ApcStateIndex ?
     
  10. AntiB

    AntiB New Member

    Публикаций:
    0
    Регистрация:
    23 мар 2007
    Сообщения:
    393
    Если я не ошибаюсь, то ApcStateIndex находиться по смещению 0xE4 от начала KTHREAD (для ХР SP 2) и у меня ето значение равно 0
     
  11. TSS

    TSS New Member

    Публикаций:
    0
    Регистрация:
    13 апр 2009
    Сообщения:
    494
    Значит текущий поток не приаттачен к процессу, отсюда и бсод.

    После вызова KeStackAttachProcess( EProcess, &ApcState ) у тебя ApcState->Process равен нулю ?
     
  12. AntiB

    AntiB New Member

    Публикаций:
    0
    Регистрация:
    23 мар 2007
    Сообщения:
    393
  13. x64

    x64 New Member

    Публикаций:
    0
    Регистрация:
    29 июл 2008
    Сообщения:
    1.370
    Адрес:
    Россия
    Если я правильно понял, то, что тебе нужно, лежит вот по этой ссылке. Сильно матом не орать, код писался довольно давно ещё, но рабочий, проверял недавно на всех системах от XP до 7. Смысл приведённого кода в создании полноценного Win32-потока в два захода через CSR. Это всё только для x86, но на 64-бита портировать сможешь, ничего там хитрого особо нет. Дальше сам, думаю, разберёшься.
     
  14. AntiB

    AntiB New Member

    Публикаций:
    0
    Регистрация:
    23 мар 2007
    Сообщения:
    393
    x64
    Большое Спасибо!
    TSS
    Тебе тоже спасибо :)
     
  15. AntiB

    AntiB New Member

    Публикаций:
    0
    Регистрация:
    23 мар 2007
    Сообщения:
    393
    хреново что только много юзаеться Kmlib, а ее у меня нету :dntknw:
     
  16. x64

    x64 New Member

    Публикаций:
    0
    Регистрация:
    29 июл 2008
    Сообщения:
    1.370
    Адрес:
    Россия
    Скажу по секрету: её ни у кого нет, кроме меня. Я начал разработку этой библиотеки очень давно, несколько лет назад, и теперь использую во всех kernel-mode разработках, при этом постоянно совершенствуя и обкатывая её в реальных проектах, что есть здорово. Это, конечно, оффтоп, но я рекомендую всем системщикам начинать именно с этого, с выделения рутинных задач в некое подобие .lib-файла. Или прикупить готовую, например, я планирую свою выпустить отдельным продуктом в течении ближайшего года. А по поводу Kmlib* функций можно спросить у меня, чем смогу - помогу.
     
  17. AntiB

    AntiB New Member

    Публикаций:
    0
    Регистрация:
    23 мар 2007
    Сообщения:
    393
    Долгими мучениями сделал запуск потока, но проблема в том что создание потока идет в NtCreateProcess (то есть сделал перехват) Суть в том что если мой код трейсить - то он работает, а если нет - то не работает. Мне кажется что не инициализируеться системный структуры, ошибку делает код KiUserApcDispatcher, как можно это исправить? думаю нужно дождаться окончание инициализации процесса, только как?

    Заранее спасибо!
     
  18. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Стек создать нужно нормальный с пограничной страницей:derisive:
     
  19. AntiB

    AntiB New Member

    Публикаций:
    0
    Регистрация:
    23 мар 2007
    Сообщения:
    393
    Код (Text):
    1.     Peb = PBI.PebBaseAddress;
    2.     NtHeaders = RtlImageNtHeader( Peb->ImageBaseAddress );
    3.  
    4.     if (!MaximumStackSize)
    5.         MaximumStackSize = NtHeaders->OptionalHeader.SizeOfStackReserve;
    6.  
    7.     if (!StackSize)
    8.         StackSize = NtHeaders->OptionalHeader.SizeOfStackCommit;
    9.  
    10.     RtlZeroMemory( InitialTeb,
    11.                    sizeof(INITIAL_TEB) );
    12.  
    13.     status = NtAllocateVirtualMemory( NtCurrentProcess(),
    14.                                       (PVOID *)(&StackBase),
    15.                                       0,
    16.                                       &MaximumStackSize,
    17.                                       MEM_RESERVE,
    18.                                       PAGE_READWRITE );
    19.  
    20.     if (NT_SUCCESS( status )) {
    21.  
    22.         InitialTeb->StackCommit = (PVOID)( (ULONG)StackBase + MaximumStackSize );
    23.         InitialTeb->StackCommitMax = StackBase;
    24.         InitialTeb->StackReserved = StackBase;
    25.  
    26.         StackBase += MaximumStackSize - StackSize;
    27.  
    28.         if (MaximumStackSize > StackSize) {
    29.  
    30.             StackBase -= PageSize;
    31.             StackSize += PageSize;
    32.             GuardPage = TRUE;
    33.  
    34.         } else {
    35.             GuardPage = FALSE;
    36.         }
    37.  
    38.         status = NtAllocateVirtualMemory( NtCurrentProcess(),
    39.                                           (PVOID *)(&StackBase),
    40.                                           0,
    41.                                           &StackSize,
    42.                                           MEM_COMMIT,
    43.                                           PAGE_READWRITE );
    44.  
    45.         if (!NT_SUCCESS( status )) {
    46.  
    47.             RegionSize = 0;
    48.             NtFreeVirtualMemory( NtCurrentProcess(),
    49.                                  (PVOID *)(&StackBase),
    50.                                  &RegionSize,
    51.                                  MEM_RELEASE );
    52.  
    53.             return status;
    54.         }
    55.  
    56.         InitialTeb->StackLimit = StackBase;
    57.  
    58.         if (GuardPage) {
    59.  
    60.             RegionSize = PageSize;
    61.             status = NtProtectVirtualMemory( NtCurrentProcess(),
    62.                                              (PVOID *)(&StackBase),
    63.                                              &RegionSize,
    64.                                              PAGE_GUARD | PAGE_READWRITE,
    65.                                              &OldProtect );
    66.  
    67.             if(!NT_SUCCESS( status ))
    68.                 return status;
    69.  
    70.             InitialTeb->StackLimit = (PVOID)( (ULONG)InitialTeb->StackLimit + RegionSize );
    71.  
    72.         }
    что я сделал не правильно?
     
  20. AntiB

    AntiB New Member

    Публикаций:
    0
    Регистрация:
    23 мар 2007
    Сообщения:
    393
    Запустил код, но только как темп сделал методом "подождать 1 секунду", но такой вариант не есть гуд, как можно подождать пока процесс не захочет создать свой первый поток?