如何查看手机沙箱进程_如何使任何进程与事务性NTFS一起工作:我编写Windows沙箱的第一步

本文探讨了Windows内核中的事务性NTFS机制,如何利用该机制强制进程在预定义的事务中运行,以及如何实现进程间的事务切换。通过修改线程的事务上下文,可以控制进程对文件系统的访问。此外,文章还提到了WoW64环境下的处理和一些未解决的问题,例如安装应用时的事务处理。
摘要由CSDN通过智能技术生成

如何查看手机沙箱进程

TransactionMaster

One of the modules in the Windows kernel provides support for combining a set of file operations into an entity known as a transaction. Just like in databases, these entities are isolated and atomic. You can make some changes to the file system that won't be visible outside until you commit them. Or, as an alternative, you can always rollback everything. In any case, you act upon the group of operations as a whole. Precisely what needed to preserve consistency while installing software or updating our systems, right? If something goes wrong — the installer or even the whole system crashes — the transaction rolls back automatically.

Windows内核中的一个模块提供了将一组文件操作组合到一个称为事务的实体中的支持。 就像在数据库中一样,这些实体是孤立的原子的 。 您可以对文件系统进行一些更改,除非您提交它们,否则这些更改将在外部看不到。 或者,您也可以始终回滚所有内容。 无论如何,您要对整个操作组进行操作。 正是在安装软件或更新我们的系统时需要什么来保持一致性 ,对吗? 如果出现问题(安装程序乃至整个系统崩溃),事务将自动回滚。

From the very first time I saw an article about this incredible mechanism, I always wondered how the world would look like from the inside. And you know what? I just discovered a truly marvelous approach to force any process to operate within a predefined transaction, which this margin is too narrow to contain. Furthermore, most of the time, it does not even require administrative privileges.

从我第一次看到有关这种令人难以置信的机制的文章时,我就一直想知道从内部看世界会是什么样。 你知道吗? 我刚刚发现了一种真正奇妙的方法,可以强制任何流程在预定义的事务中运行, 该边距太窄而无法容纳 。 此外,在大多数情况下,它甚至不需要管理特权。

Let's then talk about Windows internals, try out a new tool, and answer one question: what does it have to do with sandboxes?

然后,让我们讨论Windows的内部原理,尝试一种新工具,并回答一个问题:它与沙箱有什么关系?

资料库 (Repository)

Those who want to start experimenting right away are welcome at the project's page on GitHub: TransactionMaster.

欢迎那些想要立即开始尝试的人在GitHub上的项目页面: TransactionMaster

理论 (Theory)

Introduction of Transactional NTFS, also known as TxF, in Windows Vista was a revolutionary step toward sustaining system consistency and, therefore, stability. By exposing this functionality directly to the developers, Microsoft made it possible to dramatically simplify error handling in all of the components responsible for installing and updating software. The task of maintaining a backup plan for all possible file-system failures became a job of the OS itself, which started providing a full-featured ACID semantics on demand.

在Windows Vista中引入事务性NTFS(也称为TxF)是朝着维持系统一致性和稳定性迈出的革命性一步。 通过直接向开发人员展示此功能,Microsoft可以极大地简化负责安装和更新软件的所有组件中的错误处理。 维护所有可能的文件系统故障的备份计划的任务已成为OS本身的工作,它开始按需提供全功能的ACID语义

To provide this new instrument, Microsoft introduced a set of API functions that duplicated existing functionality, but within a context of transactions. The transaction itself became a new kernel object, alongside existing ones like files, processes, and synchronization primitives. In the simplest scenario, the application creates a new transaction using CreateTransaction, performs the required operations (CreateFileTransacted, MoveFileTransacted, DeleteFileTransacted, etc.), and then commits or rolls it back with CommitTransaction/RollbackTransaction.

为了提供这种新工具,Microsoft引入了一组API函数,这些API函数可以复制现有功能,但是要在事务上下文中进行。 事务本身与文件,进程和同步原语之类的现有对象一起成为新的内核对象。 在最简单的情况下,应用程序使用CreateTransaction创建一个新事务,执行所需的操作( CreateFileTransactedMoveFileTransactedDeleteFileTransacted等),然后使用CommitTransaction / RollbackTransaction提交或RollbackTransaction

