Sandboxie循序渐进耳之监控篇上

微信扫一扫,分享到朋友圈

Sandboxie循序渐进耳之监控篇上

本文为看雪论坛精华文章

看雪论坛作者
ID:一半人生

Sandboxie监控篇笔记太长,引擎打算重写(利于二次开发),业余时间研究会久一些,分为上下篇分享笔记。

上篇主要自编译沙盘部署(合规过程),文件举例回调/r3dll注入分析,沙盘内部构建MSG通信分析(自行添加消息),基于MFC二次开发(抛砖引玉)。

下篇主要接管资源监控数据和重写部分监控引擎,添加hook第三方接口。

本篇是进程监控笔记,以功能为出发点,进一步探讨实现原理与数据应用,参杂排错思路和开发相关知识。

David.SandboxiePlush增添了许多新功能,新鲜感的界面和多交互,确实是不错的一面。

SandBoxiePlush界面

本文基于原生的Sandboxie添加API监视模块,准备改造如下(后续会改进,危险操作将会标红):

沙盘编译部署

进程篇基于调试学习和理解,本篇需要自己实现编译且正常执行,不推荐使用脚本集成化,最好能够理解和学习每一个环节,过程无疑是比较麻烦的,这里补贴一张r3进程篇流程图。

r3-process-run

Release编译全部工程,编译期间如果遇到lib异常,请参考第一篇文章引荐的解决方案,根据错误提示解决问题,目标是能够正常运行自编译的Sandboxie即可:

编译完成后直接运行SbieCtrl.exe会发生错误,SbieSvc.exe需要以服务的方
式启动,SbieDrv
这时候也没被加载。

 

后来查看了安装脚本和David-SandMain代码启动流程(保证每个步骤都合规),依赖于KmdUtil进行加载,sandboxie作者已写好模块,只需要调用即可。

SbieControl

1) 如果本机已安装Sandboxie,调试可能会出现版本不匹配,这时候SbieSvc服务和驱动已启动,可以进行LPC查询版本号,需要卸载已安装的Sandboxie,如下所示:

 

Clinet:

版本检测CMyApp::InitInstance().CInitWait initwait(this);将会通过发送请求MSGID_SBIE_INI_GET_VERSION判断组件之间版本是否一致。

Server:

PipServer.*SbieIniServer::Handler2处理MSGID_SBIE_INI_GET_VERSION
if (msg->msgid == MSGID_SBIE_INI_GET_VERSION) {


return GetVersion(msg);
}

GetVersion查询当前版本,MY_VERSION_STRING宏声明了版本号:

MSG_HEADER *SbieIniServer::GetVersion(MSG_HEADER *msg)
{
WCHAR ver_str[16];
wsprintf(ver_str, L"%S", MY_VERSION_STRING); // MY_VERSION_STRING = "5.40"


ULONG ver_len = wcslen(ver_str);
ULONG rpl_len = sizeof(SBIE_INI_GET_USER_RPL)
+ (ver_len + 1) * sizeof(WCHAR);
SBIE_INI_GET_VERSION_RPL *rpl =
(SBIE_INI_GET_VERSION_RPL *)LONG_REPLY(rpl_len);
if (! rpl)
return SHORT_REPLY(STATUS_INSUFFICIENT_RESOURCES);


wcscpy(rpl->version, ver_str);
rpl->version_len = ver_len;
return &rpl->h;
}

检测版本号不匹配,弹窗提示,因为本机安装发行版是v5.33,源码版本是v5.4,自编译的程序应该都是v5.4版本,不会出现上述问题。

版本号校验实际开发中是必要的,多版本迭代,多个组件功能增添和优化,当新版发布后,客户只更新部分组件或某些原因更新失败,新老版参杂运行可能因接口已改动等问题造成很大的风险。

2) 指定的服务未安装,如下所示:

 

Client:

