Skip to content

Instantly share code, notes, and snippets.

@tyranid

tyranid/get_execution_alias.ps1 Secret

Last active Jul 21, 2017
Embed
What would you like to do?
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