Windows Internals 笔记——作业

1.Windows提供了一个作业内核对象,它允许我们将进程组合在一起并创建一个“沙箱”来限制进程能够做什么。创建只包含一个进程的作业同样非常有用,因为这样可以对进程施加平时不能施加的限制。

 

2.如果进程已与一个作业关联,就无法将当前进程或者它的任何子进程从作业中去除。

 

3.默认情况下,在Windows Vista中通过Windows资源管理器来启动一个应用程序时,进程会自动同一个专用的作业关联,此作业的名称使用了“PCA”字符串前缀。一旦通过Windows资源管理器启动一个老版本的应用程序出现问题,就会触发Program Compatibility Assistant(程序兼容性助手)。

 

4.如果我们为应用程序定义了一个清单(manifest),Windows资源管理器就不会将我们的进程同带“PCA”前缀的作业关联,它会假定我们已经解决了任何可能出现的兼容问题。

 

5.但是在需要调试应用程序的时候,如果调试器时从Windows资源管理器启动的,即使我们的应用程序有一个清单,它也会从调试器继承带“PCA”前缀的作业。可以从命令行启动调试器来避开这个问题。

 

6.CreateJobObject用来创建一个新的作业内核对象,如果确定在自己的代码中不再访问作业对象,就必须调用CloseHandle来关闭它的句柄。而且这个动作不会迫使作业中的所有进程都终止运行。在作业中的所有进程都已终止运行之后,会自动销毁。但是注意,关闭作业句柄会导致所有进程都不可访问此作业,即使这个作业仍然存在。

 

7.创建好一个作业以后,可以向作业应用以下几种类型的限制:

  • 基本限额和扩展基本限额,用于防止作业中的进程独占系统资源。
  • 基本的UI限制,用于防止作业内的进程更改用户界面
  • 安全限额,用于防止作业内的进程访问安全资源(文件、注册表子项等)

 

8.可以通过调用SetInformationJobObject()函数向作业施加限制

SetInformationJobObject(
    _In_ HANDLE hJob,
    _In_ JOBOBJECTINFOCLASS JobObjectInformationClass,
    _In_reads_bytes_(cbJobObjectInformationLength) LPVOID lpJobObjectInformation,
    _In_ DWORD cbJobObjectInformationLength
    );

可以设置以下限制:

 

9.作业中的进程可以调用QueryInformationJobObject获得其所属作业的相关信息,这使得进程能看到自己被施加了哪些限制,不过如果调用SetInformationJobObject时为作业句柄参数传递NULL值,会导致调用失败,目的是为了防止进程删除施加于自己身上的限制。

 

10.我们可以调用AssignProcessToJobObject()函数将进程显示地放入作业中。而且它的子进程也将属于这个作业的一部分,但是也可以通过修改JOBOBJECT_BASIC_LIMIT_INFORMATION的成员来控制脱离这个作业。

 

11.调用TerminateJobObject()可以杀死作业内部的所有进程。

 

12.作业中的进程如果尚未用完已分配的CPU时间,作业对象就处于未触发的状态(即使作业中还没有任何进程在运行),一旦已分配的CPU时间被用完,Windows就会强行杀死作业中的所有进程并触发作业对象。调用WaitForSingleObject可以轻松捕捉到这个事件。

 

13.当作业收到通知,得知一个新进程是在它的限制下创建时,GetModuleFileNameEx的调用会失败,因为在这个时候,地址空间尚未完全初始化,模块尚未与它建立映射。GetProcessImageFileName在这种极端情况下也能获取完整路径名,但是格式近似于我们在内核模式中看到的模式(\device\Harddisk\Volume1\Windows\System32\notepad.exe),而不是C:\Windows\System32\notepad.exe。而QueryFullProcessImageName在任何情况下都会返回我们预期的完整路径名。

posted @ 2018-03-19 20:48  MyCPlusPlus  阅读(222)  评论(0编辑  收藏  举报