How to get a job from a given process in kernel?

Hi, everyone.

Does anybody know how to get PEJOB (or its handle) from a given EPROCESS?

Thanks in advance,

What are your trying to accomplish?

Let’s say you had a PEJOB. It’s an opaque structure (to drivers), isn’t it?

If you want job info, you can query for it… preferably in user mode.

Peter

I need to carry some context information tied to a given JOB. Processes that belong to that JOB should have their activities tracked.
I’m assuming I can wait for a JOB to complete using KeWaitForaSingleObject since I can do the same in user-mode.

Regards,

Hmmmm… You’ve read this, right… about when Job objects are signaled:

The job object becomes signaled only if the end-of-job time limit has been reached. If the processes exit without exceeding the time limit, then the job object remains unsignaled.

Sorry… I realize that’s not answering your question.

Peter

so you are planning to use the job pointer as a key into some other data structure to find this extra context that you need to carry? If that’s the case, you should be able to use the eprocess pointer for the same if your data structure can support multiple keys referring to a single value

the trick is to determine which job each process should fall into. That’s simple in UM, but I have no idea how to do it in KM

The relevant routine is PsGetProcessJob. It’s exported, but not documented. Also note that in the presence of Windows containers and/or Desktop App Bridge, some jobs are “silos” or “server silos” and there are a bunch of routines for interacting with those - PsGetJobSilo, PsRegisterSiloMonitor, etc. - which are “documented”, in the sense there are doc pages for them, although frankly they don’t say much.
Another thing to be aware of is that often a process is created and only later assigned to a job (using AssignProcessToJobObject in user mode). That means that in the Ps callback for process creation, it may not be a member of the job yet. A common pattern is to create a child process with the initial thread suspended, call AssignProcessToJobObject and then resume the initial thread. Once the initial thread is resumed, the PsSetLoadImageNotifyRoutine notification for the process’s executable is delivered and in the context of that callback, the process will have already been assigned to the job, in that case.
In Windows 10 and higher you seemingly can “atomically” create a new process in a job by using STARTUPINFOEX with CreateProcess and passing a PROC_THREAD_ATTRIBUTE_JOB_LIST with UpdateProcThreadAttribute. However, it turns out that this actually behaves non-atomically in case of the process being the first process executing in the job - in the sense that the Ps creation callback for the process will still occur before it’s assigned to the job and only at a later point in its lifetime you’ll be able to see it’s assigned to the job.
Lastly, in Windows 8 and higher, jobs form a hierarchy and the routine above returns the most-nested job the process is assigned to - but be aware that the process may be impacted by additional parent jobs it is assigned to.