Let's take a look at the architecture of these new functions. We know, that the official API layer from libraries such as kernel32.dll does not invoke the kernel directly, but converts the parameters and forwards the call to ntdll.dll instead. Which then, issues a syscall. Surprisingly, there is no sign of any additional -Transacted functions on both the ntdll and kernel side of the call.

让我们看一下这些新功能的体系结构。 我们知道,来自诸如kernel32.dll库的官方API层不会直接调用内核,而是会转换参数并将调用转发给ntdll.dll 。 然后,发出系统调用。 令人惊讶的是, 在调用的ntdll和内核端都没有任何其他-Transacted函数的迹象。

API layers

The definitions of these Native API functions haven't changed in decades, so there is no extra parameter to specify a transaction. How does the kernel know which one to use then? The answer is simple yet promising: each thread has a designated field, where it stores a handle to the current transaction. This variable resides in a specific region of memory called TEB — Thread Environmental Block. As for other well-known fields located here as well, I can name the last error code and the thread ID.

这些Native API函数的定义几十年来没有改变,因此没有多余的参数来指定事务。 内核如何知道该使用哪个? 答案很简单,但很有希望:每个线程都有一个指定的字段,在该字段中存储当前事务的句柄。 此变量位于称为TEB(线程环境块)的特定内存区域中。 至于也位于此处的其他知名字段,我可以命名最后一个错误代码线程ID

Therefore, all functions with the -Transacted suffix set the current transaction field in TEB, call the corresponding non-transacted API, and restore the previous value. To achieve this goal, they use a pair of pretty straightforward routines called RtlGetCurrentTransaction/RtlSetCurrentTransaction from ntdll. They provide a sufficient level of abstraction, which comes in handy in the case of WoW64, more on that later.

因此,带有-Transacted后缀的所有函数都将在TEB中设置当前事务字段,调用相应的未事务处理的API,并恢复先前的值。 为了实现此目标,他们使用了ntdll的一对非常简单的例程,称为RtlGetCurrentTransaction / RtlSetCurrentTransaction 。 它们提供了足够的抽象水平,在WoW64的情况下会派上用场,以后会更多。

What does it mean for us? By changing a variable in the memory, we can control, in a context of which transaction the process accesses the file system. There is no need to install any hooks or kernel-mode callbacks, all we need is to deliver the handle to the target process and modify a couple of bytes of memory per each thread. Sounds surprisingly easy, but the result must be astonishing!

对我们意味着什么? 通过更改内存中的变量,我们可以控制进程在哪个事务中访问文件系统。 无需安装任何钩子或内核模式回调,我们所需要做的就是将句柄传递给目标进程并为每个线程修改几个内存字节。 听起来异常简单,但结果一定令人惊讶!

陷阱 (Pitfalls)

The first working concept revealed plenty of peculiar details. To my great delight, Far Manager, which I use as a replacement for Windows Explorer, is perfectly fine with transaction hot-switching. But I also spotted a couple of programs, on which my method didn't have expected effect since they create new threads for file operations. An example of the second class representative is WinFile. Just as a reminder, the current transaction is a per-thread feature. Initially, it was a hole in the plot, since tracking thread creation out-of-process is quite hard, considering the time-sensitivity of this operation.

第一个工作概念揭示了许多独特的细节。 令我高兴的是,我使用Far Manager替代了Windows资源管理器,它非常适合事务热切换。 但是我还发现了几个程序,由于它们为文件操作创建了新线程,因此它们的方法没有达到预期效果。 第二类代表的一个示例是WinFile 。 提醒一下,当前事务是每个线程的功能。 最初,这是情节中的一个漏洞,因为考虑到此操作的时间敏感性,很难在进程外跟踪线程创建。

线程跟踪DLL (Thread-tracking DLL)

Luckily, getting synchronous notifications about thread creation is extremely simple inside the context of the target process. All we need is to craft a DLL, that propagates the current transaction to new threads, the module loader from ntdll will handle the rest. Every time

