Сплайсинг ZwTerminateProcess

Тема в разделе "WASM.NT.KERNEL", создана пользователем shinigami1, 8 апр 2010.

  1. shinigami1

    shinigami1 New Member

    Публикаций:
    0
    Регистрация:
    29 мар 2010
    Сообщения:
    22
    Прочитал цикл статей про сплайсинг, решил попробовать с ZwTermnateProcess, но почему-то не работает код:

    Код (Text):
    1. typedef struct TermProcessCode
    2. {
    3.    
    4.     UCHAR First;
    5.     PVOID  Next;
    6.     UCHAR  Last;
    7.    
    8. } OldTerminateProcessCode , *pOldTerminateProcessCode;
    9.  
    10. typedef struct Jm
    11. {
    12.             UCHAR Jmp;
    13.      PVOID Adress;
    14. } JmpOp , *pJmpOp;
    15.  
    16. PVOID NewTerminateProcessAddr;
    17. OldTerminateProcessCode OldCode;
    18. UNICODE_STRING ToHook;
    19. ............................
    20. ............................
    21. RtlInitUnicodeString(&ToHook,L"ZwTerminateProcess");
    22. ..........................
    23.  
    24. VOID HOOK()
    25. {
    26.  
    27.     pOldTerminateProcessCode    OriginalCode;
    28.     pJmpOp                              NewCode;
    29.     ULONG CR0Reg;
    30.  
    31.    
    32.      OriginalCode = (pOldTerminateProcessCode)MmGetSystemRoutineAddress(&ToHook);
    33.      NewCode      = (pJmpOp) MmGetSystemRoutineAddress(&ToHook);
    34.  
    35.      if(OriginalCode == NULL || NewCode == NULL)
    36.      {
    37.          DbgPrint ("ERROR INCORRECT ADDR\n");
    38.            
    39.          return STATUS_UNSUCCESSFUL;
    40.     }
    41.  
    42.      NewTerminateProcessAddr = MyFunc;
    43.  
    44.   __try
    45.   {
    46.         __asm
    47.        {
    48.                  
    49.       cli                    
    50.       mov eax, cr0
    51.       mov CR0Reg,eax
    52.       and eax,0xFFFEFFFF      
    53.       mov cr0, eax
    54.        }
    55.    
    56.         OldCode.First   =  OriginalCode->FirstPart;
    57.         OldCode.Next   =  OriginalCode->TwoPart;
    58.         OldCode.Last   =  OriginalCode->NextPart;
    59.            
    60.                      
    61.          NewCode->Jmp = 0xE9; // jmp
    62.          NewCode->Adress =  NewTerminateProcessAddr;
    63.              
    64.        __asm
    65.       {
    66.                 mov eax, CR0Reg    
    67.                 mov cr0, eax        
    68.                 sti                    
    69.        }
    70.  
    71.        return STATUS_SUCCESS;
    72.   }
    73.  
    74.    __except(EXCEPTION_EXECUTE_HANDLER)  
    75.    {
    76.         return STATUS_UNSUCCESSFUL;
    77.    }
    78. }
    Это сам хук, видимо что-то неправильно в нём, потому что код моей ф-ции не выполняется. Посмотрите пожайлуста.
     
  2. shinigami1

    shinigami1 New Member

    Публикаций:
    0
    Регистрация:
    29 мар 2010
    Сообщения:
    22
    Код (Text):
    1. typedef struct TermProcessCode
    2. {
    3.    
    4.     UCHAR First;
    5.     PVOID  Next;
    6.     UCHAR  Last;
    7.    
    8. } OldTerminateProcessCode , *pOldTerminateProcessCode;
    9.  
    10. typedef struct Jm
    11. {
    12.     UCHAR Jmp;
    13.     PVOID Adress;
    14.  
    15. } JmpOp , *pJmpOp;
    16.  
    17. PVOID NewTerminateProcessAddr;
    18. OldTerminateProcessCode OldCode;
    19. UNICODE_STRING ToHook;
    20. ............................
    21. ............................
    22. RtlInitUnicodeString(&ToHook,L"ZwTerminateProcess");
    23. ..........................
    24.  
    25. NTSTATUS HOOK()
    26. {
    27.  
    28.     pOldTerminateProcessCode    OriginalCode;
    29.     pJmpOp                              NewCode;
    30.     ULONG CR0Reg;
    31.  
    32.    
    33.      OriginalCode = (pOldTerminateProcessCode)MmGetSystemRoutineAddress(&ToHook);
    34.      NewCode      = (pJmpOp) MmGetSystemRoutineAddress(&ToHook);
    35.  
    36.      if(OriginalCode == NULL || NewCode == NULL)
    37.      {
    38.          DbgPrint ("ERROR INCORRECT ADDR\n");
    39.            
    40.          return STATUS_UNSUCCESSFUL;
    41.     }
    42.  
    43.      NewTerminateProcessAddr = MyFunc;
    44.  
    45.   __try
    46.   {
    47.         __asm
    48.        {
    49.                  
    50.       cli                    
    51.       mov eax, cr0
    52.       mov CR0Reg,eax
    53.       and eax,0xFFFEFFFF      
    54.       mov cr0, eax
    55.        }
    56.    
    57.         OldCode.First   =  OriginalCode->FirstPart;
    58.         OldCode.Next   =  OriginalCode->TwoPart;
    59.         OldCode.Last   =  OriginalCode->NextPart;
    60.            
    61.                      
    62.          NewCode->Jmp = 0xE9; // jmp
    63.          NewCode->Adress =  NewTerminateProcessAddr;
    64.              
    65.        __asm
    66.       {
    67.                 mov eax, CR0Reg    
    68.                 mov cr0, eax        
    69.                 sti                    
    70.        }
    71.  
    72.        return STATUS_SUCCESS;
    73.   }
    74.  
    75.    __except(EXCEPTION_EXECUTE_HANDLER)  
    76.    {
    77.         return STATUS_UNSUCCESSFUL;
    78.    }
    79. }
    Фиксед
     
  3. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    shinigami1
    Разумно спросить варианты решения задачи, а не проблемы решения которое вы нашли, ибо оно не лучшее :)
    Итак по порядку.
    1. Отключение аппаратной защиты страниц, сбросом бата WP. Ваш код юзается на нулевом IRQL, это значит что память выгружаемая, а обработчик может быть где угодно(хотя нормально секции кода ядра не свопятся). Более того, вы запрещеате прерывания, а это эквиваленнтно высочайшему уровню IRQL(0xFF). Посему всегда обращайтесь к памяти перед подобной манипуляцией(перед Cli), просто попыткой чтения её. Иначе это может вызвать крах.
    2.
    Это относительное ветвление, а не абсолютное(Far), посему следует записать смещение относительно инструкции, а не относительно базы сегмента.
    3. Атомарно изменяйте код посредством lock cmpxchg8b. Иначе иной поток(на другом камне) может выполнить не до конца изменённую инструкцию, что приведёт к краху.
     
  4. shinigami1

    shinigami1 New Member

    Публикаций:
    0
    Регистрация:
    29 мар 2010
    Сообщения:
    22
    Clerk, а адрес процедуры я правильно получаю? Просто у меня такое ощущение что я вообще пишу чёрт знает куда, ибо ни бсодов ни соощений debugview не наблюдается
     
  5. shinigami1

    shinigami1 New Member

    Публикаций:
    0
    Регистрация:
    29 мар 2010
    Сообщения:
    22
    *адрес функции
     
  6. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    shinigami1
    Говрю ведь что не правильно, #2.
    Displacement = BranchAddress - $ - 5
     
  7. shinigami1

    shinigami1 New Member

    Публикаций:
    0
    Регистрация:
    29 мар 2010
    Сообщения:
    22
    Понял, попробую реализовать все рекомендации.

    з.ы. На семёрке как я понял сплайсинг единственный способ перехвата Api ядра?
     
  8. Clerk

    Clerk Забанен

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

    shinigami1 New Member

    Публикаций:
    0
    Регистрация:
    29 мар 2010
    Сообщения:
    22
    Код (Text):
    1. _declspec(dllimport)
    2. NTSTATUS   ZwTerminateProcess
    3. (
    4.            IN HANDLE  ProcessHandle,
    5.            IN NTSTATUS  ExitStatus
    6.  );
    7.  
    8.  
    9. PVOID OrigFuncAddres =&ZwTerminateProcess;
    10. .......................
    11.  
    12.  
    13. NTSTATUS HOOK()
    14. {
    15.  
    16.     pOldTerminateProcessCode    OriginalCode;
    17.     pJmpOp                              NewCode;
    18.     ULONG CR0Reg;
    19.  
    20.      OriginalCode = (pOldTerminateProcessCode)OrigFunction;
    21.      NewCode      = (pJmpOp) OrigFunction;
    22.  
    23.   __try
    24.   {
    25.        OrigFuncAddres =&ZwTerminateProcess;
    26.  
    27.         __asm
    28.        {
    29.                  
    30.       cli                    
    31.       mov eax, cr0
    32.       mov CR0Reg,eax
    33.       and eax,0xFFFEFFFF      
    34.       mov cr0, eax
    35.        }
    36.    
    37.         OldCode.First   =  OriginalCode->FirstPart;
    38.         OldCode.Next   =  OriginalCode->TwoPart;
    39.         OldCode.Last   =  OriginalCode->NextPart;
    40.            
    41.                      
    42.          NewCode->Jmp = 0xE9; // jmp
    43.          NewCode->Adress =  (PVOID) ((ULONG)NewZwTerminateProcessAddr-(ULONG)OrigFuncAddres-5);
    44.              
    45.        __asm
    46.       {
    47.                
    48.                        mov eax, CR0Reg    
    49.                        mov cr0, eax        
    50.                        sti                    
    51.        }
    52.  
    53.        return STATUS_SUCCESS;
    54.   }
    55.  
    56.    __except(EXCEPTION_EXECUTE_HANDLER)  
    57.    {
    58.         return STATUS_UNSUCCESSFUL;
    59.    }
    60. }
    Немного подправил, всё равно не переходит на мою ф-цию, мне кажется что я адрес ZwTerminateProcess неправильно получаю.
     
  10. Clerk

    Clerk Забанен

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

    shinigami1 New Member

    Публикаций:
    0
    Регистрация:
    29 мар 2010
    Сообщения:
    22
    Вы хотели сказать в импорте?
     
  12. Clerk

    Clerk Забанен

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

    shinigami1 New Member

    Публикаций:
    0
    Регистрация:
    29 мар 2010
    Сообщения:
    22
    Я проверил, он одинаковый
     
  14. shinigami1

    shinigami1 New Member

    Публикаций:
    0
    Регистрация:
    29 мар 2010
    Сообщения:
    22
    *одинаковый адрес через и импорт и через MmGetSystemRoutineAddress()
     
  15. Clerk

    Clerk Забанен

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

    shinigami1 New Member

    Публикаций:
    0
    Регистрация:
    29 мар 2010
    Сообщения:
    22
    80500688 (в 16 системе) и через - MmGetSystemRoutineAddress() и через &ZwTerminateProcess
     
  17. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    shinigami1
    На какой адрес необходимо выполнить переход и какое смещение записано ?
     
  18. shinigami1

    shinigami1 New Member

    Публикаций:
    0
    Регистрация:
    29 мар 2010
    Сообщения:
    22
    вот же ->

    Код (Text):
    1.  NewCode->Adress =  (PVOID) ((ULONG)NewZwTerminateProcessAddr-(ULONG)OrigFuncAddres-5);
    Где -> NewZwTerminateProcessAddr = MyFunction; , адрес моей ф-ции.
     
  19. Clerk

    Clerk Забанен

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

    shinigami1 New Member

    Публикаций:
    0
    Регистрация:
    29 мар 2010
    Сообщения:
    22
    с отладчиком тоже трабл есть, softice к сожалению никак не хочет работать - при запуске ntice.bat выдаёт

    System error 1058 has occurred.

    The service cannot be started, either because it is disabled or because it has no enabled devices ssociated with it.