fix ImprovedVariant.asbool + com.create_instance accept a context parameter + fix RemoteWCharP.value logic + winutils.decompress_buffer

This commit is contained in:
Clement Rouault
2017-04-04 10:10:21 +02:00
parent a107656402
commit 5431b57560
4 changed files with 84 additions and 5 deletions
+2 -2
View File
@@ -126,10 +126,10 @@ class ImprovedVariant(VARIANT):
def create_instance(clsiid, targetinterface, custom_iid=None):
def create_instance(clsiid, targetinterface, custom_iid=None, context=CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER):
if custom_iid is None:
custom_iid = targetinterface.IID
return winproxy.CoCreateInstance(byref(clsiid), None, CLSCTX_INPROC_SERVER, byref(custom_iid), byref(targetinterface))
return winproxy.CoCreateInstance(byref(clsiid), None, context, byref(custom_iid), byref(targetinterface))
class ComVtable(object):
+21 -3
View File
@@ -106,9 +106,27 @@ class RemoteWCharP(RemotePtr, ctypes.c_char_p):
@property
def value(self):
base = self.raw_value
res = []
for i in itertools.count():
x = self.target.read_memory(base + (i * 0x100), 0x100)
# Simple case where target in a WinProcess
try:
return self.target.read_wstring(base)
except AttributeError as e:
pass
# Copy of Winprocess.read_wstring if target is a custom object
read_size = 0x100
readden = 0
# I am trying to do something smart here..
while True:
try:
x = self.read_memory(addr + readden, read_size)
except winproxy.Kernel32Error as e:
if read_size == 2:
raise
# handle read_wstring at end of page
# Of read failed: read only the half of size
# read_size must remain a multiple of 2
read_size = read_size / 2
continue
readden += read_size
utf16_chars = ["".join(c) for c in zip(*[iter(x)] * 2)]
if "\x00\x00" in utf16_chars:
res.extend(utf16_chars[:utf16_chars.index("\x00\x00")])
+8
View File
@@ -223,6 +223,14 @@ def get_shared_mapping(name, size=0x1000):
# addr = windows.winproxy.MapViewOfFile(h, dwDesiredAccess=FILE_MAP_READ, dwNumberOfBytesToMap=1)
# return addr
def decompress_buffer(comptype, buffer, uncompress_size=None):
if uncompress_size is None:
uncompress_size = len(buffer) * 10
result_size = DWORD()
uncompressed = ctypes.c_buffer(uncompress_size)
windows.winproxy.RtlDecompressBuffer(comptype, uncompressed, uncompress_size, buffer, len(buffer), result_size)
return uncompressed[:result_size.value]
class VirtualProtected(object):
"""
A context manager usable like `VirtualProtect` that will restore the old protection at exit ::
+53
View File
@@ -192,6 +192,10 @@ class Crypt32Proxy(ApiProxy):
APIDLL = "crypt32"
default_error_check = staticmethod(zero_is_fail_error_check)
class Shell32Proxy(ApiProxy):
APIDLL = "shell32"
default_error_check = staticmethod(zero_is_fail_error_check)
#class OptionalExport(object):
# """used 'around' a Proxy decorator
# Should be used for export that are not available everywhere (ntdll internals | 32/64 bits stuff)
@@ -286,6 +290,7 @@ GetVersionExA = TransparentKernel32Proxy("GetVersionExA")
GetVersionExW = TransparentKernel32Proxy("GetVersionExW")
GetComputerNameA = TransparentKernel32Proxy("GetComputerNameA")
GetComputerNameW = TransparentKernel32Proxy("GetComputerNameW")
LocalFree = TransparentKernel32Proxy("LocalFree", should_return_zero_check)
@@ -823,6 +828,13 @@ def NtQuerySymbolicLinkObject(LinkHandle, LinkTarget, ReturnedLength):
def NtOpenSymbolicLinkObject(LinkHandle, DesiredAccess, ObjectAttributes):
return NtOpenSymbolicLinkObject.ctypes_function(LinkHandle, DesiredAccess, ObjectAttributes)
@NtdllProxy("RtlDecompressBuffer", error_ntstatus)
def RtlDecompressBuffer(CompressionFormat, UncompressedBuffer, UncompressedBufferSize, CompressedBuffer, CompressedBufferSize, FinalUncompressedSize):
return RtlDecompressBuffer.ctypes_function(CompressionFormat, UncompressedBuffer, UncompressedBufferSize, CompressedBuffer, CompressedBufferSize, FinalUncompressedSize)
# ##### ADVAPI32 ####### #
@Advapi32Proxy('OpenProcessToken')
@@ -833,6 +845,10 @@ def OpenProcessToken(ProcessHandle=None, DesiredAccess=NeededParameter, TokenHan
return OpenProcessToken.ctypes_function(ProcessHandle, DesiredAccess, TokenHandle)
@Advapi32Proxy('OpenThreadToken')
def OpenThreadToken(ThreadHandle, DesiredAccess, OpenAsSelf, TokenHandle):
return OpenThreadToken.ctypes_function(ThreadHandle, DesiredAccess, OpenAsSelf, TokenHandle)
@Advapi32Proxy('LookupPrivilegeValueA')
def LookupPrivilegeValueA(lpSystemName=None, lpName=NeededParameter, lpLuid=NeededParameter):
return LookupPrivilegeValueA.ctypes_function(lpSystemName, lpName, lpLuid)
@@ -871,6 +887,10 @@ def GetTokenInformation(TokenHandle=NeededParameter, TokenInformationClass=Neede
return GetTokenInformation.ctypes_function(TokenHandle, TokenInformationClass, TokenInformation, TokenInformationLength, ReturnLength)
@Advapi32Proxy('SetTokenInformation')
def SetTokenInformation(TokenHandle, TokenInformationClass, TokenInformation, TokenInformationLength):
return SetTokenInformation.ctypes_function(TokenHandle, TokenInformationClass, TokenInformation, TokenInformationLength)
@Advapi32Proxy('RegOpenKeyExA', should_return_zero_check)
def RegOpenKeyExA(hKey, lpSubKey, ulOptions, samDesired, phkResult):
return RegOpenKeyExA.ctypes_function(hKey, lpSubKey, ulOptions, samDesired, phkResult)
@@ -892,6 +912,24 @@ def GetSecurityInfo(handle, ObjectType, SecurityInfo, ppsidOwner=None, ppsidGrou
return GetSecurityInfo.ctypes_function(handle, ObjectType, SecurityInfo, ppsidOwner, ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor)
# Sid stuff
@Advapi32Proxy('ConvertStringSidToSidA')
def ConvertStringSidToSidA(StringSid, Sid):
return ConvertStringSidToSidA.ctypes_function(StringSid, Sid)
@Advapi32Proxy('ConvertStringSidToSidW')
def ConvertStringSidToSidW(StringSid, Sid):
return ConvertStringSidToSidW.ctypes_function(StringSid, Sid)
@Advapi32Proxy('ConvertSidToStringSidA')
def ConvertSidToStringSidA(Sid, StringSid):
return ConvertSidToStringSidA.ctypes_function(Sid, StringSid)
@Advapi32Proxy('ConvertSidToStringSidW')
def ConvertSidToStringSidW(Sid, StringSid):
return ConvertSidToStringSidW.ctypes_function(Sid, StringSid)
# Registry stuff
# TODO: default values? which ones ?
@@ -910,6 +948,13 @@ def RegGetValueA(hkey, lpSubKey, lpValue, dwFlags, pdwType, pvData, pcbData):
def RegGetValueW(hkey, lpSubKey=None, lpValue=NeededParameter, dwFlags=0, pdwType=None, pvData=None, pcbData=None):
return RegGetValueW.ctypes_function(hkey, lpSubKey, lpValue, dwFlags, pdwType, pvData, pcbData)
@Advapi32Proxy('RegQueryValueExA', should_return_zero_check)
def RegQueryValueExA(hKey, lpValueName, lpReserved, lpType, lpData, lpcbData):
return RegQueryValueExA.ctypes_function(hKey, lpValueName, lpReserved, lpType, lpData, lpcbData)
@Advapi32Proxy('RegQueryValueExW', should_return_zero_check)
def RegQueryValueExW(hKey, lpValueName, lpReserved, lpType, lpData, lpcbData):
return RegQueryValueExA.ctypes_function(hKey, lpValueName, lpReserved, lpType, lpData, lpcbData)
@Advapi32Proxy('RegCloseKey', should_return_zero_check)
def RegCloseKey(hKey):
@@ -1239,4 +1284,12 @@ def CoInitializeSecurity(pSecDesc, cAuthSvc, asAuthSvc, pReserved1, dwAuthnLevel
def CoCreateInstance(rclsid, pUnkOuter=None, dwClsContext=CLSCTX_INPROC_SERVER, riid=NeededParameter, ppv=NeededParameter):
return CoCreateInstance.ctypes_function(rclsid, pUnkOuter, dwClsContext, riid, ppv)
# ## Shell32 ## #
@Shell32Proxy('ShellExecuteA')
def ShellExecuteA(hwnd, lpOperation, lpFile, lpParameters, lpDirectory, nShowCmd):
return ShellExecuteA.ctypes_function(hwnd, lpOperation, lpFile, lpParameters, lpDirectory, nShowCmd)
@Shell32Proxy('ShellExecuteW')
def ShellExecuteW(hwnd, lpOperation, lpFile, lpParameters, lpDirectory, nShowCmd):
return ShellExecuteW.ctypes_function(hwnd, lpOperation, lpFile, lpParameters, lpDirectory, nShowCmd)