幸运的是,在目标进程的上下文中,获取有关线程创建的同步通知非常简单。 我们需要做的是制作一个DLL,将当前事务传播到新线程, ntdll的模块加载器将处理其余的事情。 每次

* (*)

a new thread arrives into the process, it will trigger our entry-point with the

一个新线程进入流程,它将触发我们的入口点,

DLL_THREAD_ATTACHDLL_THREAD_ATTACH

* Strictly speaking, this callback does not occur under every possible condition. Now and then, you will see one or two auxiliary threads hanging around without a transaction. Most of the time, these are the threads from the working pool of the module loader itself. The reason being, DLL notifications happen under the loader lock, which implies a variety of limitations, including the ability to load more modules. And that is indeed what such threads need to accomplish, parallelizing the file access in the meantime. Hence, an exception exists to prevent deadlocks: if the caller specifies the THREAD_CREATE_FLAGS_SKIP_THREAD_ATTACH flag while creating a thread with the help of NtCreateThreadEx, the DLL-notification callbacks don't get triggered.

*严格来说,这种回调不会在每种可能的情况下发生。 时不时地,您会看到一个或两个辅助线程在没有事务的情况下徘徊。 大多数情况下,这些是来自模块加载器本身的工作池中的线程。 原因是,DLL通知发生在加载程序锁下 ,这意味着多种限制,包括加载更多模块的能力。 确实是这些线程需要完成的工作,与此同时并行进行文件访问。 因此,存在一个防止死锁的异常:如果调用方在NtCreateThreadEx的帮助下创建线程时指定THREAD_CREATE_FLAGS_SKIP_THREAD_ATTACH标志,则不会触发DLL通知回调。

启动Windows资源管理器 (Starting Windows Explorer)

Unfortunately, there are still some programs left that can't handle transaction hot-switching well, and Windows Explorer is one of them. I can't reliably diagnose the issue. It is a complex application that usually has a lot of handles opened, and if the context of a transaction invalidates some of them, it might result in a crash. Anyway, the universal solution to such problems is to make sure the process runs within a consistent context from the very first instruction it executes.

不幸的是,仍然有一些程序无法很好地处理事务热切换,Windows资源管理器就是其中之一。 我无法可靠地诊断问题。 它是一个复杂的应用程序,通常会打开许多​​句柄,如果事务的上下文使其中的一些无效,则可能导致崩溃。 无论如何,针对此类问题的通用解决方案是确保过程从其执行的第一条指令开始便在一致的上下文中运行。

Thus, I implemented an option to perform DLL injection right away when creating a new process. And it turned out to be enough to fix crashing. Although, since Explorer intensively uses out-of-process COM, previewing, and some other features still don't work on modified files.

因此,我实现了一个在创建新进程时立即执行DLL注入的选项。 结果证明足以解决崩溃问题。 但是,由于资源管理器大量使用进程外COM,因此预览和其他一些功能仍然无法在修改后的文件上使用。

那WoW64呢? (What About WoW64?)

The compatibility benefits that Windows-on-Windows 64-bit subsystem provides are sincerely remarkable. However, taking into account its specifics often becomes tedious during system programming. Previously I mentioned, that the behavior of Rtl[Get/Set]CurrentTransaction becomes a bit more intricate in this case. Since such processes work with a distinctive size of pointers than the rest of the system, each WoW64 thread maintains two TEBs associated with it: the OS itself expects it to have a 64-bit one, and the application requires a 32-bit one as well to work correctly. And even though, from the kernel's perspective, the native TEB takes precedence, there is some extra code in these functions to ensure the corresponding values always match. Anyway, it's essential to keep all these peculiarities in mind when implementing new functionality.

Windows-on-Windows 64位子系统提供的兼容性优势非常出色。 但是,在系统编程期间,考虑到它的细节通常变得很乏味。 之前我提到过,在这种情况下Rtl[Get/Set]CurrentTransaction的行为变得更加复杂。 由于此类进程使用的指针大小比系统其他部分大,因此每个WoW64线程都维护两个与之关联的TEB:OS本身希望它具有64位,而应用程序则需要32位。正常工作。 即使从内核的角度来看,本机TEB优先,但这些函数中还有一些额外的代码可确保相应的值始终匹配。 无论如何, 在实现新功能时必须牢记所有这些特性。

