之前的时候为了解析系统的日志文件找库,找了之后又遇到不少问题,使用起来并不方便,然后就知道了原来是可以通过官方接口直接获取的,绝了….

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import win32evtlog 


hand = win32evtlog.OpenEventLog("localhost","System")
flags = win32evtlog.EVENTLOG_SEQUENTIAL_READ|win32evtlog.EVENTLOG_FORWARDS_READ
while True:
events = win32evtlog.ReadEventLog(hand, flags,0)
if events:
for event in events:
EventID = event.EventID & 0x1FFFFFFF
print('Event ID:', event.EventID & 0x1FFFFFFF) # 事件标识id
print('Event Type',event.EventType)# 事件等级
print('Event Category',event.EventCategory) # 事件类别
print('ComputerName', event.ComputerName) # 电脑名字
print('Time Generated', event.TimeGenerated) # 生成时间
print('Time Written', event.TimeWritten) # 写入时间
print('source',event.SourceName) # 来源
print('RecordNumber',event.RecordNumber)# 记录编号
print('Source Name',event.SourceName) # 来源名
print('Event Data',event.Data) # 事件信息
else:
break

但是这个并不完整,有很多其实获取不到,比如进程id之类的,因此有另一个解决方案:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
import win32evtlog
import xml.etree.ElementTree as ET

# open event file
query_handle = win32evtlog.EvtQuery('D:/**/System.evtx',
win32evtlog.EvtQueryFilePath)

read_count = 0
att_count = 0
while True:
events = win32evtlog.EvtNext(query_handle, 100)
read_count += len(events)
if len(events) == 0:
break
for event in events:
xml_content = win32evtlog.EvtRender(event, win32evtlog.EvtRenderEventXml)
xml = ET.fromstring(xml_content)
ns = '{http://schemas.microsoft.com/win/2004/08/events/event}'

event_id = xml.find(f'.//{ns}EventID').text
Version = xml.find(f'.//{ns}Version').text
level = xml.find(f'.//{ns}Level').text
Task = xml.find(f'.//{ns}Task').text
Opcode = xml.find(f'.//{ns}Opcode').text
Keywords = xml.find(f'.//{ns}Keywords').text
TimeCreated = xml.find(f'.//{ns}TimeCreated').get('SystemTime')
EventRecordID = xml.find(f'.//{ns}EventRecordID').text
execution = xml.find(f'.//{ns}Execution')
process_id = execution.get('ProcessID')
thread_id = execution.get('ThreadID')
channel = xml.find(f'.//{ns}Channel').text
Computer = xml.find(f'.//{ns}Computer').text
EventData_list = [{i.attrib.get('Name'):i.text} for i in xml.findall(f'.//{ns}Data')]
user_data = xml.find(f'.//{ns}UserData')
if event_id == '******':
print({'event_id':event_id,'Version':Version,'level':level,
'Task':Task,'Opcode':Opcode,'Keywords':Keywords,
'TimeCreated':TimeCreated,'EventRecordID':EventRecordID,
'process_id':process_id,'thread_id':thread_id,'channel':channel,
'Computer':Computer,'EventData_list':EventData_list,'user_data':user_data})
att_count+=1
# user_data has possible any data

print(f'Read {read_count} records ----{att_count}')

这个方案就能够直接拿到原始结构解析数据。