魔法薇ㄦ的书馆

wherewhere的个人博客

众所周知,UWP 一般是运行在沙盒里面的,当我们需要访问沙盒外资源的时候,就需要通过沙盒外的代理服务器来获取。一般情况下我们都是利用 WinRT API 通过 Runtime Broker 来和沙盒外互通,遇到要自定义的情况则是手动开一个 Win32 服务器来互通,但是有没有可能我们可以直接拿 UWP 本体当服务器呢?

UWP 本体实际上就是一个普通的 Win32 EXE 程序,只是想要以 UWP 状态运行只能通过系统托管,但是如果我们不需要它以 UWP 状态执行的时候完全可以直接双击打开它,这时候它就是一个很普通的散装 Win32 程序了。

利用这个特性,我们可以制作一种假装双击打开的方法,只需要在发现是 Win32 状态下启动就去用 API 唤起 UWP 形态的自己就行了

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
private static unsafe bool IsPackagedApp
{
get
{
uint length = 0;
PWSTR str = new();
_ = PInvoke.GetCurrentPackageFullName(ref length, str);

char* ptr = stackalloc char[(int)length];
str = new(ptr);
WIN32_ERROR result = PInvoke.GetCurrentPackageFullName(ref length, str);
return result != WIN32_ERROR.APPMODEL_ERROR_NO_PACKAGE;
}
}

private static void Main()
{
if (IsPackagedApp)
{
Application.Start(static p =>
{
DispatcherQueueSynchronizationContext context = new(DispatcherQueue.GetForCurrentThread());
SynchronizationContext.SetSynchronizationContext(context);
_ = new App();
});
}
else
{
StartCoreApplicationAsync().Wait();
}
}

private static async Task StartCoreApplicationAsync()
{
PackageManager manager = new();
string basePath = AppDomain.CurrentDomain.BaseDirectory;
XmlDocument manifest = await XmlDocument.LoadFromFileAsync(await StorageFile.GetFileFromPathAsync(Path.Combine(basePath, "AppxManifest.xml")));
IXmlNode identity = manifest.GetElementsByTagName("Identity")?[0];
string name = identity.Attributes.FirstOrDefault(x => x.NodeName == "Name")?.InnerText;
IXmlNode application = manifest.GetElementsByTagName("Application")?[0];
string id = application.Attributes.FirstOrDefault(x => x.NodeName == "Id")?.InnerText;
IEnumerable<Package> packages = manager.FindPackagesForUser(string.Empty).Where(x => x.Id.FamilyName.StartsWith(name));
if (packages.FirstOrDefault() is Package package)
{
IReadOnlyList<AppListEntry> entries = await package.GetAppListEntriesAsync();
if (entries?[0] is AppListEntry entry)
{
_ = await entry.LaunchAsync();
}
}
}

既然我们可以让自己唤起自己,那么自己和自己通信也不是什么难事了,我们只需要在 UWP 形态下唤起一个 Win32 的自己,就可以自己利用自己滥权(bushi)了。

阅读全文 »

众所周知,2024年9月微软正式宣布了 .NET Core App 的 UWP 支持,至此我们终于可以在新版 csproj 用 .NET 8 及以上编写 UWP 了,那么我们可不可以通过修改清单的方式来让 UWP 变成 UAP 呢?

屏幕截图(785)

UWP 和 UAP 使用的是同一套 WinRT API ,Windows 区分 UAP 和 UWP 的方式是看清单,只要是用 UAP 的清单就会仿真成 Win8.1 模式,于是我们只需要将清单变成 UAP 的样子就行了。所以首先我们新建一个 .NET 9 Native AOT 的 UWP 项目

Snipaste_2025-03-13_17-52-59

然后我们修改清单,Win8 App 清单如下,内容按需填写,Win8.1 App 的清单可以通过在 Github 搜索 OSMaxVersionTested language:XML 找到,6.2 是 Win8,6.3 是 Win8.1 ($targetentrypoint$ 需配合 ApplicationEntryPoint 使用)

