首页
社区
课程
招聘
15
[原创]Sandboxie循序渐进耳之进程篇
发表于: 2020-7-15 18:18 25734

[原创]Sandboxie循序渐进耳之进程篇

2020-7-15 18:18
25734

sandboxie没有生态,除了大佬多数和我一样是新手。
开源后业余时间断续学习,啃别人代码,理解他人思路属实不易,源码笔记有点乱序,后经过整理才有这篇文章,分享学习过程中遇到问题和思路。
本篇文章并不是轻量级沙盘实现原理,关注者可以直接略过该文。
共37页,部分内容可能不严谨,但是会随着学习的深入不断完善和改正错误。
预计分为4篇:
1. 进程篇
2. 监控篇
3. toB(正在研究的阶段)
4. 原理机制

Ps:多少参杂了一些逆向,LPC通信Handler处理用windbg附加SbieSvc服务,利用Start.exe挂调试,IDA定位分析/源码辅助学习,调试过程有些问题拿捏不准,感谢前辈的帮助。


SandBoxie循序渐进耳(进程篇)

关于沙箱,工作之外断断续续学习走过不少坑,去年部署Cuckoo用来个人学习优化Monitor。也尝试过开发轻量级沙盘,逆向Sandboxie连皮毛都没学到,幸好今年SandBoxie开源给学习者带来了更多的思路。

作者推荐了代码审计重点,个人喜欢从界面开始熟悉,交互是响应各功能模块第一步,相对比较友好,较快的理解软件流程的来龙去脉。

推荐一个活跃的sandboxie生态论坛分支,也许你会找到想要的答案:

https://www.wilderssecurity.com/forums/sandboxing-virtualization.98/

 


SandBoxie:

源码编译:

1. 如果系统已有wdk7600环境,vs2015配置7600,请参考下述文章:

https://www.cnblogs.com/iBinary/p/8290595.html

2. 解决error LNK2001: 无法解析的外部符号 _memcmp/_wcsnicmp等被引用原因:这个过程浪费了大量的业余时间,引入各类函数lib无济于事,修复skd环境,大量的obj报错最终参考msdn文档解决,在Sandboxie的论坛上也发现了解决方案。

https://docs.microsoft.com/en-us/cpp/c-runtime-library/crt-library-features?view=vs-2019

 

https://community.sophos.com/products/sandboxie/f/forum/119641/important-sandboxie-open-source-code-is-available-for-download

3. 解决MinFilter编译被引用,属性-->链接器-->输入-->附加依赖项目:fltMgr.lib

 


4. 编译成功,不错的开端(vs2017同样编译成功,v141)。

 

 


安装沙盘:

这个步骤该阶段不太重要,不影响源码学习。Install/ReadMe按照步骤来做,NSIS已经更新到了v3,按照步骤安装和替换文件。Sandbox.sln同级目录下创建tools/iconv,解压拷贝,这些工作一次性便适用,不需要重复工。

 

 

DavidXanatos推出了SandBoxie-Plush,使用了QT,如果不加入其它操作系统分析引擎(可移植),Win下面向界面便捷开发更倾向于使用Libuidk实现(基于MFC商用框架已开源-国外人可能也不知道),容易重构。

 

https://github.com/sandboxie-plus/Sandboxie

 

源码学习:

可以下载发行版Sandboxie安装到主机,如果熟悉MFC这将是好的开端,能快速定位代码,控件响应和功能模块,代码重在理解和应用,汲取自己需要的知识。

 

创建沙盘(r3)

Create New SandBox找到对应的类

 

 


1. 输入沙盘名称做规则检测,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 1. 长度小于等于32
if (len <= 32) {
// 2. 字符串是否合规
        for (; i < len; ++i) {
            if (name[i] >= L'0' && name[i] <= L'9')
                continue;
            if (name[i] >= L'A' && name[i] <= L'Z')
                continue;
            if (name[i] >= L'a' && name[i] <= L'z')
                continue;
            if (name[i] == L'_')
                continue;
            break;
        }
}
// 3. 如果违规失败
    if (i == 0 || i != len)
        errmsg = MSG_3667;


