-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathLetterBombExploit.cs
125 lines (105 loc) · 4.67 KB
/
LetterBombExploit.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
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Reflection;
using System.Security.Cryptography;
namespace WiiLetterBomb
{
public class LetterBombExploit
{
public enum Region
{
USA,
Europe,
Japan,
Korea
}
public static bool SignTemplate(Region templateRegion, string macString, string driveLetterRootDir, DateTime dt)
{
var ret = false;
var mac = StringToByteArray(macString);
Stream templateStream = null;
switch (templateRegion)
{
case Region.USA:
templateStream = OpenEmbeddedFile("templateU.bin");
break;
case Region.Europe:
templateStream = OpenEmbeddedFile("templateE.bin");
break;
case Region.Japan:
templateStream = OpenEmbeddedFile("templateJ.bin");
break;
case Region.Korea:
templateStream = OpenEmbeddedFile("templateK.bin");
break;
}
// Read template
var blob = new byte[templateStream.Length];
templateStream.Read(blob, 0, (int)templateStream.Length);
// Timestamp
//var dt = DateTime.UtcNow.AddDays(-1);
var delta = (dt - new DateTime(2000, 1, 1));
uint timestamp = (uint)(delta.TotalSeconds);
// *********************** TEST *********************
//timestamp = 716458776;
//mac = new byte[] { 0xe9, 0x0c, 0x7f, 0xd7, 0x4d, 0x75 };
var mac_suffix = new List<byte>(mac);
mac_suffix.AddRange(new byte[] { 0x75, 0x79, 0x79 });
using (var sha1 = new SHA1Managed())
{
var key = sha1.ComputeHash(mac_suffix.ToArray());
Array.Copy(key, 0, blob, 0x8, 0x10 - 0x8);
Array.Copy(new byte[20], 0, blob, 0xb0, 20);
Array.Copy(BitConverter.GetBytes(timestamp).Reverse().ToArray(), 0, blob, 0x7c, 4);
Array.Copy(Encoding.ASCII.GetBytes(string.Format("{0:0000000000}", timestamp)), 0, blob, 0x80, 10);
using (HMACSHA1 hmac = new HMACSHA1(key.Skip(8).ToArray()))
{
Array.Copy(hmac.ComputeHash(blob), 0, blob, 0xb0, 0xc4 - 0xb0);
}
var fileName = string.Format("private/wii/title/HAEA/{0}/{1}/{2:0000}/{3:00}/{4:00}/{5:00}/{6:00}/HABA_#1/txt/{7}.000", BytesToHexString(key, 0, 4), BytesToHexString(key, 4, 4), dt.Year, dt.Month - 1, dt.Day, dt.Hour, dt.Minute, timestamp.ToString("X8"));
fileName = Path.Combine(driveLetterRootDir, fileName);
Directory.CreateDirectory(Path.GetDirectoryName(fileName));
using (var fsOut = File.Open(fileName, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite))
fsOut.Write(blob, 0, blob.Length);
}
if (templateStream != null)
templateStream.Dispose();
using (var bootElf = OpenEmbeddedFile("boot.elf"))
{
var bytes = new byte[bootElf.Length];
bootElf.Read(bytes, 0, (int)bootElf.Length);
var fileName = Path.Combine(driveLetterRootDir, "boot.elf");
using (var fsOut = File.Open(fileName, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite))
fsOut.Write(bytes, 0, bytes.Length);
}
ret = true;
return ret;
}
static byte [] StringToByteArray(string hex)
{
return Enumerable.Range(0, hex.Length)
.Where(x => x % 2 == 0)
.Select(x => Convert.ToByte(hex.Substring(x, 2), 16))
.ToArray();
}
static string BytesToHexString(byte [] bytes, int startIndex = -1, int length = -1)
{
byte[] byteData = bytes;
if (startIndex != -1 && length != -1)
{
byteData = new byte[length];
Array.Copy(bytes, startIndex, byteData, 0, length);
}
return BitConverter.ToString(byteData).Replace("-", string.Empty).ToUpper();
}
static Stream OpenEmbeddedFile(string fileName)
{
var assembly = Assembly.GetExecutingAssembly();
string resourceName = assembly.GetManifestResourceNames().Single(str => str.EndsWith(fileName));
return assembly.GetManifestResourceStream(resourceName);
}
}
}