NtTerminateThread, id процесса

Тема в разделе "WASM.NT.KERNEL", создана пользователем n2, 19 ноя 2011.

  1. n2

    n2 New Member

    Публикаций:
    0
    Регистрация:
    5 авг 2011
    Сообщения:
    26
    Код (Text):
    1. NTSTATUS NewNtTerminateThread (
    2. IN HANDLE ThreadHandle,
    3. IN NTSTATUS ExitStatus )
    4. {
    5. ULONG ProcessId;
    6. THREAD_BASIC_INFORMATION threadbuff;
    7. NtQueryInformationThread(ThreadHandle,0,&threadbuff,sizeof(threadbuff),0);
    8. ProcessId =threadbuff.ClientId.UniqueProcess;
    9. if (ProcessId==(HANDLE)1004)
    10. {
    11.     return STATUS_ACCESS_DENIED;
    12. } else
    13. return TrueNtTerminateThread(ThreadHandle,ExitStatus);
    14. };
    Не работает и хоть убейся, уже месяц не могу заставить проверять ИД процесса-владельца. Путаюсь в указателях, исправьте, пожалуйста.
     
  2. n2

    n2 New Member

    Публикаций:
    0
    Регистрация:
    5 авг 2011
    Сообщения:
    26
    Да, суть кода должна быть таковой:есть хендл потока, по нему нужно получить ИД процесса-владельца и, если он равен 1004, то не дать завершить.
    NTSTATUS NtQueryInformationThread(
    __in HANDLE ThreadHandle,
    __in THREADINFOCLASS ThreadInformationClass,
    __inout PVOID ThreadInformation,
    __in ULONG ThreadInformationLength,
    __out_opt PULONG ReturnLength
    );
    typedef struct _THREAD_BASIC_INFORMATION {
    NTSTATUS ExitStatus;
    PVOID TebBaseAddress;
    CLIENT_ID ClientId;
    KAFFINITY AffinityMask;
    KPRIORITY Priority;
    KPRIORITY BasePriority;
    } THREAD_BASIC_INFORMATION, *PTHREAD_BASIC_INFORMATION;
     
  3. x64

    x64 New Member

    Публикаций:
    0
    Регистрация:
    29 июл 2008
    Сообщения:
    1.370
    Адрес:
    Россия
    n2
    Код у тебя правильный, не хватает только проверки результата вызова NtQueryInformationThread() и явного указания класса ThreadBasicInformation (хотя это и не обязательно, ибо этот класс и так равен 0, просто так нехорошо писать). Ну и в конце-концов: сам перехватчик-то вызывается вообще, проверял? К слову, я бы не стал так делать, я бы вызвал ObReferenceObjectByHandle(), чтобы получить указатель ETHREAD, и затем вызвал бы PsGetThreadProcessId() непосредственно для получения ID процесса, - так оверхед меньше.
     
  4. n2

    n2 New Member

    Публикаций:
    0
    Регистрация:
    5 авг 2011
    Сообщения:
    26
    А как проверить-то?

    Начались проблемы:Page Fault in nonepaged area. Вылетает при установке больше трёх перехватов..
    Код (Text):
    1. ULONG GetPid(HANDLE ProcessHandle)
    2. {
    3.     PEPROCESS process = 0;
    4.     ULONG pId;
    5.     ULONG pIdOffset=0x084;
    6.     ObReferenceObjectByHandle(ProcessHandle, 0, NULL, UserMode, &process, NULL);
    7.         pId = *(PULONG)(((ULONG)process) + pIdOffset);
    8.         ObDereferenceObject(process);
    9.         return pId;
    10. };
    11.  
    12.        
    13.  
    14. //функция - обработчик перехватаv
    15. NTSTATUS NewNtTerminateThread (
    16. IN HANDLE ThreadHandle,
    17. IN NTSTATUS ExitStatus )
    18. {
    19. ULONG ProcessId;
    20. THREAD_BASIC_INFORMATION threadbuff;
    21. NtQueryInformationThread(ThreadHandle,0,&threadbuff,sizeof(threadbuff),0);
    22.  DbgPrint("TryingNtTerminateThread with pid");
    23.  __try
    24.     {
    25.         ProcessId =threadbuff.ClientId.UniqueProcess;
    26.     }
    27.     __except(EXCEPTION_EXECUTE_HANDLER)
    28.     {
    29.        
    30.         return STATUS_INVALID_PARAMETER;
    31.     };
    32.  
    33. if (ProcessId==(HANDLE)888)
    34. {
    35.     return STATUS_ACCESS_DENIED;
    36. } else
    37. return TrueNtTerminateThread(ThreadHandle,ExitStatus);
    38. };
    39.  
    40. NTSTATUS NewNtOpenThread(
    41.   __out  PHANDLE ThreadHandle,
    42.   __in   ACCESS_MASK DesiredAccess,
    43.   __in   POBJECT_ATTRIBUTES ObjectAttributes,
    44.   __in   PCLIENT_ID ClientId
    45. ) {
    46.     ULONG ProcessId;
    47.     __try {
    48.     ProcessId = ClientId->UniqueProcess;
    49.     }
    50.     __except(EXCEPTION_EXECUTE_HANDLER)
    51.     {      
    52.         return STATUS_INVALID_PARAMETER;
    53.     };
    54.  
    55.     if (ProcessId == (HANDLE)888) {
    56.         return STATUS_ACCESS_DENIED;
    57.     } else
    58.     return TrueNtOpenThread(ThreadHandle,DesiredAccess,ObjectAttributes,ClientId);
    59. };
    60.  
    61. NTSTATUS NewNtWriteVirtualMemory (
    62. IN HANDLE ProcessHandle,
    63. IN PVOID BaseAddress,
    64. IN PVOID Buffer,
    65. IN ULONG NumberOfBytesToWrite,
    66. OUT PULONG NumberOfBytesWritten OPTIONAL ) {
    67.     if (GetPid(ProcessHandle)==(HANDLE)888) {
    68.     return STATUS_ACCESS_DENIED;
    69.     } else
    70. return TrueNtWriteVirtualMemory (
    71.                                  ProcessHandle,
    72.                                  BaseAddress,
    73.                                  Buffer,
    74.                                  NumberOfBytesToWrite,
    75.                                  NumberOfBytesWritten);
    76. };
     
  5. x64

    x64 New Member

    Публикаций:
    0
    Регистрация:
    29 июл 2008
    Сообщения:
    1.370
    Адрес:
    Россия
    Что!?
    Ой, не доводи до греха.
    Бряк в отладчике или вывод туда же.

    Дамп выкладывай.
    Желательно с Kernel Memory.
    Код ужасный, просто слов нет.
     
  6. n2

    n2 New Member

    Публикаций:
    0
    Регистрация:
    5 авг 2011
    Сообщения:
    26
    А чем код-то ужасен? Дамп выложу чуть позже, сейчас нет доступа к тому ПК.
     
  7. shchetinin

    shchetinin Member

    Публикаций:
    0
    Регистрация:
    27 май 2011
    Сообщения:
    715
    ULONG GetPid(HANDLE ProcessHandle)
    {
    PEPROCESS process = 0;
    ULONG pId;
    ULONG pIdOffset=0x084;
    ObReferenceObjectByHandle(ProcessHandle, 0, NULL, UserMode, &process, NULL);
    pId = *(PULONG)(((ULONG)process) + pIdOffset);
    ObDereferenceObject(process);
    return pId;
    };

    Это первая и сразу ужастная функция ...
    Почему бы не написать что то вроде

    Код (Text):
    1. NTSTATUS GetPid( IN HANDLE ProcessHandle, OUT PULONG lpPid)
    2. {
    3.     NTSTATUS    Status;
    4.     PEPROCESS   process    = 0;
    5.     const ULONG pIdOffset = 0x084;
    6.    
    7.  
    8.     *lpPid = 0;
    9.  
    10.     Status = ObReferenceObjectByHandle(ProcessHandle, 0, NULL, KeGetPreviousMode(), &process, NULL)
    11.  
    12.     if ( NTSUCCESS( Status )  )
    13.     {
    14.         *lpPid = *(PULONG)(((ULONG)process) + pIdOffset);
    15.         ObDereferenceObject(process);      
    16.     }
    17.          //DbgPrint value of Status
    18.     return Status;
    19. };
     
  8. x64

    x64 New Member

    Публикаций:
    0
    Регистрация:
    29 июл 2008
    Сообщения:
    1.370
    Адрес:
    Россия
    К сожалению, твой вариант не намного лучше, ибо есть PsGetProcessId().
     
  9. yugeniy

    yugeniy New Member

    Публикаций:
    0
    Регистрация:
    19 ноя 2011
    Сообщения:
    1
    да с PsGetProcessId() намного эффективней
     
  10. n2

    n2 New Member

    Публикаций:
    0
    Регистрация:
    5 авг 2011
    Сообщения:
    26
    А так?
    Код (Text):
    1. NTSTATUS NewNtTerminateThread (
    2. IN HANDLE ThreadHandle,
    3. IN NTSTATUS ExitStatus )
    4. {
    5.     int id;
    6.     PETHREAD thread=0;
    7.     ObReferenceObjectByHandle(ThreadHandle,0, *PsProcessType, KernelMode, (PVOID*)&thread, NULL);
    8.     id=(int)PsGetThreadProcessId(thread);
    9.     DbgPrint("TerminateThread");
    10.     DbgPrint(id);
    11. return TrueNtTerminateThread(ThreadHandle,ExitStatus);
    12. };
     
  11. shchetinin

    shchetinin Member

    Публикаций:
    0
    Регистрация:
    27 май 2011
    Сообщения:
    715
    x64
    Согласен провмыкал, я больше про оформление сорсов
     
  12. x64

    x64 New Member

    Публикаций:
    0
    Регистрация:
    29 июл 2008
    Сообщения:
    1.370
    Адрес:
    Россия
    В этом коде ошибка почти в каждой строчке, надо так:

    Код (Text):
    1. NTSTATUS
    2. NewNtTerminateThread (
    3.  
    4.     IN HANDLE ThreadHandle,
    5.     IN NTSTATUS ExitStatus)
    6.  
    7. {
    8.     ULONG uPid = 0;
    9.     PETHREAD thread = NULL;
    10.     NTSTATUS status = STATUS_UNSUCCESSFUL;
    11.  
    12.     //
    13.     // Получаем адрес объекта-потока. Маску доступа
    14.     // можно не указывать, т.к. иначе вызов может завершиться
    15.     // неудачей при отсутствии требуемых прав у объекта.
    16.     //
    17.  
    18.     status = ObReferenceObjectByHandle (
    19.         ThreadHandle,
    20.         THREAD_QUERY_INFORMATION,
    21.         *PsThreadType,
    22.         KernelMode,
    23.         (PVOID*) &thread,
    24.         NULL);
    25.  
    26.     if (! NT_SUCCESS (status))
    27.     {
    28.         //
    29.         // Обработка ошибок.
    30.         //
    31.     }
    32.  
    33.     //
    34.     // Получаем ID процесса для указанного потока.
    35.     //
    36.  
    37.     uPid = (ULONG) PsGetThreadProcessId (
    38.         thread);
    39.  
    40.     //
    41.     // Освобождаем объект потока ибо не нужен более.
    42.     //
    43.  
    44.     ObDereferenceObject (
    45.         thread);
    46.  
    47.     //
    48.     // Пишем ID процесса в отладочный вывод.
    49.     //
    50.  
    51.     DbgPrint (
    52.         "MYDRV: TerminateThread() called, Process ID = %u\n",
    53.         uPid);
    54.  
    55.     //
    56.     // Вызов оригинальной функции или следующего обработчика в цепочке.
    57.     //
    58.  
    59.     return TrueNtTerminateThread (
    60.         ThreadHandle,
    61.         ExitStatus);
    62. }
     
  13. shchetinin

    shchetinin Member

    Публикаций:
    0
    Регистрация:
    27 май 2011
    Сообщения:
    715
    x64
    А почему нет деревенса? и почему KernelMode?
     
  14. x64

    x64 New Member

    Публикаций:
    0
    Регистрация:
    29 июл 2008
    Сообщения:
    1.370
    Адрес:
    Россия
    Забыл, да.
    Код обновил.
    Вот почему я не люблю "бумажные" собеседования ;)

    Здесь заметка:

    Ну это зависит от целей перехвата вообще. Если нужно эмулировать клиента, то лучше здесь указать ExGetPreviousMode(), а если на клиента пофиг и нужно во что бы то ни стало получить доступ к объекту, обойдя проверки доступа, то лучше KernelMode указывать.
     
  15. n2

    n2 New Member

    Публикаций:
    0
    Регистрация:
    5 авг 2011
    Сообщения:
    26
    x64, благодарю, сейчас попробую. И почему же в каждой строке ошибка? Да, я не проверял статус и т.д., ибо это уже не так важно, как сам факта рабочей функции.