Как получить контекст ядерных потоков?

Тема в разделе "WASM.NT.KERNEL", создана пользователем 0x56, 2 фев 2008.

  1. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Вот код из KiSwapContext:
    Код (Text):
    1.     ;edi:PETHREAD
    2.     ;ThInitialStack=ETHREAD.Tcb.KernelStack
    3.     mov     ecx, [edi].ThInitialStack        ; get NPX save save area address
    4.     sub     ecx, NPX_FRAME_LENGTH
    5.     fxsave  [ecx]                   ; save NPX state
    6. ---------------------------------------------------------------------------------------------
    7.     ;TsEFlags=KTRAP_FRAME.EFlags
    8.     mov     eax, [esi].ThInitialStack ; get initial stack address
    9.     sub     eax, NPX_FRAME_LENGTH
    10.     test    byte ptr [eax] - KTRAP_FRAME_LENGTH + TsEFlags + 2, EFLAGS_V86_MASK / 10000h
    11. ---------------------------------------------------------------------------------------------
    12.     mov     eax, PCR[PcPrcbData.PbCurrentThread] ; get current thread address
    13.     mov     eax, [eax]+ThInitialStack ; eax = base of stack
    14.     test    dword ptr [edx]+TsEFlags, EFLAGS_V86_MASK ; is this a V86 frame?
    15.     jnz     short ae10              ; if nz, V86 frame
    16.     sub     eax, TsV86Gs - TsHardwareSegSS ; compensate for missing regs
    17. ae10:   sub     eax, NPX_FRAME_LENGTH   ; Esp0 value
     
  2. 0x56

    0x56 New Member

    Публикаций:
    0
    Регистрация:
    2 янв 2008
    Сообщения:
    63
    Great

    так вроде их состояние меняется в Waiting при свопе
    напомню что я на DISPATH_LEVEL оба ядра процессора вывожу

    я вначале предподожил что указатель невалидный на трэп, на самом деле в коде он не разьименовывался
    побайтово стэк вывел искал там адрес с 77 cd 4d 80 (nt!KiSwapContext+0x2f),
    искал уазатель от дна стека, считая что 804dcd77 равен _KTRAP_FRAME.Eip либо _KTRAP_FRAME.DbgEip, ведь в отладчике для всех eip=804dcd77
    белеберда получилась с таким указателем на трэп

    вроде WinDBg от EBP тоже пляшет, только откуда он его берет?
    TrapFrame->EBP отличается от EBP отладчика

    не знаю за что зацепиться даже, если только за TrapFrame->DbgEbp
    иногда TrapFrame->DbgEbp метко попадает в первый ChildEBP по отладчику
    если бы для всех так было, то можно было бы расковырять стек с учетом известных кол-ва и размеров параметров KiSwapContext, KiSwapThread
    и найти адрес возврата на функцию до того как тред засвопился

    пару снимков для размышления:


    Сама функция:

    Код (Text):
    1. VOID Test()
    2. {
    3.     ULONG Count=0;
    4.     ULONG Tid = 0;
    5.     ULONG Eip = 0; 
    6.     ULONG xEsp[4];
    7.     ULONG x0Esp[4];
    8.  
    9.     NTSTATUS ns;
    10.         PLIST_ENTRY ThreadLink = NULL;
    11.     PEPROCESS PsSystemProcess = NULL;
    12.     ULONG CurrentEthread = 0, CurrentTable = 0, StartEthread = 0;
    13.     ULONG StackTrapFrameHardwareEsp = 0, TcbTrapFrameHardwareEsp = 0;
    14.  
    15.     KIRQL OldIrql;
    16.     KAPC_STATE ApcState;
    17.     PKTRAP_FRAME TrapFrame;
    18.     CONTEXT ctx = {CONTEXT_FULL};
    19.     BOOLEAN bCanCheckThread = TRUE;
    20.  
    21.     ULONG ulXXX = 0;
    22.     KTHREAD_STATE ThreadState;
    23.     PVOID pThreadTrapFrame = NULL;
    24.     PVOID pThreadInitialStack = NULL;
    25.     PVOID pThreadKernelStack = NULL;
    26.     PKEXCEPTION_FRAME CxFrame = NULL;
    27.    
    28.     switch(*NtBuildNumber)
    29.     {
    30.         case 2195:  // win 2k
    31.         {      
    32.             break;
    33.         }
    34.        
    35.         case 2600:  // win xp
    36.         {
    37.             // KPROCESS.ThreadListHead
    38.             ulOffset_KPROCESS_ThreadListHead = 0x50;
    39.  
    40.             // ETHREAD.ThreadListEntry
    41.             ulOffset_ETHREAD_ThreadListEntry = 0x22c;
    42.  
    43.             // ETHREAD.UniqueThread (4 bytes)
    44.             ulOffset_ETHREAD_UniqueThread    = 0x1f0;
    45.  
    46.             // KTHREAD.ThreadListEntry
    47.             ulOffset_KTHREAD_ThreadListEntry = 0x1b0;
    48.  
    49.             // KTHREAD.InitialStack (4 bytes)
    50.             ulOffset_KTHREAD_InitialStack    = 0x018;
    51.  
    52.             // KTHREAD.KernelStack (4 bytes)
    53.             ulOffset_KTHREAD_KernelStack     = 0x028;
    54.  
    55.             // KTHREAD.State (1 bytes)
    56.             ulOffset_KTHREAD_State           = 0x02d;
    57.  
    58.             // KTHREAD.TrapFrame (4 bytes)
    59.             ulOffset_KTHREAD_TrapFrame       = 0x134;
    60.  
    61.             break;
    62.         }
    63.     }
    64.  
    65.     __asm cli;
    66.  
    67.     // DPC_LEVEL for current thread && lock other processors by our DPC-routine
    68.     OldIrql = GlobalLock();
    69.  
    70.     //PsSystemProcess = (PEPROCESS)0x818e8b28;
    71.     PsSystemProcess = PsGetCurrentProcess();
    72.     if(PsSystemProcess)
    73.     {
    74.         //KeStackAttachProcess(PsSystemProcess, &ApcState);
    75.  
    76.         CurrentEthread = *((ULONG *)((ULONG)PsSystemProcess + ulOffset_KPROCESS_ThreadListHead));
    77.         CurrentEthread = CurrentEthread - ulOffset_KTHREAD_ThreadListEntry;
    78.         StartEthread = CurrentEthread;
    79.  
    80.         while(1)
    81.         {
    82.             if(Count>=1 && CurrentEthread == StartEthread) break;
    83.  
    84.             if((PETHREAD)CurrentEthread != PsGetCurrentThread())
    85.             {          
    86.                 Eip = 0;
    87.                 bCanCheckThread = TRUE;
    88.  
    89.                 memset(&ctx, 0, sizeof(ctx));
    90.                 ctx.ContextFlags = CONTEXT_FULL;
    91.  
    92.                 Tid = *(PULONG)(CurrentEthread + ulOffset_ETHREAD_UniqueThread);
    93.  
    94.                 ThreadState = *(PKTHREAD_STATE)(CurrentEthread + ulOffset_KTHREAD_State);
    95.                 if(*NtBuildNumber == WINXP_BUILD_NUMBER) bCanCheckThread = (ThreadState != Terminated);
    96.  
    97.                 DbgPrint("\n\t\t\tThread  ::  %d [0x%x], 0x%08x, %d\n\n", Tid, Tid, CurrentEthread, ThreadState);
    98.                
    99.                 if(bCanCheckThread)
    100.                 {
    101.                     pThreadInitialStack = (PVOID)*(PULONG)(CurrentEthread + ulOffset_KTHREAD_InitialStack);
    102.                     DbgPrint("pThreadInitialStack  ::  0x%08x\n", pThreadInitialStack);
    103.  
    104.                     pThreadTrapFrame = (PVOID)*(PULONG)(CurrentEthread + ulOffset_KTHREAD_TrapFrame);
    105.                     DbgPrint("pThreadTrapFrame  ::  0x%08x\n", pThreadTrapFrame);
    106.  
    107.                     DumpTrapFrame(pThreadTrapFrame);
    108.                     DbgPrint("\n\n");
    109.  
    110.                     TrapFrame = KiGetThreadTrapFrame(pThreadInitialStack);
    111.                     DbgPrint("KiGetThreadTrapFrame(pThreadInitialStack)  ::  0x%08x\n\n", TrapFrame);
    112.  
    113.                     DumpTrapFrame(TrapFrame);
    114.                     DbgPrint("\n\n");      
    115.                    
    116.                 }
    117.                 else
    118.                 {
    119.                     DbgPrint("Cannot check this thread\n");
    120.                 }
    121.             }
    122.  
    123.             ThreadLink = (PLIST_ENTRY)(CurrentEthread + ulOffset_ETHREAD_ThreadListEntry);
    124.             CurrentEthread = (ULONG)ThreadLink->Flink;
    125.             CurrentEthread = CurrentEthread - ulOffset_ETHREAD_ThreadListEntry;
    126.  
    127.             Count++;
    128.             //if(Count>=4) break;
    129.         }
    130.  
    131.         //KeUnstackDetachProcess(&ApcState);
    132.     }
    133.    
    134.     // unlock
    135.     GlobalUnlock(OldIrql);
    136.  
    137.     __asm sti;
    138.  
    139.     DbgPrint("Test - Exit\n\n");
    140.     PsTerminateSystemThread(STATUS_SUCCESS);
    141.     return;
    142. }
    Результат на винде без отладчика в аттаче.
     
  3. 0x56

    0x56 New Member

    Публикаций:
    0
    Регистрация:
    2 янв 2008
    Сообщения:
    63
  4. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Посмотрел как создаётся контекст потока:
    KiInitializeContextThread:
    Заполняется структура ниже ETHREAD.Tcb.InitialStack - контекст и загружается Tcb.KernelStack
     
  5. 0x56

    0x56 New Member

    Публикаций:
    0
    Регистрация:
    2 янв 2008
    Сообщения:
    63
    Clerk
    и?
    в примере дизассмеблерном твоём
    все начинается с mov ecx, [edi].ThInitialStack

    предполагать можно долго но и проверять надо на практике
    я вот вижу на реальной ОС :) , что Tcb.KernelStack рядом с ESP

    а что там?
    там цепочка параметров для функций, адресов возврата и прочей лабуды

    помотри внимательней на снимки сверху

    не могу я оттуда выдернуть контекст
    пробовал )
     
  6. 0x56

    0x56 New Member

    Публикаций:
    0
    Регистрация:
    2 янв 2008
    Сообщения:
    63
    Вывел формулу для получения адреса инструкции прерваной функции, что мне и требовалось
    WinDbg рулит :)
    Кто участвовал, спасибо за внимание и подсказки )

    Код (Text):
    1. dd poi( poi(pETHREAD + ulOffset_KTHREAD_KernelStack) + 0x0C) + 0x04 l1
    Тест:
     
  7. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    0x56
    Что рулит ?, отладчик ?
    Под ним ты получишь совсем другие результаты, я вообще не пользуюсь отладкой, дизассемблированное ядро рулит - лучшей проверки не придумать. Дизассемблируеш функции работы с контекстом и получаеш ответы на вопросы, а отладка - ненадёжный способ.
     
  8. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Хы.. Реальная ОС - всмысле варя ?
     
  9. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Clerk
    исходники есть:)
     
  10. Clerk

    Clerk Забанен

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