SbieCtrl.CMyApp::InitInstance().CInitWait.initwait(this).SbieDll_StartSbieSvc(BOOLEAN retry).SbieDll_ConnectPort().当SbieSvc未启动的时候,data->ProtHandle没有句柄。

if (! data->PortHandle) { 
BOOLEAN Silent = (req->msgid == MSGID_SBIE_INI_GET_VERSION ||
req->msgid == MSGID_SBIE_INI_GET_USER ||
req->msgid == MSGID_PROCESS_CHECK_INIT_COMPLETE);
if (! SbieDll_ConnectPort(Silent))
return NULL;

调用SbieDll_ConnectPort()连接服务端,如下所示:

RtlInitUnicodeString(&PortName, SbieDll_PortName());
// 连接服务端
status = NtConnectPort(
&data->PortHandle, &PortName, &QoS,
NULL, NULL, &data->MaxDataLen, NULL, NULL);
if (! NT_SUCCESS(status)) {
if (! ErrorReported) {
if (! Silent)
SbieApi_Log(2203, L"connect %08X", status);
ErrorReported = TRUE;
}
// 连接失败返回
return FALSE;
}

如上图所示,指定服务未安装,SbieControl.exe启动过程中,默认SbieSvc服务是已加载,Server开启监听等待客户端连接,如果Server未启动,SbieControl不会做加载操作。

基于原生Sandboxie添加代码,连接服务失败则重新服务加载,为了有交互性,简单弹窗或Dlg告知用户是否需要加载SbieSvc和Drv(只提示一次),当然也可以用脚本完成服务安装和驱动安装,这里通过添加代码熟悉每一个环节,如下所示:

        status = NtConnectPort(
&data->PortHandle, &PortName, &QoS,
NULL, NULL, &data->MaxDataLen, NULL, NULL);


if (! NT_SUCCESS(status)) {
// 如果失败,提示是否加载服务和驱动 只提示一次安装服务比较合适,nServiceloadflag标志是否第一次提示
if (!nServiceloadflag && (IDYES == MessageBoxW(NULL, L"是否重新加载服务和驱动", L"RPC-Server Connect失败", MB_OK | MB_YESNOCANCEL)))
{
// 加载......
MessageBoxW(NULL, L"加载成功", L"Waring", NULL);
}
else
{
nServiceloadflag = TRUE;
if (!ErrorReported) {
if (!Silent)
SbieApi_Log(2203, L"connect %08X", status);
ErrorReported = TRUE;
}
return FALSE;
}
}

这只是一个最简单的示例,如果点击是(Y)则加载驱动和服务,如下所示:

 

KimUtil:

编写服务管理模块,阅读KimUtil源码,它负责SbieDrv和SbieSvc生命周期管理,ReadMe.txt介绍如下:

KmdUtil (installkmdutil). Builds KmdUtil.exe which is used during the installtion process. E.g. to start/stop the Sbie driver (SbieDrv.sys).

// Cmdline获取控制码
if (! Parse_Command_Line(
&Command, &Driver_Name, &Driver_Path,
&Driver_Display, &Driver_MsgFile,
&Driver_Altitude, &Driver_Group,
&Options))
return EXIT_FAILURE;
// 卸载
if (Command == CMD_DELETE) {
ok = Kmd_Delete_Service(Driver_Name);
if (ok)
ok = Kmd_Unregister_Event_Source(Driver_Name);
ok = TRUE; // don't let the calling installer fail
}


// 安装
if (Command == CMD_INSTALL) {
ok = Kmd_Install_Service(
Driver_Name, Driver_Path, Driver_Display, Driver_Group, Options);
if (ok) {
if (! Driver_MsgFile)
Driver_MsgFile = Driver_Path;
ok = Kmd_Register_Event_Source(Driver_Name, Driver_MsgFile);
if (ok && Driver_Altitude)
ok = Kmd_Register_MiniFilter(Driver_Name, Driver_Altitude);
if (! ok) {
Kmd_Unregister_Event_Source(Driver_Name);
Kmd_Delete_Service(Driver_Name);
}
}
}


// 启动
if (Command == CMD_START)
ok = Kmd_Start_Service(Driver_Name);


// 停止
if (Command == CMD_STOP)
ok = Kmd_Stop_Service(Driver_Name);

参考David.SandboxiePlush管理模块用法,初始化源码如下:

void CSbieUtils::Install(EComponent Component, QStringList& Ops)
{
QString HomePath = QCoreApplication::applicationDirPath().replace("/", ""); // "C:Program FilesSandboxie "
if ((Component & eDriver) != 0 && GetServiceStatus(SBIEDRV) == 0)
Ops.append(QString::fromWCharArray(L"kmdutil.exe|install|" SBIEDRV L"|") + """ + HomePath + "" + QString::fromWCharArray(SBIEDRV_SYS) + """ + "|type=kernel|start=demand|altitude=86900");
if ((Component & eService) != 0 && GetServiceStatus(SBIESVC) == 0) {
Ops.append(QString::fromWCharArray(L"kmdutil.exe|install|" SBIESVC L"|") + """ + HomePath + "" + QString::fromWCharArray(SBIESVC_EXE) + """ + "|type=own|start=auto|display="Sandboxie Service"|group=UIGroup");
Ops.append("reg.exe|ADD|HKLMSYSTEMControlSet001ServicesSbieSvc|/v|PreferExternalManifest|/t|REG_DWORD|/d|1");
}
}

为了方便调试,可以使用cmd就可以完成安装/启动/停止等工作,循序不能乱,先加载驱动,梳理如下所示:

Cmd runing:
1. kmdutil.exe install SbieDrv "{path}SbieDrv.sys" type=kernel start=demand altitude=86900
2. kmdutil.exe install SbieSvc "{path}SbieSvc.exe" type=own start=auto display="Sandboxie Service" group=UIGroup
3. reg.exe ADD HKLMSYSTEMControlSet001ServicesSbieSvc.exe /v PreferExternalManifest /t REG_DWORD /d 1
4. Kmdutil start SbieDrv
5. Kmdutil start SbieSvc

如果没有签名就会出现无法验证数字,解决方案,简单粗暴开机F8,如下:

驱动加载成功之后,fltmc可以查看已加载的实列和高度:

服务加载成功后如下:

如果开启SbieSvc服务遇到了拒绝访问等权限问题,先核查注册表可执行路径,确认是否因SbieSvc.exe绝对路径导致问题。在排查目录权限,百度自行解决即可(注意先启动驱动/后启动服务)。

给原生Sandboxie添加服务/驱动管理代码,至此SbieCtrl.exe界面运行成功。

Error1:运行后发现无法正常执行,会出现配置文件错误,如下所示:

 

解决方案:拷贝installTemplates.ini文件至沙箱编译运行目录下即可。

Error2:执行进程再次遇到错误,如下所示:

 

找不到对象名称?ALPC连接失败?如何出现的这个错误?当前项目共找到三处MSG_2101调用处,但是根据上下文只有一处命中,错误源于Syscall_CheckObject函数的检测,源码如下:

        if ((status != STATUS_SUCCESS)
&& (status != STATUS_BAD_INITIAL_PC)) {


WCHAR msg[256];
swprintf(msg, L"%S (%08X) access=%08X initialized=%d", syscall_entry->name, status, HandleInfo->GrantedAccess, proc->initialized);
Log_Msg(MSG_2101, msg, Name != NULL ? Name->Name.Buffer : L"Unnamed object");
}

解决方案:

SbieDrv添加断点,编译安装,Name值为空,ALPC未连接成功,alpc意味着可能未初始化,该问题上两周没有找到解决方案,因为时间花在了引擎二次开发和界面改进,有时间的朋友可以研究。

控制权限

抛砖引玉:
本篇以文件操作举例,使用Hook API, fsd hook,disk hook,Ntfs(MFT)篡改都可以实现文件权限控制(可读,可写,可访问)重定向。

沙盘已实现限制功能,可控制多进程之间的权限管理,Sandboxie自带资源访问监控,如下所示:

本篇以文件限制/资源访问两项功能为主线,进一步学习源码,分析实现原理,添加更直观的数据展示。

测试demo:


CreateFile( OPEN_ALWAYS
)–>Userinput–>WriteFile–>CloseHand–>CreateFile( OPEN_EXISTING
)–>ReadFile做为API序列。

文件限制:

1) 为了测试沙盘隔离效果,本机C盘创建1.txt文件,并且写入字符,然后Sandboxie执行Demo,创建1.txt并且写入输入的字符,如下图所示,Demo执行之后,本地1.txt没有发生任何改变:

 

