windows提供一个作业(job)内核对象,它允许我们将进程组合在一起并插件一个沙箱来限制进程能够做什么,最好将作业对象想象成一个进程容器。
BOOL bInJob = FALSE;
IsProcessInJob(GetCurrentProcess(), NULL, &bInJob);
if (bInJob) {
MessageBox(NULL, TEXT("Process already in a job"),
TEXT(""), MB_ICONINFORMATION | MB_OK);
return(-1);
}
函数将NULL作为第二个参数传入,验证当前进程是否在一个现有的作业控制之下。如果进程已经与一个作业关联,就无法将当前进程或者他的任何子进程从作业中移除,这安全特性可以确保进程无法摆脱对他施加的限制。
SECURITY_ATTRIBUTES psa, PCTSTR pszName;
HANDLE m_hJob = CreateJobObject(psa, pszName);
直接创建一个新的作业对象,和其他的内核对象一样,第一个参数将安全信息和新的作业对象相关联,然后告诉系统返回的句柄是否可以被继承。第二个参数是对次作业对象命名,使得另一个进程可以通过OpenJobObject函数。
同样当不在访问作业对象的时候,必须调用closehandle来关闭它的句柄。关闭作业句柄,不会迫使作业中的所有进程都终止运行。
inline BOOL CJob::SetBasicUIRestrictions(DWORD fdwLimits) {
JOBOBJECT_BASIC_UI_RESTRICTIONS jobuir = { fdwLimits };
return(SetInformationJobObject(m_hJob,
JobObjectBasicUIRestrictions, &jobuir, sizeof(jobuir)));
}
创建好一个作业之后,接着一般会根据作业中的进程能够执行那些操作来建立一个沙箱。
限制类型 | 第二个参数的值 | 第三个参数的结构 |
基本限制 | JobObjectBasicLimitInformation | JOBOBJECT_BASIC_LIMIT_INFORMATION |
扩展基本限制 | JobObjectExtendedLimitInformation | JOBOBJECT_EXTENDED_LIMIT_INFORMATION |
基本UI限制 | JobObjectBasicUIRestrictions | JOBOBJECT_BASIC_UI_RESTRICTIONS |
安全性限制 | JobObjectSecurityLimitInformation | JOBOBJECT_SECURITY_LIMIT_INFORMATION |
关联完成端口限制 | JobObjectAssociateCompletionPortInformation | JOBOBJECT_ASSOCIATE_COMPLETION_PORT |
|
JobObjectAssociateCompletionPortInformation
JOBOBJECT_ASSOCIATE_COMPLETION_PORT
inline BOOL CJob::AssignProcess(HANDLE hProcess) {
return(AssignProcessToJobObject(m_hJob, hProcess));
}
接下来就是将进程放入作业当中,但是请注意调用createProcess时,使用的CREATE_SUSPENDED标志,这样虽然会创建新的进程,但是不允许执行任何代码,将其加入到作业并设置好限制,然后调用ResumeThread,使得进程的线程可以在作业的限制下执行代码,于此同时可以关闭线程的句柄,因为不在需要它了。
inline BOOL CJob::Terminate(UINT uExitCode) {
return(TerminateJobObject(m_hJob, uExitCode));
}
终止作业中的所有线程!
inline BOOL CJob::QuerySecurityLimitInfo(
PJOBOBJECT_SECURITY_LIMIT_INFORMATION pjosli) {
return(QueryInformationJobObject(m_hJob, JobObjectSecurityLimitInformation,
pjosli, sizeof(*pjosli), NULL));
}
查询作业统计信息
其他的信息请参考 http://blog.csdn.net/timmy_zhou/article/details/5614952