Com & Un-Managed Warper for PS1.

Discussion in 'Scripting' started by Dark Vador, Jul 7, 2025.

  1. Dark Vador

    Dark Vador X Æ A-12

    Feb 2, 2011
    4,763
    7,027
    150
    #21 Dark Vador, Aug 11, 2025
    Last edited: Aug 11, 2025
    (OP)
    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.

    upload_2025-8-11_19-43-39.png
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  2. Dark Vador

    Dark Vador X Æ A-12

    Feb 2, 2011
    4,763
    7,027
    150
    #22 Dark Vador, Aug 12, 2025
    Last edited: Aug 12, 2025
    (OP)
    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
    
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  3. Dark Vador

    Dark Vador X Æ A-12

    Feb 2, 2011
    4,763
    7,027
    150
    #23 Dark Vador, Aug 13, 2025
    Last edited: Aug 14, 2025
    (OP)
    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.
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  4. Dark Vador

    Dark Vador X Æ A-12

    Feb 2, 2011
    4,763
    7,027
    150
    #24 Dark Vador, Aug 15, 2025
    Last edited: Aug 15, 2025
    (OP)
    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)

    upload_2025-8-15_17-31-5.png

    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" }
    
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  5. Dark Vador

    Dark Vador X Æ A-12

    Feb 2, 2011
    4,763
    7,027
    150
    #25 Dark Vador, Aug 15, 2025
    Last edited: Aug 15, 2025
    (OP)
    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
    
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  6. Dark Vador

    Dark Vador X Æ A-12

    Feb 2, 2011
    4,763
    7,027
    150
    #26 Dark Vador, Aug 16, 2025
    Last edited: Aug 16, 2025
    (OP)
    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" }
    
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  7. Dark Vador

    Dark Vador X Æ A-12

    Feb 2, 2011
    4,763
    7,027
    150
    #27 Dark Vador, Aug 16, 2025
    Last edited: Aug 16, 2025
    (OP)
    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 :rolleyes:

    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)")
        )
    }
    
    
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  8. Dark Vador

    Dark Vador X Æ A-12

    Feb 2, 2011
    4,763
    7,027
    150
    #28 Dark Vador, Aug 17, 2025
    Last edited: Aug 18, 2025
    (OP)
    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
    
    upload_2025-8-18_6-36-24.png

    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 )
    }
    
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  9. Dark Vador

    Dark Vador X Æ A-12

    Feb 2, 2011
    4,763
    7,027
    150
    #29 Dark Vador, Aug 18, 2025
    Last edited: Aug 18, 2025
    (OP)
    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.:D
    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. :D
    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! <<--
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  10. Dark Vador

    Dark Vador X Æ A-12

    Feb 2, 2011
    4,763
    7,027
    150
    #30 Dark Vador, Aug 23, 2025 at 21:28
    Last edited: Aug 23, 2025 at 21:49
    (OP)
    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
        }
    }
    
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  11. Dark Vador

    Dark Vador X Æ A-12

    Feb 2, 2011
    4,763
    7,027
    150
    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)
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...