Upload new version, this version, will have both Invoke, Using high end kernel function, and low level ntdll function for fun i presonally think, the ntdll call is more fun. Also, update Invoke to support up to 12 Params, And, also update Free-Intptr to support more crap. Also, update new-Intptr to support write Value at 0x0, as SIZE_T [Intptr Size based] so, write 4 byte's, or 8 byte's, But according to MS gpt, default is Int32, so, i keep it default Also, intersting, NTDLL call, need full name, and this function can support also not full name like cmd, or cmd.exe (with some help from mr GPT) Code: # Create Process AS System, using TrustedInstaller service # sometimes it fail on first time, since, service not loaded well. try { Invoke-Process ` -CommandLine "cmd /k echo Hello From TrustedInstaller && whoami" ` -ServiceName TrustedInstaller ` -RunAsConsole ` -RunAsTI } # Create Process AS System, using winlogon Process # its still better to use TrustedInstaller service. catch { Invoke-Process ` -CommandLine "cmd /k echo Hello From winlogon && whoami" ` -ProcessName winlogon ` -RunAsConsole ` -RunAsTI } try { $hHandle = Get-ProcessHandle ` -ProcessName 'TrustedInstaller.exe' } catch { $hHandle = Get-ProcessHandle ` -ServiceName 'TrustedInstaller' } Invoke-NativeProcess ` -ImageFile "cmd.exe" ` -commandLine "/k whoami" ` -hHandle $hHandle.ToInt64() Interesting side effect, but it still work, it does fail on notepad App, but, hi, i bypass lot of nececery s**t but, it does work for calc, cmd, powershell, etc etc etc.
Darki update the libary now (in progress) will support new parameter, why. so, just use Low level native Api to invoke process and not notified the system, well, coul fail. So, added new switch. `-Register` Code: Invoke-NativeProcess ` -ImageFile "notepad" ` -Register So, when switch to register mode --> this happen. --------------------------- <-- Idea based on --> [Original] Native API Series- Using NtCreateUserProcess to Create a Normally Working Process - Programming Technology - Kanxu https://bbs.kanxue.com/thread-272798.htm GitHub - D0pam1ne705-Direct-NtCreateUserProcess- Call NtCreateUserProcess directly as normal- https://github.com/D0pam1ne705/Direct-NtCreateUserProcess entry.cpp https://github.com/D0pam1ne705/Dire...blob/main/DirectNtCreateUserProcess/entry.cpp --------------------------- Part of code.. for example. if you ask yourself, how could it manage to understand it well, he does share offset, and i installed VS2022, to see what happen, and after lot of back forwared, done. (mr gpt did help find the last bug, and from than, work great.) Code: # Jump offset +32 $AttributeListPtr = [IntPtr]::Add($AttributeListPtr, 0x20) $ClientID = New-IntPtr -Size 16 [Marshal]::WriteInt64($AttributeListPtr, 0x00, 65539) [Marshal]::WriteInt64($AttributeListPtr, 0x08, 16) [Marshal]::WriteInt64($AttributeListPtr, 0x10, $ClientID.ToInt64()) # Jump offset +32 $AttributeListPtr = [IntPtr]::Add($AttributeListPtr, 0x20) $SectionImageInformation = New-IntPtr -Size 64 [Marshal]::WriteInt64($AttributeListPtr, 0x00, 6) [Marshal]::WriteInt64($AttributeListPtr, 0x08, 64) [Marshal]::WriteInt64($AttributeListPtr, 0x10, $SectionImageInformation.ToInt64()) [Marshal]::WriteInt32($CreateInfo, 0x10, 0x3) [Marshal]::WriteInt32($CreateInfo, 0x14, 0x001000A1) $Ret = $global:ntdll::NtCreateUserProcess( [ref]$hProcess, [ref]$hThread, 0x2000000, 0x2000000, 0, 0, 0x00000200, 0x00000001, $ProcessParameters, $CreateInfo, $AttributeList) if ($Ret -ne 0) { return $false } return Send-CsrClientCall ` -hProcess $hProcess ` -hThread $hThread ` -ImagePath $ImagePath ` -NtImagePath $NtImagePath ` -ClientID $ClientID ` -CreateInfo $CreateInfo
So, upgrade it a little bit, And also update description ---------------------------------------- So, Currently project Support of this Action's Using Delegate -or Other Low level Way's Enum & Load DLL Adjusting Token Privileges Dynamic Load Dll Api Functions Dynamic Load Com Interface Functions Get Handle, from Process / service [Using ID] Query Process List & Get Basic Info [Peb, Name, ID] Parse Error Messeges from hResult, win32, NTSTATUS Invoke Process Using Api & Also Low level NTDLL api, And, also, Spoof parent process [aka Run As Ti] Initialize, Parse, Free Native STRING / UNICODE STRING structs Free Any handle, hglobal, heap, NT handle, kernel32 handle, etc etc ---------------------------------------- So, most the of warpers cover low level api call's and actually made to prove, well, PS can be wonderfull script language even to do Low level s**ti thing's, well. it does work. i cant say no about that. Like dynamic load Dll Api & Com interface (which offically not supported) And also parse the error it return. [which also kind of nice thing. MS don't provide that.] and other kind of s**t.
Did update it a little bit, and also support for string` like will automaticaly parse to pointer instead Code: # STRSAFE typedefs (missing) "strsafe_lpstr" { $fixedType = "IntPtr" } "strsafe_lpcstr" { $fixedType = "IntPtr" } "strsafe_lpwstr" { $fixedType = "IntPtr" } "strsafe_lpcwstr" { $fixedType = "IntPtr" } "strsafe_lpcuwstr" { $fixedType = "IntPtr" } "strsafe_pcnzch" { $fixedType = "IntPtr" } "strsafe_pcnzwch" { $fixedType = "IntPtr" } "strsafe_pcunzwch" { $fixedType = "IntPtr" } which added for current list of c/c* s**ti string defination like* Code: "pstring" { $fixedType= "IntPtr" } "lpcwstr" { $fixedType= "IntPtr" } "pchar" { $fixedType= "IntPtr" } "lpstr" { $fixedType= "IntPtr" } "lpcstr" { $fixedType= "IntPtr" } "lpwstr" { $fixedType= "IntPtr" } becuase this i low level, i prefere use this method. last 3 .. Ansi,`,Uni) Spoiler: Full Conve' list Updated to 15-08-25 Code: # Fully qualified .NET types "system.boolean" { $fixedType = "bool" } "system.byte" { $fixedType = "byte" } "system.char" { $fixedType = "char" } "system.decimal" { $fixedType = "decimal" } "system.double" { $fixedType = "double" } "system.int16" { $fixedType = "short" } "system.int32" { $fixedType = "int" } "system.int64" { $fixedType = "long" } "system.intptr" { $fixedType = "IntPtr" } "system.object" { $fixedType = "object" } "system.sbyte" { $fixedType = "sbyte" } "system.single" { $fixedType = "float" } "system.string" { $fixedType = "string" } "system.uint16" { $fixedType = "ushort" } "system.uint32" { $fixedType = "uint" } "system.uint64" { $fixedType = "ulong" } "system.uintptr" { $fixedType = "UIntPtr" } # Alternate type spellings and aliases "boolean" { $fixedType = "bool" } "dword32" { $fixedType = "uint" } "dword64" { $fixedType = "ulong" } "int16" { $fixedType = "short" } "int32" { $fixedType = "int" } "int64" { $fixedType = "long" } "single" { $fixedType = "float" } "uint16" { $fixedType = "ushort" } "uint32" { $fixedType = "uint" } "uint64" { $fixedType = "ulong" } # --- Additional C/C++ & WinAPI aliases --- "double" { $fixedType = "double" } "float" { $fixedType = "float" } "long" { $fixedType = "int" } "longlong" { $fixedType = "long" } "tchar" { $fixedType = "char" } "uchar" { $fixedType = "byte" } "ulong" { $fixedType = "uint" } "ulonglong" { $fixedType = "ulong" } "short" { $fixedType = "short" } "ushort" { $fixedType = "ushort" } # --- Additional typedefs --- "atom" { $fixedType = "ushort" } "dword_ptr" { $fixedType = "UIntPtr" } "dwordlong" { $fixedType = "ulong" } "farproc" { $fixedType = "IntPtr" } "hhook" { $fixedType = "IntPtr" } "hresult" { $fixedType = "int" } "NTSTATUS" { $fixedType = "Int32" } "int_ptr" { $fixedType = "IntPtr" } "intptr_t" { $fixedType = "IntPtr" } "long_ptr" { $fixedType = "IntPtr" } "lpbyte" { $fixedType = "IntPtr" } "lpdword" { $fixedType = "IntPtr" } "lparam" { $fixedType = "IntPtr" } "pcstr" { $fixedType = "IntPtr" } "pcwstr" { $fixedType = "IntPtr" } "pstr" { $fixedType = "IntPtr" } "pwstr" { $fixedType = "IntPtr" } "uint_ptr" { $fixedType = "UIntPtr" } "uintptr_t" { $fixedType = "UIntPtr" } "wparam" { $fixedType = "UIntPtr" } # C# built-in types "bool" { $fixedType = "bool" } "byte" { $fixedType = "byte" } "char" { $fixedType = "char" } "decimal" { $fixedType = "decimal" } "double" { $fixedType = "double" } "float" { $fixedType = "float" } "int" { $fixedType = "int" } "intptr" { $fixedType = "IntPtr" } "long" { $fixedType = "long" } "nint" { $fixedType = "nint" } "nuint" { $fixedType = "nuint" } "object" { $fixedType = "object" } "sbyte" { $fixedType = "sbyte" } "short" { $fixedType = "short" } "string" { $fixedType = "string" } "uint" { $fixedType = "uint" } "uintptr" { $fixedType = "UIntPtr" } "ulong" { $fixedType = "ulong" } "ushort" { $fixedType = "ushort" } # Common WinAPI handle types "hbitmap" { $fixedType = "IntPtr" } "hbrush" { $fixedType = "IntPtr" } "hcurs" { $fixedType = "IntPtr" } "hdc" { $fixedType = "IntPtr" } "hfont" { $fixedType = "IntPtr" } "hicon" { $fixedType = "IntPtr" } "hmenu" { $fixedType = "IntPtr" } "hpen" { $fixedType = "IntPtr" } "hrgn" { $fixedType = "IntPtr" } # Pointer-based aliases "pbyte" { $fixedType = "IntPtr" } "pchar" { $fixedType = "IntPtr" } "pdword" { $fixedType = "IntPtr" } "pint" { $fixedType = "IntPtr" } "plong" { $fixedType = "IntPtr" } "puint" { $fixedType = "IntPtr" } "pulong" { $fixedType = "IntPtr" } "pvoid" { $fixedType = "IntPtr" } "lpvoid" { $fixedType = "IntPtr" } # Special types "guid" { $fixedType = "Guid" } # Windows/WinAPI types (common aliases) "dword" { $fixedType = "uint" } "handle" { $fixedType = "IntPtr" } "hinstance" { $fixedType = "IntPtr" } "hmodule" { $fixedType = "IntPtr" } "hwnd" { $fixedType = "IntPtr" } "lpcstr" { $fixedType = "IntPtr" } "lpcwstr" { $fixedType = "IntPtr" } "lpstr" { $fixedType = "IntPtr" } "lpwstr" { $fixedType = "IntPtr" } "ptr" { $fixedType = "IntPtr" } "size_t" { $fixedType = "UIntPtr" } "ssize_t" { $fixedType = "IntPtr" } "void*" { $fixedType = "IntPtr" } "word" { $fixedType = "ushort" } # Missing entries "pstring" { $fixedType = "IntPtr" } "lpcwstr" { $fixedType = "IntPtr" } "phandle" { $fixedType = "IntPtr" } "lresult" { $fixedType = "IntPtr" } # STRSAFE typedefs (missing) "strsafe_lpstr" { $fixedType = "IntPtr" } "strsafe_lpcstr" { $fixedType = "IntPtr" } "strsafe_lpwstr" { $fixedType = "IntPtr" } "strsafe_lpcwstr" { $fixedType = "IntPtr" } "strsafe_lpcuwstr" { $fixedType = "IntPtr" } "strsafe_pcnzch" { $fixedType = "IntPtr" } "strsafe_pcnzwch" { $fixedType = "IntPtr" } "strsafe_pcunzwch" { $fixedType = "IntPtr" }
Darki decide after lot of suffering, to add support for `CharSet` Default value in unicode, unless you change specification will update post later. Code: Invoke-UnmanagedMethod ` -Dll "user32.dll" ` -Function "MessageBoxW" ` -Return "int32" ` -Params "HWND hWnd, string lpText, string lpCaption, UINT uType" ` -Values @(0, "Text", "Title", 0) ` -CharSet Unicode Invoke-UnmanagedMethod ` -Dll "user32.dll" ` -Function "MessageBoxA" ` -Return "int32" ` -Params "HWND hWnd, string lpText, string lpCaption, UINT uType" ` -Values @(0, "Text", "Title", 0) ` -CharSet Ansi In the end, it affect the delegate code, so, every string you pass, will pass as Type of $charSet of your choice. managed by .net, you do nothing. Code: function Build-ApiDelegate { param ( [Parameter(Mandatory=$true, ValueFromPipeline)] [PSCustomObject]$InterfaceSpec, [Parameter(Mandatory=$true)] [string]$UNIQUE_ID ) $namespace = "namespace DynamicDelegates" $using = "`nusing System;`nusing System.Runtime.InteropServices;`n" $Params = Process-Parameters -InterfaceSpec $InterfaceSpec -Ignore $fixedReturnType = Process-ReturnType -ReturnType $InterfaceSpec.Return $charSet = if ($InterfaceSpec.CharSet) { "CharSet = CharSet.$($InterfaceSpec.CharSet)" } else { "CharSet = CharSet.Unicode" } $Return = @" [UnmanagedFunctionPointer(CallingConvention.$($InterfaceSpec.CallingType), $charSet)] public delegate $($fixedReturnType) $($UNIQUE_ID)( $($Params) ); "@ return "$using`n$namespace`n{`n$Return`n}`n" } ------------------------------------ Real life code. Because dafault option is unicode, well. only in MessageBoxA case (example purpose only) you must mention ANSI charset. simple. Code: # Test Charset <> Unicode Invoke-UnmanagedMethod ` -Dll "user32.dll" ` -Function "MessageBoxW" ` -Return "int32" ` -Params "HWND hWnd, string lpText, string lpCaption, UINT uType" ` -Values @(0, "Unicode Text Check", "Unicode Title", 0) # Test Charset <> Ansi Invoke-UnmanagedMethod ` -Dll "user32.dll" ` -Function "MessageBoxA" ` -Return "int32" ` -Params "HWND hWnd, string lpText, string lpCaption, UINT uType" ` -Values @(0, "Ansi Text Check", "ANsi Title", 0) ` -CharSet Ansi
so, i did update my Convert` list, and now this is accpatable as string offcourse' it's for input, for output, use Pointer instead save yourself from problem. Now you have 2 option 2 invoke/register DLL Invoke-UnmanagedMethod Register-NativeMethods (list based) 1` is temp Loading, for testing purpose 2` is permanent solution based Code: # Test Charset <> Ansi Invoke-UnmanagedMethod ` -Dll "user32.dll" ` -Function "MessageBoxA" ` -Return "int32" ` -Params "HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType" ` -Values @(0, "Hello from ANSI!", "MessageBoxA", 0) ` -CharSet Ansi $Func = Register-NativeMethods @( @{ Name = "MessageBoxA" Dll = "user32.dll" ReturnType = [int] CharSet = 'Ansi' Parameters = [Type[]]@( [IntPtr], # hWnd [string], # lpText [string], # lpCaption [uint32] # uType ) }) $Func::MessageBoxA( [IntPtr]::Zero, "Hello from ANSI!", "MessageBoxA", 0) The full convert' list now. Code: # Void "void" { $fixedReturnType = "void" } # Fully qualified .NET types "system.boolean" { $fixedReturnType = "bool" } "system.byte" { $fixedReturnType = "byte" } "system.char" { $fixedReturnType = "char" } "system.decimal" { $fixedReturnType = "decimal" } "system.double" { $fixedReturnType = "double" } "system.int16" { $fixedReturnType = "short" } "system.int32" { $fixedReturnType = "int" } "system.int64" { $fixedReturnType = "long" } "system.intptr" { $fixedReturnType = "IntPtr" } "system.object" { $fixedReturnType = "object" } "system.sbyte" { $fixedReturnType = "sbyte" } "system.single" { $fixedReturnType = "float" } "system.string" { $fixedReturnType = "string" } "system.uint16" { $fixedReturnType = "ushort" } "system.uint32" { $fixedReturnType = "uint" } "system.uint64" { $fixedReturnType = "ulong" } "system.uintptr" { $fixedReturnType = "UIntPtr" } # Alternate type spellings and aliases "boolean" { $fixedReturnType = "bool" } "dword32" { $fixedReturnType = "uint" } "dword64" { $fixedReturnType = "ulong" } "int16" { $fixedReturnType = "short" } "int32" { $fixedReturnType = "int" } "int64" { $fixedReturnType = "long" } "single" { $fixedReturnType = "float" } "uint16" { $fixedReturnType = "ushort" } "uint32" { $fixedReturnType = "uint" } "uint64" { $fixedReturnType = "ulong" } # --- Additional C/C++ & WinAPI aliases --- "double" { $fixedReturnType = "double" } "float" { $fixedReturnType = "float" } "long" { $fixedReturnType = "int" } "longlong" { $fixedReturnType = "long" } "tchar" { $fixedReturnType = "char" } "uchar" { $fixedReturnType = "byte" } "ulong" { $fixedReturnType = "ulong" } "ulonglong" { $fixedReturnType = "ulong" } "short" { $fixedReturnType = "short" } "ushort" { $fixedReturnType = "ushort" } # --- Additional typedefs --- "atom" { $fixedReturnType = "ushort" } "dword_ptr" { $fixedReturnType = "UIntPtr" } "dwordlong" { $fixedReturnType = "ulong" } "farproc" { $fixedReturnType = "IntPtr" } "hhook" { $fixedReturnType = "IntPtr" } "hresult" { $fixedReturnType = "int" } "NTSTATUS" { $fixedReturnType = "Int32" } "int_ptr" { $fixedReturnType = "IntPtr" } "intptr_t" { $fixedReturnType = "IntPtr" } "long_ptr" { $fixedReturnType = "IntPtr" } "lpbyte" { $fixedReturnType = "IntPtr" } "lpdword" { $fixedReturnType = "IntPtr" } "lparam" { $fixedReturnType = "IntPtr" } "pcstr" { $fixedReturnType = "IntPtr" } "pcwstr" { $fixedReturnType = "IntPtr" } "pstr" { $fixedReturnType = "IntPtr" } "pwstr" { $fixedReturnType = "IntPtr" } "uint_ptr" { $fixedReturnType = "UIntPtr" } "uintptr_t" { $fixedReturnType = "UIntPtr" } "wparam" { $fixedReturnType = "UIntPtr" } # C# built-in types "bool" { $fixedReturnType = "bool" } "byte" { $fixedReturnType = "byte" } "char" { $fixedReturnType = "char" } "decimal" { $fixedReturnType = "decimal" } "int" { $fixedReturnType = "int" } "intptr" { $fixedReturnType = "IntPtr" } "nint" { $fixedReturnType = "nint" } "nuint" { $fixedReturnType = "nuint" } "object" { $fixedReturnType = "object" } "sbyte" { $fixedReturnType = "sbyte" } "string" { $fixedReturnType = "string" } "uint" { $fixedReturnType = "uint" } "uintptr" { $fixedReturnType = "UIntPtr" } # Common WinAPI handle types "hbitmap" { $fixedReturnType = "IntPtr" } "hbrush" { $fixedReturnType = "IntPtr" } "hcurs" { $fixedReturnType = "IntPtr" } "hdc" { $fixedReturnType = "IntPtr" } "hfont" { $fixedReturnType = "IntPtr" } "hicon" { $fixedReturnType = "IntPtr" } "hmenu" { $fixedReturnType = "IntPtr" } "hpen" { $fixedReturnType = "IntPtr" } "hrgn" { $fixedReturnType = "IntPtr" } # Pointer-based aliases "pbyte" { $fixedReturnType = "IntPtr" } "pchar" { $fixedReturnType = "IntPtr" } "pdword" { $fixedReturnType = "IntPtr" } "pint" { $fixedReturnType = "IntPtr" } "plong" { $fixedReturnType = "IntPtr" } "puint" { $fixedReturnType = "IntPtr" } "pulong" { $fixedReturnType = "IntPtr" } "pvoid" { $fixedReturnType = "IntPtr" } "lpvoid" { $fixedReturnType = "IntPtr" } # Special types "guid" { $fixedReturnType = "Guid" } # Windows/WinAPI types (common aliases) "dword" { $fixedReturnType = "uint" } "handle" { $fixedReturnType = "IntPtr" } "hinstance" { $fixedReturnType = "IntPtr" } "hmodule" { $fixedReturnType = "IntPtr" } "hwnd" { $fixedReturnType = "IntPtr" } "ptr" { $fixedReturnType = "IntPtr" } "size_t" { $fixedReturnType = "UIntPtr" } "ssize_t" { $fixedReturnType = "IntPtr" } "void*" { $fixedReturnType = "IntPtr" } "word" { $fixedReturnType = "ushort" } "phandle" { $fixedReturnType = "IntPtr" } "lresult" { $fixedReturnType = "IntPtr" } # STRSAFE typedefs "strsafe_lpstr" { $fixedReturnType = "string" } # ANSI "strsafe_lpcstr" { $fixedReturnType = "string" } # ANSI "strsafe_lpwstr" { $fixedReturnType = "string" } # Unicode "strsafe_lpcwstr" { $fixedReturnType = "string" } # Unicode "strsafe_lpcuwstr" { $fixedReturnType = "string" } # Unicode "strsafe_pcnzch" { $fixedReturnType = "string" } # ANSI char "strsafe_pcnzwch" { $fixedReturnType = "string" } # Unicode wchar "strsafe_pcunzwch" { $fixedReturnType = "string" } # Unicode wchar # Wide-character (Unicode) types "lpcstr" { $fixedReturnType = "string" } # ANSI string "lpcwstr" { $fixedReturnType = "string" } # Unicode string "lpstr" { $fixedReturnType = "string" } # ANSI string "lpwstr" { $fixedReturnType = "string" } # Unicode string "pstring" { $fixedReturnType = "string" } # ANSI string (likely) "pwchar" { $fixedReturnType = "string" } # Unicode char* "lpwchar" { $fixedReturnType = "string" } # Unicode char* "pczpwstr" { $fixedReturnType = "string" } # Unicode string "pzpwstr" { $fixedReturnType = "string" } "pzwstr" { $fixedReturnType = "string" } "pzzwstr" { $fixedReturnType = "string" } "pczzwstr" { $fixedReturnType = "string" } "puczzwstr" { $fixedReturnType = "string" } "pcuczzwstr" { $fixedReturnType = "string" } "pnzwch" { $fixedReturnType = "string" } "pcnzwch" { $fixedReturnType = "string" } "punzwch" { $fixedReturnType = "string" } "pcunzwch" { $fixedReturnType = "string" } # ANSI string types "npstr" { $fixedReturnType = "string" } # ANSI string "pzpcstr" { $fixedReturnType = "string" } "pczpcstr" { $fixedReturnType = "string" } "pzzstr" { $fixedReturnType = "string" } "pczzstr" { $fixedReturnType = "string" } "pnzch" { $fixedReturnType = "string" } "pcnzch" { $fixedReturnType = "string" } # UCS types "ucschar" { $fixedReturnType = "uint" } # leave as uint "pucschar" { $fixedReturnType = "IntPtr" } "pcucschar" { $fixedReturnType = "IntPtr" } "puucschar" { $fixedReturnType = "IntPtr" } "pcuucschar" { $fixedReturnType = "IntPtr" } "pucsstr" { $fixedReturnType = "IntPtr" } "pcucsstr" { $fixedReturnType = "IntPtr" } "puucsstr" { $fixedReturnType = "IntPtr" } "pcuucsstr" { $fixedReturnType = "IntPtr" } # Neutral ANSI/Unicode (TCHAR-based) Types "ptchar" { $fixedReturnType = "IntPtr" } # keep IntPtr due to TCHAR ambiguity "tbyte" { $fixedReturnType = "byte" } "ptbyte" { $fixedReturnType = "IntPtr" } "ptstr" { $fixedReturnType = "IntPtr" } "lptstr" { $fixedReturnType = "IntPtr" } "pctstr" { $fixedReturnType = "IntPtr" } "lpctstr" { $fixedReturnType = "IntPtr" } "putstr" { $fixedReturnType = "IntPtr" } "lputstr" { $fixedReturnType = "IntPtr" } "pcutstr" { $fixedReturnType = "IntPtr" } "lpcutstr" { $fixedReturnType = "IntPtr" } "pzptstr" { $fixedReturnType = "IntPtr" } "pzzstr" { $fixedReturnType = "IntPtr" } "pczztstr" { $fixedReturnType = "IntPtr" } "pzzwstr" { $fixedReturnType = "string" } # Unicode string "pczzwstr" { $fixedReturnType = "string" }
Update version again, main post will update soon. so, no limit the ammount of Api paramaters found better way. so, support for any paramters Count, so, not limit to 10 com parameters, and 12 api parameter's and also using script block. and it also fit my dynamic load style Code: function Invoke-Object { [CmdletBinding()] param ( [Parameter(Mandatory, ValueFromPipeline)] $Interface, [Parameter(ValueFromRemainingArguments = $true)] [object[]]$Params, [Parameter(Mandatory)] [ValidateSet("API", "COM")] [string]$type ) [int]$count = 0 [void][Int]::TryParse($Params.Count, [ref]$count) $sb = New-Object System.Text.StringBuilder if ($type -eq 'COM') { if ($count -gt 0) { [void]$sb.Append('$Interface.IUnknownPtr,') } else { [void]$sb.Append('$Interface.IUnknownPtr') } } if ($count -gt 0) { for ($i = 0; $i -lt $count; $i++) { if ($i -gt 0) { [void]$sb.Append(',') } [void]$sb.Append("`$Params[$i]") } } $argsString = $sb.ToString() return & ( [scriptblock]::Create("`$Interface.DelegateInstance.Invoke($argsString)") ) }
an extension to current library, it allow you to remove the parsing of params and let's .net do it for you. free. and auto select Ansi/Unicode charset keep you only with. --> Code: Clear-Host Write-Host Call-UnmanagedMethod ` -Dll "User32.dll" ` -Function "MessageBoxA" ` -Values @( [Int64]0, "Text Block", "Text title", 20, [UIntPtr]::new(9), 1,2,"Alpha", ([REF]1), ([REF]"1"), [Int16]1, ([REF][uInt16]2) ) ` -ShowDebug New extension (updated!) Code: function Call-UnmanagedMethod { [CmdletBinding()] param( [Parameter(Mandatory=$true, Position=0)] [string]$Dll, [Parameter(Mandatory=$true, Position=1)] [string]$Function, [Parameter(Mandatory=$false, Position=2, ValueFromRemainingArguments=$true)] [object[]]$Values, [switch]$ShowDebug ) $Count = 0 [void][int]::TryParse($Values.Count,[ref]$count) $IsArrayObj = $Count -eq 1 -and $Values[0] -is [System.Array] if ($IsArrayObj) { throw "Cast all object with -Values @() Please" } try { if ($Count -le 0) { throw } $paramTypes = @($Values | % { $vType = $_.GetType() $ref = '' $Type = $vType.BaseType.Name if ($Type -eq 'PSReference') { $Name = $vType.GenericTypeArguments.Name $ref = 'ref ' } else { $Name = $vType.Name } switch ($Name) { "Int16" { "$($ref)short" } "Int32" { "$($ref)int" } "Int64" { "$($ref)long" } "UInt16" { "$($ref)ushort" } "UInt32" { "$($ref)uint" } "UInt64" { "$($ref)ulong" } "String" { "$($ref)string" } "Boolean" { "$($ref)bool" } "Double" { "$($ref)double" } "Single" { "$($ref)float" } "Byte" { "$($ref)byte" } "SByte" { "$($ref)sbyte" } "IntPtr" { "$($ref)intptr" } "UIntPtr" { "$($ref)UIntPtr" } "Char" { "$($ref)char" } "Guid" { "$($ref)guid" } "default" { throw "Unknown value: $Name" } } }) $ParamsArray = 0..($Count-1) | % { "$($paramTypes[$_]) $([char](65 + $_))" } $ParamsString = $ParamsArray -join ", " } catch { $paramTypes = '' $ParamsString = '' } $CharSet = if ($Function -like "*A") { "Ansi" } else { "Unicode" } if ($ShowDebug) { Write-Host "DLL:" -ForegroundColor Cyan -NoNewline Write-Host " $Dll" -ForegroundColor White Write-Host "Function:" -ForegroundColor Cyan -NoNewline Write-Host " $Function" -ForegroundColor White Write-Host "Values:" -ForegroundColor Cyan -NoNewline Write-Host " $($Values -join ', ')" -ForegroundColor Yellow Write-Host "Param types:" -ForegroundColor Cyan -NoNewline Write-Host " $($paramTypes -join ', ')" -ForegroundColor Green Write-Host "Params string:" -ForegroundColor Cyan -NoNewline Write-Host " $ParamsString" -ForegroundColor Magenta Write-Host "CharSet:" -ForegroundColor Cyan -NoNewline Write-Host " $CharSet" -ForegroundColor White } return ( Invoke-UnmanagedMethod ` -Dll $Dll ` -Function $Function ` -Return "int32" ` -Params $ParamsString ` -Values $Values ` -CharSet $CharSet ) }
Darki will update main post soon. update libary again, make load dll very easy 3 ways, Register, Dynamic + params, Dinamic + no params [Lazy Ass mode] Code: $Func = Register-NativeMethods @( @{ Name = "MessageBoxA" Dll = "user32.dll" ReturnType = [int] CharSet = 'Ansi' Parameters = [Type[]]@( [IntPtr], # hWnd [string], # lpText [string], # lpCaption [uint32] # uType ) }) $Func::MessageBoxA( [IntPtr]::Zero, "Hello from ANSI!", "MessageBoxA", 0) # Test Charset <> Ansi Invoke-UnmanagedMethod ` -Dll "user32.dll" ` -Function "MessageBoxA" ` -Return "int32" ` -Params "HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType" ` -Values @(0, "Hello from ANSI!", "MessageBoxA", 0) ` -CharSet Ansi Lazy Ass mode. you dont choice nothing, just prove parameter's to pass! cause you lazy. parameters supported also ([ref][]) Code: # Test Charset <> Ansi Invoke-UnmanagedMethod ` -Dll "User32.dll" ` -Function "MessageBoxA" ` -Values @( [Int64]0, "Some Text", "Some title", 0) Also this crap, can pass too. Code: # Test Charset <> Ansi Invoke-UnmanagedMethod ` -Dll "User32.dll" ` -Function "MessageBoxA" ` -Values @( [Int64]0, "Some Text", "Some title", 0, ([ref]"a"), ([ref][UintPtr]::new(90)), ([ref][Guid]::Empty)) what object's you should *Never* pass [structs], [ref]->[structs], [Object],[ref]-> [Object],[Decimal]. *Never* and, string as [In],[out], no! never. use pointer's + [Marshal]! you can allocate enough bytes as pointer for String size of (Ansi Length * 1, Unicode length * 2) only things that accaptable as legit object in C\C+ and supported by .Net C# (****) like pointer (IntPtr, UintPtr), Numbers (16,32,64), guid, Ref type's. etc. etc. are legit. (string, guid, [ref]) **** -->> who can be inside C# Delegate, important notice! <<--
will upload new version soon as i can. will support VARIANT struct s**t and also add support for free more crap, also, Use-ComInterface have new option, select type in case auto detection fail (C2E88C2F-6F5B-4AAA-894B-55C847AD3A2D,, it say it imarshal,,,, no.) Demo for Code: MIDL_INTERFACE("85713fa1-7796-4fa2-be3b-e2d6124dd373") IWindowsUpdateAgentInfo : public IDispatch { public: virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE GetInfo( /* [in] */ VARIANT varInfoIdentifier, /* [retval][out] */ __RPC__out VARIANT *retval) = 0; }; // {C2E88C2F-6F5B-4AAA-894B-55C847AD3A2D} DEFINE_GUID(CLSID_WindowsUpdateAgentInfo,0xC2E88C2F,0x6F5B,0x4AAA,0x89,0x4B,0x55,0xC8,0x47,0xAD,0x3A,0x2D); * IWindowsUpdateAgentInfo interface (wuapi.h) * https://learn.microsoft.com/en-us/windows/win32/api/wuapi/nf-wuapi-iwindowsupdateagentinfo-getinfo HRESULT GetInfo( [in] VARIANT varInfoIdentifier, [out] VARIANT *retval ); Code. Code: Clear-Host "ApiMajorVersion", "ApiMinorVersion", "ProductVersionString" | ForEach-Object { $name = $_ $outVarPtr = New-Variant -Type VT_EMPTY $inVarPtr = New-Variant -Type VT_BSTR -Value $name try { $ret = Use-ComInterface ` -CLSID "C2E88C2F-6F5B-4AAA-894B-55C847AD3A2D" ` -IID "85713fa1-7796-4fa2-be3b-e2d6124dd373" ` -Index 1 -Name "GetInfo" ` -Values @($inVarPtr, $outVarPtr) ` -Type IDispatch if ($ret -eq 0) { $value = Parse-Variant -variantPtr $outVarPtr Write-Host "$name -> $value" } } finally { Free-IntPtr -handle $inVarPtr -Method VARIANT Free-IntPtr -handle $outVarPtr -Method VARIANT } }
Upload new version clean Com object invoke code, little upgrade also, sort interface verify by diffrent order to avoid misled as `imarshal` instead `idispatch` ( interface who inh` idispatch can be seen also as `imarshal`, problem)