mirror of
https://github.com/hakril/PythonForWindows
synced 2026-06-08 14:31:45 +00:00
Improve object manager doc + add samples
This commit is contained in:
@@ -6,7 +6,15 @@ Object Manager -- Kernel objects
|
||||
The :class:`ObjectManager` instance is accessible via :py:attr:`windows.system.object_manager
|
||||
<windows.winobject.system.System.object_manager>`
|
||||
|
||||
TODO: doc + sample
|
||||
|
||||
.. note::
|
||||
|
||||
See sample at :ref:`sample_object_manager`
|
||||
|
||||
|
||||
.. warning::
|
||||
|
||||
This API have not been tested on real case yet and may be subject to changes.
|
||||
|
||||
ObjectManager
|
||||
"""""""""""""
|
||||
@@ -24,4 +32,4 @@ KernelObject
|
||||
.. autoclass:: KernelObject
|
||||
:members:
|
||||
:undoc-members:
|
||||
:special-members: __getitem__
|
||||
:special-members: __getitem__, __iter__
|
||||
@@ -0,0 +1,23 @@
|
||||
(cmd) python object_manager\findobj.py
|
||||
Looking for object name containing <ls>
|
||||
* <KernelObject "\KnownDlls32" (type="Directory")>
|
||||
* <KernelObject "\Win32kCrossSessionGlobals" (type="Section")>
|
||||
* <KernelObject "\KnownDlls" (type="Directory")>
|
||||
<\DriverStores\SYSTEM> -> STATUS_ACCESS_DENIED
|
||||
* <KernelObject "\Device\MailslotRedirector" (type="SymbolicLink")> -> <\Device\Mup\;MailslotRedirector>
|
||||
* <KernelObject "\Device\Mailslot" (type="Device")>
|
||||
<\Device\00000020> -> STATUS_ACCESS_DENIED
|
||||
<\Device\00000020> -> STATUS_ACCESS_DENIED
|
||||
<\Device\00000020> -> STATUS_ACCESS_DENIED
|
||||
<\Device\00000020> -> STATUS_ACCESS_DENIED
|
||||
<\Device\00000020> -> STATUS_ACCESS_DENIED
|
||||
<\KernelObjects\PrefetchTracesReady> -> STATUS_ACCESS_DENIED
|
||||
<\KnownDlls\powrprof.dll> -> STATUS_ACCESS_DENIED
|
||||
* <KernelObject "\RPC Control\lsapolicylookup" (type="ALPC Port")>
|
||||
* <KernelObject "\RPC Control\lsacap" (type="ALPC Port")>
|
||||
* <KernelObject "\RPC Control\lsasspirpc" (type="ALPC Port")>
|
||||
<\Windows\SbApiPort> -> STATUS_ACCESS_DENIED
|
||||
<\Windows\SbApiPort> -> STATUS_ACCESS_DENIED
|
||||
<\Sessions\BNOLINKS\1> -> STATUS_ACCESS_DENIED
|
||||
<\Sessions\BNOLINKS\1> -> STATUS_ACCESS_DENIED
|
||||
<\Sessions\BNOLINKS\1> -> STATUS_ACCESS_DENIED
|
||||
@@ -0,0 +1,22 @@
|
||||
(cmd) python object_manager\object_manager.py
|
||||
Object manager is <windows.winobject.object_manager.ObjectManager object at 0x0370ED10>
|
||||
Root object is <KernelObject "\" (type="Directory")>
|
||||
|
||||
Listing some of root-subobject:
|
||||
* PendingRenameMutex: <KernelObject "\PendingRenameMutex" (type="Mutant")>
|
||||
* ObjectTypes: <KernelObject "\ObjectTypes" (type="Directory")>
|
||||
* storqosfltport: <KernelObject "\storqosfltport" (type="FilterConnectionPort")>
|
||||
* MicrosoftMalwareProtectionRemoteIoPortWD: <KernelObject "\MicrosoftMalwareProtectionRemoteIoPortWD" (type="FilterConnectionPort")>
|
||||
|
||||
Retrieving <\Rpc Control\lsasspirpc>:
|
||||
Object is: <KernelObject "\Rpc Control\lsasspirpc" (type="ALPC Port")>
|
||||
* name: <lsasspirpc>
|
||||
* path: <\Rpc Control>
|
||||
* fullname: <\Rpc Control\lsasspirpc>
|
||||
* type: <ALPC Port>
|
||||
* target: <None>
|
||||
|
||||
Looking for a SymbolicLink in <ArcName>
|
||||
Object is: <KernelObject "\ArcName\multi(0)disk(0)rdisk(0)" (type="SymbolicLink")>
|
||||
* name: <multi(0)disk(0)rdisk(0)>
|
||||
* target: <\Device\Harddisk0\Partition0>
|
||||
@@ -0,0 +1,35 @@
|
||||
import argparse
|
||||
|
||||
import windows
|
||||
import windows.generated_def as gdef
|
||||
|
||||
def obj_with_link(obj):
|
||||
target = obj.target
|
||||
if target is None:
|
||||
return str(obj)
|
||||
return "{0} -> <{1}>".format(obj, target)
|
||||
|
||||
|
||||
def find_name(root, findname):
|
||||
TODO = [root]
|
||||
while TODO:
|
||||
try:
|
||||
for name, obj in TODO.pop().items():
|
||||
if findname in name:
|
||||
print("* {0}".format(obj_with_link(obj)))
|
||||
if obj.type == "Directory":
|
||||
TODO.append(obj)
|
||||
except gdef.NtStatusException as e:
|
||||
print("<{0}> -> {1}".format(obj.fullname, e.name))
|
||||
|
||||
|
||||
|
||||
parser = argparse.ArgumentParser(prog=__file__)
|
||||
parser.add_argument('name', nargs='?', default="ls", help='The name of the object to find')
|
||||
res = parser.parse_args()
|
||||
|
||||
objmanag = windows.system.object_manager
|
||||
print("Looking for object name containing <{0}>".format(res.name))
|
||||
find_name(objmanag.root, res.name)
|
||||
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
import sys
|
||||
import os.path
|
||||
sys.path.append(os.path.abspath(__file__ + "\..\.."))
|
||||
|
||||
import windows
|
||||
import windows.generated_def as gdef
|
||||
|
||||
object_manager = windows.system.object_manager
|
||||
print("Object manager is {0}".format(object_manager))
|
||||
root = object_manager.root
|
||||
print("Root object is {0}".format(root))
|
||||
|
||||
print("")
|
||||
print("Listing some of root-subobject:")
|
||||
# Kernel object of type 'Directory' are iterable
|
||||
for i, (name, obj) in enumerate(root.items()):
|
||||
print(" * {0}: {1}".format(name, obj))
|
||||
if i == 3:
|
||||
break
|
||||
|
||||
print("")
|
||||
print(r"Retrieving <\Rpc Control\lsasspirpc>:")
|
||||
# You can retrieve this value in one request
|
||||
x1 = root[r"\Rpc Control\lsasspirpc"]
|
||||
# Sub-directory also allow __getitem__
|
||||
x2 = root["Rpc Control"]["lsasspirpc"]
|
||||
# You can directly request the object manager that will request `root`
|
||||
x3 = object_manager[r"\Rpc Control\lsasspirpc"]
|
||||
assert x1.fullname == x2.fullname == x3.fullname
|
||||
|
||||
lsasspirpc = x1
|
||||
print("Object is: {0}".format(lsasspirpc))
|
||||
print(" * name: <{0}>".format(lsasspirpc.name))
|
||||
print(" * path: <{0}>".format(lsasspirpc.path))
|
||||
print(" * fullname: <{0}>".format(lsasspirpc.fullname))
|
||||
print(" * type: <{0}>".format(lsasspirpc.type))
|
||||
print(" * target: <{0}>".format(lsasspirpc.target)) # None on non-symlink
|
||||
|
||||
print("")
|
||||
print("Looking for a SymbolicLink in <ArcName>")
|
||||
slo = [o for o in root["ArcName"].values() if o.type == "SymbolicLink"][0]
|
||||
print("Object is: {0}".format(slo))
|
||||
print(" * name: <{0}>".format(slo.name))
|
||||
print(" * target: <{0}>".format(slo.target))
|
||||
@@ -0,0 +1,22 @@
|
||||
import argparse
|
||||
|
||||
import windows
|
||||
import windows.generated_def as gdef
|
||||
|
||||
def obj_with_link(obj):
|
||||
target = obj.target
|
||||
if target is None:
|
||||
return str(obj)
|
||||
return "{0} -> <{1}>".format(obj, target)
|
||||
|
||||
def fulllistdir(dir, depth=0):
|
||||
for name, obj in dir.items():
|
||||
print("{0} * {1}".format(" " * depth, obj_with_link(obj)))
|
||||
if obj.type == "Directory":
|
||||
try:
|
||||
fulllistdir(obj, depth + 4)
|
||||
except gdef.NtStatusException as e:
|
||||
print("{0} * {1}".format(" " * (depth + 4), e))
|
||||
|
||||
|
||||
fulllistdir(windows.system.object_manager.root)
|
||||
@@ -4,11 +4,11 @@ from collections import namedtuple
|
||||
|
||||
import windows
|
||||
from windows import winproxy
|
||||
# from windows.generated_def.winstructs import *
|
||||
import windows.generated_def as gdef
|
||||
|
||||
|
||||
def query_link(linkpath):
|
||||
"""Resolve the link object with path ``linkpath``"""
|
||||
obj_attr = gdef.OBJECT_ATTRIBUTES()
|
||||
obj_attr.Length = ctypes.sizeof(obj_attr)
|
||||
obj_attr.RootDirectory = 0
|
||||
@@ -20,11 +20,12 @@ def query_link(linkpath):
|
||||
x = winproxy.NtOpenSymbolicLinkObject(res, gdef.DIRECTORY_QUERY | gdef.READ_CONTROL , obj_attr)
|
||||
v = gdef.LSA_UNICODE_STRING.from_string("\x00" * 1000)
|
||||
s = gdef.ULONG()
|
||||
winproxy.NtQuerySymbolicLinkObject(res, v, s)
|
||||
winproxy.NtQuerySymbolicLinkObject(res, v, s) # Handle Buffer-too-small ?
|
||||
return v.str
|
||||
|
||||
|
||||
class KernelObject(object):
|
||||
"""Represent an object in the Object Manager namespace"""
|
||||
def __init__(self, path, name, type):
|
||||
self.path = path
|
||||
self.name = name
|
||||
@@ -35,20 +36,55 @@ class KernelObject(object):
|
||||
|
||||
@property
|
||||
def target(self):
|
||||
"""Resolve the target of a symbolic link object.
|
||||
|
||||
:rtype: :class:`str` or None if object is not a link
|
||||
"""
|
||||
try:
|
||||
return query_link(self.fullname)
|
||||
except windows.generated_def.ntstatus.NtStatusException as e:
|
||||
if e.code != gdef.STATUS_OBJECT_TYPE_MISMATCH:
|
||||
raise
|
||||
return None
|
||||
|
||||
def items(self):
|
||||
"""Todo: better name ?"""
|
||||
"""Return the list of tuple (object's name, object) in the current directory object.
|
||||
|
||||
:rtype: [(:class:`str`, :class:`KernelObject`)] -- A list of tuple
|
||||
|
||||
.. note::
|
||||
|
||||
the :class:`KernelObject` must be of type ``Directory`` or
|
||||
it will raise :class:`~windows.generated_def.ntstatus.NtStatusException` with
|
||||
code :data:`~windows.generated_def.STATUS_OBJECT_TYPE_MISMATCH`
|
||||
"""
|
||||
path = self.fullname
|
||||
return [(name, KernelObject(path, name, typename)) for name, typename in self._directory_query_generator()]
|
||||
|
||||
def keys(self):
|
||||
"""Return the list of objects' name in the current directory object.
|
||||
|
||||
:rtype: [:class:`str`] -- A list of name
|
||||
|
||||
.. note::
|
||||
|
||||
the :class:`KernelObject` must be of type ``Directory`` or
|
||||
it will raise :class:`~windows.generated_def.ntstatus.NtStatusException` with
|
||||
code :data:`~windows.generated_def.STATUS_OBJECT_TYPE_MISMATCH`
|
||||
"""
|
||||
return list(self)
|
||||
|
||||
def values(self):
|
||||
"""Return the list of objects in the current directory object.
|
||||
|
||||
:rtype: [:class:`KernelObject`] -- A list of object
|
||||
|
||||
.. note::
|
||||
|
||||
the :class:`KernelObject` must be of type ``Directory`` or
|
||||
it will raise :class:`~windows.generated_def.ntstatus.NtStatusException` with
|
||||
code :data:`~windows.generated_def.STATUS_OBJECT_TYPE_MISMATCH`
|
||||
"""
|
||||
path = self.fullname
|
||||
return [KernelObject(path, name, typename) for name, typename in self._directory_query_generator()]
|
||||
|
||||
@@ -96,6 +132,16 @@ class KernelObject(object):
|
||||
yield v.Name.str, v.TypeName.str
|
||||
|
||||
def __iter__(self):
|
||||
"""Iter over the list of name in the Directory object.
|
||||
|
||||
:yield: :class:`str` -- The names of objects in the directory.
|
||||
|
||||
.. note::
|
||||
|
||||
the :class:`KernelObject` must be of type ``Directory`` or
|
||||
it will raise :class:`~windows.generated_def.ntstatus.NtStatusException` with
|
||||
code :data:`~windows.generated_def.STATUS_OBJECT_TYPE_MISMATCH`
|
||||
"""
|
||||
return (name for name, type in self._directory_query_generator())
|
||||
|
||||
def __repr__(self):
|
||||
@@ -111,20 +157,30 @@ class KernelObject(object):
|
||||
return KernelObject(self.fullname, name, objtype)
|
||||
raise KeyError("Could not find WinObject <{0}> under <{1}>".format(name, self.fullname))
|
||||
|
||||
def __getitem__(self, value):
|
||||
print(self, value)
|
||||
if value.startswith("\\"):
|
||||
def __getitem__(self, name):
|
||||
"""Query object ``name`` from the directory, split and subquery on ``\\``::
|
||||
|
||||
>>> obj
|
||||
<KernelObject "\Windows" (type="Directory")>
|
||||
>>> obj["WindowStations"]["WinSta0"]
|
||||
<KernelObject "\Windows\WindowStations" (type="Directory")>
|
||||
>>> obj["WindowStations\\WinSta0"]
|
||||
<KernelObject "\Windows\WindowStations" (type="Directory")>
|
||||
|
||||
:rtype: :class:`KernelObject`
|
||||
:raise: :class:`KeyError` if ``name`` can not be found.
|
||||
"""
|
||||
if name.startswith("\\"):
|
||||
# Are we the root directory ?
|
||||
if not self.fullname == "\\" :
|
||||
raise ValueError("Cannot query an object path begining by '\\' from an object other than '\\'")
|
||||
elif value == "\\": # Ask for root ? return ourself
|
||||
elif name == "\\": # Ask for root ? return ourself
|
||||
return self
|
||||
else:
|
||||
value = value[1:]
|
||||
name = name[1:]
|
||||
|
||||
obj = self
|
||||
print(value.split("\\"))
|
||||
for part in value.split("\\"):
|
||||
for part in name.split("\\"):
|
||||
try:
|
||||
obj = obj.get(part)
|
||||
except gdef.NtStatusException as e:
|
||||
@@ -159,4 +215,5 @@ class ObjectManager(object):
|
||||
|
||||
:rtype: :class:`KernelObject`
|
||||
"""
|
||||
return self.root[name]
|
||||
return self.root[name]
|
||||
|
||||
|
||||
Reference in New Issue
Block a user