我们有一个第三方原生应用程序(相信用 CI 编写),我们希望在一台机器上运行多个实例。
然而,应用程序从一个特定的注册表项读取和写入,以便找到配置文件的位置。它在运行期间连续读取此位置。注册表项位于 HKLM 中。这意味着,如果我们尝试运行具有 2 个不同位置的配置文件的应用程序的 2 个不同实例,则进程会互相踩踏。
是否可以“虚拟化”进程正在使用的注册表(或在沙箱中运行每个进程),以便它们都可以认为它们正在写入单个位置,但实际上它们正在从不同的地方写入和读取,他们赢了不踩对方脚趾?
我们有一个第三方原生应用程序(相信用 CI 编写),我们希望在一台机器上运行多个实例。
然而,应用程序从一个特定的注册表项读取和写入,以便找到配置文件的位置。它在运行期间连续读取此位置。注册表项位于 HKLM 中。这意味着,如果我们尝试运行具有 2 个不同位置的配置文件的应用程序的 2 个不同实例,则进程会互相踩踏。
是否可以“虚拟化”进程正在使用的注册表(或在沙箱中运行每个进程),以便它们都可以认为它们正在写入单个位置,但实际上它们正在从不同的地方写入和读取,他们赢了不踩对方脚趾?
虚拟化程序有多种选择:
https ://en.wikipedia.org/wiki/Portable_application_creators
创建自己的虚拟化软件要复杂得多,并且需要使用 Windows SDK 进行编程和挂钩库调用。
然而,一个更简单的选项不需要为程序的每个副本设置和运行额外的软件,我建议创建程序的多个副本并十六进制编辑每个可执行文件。
根据需要制作应用程序的多个副本,然后在十六进制编辑器中打开应用程序文件并搜索注册表项的名称,即:
HKLM\System\CurrentControlSet\Control\Session Manager
然后将每个不同版本的最后一个字节更改为一个数字(1 个字节,0-9),即:
HKLM\System\CurrentControlSet\Control\Session Manage1
HKLM\System\CurrentControlSet\Control\Session Manage2
HKLM\System\CurrentControlSet\Control\会话管理3
对于超过 10 个差异(2 个字节,00-99),使用最后两个字节:
HKLM\System\CurrentControlSet\Control\Session Manag01
HKLM\System\CurrentControlSet\Control\Session Manag02
HKLM\System\CurrentControlSet\Control\Session Manag03
虽然 Joshua 的解决方案适用于这个特定的应用程序,但它可能不适用于其他应用程序(例如,在代码中构建注册表路径或对应用程序进行签名时)。
因此,我建议使用DLL 注入并拦截对 、 等的调用RegOpenKey(Ex)
。RegCreateKey(Ex)
这样,您可以在将调用传递给真正的 Windows 之前修改注册表路径Advapi32.dll
。
一些关于 API 挂钩的精彩文章:
是的,Sandboxie可以运行一个应用程序的多个实例,每个实例都在它自己的“沙盒”中,它认为这是整个宇宙。但如果需要,您也可以通过常规方式直接访问数据。
换句话说,Sandboxie 可以让您查看在应用程序操作中所做的所有注册表更改,并且您可以根据需要回滚它们。
是的,您可以虚拟化应用程序,这种技术称为应用程序虚拟化。试试http://www.cameyo.com/。Cameyo 是用于构建虚拟应用程序的软件。
虚拟应用程序是一个单独的 EXE 文件,其中包含整个应用程序,包括文件、DLL 和注册表。虚拟应用程序与您的系统隔离,无需安装即可从一台计算机复制和移动到另一台计算机。