I am importing ntdll.dll RtlDeriveCapabilitySidsFromName function and having access violation inside it. But can't figure what i am doing wrong.
import win32file, win32api
import os
import ctypes
import sys
from ctypes import *
from struct import calcsize
from ctypes.wintypes import BOOL, LPCVOID, LPCWSTR
prototype = WINFUNCTYPE(BOOL, LPCWSTR, LPCVOID, LPCVOID, LPCVOID, LPCVOID, use_last_error=True)
cap_group_sids = create_string_buffer(b"", 1024)
sid = create_unicode_buffer(u"S-1-15-3-1024-3424233489-972189580-2057154623-747635277-1604371224-316187997-3786583170-1043257646")
print(f'sid ', sid.value, f' cap_group_sids @ ', cap_group_sids)
param_flags = (1, "sid", sid), (1, "CapabilityGroupSids", cap_group_sids), (1, "CapabilityGroupSidCount", cap_group_sids), \
(1, "CapabilitySids", cap_group_sids), (1, "CapabilitySidCount", cap_group_sids)
print(f'param_flags: {param_flags}')
RtlDeriveCapabilitySidsFromName = prototype(("RtlDeriveCapabilitySidsFromName", windll.ntdll), param_flags)
try:
RtlDeriveCapabilitySidsFromName(sid=sid, CapabilityGroupSids=cap_group_sids, CapabilityGroupSidCount=cap_group_sids,
CapabilitySids=cap_group_sids, CapabilitySidCount=cap_group_sids)
print(f'cap {cap_group_sids}')
except Exception as e:
print(f"Error: {WinError()} RtlDeriveCapabilitySidsFromName exception: ", e)
Output:
C:\ProgramData\Anaconda3\envs\first-py\python.exe E:/projects/first-py/py-sec-tools/sid.py
sid S-1-15-3-1024-3424233489-972189580-2057154623-747635277-1604371224-316187997-3786583170-1043257646 cap_group_sids @ <ctypes.c_char_Array_1024 object at 0x0000020A2B824140>
param_flags: ((1, 'sid', <ctypes.c_wchar_Array_99 object at 0x0000020A2E24FF40>), (1, 'CapabilityGroupSids', <ctypes.c_char_Array_1024 object at 0x0000020A2B824140>), (1, 'CapabilityGroupSidCount', <ctypes.c_char_Array_1024 object at 0x0000020A2B824140>), (1, 'CapabilitySids', <ctypes.c_char_Array_1024 object at 0x0000020A2B824140>), (1, 'CapabilitySidCount', <ctypes.c_char_Array_1024 object at 0x0000020A2B824140>))
Error: [WinError 0] The operation completed successfully. RtlDeriveCapabilitySidsFromName exception: exception: access violation reading 0xFFFFFFFFFFFFFFFF
Process finished with exit code 0
CodePudding user response:
The Rtl function is undocumented and what I found online about it indicates it doesn't have the same function signature. I found and got DeriveCapabilitySidsFromName
to work as shown below. The documentation indicates it is in kernel32.dll
but it was not found there. I found it in kernelbase.dll
:
import ctypes as ct
from ctypes import wintypes as w
PSID = w.LPVOID
kb = ct.WinDLL('kernelbase') # documented as kernel32.dll but found in kernelbase.dll instead.
kb.DeriveCapabilitySidsFromName.argtypes = w.LPCWSTR, ct.POINTER(ct.POINTER(PSID)), ct.POINTER(w.DWORD), ct.POINTER(ct.POINTER(PSID)), ct.POINTER(w.DWORD)
kb.DeriveCapabilitySidsFromName.restype = w.BOOL
k32 = ct.WinDLL('kernel32')
k32.LocalFree.argtypes = w.HLOCAL,
k32.LocalFree.restype = w.HLOCAL
cap_name = ct.create_unicode_buffer('S-1-15-3-1024-3424233489-972189580-2057154623-747635277-1604371224-316187997-3786583170-1043257646')
cap_group_sids = ct.POINTER(PSID)()
cap_group_sid_count = w.DWORD()
cap_sids = ct.POINTER(PSID)()
cap_sid_count = w.DWORD()
result = kb.DeriveCapabilitySidsFromName(cap_name, ct.byref(cap_group_sids), ct.byref(cap_group_sid_count),
ct.byref(cap_sids), ct.byref(cap_sid_count))
if result:
print(cap_group_sid_count.value)
print(cap_group_sids[:cap_group_sid_count.value])
print(cap_sid_count.value)
print(cap_sids[:cap_sid_count.value])
# These all print 'None' if free succeeds.
for h in cap_group_sids[:cap_group_sid_count.value]:
print(k32.LocalFree(h))
for h in cap_sids[:cap_sid_count.value]:
print(k32.LocalFree(h))
print(k32.LocalFree(cap_group_sids))
print(k32.LocalFree(cap_sids))
Output:
1
[2568639690416]
1
[2568639690480]
None
None
None
None