阅读全文 »

众所周知,UWP 使用的窗口模型是 CoreWindow,但是 UWP 本身只是一个应用模型,所以完全可以创建 win32 窗口,那么我们可以不可以创建一个 win32 窗口,然后像 XAML 岛 (XAML Islands) 一样把 XAML 托管上去呢?本篇将讲述如何在 UWP 创建一个 XAML 岛窗口。

示例

首先,XAML 岛会判断当前的应用模型是否为ClassicDesktop,所以我们需要利用Detours劫持AppPolicyGetWindowingModel方法。具体内容如下:

阅读全文 »

众所周知,UWP 使用的窗口模型是 CoreWindow,但是 UWP 本身只是一个应用模型,所以完全可以创建 win32 窗口,那么我们可以不可以创建一个 win32 窗口,然后像 XAML 岛 (XAML Islands) 一样把 XAML 托管上去呢?本篇将讲述如何利用 WAS (Windows App SDK,俗称 WinUI3) 在 UWP 创建一个 XAML 岛窗口。

示例

演示视频:https://x.com/wherewhere7/status/1721570411388039587

由于 WAS 在 win32 应用模型下本身就是个 XAML 岛,所以 WAS 对 XAML 岛的支持要比 WUXC (Windows.UI.Xaml.Controls) 要好多了,接下来的内容大多是将 WAS 中实现窗口的方法迁移到 C#。

首先,不管是 WUXC 还是 WAS 的 XAML 岛都会判断当前的应用模型是否为ClassicDesktop,所以我们需要利用Detours劫持AppPolicyGetWindowingModel方法。具体内容如下:

阅读全文 »

众所周知,WAS (Windows App SDK,俗称 WinUI3)在刚开始是支持 UWP 的,甚至最早只支持 UWP,但是微软在正式版发布前删除了对 UWP 的支持,不过真的删除了吗?初生之鸟2023年10月发现在 VS 调试下无视报错继续运行可以正常在 UWP 加载 WAS。随着 WAS 的开源,WAS 阻止在 UWP 上运行的原因也被找到,至此大家终于找到在 UWP 上使用 WAS 的方法了。

WAS 阻止在 UWP 上运行的方法很简单,就是检查注册表HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WinUI\Xaml\EnableUWPWindow是否为00000001,如果不是就直接报错。

Window_Partial.cpp#L80-L114
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
// ----------------------------------------------------------------------
// IWindow
// ----------------------------------------------------------------------
Window::Window()
{
// The first window created internally by DXamlCore _must_ be a UWP Window. DXamlCore
// requires and controls the lifetime of a hidden UWP Microsoft.UI.Xaml.Window.
// note that this Window instance will be the 'real' window for UWP instances, but
// serves as a dummy for all other instances. dummy behavior is deprecated and being removed.
auto dxamlCore = DXamlCore::GetCurrent();
Window* window = dxamlCore->GetDummyWindowNoRef();

if (!window)
{
// Do a runtime check to see if UWP should be enabled
static auto runtimeEnabledFeatureDetector = RuntimeFeatureBehavior::GetRuntimeEnabledFeatureDetector();
auto UWPWindowEnabled = runtimeEnabledFeatureDetector->IsFeatureEnabled(RuntimeEnabledFeature::EnableUWPWindow);

// WinUI UWP
if (!UWPWindowEnabled && DXamlCore::GetCurrent()->GetHandle()->GetInitializationType() != InitializationType::IslandsOnly)
{
::RoOriginateError(
E_NOT_SUPPORTED,
wrl_wrappers::HStringReference(
L"WinUI: Error creating an UWP Window. Creating an UWP window is not allowed."
).Get());
XAML_FAIL_FAST();
}
m_spWindowImpl = std::make_shared<UWPWindowImpl>(this);
}
else
{
m_spWindowImpl = std::make_shared<DesktopWindowImpl>(this);
}
}
阅读全文 »

