function getProcAddress {
Param (
[OutputType([IntPtr])]
[Parameter( Position = 0, Mandatory = $true)]
[String]
$moduleName,
[Parameter( Position = 1, Mandatory = $true)]
[String]
$functionName
)
# Get reference to System.dll in the GAC
$sysassembly = [System.AppDomain]::CurrentDomain.GetAssemblies() | Where-Object {
$_.GlobalAssemblyCache -and $_.Location.Split('\\')[-1] -eq 'System.dll'
}
$types = $sysassembly.GetTypes()
$unsafenativemethods = ForEach ($type in $types) {
$type | Where-Object {$_.FullName -like '*NativeMethods' -and $_.Fullname -like '*Win32*' -and $_.Fullname -like '*Un*'}
}
# Get reference to GetModuleHandle and GetProcAddress methods
$modulehandle = $unsafenativemethods.GetMethods() | Where-Object {$_.Name -like '*Handle' -and $_.Name -like '*Module*'}
$procaddress = $unsafenativemethods.GetMethods() | Where-Object {$_.Name -like '*Address' -and $_.Name -like '*Proc*'} | Select-Object -First 1
# Get handle on module specified
$module = $modulehandle.Invoke($null, @($moduleName))
$procaddress.Invoke($null, @($module, $functionName))
}
function getDelegateType {
Param (
[Parameter(Position = 0, Mandatory = $True)] [Type[]] $func,
[Parameter(Position = 1)] [Type] $delType = [Void]
)
$type = [AppDomain]::CurrentDomain.
DefineDynamicAssembly((New-Object System.Reflection.AssemblyName('ReflectedDelegate')),
[System.Reflection.Emit.AssemblyBuilderAccess]::Run).
DefineDynamicModule('InMemoryModule', $false).
DefineType('MyDelegateType', 'Class, Public, Sealed, AnsiClass, AutoClass',
[System.MulticastDelegate])
$type.
DefineConstructor('RTSpecialName, HideBySig, Public', [System.Reflection.CallingConventions]::Standard, $func).
SetImplementationFlags('Runtime, Managed')
$type.
DefineMethod('Invoke', 'Public, HideBySig, NewSlot, Virtual', $delType, $func).
SetImplementationFlags('Runtime, Managed')
return $type.CreateType()
}
$GetUserNameAddr = getProcAddress Advapi32.dll GetUserNameA
$GetUserNameDelegationType = getDelegateType @([System.Text.StringBuilder], [Int].MakeByRefType())
$GetUserName = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($GetUserNameAddr, $GetUserNameDelegationType)
$size = 64
$str = New-Object System.Text.StringBuilder -ArgumentList $size
$GetUserName.Invoke($str, [Ref]$size)
$str.ToString()