Improving volume objects + adding CurrentProcess.peb.apisetmap with ApiSetMap parsing capabilities

This commit is contained in:
hakril
2017-12-04 10:12:41 +01:00
parent 8f7adb8da1
commit 23837a0713
11 changed files with 3355 additions and 12 deletions
@@ -0,0 +1,108 @@
// API SET MAP Stuff
// From apiset.h
// Used in V6
typedef struct _API_SET_VALUE_ENTRY {
ULONG Flags;
ULONG NameOffset;
ULONG NameLength;
ULONG ValueOffset;
ULONG ValueLength;
} API_SET_VALUE_ENTRY, *PAPI_SET_VALUE_ENTRY;
typedef struct _API_SET_NAMESPACE_ENTRY {
ULONG Flags;
ULONG NameOffset;
ULONG NameLength;
ULONG AliasOffset;
ULONG AliasLength;
ULONG DataOffset; // API_SET_VALUE_ARRAY
} API_SET_NAMESPACE_ENTRY, *PAPI_SET_NAMESPACE_ENTRY;
typedef struct _API_SET_NAMESPACE_ARRAY {
ULONG Version;
ULONG Size;
ULONG Flags;
ULONG Count;
API_SET_NAMESPACE_ENTRY Array[ANYSIZE_ARRAY];
} API_SET_NAMESPACE_ARRAY, *PAPI_SET_NAMESPACE_ARRAY;
// Version 2
typedef struct _API_SET_VALUE_ENTRY_V2 {
ULONG NameOffset;
ULONG NameLength;
ULONG ValueOffset;
ULONG ValueLength;
} API_SET_VALUE_ENTRY_V2, *PAPI_SET_VALUE_ENTRY_V2;
typedef struct _API_SET_VALUE_ARRAY_V2 {
ULONG Count;
API_SET_VALUE_ENTRY_V2 Array[ANYSIZE_ARRAY];
} API_SET_VALUE_ARRAY_V2,*PAPI_SET_VALUE_ARRAY_V2;
typedef struct _API_SET_NAMESPACE_ENTRY_V2 {
ULONG NameOffset;
ULONG NameLength;
ULONG DataOffset; // _API_SET_VALUE_ARRAY_V2
} API_SET_NAMESPACE_ENTRY_V2, *PAPI_SET_NAMESPACE_ENTRY_V2;
typedef struct _API_SET_NAMESPACE_ARRAY_V2 {
ULONG Version;
ULONG Count;
API_SET_NAMESPACE_ENTRY_V2 Array[ANYSIZE_ARRAY];
} API_SET_NAMESPACE_ARRAY_V2, *PAPI_SET_NAMESPACE_ARRAY_V2;
// Version 4
typedef struct _API_SET_VALUE_ARRAY_V4 {
ULONG GuessFlags;
ULONG Count;
API_SET_VALUE_ENTRY_V2 Array[ANYSIZE_ARRAY];
} API_SET_VALUE_ARRAY_V4,*PAPI_SET_VALUE_ARRAY_V2;
typedef struct _API_SET_NAMESPACE_ARRAY_V4 {
ULONG Version;
ULONG Size;
ULONG Flags;
ULONG Count;
API_SET_NAMESPACE_ENTRY Array[ANYSIZE_ARRAY];
} API_SET_NAMESPACE_ARRAY_V4, *PAPI_SET_NAMESPACE_ARRAY_V4;
typedef struct _API_SET_NAMESPACE_ENTRY_V4 {
ULONG Flags;
ULONG NameOffset;
ULONG NameLength;
ULONG AliasOffset;
ULONG AliasLength;
ULONG DataOffset;
} API_SET_NAMESPACE_ENTRY_V4, *PAPI_SET_NAMESPACE_ENTRY_V4;
// Version 6
typedef struct _API_SET_NAMESPACE_ENTRY_V6 {
ULONG Flags;
ULONG NameOffset;
ULONG NameLength;
ULONG HashedLength;
ULONG ValueOffset;
ULONG ValueCount;
} API_SET_NAMESPACE_ENTRY_V6;
typedef struct _API_SET_NAMESPACE_V6 {
ULONG Version;
ULONG Size;
ULONG Flags;
ULONG Count;
ULONG EntryOffset;
ULONG HashOffset;
ULONG HashFactor;
} API_SET_NAMESPACE_V6;
// STOP API-SET-MAP
@@ -0,0 +1,166 @@
typedef enum _FILE_INFORMATION_CLASS {
FakeFileInformationZero,
FileDirectoryInformation,
FileFullDirectoryInformation,
FileBothDirectoryInformation,
FileBasicInformation,
FileStandardInformation,
FileInternalInformation,
FileEaInformation,
FileAccessInformation,
FileNameInformation,
FileRenameInformation,
FileLinkInformation,
FileNamesInformation,
FileDispositionInformation,
FilePositionInformation,
FileFullEaInformation,
FileModeInformation,
FileAlignmentInformation,
FileAllInformation,
FileAllocationInformation,
FileEndOfFileInformation,
FileAlternateNameInformation,
FileStreamInformation,
FilePipeInformation,
FilePipeLocalInformation,
FilePipeRemoteInformation,
FileMailslotQueryInformation,
FileMailslotSetInformation,
FileCompressionInformation,
FileObjectIdInformation,
FileCompletionInformation,
FileMoveClusterInformation,
FileQuotaInformation,
FileReparsePointInformation,
FileNetworkOpenInformation,
FileAttributeTagInformation,
FileTrackingInformation,
FileIdBothDirectoryInformation,
FileIdFullDirectoryInformation,
FileValidDataLengthInformation,
FileShortNameInformation,
FileIoCompletionNotificationInformation,
FileIoStatusBlockRangeInformation,
FileIoPriorityHintInformation,
FileSfioReserveInformation,
FileSfioVolumeInformation,
FileHardLinkInformation,
FileProcessIdsUsingFileInformation,
FileNormalizedNameInformation,
FileNetworkPhysicalNameInformation,
FileIdGlobalTxDirectoryInformation,
FileIsRemoteDeviceInformation,
FileUnusedInformation,
FileNumaNodeInformation,
FileStandardLinkInformation,
FileRemoteProtocolInformation,
FileRenameInformationBypassAccessCheck,
FileLinkInformationBypassAccessCheck,
FileVolumeNameInformation,
FileIdInformation,
FileIdExtdDirectoryInformation,
FileReplaceCompletionInformation,
FileHardLinkFullIdInformation,
FileIdExtdBothDirectoryInformation,
FileDispositionInformationEx,
FileRenameInformationEx,
FileRenameInformationExBypassAccessCheck,
FileMaximumInformation
} FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS;
typedef enum _IO_PRIORITY_HINT {
IoPriorityVeryLow = 0,
IoPriorityLow = 1,
IoPriorityNormal = 2,
IoPriorityHigh = 3,
IoPriorityCritical = 4,
MaxIoPriorityTypes = 5
} IO_PRIORITY_HINT;
typedef struct _FILE_INTERNAL_INFORMATION {
LARGE_INTEGER IndexNumber;
} FILE_INTERNAL_INFORMATION, *PFILE_INTERNAL_INFORMATION;
typedef struct _FILE_ALIGNMENT_INFORMATION {
ULONG AlignmentRequirement;
} FILE_ALIGNMENT_INFORMATION, *PFILE_ALIGNMENT_INFORMATION;
typedef struct _FILE_ATTRIBUTE_TAG_INFORMATION {
ULONG FileAttributes;
ULONG ReparseTag;
} FILE_ATTRIBUTE_TAG_INFORMATION, *PFILE_ATTRIBUTE_TAG_INFORMATION;
typedef struct _FILE_BASIC_INFORMATION {
LARGE_INTEGER CreationTime;
LARGE_INTEGER LastAccessTime;
LARGE_INTEGER LastWriteTime;
LARGE_INTEGER ChangeTime;
ULONG FileAttributes;
} FILE_BASIC_INFORMATION, *PFILE_BASIC_INFORMATION;
typedef struct _FILE_EA_INFORMATION {
ULONG EaSize;
} FILE_EA_INFORMATION, *PFILE_EA_INFORMATION;
typedef struct _FILE_IO_PRIORITY_HINT_INFORMATION {
IO_PRIORITY_HINT PriorityHint;
} FILE_IO_PRIORITY_HINT_INFORMATION, *PFILE_IO_PRIORITY_HINT_INFORMATION;
typedef struct _FILE_MODE_INFORMATION {
ULONG Mode;
} FILE_MODE_INFORMATION, *PFILE_MODE_INFORMATION;
typedef struct _FILE_NAME_INFORMATION {
ULONG FileNameLength;
WCHAR FileName[1];
} FILE_NAME_INFORMATION, *PFILE_NAME_INFORMATION;
typedef struct _FILE_NETWORK_OPEN_INFORMATION {
LARGE_INTEGER CreationTime;
LARGE_INTEGER LastAccessTime;
LARGE_INTEGER LastWriteTime;
LARGE_INTEGER ChangeTime;
LARGE_INTEGER AllocationSize;
LARGE_INTEGER EndOfFile;
ULONG FileAttributes;
} FILE_NETWORK_OPEN_INFORMATION, *PFILE_NETWORK_OPEN_INFORMATION;
typedef struct _FILE_STANDARD_INFORMATION {
LARGE_INTEGER AllocationSize;
LARGE_INTEGER EndOfFile;
ULONG NumberOfLinks;
BOOLEAN DeletePending;
BOOLEAN Directory;
} FILE_STANDARD_INFORMATION, *PFILE_STANDARD_INFORMATION;
typedef struct _FILE_ACCESS_INFORMATION {
ACCESS_MASK AccessFlags;
} FILE_ACCESS_INFORMATION, *PFILE_ACCESS_INFORMATION;
typedef struct _FILE_POSITION_INFORMATION {
LARGE_INTEGER CurrentByteOffset;
} FILE_POSITION_INFORMATION, *PFILE_POSITION_INFORMATION;
typedef struct _FILE_IS_REMOTE_DEVICE_INFORMATION {
BOOLEAN IsRemote;
} FILE_IS_REMOTE_DEVICE_INFORMATION, *PFILE_IS_REMOTE_DEVICE_INFORMATION;
typedef struct _FILE_ALL_INFORMATION {
FILE_BASIC_INFORMATION BasicInformation;
FILE_STANDARD_INFORMATION StandardInformation;
FILE_INTERNAL_INFORMATION InternalInformation;
FILE_EA_INFORMATION EaInformation;
FILE_ACCESS_INFORMATION AccessInformation;
FILE_POSITION_INFORMATION PositionInformation;
FILE_MODE_INFORMATION ModeInformation;
FILE_ALIGNMENT_INFORMATION AlignmentInformation;
FILE_NAME_INFORMATION NameInformation;
} FILE_ALL_INFORMATION, *PFILE_ALL_INFORMATION;
+23
View File
@@ -0,0 +1,23 @@
import argparse
import windows
def read_apisetmap():
cp = windows.current_process
apisetmap_addr = cp.peb.ApiSetMap
print("ApiSetMap address <{0:#x}>".format(apisetmap_addr))
apisetmap_version = cp.read_dword(apisetmap_addr)
print("ApiSetMap version <{0}>".format(apisetmap_version))
meminfo = cp.query_memory(apisetmap_addr)
print(meminfo)
data = cp.read_memory(meminfo.BaseAddress, meminfo.RegionSize)
return data
parser = argparse.ArgumentParser(prog=__file__)
parser.add_argument('filename', default="apisetmap.dmp", help='The filename in which the ApiSetMap is dumped')
res = parser.parse_args()
with open(res.filename, "wb") as f:
f.write(read_apisetmap().encode("base64"))
print("<{0}> generated".format(res.filename))
File diff suppressed because it is too large Load Diff
+48
View File
@@ -0,0 +1,48 @@
import pytest
import windows
import windows.remotectypes as rctypes
from pfwtest import *
def assert_struct_offset(struct, field, offset):
assert getattr(struct, field).offset == offset
if windows.current_process.bitness == 32:
PEB32 = windows.generated_def.PEB
PEB64 = rctypes.transform_type_to_remote64bits(windows.generated_def.PEB)
else:
PEB32 = rctypes.transform_type_to_remote32bits(windows.generated_def.PEB)
PEB64 = windows.generated_def.PEB
def test_peb32_fields():
assert_peb_offset = lambda field, offset: assert_struct_offset(PEB32, field, offset)
assert_peb_offset("BeingDebugged", 2)
assert_peb_offset("ImageBaseAddress", 0x8)
assert_peb_offset("Ldr", 0xc)
assert_peb_offset("ProcessParameters", 0x10)
assert_peb_offset("KernelCallbackTable", 0x2c)
assert_peb_offset("UserSharedInfoPtr", 0x2c)
assert_peb_offset("ApiSetMap", 0x38)
assert_peb_offset("NumberOfProcessors", 0x64)
assert_peb_offset("GdiHandleBuffer", 0xc4)
assert_peb_offset("PostProcessInitRoutine", 0x14c) # Field just after 'GdiHandleBuffer' allow to also check the 'GdiHandleBuffer' size hack
assert_peb_offset("SessionId", 0x1d4)
assert_peb_offset("CSDVersion", 0x01F0)
assert_peb_offset("MinimumStackCommit", 0x0208)
def test_peb64_fields():
assert_peb_offset = lambda field, offset: assert_struct_offset(PEB64, field, offset)
assert_peb_offset("BeingDebugged", 2)
assert_peb_offset("ImageBaseAddress", 0x10)
assert_peb_offset("Ldr", 0x18)
assert_peb_offset("ProcessParameters", 0x20)
assert_peb_offset("KernelCallbackTable", 0x58)
assert_peb_offset("UserSharedInfoPtr", 0x58)
assert_peb_offset("ApiSetMap", 0x68)
assert_peb_offset("NumberOfProcessors", 0xb8)
assert_peb_offset("GdiHandleBuffer", 0x140)
assert_peb_offset("PostProcessInitRoutine", 0x230) # Field just after 'GdiHandleBuffer' allow to also check the 'GdiHandleBuffer' size hack
assert_peb_offset("SessionId", 0x2c0)
assert_peb_offset("CSDVersion", 0x02E8)
assert_peb_offset("MinimumStackCommit", 0x0318)
+2 -4
View File
@@ -356,8 +356,7 @@ class AlpcClient(AlpcTransportBase):
x = self.connect_to_port(port_name, "")
def _alpc_port_to_unicode_string(self, name):
utf16_len = len(name) * 2
return gdef.UNICODE_STRING(utf16_len, utf16_len, ctypes.cast(gdef.PWSTR(name), gdef.PVOID))
return gdef.UNICODE_STRING.from_string(name)
def connect_to_port(self, port_name, connect_message=None,
port_attr=None, port_attr_flags=0x10000, obj_attr=None,
@@ -452,8 +451,7 @@ class AlpcServer(AlpcTransportBase):
self.create_port(port_name)
def _alpc_port_to_unicode_string(self, name):
utf16_len = len(name) * 2
return gdef.UNICODE_STRING(utf16_len, utf16_len, ctypes.cast(gdef.PWSTR(name), gdef.PVOID))
return gdef.UNICODE_STRING.from_string(name)
def create_port(self, port_name, msglen=None, port_attr_flags=0, obj_attr=None, port_attr=None):
"""Create the ALPC port ``port_name``. Most of the parameters have defauls value is ``None`` is passed.
+5
View File
@@ -346,6 +346,11 @@ def get_short_path(path):
rsize = winproxy.GetShortPathNameA(path, buffer, size)
return buffer[:rsize]
def dospath_to_ntpath(dospath):
ustring = gdef.UNICODE_STRING()
windows.winproxy.RtlDosPathNameToNtPathName_U(dospath, ustring, None, None)
return ustring.str
def get_shared_mapping(name, size=0x1000):
# TODO: real code
+128
View File
@@ -0,0 +1,128 @@
import windows
import windows.generated_def as gdef
from windows import utils
def get_api_set_map_for_current_process(base):
base = windows.current_process.peb.ApiSetMap
version = windows.current_process.read_dword(base)
if version not in API_SET_MAP_BY_VERSION:
raise NotImplementedError("ApiSetMap version <{0}> not implemented, please contact me, I need a sample to implem it ;)")
return API_SET_MAP_BY_VERSION[version](base)
class ApiSetMap(object):
def __init__(self, base):
self.base = base
self.target = windows.current_process
# helpers
def read_apiset_wstring(self, offset, length):
return self.target.read_memory(self.base + offset, length).decode("utf-16")
# Low-level version-dependent parsing function
def entries_array(self):
raise NotImplementedError("Should be implemented by subclasses")
def get_entry_name(self, entry):
raise NotImplementedError("Should be implemented by subclasses")
def get_entry_name_basicimpl(self, entry):
return self.read_apiset_wstring(entry.NameOffset, entry.NameLength)
def values_for_entry(self, entry):
raise NotImplementedError("Should be implemented by subclasses")
@utils.fixedpropety
def resolution_dict(self):
res = {}
for entry in self.entries_array():
values = self.values_for_entry(entry)
if not values:
final_value = None
else:
final_value = values[-1]
res[self.get_entry_name(entry)] = final_value
return res
def resolve(self, dllname):
return self.resolution_dict[dllname]
class ApiSetMapVersion2(ApiSetMap):
def namespace(self):
return gdef.API_SET_NAMESPACE_ARRAY_V2.from_address(self.base)
def entries_array(self):
namespace = self.namespace()
array_addr = ctypes.addressof(namespace.Array)
array_size = namespace.Count
return (gdef.API_SET_NAMESPACE_ENTRY_V2 * array_size).from_address(array_addr)
get_entry_name = ApiSetMap.get_entry_name_basicimpl
def values_for_entry(self, entry):
values_array_v2 = (gdef.API_SET_VALUE_ARRAY_V2).from_address(self.base + entry.DataOffset)
array_size = values_array_v2.Count
array_addr = ctypes.addressof(values_array_v2.Array)
values_array = (gdef.API_SET_VALUE_ENTRY_V2 * array_size).from_address(array_addr)
res = []
for value in values_array:
if value.ValueLength:
v = self.read_apiset_wstring(value.ValueOffset, value.ValueLength)
res.append(v)
return res
class ApiSetMapVersion4(ApiSetMap):
def namespace(self):
return gdef.API_SET_NAMESPACE_ARRAY_V4.from_address(self.base)
def entries_array(self):
namespace = self.namespace()
array_addr = ctypes.addressof(namespace.Array)
array_size = namespace.Count
return (gdef.API_SET_NAMESPACE_ENTRY_V4 * array_size).from_address(array_addr)
get_entry_name = ApiSetMap.get_entry_name_basicimpl
def values_for_entry(self, entry):
values_array_v2 = (gdef.API_SET_VALUE_ARRAY_V4).from_address(self.base + entry.DataOffset)
array_size = values_array_v2.Count
array_addr = ctypes.addressof(values_array_v2.Array)
values_array = (gdef.API_SET_VALUE_ENTRY * array_size).from_address(array_addr)
res = []
for value in values_array:
if value.ValueLength:
v = self.read_apiset_wstring(value.ValueOffset, value.ValueLength)
res.append(v)
return res
class ApiSetMapVersion6(ApiSetMap):
def namespace(self):
return gdef.API_SET_NAMESPACE_V6.from_address(self.base)
get_entry_name = ApiSetMap.get_entry_name_basicimpl
def entries_array(self):
namespace = self.namespace()
array_offset = namespace.EntryOffset
array_size = namespace.Count
return (gdef.API_SET_NAMESPACE_ENTRY_V6 * array_size).from_address(self.base + array_offset)
def values_for_entry(self, entry):
values_array = (gdef.API_SET_VALUE_ENTRY * entry.ValueCount).from_address(self.base + entry.ValueOffset)
res = []
for value in values_array:
if value.ValueLength:
v = self.read_apiset_wstring(value.ValueOffset, value.ValueLength)
res.append(v)
return res
API_SET_MAP_BY_VERSION = {
2: ApiSetMapVersion2,
4: ApiSetMapVersion4,
6: ApiSetMapVersion6,
}
+57 -3
View File
@@ -25,6 +25,7 @@ from windows.generated_def.ntstatus import NtStatusException
from windows.winobject import exception
from windows.winobject import sid
from windows.winobject import apisetmap
TimeInfo = namedtuple("TimeInfo", ["creation", "exit", "kernel", "user"])
@@ -62,9 +63,8 @@ class AutoHandle(object):
def __del__(self):
# sys.path is not None -> check if python shutdown
if sys.path is not None and hasattr(self, "_handle") and self._handle:
if hasattr(sys, "path") and sys.path is not None and hasattr(self, "_handle") and self._handle:
# Prevent some bug where dbgprint might be None when __del__ is called in a closing process
# for i in vars(sys).items(): print(i)
dbgprint("Closing Handle {0} for {1}".format(hex(self._handle), self), "HANDLE") if dbgprint is not None else None
self._close_function(self._handle)
@@ -690,6 +690,13 @@ class Process(AutoHandle):
PROCESS_MODE_BACKGROUND_END,
REALTIME_PRIORITY_CLASS)
def query_info(self, information_class, data=None):
winproxy.NtQueryInformationProcess(self.handle, information_class, byref(data), sizeof(data))
return data
def set_info(self, information_class, data):
winproxy.NtSetInformationProcess(self.handle, information_class, byref(data), sizeof(data))
def get_priority(self):
return self.PRIORITY_CLASS_MAPPER[winproxy.GetPriorityClass(self.handle)]
@@ -1324,6 +1331,28 @@ class PEB(gdef.PEB):
current_dll = list_entry_ptr.TO_LDR_ENTRY()
return [LoadedModule.from_address(addressof(LDR)) for LDR in res]
@staticmethod
def _extract_environment(env_block_addr, target):
result = []
while True:
venv = target.read_wstring(env_block_addr)
if not venv:
return result
result.append(venv)
env_block_addr += ((len(venv) + 1) * 2)
# raise RuntimeError("Out of infinite loop")
@property
def environment(self):
# TODO: Tests
return self._extract_environment(self.ProcessParameters.contents.Environment, windows.current_process)
@property
def apisetmap(self):
if windows.system.version < (6,2):
raise NotImplementedError("ApiSetMap does not exist prior to Windows 7")
return apisetmap.get_api_set_map_for_current_process(self.ApiSetMap)
# Memory stuff
@@ -1426,6 +1455,17 @@ class RemotePEB(rctypes.RemoteStructure.from_structure(PEB)):
current_dll = self.ptr_flink_to_remote_module(list_entry_ptr)
return res
@property
def environment(self):
# TODO: Tests
return self._extract_environment(self.ProcessParameters.contents.Environment, self._target)
@property
def apisetmap(self):
raise NotImplementedError("ApiSetMap for remote process not implemented yet")
if CurrentProcess().bitness == 32:
class RemoteLoadedModule64(rctypes.transform_type_to_remote64bits(LoadedModule)):
@@ -1468,6 +1508,13 @@ if CurrentProcess().bitness == 32:
current_dll = self.ptr_flink_to_remote_module(list_entry_ptr)
return res
@property
def environment(self):
# TODO: Tests
return self._extract_environment(self.ProcessParameters.contents.Environment, self._target)
apisetmap = RemotePEB.apisetmap
if CurrentProcess().bitness == 64:
class RemoteLoadedModule32(rctypes.transform_type_to_remote32bits(LoadedModule)):
@@ -1507,4 +1554,11 @@ if CurrentProcess().bitness == 64:
res.append(current_dll)
list_entry_ptr = current_dll.InMemoryOrderLinks.Flink.raw_value
current_dll = self.ptr_flink_to_remote_module(list_entry_ptr)
return res
return res
@property
def environment(self):
# TODO: Tests
return self._extract_environment(self.ProcessParameters.contents.Environment, self._target)
apisetmap = RemotePEB.apisetmap
+21 -5
View File
@@ -5,10 +5,12 @@ from windows import winproxy
import windows.generated_def as gdef
from windows.generated_def.winstructs import *
from .process import AutoHandle
import sys
class LogicalDrive(object):
class LogicalDrive(AutoHandle):
DRIVE_TYPE = gdef.FlagMapper(DRIVE_UNKNOWN, DRIVE_NO_ROOT_DIR, DRIVE_REMOVABLE,
DRIVE_FIXED, DRIVE_REMOTE, DRIVE_CDROM, DRIVE_RAMDISK)
@@ -42,12 +44,26 @@ class LogicalDrive(object):
raise ValueError("[Unexpected result] query_dos_device(logicaldrive) returned multiple path")
return res[0]
def query_info(self, info):
return windows.utils.query_volume_information(self.handle, info)
@property
def volume_info(self):
return self.query_info(gdef.FileFsVolumeInformation)
@property
def serial(self):
return self.volume_info.VolumeSerialNumber
def _get_handle(self):
nt_name = windows.utils.dospath_to_ntpath(self.name)
handle = windows.winproxy.CreateFileA(nt_name, gdef.GENERIC_READ,
gdef.FILE_SHARE_READ, None, gdef.OPEN_EXISTING, gdef.FILE_FLAG_BACKUP_SEMANTICS , None)
return handle
def __repr__(self):
return """<{0} "{1}" ({2})>""".format(type(self).__name__, self.name, self.type.name)
def enum_logical_drive():
return [LogicalDrive(name) for name in get_logical_drive_names()]
@@ -63,7 +79,7 @@ def get_info(drivename):
fs_name = ctypes.c_buffer(size)
flags = DWORD()
winproxy.GetVolumeInformationA(drivename, volume_name, size, None, None, ctypes.byref(flags), fs_name, size)
raise NotImplementedError("get_info")
return volume_name[:10], fs_name[:10]
def query_dos_device(name):
size = 0x1000
+15
View File
@@ -841,6 +841,12 @@ def NtQueryInformationProcess(ProcessHandle, ProcessInformationClass, ProcessInf
return NtQueryInformationProcess.ctypes_function(ProcessHandle, ProcessInformationClass, ProcessInformation, ProcessInformationLength, ReturnLength)
@NtdllProxy('NtSetInformationProcess', error_ntstatus)
def NtSetInformationProcess(ProcessHandle, ProcessInformationClass, ProcessInformation, ProcessInformationLength=0):
if not ProcessInformationLength:
ProcessInformationLength = ctypes.sizeof(ProcessInformation)
return NtSetInformationProcess.ctypes_function(ProcessHandle, ProcessInformationClass, ProcessInformation, ProcessInformationLength)
@NtdllProxy('NtQueryInformationThread', error_ntstatus)
def NtQueryInformationThread(ThreadHandle, ThreadInformationClass, ThreadInformation, ThreadInformationLength=0, ReturnLength=None):
if ReturnLength is None:
@@ -1013,6 +1019,10 @@ def RtlGetCompressionWorkSpaceSize(CompressionFormatAndEngine, CompressBufferWor
return RtlGetCompressionWorkSpaceSize.ctypes_function(CompressionFormatAndEngine, CompressBufferWorkSpaceSize, CompressFragmentWorkSpaceSize)
@NtdllProxy("RtlDosPathNameToNtPathName_U", zero_is_fail_error_check)
def RtlDosPathNameToNtPathName_U(DosName, NtName=None, PartName=None, RelativeName=None):
return RtlDosPathNameToNtPathName_U.ctypes_function(DosName, NtName, PartName, RelativeName)
# Section stuff
@@ -1045,6 +1055,11 @@ def RtlGetUnloadEventTraceEx(ElementSize, ElementCount, EventTrace):
def TpCallbackSendAlpcMessageOnCompletion(TpHandle, PortHandle, Flags, SendMessage):
return TpCallbackSendAlpcMessageOnCompletion.ctypes_function(TpHandle, PortHandle, Flags, SendMessage)
# Not exported
# @NtdllProxy("ApiSetResolveToHost")
# def ApiSetResolveToHost(Schema, FileNameIn, ParentName, Resolved, HostBinary):
# return ApiSetResolveToHost.ctypes_function(Schema, FileNameIn, ParentName, Resolved, HostBinary)
# ##### ADVAPI32 ####### #