2) 沙盘目录下已创建了C1.txt,且写入了Demo中输入的字符串,这就是重定向。

文件权限:

如何去构造进程监控?r3层跨进程hook依赖远程线程注入Dll或shellcode,对目标进程API挂钩实现过滤。Sandboxie如何实现重定向和监控呢?一起寻找答案如果windbg过程中寻找答案,那将是非常耗费精力的事情,善于搜索源码,Sandboxie以各类消息进行通信,注入也会有消息定义,可以搜索关键字。

enum {
SVC_FIRST = 0x23450000L,


SVC_LOOKUP_SID,
SVC_INJECT_PROCESS,
SVC_CANCEL_PROCESS,
SVC_UNMOUNT_HIVE,
SVC_LOG_MESSAGE,
SVC_RESTART_HOST_INJECTED_SVCS,


SVC_LAST
};


其中SVC_INJECT_PROCESS/SVC_RESTART_HOST_INJECTED_SVCS字面意思很明显,服务注入进程,通过代码搜索调用函数及回溯。进程篇发现执行过程中r3没有做hook代码?如何实现进程监控呢?这里阐述驱动初始化过程( 文件)
,一开始是想放到原理篇( SbieDrv完整性分析
)。

1. _FX NTSTATUS DriverEntry()SbieDrv驱动入口点,驱动加载时候将会执行方法,Process_Init()

    //
