如何在 C#/Win32 api 中找到 Windows 应用程序执行别名的目标?

2023-12-19

Microsoft Windows 终端(通过 Microsoft Store 安装)创建 0 字节wt.exe文件是一个Windows 执行别名 https://www.tiraniddo.dev/2019/09/overview-of-windows-execution-aliases.html。 AFAIK 它类似于符号链接,除了它似乎在CreateProcessAPI 级别,而不是在文件系统中转换的符号链接。

在 powershell 中:

❯ dir ~\AppData\Local\Microsoft\WindowsApps\wt.exe

Mode    Name
----    ----
la---   wt.exe -> C:\Program Files\WindowsApps\Microsoft.WindowsTerminal_1.0.1401.0_x64__8wekyb3d8bbwe\WindowsTerminal.exe

❯ Get-Item .\wt.exe | fl

Name           : wt.exe
Length         : 0
LinkType       : AppExeCLink
Target         : C:\Program Files\WindowsApps\Microsoft.WindowsTerminal_1.0.1401.0_x64__8wekyb3d8bbwe\WindowsTerminal.exe

我无法找到这些“新”别名的正确文档。甚至谷歌PSAppExeCLink值不是很有用。

我需要一种快速方法来解析 C# 应用程序中的执行别名(获取目标文件)。鉴于我的要求,我更喜欢非托管(Win32 Api)方式,而不是添加对慢速 WMI 或外部 300kb nuget 包的引用。

Thanks!


我在我的项目中遇到了同样的问题系统工具库 https://github.com/JFLarvoire/SysToolsLib%22,这些新型链接令人窒息。该库用 C 语言编写,并使用 WIN32 API。

