首页
论坛
课程
招聘
[原创]Sandboxie循序渐进耳之监控篇上
2020-8-8 23:33 2649

[原创]Sandboxie循序渐进耳之监控篇上

2020-8-8 23:33
2649

SandBoxie循序渐进耳监控篇上

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 (\install\kmdutil). 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 Files\\Sandboxie "
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|HKLM\\SYSTEM\\ControlSet001\\Services\\SbieSvc|/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 HKLM\SYSTEM\ControlSet001\Services\SbieSvc.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: 运行后发现无法正常执行,会出现配置文件错误,如下所示:

 

解决方案:拷贝install\Templates.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) 沙盘目录下已创建了C\1.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-master\core\svc\DriverAssistInject.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作者考虑周全细致,学到了很多知识,详细请自行“食用”源码。        


界面开发:

 

界面初始化流程

定位代码随便加入一行尝试是否生效,界面源码apps\control目录,添加测试属性如下,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);

 

这样添加不合理,会出问题,暂时先这样处理。资源访问控制功能设计模态,当监视窗口弹出无法对主界面做任何操作。apps\control\MonitorDialog.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_level恶意行为检测感兴趣的朋友可以加群一起沟通,希望更多对底层安全开发的人一起学习研究。引入rootkit监控(动态拦截),成熟后引入vt框架ept_apimonitor,这是比较有意思的攻防对抗。

QQ群:493501344

Sandboxie监控篇下笔记分享之后源码上传至github(方便维护),vs2017(141)编译+wdk7600,后续同步Git(目前因有问题,包括界面无数据,暂不上传)

Github:https://github.com/TimelifeCzy 



看雪论坛2020激励机制:能力值、活跃值和雪币体系!会员积分、权限和会员发帖、回帖活跃程度关联!

最后于 2020-8-9 00:08 被一半人生编辑 ,原因:
收藏
点赞5
打赏
分享
最新回复 (2)
雪    币: 5991
活跃值: 活跃值 (2264)
能力值: ( LV11,RANK:197 )
在线值:
发帖
回帖
粉丝
一半人生 活跃值 3 2020-8-8 23:35
2
0

图片已补

最后于 2020-8-9 00:09 被一半人生编辑 ,原因:
雪    币: 3422
活跃值: 活跃值 (130)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
皮皮虾啊 活跃值 2020-8-9 10:46
3
0
强!!!
游客
登录 | 注册 方可回帖
返回