// initialize modules. these place hooks into the system. hooks
// become active as soon as installed. the Process module must be
// initialized first, because it initializes the process list
//


if (ok)
ok = Process_Init();

2. Process_Init()函数函数负责注册回调,PsSetCreateProcessNotifyRoutine ,进程创建/结束将会调用回调函数Process_NotifyProcess()

    //
// install process notify routines
//


status = PsSetCreateProcessNotifyRoutine(Process_NotifyProcess, FALSE);

3. Process_NotifyProcess()函数进程创建将会处理Process_NotifyProcess_Create()

    if (ProcessId) {


if (Create) {


if (ParentId) {


Process_NotifyProcess_Create(ProcessId, ParentId, NULL);
}


} else {


Process_NotifyProcess_Delete(ProcessId);
}
}

4. 负责进程相关的结构填充,通过Process_Low_Inject发送SVC_INJECT_PROCESS至SbieSvc告知注入,等待SbieSvc的挂钩处理。

            Process_Low_Inject(
pid, session_id, create_time, nptr1, add_process_to_job, bHostInject);


if (! Api_SendServiceMessage(SVC_INJECT_PROCESS, sizeof(msg), &msg))
status = STATUS_SERVER_DISABLED;

5. SbieSvc接收到消息之后,DriverAssist.cpp.MsgWorkerThread开始工作,如下:

    else if (msgid == SVC_INJECT_PROCESS) {


InjectLow(data_ptr);


} else if (msgid == SVC_RESTART_HOST_INJECTED_SVCS) {


RestartHostInjectedSvcs();
}

