- •Лабораторная работа №5. Перехват системных сервисов Цель работы
- •Драйвер-фильтр вызовов системных сервисов.
- •Модификация диалоговой прикладной программы управления драйверами для тестирования драйвера перехвата системных сервисов
- •Пояснения
- •1. Работа с таблицей системных сервисов
- •2. Получение имени текущего процесса
- •Лабораторная работа №6. Получение копии адресного пространства указанного процесса
- •Драйвер-фильтр получения копии адресного пространства на уровне vaDи на уровне каталога-таблиц страниц.
- •Модификация диалоговой прикладной программы управления драйверами для тестирования драйвера получения копии адресного пространства
- •Пояснения
- •1. Получение списка процессов:
- •2, 3. Получение адреса структуры peBпоPid, переключение адресного пространства на нужный процесс по егоPiDс помощью недокументированных функцийKeAttachProcess()/KeDetachProcess()
- •4. Работа с деревом виртуальных адресных дескрипторов процесса (vad): получение снимка адресного пространства на уровнеVad
- •5. Работа с каталогом страниц (см. Также п.11.3 в документации “PentiumProcessor.Pdf”):
- •6. Работа с файлами на уровне драйвера
Пояснения
1. Получение списка процессов:
Использовать функцию NtQuerySystemInformation() (см. описание ZwQuerySystemInformation в “Windows NT Native API.pdf”):
struct ThreadInfo
{
FILETIME ftCreationTime;
DWORD dwUnknown1;
DWORD dwStartAddress;
DWORD dwOwningPID;
DWORD dwThreadID;
DWORD dwCurrentPriority;
DWORD dwBasePriority;
DWORD dwContextSwitches;
/*THREAD_STATE*/DWORD ThreadState;
/*KWAIT_REASON*/DWORD WaitReason;
DWORD dwUnknown3;
DWORD dwUnknown4;
DWORD dwUnknown5;
DWORD dwUnknown6;
DWORD dwUnknown7;
};
struct ProcessInfo
{
DWORD dwOffset; // an offset to the next Process structure
DWORD dwThreadCount;
DWORD dwUnknown1[6];
FILETIME ftCreationTime; //LARGE_INTEGER CreateTime; DWORD low, DWORD high
DWORD dwUnknown2;
DWORD dwUnknown3; //LARGE_INTEGER UserTime
DWORD dwUnknown4;
DWORD dwUnknown5; //LARGE_INTEGER KernelTime
DWORD dwUnknown6;
WCHAR* pszProcessName;
DWORD dwBasePriority;
DWORD dwProcessID; //PID !!!
DWORD dwParentProcessID;
DWORD dwHandleCount;
DWORD dwUnknown7;
DWORD dwUnknown8;
DWORD dwVirtualBytesPeak;
DWORD dwVirtualBytes;
DWORD dwPageFaults;
DWORD dwWorkingSetPeak;
DWORD dwWorkingSet;
DWORD dwUnknown9; //QuotaPeakPagedPoolUsage
DWORD dwPagedPool; // kbytes
DWORD dwUnknown10; //QuotaPeakNonPagedPoolUsage
DWORD dwNonPagedPool; // kbytes
DWORD dwPageFileBytesPeak;
DWORD dwPageFileBytes;
DWORD dwPrivateBytes;
DWORD dwUnknown11;
DWORD dwUnknown12;
DWORD dwUnknown13;
DWORD dwUnknown14;
struct ThreadInfo ati[1];
};
void qsi5()
{
DWORD rv;
DWORD offset = 0;
DWORD bsize = BLOCK_SIZE;
if(qsi_05_buf!=NULL)
delete[] qsi_05_buf;
qsi_05_buf = new unsigned char[bsize];
memset(qsi_05_buf, 0, bsize);
rv = NtQuerySystemInformation(5, qsi_05_buf, bsize, &offset);
//spf("rv = %08lx, offset = %08lx", rv, offset );
while(rv!=0)
{
delete[] qsi_05_buf;
bsize += BLOCK_SIZE;
qsi_05_buf = new unsigned char[bsize];
rv = NtQuerySystemInformation(5, qsi_05_buf, bsize, &offset);
// spf("rv = %08lx, offset = %08lx", rv, offset );
}
}
2, 3. Получение адреса структуры peBпоPid, переключение адресного пространства на нужный процесс по егоPiDс помощью недокументированных функцийKeAttachProcess()/KeDetachProcess()
HANDLE h;
ACCESS_MASK access = PROCESS_ALL_ACCESS;
OBJECT_ATTRIBUTES attr;
CLIENT_ID client_id;
NTSTATUS stat;
PVOID peb;
OBJECT_HANDLE_INFORMATION h_inf;
//получаем хэндл выбранного процесса по егоpid
InitializeObjectAttributes(&attr, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);
client_id.UniqueProcess = pid;
client_id.UniqueThread = 0;//tid;
stat = ZwOpenProcess(&h, access, &attr , &client_id);
if(STATUS_SUCCESS != stat)
{
DbgPrint("SetInterrupt (ZwOpenProcess): stat=%lx\n", stat);
return 0;
}
DbgPrint("ZwOpenProcess - OK...\n");
//получаем указатель наpebпо хэндлу процесса
stat = ObReferenceObjectByHandle(h, access, NULL, KernelMode, &peb, &h_inf);
if(STATUS_SUCCESS != stat)
{
DbgPrint("SetInterrupt (ObReferenceObjectByHandle): stat=%lx\n", stat);
ZwClose(h);
return 0;
}
DbgPrint("ObReferenceObjectByHandle - OK... peb = %lx\n ", peb);
//меняем текущее адресное пространство на адр. пр-во выбранного процесса
stat = KeAttachProcess(peb);
if(STATUS_SUCCESS != stat)
{
DbgPrint("SetInterrupt (KeAttachProcess): stat=%lx\n", stat);
ZwClose(h);
return 0;
}
DbgPrint("KeAttachProcess - OK...\n");
//работаем в адресном пространстве “чужого” процесса
stat = KeDetachProcess();
if(STATUS_SUCCESS != stat)
{
DbgPrint("SetInterrupt: stat=%lx\n", stat);
ZwClose(h);
return 0;
}
DbgPrint("KeDetachProcess - OK...\n");
ZwClose(h);