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)
Fix few bugs & Update ~ Free Heap using ntdll call instead kernelbase call [update] ~ Invoke-NativeProcess, console return memory error [fixed] ~ Adjust-TokenPrivileges, if 1 fail, all function fail [fixed] ~ Get-LoadedModules, some variable construct outside the loop [fixed] ~ Some Modules improve ~~~~~~~~~~~~~~~~~~~~ ~ Invoke-NativeProcess Now support x64/x86 [tested only on x64]
Added few update, And now also added Code: * Get Access to TEB / PEB & Structs, using shellCode injection *NEW*
Update the library. some of the Ntdll calls have wrong defination [x64 work fine, x86 fail, ise crash] It also fix the Invoke-unmanaged meth` to work well in x86 enviroment Invoke native process, still fail at x86, could figure out the reason [yet]
-- x86 Support added -- stub validation added ~~~~~~~~~~~~~~ Will update the libary soon, Will support SyaCalls AKA STUB using PS1 code And yes, it Acquire the sysCall value directly from the NTDLL! function SO, now this library can be called officially a a malware
Well, darki found that some Sec` software hook your Api, so, it will read the Actual file, and extract the Function Data, include SyscalliD, problem solved.! in my case, NtClose was hooked by comodo, so, i couldn't extract the SysCallID. upload new version now. So, now this should work fine. Code: NtGetNextProcess Test WARNING: Returning reusable module object for NTDLL 0 0 1924 NtGetNextThread Test WARNING: Returning reusable module object for NTDLL 0 0 4328 NtClose Test 000 Hooked by Comodo Sec` software WARNING: Returning reusable module object for NTDLL 0 0
So, in the origional Context, Offer here Code: GitHub - jhalon/SharpCall: Simple PoC demonstrating syscall execution in C# https://github.com/jhalon/SharpCall Red Team Tactics: Utilizing Syscalls in C# - Writing The Code - Jack Hacks https://jhalon.github.io/utilizing-syscalls-in-csharp-2/ Lot of code, SO, darki make create the same example just shorter, Create file, using SysCall with minimum params, using PS`1 Support x64 system, and x64 process ~~~~~~~~~~~~~~~~~~~~~ BTW seems that Comodo, also hooked NtCreateFile. well. Darki have to read it from Local file. [fail safe method]. i always recommnded on this software, provide a couple layer of protection Code: Clear-Host Write-Host write-host 'NtCreateFile Test' $FileHandle = [IntPtr]::Zero $IoStatusBlock = New-IntPtr -Size 16 $ObjectAttributes = New-IntPtr -Size 48 -WriteSizeAtZero $filePath = ("\??\{0}\test.txt" -f [Environment]::GetFolderPath('Desktop')) $ObjectName = Init-NativeString -Encoding Unicode -Value $filePath [Marshal]::WriteIntPtr($ObjectAttributes, 0x10, $ObjectName) [Marshal]::WriteInt32($ObjectAttributes, 0x18, 0x40) # Call syscall Invoke-UnmanagedMethod ` -Dll NTDLL ` -Function NtCreateFile ` -Values @( ([ref]$FileHandle), # OUT HANDLE 0x40100080, # DesiredAccess (GENERIC_WRITE | SYNCHRONIZE | FILE_WRITE_DATA) $ObjectAttributes, # POBJECT_ATTRIBUTES $IoStatusBlock, # PIO_STATUS_BLOCK [IntPtr]::Zero, # AllocationSize 0x80, # FileAttributes (FILE_ATTRIBUTE_NORMAL) 0x07, # ShareAccess (read|write|delete) 0x5, # CreateDisposition (FILE_OVERWRITE_IF) 0x20, # CreateOptions (FILE_NON_DIRECTORY_FILE) [IntPtr]::Zero, # EaBuffer 0x00 # EaLength ) ` -SysCall Free-NativeString -StringPtr $ObjectName
PS1 libary updates. test file is seperated add option to run as user [using 3 high level api], 2 using advapi rpc call, another 1 using NtCreateProcess add uoption for Token / Procss using low level create process, HToken support need System Acc' add c+ dll helper to help deal with token for RunAs, based on hard work from, https://github.com/msmania/logue/blob/master/logue.cpp add option to get heap address, from TEB [NtCurrentTeb -ProcessHeap ~~~~~~~~~~~~~~~~~~~ Logon Way, simple RPC call, from any user, work fine [not work from sys` account] Token Way, work fine, using Modified token, using modern APi from visa era [rest from xp era !], using RPC call. User Way, from kernelbase, not from advapi like others, not rpc call, stub sys call to NtCreateProcess Api .! Token & User ways, both use modifed token, using external C+ dll api call, saved in temp folder.! Invoke-NativeProcess + hToken, same but low level, and manual contract everything. need sys` to make it work.! ~~~~~~~~~~~~~~~~~~~ Source's msmania github https://github.com/msmania/logue Starting an Interactive Client Process in C++ (Windows) - Microsoft Learn https://learn.microsoft.com/en-us/previous-versions//aa379608(v=vs.85)?redirectedfrom=MSDN ~~~~~~~~~~~~~~~~~~~ Code: # Fail from system/TI Write-Host 'Invoke-ProcessAsUser, As Logon' -ForegroundColor Green Invoke-ProcessAsUser ` -Application cmd ` -CommandLine "/k whoami" ` -UserName user ` -Password 0444 ` -Mode Logon ` -RunAsConsole # Work From both Normal/Admin/System/TI Account Write-Host 'Invoke-ProcessAsUser, As Token' -ForegroundColor Green Invoke-ProcessAsUser ` -Application cmd ` -CommandLine "/k whoami" ` -UserName user ` -Password 0444 ` -Mode Token ` -RunAsConsole # only work from system/TI Write-Host 'Invoke-ProcessAsUser, As User' -ForegroundColor Green Invoke-ProcessAsUser ` -Application cmd ` -CommandLine "/k whoami" ` -UserName user ` -Password 0444 ` -Mode User ` -RunAsConsole # only work from system/TI Write-Host 'Invoke-NativeProcess, with hToken' -ForegroundColor Green $hToken = Obtain-UserToken ` -UserName user ` -Password 0444 ` -loadProfile Invoke-NativeProcess ` -ImageFile cmd ` -commandLine "/k whoami" ` -hToken $hToken Free-IntPtr $hToken -Method NtHandle
Did some extra tests Under window 10 it does do problem Well, in later windows 11 LTSC, work fine All 4 ways , so, wtf is that ?? Maybe kernel is more friendly, or security software Seriously, don’t understand why In both tests I use administrator account
27/09/25 Change's Added Dacl.dll into main thread [open source] Adjust-TokenPrivileges, Add nwe paramter [-Query] All Run-As modes will run at all System W11/W10, with a warning [cause, w11, all modes run fine, w10, some` you need system Acc] ~~~~~~~~~~~~~~~ i try to make .dll -> managed library based code, using Managed available C# libraries only, not so easy. so, for now, DLL call, to modify Ace etc etc. [using custom dacl.dll] ~~~~~~~~~~~~~~~ Demo result's Code: PS C:\Users\Administrator> Adjust-TokenPrivileges -Query Name LUID Enabled ---- ---- ------- SeLockMemoryPrivilege 4 False SeIncreaseQuotaPrivilege 5 True SeSecurityPrivilege 8 False SeTakeOwnershipPrivilege 9 False SeLoadDriverPrivilege 10 False SeSystemProfilePrivilege 11 False SeSystemtimePrivilege 12 False SeProfileSingleProcessPrivilege 13 False SeIncreaseBasePriorityPrivilege 14 False SeCreatePagefilePrivilege 15 False SeBackupPrivilege 17 False SeRestorePrivilege 18 False SeShutdownPrivilege 19 False SeDebugPrivilege 20 True SeSystemEnvironmentPrivilege 22 True SeChangeNotifyPrivilege 23 True SeRemoteShutdownPrivilege 24 False SeUndockPrivilege 25 False SeManageVolumePrivilege 28 False SeImpersonatePrivilege 29 True SeCreateGlobalPrivilege 30 True SeIncreaseWorkingSetPrivilege 33 False SeTimeZonePrivilege 34 False SeCreateSymbolicLinkPrivilege 35 False SeDelegateSessionUserImpersonatePrivilege 36 False