这是我到目前为止发现的:

  • 在 Windows 中引入三年后,cmd.exe 和 PowerShell 5.1 仍然不知道 App Exec 链接,并将它们报告为 0 字节文件。

    但 PowerShell Core 7 了解它们:

    PS C:\Temp> dir $env:LOCALAPPDATA\Microsoft\WindowsApps | ?{$_.LinkType} | select Name,LinkType,Target
    
    Name                        LinkType    Target
    ----                        --------    ------
    GameBarElevatedFT_Alias.exe AppExeCLink C:\Program Files\WindowsApps\Microsoft.XboxGamingOverlay_5.420.11102.0_x64__8w...
    MicrosoftEdge.exe           AppExeCLink C:\WINDOWS\system32\SystemUWPLauncher.exe
    python.exe                  AppExeCLink C:\Program Files\WindowsApps\Microsoft.DesktopAppInstaller_1.11.3162.0_x64__8w...
    python3.exe                 AppExeCLink C:\Program Files\WindowsApps\Microsoft.DesktopAppInstaller_1.11.3162.0_x64__8w...
    ubuntu.exe                  AppExeCLink C:\Program Files\WindowsApps\CanonicalGroupLimited.UbuntuonWindows_2004.2020.8...
    ubuntu1804.exe              AppExeCLink C:\Program Files\WindowsApps\CanonicalGroupLimited.Ubuntu18.04onWindows_2020.1...
    WinFR.exe                   AppExeCLink C:\Program Files\WindowsApps\Microsoft.WindowsFileRecovery_0.1.13492.0_x64__8w...
    winget.exe                  AppExeCLink C:\Program Files\WindowsApps\Microsoft.DesktopAppInstaller_1.11.3162.0_x64__8w...
    wt.exe                      AppExeCLink C:\Program Files\WindowsApps\Microsoft.WindowsTerminal_1.4.3243.0_x64__8wekyb3...
    
    PS C:\Temp>
    
  • 这些应用程序执行链接是 NTFS 重新分析点,标记为
    IO_REPARSE_TAG_APPEXECLINK = 0x8000001b。

    您可以使用 WIN32 API 在 C/C++/C# 程序中读取它们DeviceIoControl()FSCTL_GET_REPARSE_POINT控制代码。

    My 读链接.c https://github.com/JFLarvoire/SysToolsLib/blob/master/C/MsvcLibX/src/readlink.c模块包含一个ReadReparsePointW()例行程序证明了这一点。

  • 您可以通过运行以下命令转储此类链接的内容:

    fsutil reparsepoint query <REPARSE_POINT_PATHNAME>
    

    Ex:

    C:\Temp>fsutil reparsepoint query "%LOCALAPPDATA%\Microsoft\WindowsApps\wt.exe"
    Reparse Tag Value : 0x8000001b
    Tag value: Microsoft
    
    Reparse Data Length: 0x168
    Reparse Data:
    0000:  03 00 00 00 4d 00 69 00  63 00 72 00 6f 00 73 00  ....M.i.c.r.o.s.
    0010:  6f 00 66 00 74 00 2e 00  57 00 69 00 6e 00 64 00  o.f.t...W.i.n.d.
    0020:  6f 00 77 00 73 00 54 00  65 00 72 00 6d 00 69 00  o.w.s.T.e.r.m.i.
    0030:  6e 00 61 00 6c 00 5f 00  38 00 77 00 65 00 6b 00  n.a.l._.8.w.e.k.
    0040:  79 00 62 00 33 00 64 00  38 00 62 00 62 00 77 00  y.b.3.d.8.b.b.w.
    0050:  65 00 00 00 4d 00 69 00  63 00 72 00 6f 00 73 00  e...M.i.c.r.o.s.
    0060:  6f 00 66 00 74 00 2e 00  57 00 69 00 6e 00 64 00  o.f.t...W.i.n.d.
    0070:  6f 00 77 00 73 00 54 00  65 00 72 00 6d 00 69 00  o.w.s.T.e.r.m.i.
    0080:  6e 00 61 00 6c 00 5f 00  38 00 77 00 65 00 6b 00  n.a.l._.8.w.e.k.
    0090:  79 00 62 00 33 00 64 00  38 00 62 00 62 00 77 00  y.b.3.d.8.b.b.w.
    00a0:  65 00 21 00 41 00 70 00  70 00 00 00 43 00 3a 00  e.!.A.p.p...C.:.
    00b0:  5c 00 50 00 72 00 6f 00  67 00 72 00 61 00 6d 00  \.P.r.o.g.r.a.m.
    00c0:  20 00 46 00 69 00 6c 00  65 00 73 00 5c 00 57 00   .F.i.l.e.s.\.W.
    00d0:  69 00 6e 00 64 00 6f 00  77 00 73 00 41 00 70 00  i.n.d.o.w.s.A.p.
    00e0:  70 00 73 00 5c 00 4d 00  69 00 63 00 72 00 6f 00  p.s.\.M.i.c.r.o.
    00f0:  73 00 6f 00 66 00 74 00  2e 00 57 00 69 00 6e 00  s.o.f.t...W.i.n.
    0100:  64 00 6f 00 77 00 73 00  54 00 65 00 72 00 6d 00  d.o.w.s.T.e.r.m.
    0110:  69 00 6e 00 61 00 6c 00  5f 00 31 00 2e 00 34 00  i.n.a.l._.1...4.
    0120:  2e 00 33 00 32 00 34 00  33 00 2e 00 30 00 5f 00  ..3.2.4.3...0._.
    0130:  78 00 36 00 34 00 5f 00  5f 00 38 00 77 00 65 00  x.6.4._._.8.w.e.
    0140:  6b 00 79 00 62 00 33 00  64 00 38 00 62 00 62 00  k.y.b.3.d.8.b.b.
    0150:  77 00 65 00 5c 00 77 00  74 00 2e 00 65 00 78 00  w.e.\.w.t...e.x.
    0160:  65 00 00 00 30 00 00 00                           e...0...
    
    C:\Temp>
    
  • 重新解析数据有一个包含四个宽字符串的结构,如下所示:

    typedef struct _REPARSE_APPEXECLINK_READ_BUFFER { // For tag IO_REPARSE_TAG_APPEXECLINK
      DWORD  ReparseTag;
      WORD   ReparseDataLength;
      WORD   Reserved;
      ULONG  Version;    // Currently version 3
      WCHAR  StringList[1];  // Multistring (Consecutive UTF-16 strings each ending with a NUL)
      /* There are normally 4 strings here. Ex:
        Package ID:  L"Microsoft.WindowsTerminal_8wekyb3d8bbwe"
        Entry Point: L"Microsoft.WindowsTerminal_8wekyb3d8bbwe!App"
        Executable:  L"C:\Program Files\WindowsApps\Microsoft.WindowsTerminal_1.4.3243.0_x64__8wekyb3d8bbwe\wt.exe"
        Applic. Type: L"0"   // Integer as ASCII. "0" = Desktop bridge application; Else sandboxed UWP application
      */     
    } APPEXECLINK_READ_BUFFER, *PAPPEXECLINK_READ_BUFFER;
    
  • 正在运行 wt.exe 的 App Exec Link 目标...

    "C:\Program Files\WindowsApps\Microsoft.WindowsTerminal_1.4.3243.0_x64__8wekyb3d8bbwe\wt.exe"
    

    ...工作,并启动 Windows 终端。

    但是运行 MicrosoftEdge.exe 的 App Exec Link 目标...

    "C:\WINDOWS\system32\SystemUWPLauncher.exe"
    

    ... 什么也没做。

    ⇒ 重解析数据中的其他参数在某种程度上也很重要。 (但我不知道如何使用它们。)

  • Running

    "%LOCALAPPDATA%\Microsoft\WindowsApps\MicrosoftEdge.exe"
    

    然后在任务管理器中查看,我发现 MS Edge 运行的真正可执行文件是

    "C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe"
    

    ⇒ 这证明App Exec Link目标程序并不总是真实的程序。

  • 可以使用重解析数据中的入口点字符串而不是目标路径名来启动目标应用程序,方法是:

    explorer.exe shell:appsFolder\<REPARSE_POINT_ENTRY_POINT_NAME>
    

    例如,这将启动 Microsoft Edge:

    explorer.exe shell:appsFolder\Microsoft.MicrosoftEdge_8wekyb3d8bbwe!MicrosoftEdge
    

    但这不是我想要的。我真的很想找到如何使用目标应用程序路径名和其他两个参数启动应用程序。