2.调用SbieApi_IsBoxEnabled()判断沙盘名称是否已创建,发送API_SBIEDRV_CTLCODEDLL查询,封装了两个重要的参数:

1. API_IS_BOX_ENABLED(Driver API Codes)

2. Name_Address

 

3. Drv驱动 --> api.c(370行开始),对分发进行校验和处理:

3. 校验API_SBIEDRV_CTLCODEDLL

4. 分发api,回调查询code-->API_IS_BOX_ENABLED


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
 __try {
        ProbeForRead(
            buf, sizeof(ULONG64) * API_NUM_ARGS, sizeof(ULONG64));
// 1. 拷贝r3传递过来的数据user_args
        memzero(user_args, sizeof(ULONG64) * API_NUM_ARGS);
        memcpy(user_args, buf, buf_len);
  
        func_code = (ULONG)user_args[0];
// 2. 这里对DerviceCode做校验
        if (func_code > API_FIRST && func_code < API_LAST)
// 3. 获取功能函数指针
            func_ptr = Api_Functions[func_code - API_FIRST - 1];
        if (func_ptr) {
       // 4. 返回执行状态
 status = func_ptr(proc, user_args);
        else
            status = STATUS_INVALID_DEVICE_REQUEST;
} __except (EXCEPTION_EXECUTE_HANDLER) {

Api_functions通过SetFunction初始化(conf_user.c-->106行),初始化分发函数.

Api_SetFunction(API_IS_BOX_ENABLED, Conf_Api_IsBoxEnabled)回调函数处理,如果不存在添加到链中,返回状态码标识是否成功,详细请见代码。

 


沙盘进程运行:

1. 选中沙盘点击运行,也可以直接拖到Dlg中,如下所示:

 


2. 思路有很多种,最简单直接的办法搜索函数,这里拖拽文件响应使用OnDropFiles,该工程也只有这一处拖拽使用,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void CMyFrame::OnDropFiles(HDROP hDrop)
{
WCHAR path[512];
// 1. 响应拖拽消息
    if (! DragQueryFile(hDrop, 0, path, sizeof(path) / sizeof(WCHAR) - 1))
        path[0] = L'\0';
    if (path[0]) {
        CString QuotedPath = L"\"" + CString(path) + L"\"";
// 2. 进入处理函数
        CMyApp::RunStartExe(QuotedPath, CString());
    }
}
void CMyApp::RunStartExe(
    const CString &cmd, const CString &box, BOOL wait, BOOL inherit)
{
// 3. 再次封装调用 
Common_RunStartExe(cmd, box, wait, inherit);
}

3. 沙盘如何将可执行文件加载,这是一个漫长的过程,RunStartExe.cpp --> 35行Common_RunStartExe,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//---------------------------------------------------------------------------
// Common_RunStartExe
//---------------------------------------------------------------------------
// 1. 拼接指令 "/box:__ask__ fileName
    wcscpy(cmdline, L"/box:");
    if (box.IsEmpty())
        wcscat(cmdline, L"__ask__");
    else
        wcscat(cmdline, box);
    wcscat(cmdline, L" ");
    wcscat(cmdline, cmd);
  
// 2. 重点:SbieDll_RunFromHome  Start.exe加载执行文件
if (! SbieDll_RunFromHome(START_EXE, cmdline, &si, &pi));


4. SbieDll_RunFromHome被定义在了proc.c进程模块,最终会通过CreateProcessW来启动文件,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 1. 拼接执行命令格式
    if (si->lpReserved) {
        inherit = TRUE;
        si->lpReserved = NULL;
    else
        inherit = FALSE;
    if (si->dwXCountChars == tzuk && si->dwYCountChars == tzuk) {
        creation_flags = ABOVE_NORMAL_PRIORITY_CLASS;
        si->dwXCountChars = si->dwYCountChars = 0;
    else
        creation_flags = 0;
    memzero(pi, sizeof(PROCESS_INFORMATION));
// 2. 创建进程
    ok = CreateProcess(NULL, path, NULL, NULL, inherit, creation_flags,
                       NULL, NULL, si, pi)


参数:"E:\Program Files\Sandboxie\Start.exe" /box:__ask__ "C:\Users\Administrator\Downloads\powershell.txt"

5. Start.exe,可以选择x64跟踪,也可以选择参数带入源码,解析格式box和_,查询进程信息,box:__ask__,如下所示:

1
2
3
4
if (_wcsnicmp(cmd, L"box:", 4) == 0) {
if (*tmp == L'-' &&
                    (! SbieApi_QueryProcessInfo(
                        (HANDLE)(ULONG_PTR)GetCurrentProcessId(), 0))) {

针对一些指令会进行处理,Parse_Command_Line()返回执行文件路径。

 


Validate_Box_Name选择使用沙盘,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
if (! disable_force_on_this_program) {
// 1. 判断标识
        if (_wcsicmp(BoxName, L"__ask__") == 0 ||
            _wcsicmp(BoxName, L"current") == 0) {
            if (auto_select_default_box) {
                wcscpy(BoxName, L"DefaultBox");
                if (SbieApi_IsBoxEnabled(BoxName) != STATUS_SUCCESS)
                    auto_select_default_box = FALSE;
            }
            if (! auto_select_default_box)
// 2. DoBoxDialog选择使用沙盘,记录沙盘名称
                wcscpy(BoxName, DoBoxDialog());
            if (! BoxName[0]) {
                if (disable_force_on_this_program) {
                    // might be set by DoBoxDialog
                    return FALSE;
                }
                return die(EXIT_FAILURE);
            }
        }
// 3. 判断沙盘是否开启,获取当前状态
        if (SbieApi_IsBoxEnabled(BoxName) != STATUS_SUCCESS) {
  
            if (run_silent)
                ExitProcess(ERROR_UNKNOWN_PROPERTY);
  
            SetLastError(0);
            Show_Error(SbieDll_FormatMessage1(MSG_3204, BoxName));
            return die(EXIT_FAILURE);
        }
    }


6. 通过return die(RestartInSandbox())完成进程启动,RestartInSandbox函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
 dir = (WCHAR *)MyHeapAlloc(1024 * sizeof(WCHAR));
    GetCurrentDirectory(1020, dir);
  
    cmd = (WCHAR *)MyHeapAlloc(16384 * sizeof(WCHAR));
    cmd[0] = L'\"';
    GetModuleFileName(NULL, cmd + 1, MAX_PATH);
    ptr = cmd + wcslen(cmd);
    wcscpy(ptr, L"\" /env:00000000_" SBIE L"_CURRENT_DIRECTORY=\"");
    wcscat(ptr, dir);
    wcscat(ptr, L"\" /env:=Refresh ");
    ptr += wcslen(ptr);
    if (run_elevated_2) {
        wcscpy(ptr, L"/elevate ");
        ptr = cmd + wcslen(cmd);
    }
    if (wait_for_process) {
        wcscpy(ptr, L"/wait ");
        ptr = cmd + wcslen(cmd);
    }
wcscpy(ptr, ChildCmdLine);



7. 调用Callsvc.c(dll模块)处理req,req结构体下文会介绍,数据如下:

1
2
3
rpl = (
PROCESS_RUN_SANDBOXED_RPL
 *)SbieDll_CallServer(&req->h);

 

 


SandBoxie-LPC通信

 

LPC参考:https://bbs.pediy.com/thread-144492.htm


8. 本地通信模块需要熟悉LPC,推荐如下:

https://bbs.pediy.com/thread-144492.htm

https://bbs.pediy.com/thread-162365.htm

Client-Server调试方式,每个人都有自己的学习习惯,文章使用的第二种方式:

1. vs执行start源码,vs执行SbieSvc源码,编译好全部工程,输出目录同一个文件夹下,安装驱动,然后进行调试。(未尝试,理论可行)

2. vs执行start源码,windbg附加SbieSvc服务,IDA+源码辅助学习。


Client:

SbieDll_RunSandboxed()

负责tagPROCESS_RUN_SANDBOXED_REQ结构数据填充,前8bit数据MSG_HEADER结构体。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
// msgid是0x1205,沙盘运行进程
    req->h.msgid = MSGID_PROCESS_RUN_SANDBOXED;
    wcscpy(req->boxname, box_name);
    req->si_flags = si->dwFlags;
    req->si_show_window = si->wShowWindow;
    req->creation_flags = creation_flags;
  
    ptr = (WCHAR *)((ULONG_PTR)req + sizeof(PROCESS_RUN_SANDBOXED_REQ));
// 拷贝执行的命令
    req->cmd_ofs = (ULONG)((ULONG_PTR)ptr - (ULONG_PTR)req);
    req->cmd_len = cmd_len;
    if (cmd_len) {
        wmemcpy(ptr, cmd, cmd_len);
        ptr += cmd_len;
    }
    *ptr = L'\0';
    ++ptr;
// 拷贝dir
    req->dir_ofs = (ULONG)((ULONG_PTR)ptr - (ULONG_PTR)req);
    req->dir_len = dir_len;
    if (dir_len) {
        wmemcpy(ptr, dir, dir_len);
        ptr += dir_len;
    }
    *ptr = L'\0';
    ++ptr;
// 拷贝环境变量(字符巨多)
    req->env_ofs = (ULONG)((ULONG_PTR)ptr - (ULONG_PTR)req);
    req->env_len = env_len;
    if (env_len) {
        wmemcpy(ptr, env, env_len);
        ptr += env_len;
    }
rpl = (PROCESS_RUN_SANDBOXED_RPL *)SbieDll_CallServer(&req->h);

tagPROCESS_RUN_SANDBOXED_REQ结构,后面尾随的是消息块包括执行cmd和dir,env环境,内存数据如下所示:   

 

 


SbieDll_CallServer()

负责将客户端结构数据分发至服务端处理。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
_FX MSG_HEADER *SbieDll_CallServer(MSG_HEADER *req)
{
    static volatile ULONG last_sequence = 0;
    UCHAR curr_sequence;
    THREAD_DATA *data = Dll_GetTlsData(NULL);
    UCHAR spaceReq[MAX_PORTMSG_LENGTH], spaceRpl[MAX_PORTMSG_LENGTH];
    NTSTATUS status;
    PORT_MESSAGE *msg;
    UCHAR *buf, *msg_data;
    ULONG buf_len, send_len;
    MSG_HEADER *rpl;
  
    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);
// 1. 连接\\RPC Control\\SbieSvcPort
        if (! SbieDll_ConnectPort(Silent))
            return NULL;
    }
  
  
// 连接成功,循环Dispatch
    curr_sequence = (UCHAR) InterlockedIncrement(&last_sequence);
  
    buf = (UCHAR *)req;
    buf_len = req->length;
  
    while (buf_len) {
  
        msg = (PORT_MESSAGE *)spaceReq;
  
        memzero(msg, data->SizeofPortMsg);
        msg_data = (UCHAR *)msg + data->SizeofPortMsg;
  
        if (buf_len > data->MaxDataLen)
            send_len = data->MaxDataLen;
        else
            send_len = buf_len;
  
        msg->u1.s1.DataLength = (USHORT)send_len;
        msg->u1.s1.TotalLength = (USHORT)(data->SizeofPortMsg + send_len);
  
        memcpy(msg_data, buf, send_len);
  
        if (buf == (UCHAR *)req) {
  
            msg_data[3] = curr_sequence;
        }
  
        buf += send_len;
        buf_len -= send_len;
// 发送至server,等待回复
        status = NtRequestWaitReplyPort(data->PortHandle,
                    (PORT_MESSAGE *)spaceReq, (PORT_MESSAGE *)spaceRpl);
        if (! NT_SUCCESS(status))
            break;
  
        msg = (PORT_MESSAGE *)spaceRpl;
  
        if (buf_len && msg->u1.s1.DataLength) {
            SbieApi_Log(2203, L"early reply");
            return NULL;
        }
}


Service:

Sandboxie客户端循环发送MSG消息到服Svc.Pipserver.cpp(SbieSvcPort),服务端由NtReplyWaitReceivePort循环等待客户端数据,源码中封装如下:

NtReplyWaitReceivePort():

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
void PipeServer::Thread()
{
    NTSTATUS status;
    UCHAR space[MAX_PORTMSG_LENGTH], spaceReply[MAX_PORTMSG_LENGTH];
    PORT_MESSAGE *msg = (PORT_MESSAGE *)space;
    HANDLE hReplyPort;
    PORT_MESSAGE *ReplyMsg;
  
    hReplyPort = m_hServerPort;
    ReplyMsg = NULL;
  
    while (1) {
  
        if (ReplyMsg) {
  
            memcpy(spaceReply, ReplyMsg, ReplyMsg->u1.s1.TotalLength);
            ReplyMsg = (PORT_MESSAGE *)spaceReply;
        }
  
        status = NtReplyWaitReceivePort(hReplyPort, NULL, ReplyMsg, msg);
  
        if (! m_hServerPort)    // service is shutting down
            break;
  
        if (ReplyMsg) {
  
            hReplyPort = m_hServerPort;
            ReplyMsg = NULL;
  
            if (! NT_SUCCESS(status))
                continue;       // ignore errors on client port
  
        else if (! NT_SUCCESS(status)) {
  
            if (status == STATUS_UNSUCCESSFUL) {
                // can be considered a warning rather than an error
                continue;
            }
            break;              // abort on errors on server port
        }
  
        if (msg->u2.s2.Type == LPC_CONNECTION_REQUEST) {
            PortConnect(msg);
  
        else if (msg->u2.s2.Type == LPC_REQUEST) {
// 查找客户端client
            CLIENT_THREAD *client = (CLIENT_THREAD *)PortFindClient(msg);
            if (! client)
                continue;
            if (! client->replying)
                PortRequest(client->hPort, msg, client);
            msg->u2.ZeroInit = 0;
            if (client->replying)
                PortReply(msg, client);
            else {
                msg->u1.s1.DataLength = (USHORT) 0;
                msg->u1.s1.TotalLength = sizeof(PORT_MESSAGE);
            }
            hReplyPort = client->hPort;
            ReplyMsg = msg;
            client->in_use = FALSE;
  
        else if (msg->u2.s2.Type == LPC_PORT_CLOSED ||
                   msg->u2.s2.Type == LPC_CLIENT_DIED) {
            PortDisconnect(msg);
        }
    }
}


构造PORT_MESSAGE数据包,data->MaxDataLen数值是288bit,TotalLength总大小是328bit,包含结构体本身大小,LPC传输超过256bit进行内存共享传输。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
      msg = (PORT_MESSAGE *)spaceReq;
  
        memzero(msg, data->SizeofPortMsg);
        msg_data = (UCHAR *)msg + data->SizeofPortMsg;
  
        if (buf_len > data->MaxDataLen)
            send_len = data->MaxDataLen;
        else
            send_len = buf_len;
  
        msg->u1.s1.DataLength = (USHORT)send_len;
        msg->u1.s1.TotalLength = (USHORT)(data->SizeofPortMsg + send_len);
  
        memcpy(msg_data, buf, send_len);
.......
// buf_len <= 0时候意味着客户端传输完成
        buf += send_len;
        buf_len -= send_len;

windbg下断SbieSvc.exe-->NtReplyWaitReceivePort,客户端发送MSG至服务端消息队列,也可以直接审计源码,如下所示:

 

Sbiesvc.exe拖入ida,定位代码段:

 

 

LPC处理LPC_CONNECTION_REQUEST,LPC_REQUEST,LPC_PORT_CLOSED,LPC_CLIENT_DIED类型。

客户端client->replying标志,客户端在循环传输过程中调用PortRequest。    

1
2
    if (! client->replying)
                PortRequest(client->hPort, msg, client);

PortRequest():

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
     if (! client->buf_hdr) {
  
        ULONG *msg_Data = (ULONG *)msg->Data;
        ULONG msgid = msg_Data[1];
  
        client->sequence = ((UCHAR *)msg_Data)[3];
        ((UCHAR *)msg_Data)[3] = 0;
  
        buf_len = msg_Data[0];
  
        if (msgid && buf_len &&
                buf_len < MAX_REQUEST_LENGTH &&
                buf_len >= sizeof(MSG_HEADER) &&
                buf_len >= msg->u1.s1.DataLength) {
   // 申请内存
            client->buf_hdr = AllocMsg(buf_len);


 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
            client->buf_ptr = (UCHAR *)client->buf_hdr;
        }
  
        if (! client->buf_hdr) {
            client->sequence = 0;
            goto finish;
        }
// 拷贝客户端发来的消息
    memcpy(client->buf_ptr, msg->Data, msg->u1.s1.DataLength);
    client->buf_ptr += msg->u1.s1.DataLength;
buf_len += msg->u1.s1.DataLength;
  
// MSG_HEADER msgid
    client->buf_hdr = (MSG_HEADER *)buf_ptr;
client->buf_ptr = (UCHAR *)buf_ptr 
client->replying = TRUE;
  
// 判断是否接收数据完毕
    if (buf_len < client->buf_hdr->length)
        return;
// 接收完毕,LPC handler功能分发处理
buf_ptr = CallTarget(client->buf_hdr, PortHandle, msg);


CallTarget():

负责LPC Handler函数分发,LPC Handler根据Msgid执行功能函数。

 

 

定位分发函数,断点0x1205观察,通过搜索定位函数代码,如下所示:

*ProcessServer::Handler()

 


IDA-Windbg对比源码无误,下断g运行,如下所示:

 

 

运行后会触发LPC回调分发,MSGID_PROCESS_RUN_SANDBOXED调用号断下1205,ProcessServer.cpp(line:428),启动新进程主模块。

*ProcessServer::RunSandboxedHandler()

1
MSG_HEADER *ProcessServer::RunSandboxedHandler(MSG_HEADER *msg)

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

最后于 2020-7-16 15:03 被一半人生编辑 ,原因:
收藏
免费 15
支持
分享
赞赏记录
参与人
雪币
留言
时间
東陽不列山
感谢你的贡献,论坛因你而更加精彩!
2025-2-14 04:17
wx_好一脚头球
为你点赞~
2023-7-13 18:32
PLEBFE
为你点赞~
2022-7-27 01:23
心游尘世外
为你点赞~
2022-7-26 23:12
飘零丶
为你点赞~
2022-7-17 02:47
ToCrack
为你点赞~
2021-5-18 16:49
afa9040e
为你点赞~
2020-12-21 12:23
低调putchar
为你点赞~
2020-12-9 19:18
yangya
为你点赞~
2020-8-21 11:05
红金龙e晓楼
为你点赞~
2020-8-4 00:17
MagicFuzzX
为你点赞~
2020-7-31 18:25
Editor
为你点赞~
2020-7-16 15:21
阿尔斯兰
为你点赞~
2020-7-15 23:16
dx苹果的心愿
为你点赞~
2020-7-15 18:28
一半人生
为你点赞~
2020-7-15 18:19
最新回复 (25)
雪    币: 1400
活跃值: (176)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
表哥,word2016提示文件无法打开,内容有问题
2020-7-15 23:19
0
雪    币: 2508
活跃值: (13089)
能力值: ( LV12,RANK:312 )
在线值:
发帖
回帖
粉丝
3
阿尔斯兰 表哥,word2016提示文件无法打开,内容有问题
我尝试了一下,文档正常,手机也可以查看
2020-7-16 06:45
0
雪    币: 407
活跃值: (1932)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4

2020-7-16 09:14
0
雪    币: 10716
活跃值: (4870)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
建议转PDF,里面加一些声明什么的,做好知识产权保护,直接放docx容易被人拿去做盗版。
2020-7-16 09:20
0
雪    币: 26660
活跃值: (1068)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
修改下后缀名,.docx去掉x,即改为.doc再尝试打开试试
2020-7-16 09:23
0
雪    币: 23352
活跃值: (3462)
能力值: (RANK:648 )
在线值:
发帖
回帖
粉丝
7
楼主您好,您的文章质量较高,但是放在附件中会有两个问题:一是楼上的朋友们说的直接放docx容易被人拿去做盗版,不利于知识产权保护;二是无法被搜索引擎搜到,不利于知识的传播与学习。
有一个快速发帖的方法:将word文档另存为html,然后全部复制粘贴到编辑框中。
2020-7-16 10:13
0
雪    币: 1468
活跃值: (4733)
能力值: ( LV9,RANK:220 )
在线值:
发帖
回帖
粉丝
8
suiyingjie 修改下后缀名,.docx去掉x,即改为.doc再尝试打开试试
太棒了,一直打不开刚好解决
2020-7-16 14:13
0
雪    币: 2508
活跃值: (13089)
能力值: ( LV12,RANK:312 )
在线值:
发帖
回帖
粉丝
9
KevinsBobo 楼主您好,您的文章质量较高,但是放在附件中会有两个问题:一是楼上的朋友们说的直接放docx容易被人拿去做盗版,不利于知识产权保护;二是无法被搜索引擎搜到,不利于知识的传播与学习。 有一个快速发帖的方 ...
思考不周,感谢版主,虽然排版有些难堪已更新
2020-7-16 14:29
0
雪    币: 2508
活跃值: (13089)
能力值: ( LV12,RANK:312 )
在线值:
发帖
回帖
粉丝
10
Willarcap 建议转PDF,里面加一些声明什么的,做好知识产权保护,直接放docx容易被人拿去做盗版。
感谢
2020-7-16 14:30
0
雪    币: 1664
活跃值: (2193)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
11
感谢分享!!!!!!
2020-7-16 14:43
0
雪    币: 40
活跃值: (701)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
你好,请问vs2017用的什么版本wdk
2020-7-16 15:00
0
雪    币: 35814
活跃值: (64446)
能力值: (RANK:135 )
在线值:
发帖
回帖
粉丝
13
感谢分享~
2020-7-16 15:22
0
雪    币: 2508
活跃值: (13089)
能力值: ( LV12,RANK:312 )
在线值:
发帖
回帖
粉丝
14
killerfive 你好,请问vs2017用的什么版本wdk
vs2017(141) + wdk7600
2020-7-16 18:55
0
雪    币: 418
活跃值: (4247)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
15
表哥太强了,make一下  = =|
2020-7-16 19:04
0
雪    币: 8448
活跃值: (2925)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
请教一下,ida怎么得到switch语句的
2020-7-18 04:24
0
雪    币: 300
活跃值: (2647)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
mark
2020-7-20 10:41
0
雪    币: 12
活跃值: (783)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
lpc我记得不支持win10的那些app
2020-7-31 18:25
0
雪    币: 0
活跃值: (35)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
感谢大佬分享!希望大佬继续更新。我现在也要研究这东西,希望可以相互交流
2020-8-8 17:52
0
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
20
大佬我想问一下,你有遇到过报错SBIE1402和SBIE1409错误吗?  我这边是提示templates.ini文件和sandboxie.ini文件找不到Nt Status Codes是C0000034 Object not found,但是我在其他目录下确实有这两个ini文件。非常感谢!
2020-12-9 15:53
0
雪    币: 239
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
21

感谢分享,非常不错,谢谢 !

最后于 2020-12-25 09:26 被lyanl编辑 ,原因:
2020-12-15 09:26
0
雪    币: 3037
活跃值: (369)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
22
大佬膜拜
2020-12-20 23:01
0
雪    币: 178
活跃值: (396)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
23
你好,最近我也在研究sandboxie,请问要在沙盘中程序是在什么时候真正执行的呢,它的内存又是如何布局管理的?
2021-9-22 10:08
0
雪    币: 204
活跃值: (49)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
24
大佬膜拜
2022-5-31 21:19
0
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
25
大佬膜拜 
2023-5-30 17:24
0
游客
登录 | 注册 方可回帖
返回

账号登录
验证码登录

忘记密码?
没有账号?立即免费注册