6. 响应SVC_INJECT_PROCESS,call InjectLow负责处理和目标进程注入,最后通知注入完成。

    if (SbieApi_CallOne(API_INJECT_COMPLETE, msg->process_id) == 0)
errlvl = 0;
else
errlvl = 0x99;

7. svc注入进程其实与平常注入无二样,通过VirtualProtectEx/WriteProcessMemory来写入目标进程,它选择覆盖了LdrInitializeThunk函数来挂钩执行。

sandboxie-mastercoresvcDriverAssistInject.cpp有具体hook过程,包括判断了是否已经被hook等处理,这里将不全部刨析。dll注入后如何监控呢,dll源码寻找初始化hook的痕迹,如下所示:

Sboxdll.file_init

#define SBIEDLL_HOOK(pfx,proc)                  
*(ULONG_PTR *)&__sys_##proc = (ULONG_PTR)
SbieDll_Hook(#proc, proc, pfx##proc);
if (! __sys_##proc) return FALSE;

SbieDll_Hook函数是实现r3-inlinehook的主要模块,如下所示:

 

函数原型可知,参数一标识函数名,参数二/三分别是原函数地址和过滤函数地址。

Sandboxie实现inlinehook,经过了以下几个步骤(x32举例):

1) 函数源地址参数校验

   if (! SourceFunc) {
SbieApi_Log(2303, _fmt1, SourceFuncName, 1);
return NULL;
}

2) 检测沙箱hook支持,x32/x64不同,找到函数hook的点。

  UCHAR *func = (UCHAR *)SourceFunc;
if (func[0] == 0xB8 && // mov eax,?
func[5] == 0xBA && // mov edx,?
*(USHORT *)&func[10] == 0xE2FF) // jmp edx
{
ULONG i = 0;
ULONG *longs = *(ULONG **)&func[6];


for (i = 0; i < 20; i++, longs++)
{
if (longs[0] == 0x5208EC83 && longs[1] == 0x0C24548B &&
longs[2] == 0x08245489 && longs[3] == 0x0C2444C7 &&
longs[5] == 0x042444C7)
{
SourceFunc = (void *)longs[4];
break;
}
}
}

3) 检测是否已被挂钩,如果是0xEB(short jmp)

    if (*(UCHAR *)SourceFunc == 0xEB) {
signed char offset = *((signed char *)SourceFunc + 1);
SourceFunc = (UCHAR *)SourceFunc + offset + 2;
}

4) 0xE9(near jump)

    while (*(UCHAR *)SourceFunc == 0xE9) {
diff = *(LONG *)((ULONG_PTR)SourceFunc + 1);
target = (ULONG_PTR)SourceFunc + diff + 5;
if (target == (ULONG_PTR)DetourFunc) {
SbieApi_Log(2303, _fmt1, SourceFuncName, 4);
return NULL;
}

5) 调用驱动来创建跳板

    tramp = Dll_AllocCode128();
if (SbieApi_HookTramp(SourceFunc, tramp) != 0) {
SbieApi_Log(2303, _fmt1, SourceFuncName, 2);
return NULL;

6) inlinehook指针替换

    func = (UCHAR *)SourceFunc;


if (!VirtualProtect(&func[-8], 20, PAGE_EXECUTE_READWRITE, &prot)) {


ULONG err = GetLastError();
SbieApi_Log(2303, _fmt2, SourceFuncName, 33, err);
return NULL;
}
diff = (UCHAR *)DetourFunc - (func + 5);
func[0] = 0xE9; // JMP DetourFunc
*(ULONG *)(&func[1]) = (ULONG)diff;
VirtualProtect(&func[-8], 20, prot, &dummy_prot);
func = (UCHAR *)(ULONG_PTR)(tramp + 16);

整个过程与平常编写的inlinehook如出一辙,Sandboxie已商用化10几年,inlinehook稳定性/兼容性比较靠谱,按照固定格式添加hook的函数即可,或者修改已定义的过滤函数,实现格外的过滤功能。

