This repository has been archived by the owner on Dec 19, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
MagicNumber.cs
104 lines (92 loc) · 2.96 KB
/
MagicNumber.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
using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Text;
using System.Xml;
namespace MagicNumberLite
{
public class DataType
{
public readonly string Extension;
public readonly string MimeType;
public readonly string Name;
public DataType(string ext, string mime, string name)
{
Extension = ext;
MimeType = mime;
Name = name;
}
}
public class Match : DataType
{
public byte[] Bytes;
public Match(byte[] bytes, string ext, string mime, string name)
: base(ext, mime, name)
{
Bytes = bytes;
}
public bool Matches(byte[] data)
{
if (Bytes == null && data == null) return true;
if (Bytes == null || data == null) return false;
for (int i = 0; i < Bytes.Length; i++)
if (Bytes[i] != data[i])
return false;
return true;
}
}
public class Inspector
{
Dictionary<long, Dictionary<byte, Match[]>> Matches;
public Inspector()
{
Matches = new Dictionary<long, Dictionary<byte, Match[]>>();
XmlDocument xml = new XmlDocument();
xml.Load(Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetAssembly(typeof(Inspector)).Location),
ConfigurationManager.AppSettings["MagicNumberLiteXml"]));
foreach (XmlElement offset in xml.DocumentElement.ChildNodes)
{
Dictionary<byte, Match[]> bundle = new Dictionary<byte, Match[]>();
foreach (XmlElement bundlenode in offset.ChildNodes)
{
List<Match> matches = new List<Match>();
foreach (XmlElement matchnode in bundlenode.ChildNodes)
{
string[] nibpairs = matchnode.GetAttribute("bytes").Split(null);
byte[] bytes = new byte[nibpairs.Length];
for (byte i = 0; i < nibpairs.Length; i++)
bytes[i] = Byte.Parse(nibpairs[i], System.Globalization.NumberStyles.HexNumber);
matches.Add(new Match(bytes, matchnode.GetAttribute("ext"),
matchnode.GetAttribute("mime"), matchnode.GetAttribute("name")));
}
bundle.Add(Byte.Parse(bundlenode.GetAttribute("byte"),
System.Globalization.NumberStyles.HexNumber), matches.ToArray());
}
Matches.Add(Int32.Parse(offset.GetAttribute("at")), bundle);
}
}
public DataType GetDataType(byte[] data)
{
return GetDataType(new BinaryReader(new MemoryStream(data)));
}
public DataType GetDataType(Stream data)
{
return GetDataType(new BinaryReader(data));
}
public DataType GetDataType(BinaryReader data)
{
foreach (long offset in Matches.Keys)
{
data.BaseStream.Seek(offset, SeekOrigin.Begin);
byte[] databytes = new byte[64];
data.BaseStream.Seek(offset, SeekOrigin.Begin);
data.Read(databytes, 0, databytes.Length);
if (Matches[offset].ContainsKey(databytes[0]))
foreach (Match match in Matches[offset][databytes[0]])
if (match.Matches(databytes)) return match as DataType;
}
return new DataType("","application/octet-stream","Unknown");
}
}
}