必须在进程创建后,在把进程移动到JOB中。所以必须先SUSPEND进程,这个时候进程不能执行任何代码,之后再将进程移动到JOB中,然后恢复进程。能不能用JOB限制AV?Check
通过BOOL IsProcessInJob( HANDLE hProcess, HANDLE hJob, PBOOL pbInJob);
判断当前进程是否在JOB中,第二个参数传NULL。
如果进程已经在JOB中,无法将进程移出JOB,子进程也会自动在JOB中
默认情况下通过Exploerer创建的进程关联 PCA 前缀的JOB。所以想要再关联JOB就会失败。 如果定义了manifest 文件就不会自动关联JOB 但是如果你想要调试你的程序,如果调试器被Explorer 启动。你的进程即使带有manifest,也会继承 PCA 前缀的JOB。一个解决方法就是使用命令行启动调试器
创建JOB
HANDLE CreateJobObject( PSECURITY_ATTRIBUTES psa, PCTSTR pszName);
通过名称打开JOB
HANDLE OpenJobObject(DWORD dwDesiredAccess , BOOL bInheritHandle, PCTSTR pszName);
关闭JOB,不会停止JOB关联的进程。只是将JOB标记为删除,当关联进程结束后,JOB自动删除。
当关闭Close Job Handle 后,JOB Handle 就不能被使用了。
在JOB进程上限制
有下面几种限制
-
基本的对于系统资源的限制
-
限制UI,不然限制在用户界面上
-
安全限制,阻止进程接触资源 files 、 registry subkeys
BOOL SetInformationJobObject(
HANDLE hJob,
JOBOBJECTINFOCLASS JobObjectInformationClass,
PVOID pJobObjectInformation,
DWORD cbJobObjectInformationSize);
第一个参数是JOB Handle 第二个参数是 一个 枚举类型关于 想要限制的类型 第三个参数指向 限制设置结构体的指针 第四个参数指向 结构体大小
下图展示限制类型
将进程放入JOB
BOOL AssignProcessToJobObject( HANDLE hJob, HANDLE hProcess);
但是如果进程已经在JOB中,就不然重新放到JOB中。子进程默认放入父进程的JOB中,可以用下面两个方法来改变
-
开启 JOBOBJECT_BASIC_LIMIT_INFORMATION’s LimitFlags 中的 JOB_OBJECT_LIMIT_BREAKAWAY_OK,然后CreateProcess 使用 CREATE_BREAKAWAY_FROM_JOB Flag
-
开启 JOBOBJECT_BASIC_LIMIT_INFORMATION’s LimitFlag 中的 JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK FLag , 这个使用 CreateProcess 不需要显式声明
结束JOB中所有进程
Kill Job中的进程
BOOL TerminateJobObject( HANDLE hJob, UINT uExitCode);
这与对所有进程调用TerminateProcess 类似
Querying Job Statistics
作业通知
当JOB耗尽了分配的CPU时间,就会强制结束JOB中所有的进程,并signal(触发作业对象)。 可以使用WaitForSingleObject 捕获这个事件,并可以在之后通过SetInformationJobObject 修改JOB 为 nonsignaled 状态,并分配更多CPU时间。