DLL几乎接管了常见的API,但WMI等不在这个范围内,需要格外的编写监控模块,添加到沙盘机制中。

CreateFile过滤函数

hook过程我没有调试,所以不一定严谨,想自己接管引擎在开发中,沙盘中的进程调用NtCreateFile,将会执行已被挂钩函数File_NtCreateFileImpl,如上图可以看到函数源码近1200行,Snadboxie作者考虑周全细致,学到了很多知识,详
细请自行
“食用”源码。        

界面开发:

界面初始化流程

定位代码随便加入一行尝试是否生效,界面源码appscontrol目录,添加测试属性如下,ProcListCtrl.Create()为例:

    // 设置List表
CListCtrl::InsertColumn(0, CMyMsg(MSG_3517), LVCFMT_LEFT, width0, 0);
CListCtrl::InsertColumn(1, CMyMsg(MSG_3518), LVCFMT_LEFT, width1, 0);
CListCtrl::InsertColumn(2, CMyMsg(MSG_3519), LVCFMT_LEFT, width2, 0);
CListCtrl::InsertColumn(3, L"测试", LVCFMT_LEFT, width2, 0);

这样添加不合理,会出问题,暂时先这样处理。资源访问控制功能设计模态,当监视窗口弹出无法对主界面做任何操作。

appscontrolMonitorDialog.cpp,后面会详细介绍MSG自定义添加消息处理,如下所示:

注意,Dlg应该没有构建类,无法通过向导绑定资源变量(目前本机测试是这样),需要自己用CListCtrl类获取组件ID进行操作。MFC作者重写了控件类,CMyxxx标识为重构的类。上述ListCtrl添加完成后,属性ID=ID_MESSAGE_LIST_MONITORL,使用CListCtrl代码如下:

CRect rc;
this->GetClientRect(rc);
int nWidth = rc.Width();
CListCtrl *listctrl = (CListCtrl *)GetDlgItem(ID_MESSAGE_LIST_MONITORL);
DWORD dwOldStyle;
dwOldStyle = listctrl->GetExtendedStyle();
listctrl->SetExtendedStyle(dwOldStyle | LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES);
listctrl->InsertColumn(0, L"监控类型", LVCFMT_CENTER, nWidth / 3);
listctrl->InsertColumn(1, L"监控api", LVCFMT_CENTER, nWidth / 3);
listctrl->InsertColumn(2, L"捕获数据", LVCFMT_CENTER, nWidth / 3);

如何构建非模态对话框呢,这是一个麻烦的过程,尝试后果断放弃,耗时费力不讨好,有更好的方案来代替。弃用Sandboxie作者写的监控窗口,移植到Master主页面,如何设计呢?具备可扩展性?考虑BaseDlg可伸缩,随意调整大小,不改动原有的界面,没有原型图,直接手绘就好了,按钮有点多余,可以添加到菜单栏,否则显得太突兀,点击即可显示,如开篇所示。

1. 第一步,添加菜单按钮,Api监视模块,一般都是绑定菜单处理,处理输入名称即可,该工程需要全部手工完成。

2. 上述编号3411~3451对应着主界面菜单,0x3461其实已被占用,5160~7000之间ID标识未被使用,添加的ID做好维护,菜单处理代码:

