Значится, дело происходит в ring0. Перехват NtProtectVirtualMemory. Долго мучался, но никак не могу получить ID процесса по его хендлу. Постоянно получается ошибка Access Violation (0xC0000005). Вот код: NTSTATUS NewNtProtectVirtualMemory( IN HANDLE ProcessHandle, IN OUT PVOID *BaseAddress, IN OUT PSIZE_T RegionSize, IN ULONG NewProtect, OUT PULONG OldProtect ) { PEPROCESS pEproc; ULONG calledByPid, calledForPid, i; PROCESS_BASIC_INFORMATION pbi; NTSTATUS s; pEproc = IoGetCurrentProcess(); calledByPid = *(PULONG)((ULONG)pEproc + pIdOffset); if ((ULONG)ProcessHandle == 0xFFFFFFFF) { return TrueNtProtectVirtualMemory(ProcessHandle, BaseAddress, RegionSize, NewProtect, OldProtect); } s = NtQueryInformationProcess(ProcessHandle, 0, &pbi, sizeof(PROCESS_BASIC_INFORMATION), 0); DPRINT("NtQueryInformationProcess NTSTATUS: %08X FOR HANDLE %08X\n", (ULONG)s, (ULONG)ProcessHandle); DPRINT("PUniqueId: %08X\n", (ULONG)pbi.UniqueProcessId);
Так как в обработчике NewNtProtectVirtualMemory PerivousMode будет равно UserMode, то вызываемые API будут требовать расположения своих параметров в юзермодной памяти. В данном случае можно либо замапить кусок памяти в юзермод (через MDL), либо использовать воркитемы, либо вместо NtQueryInformationProcess сделать ObReferenceObjectByHandle и извлечь pid из EPROCESS.
Не поможет, так как он вызывает тотже NtQueryInformationProcess, но только не напрямую, а через KiSystemService.
Извини, Ms Rem, но ты неправ. При вызове функции через KiSystemService из ядра PreviuosMode на время вызова функции устанавливается в KernelMode, и можно использовать драйверную память под параметры. Посмотри сырцы виндов- там это чётко написано.
//------------------------------------------------------ NTSTATUS ArtificialZwTerminateProcess(IN HANDLE ProcessHandle, IN NTSTATUS ExitStatus) { PVOID pObject = NULL; POBJECT_HANDLE_INFORMATION HandleInformaton = NULL; UNICODE_STRING fNameU; if (ProcessHandle == 0) { if ((ProcessIdToHide == PsGetCurrentProcessId()) && (SetHideProcess)) return STATUS_ACCESS_DENIED; } if (NT_SUCCESS(ObReferenceObjectByHandle(ProcessHandle,FILE_ANY_ACCESS,NU LL,KernelMode,&pObject,NULL))) { ObDereferenceObject(pObject); RtlInitUnicodeString(&fNameU,L"PsGetProcessId"); if ((ProcessIdToHide == ((PVOID)((NTPROC)MmGetSystemRoutineAddress(&fNameU))(pObject))) && (SetHideProcess)) return STATUS_ACCESS_DENIED; } return TrueZwTerminateProcess(ProcessHandle, ExitStatus); } //------------------------------------------------------ тупо, но примерно так и можно получить твой процид.)