-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathEventLog.cs
159 lines (113 loc) · 4.17 KB
/
EventLog.cs
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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
using System;
using System.Collections.Generic;
using System.IO;
using System.Xml;
namespace evtxsharp
{
public class EventLog
{
public EventLog (string filename)
{
this.Strings = new Dictionary<long, string>();
using (FileStream stream = File.OpenRead(filename))
{
using (BinaryReader reader = new BinaryReader(stream))
{
byte[] h = reader.ReadBytes(8);
if (!(h[0] == 'E' && h[1] == 'l' && h[2] == 'f' && h[3] == 'F' && h[4] == 'i' && h[5] == 'l' && h[6] == 'e'))
throw new Exception("Unsupported file type");
int numOldLow, numOldHigh;
int numCurLow, numCurHigh;
int nextRecLow, nextRecHigh;
numOldLow = reader.ReadInt32();
numOldHigh = reader.ReadInt32();
numCurLow = reader.ReadInt32();
numCurHigh = reader.ReadInt32();
nextRecLow = reader.ReadInt32();
nextRecHigh = reader.ReadInt32();
int numOld = (numOldHigh << 32) ^ numOldLow;
int numCur = (numCurHigh << 32) ^ numCurLow;
int nextRec = (nextRecHigh << 32) ^ nextRecLow;
byte[] headerPart, versionMinor, versionMajor, headerLen, chunkCount;
headerPart = reader.ReadBytes(4);
versionMinor = reader.ReadBytes(2);
versionMajor = reader.ReadBytes(2);
headerLen = reader.ReadBytes(2);
chunkCount = reader.ReadBytes(2);
if (!BitConverter.IsLittleEndian)
{
Array.Reverse(headerLen);
Array.Reverse(headerPart);
Array.Reverse(versionMajor);
Array.Reverse(versionMinor);
Array.Reverse(chunkCount);
}
int chunkc = BitConverter.ToInt16(chunkCount,0);
long chunkOffset = 0x1000;
reader.BaseStream.Position = chunkOffset;
int n = 1;
for (int k = 0; k < chunkc; k++)
{
h = reader.ReadBytes(8);
if (!(h[0] == 'E' && h[1] == 'l' && h[2] == 'f' && h[3] == 'C' && h[4] == 'h' && h[5] == 'n' && h[6] == 'k'))
throw new Exception("Bad chunk at offset: " + reader.BaseStream.Position);
ulong first = reader.ReadUInt64();
ulong last = reader.ReadUInt64();
ulong rfirst = reader.ReadUInt64(); //redundant first
ulong rlast = reader.ReadUInt64(); //redundant last
uint unk1 = reader.ReadUInt32();
uint unk2 = reader.ReadUInt32();
uint offset = reader.ReadUInt32();
uint crcData = reader.ReadUInt32();
uint crcHeader = reader.ReadUInt32();
if (crcData == 0)
continue; //empty chunk
uint nextOffset = 0x200; //first event in a chunk
reader.BaseStream.Position = chunkOffset + nextOffset; //(512+4096)
this.Roots = new List<LogRoot>();
for (ulong i = first; i <= last; i++)
{
long pos = reader.BaseStream.Position;
h = reader.ReadBytes(2);
if (h[0] != '*' || h[1] != '*')
{
Console.WriteLine("Bad event at position: " + reader.BaseStream.Position);
continue;
}
reader.BaseStream.Position += 2;
uint el = reader.ReadUInt32() - 28;
long rid = reader.ReadInt64();
ulong ts = reader.ReadUInt64();
ts /= 1000;
ts -= 116444736000000;
int secs = (int)(ts / 10000);
DateTime timestamp = GetTime (secs);
LogRoot root = new LogRoot(reader, chunkOffset, el, this) { Offset = pos };
Console.WriteLine(root.ToXML());
this.Roots.Add(root);
reader.BaseStream.Position = (el + pos);
}
reader.BaseStream.Position = chunkOffset = (n++*0x10000)+0x1000;
}
}
}
string xml = "<Events>";
foreach (LogRoot root in this.Roots)
xml += root.ToXML();
Console.WriteLine(xml);
xml += "</Events>";
this.XmlDocument = new XmlDocument();
this.XmlDocument.LoadXml(xml);
}
private List<LogRoot> Roots { get; set; }
public List<LogItem> Items { get; set; }
public Dictionary<long, string> Strings { get; set; }
public XmlDocument XmlDocument { get; set; }
private DateTime GetTime(int time)
{
DateTime output = new DateTime(1970, 1, 1, 0, 0, 0);
output = output.AddSeconds(time);
return output;
}
}
}