void CMyFrame::InitMenus(void)
{
//
// create and customize main menu
//


CMenu *pMenu = CMyApp::MyLoadMenu(L"TOP_MENU");

遵循作者消息规范操作,通过查询Dll来获取对应的字符串。菜单初始化通过循环完成,TOP_MENU主菜单,MSG_3411消息号递增10(10个以内子菜单)。一开始以为基于msgs.h生成,几经折腾,Parse工程负责将本地txt生成mc,转换msgs.h文件,MSG工程编译dll,共享内存使用。

 

创建msgs.mc文件:

自定义MSG-ID只有写入Sbie-English-1033.txt文件才会生效,编译后的msgs.h才会包含,自定义格式如下:

#----------------------------------------------------------------------------
# New TOP_MENUS MSG
#----------------------------------------------------------------------------
5161;txt;01
&Test
.


5162;txt;01
&ProcessAPiMonitor
.

3. MyFarMe.Cpp添加菜单响应消息手动添加,如下所示:

1. Class类声明
afx_msg void OnCmdPackTools();


2. Map映射,OnCmdPackTools响应菜单点击函数
BEGIN_MESSAGE_MAP(CMyFrame, CFrameWnd)
{
......
ON_COMMAND(ID_MEUN_APIMONITOR, OnCmdPackTools)
......
}


3. 方法实现,如何操作:
void CMyFrame::OnCmdPackTools()
{
AfxMessageBox(L"1");
}


4. 第二步,List宽度对于当前窗口减半,初始化新的监控List窗口(占据另一半
。菜单检测没有使用Checks属性,自己实现,同样List也被重构,ProcessList/FileList都对应的初始化如下:

    //
// create viewers
//
// 初始化List-tree控件 进程/文件
m_proclist.Create(this);
m_filelist.Create(this);

5. m_procList/m_filelist组件对象,可以通过变量来控制组件属性。梳理List继承,MyListCtr继承基类CListCtrl,封装使用单独继承MyListCtr,每个功能模块都可以继承封装。

 

创建进程API监控类.cpp/.h,继承CMyListCtrl或者直接用ProcListCtrl类,编写控制List大小函数。

虽然没有介绍初始化过程和原理,进程篇到监控篇学习至少可以掌握代码增删改查,能够执行/测试,编写部分功能和模块,对各组件之间联系更深一步,函数调用关系愈发清晰,目前来说这些是足够的。

可以按照个人的意愿修改源码,这不同于进程篇的调试和理解,从这里开始你将可以基于Sandboxie做一些认为好的事情,这将是一个新的里程碑。

原理篇放在最后是因为Sandboxie工程量偏大,设计与代码质量高,二次开发中不断学习,久而久之才能更好理解每一个过程,才能严谨的对Sandboxie原理完善总结。

最后很多人搞混轻量级沙盘和恶意软件分析沙箱的概念,准确来说二者完全不是一回事,除了虚拟化安全这条理念,设计出发点不同。


个人使用Sandboxie一直以来用于游戏多开和安装未知软件,你会发现Sandboxie社区散户大多是用来安装软件( 包括移植
)和游戏,它并不是为了恶意软件分析而设计,但是开源后的Sandboxie,如果你愿意它完全可以成为Windows下优秀的恶意软件分析沙箱之一。

希望更多对底层安全开发的人一起学习研究。引入rootkit监控(动态拦截),成熟后引入vt框架ept_apimonitor,这是比较有意思的攻防对抗。

看雪ID:一半人生

https://bbs.pediy.com/user-819685.htm

*本文由看雪论坛 一半人生 原创,转载请注明来自看雪社区。

推荐文章++++

*
0基础也能看懂的函数栈结构分析

*
CVE-2020-1054分析

*
对比总结32/64位下Windows部分数据结构的异同

*
CVE-2020-1350分析与复现

*
关于抓包的碎碎念

公众号ID:ikanxue

官方微博:看雪安全

商务合作:wsc@kanxue.com

求分享

求点赞

求在看



“阅读原文

立即报名吧

微信扫一扫,分享到朋友圈

Sandboxie循序渐进耳之监控篇上

央视再评大胃王吃播:袁隆平爷爷让咱吃饱没让咱糟践粮食

上一篇

爱奇艺:中国消费者愿为内容付费 19.8元会员太便宜 将探索更多付费方式

下一篇

你也可能喜欢

Sandboxie循序渐进耳之监控篇上

长按储存图像,分享给朋友