Add doc/sample/test for event log code

This commit is contained in:
hakril
2018-06-05 11:30:25 +02:00
parent 057d4e5408
commit 93bb9b6540
6 changed files with 507 additions and 56 deletions
+92
View File
@@ -0,0 +1,92 @@
Event Log
=========
.. module:: windows.winobject.event_log
Some part of the Event Log WINAPI are not straightforward.
I have tried to offer some abstraction without completly hidding the some underlying subtilities (for now).
The current API may need some works to provide simpler/highter level API in the future.
For now, the best thing to do is look at the sample:
.. note::
See sample :ref:`sample_event_log`
.. warning::
This API have not been tested on real case yet and may be subject to changes.
EvtlogManager
"""""""""""""
.. autoclass:: EvtlogManager
:special-members: __getitem__
Channel
"""""""
EvtChannel
''''''''''
.. autoclass:: EvtChannel
ChannelConfig
'''''''''''''
.. autoclass:: ChannelConfig
Publisher
"""""""""
EvtPublisher
''''''''''''
.. autoclass:: EvtPublisher
PublisherMetadata
'''''''''''''''''
.. autoclass:: PublisherMetadata
EvtFile
"""""""
.. autoclass:: EvtFile
Event
"""""
EvtEvent
''''''''
.. autoclass:: EvtEvent
EventMetadata
'''''''''''''
.. autoclass:: EventMetadata
EvtQuery
''''''''
.. autoclass:: EvtQuery
TODO
""""
.. autoclass:: PropertyArray
@@ -0,0 +1,55 @@
(cmd) python event_log\eventlog.py
Event log Manager is: <windows.winobject.event_log.EvtlogManager object at 0x0592DB70>
They are <1155> channels
They are <1179> publishers
Openning channel <Microsoft-Windows-Windows Firewall With Advanced Security/Firewall>
Channel is <EvtChannel "Microsoft-Windows-Windows Firewall With Advanced Security/Firewall">
The channel contains <1037> events
Querying "Event/EventData[Data='C:\WINDOWS\System32\svchost.exe'] and Event/System[EventID=2006]">
Query is <EvtQuery object at 0x06E9F440>
List contains 304 event
First event is <EvtEvent id="2006" time="2018-05-06 08:03:06.210109">
System values:
* ID: 2006
* version: 0
* level: 4
* opcode: 0
* time_created: 131700673862101088
* ID: 2006
Event specific values:
* <ModifyingUser> -> <108703760>
* <RuleName> -> <ByteCodeGeneration>
* <ModifyingApplication> -> <C:\WINDOWS\System32\svchost.exe>
* <RuleId> -> <{318EF1CF-A3FA-4B04-8AAC-712276661117}>
Event metadata is <EventMetadata object at 0x06EB96C0>
* id : 2006
* channel_id : 16
* message_id : 2986346454
* event_data : [u'RuleId', u'RuleName', u'ModifyingUser', u'ModifyingApplication']
* EventData template :
<template xmlns="http://schemas.microsoft.com/win/2004/08/events">
<data name="RuleId" inType="win:UnicodeString" outType="xs:string"/>
<data name="RuleName" inType="win:UnicodeString" outType="xs:string"/>
<data name="ModifyingUser" inType="win:SID" outType="xs:string"/>
<data name="ModifyingApplication" inType="win:UnicodeString" outType="xs:string"/>
</template>
Exploring complex Evt types:
Channel is still <EvtChannel "Microsoft-Windows-Windows Firewall With Advanced Security/Firewall">
Channel config is <ChannelConfig "Microsoft-Windows-Windows Firewall With Advanced Security/Firewall">
Channel publisher is <EvtPublisher "Microsoft-Windows-Windows Firewall With Advanced Security">
Channel publisher metadata is <PublisherMetadata "Microsoft-Windows-Windows Firewall With Advanced Security">
Publisher's channels are:
* <EvtChannel "Microsoft-Windows-Windows Firewall With Advanced Security/Firewall">
* <EvtChannel "Microsoft-Windows-Windows Firewall With Advanced Security/ConnectionSecurity">
* <EvtChannel "Microsoft-Windows-Windows Firewall With Advanced Security/FirewallVerbose">
* <EvtChannel "Microsoft-Windows-Windows Firewall With Advanced Security/ConnectionSecurityVerbose">
* <EvtChannel "Network Isolation Operational">
Some publisher's event metadata are:
* <EventMetadata object at 0x06EBE710>: id=2000
* <EventMetadata object at 0x06EBE7B0>: id=2001
* <EventMetadata object at 0x06EBE3F0>: id=2002
+65
View File
@@ -0,0 +1,65 @@
import windows
import windows.generated_def as gdef
evtlogmgr = windows.system.event_log
print("Event log Manager is: {0}".format(evtlogmgr))
print("They are <{0}> channels".format(len(list(evtlogmgr.channels))))
print("They are <{0}> publishers".format(len(list(evtlogmgr.publishers))))
FIREWALL_CHANNEL = "Microsoft-Windows-Windows Firewall With Advanced Security/Firewall"
print("Openning channel <{0}>".format(FIREWALL_CHANNEL))
evtchan = evtlogmgr[FIREWALL_CHANNEL]
print("Channel is {0}".format(evtchan))
# Note that `evtchan.events` is an alias for `evtchan.query().all()`
print("The channel contains <{0}> events".format(len(evtchan.events)))
print("")
EVT_QUERY = "Event/EventData[Data='C:\\WINDOWS\\System32\\svchost.exe'] and Event/System[EventID=2006]"
print("""Querying "{0}">""".format(EVT_QUERY))
query = evtchan.query(EVT_QUERY)
print("Query is {0}".format(query))
event_list = list(query)
print("List contains {0} event".format(len(event_list)))
event = event_list[0]
print("")
print("First event is {0}".format(event))
print("System values:")
print(" * ID: {0}".format(event.id))
print(" * version: {0}".format(event.version))
print(" * level: {0}".format(event.level))
print(" * opcode: {0}".format(event.opcode))
print(" * time_created: {0}".format(event.time_created))
print(" * ID: {0}".format(event.id))
print("Event specific values:")
for name, value in event.data.items():
print(" * <{0}> -> <{1}>".format(name, value))
print("")
evtmeta = event.metadata
print("Event metadata is {0}".format(evtmeta))
print(" * id : {0}".format(evtmeta.id))
print(" * channel_id : {0}".format(evtmeta.channel_id))
print(" * message_id : {0}".format(evtmeta.message_id))
print(" * event_data : {0}".format(evtmeta.event_data))
print(" * EventData template :\n{0}".format(evtmeta.template.replace("\r\n", "\n")))
print("")
print("Exploring complex Evt types:")
print("Channel is still {0}".format(evtchan))
print("Channel config is {0}".format(evtchan.config))
publisher = evtchan.config.publisher
print("Channel publisher is {0}".format(publisher))
print("Channel publisher metadata is {0}".format(publisher.metadata))
print("Publisher's channels are:")
for chan in publisher.metadata.channels:
print(" * {0}".format(chan))
print("Some publisher's event metadata are:")
for evtmeta in list(publisher.metadata.events_metadata)[:3]:
print(" * {0}: id={1}".format(evtmeta, evtmeta.id))
+74
View File
@@ -0,0 +1,74 @@
import pytest
import subprocess
import os.path
import windows
import windows.generated_def as gdef
import windows.winobject.event_log as evtl
CHANNEL_NAME = "Microsoft-Windows-Windows Firewall With Advanced Security/Firewall"
PUBLISHER_NAME = "Microsoft-Windows-Windows Firewall With Advanced Security"
ALL_FIREWALL_CHAN = ["Microsoft-Windows-Windows Firewall With Advanced Security/Firewall",
"Microsoft-Windows-Windows Firewall With Advanced Security/ConnectionSecurity",
"Microsoft-Windows-Windows Firewall With Advanced Security/FirewallVerbose",
"Microsoft-Windows-Windows Firewall With Advanced Security/ConnectionSecurityVerbose",
"Network Isolation Operational"]
@pytest.mark.parametrize("name, publisher_name", [(CHANNEL_NAME, PUBLISHER_NAME)])
def test_event_channel(name, publisher_name):
chan = windows.system.event_log[name]
assert isinstance(chan, evtl.EvtChannel)
assert chan.name == name
assert chan.config.publisher.name == publisher_name
assert not chan.config.classic
@pytest.mark.parametrize("name, eventid", [(CHANNEL_NAME, 2004)])
def test_event_channel_query(name, eventid):
chan = windows.system.event_log[name]
all_events = chan.events
assert len(all_events) # Should have some event to test | skip else ?
eventquery = chan.query(ids=2004)
assert isinstance(eventquery, evtl.EvtQuery)
all_id_events = eventquery.all()
assert len(all_id_events)
assert len(all_id_events) <= len(all_events)
assert all(evt.id == eventid for evt in all_id_events)
# Extract event metadata
event_data_names = chan.get_event_metadata(eventid).event_data
# Check all event data match event metadata description
for evt in all_id_events:
assert set(evt.data.keys()) == set(event_data_names)
@pytest.mark.parametrize("name, chans, eventid", [(PUBLISHER_NAME, ALL_FIREWALL_CHAN, 2004)])
def test_event_publisher(name, chans, eventid):
publisher = windows.system.event_log[name]
assert isinstance(publisher, evtl.EvtPublisher)
assert publisher.name == name
pmetadata = publisher.metadata
assert set(chan.name for chan in pmetadata.channels) == set(chans)
assert eventid in [evtmedata.id for evtmedata in pmetadata.events_metadata]
POWERSHELL_PATH = r"C:\Windows\System32\WindowsPowershell\v1.0\powershell.exe"
POWERSHELL_ARG = "PFW_TEST_STRING.NOTEXISTS"
def test_new_event():
chan = windows.system.event_log["Microsoft-Windows-PowerShell/Operational"]
pre_events = chan.events
p = windows.utils.create_process(POWERSHELL_PATH, ["PFW_TEST_STRING.NOTEXISTS"], show_windows=False)
p.wait()
import time; time.sleep(1) # It seems to take some time to log the event
post_events = chan.events
assert len(post_events) > len(pre_events)
nb_new_events = len(post_events) - len(pre_events)
new_events = post_events[-nb_new_events:]
# Check that some new event were triggered by our powershell
# TODO: should be nice to find simpler event log to trigger with controled data
assert any(evt.pid == p.pid for evt in new_events)
@@ -52,6 +52,7 @@ publishinfo = generate_query_function(winproxy.EvtGetPublisherMetadataProperty)
# Class high-level API
class EvtQuery(gdef.EVT_HANDLE):
"""Represent an Event-log query"""
TIMEOUT = 0x1000
def __init__(self, handle=0, channel=None):
@@ -59,6 +60,7 @@ class EvtQuery(gdef.EVT_HANDLE):
self.channel = channel
def __next__(self):
"""Return the next :class:`EvtEvent` matching the query"""
try:
event = EvtEvent(channel=self.channel)
ret = gdef.DWORD()
@@ -76,10 +78,15 @@ class EvtQuery(gdef.EVT_HANDLE):
next = __next__ # Yep.. real name is 'next' in Py2 :D
def all(self): # SqlAlchemy like :)
"""Return a list with all the query results
:rtype: [:class:`EvtEvent`] -- A list of Event
"""
return list(self)
class EvtEvent(gdef.EVT_HANDLE):
"""An Event log"""
def __init__(self, handle=0, channel=None):
super(EvtEvent, self).__init__(handle)
self.channel = channel
@@ -111,6 +118,10 @@ class EvtEvent(gdef.EVT_HANDLE):
return xml[:-1]
def value(self, name, **kwargs):
"""Retrieve a value from the event.
``name`` is an XPath expressions that uniquely identify a node or attribute in the event.
(see https://msdn.microsoft.com/en-us/library/windows/desktop/aa385352(v=vs.85).aspx)
"""
values = self.get_values((name,), **kwargs)
assert len(values) == 1
return values[0]
@@ -126,12 +137,12 @@ class EvtEvent(gdef.EVT_HANDLE):
result = self.render(ctx, gdef.EvtRenderEventValues)
return [r.value for r in result]
def system(self): # POC: use this for all @property based on system data ?
def system_values(self): # POC: use this for all @property based on system data ?
ctx = windows.winproxy.EvtCreateRenderContext(0, None, gdef.EvtRenderContextSystem)
result = self.render(ctx, gdef.EvtRenderEventValues)
return [r.value for r in result]
def user(self):
def event_values(self):
ctx = windows.winproxy.EvtCreateRenderContext(0, None, gdef.EvtRenderContextUser)
result = self.render(ctx, gdef.EvtRenderEventValues)
return [r.value for r in result]
@@ -139,33 +150,55 @@ class EvtEvent(gdef.EVT_HANDLE):
# Properties arround common Event/System values
@property
def id(self):
"""The ID of the Event"""
return self.value("Event/System/EventID")
@property
def version(self):
"""The version of the Event"""
return self.value("Event/System/Version")
@property
def level(self):
"""The level of the Event"""
return self.value("Event/System/Level")
@property
def opcode(self):
"""The opcode of the Event"""
return self.value("Event/System/Opcode")
@property
def time_created(self):
"""The creation time of the Event"""
return self.value("Event/System/TimeCreated/@SystemTime")
@property
def pid(self):
"""The process ID of the Event"""
return self.value("Event/System/Execution/@ProcessID")
@property
def tid(self):
"""The process ID of the Event"""
return self.value("Event/System/Execution/@ThreadID")
@property
def metadata(self):
"HEAVY CALL"
"""The medata for the current Event
:type: :class:`EventMetadata`
"""
return self.channel.get_event_metadata(self.id)
# Test
@property
def data(self): # user/event specifique data
return {k:v for k,v in zip(self.metadata.user_data, self.user())}
"""A dict of EventData Name:Value for the current dict.
:type: :class:`dict`
"""
return {k:v for k,v in zip(self.metadata.event_data, self.event_values())}
def __repr__(self):
@@ -216,43 +249,8 @@ class ImprovedEVT_VARIANT(gdef.EVT_VARIANT):
return "<{0} of type={1}>".format(type(self).__name__, self.Type)
def channels():
h = windows.winproxy.EvtOpenChannelEnum(None, 0)
size = 0x1000
buffer = ctypes.create_unicode_buffer(size)
ressize = gdef.DWORD()
try:
while True:
try:
windows.winproxy.EvtNextChannelPath(h, size, buffer, ressize)
except WindowsError as e:
if e.winerror != gdef.ERROR_NO_MORE_ITEMS:
raise
return
assert buffer[ressize.value - 1] == "\x00"
yield buffer[:ressize.value - 1]
finally: # TODO: ctx manager
windows.winproxy.EvtClose(h)
def publishers():
h = windows.winproxy.EvtOpenPublisherEnum(None, 0)
size = 0x1000
buffer = ctypes.create_unicode_buffer(size)
ressize = gdef.DWORD()
try:
while True:
try:
windows.winproxy.EvtNextPublisherId(h, size, buffer, ressize)
except WindowsError as e:
if e.winerror != gdef.ERROR_NO_MORE_ITEMS:
raise
return
assert buffer[ressize.value - 1] == "\x00"
yield buffer[:ressize.value - 1]
finally: # TODO: ctx manager
windows.winproxy.EvtClose(h)
# x = windows.winproxy.EvtQuery(None,
@@ -273,13 +271,33 @@ def publishers():
# list(channels())
class EvtChannel(object):
"""An Event Log channel"""
DEFAULT_QUERY_FLAGS = gdef.EvtQueryChannelPath + gdef.EvtQueryForwardDirection
def __init__(self, name):
self.name = name
self.event_metadata_by_id = {}
def query(self, ids=None, filter=None):
def query(self, filter=None, ids=None):
"""Query the event with the ``ids`` or perform a query with the raw query ``filter``
Both parameters are mutually exclusive.
.. note:: Here are some query examples
List all events with a event data attribute named 'RuleName':
``Event/EventData/Data[@Name='RuleName']``
List all events with a event data value of 'C:\\\\WINDOWS\\\\System32\\\\svchost.exe':
``Event/EventData[Data='C:\\WINDOWS\\System32\\svchost.exe']``
List all events with an EventID of 2006:
``Event/System[EventID=2006]``
:rtype: :class:`EvtQuery`
"""
if ids and filter:
raise ValueError("<ids> and <filter> are mutually exclusive")
if ids is not None:
if isinstance(ids, (long, int)):
ids = (ids,)
@@ -288,11 +306,27 @@ class EvtChannel(object):
query_handle = winproxy.EvtQuery(None, self.name, filter, self.DEFAULT_QUERY_FLAGS)
return EvtQuery(query_handle, self)
@property
def events(self):
"""The list of all events in the channels, an alias for ``channel.query().all()``
:type: [:class:`EvtEvent`] -- A list of :class:`EvtEvent`
"""
return self.query().all()
@property
def config(self):
"""The configuration of the channel
:type: :class:`ChannelConfig`
"""
return ChannelConfig.from_channel_name(self.name)
def get_event_metadata(self, id):
"""Return the metadata for the event ID ``id``
:rtype: :class:`EventMetadata`
"""
try:
return self.event_metadata_by_id[id]
except KeyError as e:
@@ -308,36 +342,55 @@ class EvtChannel(object):
class EvtFile(EvtChannel):
"""Represent an Evtx file"""
DEFAULT_QUERY_FLAGS = gdef.EvtQueryFilePath + gdef.EvtQueryForwardDirection
@property
def config(self):
"""Not implemented for EvtFile
:raise: :class:`NotImplementedError`
"""
raise NotImplementedError("Cannot retrieve the configuration of an EvtFile")
class ChannelConfig(gdef.EVT_HANDLE):
"""The configuration of a event channel"""
def __init__(self, handle, name=None):
super(ChannelConfig, self).__init__(handle)
self.name = name
@classmethod
def from_channel_name(cls, channel_name):
return cls(winproxy.EvtOpenChannelConfig(None, channel_name, 0), channel_name)
def from_channel_name(cls, name):
"""Return the :class:`ChannelConfig` for the channel ``name``"""
return cls(winproxy.EvtOpenChannelConfig(None, name, 0), name)
@property
def publisher(self):
"""The :class:`EvtPublisher` for the channel"""
return EvtPublisher(chaninfo(self, gdef.EvtChannelConfigOwningPublisher).value)
@property
def classic(self):
"""``True`` if the channel is a classic event channel (for example the Application or System log)"""
return bool(chaninfo(self, gdef.EvtChannelConfigClassicEventlog).value)
def __repr__(self):
return '<{0} "{1}">'.format(type(self).__name__, self.name)
class EvtPublisher(object):
"""An Event provider"""
def __init__(self, name):
self.name = name
@property
def metadata(self):
"""Return the metadata for this publisher
:type: :class:`PublisherMetadata`
"""
return PublisherMetadata.from_publisher_name(self.name)
def __repr__(self):
@@ -345,20 +398,30 @@ class EvtPublisher(object):
class PublisherMetadata(gdef.EVT_HANDLE):
"""The metadata about an event provider"""
def __init__(self, handle, name=None):
super(PublisherMetadata, self).__init__(handle)
self.name = name
@classmethod
def from_publisher_name(cls, publisher_name):
return cls(winproxy.EvtOpenPublisherMetadata(None, publisher_name, None, 0, 0), publisher_name)
def from_publisher_name(cls, name):
"""The :class:`PublisherMetadata` for the publisher ``name``"""
return cls(winproxy.EvtOpenPublisherMetadata(None, name, None, 0, 0), name)
@property
def chanrefs(self):
"""Identifies the channels child element of the provider.
:type: :class:`PropertyArray`
"""
return PropertyArray(publishinfo(self, gdef.EvtPublisherMetadataChannelReferences).value)
@property
def events_metadata(self):
"""The :class:`EventMetadata` for each event this provider defines
:yield: :class:`EventMetadata`
"""
eh = winproxy.EvtOpenEventMetadataEnum(self, 0)
with ClosingEvtHandle(eh):
while True:
@@ -370,16 +433,32 @@ class PublisherMetadata(gdef.EVT_HANDLE):
raise
break
@property
def channel_name_by_id(self):
"""The dict of channel defined by this provider by their id
:type: :class:`dict`
"""
chansref = self.chanrefs
channame_by_value_id = {}
for i in range(chansref.size):
value = chansref.propery(gdef.EvtPublisherMetadataChannelReferenceID, i)
name = chansref.propery(gdef.EvtPublisherMetadataChannelReferencePath, i)
value = chansref.property(gdef.EvtPublisherMetadataChannelReferenceID, i)
name = chansref.property(gdef.EvtPublisherMetadataChannelReferencePath, i)
channame_by_value_id[value] = name
return channame_by_value_id
@property
def channels(self):
"""The list of :class:`EvtChannel` defined by this provider
:type: [:class:`EvtChannel`] -- A list of :class:`EvtChannel`
"""
chansref = self.chanrefs
propertyid = gdef.EvtPublisherMetadataChannelReferencePath
return [EvtChannel(chansref.property(propertyid, i)) for i in range(chansref.size)]
def message(self, msgid):
"TODO"
size = 0x1000
buffer = ctypes.c_buffer(size)
sbuff = ctypes.cast(buffer, gdef.LPWSTR)
@@ -396,65 +475,143 @@ class PublisherMetadata(gdef.EVT_HANDLE):
class PropertyArray(gdef.EVT_OBJECT_ARRAY_PROPERTY_HANDLE):
"TODO"
@property
def size(self):
array_size = gdef.DWORD()
windows.winproxy.EvtGetObjectArraySize(self, array_size)
return array_size.value
def propery(self, type, index):
def property(self, type, index):
return arrayproperty(self, type, index).value
class EventMetadata(gdef.EVT_HANDLE):
"""The Metadata about a given Event type
see: https://msdn.microsoft.com/en-us/library/windows/desktop/aa385517(v=vs.85).aspx
"""
@property
def id(self):
"""The ID of the Event"""
return eventinfo(self, gdef.EventMetadataEventID).value
@property
def channel_id(self):
"""The the Channel attribute of the Event definition"""
return eventinfo(self, gdef.EventMetadataEventChannel).value
@property
def message_id(self):
"""Identifies the message attribute of the event definition."""
return eventinfo(self, gdef.EventMetadataEventMessageID).value
@property
def template(self):
"""Identifies the template attribute of the event definition which is an XML string"""
return eventinfo(self, gdef.EventMetadataEventTemplate).value
@property
def user_data(self):
def event_data(self):
"""The list of attribute specifique for this event.
Retrieved by parsing :data:`EventMetadata.template`
"""
result = []
xmltemplate = xml.dom.minidom.parseString(self.template)
template = self.template
if not template:
return {}
xmltemplate = xml.dom.minidom.parseString(template)
for data in xmltemplate.getElementsByTagName("data"):
result.append(data.attributes["name"].value)
return result
class EvtlogManager(object):
"TODO: doc -> the frontend API object"
"""The main Evt class to open Evt channel/publisher and evtx file"""
# https://msdn.microsoft.com/en-us/library/windows/desktop/aa385784(v=vs.85).aspx
def open_channel(self, channel_name):
chan = EvtChannel(channel_name)
def is_implemented(self):
"""Return ``True`` if the new Evt-API is implemented on the current computer
see: https://msdn.microsoft.com/en-us/library/windows/desktop/aa385784(v=vs.85).aspx
"""
return windows.winproxy.is_implemented(windows.winproxy.EvtQuery)
@property
def channels(self):
h = windows.winproxy.EvtOpenChannelEnum(None, 0)
size = 0x1000
buffer = ctypes.create_unicode_buffer(size)
ressize = gdef.DWORD()
with ClosingEvtHandle(h):
while True:
try:
windows.winproxy.EvtNextChannelPath(h, size, buffer, ressize)
except WindowsError as e:
if e.winerror != gdef.ERROR_NO_MORE_ITEMS:
raise
return
assert buffer[ressize.value - 1] == "\x00"
name = buffer[:ressize.value - 1]
chan = EvtChannel(name)
yield chan
@property
def publishers(self):
h = windows.winproxy.EvtOpenPublisherEnum(None, 0)
size = 0x1000
buffer = ctypes.create_unicode_buffer(size)
ressize = gdef.DWORD()
with ClosingEvtHandle(h):
while True:
try:
windows.winproxy.EvtNextPublisherId(h, size, buffer, ressize)
except WindowsError as e:
if e.winerror != gdef.ERROR_NO_MORE_ITEMS:
raise
return
assert buffer[ressize.value - 1] == "\x00"
name = buffer[:ressize.value - 1]
publisher = EvtPublisher(name)
yield publisher
def open_channel(self, name):
"""Open the Evt channel with ``name``
:rtype: :class:`EvtChannel`
"""
chan = EvtChannel(name)
chan.config # Force to retrieve a handle (check channel exists)
return chan
def open_evtx_file(self, filename):
# We don't check if file exists because of 32->64 redirection
# Do a check with FSRedirection disabled ?
"""Open the evtx file with ``filename``
:rtype: :class:`EvtFile`
"""
with windows.utils.DisableWow64FsRedirection():
if not os.path.exists(filename):
raise WindowsError(gdef.ERROR_FILE_NOT_FOUND, "Could not find file <{0}>".format(filename))
file = EvtFile(filename)
return file
def open_publisher(self, publisher_name):
publisher = EvtPublisher(publisher_name)
def open_publisher(self, name):
"""Open the Evt publisher with ``name``
:rtype: :class:`EvtPublisher`
"""
publisher = EvtPublisher(name)
publisher.metadata # Force to retrieve a handle (check channel exists)
return publisher
def __getitem__(self, name):
"""Open the Evt Channel/Publisher or Evtx file with ``name``
:rtype: :class:`EvtChannel` or :class:`EvtPublisher` or :class:`EvtFile`
"""
try:
return self.open_channel(name)
except WindowsError as e:
+8
View File
@@ -18,6 +18,7 @@ from windows.winobject import volume
from windows.winobject import wmi
from windows.winobject import kernobj
from windows.winobject import handle
from windows.winobject import event_log
from windows.winobject import task_scheduler
from windows.generated_def.winstructs import *
@@ -89,6 +90,11 @@ class System(object):
return wmi.WmiManager()
@utils.fixedpropety
def event_log(self):
return event_log.EvtlogManager()
@utils.fixedpropety
def task_scheduler(self):
"""An object able to manage scheduled tasks on the local system
@@ -98,6 +104,8 @@ class System(object):
windows.com.init()
clsid_task_scheduler = gdef.IID.from_string("0f87369f-a4e5-4cfc-bd3e-73e6154572dd")
task_service = task_scheduler.TaskService()
# What is non-implemented (WinXP)
# Raise (NotImplementedError?) ? Return NotImplemented ?
windows.com.create_instance(clsid_task_scheduler, task_service)
task_service.connect()
return task_service