众所周知,UWP 是运行在沙盒里面的,所有权限都有严格限制,和沙盒外交互也需要特殊的通道,所以从根本杜绝了 UWP 毒瘤的存在。但是实际上 UWP 只是一个应用模型,本身是没有什么权限管理的,权限管理全靠 App Container 沙盒控制,如果我们脱离了这个沙盒,UWP 就会放飞自我了。那么有没有这种可能呢?

我们打开设置应用,通过任务管理器查看进程,就会发现它并没有 Runtime Broker 存在,这个进程是用来在沙盒间代理的,这说明微软给 UWP 开了一个后门。

任务管理器

那么我们是不是也有办法脱离沙盒运行呢?Ahmed Walid 在 2023年2月 发表了这样一个帖子

阅读全文 »

众所周知,C# 只支持对 基类/接口/class/struct/new() 以及一些 IDE 魔法的约束,比如这样

1
2
3
4
5
6
7
8
9
public static string Test<T>(T value) where T : ITest
{
return value.Test();
}

public interface ITest
{
string Test();
}

但是如果我们想要随心所欲的约束就不行了

1
2
3
4
public static string Test<T>(T value) where T : { string Test(); }
{
return value.Test();
}

最近无聊乱折腾 MSIL,弄出来好多不能跑的魔法,虽然不能跑但是反编译出的 C# 看着很神奇,其中正好就有想看看能不能弄个神奇的泛型出来,于是我胡写了一段代码

阅读全文 »

Announcing

We have packaged this project into winrt. With the winrt version, we can use it in cpp/winrt and other projects. You can find the winrt version in winrt branch.

How to use it

There are two way to reference it.

  • Reference to the project directly

    Fork this repository and change the branch to winrt.

    • If your project is face to uwp, add this to your .vcproj

      1
      2
      3
      4
      <ProjectReference Include="\path\to\AdvancedSharpAdbClient.WinRT.csproj">
      <Project>{083cdc04-9cc2-46e4-84c2-55b645be9d50}</Project>
      <SetTargetFramework>TargetFramework=uap10.0</SetTargetFramework>
      </ProjectReference>
    • If your project is face to desktop, add this to your .vcproj

      1
      2
      3
      4
      <ProjectReference Include="\path\to\AdvancedSharpAdbClient.WinRT.csproj">
      <Project>{083cdc04-9cc2-46e4-84c2-55b645be9d50}</Project>
      <SetTargetFramework>TargetFramework=net6.0-windows10.0.17763.0</SetTargetFramework>
      </ProjectReference>
  • Reference to the nuget package

    阅读全文 »

【UWP】开发小技巧――简单的增量加载

#UWP# #爱编程# #电脑玩家#

增量加载的原理这里就不多说了,具体是干什么的可以看 CNBlogs 的讲解:查看链接

这里只讲解如何使用 CNBlogs UAP 中使用的增量加载方案(我硬是看了一天才知道怎么用。。。

首先附上代码(已经被我修改过了):查看链接

部分代码

部分代码

引用时不要忘了附上出处(不是我这,是CNBlogs

阅读全文 »

APK Installer LOGO

APK Installer

一个适用于 WIndows 的 Android 应用安装程序

CrowdinCrowdin

注意

  • 本应用已上架应用商店,请认准作者为 wherewhere,请不要使用来历不明的版本,如果因为使用不明版本而出现的故障请自行解决。
  • 本应用分为 WinUI3版WPF版,请根据需要选取

下载链接

APK 安装程序 - WinUI 3APK 安装程序 - WPF

如何安装应用

最低需求

  • Windows 10 Build 18362及以上
  • 设备需支持ARM64/x86/x64
  • 至少400MB的空余储存空间(用于储存安装包与安装应用)

使用应用安装脚本安装应用

阅读全文 »
0%