Skip to content

Commit d833e40

Browse files
committed
added better comments, more testing, and reformatted output
1 parent bba9e22 commit d833e40

4 files changed

Lines changed: 60 additions & 60 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ python-evtx operates on event log files from Windows operating systems newer tha
2929

3030
Examples
3131
--------
32-
Provided with the parsing module `Evtx` are three scripts that mimic the tools distributed with Parse-Evtx. `evtx_info.py` prints metadata about the event log and verifies the checksums of each chunk. `evtx_templates.py` builds and prints the templates used throughout the event log. Finally, `evtx_dump.py` parses the event log and transforms the binary XML into a human readable ASCII XML format.
32+
Provided with the parsing module `Evtx` are four scripts that mimic the tools distributed with Parse-Evtx. `evtx_info.py` prints metadata about the event log and verifies the checksums of each chunk. `evtx_templates.py` builds and prints the templates used throughout the event log. `evtx_dump.py` parses the event log and transforms the binary XML into a human readable ASCII XML format. Finally, `evtx_dump_json.py` parses event logs, similar to `evtx_dump.py` and transforms the binary XML into JSON with the added capability to output new line delimited JSON to a file.
3333

3434
Note the length of the `evtx_dump.py` script: its only 20 lines. Now, review the contents and notice the complete implementation of the logic:
3535

scripts/evtx_dump.py

Lines changed: 5 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,6 @@
1919
# Version v0.1.1
2020
import Evtx.Evtx as evtx
2121
import Evtx.Views as e_views
22-
import os
23-
import xmltodict
24-
import json
25-
2622

2723
def main():
2824
import argparse
@@ -31,43 +27,14 @@ def main():
3127
description="Dump a binary EVTX file into XML.")
3228
parser.add_argument("evtx", type=str,
3329
help="Path to the Windows EVTX event log file")
34-
parser.add_argument("-o","--output",type=str,help="Path to output JSON file")
3530
args = parser.parse_args()
3631

3732
with evtx.Evtx(args.evtx) as log:
38-
39-
if (args.output):
40-
final_json=[]
41-
for record in log.records():
42-
data_dict=xmltodict.parse(record.xml()) #convert the xml to a dictionary
43-
for event_system_key, event_system_value in data_dict['Event']['System'].items(): # loop through each key and value pair
44-
if (event_system_key=="EventRecordID"):
45-
json_subline={}
46-
firstline={event_system_key:event_system_value}
47-
json_subline.update(firstline) #add the event ID to JSON subline
48-
for event_data_key, event_data_value in data_dict['Event']['EventData'].items(): # loop through each key and value pair
49-
for values in event_data_value:
50-
for event_data_subkey,event_data_subvalue in values.items(): #loop through each
51-
if event_data_subkey=="@Name": #extract the name from the value
52-
data_name=event_data_subvalue
53-
else:
54-
data_value=event_data_subvalue #extract the true value
55-
json_subline.update({data_name:data_value}) #update the JSON sub line
56-
final_json.append(json_subline) #update the final
57-
58-
# Output the JSON data
59-
if (os.path.splitext(args.output)[1] == ".json"): #if the file extension is correct
60-
json_file=args.output
61-
else: # if the file extension is incorrect
62-
json_file=args.output +".json"
63-
with open(json_file,"w") as outfile: #write to an output file
64-
json.dump(final_json,outfile)
65-
else:
66-
print(e_views.XML_HEADER)
67-
print("<Events>")
68-
for record in log.records():
69-
print(record.xml())
70-
print("</Events>")
33+
print(e_views.XML_HEADER)
34+
print("<Events>")
35+
for record in log.records():
36+
print(record.xml())
37+
print("</Events>")
7138

7239

7340
if __name__ == "__main__":

scripts/evtx_dump_json.py

Lines changed: 53 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,84 @@
1-
# Written by AJ Read with help from evtx_dump.py file
2-
# Adds functionality to evtx_dump so that the user can dump evtx data formatted in JSON to the command line or a file.
3-
# The JSON data uses only the "EventRecordID" from the "System" XML structure while using all the fields in the "EventData" xml structure.
1+
#!/usr/bin/env python3
2+
# This file is part of python-evtx.
3+
# Written by AJ Read with help from evtx_dump.py file written by Willi Ballenthin.
4+
#
5+
# Purpose: User can dump evtx data into JSON format to either the command line or a JSON file in new line delimited format.
46

57
import Evtx.Evtx as evtx
68
import Evtx.Views as e_views
7-
import os #added dependency
8-
import xmltodict #added dependency
9-
import json #added dependency
9+
10+
# Added packages
11+
import os
12+
import xmltodict
13+
import json
14+
1015

1116
def main():
1217
import argparse
13-
1418
parser = argparse.ArgumentParser(
1519
description="Dump a binary EVTX file into XML.")
1620
parser.add_argument("evtx", type=str,
1721
help="Path to the Windows EVTX event log file")
18-
parser.add_argument("-o","--output",type=str,help="Path to output JSON file")
22+
parser.add_argument("-o","--output",type=str,
23+
help="Path of output JSON file")
1924
args = parser.parse_args()
2025

2126
with evtx.Evtx(args.evtx) as log:
27+
28+
# Instantiate the final json object
2229
final_json=[]
30+
31+
# Loop through each record in the evtx log
2332
for record in log.records():
24-
data_dict=xmltodict.parse(record.xml()) #convert the xml to a dictionary
25-
for event_system_key, event_system_value in data_dict['Event']['System'].items(): # loop through each key and value pair
33+
34+
# Convert the record to a dictionary for ease of parsing
35+
data_dict=xmltodict.parse(record.xml())
36+
37+
# Loop through each key,value pair of the System section of the evtx logs and extract the EventRecordID
38+
for event_system_key, event_system_value in data_dict['Event']['System'].items():
2639
if (event_system_key=="EventRecordID"):
2740
json_subline={}
2841
firstline={event_system_key:event_system_value}
42+
43+
# Add information to the JSON object for this specific log
2944
json_subline.update(firstline) #add the event ID to JSON subline
30-
for event_data_key, event_data_value in data_dict['Event']['EventData'].items(): # loop through each key and value pair
45+
46+
# Loop through each key, value pair of the EventData section of the evtx logs
47+
for event_data_key, event_data_value in data_dict['Event']['EventData'].items():
3148
for values in event_data_value:
32-
for event_data_subkey,event_data_subvalue in values.items(): #loop through each
33-
if event_data_subkey=="@Name": #extract the name from the value
49+
50+
# Loop through each subvalue within the EvenData section to extract necessary information
51+
for event_data_subkey,event_data_subvalue in values.items():
52+
if event_data_subkey=="@Name":
3453
data_name=event_data_subvalue
3554
else:
36-
data_value=event_data_subvalue #extract the true value
37-
json_subline.update({data_name:data_value}) #update the JSON sub line
38-
final_json.append(json_subline) #update the final
55+
data_value=event_data_subvalue
56+
57+
# Add information to the JSON object for this specific log
58+
json_subline.update({data_name:data_value})
59+
60+
# Print the JSON object for the specific log if not requested to output to file
61+
if not args.output:
62+
print(json_subline)
63+
64+
# Add specific log JSON object to the final JSON object
65+
if not final_json:
66+
final_json=[json_subline]
67+
else:
68+
final_json.append(json_subline)
3969

4070
# If output is desired
4171
if (args.output):
72+
4273
# Output the JSON data
43-
if (os.path.splitext(args.output)[1] == ".json"): #if the file extension is correct
74+
if (os.path.splitext(args.output)[1] == ".json"):
4475
json_file=args.output
45-
else: # if the file extension is incorrect
76+
else:
4677
json_file=args.output +".json"
47-
with open(json_file,"w") as outfile: #write to an output file
78+
79+
# Write to JSON file
80+
with open(json_file,"w") as outfile:
4881
json.dump(final_json,outfile)
49-
else:
50-
print(final_json)
82+
5183
if __name__ == "__main__":
5284
main()

setup.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
]
4141
},
4242
scripts=['scripts/evtx_dump.py',
43+
'scripts/evtx_dump_json.py'
4344
'scripts/evtx_dump_chunk_slack.py',
4445
'scripts/evtx_eid_record_numbers.py',
4546
'scripts/evtx_extract_record.py',

0 commit comments

Comments
 (0)