未解决的问题 (Unsolved Problems)

As sad as it is, the first usage scenario that comes to our minds — installing applications in this mode — doesn't work well for now. First of all, installers frequently create supplementary processes, and I haven't implemented capturing child processes into the same transaction yet. I see multiple ways of doing so, but it might take a while. Another major problem arises when we try to execute binaries that get unpacked during the installation, and, hence, don't exist anywhere else. Considering that NtCreateUserProcess and, therefore, CreateProcess, ignore the current transaction for some reason, solving this issue will probably require some creativity, combined with a bunch of sophisticated tricks. Of course, we can always rely on NtCreateProcessEx as a last resort, but fixing compatibility might become a nightmare in this case.

令人难过的是,我们想到的第一个使用场景(以这种模式安装应用程序)目前无法正常工作。 首先,安装程序经常创建补充流程,而我尚未实现将子流程捕获到同一事务中。 我看到了这样做的多种方法,但可能需要一段时间。 当我们尝试执行在安装过程中解压缩的二进制文件时出现了另一个主要问题,因此,其他任何地方都不存在。 考虑到NtCreateUserProcess以及因此的CreateProcess出于某种原因而忽略了当前事务,解决此问题可能需要一定的创造力,并结合许多复杂的技巧。 当然,我们始终可以将NtCreateProcessEx作为最后的手段,但是在这种情况下,修复兼容性可能会成为噩梦。

By the way, it reminds me of a story I read about a malware that managed to fool a couple of naïve antiviruses applying a similar approach. It used to drop a payload into a transaction, launch it, and roll back the changes to cover the tracks, enabling the process to execute without an image on the disk. Even if the logic of “no file — no threat” sounds silly, it might not have been the case for some AVs, at least a few years ago.

顺便说一句,它使我想起一个我读过的关于一个恶意软件的故事,该恶意软件使用相似的方法设法欺骗了一些简单的杀毒软件。 它曾经将有效负载放入事务中,启动它,然后回滚所做的更改以覆盖轨道,从而使该过程得以执行而磁盘上没有映像。 即使“无文件无威胁”的逻辑听起来很愚蠢,但至少在几年前,某些AV可能并非如此。

什么是沙箱? (What's With Sandboxing?)

Take a look at this screenshot below. You can see three programs completely disagreeing on the content of the same folder. They all work inside of three different transactions. That's the power of isolation in ACID semantics.

在下面查看此屏幕截图。 您会看到三个程序完全不同意同一文件夹的内容。 它们都在三个不同的事务中工作。 这就是ACID语义中隔离的力量。

Transaction isolation

My program is not a sandbox whatsoever; it lacks one crucial piece — a security boundary. I know that some companies still manage to sell similar products, presenting them as real sandboxes, shame on them, what can I say. And you might think: How can you ever make it a sandbox, even being a debugger you can't reliably prevent a process from modifying a variable that controls the transaction, it resides in its memory after all. Fair enough, that's why I have to have another marvelous trick in my sleeve, which will eventually help me finish this project and which I won't reveal for now. Yes, I am planning to create a completely user-mode sandbox with file system virtualization. In the meantime, use Sandboxie and keep experimenting with AppContainers. Stay tuned.

我的程序根本不是沙盒; 它缺少一个关键要素- 安全边界 。 我知道有些公司仍然设法销售类似的产品,将它们呈现为真实的沙箱,让他们感到羞耻,我能说什么。 您可能会想:您如何才能使其成为沙盒,即使是调试器,您也无法可靠地阻止进程修改控制事务的变量,该变量毕竟驻留在其内存中。 公平地说,这就是为什么我必须袖子再加上一个绝妙的技巧,这最终将帮助我完成这个项目,而现在我不会透露。 是的,我计划创建一个具有文件系统虚拟化功能的完全用户模式的沙箱。 同时,使用Sandboxie并继续尝试AppContainers 。 敬请关注。

Project's repository on GitHub: TransactionMaster.

GitHub上项目的存储库: TransactionMaster

翻译自: https://habr.com/en/post/485788/

如何查看手机沙箱进程

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值