The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

Win32::Security::Raw - low-level access Win32 Security API calls

SYNOPSIS

        use Win32::Security::Raw;

DESCRIPTION

This module provides access to a limited number of Win32 Security API calls. As I have need for other functions I will add them to the module. If anyone has suggestions, feel free to ask - I will be quite happy to extend this module.

Installation instructions

This installs as part of Win32-Security. See Win32::Security::NamedObject for more information.

It depends upon the Win32::API and Data::BitMask modules, which should be installable via PPM or available on CPAN.

Function Reference: Helper functions

_is_x64

Returns 1 if Perl is x64, 0 if Perl is x86.

_uint32

Clarifies using Win32::API on both the x86 (32-bit) and x64 (64-bit) versions of Perl. It returns the Win32::API parameter character specifier for an unsigned 32-bit, independent of Perl bit-version:

  • I (unsigned 32-bit int) on x64 Perl

  • I (unsigned 32-bit int) on x32 Perl

_uint64

Clarifies using Win32::API on both the x86 (32-bit) and x64 (64-bit) versions of Perl. It returns the Win32::API parameter character specifier for an unsigned pointer-sized int (i.e. 32-bit on x86, 64-bit on x64), dependent on Perl bit-version:

  • Q (unsigned 64-bit int) on x64 Perl

  • I (unsigned 32-bit int) on x32 Perl

_pack_uint32

Clarifies using pack/unpack on both the x86 (32-bit) and x64 (64-bit) versions of Perl. It returns the pack/unpack TEMPLATE character for an unsigned 32-bit, independent of Perl bit-version:

  • V (unsigned 32-bit int) on x64 Perl

  • V (unsigned 32-bit int) on x32 Perl

_pack_uint64

Clarifies using pack/unpack on both the x86 (32-bit) and x64 (64-bit) versions of Perl. It returns the pack/unpack TEMPLATE character for an unsigned pointer-sized int (i.e. 32-bit on x86, 64-bit on x64), dependent on Perl bit-version:

  • Q (unsigned 64-bit int) on x64 Perl

  • V (unsigned 32-bit int) on x32 Perl

_format_error

Formats an error message starting with the passed Win32 API function name, followed by the output from Win32::FormatMessage on the optional passed $retval or return value from Win32::GetLastError.

Function Reference: Memory functions

LocalAlloc

Calls LocalAlloc with the passed Flags and Bytes. It returns a pointer as a Perl int, but dies if a null pointer is returned from the call. The Flags parameter can be passed as either an integer or as legal Win32::Security::LMEM_FLAGS.

LocalFree

Calls LocalFree on the passed pointer (as Perl int).

LocalSize

Calls LocalSize on the passed pointer (as Perl int).

CopyMemory_Read

Uses RtlMoveMemory to copy an arbitrary memory location into a Perl string. Pass pointer as Perl int. The number of bytes to read from that location is optional - if not passed, LocalSize will be used to determine the number of bytes to read.

The function will return the data read in a Perl string.

CopyMemory_Write

Uses RtlMoveMemory to write to an arbitrary memory location. Pass a string that will be copied and a pointer (as Perl int). The caller is responsible for ensuring that the data to be written will not overrun the memory location.

Function Reference: Process functions

GetCurrentProcess

Returns a handle to the CurrentProcess as an integer.

OpenProcessToken

Pass ProcessHandle and DesiredAccess (TokenRights). Returns TokenHandle.

LookupPrivilegeValue

Pass SystemName (undef permitted) and a privilege Name (i.e. SeRestorePrivilege). Returns the Luid.

AdjustTokenPrivileges

Pass the following three parameters:

  • TokenHandle from OpenProcessToken

  • DisableAllPrivileges 0 or 1

  • NewState array ref like so: [ [Luid from LookupPrivilegeValue, LUID_ATTRIBUTES mask], .. ] i.e. [ [$luid, 'SE_PRIVILEGE_ENABLED'] ]

The first return value is array PreviousState that will be similar to the passed NewState. The second return value is any error messages returned from the call to AdjustTokenPrivileges.

Function Reference: Security Descriptor functions

GetNamedSecurityInfo

This expects an object name (i.e. a path to a file, registry key, etc.), an object type (i.e. 'SE_FILE_OBJECT'), and a SECURITY_INFORMATION mask (i.e. 'OWNER_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION'). It returns pointers (as Perl ints) to sidOwner, sidGroup, Dacl, Sacl, and the SecurityDescriptor. Some of these may be null pointers.

IMPORTANT: When done with the returned data, call Win32::Security::Raw::LocalFree on the returned SecurityDescriptor;

GetSecurityDescriptorControl

This expects a pointer to a SecurityDescriptor. It returns the Data::BitMask::break_mask form for the SECURITY_DESCRIPTOR_CONTROL mask and the Revision.

GetLengthSid

This accepts a pointer (as a Perl int) to a SID as an integer and returns the length.

GetAclInformation

This expects a pointer to an ACL and an AclInformationClass value (i.e. 'AclSizeInformation' or 'AclRevisionInformation'). It returns the approriate data for the AclInformationClass value (the AclRevision in the case of AclRevisionInformation, the AceCount, AclBytesInUse, and AclBytesFree in the case of AclSizeInformation).

SECURITY_DESCRIPTOR_MIN_LENGTH

Returns the minimum length for a valid SecurityDescriptor. This is 4 bytes plus 4 times the size of a pointer (i.e. 4 + 4*4 = 20 on x86, 4 + 4*8 = 36 on x64).

InitializeSecurityDescriptor

Revision is optional - if omitted, revision 1 is used. Dies if the call fails.

The call will allocate a chunk of memory for the new SecurityDescriptor before initializing it and then return a pointer to it.

IMPORTANT: When done with using the new SecurityDescriptor, call Win32::Security::Raw::LocalFree on the returned SecurityDescriptor;

SetSecurityDescriptorDacl

Calls SetSecurityDescriptorDacl. Expects a pointer to a SecurityDescriptor, bool DaclPresent, pointer to Dacl, and pointer to DaclDefaulted. Dies if the call fails.

SetFileSecurity

Pass FileName, SecurityInfo, and pointer (as Perl int) to SecurityDescriptor. Useful for setting permissions without propagating inheritable ACEs.

SetNamedSecurityInfo

This expects an object name (i.e. a path to a file, registry key, etc.), an object type (i.e. 'SE_FILE_OBJECT'), and a SECURITY_INFORMATION mask (i.e. 'OWNER_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION'), and byte strings for sidOwner, sidGroup, Dacl, and Sacl. The byte strings may be undef if they are not referenced in the SECURITY_INFORMATION mask.

Data::BitMask Objects

The objects are accessed via class methods on Win32::Security. The Data::BitMask objects are created by the first call and lexically cached.

&Win32::Security::SE_OBJECT_TYPE

Win32 constants for SE_OBJECT_TYPE, along with the following aliases:

  • FILE (SE_FILE_OBJECT)

  • SERVICE (SE_SERVICE)

  • PRINTER (SE_PRINTER)

  • REG (SE_REGISTRY_KEY)

  • REGISTRY (SE_REGISTRY_KEY)

  • SHARE (SE_LMSHARE)

&Win32::Security::SECURITY_INFORMATION

&Win32::Security::SECURITY_DESCRIPTOR_CONTROL

&Win32::Security::ACL_INFORMATION_CLASS

&Win32::Security::TokenRights

&Win32::Security::LUID_ATTRIBUTES

&Win32::Security::LMEM_FLAGS

AUTHOR

Toby Ovod-Everett, toby@ovod-everett.org