Skip to content

Instantly share code, notes, and snippets.

@tyranid
Last active July 21, 2017 15:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tyranid/95a2a66afc2922047dc96d15c2483baf to your computer and use it in GitHub Desktop.
Save tyranid/95a2a66afc2922047dc96d15c2483baf to your computer and use it in GitHub Desktop.
Simple script which uses NtObjectManager to extract information about UWP execution aliases from insider build 16226 and above.
# Quick and dirty parser for UWP Execution Aliases
# Thanks for @aionescu for tagging me on the twitter thread.
Import-Module NtObjectManager
function Get-NulTerminatedString
{
Param(
[Parameter(Mandatory=$true, Position=0)]
[IO.BinaryReader]$reader
)
$builder = [Text.StringBuilder]::new()
try {
while ($true) {
$c = $reader.ReadChar()
if ($c -eq 0) {
break
}
$builder.Append($c) | Out-Null
}
} catch {
throw $_
}
return $builder.ToString()
}
<#
.SYNOPSIS
Gets the execution alias information from a name.
.DESCRIPTION
This cmdlet looks up an execution alias and tries to parse its reparse point to extract internal information.
.PARAMETER AliasName
The alias name to lookup. Can be either a full path to the alias or a name which will be found in the WindowsApps
folder.
#>
function Get-ExecutionAlias
{
Param(
[Parameter(Mandatory=$true, Position=0)]
[string]$AliasName
)
if (Test-Path $AliasName) {
$path = Resolve-Path $AliasName
} else {
$path = $env:LOCALAPPDATA + "\Microsoft\WindowsApps\$AliasName"
}
$rp = Use-NtObject($file = Get-NtFile -Path $path -Win32Path -Options OpenReparsePoint,SynchronousIoNonAlert -Access GenericRead,Synchronize) {
$file.GetReparsePoint()
}
if ($rp.Tag -eq 2147483675) {
$reader = [IO.BinaryReader]::new([IO.MemoryStream]::new($rp.Data), [Text.Encoding]::Unicode)
$version = $reader.ReadInt32()
$package_name = Get-NulTerminatedString $reader
$entrypoint = Get-NulTerminatedString $reader
$target = Get-NulTerminatedString $reader
$flags = $reader.ReadInt32()
return [PSCustomObject]@{
Version = $version
PackageName = $package_name
EntryPoint = $entrypoint
Target = $target
Flags = $flags
}
}
}
<#
.SYNOPSIS
Creates a new execution alias information.
.DESCRIPTION
This cmdlet creates a new execution alias for a packaged application.
.PARAMETER PackageName
The name of the UWP package.
.PARAMETER EntryPoint
The entry point of the application
.PARAMETER Target
The target executable path
.PARAMETER Flags
Additional flags
.PARAMETER Version
Version number
#>
function New-ExecutionAlias
{
Param(
[Parameter(Mandatory=$true, Position=0)]
[string]$Path,
[Parameter(Mandatory=$true, Position=1)]
[string]$PackageName,
[Parameter(Mandatory=$true, Position=2)]
[string]$EntryPoint,
[Parameter(Mandatory=$true, Position=3)]
[string]$Target,
[Int32]$Flags = 48,
[Int32]$Version = 3
)
$stm = [IO.MemoryStream]::new()
$encoding = [Text.Encoding]::Unicode
$writer = [IO.BinaryWriter]::new($stm, $encoding)
$writer.Write([Int32]3)
$writer.Write($encoding.GetBytes($PackageName + "`0"))
$writer.Write($encoding.GetBytes($EntryPoint + "`0"))
$writer.Write($encoding.GetBytes($Target + "`0"))
$writer.Write($Flags)
$tag = [Enum]::ToObject([NtApiDotNet.ReparseTag], [uint32]2147483675)
$rp = [NtApiDotNet.GenericReparseBuffer]::new($tag, $stm.ToArray())
Use-NtObject($file = New-NtFile -Path $Path -Win32Path -Options OpenReparsePoint,SynchronousIoNonAlert -Access GenericWrite,Synchronize -Disposition OpenIf) {
Use-NtObject($buffer = [NtApiDotNet.SafeHGlobalBuffer]::new($rp.ToByteArray())) {
$file.FsControl([NtApiDotNet.NtWellKnownIoControlCodes]::FSCTL_SET_REPARSE_POINT, $buffer, $null) | Out-Null
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment