Windows日志 模块安装
pip install python-evtx
Windows日志 解析源码
源码
import mmap
import contextlib
import datetime
import Evtx.BinaryParser
from Evtx.Evtx import FileHeader
from Evtx.Views import evtx_file_xml_view
from xml.dom import minidom
from pandas import DataFrame
def Log_Get(evtxpath):
'''
将 evt 日志文件解析成 Dataframe 数据
:param evtxpath:evt 格式的日志路径
:return:
'''
try:
with open(evtxpath, 'r') as f:
with contextlib.closing(mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ)) as buf:
content_list = []
fh = FileHeader(buf, 0)
# 遍历每条日志信息
for xml, record in evtx_file_xml_view(fh):
content_dict = {}
domtree = minidom.parseString(xml)
# 获取事件标准信息(System)
content_dict['Channel'] = domtree.getElementsByTagName('Channel')[0].childNodes[0].data
content_dict['SystemTime'] = str(datetime.datetime.strptime(
domtree.getElementsByTagName('TimeCreated')[0].getAttribute('SystemTime')[:19],
'%Y-%m-%d %H:%M:%S') + datetime.timedelta(hours=8))
content_dict['EventID'] = domtree.getElementsByTagName('EventID')[0].childNodes[0].data
content_dict['Level'] = domtree.getElementsByTagName('Level')[0].childNodes[0].data
content_dict['UserID'] = domtree.getElementsByTagName('Security')[0].getAttribute('UserID')
# content_dict['ProcessID'] = domtree.getElementsByTagName('Execution')[0].getAttribute('ProcessID')
content_dict['Computer'] = domtree.getElementsByTagName('Computer')[0].childNodes[0].data
# 获取事件详情信息(EventData)
for data in domtree.getElementsByTagName('Data'):
if len(data.childNodes):
content_dict[data.getAttribute('Name') + '_EventData'] = data.childNodes[0].data
# 获取用户数据信息(UserData)
# EventData 与 UserData 一样都是3级子列表,都可以使用以下循环获取完整的日志信息。System 也可以,但需修改为2级
for eleone in domtree.getElementsByTagName('UserData'):
for eletwo in eleone.childNodes:
for elethree in eletwo.childNodes:
if elethree.childNodes != () and len(elethree.childNodes) == 1: # 也可能存在4级,直接忽略
content_dict[elethree.tagName + '_UserData'] = elethree.childNodes[0].data
# 归档日志信息
content_list.append(content_dict)
f.close()
df = DataFrame(content_list).fillna('') # 让 Nan 为空字符串
# df = DataFrame(content_list).fillna('').sort_values(by=['SystemTime']) # 按时间排序
return df
# 出现一些编码无法识别的日志文件,如果该日志不属于 ['Security', 'System', 'Setup'],则进行忽略
except (Evtx.BinaryParser.OverrunBufferException, KeyError):
if os.path.splitext(os.path.basename(evtxpath))[0] not in ['Security', 'System', 'Setup']:
return DataFrame()
else:
raise
print(Log_Get('./Security.evtx'))
本文是以 Dataframe 结构输出数据,需要使用命令 “pip install pandas” 同时安装 pandas 模块。如无需要,以字典输出数据即可,“return df” 改为 “return content_list”。
解析
代码中的每个部分与事件查看器中xml形式的内容都是一一对应的,如下图所示:
参考链接
xml.dom — The Document Object Model API — Python 3.10.4 documentation