{"id":14063498,"url":"https://github.com/jborean93/PowerShell-ctypes","last_synced_at":"2025-07-29T15:33:39.219Z","repository":{"id":65426084,"uuid":"590784454","full_name":"jborean93/PowerShell-ctypes","owner":"jborean93","description":"PowerShell module for ctypes/PInvoke calls","archived":false,"fork":false,"pushed_at":"2024-11-10T19:16:20.000Z","size":143,"stargazers_count":21,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"main","last_synced_at":"2024-11-25T09:26:51.518Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"PowerShell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jborean93.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-01-19T07:44:10.000Z","updated_at":"2024-11-10T19:16:23.000Z","dependencies_parsed_at":"2024-08-13T07:15:02.994Z","dependency_job_id":null,"html_url":"https://github.com/jborean93/PowerShell-ctypes","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jborean93%2FPowerShell-ctypes","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jborean93%2FPowerShell-ctypes/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jborean93%2FPowerShell-ctypes/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jborean93%2FPowerShell-ctypes/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jborean93","download_url":"https://codeload.github.com/jborean93/PowerShell-ctypes/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":228028458,"owners_count":17858338,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-13T07:03:22.186Z","updated_at":"2025-07-29T15:33:39.204Z","avatar_url":"https://github.com/jborean93.png","language":"PowerShell","readme":"# Ctypes\n\n[![Test workflow](https://github.com/jborean93/PowerShell-ctypes/workflows/Test%20Ctypes/badge.svg)](https://github.com/jborean93/PowerShell-ctypes/actions/workflows/ci.yml)\n[![codecov](https://codecov.io/gh/jborean93/PowerShell-Ctypes/branch/main/graph/badge.svg?token=b51IOhpLfQ)](https://codecov.io/gh/jborean93/PowerShell-Ctypes)\n[![PowerShell Gallery](https://img.shields.io/powershellgallery/dt/Ctypes.svg)](https://www.powershellgallery.com/packages/Ctypes)\n[![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/jborean93/PowerShell-ctypes/blob/main/LICENSE)\n\nProvides a unique way to call native APIs in PInvoke in PowerShell.\nIt is modelled after the Python [ctypes library](https://docs.python.org/3/library/ctypes.html).\n\nSee [ctypes index](docs/en-US/Ctypes.md) for more details.\n\n## Examples\n\n_Note: All these examples use the generics to specify the return method which is pwsh 7.3+ only. Use `.Returns([type])` instead for older versions._\n\n### Calling CreateFileW directly\n\n```powershell\n$k32 = New-CtypesLib Kernel32.dll\n$fh = $k32.CharSet('Unicode').SetLastError().CreateFileW[Microsoft.Win32.SafeHandles.SafeFileHandle](\n    \"\\\\?\\C:\\temp\\test.txt\",\n    [System.Security.AccessControl.FileSystemRights]'FullControl',\n    [System.IO.FileShare]::Read,\n    $null,\n    [System.IO.FileMode]::Create,\n    0,  # FlagsAndAttributes\n    $null)\nif ($fh.IsInvalid -eq [IntPtr](-1)) {\n    throw [System.ComponentModel.Win32Exception]$k32.LastError\n}\n\n$fs = [System.IO.FileStream]::new($fh, [System.IO.FileAccess]::ReadWrite)\n...\n```\n\nCalls [CreateFileW](https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilew) directly with the long path prefix and creates a filestream on the returned object.\nIt also wraps the raw handle in a `SafeFileHandle` making it easy to dispose the object when not needed anymore.\n\n### Using a struct and references\n\n```powershell\n[int]$processId = Read-Host -Prompt 'What pid do you wish to inspect'\n$k32 = New-CtypesLib Kernel32.dll\n$advapi = New-CtypesLib Advapi32.dll\n\n[Flags()] enum PrivilegeAttributes {\n    NONE = 0x00000000\n    SE_PRIVILEGE_ENABLED_BY_DEFAULT = 0x00000001\n    SE_PRIVILEGE_ENABLED = 0x00000002\n    SE_PRIVILEGE_REMOVED = 0x00000004\n    SE_PRIVILEGE_USED_FOR_ACCESS = 0x80000000\n}\n\nctypes_struct LUID {\n    [int]$LowPart\n    [int]$HighPart\n}\n\nctypes_struct LUID_AND_ATTRIBUTES {\n    [LUID]$Luid\n    [PrivilegeAttributes]$Attributes\n}\n\nctypes_struct TOKEN_PRIVILEGES {\n    [int]$PrivilegeCount\n    [MarshalAs('ByValArray', SizeConst=1)][LUID_AND_ATTRIBUTES[]]$Privileges\n}\n\n$proc = $k32.SetLastError().OpenProcess[IntPtr](\n    0x400,  # PROCESS_QUERY_INFORMATION\n    $false,\n    $processId)\nif ($proc -eq [IntPtr]::Zero) {\n    throw [System.ComponentModel.Win32Exception]$k32.LastError\n}\n\n$handle = [IntPtr]::Zero\n$buffer = [IntPtr]::Zero\ntry {\n    $res = $advapi.SetLastError().OpenProcessToken[bool](\n        $proc,\n        [System.Security.Principal.TokenAccessLevels]::Query,\n        [ref]$handle)\n    if (-not $res) {\n        throw [System.ComponentModel.Win32Exception]$advapi.LastError\n    }\n\n    $bufferLength = 0\n    $null = $advapi.SetLastError().GetTokenInformation[bool](\n        $handle,\n        3,  # TokenPrivileges\n        $null,\n        0,\n        [ref]$bufferLength)\n    $buffer = [System.Runtime.InteropServices.Marshal]::AllocHGlobal($bufferLength)\n\n    $res = $advapi.GetTokenInformation(\n        $handle,\n        3,\n        $buffer,\n        $bufferLength,\n        [ref]$bufferLength)\n    if (-not $res) {\n        throw [System.ComponentModel.Win32Exception]$advapi.LastError\n    }\n\n    $privileges = [System.Runtime.InteropServices.Marshal]::PtrToStructure($buffer,\n        [type][TOKEN_PRIVILEGES])\n    $currentPtr = [IntPtr]::Add($buffer, 4)  # Offset to the Privileges array\n    for ($i = 0; $i -lt $privileges.PrivilegeCount; $i++) {\n        $info = [System.Runtime.InteropServices.Marshal]::PtrToStructure($currentPtr,\n            [type][LUID_AND_ATTRIBUTES])\n\n        $luid = $info.Luid\n        $name = [System.Text.StringBuilder]::new(0)\n        $nameLength = 0\n        $null = $advapi.SetLastError().CharSet('Unicode').LookupPrivilegeNameW[bool](\n            $null,\n            [ref]$luid,\n            $name,\n            [ref]$nameLength)\n\n        $null = $name.EnsureCapacity($nameLength + 1)\n        $res = $advapi.LookupPrivilegeNameW(\n            $null,\n            [ref]$luid,\n            $name,\n            [ref]$nameLength)\n        if (-not $res) {\n            throw [System.ComponentModel.Win32Exception]$advapi.LastError\n        }\n\n        [PSCustomObject]@{\n            Name = $name.ToString()\n            Luid = $luid\n            Attributes = $info.Attributes\n        }\n        $currentPtr = [IntPtr]::Add($currentPtr, [System.Runtime.InteropServices.Marshal]::SizeOf(\n            [type][LUID_AND_ATTRIBUTES]))\n    }\n}\nfinally {\n    if ($buffer -ne [IntPtr]::Zero) {\n        [System.Runtime.InteropServices.Marshal]::FreeHGlobal($buffer)\n    }\n    if ($handle -ne [IntPtr]::Zero) {\n        $k32.CloseHandle[void]($handle)\n    }\n    $k32.CloseHandle[void]($proc)\n}\n```\n\nThis is a more complex example that uses reference types and structs to get the token privileges of another process handle.\n\n### Gettings libc version\n\n```powershell\n$libc = New-CtypesLib libc\n[System.Runtime.InteropServices.Marshal]::PtrToStringUTF8(\n    $libc.gnu_get_libc_version[IntPtr]())\n```\n\n_Note: This can't return a string directly as dotnet will try and free the memory which cannot be done._\n\n## Requirements\n\nThese cmdlets have the following requirements\n\n* PowerShell v5.1, or 7.4+\n\n## Installing\n\nThe easiest way to install this module is through [PowerShellGet](https://docs.microsoft.com/en-us/powershell/gallery/overview).\n\nYou can install this module by running;\n\n```powershell\n# Install for only the current user\nInstall-PSResource -Name Ctypes -Scope CurrentUser\nInstall-Module -Name Ctypes -Scope CurrentUser\n\n# Install for all users\nInstall-PSResource -Name Ctypes -Scope AllUsers\nInstall-Module -Name Ctypes -Scope AllUsers\n```\n\n## Contributing\n\nContributing is quite easy, fork this repo and submit a pull request with the changes.\nTo build this module run `.\\build.ps1 -Task Build` in PowerShell.\nTo test a build run `.\\build.ps1 -Task Test` in PowerShell.\nThis script will ensure all dependencies are installed before running the test suite.\n","funding_links":[],"categories":["PowerShell"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjborean93%2FPowerShell-ctypes","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjborean93%2FPowerShell-ctypes","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjborean93%2FPowerShell-ctypes/lists"}