新年到了,伴随着新年的钟声,人们各自回到了温馨的家,绽开了可爱的笑脸。然而,在世界的某个角落,有一群人,他们在利用各个软件漏洞来榨取人们的钱财,扼杀人们对世界和平的信心!没错,就是他们!为了我们的合法权益,我们必须学会保护自己!!来吧,让我们一起用我们的知识创造一个我们的软件沙箱!!

用户接口
1、首先要设计好好用户界面:为了简单,我们用一个对话框来作为“软件沙箱”的用户接口,再加上几个静态文本、Edit编辑框、Button按钮、ListBox就完成了用户界面。至于图标,对话框对图标的设置可以调用SetClassLong,这不是重点,具体见最后的源代码。
真正的功能(重点)
1、现在,我们来实现真正的功能!!首先,创建一个作业内核对象:HANDLEhJob=CreateJobObject(NULL,NULL);
2、接着,我们根据用户的选项(Edit编辑框和Check的值来初始化两个结构)这里,我初始化了两个结构,其实还有一个另一个结构可以用于进行 安全限制 的,但由于这些功能需要用户有一定的基础知识而不常用,所以这里没有提供这个接口。以下是源代码(耐得住寂寞才会成功):VOID OnSetInformation(HWND hWnd){ /*基本限制*/ JOBOBJECT_BASIC_LIMIT_INFORMATION jbli={0}; LARGE_INTEGER li={0}; li.LowPart=GetDlgItemInt(hWnd,IDC_PerProcessUserTimeLimit,NULL,FALSE); jbli.PerProcessUserTimeLimit=li; li.LowPart=GetDlgItemText(hWnd,IDC_PerJobUserTimeLimit,NULL,FALSE); jbli.PerJobUserTimeLimit=li; jbli.ActiveProcessLimit=GetDlgItemInt(hWnd,IDC_ActiveProcessLimit,NULL,FALSE); jbli.MinimumWorkingSetSize=GetDlgItemInt(hWnd,IDC_MinimumWorkingSetSize,NULL,FALSE); jbli.MaximumWorkingSetSize=GetDlgItemInt(hWnd,IDC_MaximumWorkingSetSize,NULL,FALSE); jbli.SchedulingClass=GetDlgItemInt(hWnd,IDC_SchedulingClasss,NULL,FALSE); TCHAR szPriorityClass[10]; GetWindowText(GetDlgItem(hWnd,IDC_PriorityClass),szPriorityClass,_countof(szPriorityClass)); //进程优先级 if(lstrcmp(szPriorityClass,_T("高"))) jbli.PriorityClass=THREAD_PRIORITY_HIGHEST; else if(lstrcmp(szPriorityClass,_T("高于正常"))) jbli.PriorityClass=THREAD_PRIORITY_ABOVE_NORMAL; else if(lstrcmp(szPriorityClass,_T("正常"))) jbli.PriorityClass=THREAD_PRIORITY_NORMAL; else if(lstrcmp(szPriorityClass,_T("低于正常"))) jbli.PriorityClass=THREAD_PRIORITY_BELOW_NORMAL; else if(lstrcmp(szPriorityClass,_T("低"))) jbli.PriorityClass=THREAD_PRIORITY_LOWEST; else if(lstrcmp(szPriorityClass,_T("空闲"))) jbli.PriorityClass=THREAD_PRIORITY_IDLE; jbli.LimitFlags=JOB_OBJECT_LIMIT_PROCESS_TIME | JOB_OBJECT_LIMIT_JOB_TIME | JOB_OBJECT_LIMIT_WORKINGSET | JOB_OBJECT_LIMIT_ACTIVE_PROCESS | JOB_OBJECT_LIMIT_AFFINITY | JOB_OBJECT_LIMIT_SCHEDULING_CLASS; SetInformationJobObject(hJob,JobObjectBasicLimitInformation,&jbli,sizeof(jbli)); /*UI限制*/ JOBOBJECT_BASIC_UI_RESTRICTIONS jbur={0}; if(SendMessage(GetDlgItem(hWnd,IDC_UILIMITEXITWINDOWS),BM_GETCHECK,0,0)) jbur.UIRestrictionsClass|=JOB_OBJECT_UILIMIT_EXITWINDOWS; if(SendMessage(GetDlgItem(hWnd,IDC_UILIMITREADCLIPBOARD),BM_GETCHECK,0,0)) jbur.UIRestrictionsClass|=JOB_OBJECT_UILIMIT_READCLIPBOARD; if(SendMessage(GetDlgItem(hWnd,IDC_UILIMITWRITECLIPBOARD),BM_GETCHECK,0,0)) jbur.UIRestrictionsClass|=JOB_OBJECT_UILIMIT_WRITECLIPBOARD; if(SendMessage(GetDlgItem(hWnd,IDC_UILIMITDESKTOP),BM_GETCHECK,0,0)) jbur.UIRestrictionsClass|=JOB_OBJECT_UILIMIT_DESKTOP; if(SendMessage(GetDlgItem(hWnd,IDC_UILIMITSYSTEMPARAMETERS),BM_GETCHECK,0,0)) jbur.UIRestrictionsClass|=JOB_OBJECT_UILIMIT_SYSTEMPARAMETERS; if(SendMessage(GetDlgItem(hWnd,IDC_UILIMITDISPLAYSETTINGS),BM_GETCHECK,0,0)) jbur.UIRestrictionsClass|=JOB_OBJECT_UILIMIT_DISPLAYSETTINGS; if(SendMessage(GetDlgItem(hWnd,IDC_UILIMITGLOBALATOMS),BM_GETCHECK,0,0)) jbur.UIRestrictionsClass|=JOB_OBJECT_UILIMIT_GLOBALATOMS; if(SendMessage(GetDlgItem(hWnd,IDC_UILIMIT_HANDLES),BM_GETCHECK,0,0)) jbur.UIRestrictionsClass|=JOB_OBJECT_UILIMIT_HANDLES; SetInformationJobObject(hJob,JobObjectBasicUIRestrictions,&jbur,sizeof(jbur)); AddText(GetDlgItem(hWnd,IDC_JOBMSG),_T("设置限制完成!"));}
3、以上就是所有的操作了!看懂了源代码你就已经成功了!!如果你没看懂,没关系,这里是一些解释:贯穿代码中的两个结构:JOBOBJECT_BASIC_LIMIT忧溲枷茫_INFORMATION jbli={0} //基本限制JOBOBJECT_BASIC_UI_RESTRICTIONS jbur={0} //UI限制贯穿代码中的两次函数调用:SetInformationJobObject(hJob,JobObjectBasicLimitInformation,&jbli,sizeof(jbli));SetInformationJobObject(hJob,JobObjectBasicUIRestrictions,&jbur,sizeof(jbur));没错,你所看到的所有冗长的操作都是根据用户的操作调整这两个数据结构而已!!而关于这两个数据结构和SetInformationJobObject,MSDN上的解释非常好(再加上我想偷懒),这里就不再解释了。不过,听说MSDN是英文版的~~2012是这样~~为了帮助大家更容易理解,这里我引用一篇文档,链接见最后的注意事项1(正文不能有链接~~)当然,也可以参考:《Windows核心编程5 Via C/C++》第五张<作业>
调试程序
1、成功编写,不代表你的软件毫无差错!!调试是很重要的。我们来做个实验。打开软件沙箱。并勾选“禁止注销...”并单击“设置限制”。


4、再来一个,前段时间我的一位同学编了一个小程序来捉弄我~~这个程序会打开100个cmd窗口~~然而,我的“软件沙箱”帮我渡过了难关!!来,有图有真相!!妈妈吖,我差点挂了(这C霸烹钟爷PU占用率是很高的!),殊不知我一关掉“软件沙箱”(这时软件沙箱会终止作业中的所有进程【通过调用TerminateJobObject】【详见源代码】),全部cmd窗口都没了~~

5、我们再来玩玩Microsoft的spy++(这家伙挺厉害的)spy++的启动需要管理员权限,所以也需要用管理员权限来启动“软件沙箱”勾选“禁止使用进程外部用户对象”并启动spy++看,spy++中啥都没有


