在驱动中注册进程回调函数PsSetCreateProcessNotifyRoutine后,如果进程创建或退出的时候都应该进入相应的回调函数,我在回调函数中通过PsGetCurrentProcess()获取进程的信息结构体指针PEPROCESS,然后通过偏移找到PEB结构,最后直接从ImagePathName取进程的全路径,代码如下:void GetProcessInfo(
IN HANDLE ParentId,
IN HANDLE ProcessId,
IN PWCHAR pro_imageName_buf,
IN PWCHAR pro_full_path_buf )
{
ULONG addr = 0;
PEPROCESS EProcess;
PWCHAR p = NULL;
KAPC_STATE apc_state;
NTSTATUS status = STATUS_SUCCESS;
EProcess = PsGetCurrentProcess();
//status = PsLookupProcessByProcessId( ProcessId, &EProcess );
//if ( !NT_SUCCESS(status) )
//{
//return;
//}
addr = (ULONG ) EProcess;
if(addr == 0 || addr == 0xFFFFFFFF)
{
return;
}
//附加到该进程
//KeStackAttachProcess( EProcess, &apc_state );
//addr是EPROCESS中PEB*成员的地址
addr += 0x1B0;
//addr是PEB*
if((addr = *(ULONG*)addr) == 0)
{
//KeUnstackDetachProcess( &apc_state );
return;
}
//addr是PEB中的ProcessParameters
addr += 0x10;
if((addr = *(ULONG*)addr) == 0)
{
//KeUnstackDetachProcess( &apc_state );
return;
}
addr += 0x3C;
//addr是ImagePathName(UNICODE_STRING)
if((addr = *(ULONG*)addr) == 0)
{
//KeUnstackDetachProcess( &apc_state );
return ;
}
wcscpy(pro_full_path_buf,(PWCHAR)addr);
if( (p = wcsrchr(pro_full_path_buf,L'\\')) != NULL)
{
p++;
wcscpy(pro_imageName_buf,p);
}
//KeUnstackDetachProcess( &apc_state );
}
起初的时候,没有用到KeStackAttachProcess,最后发现打开记事本的时候,应该创建的是notepad.exe,但是通过上面程序得到的全路径却是C:\WINDOWS\Explorer.EXE,但是退出记事本的时候,通过上面程序获取的是C:\WINDOWS\system32\notepad.exe。这个应该是线程上下文导致,要用KeStackAttachProcess类似的函数附加到进程,但是附加后还是没作用。
后来,继续实验的时候,发现PsSetCreateProcessNotifyRoutine和PsGetCurrentProcess针对同一次进程回调,结果返回的EPROCESS指针的数值是不一样的。
为什么会出现这样的情况呢?如何才可以获取到真正的进程名呢?希望有人可以指点下。
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课