不管怎样,我已经更新了我的 readlink() 例程MsvcLibX 库 https://github.com/JFLarvoire/SysToolsLib/tree/master/C/MsvcLibX返回 App Exec Links 的目标。 我的所有工具系统工具库 https://github.com/JFLarvoire/SysToolsLib%22可以处理符号链接的现在显示该目标。
但由于这个目标显然不是完整的答案,我认为当前版本充其量只是一个临时实现。

如果有人找到有关此主题的更多信息,我非常感兴趣!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 C#/Win32 api 中找到 Windows 应用程序执行别名的目标? 的相关文章

随机推荐

  • 如何将 Binder (mybinder.org) 与私有 Github 存储库结合使用?

    在审查了这个确切的问题之后 https github com jupyterhub binderhub issues 237 https github com jupyterhub binderhub issues 237 看来这个功能已经
  • 无法自动装配字段:无法连接到 com.sun.proxy.$Proxy22

    Caused by org springframework beans factory BeanCreationException Could not autowire field protected com cms service Fol
  • 加拿大邮政编码验证

    我需要验证加拿大邮政编码 例如 M4B 1C7 使用 C NET 正则表达式 加拿大邮政编码不能包含字母 D F I O Q 或 U 并且不能以 W 或 Z 开头 ABCEGHJKLMNPRSTVXY 0 9 ABCEGHJKLMNPRST
  • C++ 序列化性能

    我正在构建一个分布式 C 应用程序 该应用程序需要对在不同进程和计算机之间传递的简单数据结构进行大量序列化和反序列化 我对序列化复杂的类层次结构不感兴趣 但更感兴趣的是发送带有一些简单成员 例如数字 字符串和数据向量 的结构 数据向量通常可
  • 如何在Redis 6 docker库中启用tls/ssl?

    最新版本的Redis Docker引入了TLS SSL功能 但我无法弄清楚如何为最新版本的 Redis Docker 启用它 此外 我还想知道 对于Docker环境 如何修改IO线程数 对于多线程 也在Redis 6中引入 Docker 的
  • UTF-8 是 Ruby v.2 中的默认编码吗?

    Matz 在他的书中写道 为了使用 UTF 8 您必须在脚本的第一行添加编码注释 他给我们举了一个例子 coding utf 8 Specify Unicode UTF 8 characters This is a string liter
  • 在 Python 中将字符串列表转换为整数(或双精度数)

    我有很多看起来与此类似的字符串列表 list 4 5 5 763 6 423 5 6 77 10 我想将其转换为整数 或双精度 列表 但是 不断产生错误 gt gt gt lst 4 5 5 763 6 423 5 6 77 10 gt g
  • 为什么我无法使用 UPnP 单播 M-SEARCH 来代替 MultiCast M-SEARCH?

    早上好 我们决定尽可能使用 UPnP 我们在 239 255 255 250 1900 上使用 MultiCast 进行 M SEARCH 不过 我们正在研究如何处理客户在其网络上锁定 MultiCast 的情况 查看 UPnP 1 1 规
  • 为什么 openCV 中的 CvBlobDetector 位于旧库中?

    是否有更新的斑点检测 跟踪库 这不是一个好的图书馆吗 难道遗留代码不应该是旧的 无用的代码吗 有人知道吗 这是较新的斑点检测器 http opencv itseez com modules features2d doc common int
  • Jquery 查找类型的第一个直接子代

    我正在寻找一种方法来查找精确类型的元素的第一个直接子元素 让我们想象一下这个标记 div div p Stuff p div p Stuff 2 p p Stuff 3 p div 所以在这里 我想要得到的是 Stuff 2 作为直接子代的
  • 好友声明介绍的姓名

    我正在考虑 N3797 工作草案 有来自3 3 1 4的引用 好友声明 11 3 可能会引入一个 可能不可见的 名称 进入封闭的命名空间 进一步在 3 3 2 11 中我发现 友元声明指的是作为成员的函数或类 最近的封闭命名空间 但它们不会
  • Node.js:计算文件中的行数

    我有很大的文本文件 其范围在30MB and 10GB 如何使用以下命令计算文件中的行数Node js 我有这些限制 不需要将整个文件写入内存 执行该任务不需要子进程 不使用wc的解决方案 var i var count 0 require
  • 通过 SSH 传输文件 [关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 我正在命令行上通过 SSH 连接到远程服务器 并尝试使用以下命令将目录复制到本地计算机上scp命令 但是 远程服务器返回此 使用 消息 Stewart
  • 为什么let=0有效但var=0无效? [复制]

    这个问题在这里已经有答案了 为什么不 let 0 显示任何语法错误 但是 var 0 做 我在Safari上测试过 不过我尝试过 console log let 但它有错误 似乎 let 不是一个已经定义的变量 为什么会发生这种情况 Bec
  • gke-metrics-agent 与 prometheus 相关的多个错误

    我向 GKE 部署了一个新应用程序 我看到 GKE 仪表板的 gke metrics agent 上有数千个错误 它使用大量资源 I checked the logs and I saw all errors related to Prom
  • 是否可以重写控制台中的前一行?

    我正在尝试在我的控制台应用程序中创建过程动画 是否可以根据此需要重写以前的行 我知道关于 r但它仅适用于当前行 如果不可能的话 怎样才能实现动画效果呢 谢谢 我的控制台是标准 Ubuntu 12 04 终端模拟器 感谢 MrSmith42
  • 如何使用Python将BLOB插入Oracle?

    我正在尝试使用 cx Oracle 6 3 将大量 BLOB 每个 2 到 20 MB 插入到 Oracle 12 中 经过大量的谷歌搜索和实验 我得到了以下代码 我是 Python 新手 想知道 该方法有效吗 有更快的方法吗 usr lo
  • 使用 Get-Help cmdlet 以相同格式显示基于注释的帮助

    我尝试使用 Get Help cmdlet 以与显示从 XML 文件生成的 cmdlet 帮助主题相同的格式显示基于注释的帮助 执行此操作的能力记录在about Comment based Help http technet microso
  • Tridion GUI Extensions CommandSet 如何映射到 js 方法?

    Tridion GUI 扩展配置如何将名称映射到 JS 文件 例如 我正在使用 Jaime 的你好世界帖子 http jaimesantosalcon blogspot com 2011 02 sdl tridion 2011 ga gui
  • 如何在 C#/Win32 api 中找到 Windows 应用程序执行别名的目标?

    Microsoft Windows 终端 通过 Microsoft Store 安装 创建 0 字节wt exe文件是一个Windows 执行别名 https www tiraniddo dev 2019 09 overview of wi