Здарова мужики! я закалустался получать эту стуктуру. пишу драйвер, в нем пытаюсь получить указатель на PEB. скачал с мелкософта ntoskrnl.pdb для xp (скачивал для sp2, блин - на сколько помню). С помощью pdbdump'а получил файл со структурами, в том числе и EPROCESS, KPROCESS и PEB. Тестю драйвер на виртуальной машине. На компе установлен xp3, на виртуальной машине xp2, отлаживаю с помощью windbg... получаю указатель на EPROCESS с помощью PsLookupProcessByProcessId. Смотрю что у меня показывает отладчик в структуре PEB - а там memory access error. Попробовал обратиться к полям этой структуры - конечно ничего хорошо не произошло, пришлось перезагружать виртуальную машину. Вот не пойму из-за чего. Может быть из-за того что смещение не правильно объявленно???? у меня вот: typedef struct _EPROCESS { ... /*<thisrel this+0x190>*/ /*|0x4|*/ struct _PEB* Peb; ... } EPROCESS, *PEPROCESS; подскажите, кто знает
Смещение уникально для каждой версии. Задавать такой вопрос без указания точной версии ядра бессмысленно. А вообще, как уже сказали, есть PsGetProcessPeb, ну или на худой конец ZwQueryInformationProcess (ProcessBasicInformation) : поле PebBaseAddress
вот рабочая функция и еще на счет: ...PEB - а там memory access error... уточнение сам указатель struct _PEB * Peb имеет значения, а вот его поля как раз содержат memory access error NTSTATUS DeviceControlRoutine( IN PDEVICE_OBJECT fdo, IN PIRP Irp ) NTSTATUS DeviceControlRoutine( IN PDEVICE_OBJECT fdo, IN PIRP Irp ) { NTSTATUS status = STATUS_SUCCESS; ULONG BytesTxd =0; PIO_STACK_LOCATION IrpStack=IoGetCurrentIrpStackLocation(Irp); PDEVICE_EXTENSION dx = (PDEVICE_EXTENSION)fdo->DeviceExtension; ULONG ControlCode = IrpStack->Parameters.DeviceIoControl.IoControlCode; ULONG method = ControlCode & 0x03; //KIRQL irql, //currentIrql = KeGetCurrentIrql(); #if DBG DbgPrint("-Example- In DeviceControlRoutine (fdo= %X)\n",fdo); DbgPrint("-Example- DeviceIoControl: IOCTL %x.", ControlCode ); //if(currentIrql==PASSIVE_LEVEL) // DbgPrint("-Example- PASSIVE_LEVEL (val=%d)",currentIrql); #endif switch( ControlCode) { #ifndef SMALL_VERSION case IOCTL_PROCESS: { PEPROCESS pEprocess, pEprocess0; PPEB Peb = NULL; DWORD InputLength = (DWORD)IrpStack->Parameters.DeviceIoControl.InputBufferLength; if (InputLength != sizeof(DWORD)) break; DWORD dwPID; dwPID = *((PDWORD)(Irp -> AssociatedIrp.SystemBuffer)); NTSTATUS s; s = PsLookupProcessByProcessId((HANDLE)dwPID, &pEprocess); if (!NT_SUCCESS(s)) { break; } dx->pEPROCESS = pEprocess; KAPC_STATE ApcState; KeStackAttachProcess((PKPROCESS)pEprocess, &ApcState); Peb = pEprocess->Peb; KeUnstackDetachProcess(&ApcState); break; } #endif default: status = STATUS_INVALID_DEVICE_REQUEST; } #if DBG DbgPrint("-Example- DeviceIoControl: %d bytes written.", (int)BytesTxd); #endif return CompleteIrp(Irp,status,BytesTxd); }
Он же в юзермодном адресном пространстве, нужно переключать адресное пространство, это системное ап общее. Само собой что в разных процессах адрес страницы PEB разный. Если из чужёго EPROCESS считать указатель на PEB и в текущем обращаться к нему, то вероятно что там страница не выделена, вот и экцепшин вылетает.
Так так так Значит PEB находится в адресном пространстве процесса??? я прально понял? просто думал что KeStackAttachProcess все сделает знаю что он редактирует регистр cr3 указывающий на католог страниц процесса... который отражается в моей голове пустым звуком ладно буду разбиратся с этим, спасибо - направил на путь праведный да и не подскажешь как загрузить в таком случае PEB?
Clerk Он же и так аттачнут о_0 Да, ты прав, keStackAttachProcess всё сделает. Memory access error - в чем смотришь, в WinDbg? Страница может быть выгружена, он такие смотреть не умеет.
>03:47:05 Great приятно видеть что не я один не могу спать спокойно да смотрю в Windbg Вот пытаюсь использовать MmGetSystemAddressForMdl и MmProbeAndLockPages: у Солдатова написано что он загружает по необходимости страницы, только без результатно.
Clerk А я не увидел обращений к пеб после детача. Где там? brainFucker То, что WinDbg показывает memory access error для участка памяти, _НЕ_ означает, что драйверу не получится к ней обратиться. Драйверам вообще-то тоже можно обращаться к подкачиваемой памяти. Правда, с условиями: код должен выолняться на IRQL < 2. Где у тебя вообще обращение к поням Peb? Не надо полагаться на вывод виндбг, просто напиши чтение любого поля (естественно, внутри блока Attach/Detach) и проверь. А то уже в мдл полез.. Не надо никаких MmProbe.../MmMap.../MmGetSystemAddress...
Clerk Ну вообще по-моему вроде как тоже нет. Я на всякий случай сказал. Ибо автор предоставляет маловато информации. PS. Посморел щас MiCreatePebOrTeb - вроде выделяется обычный VAD для частной страницы. Должно свопиться.
уже пробовал обртиться к полям PEB только на этот раз заключил в сех)) не работает все равно(( Код (Text): NTSTATUS DeviceControlRoutine( IN PDEVICE_OBJECT fdo, IN PIRP Irp ) { NTSTATUS status = STATUS_SUCCESS; ULONG BytesTxd =0; PIO_STACK_LOCATION IrpStack=IoGetCurrentIrpStackLocation(Irp); PDEVICE_EXTENSION dx = (PDEVICE_EXTENSION)fdo->DeviceExtension; ULONG ControlCode = IrpStack->Parameters.DeviceIoControl.IoControlCode; ULONG method = ControlCode & 0x03; //KIRQL irql, //currentIrql = KeGetCurrentIrql(); #if DBG DbgPrint("-Example- In DeviceControlRoutine (fdo= %X)\n",fdo); DbgPrint("-Example- DeviceIoControl: IOCTL %x.", ControlCode ); //if(currentIrql==PASSIVE_LEVEL) // DbgPrint("-Example- PASSIVE_LEVEL (val=%d)",currentIrql); #endif switch( ControlCode) { #ifndef SMALL_VERSION case IOCTL_PROCESS: { KIRQL irql = PASSIVE_LEVEL, currentIrql = KeGetCurrentIrql(); PVOID pVoid = NULL; PEPROCESS pEprocess, pEprocess0; PPEB Peb = NULL; DWORD InputLength = (DWORD)IrpStack->Parameters.DeviceIoControl.InputBufferLength; if (InputLength != sizeof(DWORD)) break; DWORD dwPID; dwPID = *((PDWORD)(Irp -> AssociatedIrp.SystemBuffer)); NTSTATUS s; s = PsLookupProcessByProcessId((HANDLE)dwPID, &pEprocess); if (!NT_SUCCESS(s)) { break; } dx->pEPROCESS = pEprocess; if (currentIrql != PASSIVE_LEVEL) { KeLowerIrql(irql); } KAPC_STATE ApcState; KeStackAttachProcess((PKPROCESS)pEprocess, &ApcState); Peb = pEprocess->Peb; __try { pVoid = Peb->ImageBaseAddress; } __except(EXCEPTION_EXECUTE_HANDLER) { #if DBG DbgPrint("Fuck!"); #endif } KeUnstackDetachProcess(&ApcState); if (currentIrql != PASSIVE_LEVEL) { KeRaiseIrql(currentIrql, &irql); } break; } #endif default: status = STATUS_INVALID_DEVICE_REQUEST; } #if DBG DbgPrint("-Example- DeviceIoControl: %d bytes written.", (int)BytesTxd); #endif return CompleteIrp(Irp,status,BytesTxd); }
Я уже n*10^m раз писал, что "не работает" - не описание ошибки. Не работает == выполняется сех? Или бсод? Или где. Специально для танкистов напоминаю про debug printы. Очень хорошее средство отладки. Замени на Код (Text): KAPC_STATE ApcState; KeStackAttachProcess((PKPROCESS)pEprocess, &ApcState); Peb = pEprocess->Peb; DbgPrint ("Attached to process %p, PEB %p\n", pEprocess, Peb); __try { DbgPrint("ImageBaseAddress = %p\n", Peb->ImageBaseAddress); } __except(EXCEPTION_EXECUTE_HANDLER) { DbgPrint("Got exception code %x\n", GetExceptionCode()); } KeUnstackDetachProcess(&ApcState); и покажи отладочный вывод PS. Это что еще за бред!??! Код (Text): if (currentIrql != PASSIVE_LEVEL) { KeLowerIrql(irql); } Нельзя насильно понижать IRQL ниже уровня вызова функции! Кто тебе этот кошмар подсказал? Тем более, что это здесь и не нужно. DriverDispatch всегда вызывается на IRQL достаточно низком для выполнения аттача.
от танкиста танкисту черт знает зачем вставил этот код Код (Text): if (currentIrql != PASSIVE_LEVEL) { KeLowerIrql(irql); } отчаялся наверное заменил на код предложенный Great вот что показывает отладчик