├── .gitignore
├── CHANGELOG.txt
├── LICENSE
├── NUSGrabberGUI.sln
├── NUSGrabberGUI
├── App.config
├── CertificateChain.cs
├── CommonKey.cs
├── ContentIndices.cs
├── Form1.Designer.cs
├── Form1.cs
├── Form1.resx
├── GlobalSuppressions.cs
├── Headers.cs
├── Lz77.cs
├── MessageEventArgs.cs
├── NUSGrabberGUI.csproj
├── NUSGrabberGUI.csproj.user
├── NUSGrabberGUI.ico
├── NUSGrabberGUI_TemporaryKey.pfx
├── NusClient.cs
├── Program.cs
├── Properties
│ ├── AssemblyInfo.cs
│ ├── Resources.Designer.cs
│ ├── Resources.resx
│ ├── Settings.Designer.cs
│ ├── Settings.settings
│ └── app.manifest
├── Resources
│ ├── CDecrypt.exe
│ ├── HtmlAgilityPack.dll
│ ├── NUSgrabber.exe
│ ├── NUSgrabberORIG.exe
│ ├── en.Designer.cs
│ ├── en.resx
│ ├── libeay32.dll
│ ├── vcruntime140.dll
│ ├── wget.exe
│ └── wiiu_versionlist.txt
├── Settings.Designer.cs
├── Settings.cs
├── Settings.resx
├── Shared.cs
├── TMD.cs
├── Ticket.cs
├── U8.cs
├── WAD.cs
└── packages.config
├── README.md
└── packages
└── HtmlAgilityPack.1.4.9
├── HAPIcon.png
├── HtmlAgilityPack.1.4.9.nupkg
├── lib
├── Net20
│ ├── HtmlAgilityPack.dll
│ ├── HtmlAgilityPack.pdb
│ └── HtmlAgilityPack.xml
├── Net40-client
│ ├── HtmlAgilityPack.dll
│ ├── HtmlAgilityPack.pdb
│ └── HtmlAgilityPack.xml
├── Net40
│ ├── HtmlAgilityPack.XML
│ ├── HtmlAgilityPack.dll
│ └── HtmlAgilityPack.pdb
├── Net45
│ ├── HtmlAgilityPack.XML
│ ├── HtmlAgilityPack.dll
│ └── HtmlAgilityPack.pdb
├── NetCore45
│ ├── HtmlAgilityPack.dll
│ ├── HtmlAgilityPack.pdb
│ ├── HtmlAgilityPack.pri
│ └── HtmlAgilityPack.xml
├── portable-net45+netcore45+wp8+MonoAndroid+MonoTouch
│ ├── HtmlAgilityPack.dll
│ └── HtmlAgilityPack.pdb
├── portable-net45+netcore45+wpa81+wp8+MonoAndroid+MonoTouch
│ ├── HtmlAgilityPack.dll
│ └── HtmlAgilityPack.pdb
├── sl3-wp
│ └── _._
├── sl4
│ ├── HtmlAgilityPack.XML
│ ├── HtmlAgilityPack.dll
│ └── HtmlAgilityPack.pdb
└── sl5
│ ├── HtmlAgilityPack.XML
│ ├── HtmlAgilityPack.dll
│ └── HtmlAgilityPack.pdb
└── readme.txt
/.gitignore:
--------------------------------------------------------------------------------
1 | *.suo
2 | *.user
3 | *.sln.docstates
4 |
5 | *.psess
6 | *.vsp
7 | *.vspx
8 |
9 | [Dd]ebug/
10 | [Rr]elease/
11 | x64/
12 | build/
13 | [Bb]in/
14 | [Oo]bj/
15 |
16 | [Tt]est[Rr]esult*/
17 | [Bb]uild[Ll]og.*
18 |
19 | *_i.c
20 | *_p.c
21 | *.ilk
22 | *.meta
23 | *.obj
24 | *.pch
25 | *.pdb
26 | *.pgc
27 | *.pgd
28 | *.rsp
29 | *.sbr
30 | *.tlb
31 | *.tli
32 | *.tlh
33 | *.tmp
34 | *.tmp_proj
35 | *.log
36 | *.vspscc
37 | *.vssscc
38 | .builds
39 | *.pidb
40 | *.log
41 | *.scc
42 |
43 | Thumbs.db
44 | ehthumbs.db
45 | Desktop.ini
46 | NUSGrabberGUI/obj/
47 | .vs
--------------------------------------------------------------------------------
/CHANGELOG.txt:
--------------------------------------------------------------------------------
1 | Changelog for NEW-NUSGrabberGUI
2 |
3 | TODO:
4 | + Added more languages (mostly from Google Translate...)
5 |
6 | 0.92 beta
7 | - Actually updated the version number this time.
8 | - Removed unneeded space before the contributors line in the "Settings/About" dialog.
9 |
10 | 0.91 beta
11 | - Fixed grammar and added new ways to format it.
12 | - Added title to prompt to ask the user where ckey.bin is located at.
13 | - Added contributors in "Settings/About" dialog.
14 | - Updated wiiu_versionlist.txt.
15 | - Added the .exe trying to rename itself back to normal after an attempt to rename the .exe to an unsupported name (breaks updates).
16 |
17 | 0.902 beta
18 | - Removed the ability to rename the main .exe to "NUtSGrabberGUI.exe" or "DeezNUSGrabberGUI.exe" in order to put the program in debug mode. Why did I let someone talk me into doing that?
19 | - Fixed link to dropbox in message box that appears when an update fails.
20 | - Fixed bug with LanguageString; the value was trimmed, but was never set back to the value again, making it useless.
21 | - Updated project to work with Visual Studio 2017.
22 |
23 | 0.901 beta
24 | - Added actual language support.
25 | - Changed dropbox link because the public folder is no longer functional.
26 |
27 | 0.90 beta
28 | - Fixed a potential bug with the internal version lists - it now counts how many there are to determine if it's already been loaded or not.
29 | - Fixed a bug with HTML parsing - was not being taken out.
30 | - Removed MSVCR120.DLL and MSVCP140.DLL, as they are not compatable with all systems.
31 | - Added preliminary support for languages.
32 | - Fixed a typo in the region settings text.
33 | - Fixed a bug when shutting down in the debug log.
34 | - Merged a hotfix from "Paul-Roesink" for the unexpected reorganization of "wiiubrew.org/wiki/Title_database".
35 |
36 | 0.89 beta
37 | - Updated NUSGrabber to the latest version, replacing the hacked one with a real one by crediar.
38 |
39 | 0.88 beta
40 | - Fixed an issue with the region not being saved internally for each title, preventing exporting to the debug log.
41 | - Full title support has been increased, but not fully implimented. Downloading works, but decryption is still in progress.
42 |
43 | 0.87 beta
44 | - Added the ability to export a title and it's full description to the debug log.
45 | - Fixed a bug reported by kavid - Japanese titles don't populate the list when JPN is selected.
46 | - Fixed a bug when switching regions - Titles weren't reloading properly.
47 | - Hopefully fixed a bug that made the UI not disable.
48 |
49 | 0.86 beta
50 | - Added a Help/FAQ button in the settings.
51 | - Expanded the main window of the app to include the Title ID of a selected title.
52 | - Added the ability to search by Title ID. To search, search only by the last 8 hex values (An example: 10115E00).
53 | - Fixed some spelling issues. Why does no one notice/tell me about these things?!
54 |
55 | 0.85 beta
56 | - Added project to GitHub!
57 | - Updated NUSGrabber to a hacked version (by DaBlackDeath) designed to support the new protocol Nintendo has implemented.
58 | - Added option to switch between hacked version and normal version of NUSGrabber.
59 | - Fixed a bug with switching pages not disabling UI when performing tasks.
60 | - Fixed a bug with incomplete downloads not being detected.
61 | - Fixed a bug with already downloaded titles and overwriting them properly (without destroying user data).
62 | - Changed some wording to better fit what's actually going on.
63 | - LibWiiSharp is now debug protected and automatically turns off when you exit the program.
64 | - Fixed a bug with multiple calls to the main fourm writing usless data in the debug log.
65 |
66 | 0.84 beta
67 | - Added more exit code interpretation to detect more errors when running NUSGrabber.
68 | - Added more comments for others to understand the code better once it's open source.
69 |
70 | 0.83 beta
71 | - Hopefully fixed a bug reported by hama - NUSGrabber was not being detected properly on some systems on download start. It now waits 2 seconds before processing.
72 | - Added exit code interpretation to hopefully detect when C++ is not installed.
73 |
74 | 0.82 beta
75 | - Fixed a bug reported by supermalloch when multi-tasking - Separated (internally) NUSGrabber and CDecrypt.
76 |
77 | 0.81 beta
78 | - Removed the annoying "&" in the description from parsed HTML.
79 | - Re-re-fixed (hopefully) yet another part of the bug "Title not found." If it doesn't work past this, then use the archived version in the settings.
80 | - Added a new feature that allows the program to cleanup resources after it exits. You can choose to disable this in the settings.
81 | - Program now safely removes files, as well as forcing others (like read-only ones) to be normal before deletion.
82 |
83 | 0.8 beta
84 | - Re-fixed another part of the bug with the assumed file path.
85 | - Fixed another popular bug "Unable to set directory"; the file path was being amended, not set.
86 |
87 | 0.79 beta
88 | - Fixed the popular bug "Title not found." with every download; the assumed file path was wrong.
89 | - Fixed a bug reported by markehmus - Versions weren't being cleared out when searching for a title that doesn't exist.
90 | - Fixed a bug where if there was no internet, the reload button would NOT be displayed.
91 | - Provided more documentation in the code in prep for making the code public.
92 |
93 | 0.78 beta
94 | - Made the folder selection dialog auto-set its starting path based on the current working directory.
95 | - Fixed a bug with decryption not setting the current working path back to normal.
96 | - Fixed a bug with auto-decryption not setting the correct working path.
97 | - Fixed a minor bug with the update text.
98 | - Added a progress bar for the embedded NUSGrabber, which still isn't useful to the public yet.
99 |
100 | 0.77 beta
101 | - Added an option to use an archived version of the title database instead of the latest.
102 | - Fixed some minor bugs.
103 | - Limited the view down to your specific region.
104 |
105 | 0.76 beta
106 | - Added a new method of connecting to Nintendo's NUS, by use of a modified libWiiSharp.
107 | - Added an option to use the new method or stick with the original (NUSGrabber commandline)
108 | - Fixed an unhandled exception with having no internet when loading titles.
109 |
110 | 0.75 beta
111 | - Added MSVCP140.dll, which is needed by NUSGrabber.
112 |
113 | 0.74 beta
114 | - Fixed a bug reported by Nym5 - CDecrypt needed MSVCR120.dll, which is not pre-installed on some systems.
115 | - Added ability to watch for file changes while downloading and report what file is downloading in the GUI.
116 |
117 | 0.73 beta (private)
118 | - Removed locale requirement. Now checks for specific files created by NUSGrabber to determine status.
119 | - Added option to load titles on start.
120 | - Errors while downloading are now more descriptive about the problem.
121 | - Cleaned up decryption code to start decryption faster.
122 |
123 | 0.72 beta
124 | - Using LINQ to iterate through locale now, making it easier to add new locales.
125 | - Added more locale updates.
126 | - Added regions to help pick through code.
127 | - Added a cleanup script to get rid of files that are unused at end of program. (WARNING: This will delete the log file if you switch back to standard mode, so rename your log file if you want to keep it!)
128 |
129 | 0.71 beta
130 | - Tweaked code to be more fluid and meaningful.
131 | - Fixed debug log overwriting itself every time it writes.
132 |
133 | 0.7 beta
134 | - Added debug logs.
135 | - Created a changelog, now that the program is mostly stable.
136 |
--------------------------------------------------------------------------------
/NUSGrabberGUI.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 14
4 | VisualStudioVersion = 14.0.24720.0
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NUSGrabberGUI", "NUSGrabberGUI\NUSGrabberGUI.csproj", "{759B9695-7DBE-4964-8968-8713435ECA1E}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Release|Any CPU = Release|Any CPU
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {759B9695-7DBE-4964-8968-8713435ECA1E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15 | {759B9695-7DBE-4964-8968-8713435ECA1E}.Debug|Any CPU.Build.0 = Debug|Any CPU
16 | {759B9695-7DBE-4964-8968-8713435ECA1E}.Release|Any CPU.ActiveCfg = Release|Any CPU
17 | {759B9695-7DBE-4964-8968-8713435ECA1E}.Release|Any CPU.Build.0 = Release|Any CPU
18 | EndGlobalSection
19 | GlobalSection(SolutionProperties) = preSolution
20 | HideSolutionNode = FALSE
21 | EndGlobalSection
22 | EndGlobal
23 |
--------------------------------------------------------------------------------
/NUSGrabberGUI/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 | USA
21 |
22 |
23 | False
24 |
25 |
26 | True
27 |
28 |
29 | False
30 |
31 |
32 | True
33 |
34 |
35 | False
36 |
37 |
38 | False
39 |
40 |
41 | True
42 |
43 |
44 | False
45 |
46 |
47 | en
48 |
49 |
50 |
51 |
52 |
53 |
54 | beta
55 |
56 |
57 | 92
58 |
59 |
60 |
61 |
62 |
--------------------------------------------------------------------------------
/NUSGrabberGUI/CertificateChain.cs:
--------------------------------------------------------------------------------
1 | /* This file is part of libWiiSharp
2 | * Copyright (C) 2009 Leathl
3 | *
4 | * libWiiSharp is free software: you can redistribute it and/or
5 | * modify it under the terms of the GNU General Public License as published
6 | * by the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * libWiiSharp is distributed in the hope that it will be
10 | * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
11 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 |
18 | using System;
19 | using System.IO;
20 | using System.Security.Cryptography;
21 |
22 | namespace libWiiSharp
23 | {
24 | public class CertificateChain : IDisposable
25 | {
26 | private const string certCaHash = "5B7D3EE28706AD8DA2CBD5A6B75C15D0F9B6F318";
27 | private const string certCpHash = "6824D6DA4C25184F0D6DAF6EDB9C0FC57522A41C";
28 | private const string certXsHash = "09787045037121477824BC6A3E5E076156573F8A";
29 | private SHA1 sha = SHA1.Create();
30 | private bool[] certsComplete = new bool[3];
31 |
32 | private byte[] certCa = new byte[0x400];
33 | private byte[] certCp = new byte[0x300];
34 | private byte[] certXs = new byte[0x300];
35 |
36 | ///
37 | /// If false, the Certificate Chain is not complete (i.e. at least one certificate is missing).
38 | ///
39 | public bool CertsComplete { get { return (certsComplete[0] && certsComplete[1] && certsComplete[2]); } }
40 |
41 | #region IDisposable Members
42 | private bool isDisposed = false;
43 |
44 | ~CertificateChain()
45 | {
46 | Dispose(false);
47 | }
48 |
49 | public void Dispose()
50 | {
51 | Dispose(true);
52 | GC.SuppressFinalize(this);
53 | }
54 |
55 | protected virtual void Dispose(bool disposing)
56 | {
57 | if (disposing && !isDisposed)
58 | {
59 | sha.Clear();
60 | sha = null;
61 |
62 | certsComplete = null;
63 | certCa = null;
64 | certCp = null;
65 | certXs = null;
66 | }
67 |
68 | isDisposed = true;
69 | }
70 | #endregion
71 |
72 | #region Public Functions
73 | ///
74 | /// Loads a cert file.
75 | ///
76 | ///
77 | ///
78 | public static CertificateChain Load(string pathToCert)
79 | {
80 | return Load(File.ReadAllBytes(pathToCert));
81 | }
82 |
83 | ///
84 | /// Loads a cert file.
85 | ///
86 | ///
87 | ///
88 | public static CertificateChain Load(byte[] certFile)
89 | {
90 | CertificateChain c = new CertificateChain();
91 | MemoryStream ms = new MemoryStream(certFile);
92 |
93 | try { c.parseCert(ms); }
94 | catch { ms.Dispose(); throw; }
95 |
96 | ms.Dispose();
97 | return c;
98 | }
99 |
100 | ///
101 | /// Loads a cert file.
102 | ///
103 | ///
104 | ///
105 | public static CertificateChain Load(Stream cert)
106 | {
107 | CertificateChain c = new CertificateChain();
108 | c.parseCert(cert);
109 | return c;
110 | }
111 |
112 | ///
113 | /// Grabs certificates from Ticket and Tmd.
114 | /// Ticket and Tmd must contain certs! (They do when they're downloaded from NUS!)
115 | ///
116 | ///
117 | ///
118 | ///
119 | public static CertificateChain FromTikTmd(string pathToTik, string pathToTmd)
120 | {
121 | return FromTikTmd(File.ReadAllBytes(pathToTik), File.ReadAllBytes(pathToTmd));
122 | }
123 |
124 | ///
125 | /// Grabs certificates from Ticket and Tmd.
126 | /// Ticket and Tmd must contain certs! (They do when they're downloaded from NUS!)
127 | ///
128 | ///
129 | ///
130 | ///
131 | public static CertificateChain FromTikTmd(string pathToTik, byte[] tmdFile)
132 | {
133 | return FromTikTmd(File.ReadAllBytes(pathToTik), tmdFile);
134 | }
135 |
136 | ///
137 | /// Grabs certificates from Ticket and Tmd.
138 | /// Ticket and Tmd must contain certs! (They do when they're downloaded from NUS!)
139 | ///
140 | ///
141 | ///
142 | ///
143 | public static CertificateChain FromTikTmd(byte[] tikFile, byte[] tmdFile)
144 | {
145 | CertificateChain c = new CertificateChain();
146 | MemoryStream ms = new MemoryStream(tikFile);
147 |
148 | try { c.grabFromTik(ms); }
149 | catch { ms.Dispose(); throw; }
150 |
151 | ms = new MemoryStream(tmdFile);
152 |
153 | try { c.grabFromTmd(ms); }
154 | catch { ms.Dispose(); throw; }
155 |
156 | ms.Dispose();
157 |
158 | if (!c.CertsComplete) throw new Exception("Couldn't locate all certs!");
159 |
160 | return c;
161 | }
162 |
163 | ///
164 | /// Grabs certificates from Ticket and Tmd.
165 | /// Ticket and Tmd must contain certs! (They do when they're downloaded from NUS!)
166 | ///
167 | ///
168 | ///
169 | ///
170 | public static CertificateChain FromTikTmd(Stream tik, Stream tmd)
171 | {
172 | CertificateChain c = new CertificateChain();
173 | c.grabFromTik(tik);
174 | c.grabFromTmd(tmd);
175 | return c;
176 | }
177 |
178 |
179 |
180 | ///
181 | /// Loads a cert file.
182 | ///
183 | ///
184 | public void LoadFile(string pathToCert)
185 | {
186 | LoadFile(File.ReadAllBytes(pathToCert));
187 | }
188 |
189 | ///
190 | /// Loads a cert file.
191 | ///
192 | ///
193 | public void LoadFile(byte[] certFile)
194 | {
195 | MemoryStream ms = new MemoryStream(certFile);
196 |
197 | try { parseCert(ms); }
198 | catch { ms.Dispose(); throw; }
199 |
200 | ms.Dispose();
201 | }
202 |
203 | ///
204 | /// Loads a cert file.
205 | ///
206 | ///
207 | public void LoadFile(Stream cert)
208 | {
209 | parseCert(cert);
210 | }
211 |
212 | ///
213 | /// Grabs certificates from Ticket and Tmd.
214 | /// Ticket and Tmd must contain certs! (They do when they're downloaded from NUS!)
215 | ///
216 | ///
217 | ///
218 | ///
219 | public void LoadFromTikTmd(string pathToTik, string pathToTmd)
220 | {
221 | LoadFromTikTmd(File.ReadAllBytes(pathToTik), File.ReadAllBytes(pathToTmd));
222 | }
223 |
224 | ///
225 | /// Grabs certificates from Ticket and Tmd.
226 | /// Ticket and Tmd must contain certs! (They do when they're downloaded from NUS!)
227 | ///
228 | ///
229 | ///
230 | ///
231 | public void LoadFromTikTmd(string pathToTik, byte[] tmdFile)
232 | {
233 | LoadFromTikTmd(File.ReadAllBytes(pathToTik), tmdFile);
234 | }
235 |
236 | ///
237 | /// Grabs certificates from Ticket and Tmd.
238 | /// Ticket and Tmd must contain certs! (They do when they're downloaded from NUS!)
239 | ///
240 | ///
241 | ///
242 | public void LoadFromTikTmd(byte[] tikFile, byte[] tmdFile)
243 | {
244 | MemoryStream ms = new MemoryStream(tikFile);
245 |
246 | try { grabFromTik(ms); }
247 | catch { ms.Dispose(); throw; }
248 |
249 | ms = new MemoryStream(tmdFile);
250 |
251 | try { grabFromTmd(ms); }
252 | catch { ms.Dispose(); throw; }
253 |
254 | ms.Dispose();
255 |
256 | if (!CertsComplete) throw new Exception("Couldn't locate all certs!");
257 | }
258 |
259 | ///
260 | /// Grabs certificates from Ticket and Tmd.
261 | /// Ticket and Tmd must contain certs! (They do when they're downloaded from NUS!)
262 | ///
263 | ///
264 | ///
265 | public void LoadFromTikTmd(Stream tik, Stream tmd)
266 | {
267 | grabFromTik(tik);
268 | grabFromTmd(tmd);
269 | }
270 |
271 |
272 |
273 | ///
274 | /// Saves the Certificate Chain.
275 | ///
276 | ///
277 | public void Save(string savePath)
278 | {
279 | if (File.Exists(savePath)) File.Delete(savePath);
280 |
281 | using (FileStream fs = new FileStream(savePath, FileMode.Create))
282 | writeToStream(fs);
283 | }
284 |
285 | ///
286 | /// Returns the Certificate Chain as a memory stream.
287 | ///
288 | ///
289 | public MemoryStream ToMemoryStream()
290 | {
291 | MemoryStream ms = new MemoryStream();
292 |
293 | try { writeToStream(ms); }
294 | catch { ms.Dispose(); throw; }
295 |
296 | return ms;
297 | }
298 |
299 | ///
300 | /// Returns the Certificate Chain as a byte array.
301 | ///
302 | ///
303 | public byte[] ToByteArray()
304 | {
305 | MemoryStream ms = new MemoryStream();
306 |
307 | try { writeToStream(ms); }
308 | catch { ms.Dispose(); throw; }
309 |
310 | byte[] res = ms.ToArray();
311 | ms.Dispose();
312 | return res;
313 | }
314 | #endregion
315 |
316 | #region Private Functions
317 | private void writeToStream(Stream writeStream)
318 | {
319 | fireDebug("Writing Certificate Chain...");
320 |
321 | if (!CertsComplete)
322 | { fireDebug(" Certificate Chain incomplete..."); throw new Exception("At least one certificate is missing!"); }
323 |
324 | writeStream.Seek(0, SeekOrigin.Begin);
325 |
326 | fireDebug(" Writing Certificate CA... (Offset: 0x{0})", writeStream.Position.ToString("x8"));
327 | writeStream.Write(certCa, 0, certCa.Length);
328 |
329 | fireDebug(" Writing Certificate CP... (Offset: 0x{0})", writeStream.Position.ToString("x8"));
330 | writeStream.Write(certCp, 0, certCp.Length);
331 |
332 | fireDebug(" Writing Certificate XS... (Offset: 0x{0})", writeStream.Position.ToString("x8"));
333 | writeStream.Write(certXs, 0, certXs.Length);
334 |
335 | fireDebug("Writing Certificate Chain Finished...");
336 | }
337 |
338 | private void parseCert(Stream certFile)
339 | {
340 | fireDebug("Parsing Certificate Chain...");
341 | int off = 0;
342 |
343 | for (int i = 0; i < 3; i++)
344 | {
345 | fireDebug(" Scanning at Offset 0x{0}:", off.ToString("x8"));
346 |
347 | try
348 | {
349 | certFile.Seek(off, SeekOrigin.Begin);
350 | byte[] temp = new byte[0x400];
351 |
352 | certFile.Read(temp, 0, temp.Length);
353 |
354 | fireDebug(" Checking for Certificate CA...");
355 | if (isCertCa(temp) && !certsComplete[1])
356 | { fireDebug(" Certificate CA detected..."); certCa = temp; certsComplete[1] = true; off += 0x400; continue; }
357 |
358 | fireDebug(" Checking for Certificate CP...");
359 | if (isCertCp(temp) && !certsComplete[2])
360 | { fireDebug(" Certificate CP detected..."); Array.Resize(ref temp, 0x300); certCp = temp; certsComplete[2] = true; off += 0x300; continue; }
361 |
362 | fireDebug(" Checking for Certificate XS...");
363 | if (isCertXs(temp) && !certsComplete[0])
364 | { fireDebug(" Certificate XS detected..."); Array.Resize(ref temp, 0x300); certXs = temp; certsComplete[0] = true; off += 0x300; continue; }
365 | }
366 | catch (Exception ex) { fireDebug("Error: {0}", ex.Message); }
367 |
368 | off += 0x300;
369 | }
370 |
371 | if (!CertsComplete)
372 | { fireDebug(" Couldn't locate all Certificates..."); throw new Exception("Couldn't locate all certs!"); }
373 |
374 | fireDebug("Parsing Certificate Chain Finished...");
375 | }
376 |
377 | private void grabFromTik(Stream tik)
378 | {
379 | fireDebug("Scanning Ticket for Certificates...");
380 | int off = 676;
381 |
382 | for (int i = 0; i < 3; i++)
383 | {
384 | fireDebug(" Scanning at Offset 0x{0}:", off.ToString("x8"));
385 |
386 | try
387 | {
388 | tik.Seek(off, SeekOrigin.Begin);
389 | byte[] temp = new byte[0x400];
390 |
391 | tik.Read(temp, 0, temp.Length);
392 |
393 | fireDebug(" Checking for Certificate CA...");
394 | if (isCertCa(temp) && !certsComplete[1])
395 | { fireDebug(" Certificate CA detected..."); certCa = temp; certsComplete[1] = true; off += 0x400; continue; }
396 |
397 | fireDebug(" Checking for Certificate CP...");
398 | if (isCertCp(temp) && !certsComplete[2])
399 | { fireDebug(" Certificate CP detected..."); Array.Resize(ref temp, 0x300); certCp = temp; certsComplete[2] = true; off += 0x300; continue; }
400 |
401 | fireDebug(" Checking for Certificate XS...");
402 | if (isCertXs(temp) && !certsComplete[0])
403 | { fireDebug(" Certificate XS detected..."); Array.Resize(ref temp, 0x300); certXs = temp; certsComplete[0] = true; off += 0x300; continue; }
404 | }
405 | catch { }
406 |
407 | off += 0x300;
408 | }
409 |
410 | fireDebug("Scanning Ticket for Certificates Finished...");
411 | }
412 |
413 | private void grabFromTmd(Stream tmd)
414 | {
415 | fireDebug("Scanning TMD for Certificates...");
416 |
417 | byte[] temp = new byte[2];
418 | tmd.Seek(478, SeekOrigin.Begin);
419 | tmd.Read(temp, 0, 2);
420 |
421 | int numContents = Shared.Swap(BitConverter.ToUInt16(temp, 0));
422 | int off = 484 + numContents * 36;
423 |
424 | for (int i = 0; i < 3; i++)
425 | {
426 | fireDebug(" Scanning at Offset 0x{0}:", off.ToString("x8"));
427 |
428 | try
429 | {
430 | tmd.Seek(off, SeekOrigin.Begin);
431 | temp = new byte[0x400];
432 |
433 | tmd.Read(temp, 0, temp.Length);
434 |
435 | fireDebug(" Checking for Certificate CA...");
436 | if (isCertCa(temp) && !certsComplete[1])
437 | { fireDebug(" Certificate CA detected..."); certCa = temp; certsComplete[1] = true; off += 0x400; continue; }
438 |
439 | fireDebug(" Checking for Certificate CP...");
440 | if (isCertCp(temp) && !certsComplete[2])
441 | { fireDebug(" Certificate CP detected..."); Array.Resize(ref temp, 0x300); certCp = temp; certsComplete[2] = true; off += 0x300; continue; }
442 |
443 | fireDebug(" Checking for Certificate XS...");
444 | if (isCertXs(temp) && !certsComplete[0])
445 | { fireDebug(" Certificate XS detected..."); Array.Resize(ref temp, 0x300); certXs = temp; certsComplete[0] = true; off += 0x300; continue; }
446 | }
447 | catch { }
448 |
449 | off += 0x300;
450 | }
451 |
452 | fireDebug("Scanning TMD for Certificates Finished...");
453 | }
454 |
455 | private bool isCertXs(byte[] part)
456 | {
457 | if (part.Length < 0x300) return false;
458 | else if (part.Length > 0x300) Array.Resize(ref part, 0x300);
459 |
460 | if (part[0x184] == 'X' && part[0x185] == 'S')
461 | {
462 | byte[] newHash = sha.ComputeHash(part);
463 | byte[] oldHash = Shared.HexStringToByteArray(certXsHash);
464 |
465 | if (Shared.CompareByteArrays(newHash, oldHash)) return true;
466 | }
467 |
468 | return false;
469 | }
470 |
471 | private bool isCertCa(byte[] part)
472 | {
473 | if (part.Length < 0x400) return false;
474 | else if (part.Length > 0x400) Array.Resize(ref part, 0x400);
475 |
476 | if (part[0x284] == 'C' && part[0x285] == 'A')
477 | {
478 | byte[] newHash = sha.ComputeHash(part);
479 | byte[] oldHash = Shared.HexStringToByteArray(certCaHash);
480 |
481 | if (Shared.CompareByteArrays(newHash, oldHash)) return true;
482 | }
483 |
484 | return false;
485 | }
486 |
487 | private bool isCertCp(byte[] part)
488 | {
489 | if (part.Length < 0x300) return false;
490 | else if (part.Length > 0x300) Array.Resize(ref part, 0x300);
491 |
492 | if (part[0x184] == 'C' && part[0x185] == 'P')
493 | {
494 | byte[] newHash = sha.ComputeHash(part);
495 | byte[] oldHash = Shared.HexStringToByteArray(certCpHash);
496 |
497 | if (Shared.CompareByteArrays(newHash, oldHash)) return true;
498 | }
499 |
500 | return false;
501 | }
502 | #endregion
503 |
504 | #region Events
505 | ///
506 | /// Fires debugging messages. You may write them into a log file or log textbox.
507 | ///
508 | public event EventHandler Debug;
509 |
510 | private void fireDebug(string debugMessage, params object[] args)
511 | {
512 | Debug?.Invoke(new object(), new MessageEventArgs(string.Format(debugMessage, args)));
513 | }
514 | #endregion
515 | }
516 | }
517 |
--------------------------------------------------------------------------------
/NUSGrabberGUI/CommonKey.cs:
--------------------------------------------------------------------------------
1 | namespace libWiiSharp
2 | {
3 | public class CommonKey
4 | {
5 | private static byte[] wiiuKey = new byte[16];
6 | public static byte[] GetStandardKey()
7 | {
8 | if (!System.IO.File.Exists(NUSGrabberGUI.Properties.Settings.Default.CommonKeyPath))
9 | {
10 | System.Windows.Forms.OpenFileDialog FileDialog = new System.Windows.Forms.OpenFileDialog();
11 | FileDialog.Filter = "WiiU Common Key|*.bin";
12 | FileDialog.FileName = "ckey.bin";
13 | if (FileDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
14 | {
15 | NUSGrabberGUI.Properties.Settings.Default.CommonKeyPath = FileDialog.FileName;
16 | NUSGrabberGUI.Properties.Settings.Default.Save();
17 | }
18 | else return null;
19 | }
20 | try
21 | {
22 | System.IO.FileStream ckey = System.IO.File.OpenRead(NUSGrabberGUI.Properties.Settings.Default.CommonKeyPath);
23 | if (ckey.Length == 16)
24 | try { ckey.Read(wiiuKey, 0, 16); }
25 | catch
26 | {
27 | System.Windows.Forms.MessageBox.Show("Unable to parse saved common key. Make sure it is valid!");
28 | return null;
29 | }
30 | else
31 | {
32 | System.Windows.Forms.MessageBox.Show("Your common key is not valid! Please make sure it truly is the common key.");
33 | return null;
34 | }
35 | }
36 | catch
37 | {
38 | System.Windows.Forms.MessageBox.Show("Unable to open saved common key. Make sure it is readable and still there!");
39 | return null;
40 | }
41 | return wiiuKey;
42 | }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/NUSGrabberGUI/ContentIndices.cs:
--------------------------------------------------------------------------------
1 | /* This file is part of libWiiSharp
2 | * Copyright (C) 2009 Leathl
3 | *
4 | * libWiiSharp is free software: you can redistribute it and/or
5 | * modify it under the terms of the GNU General Public License as published
6 | * by the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * libWiiSharp is distributed in the hope that it will be
10 | * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
11 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 |
18 | using System;
19 |
20 | namespace libWiiSharp
21 | {
22 | internal struct ContentIndices : IComparable
23 | {
24 | private int index;
25 | private int contentIndex;
26 |
27 | public int Index { get { return index; } }
28 | public int ContentIndex { get { return contentIndex; } }
29 |
30 | public ContentIndices(int index, int contentIndex)
31 | {
32 | this.index = index;
33 | this.contentIndex = contentIndex;
34 | }
35 |
36 | public int CompareTo(object obj)
37 | {
38 | if (obj is ContentIndices) return contentIndex.CompareTo(((ContentIndices)obj).contentIndex);
39 | else throw new ArgumentException();
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/NUSGrabberGUI/Form1.Designer.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Drawing;
3 | using System.Windows.Forms;
4 | using System.ComponentModel;
5 |
6 | namespace NUSGrabberGUI
7 | {
8 | partial class NUSGrabberForm
9 | {
10 | ///
11 | /// Required designer variable.
12 | ///
13 | private IContainer components = null;
14 |
15 | ///
16 | /// Clean up any resources being used.
17 | ///
18 | /// true if managed resources should be disposed; otherwise, false.
19 | protected override void Dispose(bool disposing)
20 | {
21 | if (disposing && (components != null))
22 | {
23 | components.Dispose();
24 | }
25 | base.Dispose(disposing);
26 | }
27 |
28 | #region Windows Form Designer generated code
29 |
30 | ///
31 | /// Required method for Designer support - do not modify
32 | /// the contents of this method with the code editor.
33 | ///
34 | private void InitializeComponent()
35 | {
36 | NUSTabs = new TabControl();
37 | GameUpdateTab = new TabPage();
38 | GUExportButton = new Button();
39 | GUTitleIDLabel = new Label();
40 | NUSGrabberProgress = new ProgressBar();
41 | GUVersionList = new ListBox();
42 | GUVersionsLabel = new Label();
43 | GUTitlesLabel = new Label();
44 | GUSearchLabel = new Label();
45 | GUSearchBox = new TextBox();
46 | GUTitleList = new ListBox();
47 | SystemTab = new TabPage();
48 | STExportButton = new Button();
49 | STTitleIDLabel = new Label();
50 | STVersionList = new ListBox();
51 | STVersionsLabel = new Label();
52 | STTitlesLabel = new Label();
53 | STSearchLabel = new Label();
54 | STSearchBox = new TextBox();
55 | STTitleList = new ListBox();
56 | FullListTab = new TabPage();
57 | FTExportButton = new Button();
58 | FTTitleIDLabel = new Label();
59 | FTTitlesLabel = new Label();
60 | FTSearchLabel = new Label();
61 | FTSearchBox = new TextBox();
62 | FTTitleList = new ListBox();
63 | DownloadButton = new Button();
64 | UpdateButton = new Button();
65 | AboutButton = new Button();
66 | ReloadButton = new Button();
67 | DecryptButton = new Button();
68 | OpenFileDialog = new OpenFileDialog();
69 | EmbedNUSGrabber = new BackgroundWorker();
70 | NUSTabs.SuspendLayout();
71 | GameUpdateTab.SuspendLayout();
72 | SystemTab.SuspendLayout();
73 | FullListTab.SuspendLayout();
74 | SuspendLayout();
75 | //
76 | // NUSTabs
77 | //
78 | NUSTabs.Controls.Add(GameUpdateTab);
79 | NUSTabs.Controls.Add(SystemTab);
80 | NUSTabs.Controls.Add(FullListTab);
81 | NUSTabs.Location = new Point(12, 12);
82 | NUSTabs.Name = "NUSTabs";
83 | NUSTabs.SelectedIndex = 0;
84 | NUSTabs.Size = new Size(360, 283);
85 | NUSTabs.TabIndex = 0;
86 | NUSTabs.SelectedIndexChanged += new EventHandler(NUSTabs_IndexChanged);
87 | //
88 | // GameUpdateTab
89 | //
90 | GameUpdateTab.BackColor = Color.LightGreen;
91 | GameUpdateTab.Controls.Add(GUExportButton);
92 | GameUpdateTab.Controls.Add(GUTitleIDLabel);
93 | GameUpdateTab.Controls.Add(NUSGrabberProgress);
94 | GameUpdateTab.Controls.Add(GUVersionList);
95 | GameUpdateTab.Controls.Add(GUVersionsLabel);
96 | GameUpdateTab.Controls.Add(GUTitlesLabel);
97 | GameUpdateTab.Controls.Add(GUSearchLabel);
98 | GameUpdateTab.Controls.Add(GUSearchBox);
99 | GameUpdateTab.Controls.Add(GUTitleList);
100 | GameUpdateTab.ForeColor = SystemColors.ControlText;
101 | GameUpdateTab.Location = new Point(4, 22);
102 | GameUpdateTab.Name = "GameUpdateTab";
103 | GameUpdateTab.Padding = new Padding(3);
104 | GameUpdateTab.Size = new Size(352, 257);
105 | GameUpdateTab.TabIndex = 0;
106 | GameUpdateTab.Text = "Game Updates";
107 | //
108 | // GUExportButton
109 | //
110 | GUExportButton.DialogResult = DialogResult.Cancel;
111 | GUExportButton.Enabled = false;
112 | GUExportButton.Location = new Point(172, 231);
113 | GUExportButton.Name = "GUExportButton";
114 | GUExportButton.Size = new Size(174, 23);
115 | GUExportButton.TabIndex = 8;
116 | GUExportButton.Text = "Export Title to Debug Log";
117 | GUExportButton.UseVisualStyleBackColor = true;
118 | GUExportButton.Visible = false;
119 | GUExportButton.Click += new EventHandler(GUExportButton_Click);
120 | //
121 | // GUTitleIDLabel
122 | //
123 | GUTitleIDLabel.AutoSize = true;
124 | GUTitleIDLabel.Location = new Point(9, 233);
125 | GUTitleIDLabel.Name = "GUTitleIDLabel";
126 | GUTitleIDLabel.Size = new Size(44, 13);
127 | GUTitleIDLabel.TabIndex = 7;
128 | GUTitleIDLabel.Text = "Title ID:";
129 | //
130 | // NUSGrabberProgress
131 | //
132 | NUSGrabberProgress.Location = new Point(56, 6);
133 | NUSGrabberProgress.Name = "NUSGrabberProgress";
134 | NUSGrabberProgress.Size = new Size(290, 20);
135 | NUSGrabberProgress.TabIndex = 6;
136 | NUSGrabberProgress.Visible = false;
137 | //
138 | // GUVersionList
139 | //
140 | GUVersionList.FormattingEnabled = true;
141 | GUVersionList.Location = new Point(289, 53);
142 | GUVersionList.Name = "GUVersionList";
143 | GUVersionList.Size = new Size(57, 173);
144 | GUVersionList.TabIndex = 5;
145 | //
146 | // GUVersionsLabel
147 | //
148 | GUVersionsLabel.AutoSize = true;
149 | GUVersionsLabel.Location = new Point(292, 37);
150 | GUVersionsLabel.Name = "GUVersionsLabel";
151 | GUVersionsLabel.Size = new Size(50, 13);
152 | GUVersionsLabel.TabIndex = 4;
153 | GUVersionsLabel.Text = "Versions:";
154 | //
155 | // GUTitlesLabel
156 | //
157 | GUTitlesLabel.AutoSize = true;
158 | GUTitlesLabel.Location = new Point(120, 37);
159 | GUTitlesLabel.Name = "GUTitlesLabel";
160 | GUTitlesLabel.Size = new Size(35, 13);
161 | GUTitlesLabel.TabIndex = 3;
162 | GUTitlesLabel.Text = "Titles:";
163 | //
164 | // GUSearchLabel
165 | //
166 | GUSearchLabel.AutoSize = true;
167 | GUSearchLabel.Location = new Point(6, 9);
168 | GUSearchLabel.Name = "GUSearchLabel";
169 | GUSearchLabel.Size = new Size(44, 13);
170 | GUSearchLabel.TabIndex = 2;
171 | GUSearchLabel.Text = "Search:";
172 | //
173 | // GUSearchBox
174 | //
175 | GUSearchBox.Location = new Point(56, 6);
176 | GUSearchBox.Name = "GUSearchBox";
177 | GUSearchBox.Size = new Size(290, 20);
178 | GUSearchBox.TabIndex = 1;
179 | GUSearchBox.TextChanged += new EventHandler(GUSearchBox_TextChanged);
180 | //
181 | // GUTitleList
182 | //
183 | GUTitleList.FormattingEnabled = true;
184 | GUTitleList.Location = new Point(6, 53);
185 | GUTitleList.Name = "GUTitleList";
186 | GUTitleList.Size = new Size(277, 173);
187 | GUTitleList.TabIndex = 0;
188 | GUTitleList.SelectedIndexChanged += new EventHandler(GUTitleList_SelectedIndexChanged);
189 | //
190 | // SystemTab
191 | //
192 | SystemTab.BackColor = Color.LightCoral;
193 | SystemTab.Controls.Add(STExportButton);
194 | SystemTab.Controls.Add(STTitleIDLabel);
195 | SystemTab.Controls.Add(STVersionList);
196 | SystemTab.Controls.Add(STVersionsLabel);
197 | SystemTab.Controls.Add(STTitlesLabel);
198 | SystemTab.Controls.Add(STSearchLabel);
199 | SystemTab.Controls.Add(STSearchBox);
200 | SystemTab.Controls.Add(STTitleList);
201 | SystemTab.Location = new Point(4, 22);
202 | SystemTab.Name = "SystemTab";
203 | SystemTab.Padding = new Padding(3);
204 | SystemTab.Size = new Size(352, 257);
205 | SystemTab.TabIndex = 1;
206 | SystemTab.Text = "System Titles";
207 | //
208 | // STExportButton
209 | //
210 | STExportButton.DialogResult = DialogResult.Cancel;
211 | STExportButton.Enabled = false;
212 | STExportButton.Location = new Point(172, 231);
213 | STExportButton.Name = "STExportButton";
214 | STExportButton.Size = new Size(174, 23);
215 | STExportButton.TabIndex = 13;
216 | STExportButton.Text = "Export Title to Debug Log";
217 | STExportButton.UseVisualStyleBackColor = true;
218 | STExportButton.Visible = false;
219 | STExportButton.Click += new EventHandler(STExportButton_Click);
220 | //
221 | // STTitleIDLabel
222 | //
223 | STTitleIDLabel.AutoSize = true;
224 | STTitleIDLabel.Location = new Point(9, 233);
225 | STTitleIDLabel.Name = "STTitleIDLabel";
226 | STTitleIDLabel.Size = new Size(44, 13);
227 | STTitleIDLabel.TabIndex = 12;
228 | STTitleIDLabel.Text = "Title ID:";
229 | //
230 | // STVersionList
231 | //
232 | STVersionList.FormattingEnabled = true;
233 | STVersionList.Location = new Point(272, 53);
234 | STVersionList.Name = "STVersionList";
235 | STVersionList.Size = new Size(74, 173);
236 | STVersionList.TabIndex = 11;
237 | //
238 | // STVersionsLabel
239 | //
240 | STVersionsLabel.AutoSize = true;
241 | STVersionsLabel.Location = new Point(285, 37);
242 | STVersionsLabel.Name = "STVersionsLabel";
243 | STVersionsLabel.Size = new Size(50, 13);
244 | STVersionsLabel.TabIndex = 10;
245 | STVersionsLabel.Text = "Versions:";
246 | //
247 | // STTitlesLabel
248 | //
249 | STTitlesLabel.AutoSize = true;
250 | STTitlesLabel.Location = new Point(111, 37);
251 | STTitlesLabel.Name = "STTitlesLabel";
252 | STTitlesLabel.Size = new Size(35, 13);
253 | STTitlesLabel.TabIndex = 9;
254 | STTitlesLabel.Text = "Titles:";
255 | //
256 | // STSearchLabel
257 | //
258 | STSearchLabel.AutoSize = true;
259 | STSearchLabel.Location = new Point(6, 9);
260 | STSearchLabel.Name = "STSearchLabel";
261 | STSearchLabel.Size = new Size(44, 13);
262 | STSearchLabel.TabIndex = 8;
263 | STSearchLabel.Text = "Search:";
264 | //
265 | // STSearchBox
266 | //
267 | STSearchBox.Location = new Point(56, 6);
268 | STSearchBox.Name = "STSearchBox";
269 | STSearchBox.Size = new Size(290, 20);
270 | STSearchBox.TabIndex = 7;
271 | STSearchBox.TextChanged += new EventHandler(STSearchBox_TextChanged);
272 | //
273 | // STTitleList
274 | //
275 | STTitleList.FormattingEnabled = true;
276 | STTitleList.Location = new Point(6, 53);
277 | STTitleList.Name = "STTitleList";
278 | STTitleList.Size = new Size(260, 173);
279 | STTitleList.TabIndex = 6;
280 | STTitleList.SelectedIndexChanged += new EventHandler(STTitleList_SelectedIndexChanged);
281 | //
282 | // FullListTab
283 | //
284 | FullListTab.BackColor = Color.Turquoise;
285 | FullListTab.Controls.Add(FTExportButton);
286 | FullListTab.Controls.Add(FTTitleIDLabel);
287 | FullListTab.Controls.Add(FTTitlesLabel);
288 | FullListTab.Controls.Add(FTSearchLabel);
289 | FullListTab.Controls.Add(FTSearchBox);
290 | FullListTab.Controls.Add(FTTitleList);
291 | FullListTab.Location = new Point(4, 22);
292 | FullListTab.Name = "FullListTab";
293 | FullListTab.Padding = new Padding(3);
294 | FullListTab.Size = new Size(352, 257);
295 | FullListTab.TabIndex = 2;
296 | FullListTab.Text = "Full Titles";
297 | //
298 | // FTExportButton
299 | //
300 | FTExportButton.DialogResult = DialogResult.Cancel;
301 | FTExportButton.Enabled = false;
302 | FTExportButton.Location = new Point(172, 231);
303 | FTExportButton.Name = "FTExportButton";
304 | FTExportButton.Size = new Size(174, 23);
305 | FTExportButton.TabIndex = 11;
306 | FTExportButton.Text = "Export Title to Debug Log";
307 | FTExportButton.UseVisualStyleBackColor = true;
308 | FTExportButton.Visible = false;
309 | FTExportButton.Click += new EventHandler(FTExportButton_Click);
310 | //
311 | // FTTitleIDLabel
312 | //
313 | FTTitleIDLabel.AutoSize = true;
314 | FTTitleIDLabel.Location = new Point(9, 233);
315 | FTTitleIDLabel.Name = "FTTitleIDLabel";
316 | FTTitleIDLabel.Size = new Size(44, 13);
317 | FTTitleIDLabel.TabIndex = 10;
318 | FTTitleIDLabel.Text = "Title ID:";
319 | //
320 | // FTTitlesLabel
321 | //
322 | FTTitlesLabel.AutoSize = true;
323 | FTTitlesLabel.Location = new Point(152, 37);
324 | FTTitlesLabel.Name = "FTTitlesLabel";
325 | FTTitlesLabel.Size = new Size(35, 13);
326 | FTTitlesLabel.TabIndex = 9;
327 | FTTitlesLabel.Text = "Titles:";
328 | //
329 | // FTSearchLabel
330 | //
331 | FTSearchLabel.AutoSize = true;
332 | FTSearchLabel.Location = new Point(6, 9);
333 | FTSearchLabel.Name = "FTSearchLabel";
334 | FTSearchLabel.Size = new Size(44, 13);
335 | FTSearchLabel.TabIndex = 8;
336 | FTSearchLabel.Text = "Search:";
337 | //
338 | // FTSearchBox
339 | //
340 | FTSearchBox.Location = new Point(56, 6);
341 | FTSearchBox.Name = "FTSearchBox";
342 | FTSearchBox.Size = new Size(290, 20);
343 | FTSearchBox.TabIndex = 7;
344 | FTSearchBox.TextChanged += new EventHandler(FTSearchBox_TextChanged);
345 | //
346 | // FTTitleList
347 | //
348 | FTTitleList.FormattingEnabled = true;
349 | FTTitleList.Location = new Point(6, 53);
350 | FTTitleList.Name = "FTTitleList";
351 | FTTitleList.Size = new Size(340, 173);
352 | FTTitleList.TabIndex = 6;
353 | FTTitleList.SelectedIndexChanged += new EventHandler(FTTitleList_SelectedIndexChanged);
354 | //
355 | // DownloadButton
356 | //
357 | DownloadButton.DialogResult = DialogResult.Cancel;
358 | DownloadButton.Enabled = false;
359 | DownloadButton.Location = new Point(300, 301);
360 | DownloadButton.Name = "DownloadButton";
361 | DownloadButton.Size = new Size(72, 23);
362 | DownloadButton.TabIndex = 3;
363 | DownloadButton.Text = "Download";
364 | DownloadButton.UseVisualStyleBackColor = true;
365 | DownloadButton.Click += new EventHandler(DownloadButton_Click);
366 | //
367 | // UpdateButton
368 | //
369 | UpdateButton.Enabled = false;
370 | UpdateButton.Location = new Point(72, 301);
371 | UpdateButton.Name = "UpdateButton";
372 | UpdateButton.Size = new Size(110, 23);
373 | UpdateButton.TabIndex = 4;
374 | UpdateButton.Text = "Update VersionList";
375 | UpdateButton.UseVisualStyleBackColor = true;
376 | UpdateButton.Click += new EventHandler(UpdateButton_Click);
377 | //
378 | // AboutButton
379 | //
380 | AboutButton.Enabled = false;
381 | AboutButton.Location = new Point(12, 301);
382 | AboutButton.Name = "AboutButton";
383 | AboutButton.Size = new Size(54, 23);
384 | AboutButton.TabIndex = 5;
385 | AboutButton.Text = "Settings";
386 | AboutButton.UseVisualStyleBackColor = true;
387 | AboutButton.Click += new EventHandler(AboutButton_Click);
388 | //
389 | // ReloadButton
390 | //
391 | ReloadButton.Font = new Font("Microsoft Sans Serif", 8.25F, FontStyle.Bold, GraphicsUnit.Point, ((byte)(0)));
392 | ReloadButton.Location = new Point(288, 10);
393 | ReloadButton.Name = "ReloadButton";
394 | ReloadButton.Size = new Size(82, 22);
395 | ReloadButton.TabIndex = 6;
396 | ReloadButton.Text = "Load Titles";
397 | ReloadButton.TextAlign = ContentAlignment.TopCenter;
398 | ReloadButton.UseVisualStyleBackColor = true;
399 | ReloadButton.Click += new EventHandler(ReloadButton_Click);
400 | //
401 | // DecryptButton
402 | //
403 | DecryptButton.Enabled = false;
404 | DecryptButton.Location = new Point(188, 301);
405 | DecryptButton.Name = "DecryptButton";
406 | DecryptButton.Size = new Size(106, 23);
407 | DecryptButton.TabIndex = 7;
408 | DecryptButton.Text = "Decrypt Download";
409 | DecryptButton.UseVisualStyleBackColor = true;
410 | DecryptButton.Click += new EventHandler(DecryptButton_Click);
411 | //
412 | // OpenFileDialog
413 | //
414 | OpenFileDialog.FileName = "ckey.bin";
415 | //
416 | // EmbedNUSGrabber
417 | //
418 | EmbedNUSGrabber.DoWork += new DoWorkEventHandler(EmbedNUSGrabber_Work);
419 | EmbedNUSGrabber.RunWorkerCompleted += new RunWorkerCompletedEventHandler(EmbedNUSGrabber_Done);
420 | //
421 | // NUSGrabberForm
422 | //
423 | AutoScaleDimensions = new SizeF(6F, 13F);
424 | AutoScaleMode = AutoScaleMode.Font;
425 | ClientSize = new Size(384, 336);
426 | Controls.Add(DecryptButton);
427 | Controls.Add(ReloadButton);
428 | Controls.Add(AboutButton);
429 | Controls.Add(UpdateButton);
430 | Controls.Add(DownloadButton);
431 | Controls.Add(NUSTabs);
432 | FormBorderStyle = FormBorderStyle.FixedSingle;
433 | Name = "NUSGrabberForm";
434 | ShowIcon = false;
435 | Text = "NEW-NUSGrabberGUI";
436 | NUSTabs.ResumeLayout(false);
437 | GameUpdateTab.ResumeLayout(false);
438 | GameUpdateTab.PerformLayout();
439 | SystemTab.ResumeLayout(false);
440 | SystemTab.PerformLayout();
441 | FullListTab.ResumeLayout(false);
442 | FullListTab.PerformLayout();
443 | ResumeLayout(false);
444 |
445 | }
446 |
447 | #endregion
448 |
449 | private TabControl NUSTabs;
450 | private TabPage GameUpdateTab;
451 | private ListBox GUVersionList;
452 | private Label GUVersionsLabel;
453 | private Label GUTitlesLabel;
454 | private Label GUSearchLabel;
455 | private TextBox GUSearchBox;
456 | private ListBox GUTitleList;
457 | private TabPage SystemTab;
458 | private TabPage FullListTab;
459 | private Button DownloadButton;
460 | private ListBox STVersionList;
461 | private Label STVersionsLabel;
462 | private Label STTitlesLabel;
463 | private Label STSearchLabel;
464 | private TextBox STSearchBox;
465 | private ListBox STTitleList;
466 | private Label FTTitlesLabel;
467 | private Label FTSearchLabel;
468 | private TextBox FTSearchBox;
469 | private ListBox FTTitleList;
470 | private Button UpdateButton;
471 | private Button AboutButton;
472 | private Button ReloadButton;
473 | private Button DecryptButton;
474 | private OpenFileDialog OpenFileDialog;
475 | private BackgroundWorker EmbedNUSGrabber;
476 | private ProgressBar NUSGrabberProgress;
477 | private Label GUTitleIDLabel;
478 | private Label STTitleIDLabel;
479 | private Label FTTitleIDLabel;
480 | private Button GUExportButton;
481 | private Button STExportButton;
482 | private Button FTExportButton;
483 | }
484 | }
485 |
486 |
--------------------------------------------------------------------------------
/NUSGrabberGUI/Form1.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
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 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | 175, 17
122 |
123 |
124 | 17, 17
125 |
126 |
127 | True
128 |
129 |
--------------------------------------------------------------------------------
/NUSGrabberGUI/GlobalSuppressions.cs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FoxMcloud5655/NEW-NUSGrabberGUI/69047f56db6d545107751590e60f97a53bde6c77/NUSGrabberGUI/GlobalSuppressions.cs
--------------------------------------------------------------------------------
/NUSGrabberGUI/Lz77.cs:
--------------------------------------------------------------------------------
1 | /* This file is part of libWiiSharp
2 | * Copyright (C) 2009 Leathl
3 | *
4 | * libWiiSharp is free software: you can redistribute it and/or
5 | * modify it under the terms of the GNU General Public License as published
6 | * by the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * libWiiSharp is distributed in the hope that it will be
10 | * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
11 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 |
18 | //Lz77 (de-)compression algorithm based on gbalzss by Andre Perrot (Thanks!)
19 |
20 | using System;
21 | using System.IO;
22 |
23 | namespace libWiiSharp
24 | {
25 | public class Lz77
26 | {
27 | private static uint lz77Magic = 0x4c5a3737;
28 | private const int N = 4096;
29 | private const int F = 18;
30 | private const int threshold = 2;
31 | private int[] leftSon = new int[N + 1];
32 | private int[] rightSon = new int[N + 257];
33 | private int[] dad = new int[N + 1];
34 | private ushort[] textBuffer = new ushort[N + 17];
35 | private int matchPosition = 0, matchLength = 0;
36 |
37 | ///
38 | /// Lz77 Magic.
39 | ///
40 | public static uint Lz77Magic { get { return lz77Magic; } }
41 |
42 | #region Public Functions
43 | ///
44 | /// Checks whether a file is Lz77 compressed or not.
45 | ///
46 | ///
47 | ///
48 | public static bool IsLz77Compressed(string file)
49 | {
50 | return IsLz77Compressed(File.ReadAllBytes(file));
51 | }
52 |
53 | ///
54 | /// Checks whether a file is Lz77 compressed or not.
55 | ///
56 | ///
57 | ///
58 | public static bool IsLz77Compressed(byte[] file)
59 | {
60 | Headers.HeaderType h = Headers.DetectHeader(file);
61 | return (Shared.Swap(BitConverter.ToUInt32(file, (int)h)) == lz77Magic) ;
62 | }
63 |
64 | ///
65 | /// Checks whether a file is Lz77 compressed or not.
66 | ///
67 | ///
68 | ///
69 | public static bool IsLz77Compressed(Stream file)
70 | {
71 | Headers.HeaderType h = Headers.DetectHeader(file);
72 | byte[] temp = new byte[4];
73 | file.Seek((long)h, SeekOrigin.Begin);
74 | file.Read(temp, 0, temp.Length);
75 | return (Shared.Swap(BitConverter.ToUInt32(temp, 0)) == lz77Magic);
76 | }
77 |
78 |
79 |
80 | ///
81 | /// Compresses a file using the Lz77 algorithm.
82 | ///
83 | ///
84 | ///
85 | public void Compress(string inFile, string outFile)
86 | {
87 | Stream compressedFile;
88 |
89 | using (FileStream fsIn = new FileStream(inFile, FileMode.Open))
90 | compressedFile = compress(fsIn);
91 |
92 | byte[] output = new byte[compressedFile.Length];
93 | compressedFile.Read(output, 0, output.Length);
94 |
95 | if (File.Exists(outFile)) File.Delete(outFile);
96 |
97 | using (FileStream fs = new FileStream(outFile, FileMode.Create))
98 | fs.Write(output, 0, output.Length);
99 | }
100 |
101 | ///
102 | /// Compresses the byte array using the Lz77 algorithm.
103 | ///
104 | ///
105 | ///
106 | public byte[] Compress(byte[] file)
107 | {
108 | return ((MemoryStream)compress(new MemoryStream(file))).ToArray();
109 | }
110 |
111 | ///
112 | /// Compresses the stream using the Lz77 algorithm.
113 | ///
114 | ///
115 | ///
116 | public Stream Compress(Stream file)
117 | {
118 | return compress(file);
119 | }
120 |
121 | ///
122 | /// Decompresses a file using the Lz77 algorithm.
123 | ///
124 | ///
125 | ///
126 | public void Decompress(string inFile, string outFile)
127 | {
128 | Stream compressedFile;
129 |
130 | using (FileStream fsIn = new FileStream(inFile, FileMode.Open))
131 | compressedFile = decompress(fsIn);
132 |
133 | byte[] output = new byte[compressedFile.Length];
134 | compressedFile.Read(output, 0, output.Length);
135 |
136 | if (File.Exists(outFile)) File.Delete(outFile);
137 |
138 | using (FileStream fs = new FileStream(outFile, FileMode.Create))
139 | fs.Write(output, 0, output.Length);
140 | }
141 |
142 | ///
143 | /// Decompresses the byte array using the Lz77 algorithm.
144 | ///
145 | ///
146 | ///
147 | public byte[] Decompress(byte[] file)
148 | {
149 | return ((MemoryStream)decompress(new MemoryStream(file))).ToArray();
150 | }
151 |
152 | public Stream Decompress(Stream file)
153 | {
154 | return decompress(file);
155 | }
156 | #endregion
157 |
158 | #region Private Functions
159 | private Stream decompress(Stream inFile)
160 | {
161 | if (!Lz77.IsLz77Compressed(inFile)) return inFile;
162 | inFile.Seek(0, SeekOrigin.Begin);
163 |
164 | int i, j, k, r, c, z;
165 | uint flags, decompressedSize, currentSize = 0;
166 |
167 | Headers.HeaderType h = Headers.DetectHeader(inFile);
168 |
169 | byte[] temp = new byte[8];
170 | inFile.Seek((int)h, SeekOrigin.Begin);
171 | inFile.Read(temp, 0, 8);
172 |
173 | if (Shared.Swap(BitConverter.ToUInt32(temp, 0)) != lz77Magic)
174 | { inFile.Dispose(); throw new Exception("Invaild Magic!"); }
175 | if (temp[4] != 0x10)
176 | { inFile.Dispose(); throw new Exception("Unsupported Compression Type!"); }
177 |
178 | decompressedSize = (BitConverter.ToUInt32(temp, 4)) >> 8;
179 |
180 | for (i = 0; i < N - F; i++) textBuffer[i] = 0xdf;
181 | r = N - F; flags = 7; z = 7;
182 |
183 | MemoryStream outFile = new MemoryStream();
184 | while (true)
185 | {
186 | flags <<= 1;
187 | z++;
188 |
189 | if (z == 8)
190 | {
191 | if ((c = inFile.ReadByte()) == -1) break;
192 |
193 | flags = (uint)c;
194 | z = 0;
195 | }
196 |
197 | if ((flags & 0x80) == 0)
198 | {
199 | if ((c = inFile.ReadByte()) == inFile.Length - 1) break;
200 | if (currentSize < decompressedSize) outFile.WriteByte((byte)c);
201 |
202 | textBuffer[r++] = (byte)c;
203 | r &= (N - 1);
204 | currentSize++;
205 | }
206 | else
207 | {
208 | if ((i = inFile.ReadByte()) == -1) break;
209 | if ((j = inFile.ReadByte()) == -1) break;
210 |
211 | j = j | ((i << 8) & 0xf00);
212 | i = ((i >> 4) & 0x0f) + threshold;
213 | for (k = 0; k <= i; k++)
214 | {
215 | c = textBuffer[(r - j - 1) & (N - 1)];
216 | if (currentSize < decompressedSize) outFile.WriteByte((byte)c); textBuffer[r++] = (byte)c; r &= (N - 1); currentSize++;
217 | }
218 | }
219 | }
220 |
221 | return outFile;
222 | }
223 |
224 | private Stream compress(Stream inFile)
225 | {
226 | if (Lz77.IsLz77Compressed(inFile)) return inFile;
227 | inFile.Seek(0, SeekOrigin.Begin);
228 |
229 | int textSize = 0;
230 | int codeSize = 0;
231 |
232 | int i, c, r, s, length, lastMatchLength, codeBufferPointer, mask;
233 | int[] codeBuffer = new int[17];
234 |
235 | uint fileSize = ((Convert.ToUInt32(inFile.Length)) << 8) + 0x10;
236 | MemoryStream outFile = new MemoryStream();
237 |
238 | outFile.Write(BitConverter.GetBytes(Shared.Swap(lz77Magic)), 0, 4);
239 | outFile.Write(BitConverter.GetBytes(fileSize), 0, 4);
240 |
241 | InitTree();
242 | codeBuffer[0] = 0;
243 | codeBufferPointer = 1;
244 | mask = 0x80;
245 | s = 0;
246 | r = N - F;
247 |
248 | for (i = s; i < r; i++) textBuffer[i] = 0xffff;
249 |
250 | for (length = 0; length < F && (c = (int)inFile.ReadByte()) != -1; length++)
251 | textBuffer[r + length] = (ushort)c;
252 |
253 | if ((textSize = length) == 0) return inFile;
254 |
255 | for (i = 1; i <= F; i++) InsertNode(r - i);
256 | InsertNode(r);
257 |
258 | do
259 | {
260 | if (matchLength > length) matchLength = length;
261 |
262 | if (matchLength <= threshold)
263 | {
264 | matchLength = 1;
265 | codeBuffer[codeBufferPointer++] = textBuffer[r];
266 | }
267 | else
268 | {
269 | codeBuffer[0] |= mask;
270 |
271 | codeBuffer[codeBufferPointer++] = (char)
272 | (((r - matchPosition - 1) >> 8) & 0x0f) |
273 | ((matchLength - (threshold + 1)) << 4);
274 |
275 | codeBuffer[codeBufferPointer++] = (char)((r - matchPosition - 1) & 0xff);
276 | }
277 |
278 | if ((mask >>= 1) == 0)
279 | {
280 | for (i = 0; i < codeBufferPointer; i++)
281 | outFile.WriteByte((byte)codeBuffer[i]);
282 |
283 | codeSize += codeBufferPointer;
284 | codeBuffer[0] = 0; codeBufferPointer = 1;
285 | mask = 0x80;
286 | }
287 |
288 | lastMatchLength = matchLength;
289 | for (i = 0; i < lastMatchLength && (c = (int)inFile.ReadByte()) != -1; i++)
290 | {
291 | DeleteNode(s);
292 |
293 | textBuffer[s] = (ushort)c;
294 | if (s < F - 1) textBuffer[s + N] = (ushort)c;
295 | s = (s + 1) & (N - 1); r = (r + 1) & (N - 1);
296 |
297 | InsertNode(r);
298 | }
299 |
300 | while (i++ < lastMatchLength)
301 | {
302 | DeleteNode(s);
303 |
304 | s = (s + 1) & (N - 1); r = (r + 1) & (N - 1);
305 | if (--length != 0) InsertNode(r);
306 | }
307 | } while (length > 0);
308 |
309 |
310 | if (codeBufferPointer > 1)
311 | {
312 | for (i = 0; i < codeBufferPointer; i++) outFile.WriteByte((byte)codeBuffer[i]);
313 | codeSize += codeBufferPointer;
314 | }
315 |
316 | if (codeSize % 4 != 0)
317 | for (i = 0; i < 4 - (codeSize % 4); i++)
318 | outFile.WriteByte(0x00);
319 |
320 | return outFile;
321 | }
322 |
323 | private void InitTree()
324 | {
325 | int i;
326 | for (i = N + 1; i <= N + 256; i++) rightSon[i] = N;
327 | for (i = 0; i < N; i++) dad[i] = N;
328 | }
329 |
330 | private void InsertNode(int r)
331 | {
332 | int i, p, cmp;
333 | cmp = 1;
334 | p = N + 1 + (textBuffer[r] == 0xffff ? 0 : (int)textBuffer[r]);
335 | rightSon[r] = leftSon[r] = N; matchLength = 0;
336 |
337 | for (; ; )
338 | {
339 | if (cmp >= 0)
340 | {
341 | if (rightSon[p] != N) p = rightSon[p];
342 | else { rightSon[p] = r; dad[r] = p; return; }
343 | }
344 | else
345 | {
346 | if (leftSon[p] != N) p = leftSon[p];
347 | else { leftSon[p] = r; dad[r] = p; return; }
348 | }
349 |
350 | for (i = 1; i < F; i++)
351 | if ((cmp = textBuffer[r + i] - textBuffer[p + i]) != 0) break;
352 |
353 | if (i > matchLength)
354 | {
355 | matchPosition = p;
356 | if ((matchLength = i) >= F) break;
357 | }
358 | }
359 |
360 | dad[r] = dad[p]; leftSon[r] = leftSon[p]; rightSon[r] = rightSon[p];
361 | dad[leftSon[p]] = r; dad[rightSon[p]] = r;
362 |
363 | if (rightSon[dad[p]] == p) rightSon[dad[p]] = r;
364 | else leftSon[dad[p]] = r;
365 |
366 | dad[p] = N;
367 | }
368 |
369 | private void DeleteNode(int p)
370 | {
371 | int q;
372 |
373 | if (dad[p] == N) return;
374 |
375 | if (rightSon[p] == N) q = leftSon[p];
376 | else if (leftSon[p] == N) q = rightSon[p];
377 | else
378 | {
379 | q = leftSon[p];
380 |
381 | if (rightSon[q] != N)
382 | {
383 | do { q = rightSon[q]; } while (rightSon[q] != N);
384 | rightSon[dad[q]] = leftSon[q]; dad[leftSon[q]] = dad[q];
385 | leftSon[q] = leftSon[p]; dad[leftSon[p]] = q;
386 | }
387 |
388 | rightSon[q] = rightSon[p]; dad[rightSon[p]] = q;
389 | }
390 |
391 | dad[q] = dad[p];
392 |
393 | if (rightSon[dad[p]] == p) rightSon[dad[p]] = q;
394 | else leftSon[dad[p]] = q;
395 |
396 | dad[p] = N;
397 | }
398 | #endregion
399 | }
400 | }
401 |
--------------------------------------------------------------------------------
/NUSGrabberGUI/MessageEventArgs.cs:
--------------------------------------------------------------------------------
1 | /* This file is part of libWiiSharp
2 | * Copyright (C) 2009 Leathl
3 | *
4 | * libWiiSharp is free software: you can redistribute it and/or
5 | * modify it under the terms of the GNU General Public License as published
6 | * by the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * libWiiSharp is distributed in the hope that it will be
10 | * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
11 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 |
18 | using System;
19 |
20 | namespace libWiiSharp
21 | {
22 | public class MessageEventArgs : EventArgs
23 | {
24 | private string message;
25 | public string Message { get { return message; } }
26 |
27 | public MessageEventArgs(string message) { this.message = message; }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/NUSGrabberGUI/NUSGrabberGUI.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {759B9695-7DBE-4964-8968-8713435ECA1E}
8 | WinExe
9 | Properties
10 | NUSGrabberGUI
11 | NEW-NUSGrabberGUI
12 | v4.5
13 | 512
14 | true
15 | false
16 |
17 | C:\Temp\
18 | false
19 | Disk
20 | true
21 | Foreground
22 | 7
23 | Days
24 | false
25 | false
26 | true
27 | 0
28 | 0.9.1.%2a
29 | false
30 | true
31 | true
32 |
33 |
34 | AnyCPU
35 | true
36 | full
37 | false
38 | bin\Debug\
39 | DEBUG;TRACE
40 | prompt
41 | 4
42 | true
43 | true
44 |
45 |
46 | AnyCPU
47 | pdbonly
48 | true
49 | bin\Release\
50 | TRACE
51 | prompt
52 | 4
53 | false
54 |
55 |
56 | NUSGrabberGUI.ico
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 | 8B9D9B1C5CC6330D3E889A80AB956149BF9E3812
65 |
66 |
67 | NUSGrabberGUI_TemporaryKey.pfx
68 |
69 |
70 | true
71 |
72 |
73 | Internet
74 |
75 |
76 | Properties\app.manifest
77 |
78 |
79 | false
80 |
81 |
82 |
83 | ..\packages\HtmlAgilityPack.1.4.9\lib\Net45\HtmlAgilityPack.dll
84 | True
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 | Form
104 |
105 |
106 | Form1.cs
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 | True
117 | True
118 | en.resx
119 |
120 |
121 | Form
122 |
123 |
124 | Settings.cs
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 | Form1.cs
133 |
134 |
135 | ResXFileCodeGenerator
136 | Resources.Designer.cs
137 | Designer
138 |
139 |
140 | True
141 | Resources.resx
142 | True
143 |
144 |
145 | ResXFileCodeGenerator
146 | en.Designer.cs
147 |
148 |
149 | Settings.cs
150 |
151 |
152 |
153 |
154 |
155 | SettingsSingleFileGenerator
156 | Settings.Designer.cs
157 |
158 |
159 | True
160 | Settings.settings
161 | True
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 | False
170 | Microsoft .NET Framework 4.5 %28x86 and x64%29
171 | true
172 |
173 |
174 | False
175 | .NET Framework 3.5 SP1
176 | false
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
198 |
--------------------------------------------------------------------------------
/NUSGrabberGUI/NUSGrabberGUI.csproj.user:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | C:\Temp\|C:\Users\tpitts\Dropbox\Public\NUSGrabber\|publish\
5 |
6 |
7 |
8 |
9 |
10 | en-US
11 | false
12 |
13 |
14 | false
15 |
16 |
17 | false
18 |
19 |
--------------------------------------------------------------------------------
/NUSGrabberGUI/NUSGrabberGUI.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FoxMcloud5655/NEW-NUSGrabberGUI/69047f56db6d545107751590e60f97a53bde6c77/NUSGrabberGUI/NUSGrabberGUI.ico
--------------------------------------------------------------------------------
/NUSGrabberGUI/NUSGrabberGUI_TemporaryKey.pfx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FoxMcloud5655/NEW-NUSGrabberGUI/69047f56db6d545107751590e60f97a53bde6c77/NUSGrabberGUI/NUSGrabberGUI_TemporaryKey.pfx
--------------------------------------------------------------------------------
/NUSGrabberGUI/NusClient.cs:
--------------------------------------------------------------------------------
1 | /* This file is part of libWiiSharp
2 | * Copyright (C) 2009 Leathl
3 | *
4 | * libWiiSharp is free software: you can redistribute it and/or
5 | * modify it under the terms of the GNU General Public License as published
6 | * by the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * libWiiSharp is distributed in the hope that it will be
10 | * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
11 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 |
18 | using System;
19 | using System.ComponentModel;
20 | using System.IO;
21 | using System.Net;
22 | using System.Security.Cryptography;
23 |
24 | namespace libWiiSharp
25 | {
26 | public enum StoreType
27 | {
28 | EncryptedContent = 0,
29 | DecryptedContent = 1,
30 | WAD = 2,
31 | All = 3,
32 | Empty = 4
33 | }
34 |
35 | public class NusClient : IDisposable
36 | {
37 | private const string WII_NUS_URL = "http://nus.cdn.shop.wii.com/ccs/download/";
38 | private const string DSI_NUS_URL = "http://nus.cdn.t.shop.nintendowifi.net/ccs/download/";
39 |
40 | private const string WII_USER_AGENT = "wii libnup/1.0";
41 | private const string DSI_USER_AGENT = "Opera/9.50 (Nintendo; Opera/154; U; Nintendo DS; en)";
42 |
43 | private string nusUrl = WII_NUS_URL;
44 | private WebClient wcNus = new WebClient();
45 | private bool useLocalFiles = false;
46 | private bool continueWithoutTicket = false;
47 |
48 | private int titleversion;
49 |
50 | public int TitleVersion { get { return titleversion; } }
51 |
52 | ///
53 | /// If true, existing local files will be used.
54 | ///
55 | public bool UseLocalFiles { get { return useLocalFiles; } set { useLocalFiles = value; } }
56 | ///
57 | /// If true, the download will be continued even if no ticket for the title is avaiable (WAD packaging and decryption are disabled).
58 | ///
59 | public bool ContinueWithoutTicket { get { return continueWithoutTicket; } set { continueWithoutTicket = value; } }
60 |
61 | #region IDisposable Members
62 | private bool isDisposed = false;
63 |
64 | ~NusClient()
65 | {
66 | Dispose(false);
67 | }
68 |
69 | public void Dispose()
70 | {
71 | Dispose(true);
72 | GC.SuppressFinalize(this);
73 | }
74 |
75 | protected virtual void Dispose(bool disposing)
76 | {
77 | if (disposing && !isDisposed)
78 | {
79 | wcNus.Dispose();
80 | }
81 |
82 | isDisposed = true;
83 | }
84 | #endregion
85 |
86 | #region Public Functions
87 |
88 | public void ConfigureNusClient(WebClient wcReady)
89 | {
90 | wcNus = wcReady;
91 | }
92 |
93 | public void SetToWiiServer()
94 | {
95 | nusUrl = WII_NUS_URL;
96 | wcNus.Headers.Add("User-Agent", WII_USER_AGENT);
97 | }
98 |
99 | public void SetToDSiServer()
100 | {
101 | nusUrl = DSI_NUS_URL;
102 | wcNus.Headers.Add("User-Agent", DSI_USER_AGENT);
103 | }
104 |
105 | ///
106 | /// Grabs a title from NUS, you can define several store types.
107 | /// Leave the title version empty for the latest.
108 | ///
109 | ///
110 | ///
111 | ///
112 | ///
113 | public void DownloadTitle(string titleId, string titleVersion, string outputDir, string wadName, params StoreType[] storeTypes)
114 | {
115 | if (titleId.Length != 16) throw new Exception("Title ID must be 16 characters long!");
116 | downloadTitle(titleId, titleVersion, outputDir, wadName, storeTypes);
117 | }
118 |
119 | ///
120 | /// Grabs a TMD from NUS.
121 | /// Leave the title version empty for the latest.
122 | ///
123 | ///
124 | ///
125 | ///
126 | public TMD DownloadTMD(string titleId, string titleVersion)
127 | {
128 | if (titleId.Length != 16) throw new Exception("Title ID must be 16 characters long!");
129 | return downloadTmd(titleId, titleVersion);
130 | }
131 |
132 | ///
133 | /// Grabs a Ticket from NUS.
134 | ///
135 | ///
136 | ///
137 | public Ticket DownloadTicket(string titleId)
138 | {
139 | if (titleId.Length != 16) throw new Exception("Title ID must be 16 characters long!");
140 | return downloadTicket(titleId);
141 | }
142 |
143 | ///
144 | /// Grabs a single content file and decrypts it.
145 | /// Leave the title version empty for the latest.
146 | ///
147 | ///
148 | ///
149 | ///
150 | ///
151 | public byte[] DownloadSingleContent(string titleId, string titleVersion, string contentId)
152 | {
153 | if (titleId.Length != 16) throw new Exception("Title ID must be 16 characters long!");
154 | return downloadSingleContent(titleId, titleVersion, contentId);
155 | }
156 |
157 | ///
158 | /// Grabs a single content file and decrypts it.
159 | /// Leave the title version empty for the latest.
160 | ///
161 | ///
162 | ///
163 | ///
164 | ///
165 | public void DownloadSingleContent(string titleId, string titleVersion, string contentId, string savePath)
166 | {
167 | if (titleId.Length != 16) throw new Exception("Title ID must be 16 characters long!");
168 | if (!Directory.Exists(Path.GetDirectoryName(savePath))) Directory.CreateDirectory(Path.GetDirectoryName(savePath));
169 | if (File.Exists(savePath)) File.Delete(savePath);
170 |
171 | byte[] content = downloadSingleContent(titleId, titleVersion, contentId);
172 | File.WriteAllBytes(savePath, content);
173 | }
174 | #endregion
175 |
176 | #region Private Functions
177 | private byte[] downloadSingleContent(string titleId, string titleVersion, string contentId)
178 | {
179 | uint cId = uint.Parse(contentId, System.Globalization.NumberStyles.HexNumber);
180 | contentId = cId.ToString("x8");
181 |
182 | fireDebug("Downloading Content (Content ID: {0}) of Title {1} v{2}...", contentId, titleId, (string.IsNullOrEmpty(titleVersion)) ? "[Latest]" : titleVersion);
183 |
184 | fireDebug(" Checking for Internet connection...");
185 | if (!CheckInet())
186 | { fireDebug(" Connection not found..."); throw new Exception("You're not connected to the internet!"); }
187 |
188 | fireProgress(0);
189 |
190 | string tmdFile = "tmd" + (string.IsNullOrEmpty(titleVersion) ? string.Empty : string.Format(".{0}", titleVersion));
191 | string titleUrl = string.Format("{0}{1}/", nusUrl, titleId);
192 | string contentIdString = string.Empty;
193 | int cIndex = 0;
194 |
195 | //Download TMD
196 | fireDebug(" Downloading TMD...");
197 | byte[] tmdArray = wcNus.DownloadData(titleUrl + tmdFile);
198 | fireDebug(" Parsing TMD...");
199 | TMD tmd = TMD.Load(tmdArray);
200 |
201 | fireProgress(20);
202 |
203 | //Search for Content ID in TMD
204 | fireDebug(" Looking for Content ID {0} in TMD...", contentId);
205 | bool foundContentId = false;
206 | for (int i = 0; i < tmd.Contents.Length; i++)
207 | if (tmd.Contents[i].ContentID == cId)
208 | {
209 | fireDebug(" Content ID {0} found in TMD...", contentId);
210 | foundContentId = true;
211 | contentIdString = tmd.Contents[i].ContentID.ToString("x8");
212 | cIndex = i;
213 | break;
214 | }
215 |
216 | if (!foundContentId)
217 | { fireDebug(" Content ID {0} wasn't found in TMD...", contentId); throw new Exception("Content ID wasn't found in the TMD!"); }
218 |
219 | //Download Ticket
220 | fireDebug(" Downloading Ticket...");
221 | byte[] tikArray = wcNus.DownloadData(titleUrl + "cetk");
222 | fireDebug(" Parsing Ticket...");
223 | Ticket tik = Ticket.Load(tikArray);
224 |
225 | fireProgress(40);
226 |
227 | //Download and Decrypt Content
228 | fireDebug(" Downloading Content... ({0} bytes)", tmd.Contents[cIndex].Size);
229 | byte[] encryptedContent = wcNus.DownloadData(titleUrl + contentIdString);
230 |
231 | fireProgress(80);
232 |
233 | fireDebug(" Decrypting Content...");
234 | byte[] decryptedContent = decryptContent(encryptedContent, cIndex, tik, tmd);
235 | Array.Resize(ref decryptedContent, (int)tmd.Contents[cIndex].Size);
236 |
237 | //Check SHA1
238 | SHA1 s = SHA1.Create();
239 | byte[] newSha = s.ComputeHash(decryptedContent);
240 |
241 | if (!Shared.CompareByteArrays(newSha, tmd.Contents[cIndex].Hash))
242 | { fireDebug(@"/!\ /!\ /!\ Hashes do not match /!\ /!\ /!\"); throw new Exception("Hashes do not match!"); }
243 |
244 | fireProgress(100);
245 |
246 | fireDebug("Downloading Content (Content ID: {0}) of Title {1} v{2} Finished...", contentId, titleId, (string.IsNullOrEmpty(titleVersion)) ? "[Latest]" : titleVersion);
247 | return decryptedContent;
248 | }
249 |
250 | private Ticket downloadTicket(string titleId)
251 | {
252 | if (!CheckInet())
253 | throw new Exception("You're not connected to the internet!");
254 |
255 | string titleUrl = string.Format("{0}{1}/", nusUrl, titleId);
256 | byte[] tikArray = wcNus.DownloadData(titleUrl + "cetk");
257 |
258 | return Ticket.Load(tikArray);
259 | }
260 |
261 | private TMD downloadTmd(string titleId, string titleVersion)
262 | {
263 | if (!CheckInet())
264 | throw new Exception("You're not connected to the internet!");
265 |
266 | string titleUrl = string.Format("{0}{1}/", nusUrl, titleId);
267 | string tmdFile = "tmd" + (string.IsNullOrEmpty(titleVersion) ? string.Empty : string.Format(".{0}", titleVersion));
268 |
269 | byte[] tmdArray = wcNus.DownloadData(titleUrl + tmdFile);
270 |
271 | return TMD.Load(tmdArray);
272 | }
273 |
274 | private void downloadTitle(string titleId, string titleVersion, string outputDir, string wadName, StoreType[] storeTypes)
275 | {
276 | fireDebug("Downloading Title {0} v{1}...", titleId, (string.IsNullOrEmpty(titleVersion)) ? "[Latest]" : titleVersion);
277 |
278 | if (storeTypes.Length < 1)
279 | { fireDebug(" No store types were defined..."); throw new Exception("You must at least define one store type!"); }
280 |
281 | string titleUrl = string.Format("{0}{1}/", nusUrl, titleId);
282 | bool storeEncrypted = false;
283 | bool storeDecrypted = false;
284 | bool storeWad = false;
285 |
286 | fireProgress(0);
287 |
288 | foreach (StoreType st in storeTypes)
289 | {
290 | switch (st)
291 | {
292 | case StoreType.DecryptedContent:
293 | fireDebug(" [=] Storing Decrypted Content...");
294 | storeDecrypted = true;
295 | break;
296 | case StoreType.EncryptedContent:
297 | fireDebug(" [=] Storing Encrypted Content...");
298 | storeEncrypted = true;
299 | break;
300 | case StoreType.WAD:
301 | fireDebug(" [=] Storing WAD...");
302 | storeWad = true;
303 | break;
304 | case StoreType.All:
305 | fireDebug(" [=] Storing Decrypted Content...");
306 | fireDebug(" [=] Storing Encrypted Content...");
307 | fireDebug(" [=] Storing WAD...");
308 | storeDecrypted = true;
309 | storeEncrypted = true;
310 | storeWad = true;
311 | break;
312 | case StoreType.Empty:
313 | break;
314 | }
315 | }
316 | /*
317 | fireDebug(" - Checking for Internet connection...");
318 | if (!CheckInet())
319 | { fireDebug(" + Connection not found..."); throw new Exception("You're not connected to the internet!"); }
320 | */
321 |
322 | if (!Directory.Exists(outputDir)) Directory.CreateDirectory(outputDir);
323 | if (!Directory.Exists(Path.Combine(outputDir, titleId))) Directory.CreateDirectory(Path.Combine(outputDir, titleId));
324 | outputDir = Path.Combine(outputDir, titleId);
325 |
326 | string tmdFile = "tmd" + (string.IsNullOrEmpty(titleVersion) ? string.Empty : string.Format(".{0}", titleVersion));
327 |
328 | //Download TMD
329 | fireDebug(" - Downloading TMD...");
330 | TMD tmd;
331 | byte[] tmdFileWithCerts;
332 | try
333 | {
334 | tmdFileWithCerts = wcNus.DownloadData(titleUrl + tmdFile);
335 | tmd = TMD.Load(tmdFileWithCerts);
336 | }
337 | catch (Exception ex) { fireDebug(" + Downloading TMD Failed..."); throw new Exception("Downloading TMD Failed:\n" + ex.Message); }
338 |
339 | //Parse TMD
340 | fireDebug(" - Parsing TMD...");
341 |
342 | if (string.IsNullOrEmpty(titleVersion)) { fireDebug(" + Title Version: {0}", tmd.TitleVersion); }
343 | fireDebug(" + {0} Contents", tmd.NumOfContents);
344 |
345 | if (!Directory.Exists(Path.Combine(outputDir, tmd.TitleVersion.ToString()))) Directory.CreateDirectory(Path.Combine(outputDir, tmd.TitleVersion.ToString()));
346 | outputDir = Path.Combine(outputDir, tmd.TitleVersion.ToString());
347 |
348 | this.titleversion = tmd.TitleVersion;
349 |
350 | File.WriteAllBytes(Path.Combine(outputDir, tmdFile), tmd.ToByteArray());
351 |
352 | fireProgress(5);
353 |
354 | //Download cetk
355 | fireDebug(" - Downloading Ticket...");
356 | try
357 | {
358 | wcNus.DownloadFile(Path.Combine(titleUrl, "cetk"), Path.Combine(outputDir, "cetk"));
359 | }
360 | catch (Exception ex)
361 | {
362 | if (!continueWithoutTicket || !storeEncrypted)
363 | {
364 | fireDebug(" + Downloading Ticket Failed...");
365 | throw new Exception("Downloading Ticket Failed:\n" + ex.Message);
366 | }
367 |
368 | if (!(File.Exists(Path.Combine(outputDir, "cetk"))))
369 | {
370 | storeDecrypted = false;
371 | storeWad = false;
372 | }
373 | }
374 |
375 | fireProgress(10);
376 |
377 | // Parse Ticket
378 | Ticket tik = new Ticket();
379 |
380 | if (File.Exists(Path.Combine(outputDir, "cetk")))
381 | {
382 | fireDebug(" + Parsing Ticket...");
383 | tik = Ticket.Load(Path.Combine(outputDir, "cetk"));
384 |
385 | // DSi ticket? Must make sure to use DSi Key :D
386 | if (nusUrl == DSI_NUS_URL)
387 | tik.DSiTicket = true;
388 | }
389 | else
390 | {
391 | fireDebug(" + Ticket Unavailable...");
392 | }
393 |
394 | string[] encryptedContents = new string[tmd.NumOfContents];
395 |
396 | //Download Content
397 | for (int i = 0; i < tmd.NumOfContents; i++)
398 | {
399 | fireDebug(" - Downloading Content #{0} of {1}... ({2} bytes)", i + 1, tmd.NumOfContents, tmd.Contents[i].Size);
400 | fireProgress(((i + 1) * 60 / tmd.NumOfContents) + 10);
401 |
402 | if (useLocalFiles && File.Exists(Path.Combine(outputDir, tmd.Contents[i].ContentID.ToString("x8"))))
403 | { fireDebug(" + Using Local File, Skipping..."); continue; }
404 |
405 | try
406 | {
407 | wcNus.DownloadFile(titleUrl + tmd.Contents[i].ContentID.ToString("x8"),
408 | Path.Combine(outputDir, tmd.Contents[i].ContentID.ToString("x8")));
409 |
410 | encryptedContents[i] = tmd.Contents[i].ContentID.ToString("x8");
411 | }
412 | catch (Exception ex) { fireDebug(" - Downloading Content #{0} of {1} failed...", i + 1, tmd.NumOfContents); throw new Exception("Downloading Content Failed:\n" + ex.Message); }
413 | }
414 |
415 | //Decrypt Content
416 | if (storeDecrypted || storeWad)
417 | {
418 | SHA1 s = SHA1.Create();
419 |
420 | for (int i = 0; i < tmd.NumOfContents; i++)
421 | {
422 | fireDebug(" - Decrypting Content #{0} of {1}...", i + 1, tmd.NumOfContents);
423 | fireProgress(((i + 1) * 20 / tmd.NumOfContents) + 75);
424 |
425 | //Decrypt Content
426 | byte[] decryptedContent =
427 | decryptContent(File.ReadAllBytes(Path.Combine(outputDir, tmd.Contents[i].ContentID.ToString("x8"))), i, tik, tmd);
428 | Array.Resize(ref decryptedContent, (int)tmd.Contents[i].Size);
429 |
430 | //Check SHA1
431 | byte[] newSha = s.ComputeHash(decryptedContent);
432 | if (!Shared.CompareByteArrays(newSha, tmd.Contents[i].Hash))
433 | {
434 | fireDebug(@" + Hashes do not match! (Invalid Output)");
435 | //throw new Exception(string.Format("Content #{0}: Hashes do not match!", i));
436 | }
437 |
438 | //Write Decrypted Content
439 | File.WriteAllBytes(Path.Combine(outputDir, (tmd.Contents[i].ContentID.ToString("x8") + ".app")), decryptedContent);
440 | }
441 |
442 | s.Clear();
443 | }
444 |
445 | //Pack Wad
446 | if (storeWad)
447 | {
448 | fireDebug(" - Building Certificate Chain...");
449 | CertificateChain cert = CertificateChain.FromTikTmd(Path.Combine(outputDir, "cetk"), tmdFileWithCerts);
450 |
451 | byte[][] contents = new byte[tmd.NumOfContents][];
452 |
453 | for (int i = 0; i < tmd.NumOfContents; i++)
454 | contents[i] = File.ReadAllBytes(Path.Combine(outputDir, (tmd.Contents[i].ContentID.ToString("x8") + ".app")));
455 |
456 | fireDebug(" - Creating WAD...");
457 | WAD wad = WAD.Create(cert, tik, tmd, contents);
458 | wad.RemoveFooter();
459 | wadName = wadName.Replace("[v]", "v" + this.TitleVersion.ToString()); // fix by madri2
460 | if (Path.DirectorySeparatorChar.ToString() != "/" && Path.AltDirectorySeparatorChar.ToString() != "/")
461 | wadName = wadName.Replace("/", "");
462 | if (wadName.Contains(Path.DirectorySeparatorChar.ToString()) || wadName.Contains(Path.AltDirectorySeparatorChar.ToString()))
463 | wad.Save(wadName);
464 | else
465 | wad.Save(Path.Combine(outputDir, wadName));
466 | }
467 |
468 | //Delete not wanted files
469 | if (!storeEncrypted)
470 | {
471 | fireDebug(" - Deleting Encrypted Contents...");
472 | for (int i = 0; i < encryptedContents.Length; i++)
473 | if (File.Exists(Path.Combine(outputDir, encryptedContents[i]))) File.Delete(Path.Combine(outputDir, encryptedContents[i]));
474 | }
475 |
476 | if (storeWad && !storeDecrypted)
477 | {
478 | fireDebug(" - Deleting Decrypted Contents...");
479 | for (int i = 0; i < encryptedContents.Length; i++)
480 | if (File.Exists(Path.Combine(outputDir, (encryptedContents[i] + ".app")))) File.Delete(Path.Combine(outputDir, (encryptedContents[i] + ".app")));
481 | }
482 |
483 | if (!storeDecrypted && !storeEncrypted)
484 | {
485 | fireDebug(" - Deleting TMD and Ticket...");
486 | File.Delete(Path.Combine(outputDir, tmdFile));
487 | File.Delete(Path.Combine(outputDir, "cetk"));
488 | }
489 |
490 | fireDebug("Downloading Title {0} v{1} Finished...", titleId, tmd.TitleVersion /*(string.IsNullOrEmpty(titleVersion)) ? "[Latest]" : titleVersion*/);
491 | fireProgress(100);
492 | }
493 |
494 | private byte[] decryptContent(byte[] content, int contentIndex, Ticket tik, TMD tmd)
495 | {
496 | Array.Resize(ref content, Shared.AddPadding(content.Length, 16));
497 | byte[] titleKey = tik.TitleKey;
498 | byte[] iv = new byte[16];
499 |
500 | byte[] tmp = BitConverter.GetBytes(tmd.Contents[contentIndex].Index);
501 | iv[0] = tmp[1];
502 | iv[1] = tmp[0];
503 |
504 | RijndaelManaged rm = new RijndaelManaged();
505 | rm.Mode = CipherMode.CBC;
506 | rm.Padding = PaddingMode.None;
507 | rm.KeySize = 128;
508 | rm.BlockSize = 128;
509 | rm.Key = titleKey;
510 | rm.IV = iv;
511 |
512 | ICryptoTransform decryptor = rm.CreateDecryptor();
513 |
514 | MemoryStream ms = new MemoryStream(content);
515 | CryptoStream cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read);
516 |
517 | byte[] decCont = new byte[content.Length];
518 | cs.Read(decCont, 0, decCont.Length);
519 |
520 | cs.Dispose();
521 | ms.Dispose();
522 |
523 | return decCont;
524 | }
525 |
526 | private bool CheckInet()
527 | {
528 | try
529 | {
530 | System.Net.IPHostEntry ipHost = System.Net.Dns.GetHostEntry("www.google.com");
531 | return true;
532 | }
533 | catch { return false; }
534 | }
535 | #endregion
536 |
537 | #region Events
538 | ///
539 | /// Fires the Progress of various operations
540 | ///
541 | public event EventHandler Progress;
542 | ///
543 | /// Fires debugging messages. You may write them into a log file or log textbox.
544 | ///
545 | public event EventHandler Debug;
546 |
547 | private void fireDebug(string debugMessage, params object[] args)
548 | {
549 | EventHandler debug = Debug;
550 | if (debug != null)
551 | debug(new object(), new MessageEventArgs(string.Format(debugMessage, args)));
552 | }
553 |
554 | private void fireProgress(int progressPercentage)
555 | {
556 | EventHandler progress = Progress;
557 | if (progress != null)
558 | progress(new object(), new ProgressChangedEventArgs(progressPercentage, string.Empty));
559 | }
560 | #endregion
561 | }
562 | }
563 |
--------------------------------------------------------------------------------
/NUSGrabberGUI/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Windows.Forms;
3 |
4 | namespace NUSGrabberGUI
5 | {
6 | static class Program
7 | {
8 | ///
9 | /// The main entry point for the application.
10 | ///
11 | [STAThread]
12 | static void Main()
13 | {
14 | Application.EnableVisualStyles();
15 | Application.SetCompatibleTextRenderingDefault(false);
16 | Application.Run(new NUSGrabberForm());
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/NUSGrabberGUI/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("NUSGrabberGUI")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("NUSGrabberGUI")]
13 | [assembly: AssemblyCopyright("Copyright © 2016")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("759b9695-7dbe-4964-8968-8713435eca1e")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/NUSGrabberGUI/Properties/Resources.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace NUSGrabberGUI.Properties {
12 | using System;
13 |
14 |
15 | ///
16 | /// A strongly-typed resource class, for looking up localized strings, etc.
17 | ///
18 | // This class was auto-generated by the StronglyTypedResourceBuilder
19 | // class via a tool like ResGen or Visual Studio.
20 | // To add or remove a member, edit your .ResX file then rerun ResGen
21 | // with the /str option, or rebuild your VS project.
22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
25 | internal class Resources {
26 |
27 | private static global::System.Resources.ResourceManager resourceMan;
28 |
29 | private static global::System.Globalization.CultureInfo resourceCulture;
30 |
31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
32 | internal Resources() {
33 | }
34 |
35 | ///
36 | /// Returns the cached ResourceManager instance used by this class.
37 | ///
38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
39 | internal static global::System.Resources.ResourceManager ResourceManager {
40 | get {
41 | if (object.ReferenceEquals(resourceMan, null)) {
42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("NUSGrabberGUI.Properties.Resources", typeof(Resources).Assembly);
43 | resourceMan = temp;
44 | }
45 | return resourceMan;
46 | }
47 | }
48 |
49 | ///
50 | /// Overrides the current thread's CurrentUICulture property for all
51 | /// resource lookups using this strongly typed resource class.
52 | ///
53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
54 | internal static global::System.Globalization.CultureInfo Culture {
55 | get {
56 | return resourceCulture;
57 | }
58 | set {
59 | resourceCulture = value;
60 | }
61 | }
62 |
63 | ///
64 | /// Looks up a localized resource of type System.Byte[].
65 | ///
66 | internal static byte[] CDecrypt {
67 | get {
68 | object obj = ResourceManager.GetObject("CDecrypt", resourceCulture);
69 | return ((byte[])(obj));
70 | }
71 | }
72 |
73 | ///
74 | /// Looks up a localized string similar to <?xml version="1.0" encoding="utf-8"?>
75 | ///<root>
76 | /// <!--
77 | /// Microsoft ResX Schema
78 | ///
79 | /// Version 2.0
80 | ///
81 | /// The primary goals of this format is to allow a simple XML format
82 | /// that is mostly human readable. The generation and parsing of the
83 | /// various data types are done through the TypeConverter classes
84 | /// associated with the data types.
85 | ///
86 | /// Example:
87 | ///
88 | /// ... ado.net/XML headers & schema ...
89 | /// <resheader name="resmimetype">text/microsoft-resx</resheader>
90 | /// <resheader n [rest of string was truncated]";.
91 | ///
92 | internal static string en {
93 | get {
94 | return ResourceManager.GetString("en", resourceCulture);
95 | }
96 | }
97 |
98 | ///
99 | /// Looks up a localized resource of type System.Byte[].
100 | ///
101 | internal static byte[] HtmlAgilityPack {
102 | get {
103 | object obj = ResourceManager.GetObject("HtmlAgilityPack", resourceCulture);
104 | return ((byte[])(obj));
105 | }
106 | }
107 |
108 | ///
109 | /// Looks up a localized resource of type System.Byte[].
110 | ///
111 | internal static byte[] libeay32 {
112 | get {
113 | object obj = ResourceManager.GetObject("libeay32", resourceCulture);
114 | return ((byte[])(obj));
115 | }
116 | }
117 |
118 | ///
119 | /// Looks up a localized resource of type System.Byte[].
120 | ///
121 | internal static byte[] NUSgrabber {
122 | get {
123 | object obj = ResourceManager.GetObject("NUSgrabber", resourceCulture);
124 | return ((byte[])(obj));
125 | }
126 | }
127 |
128 | ///
129 | /// Looks up a localized resource of type System.Byte[].
130 | ///
131 | internal static byte[] NUSgrabberORIG {
132 | get {
133 | object obj = ResourceManager.GetObject("NUSgrabberORIG", resourceCulture);
134 | return ((byte[])(obj));
135 | }
136 | }
137 |
138 | ///
139 | /// Looks up a localized resource of type System.Byte[].
140 | ///
141 | internal static byte[] vcruntime140 {
142 | get {
143 | object obj = ResourceManager.GetObject("vcruntime140", resourceCulture);
144 | return ((byte[])(obj));
145 | }
146 | }
147 |
148 | ///
149 | /// Looks up a localized resource of type System.Byte[].
150 | ///
151 | internal static byte[] wget {
152 | get {
153 | object obj = ResourceManager.GetObject("wget", resourceCulture);
154 | return ((byte[])(obj));
155 | }
156 | }
157 |
158 | ///
159 | /// Looks up a localized string similar to 10100600
160 | /// 16
161 | ///10100D00
162 | /// 112
163 | /// 16
164 | /// 49
165 | /// 64
166 | /// 80
167 | /// 96
168 | ///10101A00
169 | /// 0
170 | ///10101B00
171 | /// 0
172 | /// 16
173 | ///10101C00
174 | /// 32
175 | /// 48
176 | /// 65
177 | ///10101D00
178 | /// 32
179 | /// 48
180 | /// 64
181 | ///10101E00
182 | /// 32
183 | /// 48
184 | /// 80
185 | ///10101F00
186 | /// 32
187 | ///10102000
188 | /// 32
189 | ///10102100
190 | /// 32
191 | ///10102200
192 | /// 32
193 | /// 48
194 | /// 64
195 | /// 81
196 | ///10102300
197 | /// 48
198 | /// 64
199 | /// 81
200 | ///10102400
201 | /// 16
202 | /// 48
203 | /// 64
204 | /// 81
205 | ///10102500
206 | /// 32
207 | /// 49
208 | /// 65
209 | /// 80
210 | /// 96
211 | ///10102900
212 | /// 18
213 | /// 32
214 | ///10102A00
215 | /// 19
216 | /// 48
217 | ///10102D00
218 | /// 16
219 | /// 32
220 | /// 48
221 | /// 80
222 | ///10102E00
223 | /// 16
224 | ///10102F00
225 | /// 16
226 | /// 32
227 | ///10104C00
228 | /// 48
229 | ///10104D00
230 | /// 0
231 | /// 16
232 | /// 32
233 | /// 48
234 | /// 65
235 | /// 80
236 | /// 96
237 | ///10105700
238 | /// 112
239 | /// 12 [rest of string was truncated]";.
240 | ///
241 | internal static string wiiu_versionlist {
242 | get {
243 | return ResourceManager.GetString("wiiu_versionlist", resourceCulture);
244 | }
245 | }
246 | }
247 | }
248 |
--------------------------------------------------------------------------------
/NUSGrabberGUI/Properties/Resources.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
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 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 |
122 | ..\Resources\CDecrypt.exe;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
123 |
124 |
125 | ..\Resources\HtmlAgilityPack.dll;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
126 |
127 |
128 | ..\Resources\libeay32.dll;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
129 |
130 |
131 | ..\Resources\vcruntime140.dll;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
132 |
133 |
134 | ..\Resources\wget.exe;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
135 |
136 |
137 | ..\Resources\wiiu_versionlist.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252
138 |
139 |
140 | ..\Resources\NUSgrabber.exe;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
141 |
142 |
143 | ..\Resources\NUSgrabberORIG.exe;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
144 |
145 |
146 | ..\Resources\en.resx;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8
147 |
148 |
--------------------------------------------------------------------------------
/NUSGrabberGUI/Properties/Settings.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace NUSGrabberGUI.Properties {
12 |
13 |
14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.9.0.0")]
16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
17 |
18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
19 |
20 | public static Settings Default {
21 | get {
22 | return defaultInstance;
23 | }
24 | }
25 |
26 | [global::System.Configuration.UserScopedSettingAttribute()]
27 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
28 | [global::System.Configuration.DefaultSettingValueAttribute("")]
29 | public string CommonKeyPath {
30 | get {
31 | return ((string)(this["CommonKeyPath"]));
32 | }
33 | set {
34 | this["CommonKeyPath"] = value;
35 | }
36 | }
37 |
38 | [global::System.Configuration.UserScopedSettingAttribute()]
39 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
40 | [global::System.Configuration.DefaultSettingValueAttribute("USA")]
41 | public string Region {
42 | get {
43 | return ((string)(this["Region"]));
44 | }
45 | set {
46 | this["Region"] = value;
47 | }
48 | }
49 |
50 | [global::System.Configuration.ApplicationScopedSettingAttribute()]
51 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
52 | [global::System.Configuration.DefaultSettingValueAttribute("beta")]
53 | public string VersionType {
54 | get {
55 | return ((string)(this["VersionType"]));
56 | }
57 | }
58 |
59 | [global::System.Configuration.UserScopedSettingAttribute()]
60 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
61 | [global::System.Configuration.DefaultSettingValueAttribute("False")]
62 | public bool Debug {
63 | get {
64 | return ((bool)(this["Debug"]));
65 | }
66 | set {
67 | this["Debug"] = value;
68 | }
69 | }
70 |
71 | [global::System.Configuration.UserScopedSettingAttribute()]
72 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
73 | [global::System.Configuration.DefaultSettingValueAttribute("True")]
74 | public bool HideNUS {
75 | get {
76 | return ((bool)(this["HideNUS"]));
77 | }
78 | set {
79 | this["HideNUS"] = value;
80 | }
81 | }
82 |
83 | [global::System.Configuration.UserScopedSettingAttribute()]
84 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
85 | [global::System.Configuration.DefaultSettingValueAttribute("False")]
86 | public bool AutoDecrypt {
87 | get {
88 | return ((bool)(this["AutoDecrypt"]));
89 | }
90 | set {
91 | this["AutoDecrypt"] = value;
92 | }
93 | }
94 |
95 | [global::System.Configuration.UserScopedSettingAttribute()]
96 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
97 | [global::System.Configuration.DefaultSettingValueAttribute("True")]
98 | public bool LoadTitles {
99 | get {
100 | return ((bool)(this["LoadTitles"]));
101 | }
102 | set {
103 | this["LoadTitles"] = value;
104 | }
105 | }
106 |
107 | [global::System.Configuration.UserScopedSettingAttribute()]
108 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
109 | [global::System.Configuration.DefaultSettingValueAttribute("False")]
110 | public bool UseEmbedNUS {
111 | get {
112 | return ((bool)(this["UseEmbedNUS"]));
113 | }
114 | set {
115 | this["UseEmbedNUS"] = value;
116 | }
117 | }
118 |
119 | [global::System.Configuration.UserScopedSettingAttribute()]
120 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
121 | [global::System.Configuration.DefaultSettingValueAttribute("False")]
122 | public bool ArchivedDatabase {
123 | get {
124 | return ((bool)(this["ArchivedDatabase"]));
125 | }
126 | set {
127 | this["ArchivedDatabase"] = value;
128 | }
129 | }
130 |
131 | [global::System.Configuration.UserScopedSettingAttribute()]
132 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
133 | [global::System.Configuration.DefaultSettingValueAttribute("True")]
134 | public bool Cleanup {
135 | get {
136 | return ((bool)(this["Cleanup"]));
137 | }
138 | set {
139 | this["Cleanup"] = value;
140 | }
141 | }
142 |
143 | [global::System.Configuration.UserScopedSettingAttribute()]
144 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
145 | [global::System.Configuration.DefaultSettingValueAttribute("False")]
146 | public bool UseOrigNUS {
147 | get {
148 | return ((bool)(this["UseOrigNUS"]));
149 | }
150 | set {
151 | this["UseOrigNUS"] = value;
152 | }
153 | }
154 |
155 | [global::System.Configuration.UserScopedSettingAttribute()]
156 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
157 | [global::System.Configuration.DefaultSettingValueAttribute("en")]
158 | public string Language {
159 | get {
160 | return ((string)(this["Language"]));
161 | }
162 | set {
163 | this["Language"] = value;
164 | }
165 | }
166 |
167 | [global::System.Configuration.ApplicationScopedSettingAttribute()]
168 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
169 | [global::System.Configuration.DefaultSettingValueAttribute("92")]
170 | public int Version {
171 | get {
172 | return ((int)(this["Version"]));
173 | }
174 | }
175 | }
176 | }
177 |
--------------------------------------------------------------------------------
/NUSGrabberGUI/Properties/Settings.settings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | USA
10 |
11 |
12 | beta
13 |
14 |
15 | False
16 |
17 |
18 | True
19 |
20 |
21 | False
22 |
23 |
24 | True
25 |
26 |
27 | False
28 |
29 |
30 | False
31 |
32 |
33 | True
34 |
35 |
36 | False
37 |
38 |
39 | en
40 |
41 |
42 | 92
43 |
44 |
45 |
--------------------------------------------------------------------------------
/NUSGrabberGUI/Properties/app.manifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
48 |
55 |
56 |
70 |
--------------------------------------------------------------------------------
/NUSGrabberGUI/Resources/CDecrypt.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FoxMcloud5655/NEW-NUSGrabberGUI/69047f56db6d545107751590e60f97a53bde6c77/NUSGrabberGUI/Resources/CDecrypt.exe
--------------------------------------------------------------------------------
/NUSGrabberGUI/Resources/HtmlAgilityPack.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FoxMcloud5655/NEW-NUSGrabberGUI/69047f56db6d545107751590e60f97a53bde6c77/NUSGrabberGUI/Resources/HtmlAgilityPack.dll
--------------------------------------------------------------------------------
/NUSGrabberGUI/Resources/NUSgrabber.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FoxMcloud5655/NEW-NUSGrabberGUI/69047f56db6d545107751590e60f97a53bde6c77/NUSGrabberGUI/Resources/NUSgrabber.exe
--------------------------------------------------------------------------------
/NUSGrabberGUI/Resources/NUSgrabberORIG.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FoxMcloud5655/NEW-NUSGrabberGUI/69047f56db6d545107751590e60f97a53bde6c77/NUSGrabberGUI/Resources/NUSgrabberORIG.exe
--------------------------------------------------------------------------------
/NUSGrabberGUI/Resources/libeay32.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FoxMcloud5655/NEW-NUSGrabberGUI/69047f56db6d545107751590e60f97a53bde6c77/NUSGrabberGUI/Resources/libeay32.dll
--------------------------------------------------------------------------------
/NUSGrabberGUI/Resources/vcruntime140.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FoxMcloud5655/NEW-NUSGrabberGUI/69047f56db6d545107751590e60f97a53bde6c77/NUSGrabberGUI/Resources/vcruntime140.dll
--------------------------------------------------------------------------------
/NUSGrabberGUI/Resources/wget.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FoxMcloud5655/NEW-NUSGrabberGUI/69047f56db6d545107751590e60f97a53bde6c77/NUSGrabberGUI/Resources/wget.exe
--------------------------------------------------------------------------------
/NUSGrabberGUI/Settings.Designer.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Drawing;
3 | using System.Windows.Forms;
4 | using System.ComponentModel;
5 |
6 | namespace NUSGrabberGUI
7 | {
8 | partial class SettingsForm
9 | {
10 | ///
11 | /// Required designer variable.
12 | ///
13 | private IContainer components = null;
14 |
15 | ///
16 | /// Clean up any resources being used.
17 | ///
18 | /// true if managed resources should be disposed; otherwise, false.
19 | protected override void Dispose(bool disposing)
20 | {
21 | if (disposing && (components != null))
22 | {
23 | components.Dispose();
24 | }
25 | base.Dispose(disposing);
26 | }
27 |
28 | #region Windows Form Designer generated code
29 |
30 | ///
31 | /// Required method for Designer support - do not modify
32 | /// the contents of this method with the code editor.
33 | ///
34 | private void InitializeComponent()
35 | {
36 | this.RegionBox = new System.Windows.Forms.ComboBox();
37 | this.RegionLabel = new System.Windows.Forms.Label();
38 | this.AboutButton = new System.Windows.Forms.Button();
39 | this.SaveCloseButton = new System.Windows.Forms.Button();
40 | this.UpdateButton = new System.Windows.Forms.Button();
41 | this.DecryptCheckBox = new System.Windows.Forms.CheckBox();
42 | this.HideCheckBox = new System.Windows.Forms.CheckBox();
43 | this.LoadCheckBox = new System.Windows.Forms.CheckBox();
44 | this.EmbedCheckBox = new System.Windows.Forms.CheckBox();
45 | this.ArchivedCheckBox = new System.Windows.Forms.CheckBox();
46 | this.CleanupCheckBox = new System.Windows.Forms.CheckBox();
47 | this.OrigCheckBox = new System.Windows.Forms.CheckBox();
48 | this.FAQButton = new System.Windows.Forms.Button();
49 | this.LanguageLabel = new System.Windows.Forms.Label();
50 | this.LanguageBox = new System.Windows.Forms.ComboBox();
51 | this.SuspendLayout();
52 | //
53 | // RegionBox
54 | //
55 | this.RegionBox.FormattingEnabled = true;
56 | this.RegionBox.Items.AddRange(new object[] {
57 | "USA",
58 | "EUR",
59 | "JPN"});
60 | this.RegionBox.Location = new System.Drawing.Point(30, 33);
61 | this.RegionBox.Name = "RegionBox";
62 | this.RegionBox.Size = new System.Drawing.Size(121, 21);
63 | this.RegionBox.TabIndex = 0;
64 | //
65 | // RegionLabel
66 | //
67 | this.RegionLabel.AutoSize = true;
68 | this.RegionLabel.Location = new System.Drawing.Point(13, 13);
69 | this.RegionLabel.Name = "RegionLabel";
70 | this.RegionLabel.Size = new System.Drawing.Size(262, 13);
71 | this.RegionLabel.TabIndex = 1;
72 | this.RegionLabel.Text = "Region - Select a region to download versionlists from:";
73 | //
74 | // AboutButton
75 | //
76 | this.AboutButton.Location = new System.Drawing.Point(12, 274);
77 | this.AboutButton.Name = "AboutButton";
78 | this.AboutButton.Size = new System.Drawing.Size(46, 23);
79 | this.AboutButton.TabIndex = 2;
80 | this.AboutButton.Text = "About";
81 | this.AboutButton.UseVisualStyleBackColor = true;
82 | this.AboutButton.Click += new System.EventHandler(this.AboutButton_Click);
83 | //
84 | // SaveCloseButton
85 | //
86 | this.SaveCloseButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;
87 | this.SaveCloseButton.Location = new System.Drawing.Point(246, 274);
88 | this.SaveCloseButton.Name = "SaveCloseButton";
89 | this.SaveCloseButton.Size = new System.Drawing.Size(97, 23);
90 | this.SaveCloseButton.TabIndex = 3;
91 | this.SaveCloseButton.Text = "Save and Close";
92 | this.SaveCloseButton.UseVisualStyleBackColor = true;
93 | this.SaveCloseButton.Click += new System.EventHandler(this.SaveCloseButton_Click);
94 | //
95 | // UpdateButton
96 | //
97 | this.UpdateButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;
98 | this.UpdateButton.Location = new System.Drawing.Point(135, 274);
99 | this.UpdateButton.Name = "UpdateButton";
100 | this.UpdateButton.Size = new System.Drawing.Size(105, 23);
101 | this.UpdateButton.TabIndex = 4;
102 | this.UpdateButton.Text = "Check for Updates";
103 | this.UpdateButton.UseVisualStyleBackColor = true;
104 | this.UpdateButton.Click += new System.EventHandler(this.UpdateButton_Click);
105 | //
106 | // DecryptCheckBox
107 | //
108 | this.DecryptCheckBox.AutoSize = true;
109 | this.DecryptCheckBox.Location = new System.Drawing.Point(16, 113);
110 | this.DecryptCheckBox.Name = "DecryptCheckBox";
111 | this.DecryptCheckBox.Size = new System.Drawing.Size(180, 17);
112 | this.DecryptCheckBox.TabIndex = 5;
113 | this.DecryptCheckBox.Text = "Automatically decrypt downloads";
114 | this.DecryptCheckBox.UseVisualStyleBackColor = true;
115 | //
116 | // HideCheckBox
117 | //
118 | this.HideCheckBox.AutoSize = true;
119 | this.HideCheckBox.Location = new System.Drawing.Point(16, 159);
120 | this.HideCheckBox.Name = "HideCheckBox";
121 | this.HideCheckBox.Size = new System.Drawing.Size(228, 17);
122 | this.HideCheckBox.TabIndex = 6;
123 | this.HideCheckBox.Text = "Hide NUSgrabber/wget while downloading";
124 | this.HideCheckBox.UseVisualStyleBackColor = true;
125 | //
126 | // LoadCheckBox
127 | //
128 | this.LoadCheckBox.AutoSize = true;
129 | this.LoadCheckBox.Location = new System.Drawing.Point(16, 136);
130 | this.LoadCheckBox.Name = "LoadCheckBox";
131 | this.LoadCheckBox.Size = new System.Drawing.Size(124, 17);
132 | this.LoadCheckBox.TabIndex = 7;
133 | this.LoadCheckBox.Text = "Load titles on startup";
134 | this.LoadCheckBox.UseVisualStyleBackColor = true;
135 | //
136 | // EmbedCheckBox
137 | //
138 | this.EmbedCheckBox.AutoSize = true;
139 | this.EmbedCheckBox.Checked = true;
140 | this.EmbedCheckBox.CheckState = System.Windows.Forms.CheckState.Checked;
141 | this.EmbedCheckBox.Location = new System.Drawing.Point(16, 251);
142 | this.EmbedCheckBox.Name = "EmbedCheckBox";
143 | this.EmbedCheckBox.Size = new System.Drawing.Size(167, 17);
144 | this.EmbedCheckBox.TabIndex = 8;
145 | this.EmbedCheckBox.Text = "Use experimental LibWiiSharp";
146 | this.EmbedCheckBox.UseVisualStyleBackColor = true;
147 | this.EmbedCheckBox.CheckedChanged += new System.EventHandler(this.EmbedCheckBox_CheckedChanged);
148 | //
149 | // ArchivedCheckBox
150 | //
151 | this.ArchivedCheckBox.AutoSize = true;
152 | this.ArchivedCheckBox.Location = new System.Drawing.Point(16, 205);
153 | this.ArchivedCheckBox.Name = "ArchivedCheckBox";
154 | this.ArchivedCheckBox.Size = new System.Drawing.Size(218, 17);
155 | this.ArchivedCheckBox.TabIndex = 9;
156 | this.ArchivedCheckBox.Text = "Load archived database instead of latest";
157 | this.ArchivedCheckBox.UseVisualStyleBackColor = true;
158 | //
159 | // CleanupCheckBox
160 | //
161 | this.CleanupCheckBox.AutoSize = true;
162 | this.CleanupCheckBox.Location = new System.Drawing.Point(16, 228);
163 | this.CleanupCheckBox.Name = "CleanupCheckBox";
164 | this.CleanupCheckBox.Size = new System.Drawing.Size(148, 17);
165 | this.CleanupCheckBox.TabIndex = 10;
166 | this.CleanupCheckBox.Text = "Cleanup resources on exit";
167 | this.CleanupCheckBox.UseVisualStyleBackColor = true;
168 | //
169 | // OrigCheckBox
170 | //
171 | this.OrigCheckBox.AutoSize = true;
172 | this.OrigCheckBox.Location = new System.Drawing.Point(16, 182);
173 | this.OrigCheckBox.Name = "OrigCheckBox";
174 | this.OrigCheckBox.Size = new System.Drawing.Size(145, 17);
175 | this.OrigCheckBox.TabIndex = 11;
176 | this.OrigCheckBox.Text = "Use original NUSGrabber";
177 | this.OrigCheckBox.UseVisualStyleBackColor = true;
178 | //
179 | // FAQButton
180 | //
181 | this.FAQButton.Location = new System.Drawing.Point(64, 274);
182 | this.FAQButton.Name = "FAQButton";
183 | this.FAQButton.Size = new System.Drawing.Size(65, 23);
184 | this.FAQButton.TabIndex = 12;
185 | this.FAQButton.Text = "Help/FAQ";
186 | this.FAQButton.UseVisualStyleBackColor = true;
187 | this.FAQButton.Click += new System.EventHandler(this.FAQButton_Click);
188 | //
189 | // LanguageLabel
190 | //
191 | this.LanguageLabel.AutoSize = true;
192 | this.LanguageLabel.Location = new System.Drawing.Point(13, 64);
193 | this.LanguageLabel.Name = "LanguageLabel";
194 | this.LanguageLabel.Size = new System.Drawing.Size(220, 13);
195 | this.LanguageLabel.TabIndex = 14;
196 | this.LanguageLabel.Text = "Language - Select a language to translate to:";
197 | //
198 | // LanguageBox
199 | //
200 | this.LanguageBox.FormattingEnabled = true;
201 | this.LanguageBox.Items.AddRange(new object[] {
202 | "en"});
203 | this.LanguageBox.Location = new System.Drawing.Point(30, 84);
204 | this.LanguageBox.Name = "LanguageBox";
205 | this.LanguageBox.Size = new System.Drawing.Size(121, 21);
206 | this.LanguageBox.TabIndex = 13;
207 | //
208 | // SettingsForm
209 | //
210 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
211 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
212 | this.CancelButton = this.SaveCloseButton;
213 | this.ClientSize = new System.Drawing.Size(355, 309);
214 | this.Controls.Add(this.LanguageLabel);
215 | this.Controls.Add(this.LanguageBox);
216 | this.Controls.Add(this.FAQButton);
217 | this.Controls.Add(this.OrigCheckBox);
218 | this.Controls.Add(this.CleanupCheckBox);
219 | this.Controls.Add(this.ArchivedCheckBox);
220 | this.Controls.Add(this.EmbedCheckBox);
221 | this.Controls.Add(this.LoadCheckBox);
222 | this.Controls.Add(this.HideCheckBox);
223 | this.Controls.Add(this.DecryptCheckBox);
224 | this.Controls.Add(this.UpdateButton);
225 | this.Controls.Add(this.SaveCloseButton);
226 | this.Controls.Add(this.AboutButton);
227 | this.Controls.Add(this.RegionLabel);
228 | this.Controls.Add(this.RegionBox);
229 | this.Name = "SettingsForm";
230 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
231 | this.Text = "Settings";
232 | this.ResumeLayout(false);
233 | this.PerformLayout();
234 |
235 | }
236 |
237 | #endregion
238 |
239 | private ComboBox RegionBox;
240 | private Label RegionLabel;
241 | private Button AboutButton;
242 | private Button SaveCloseButton;
243 | private Button UpdateButton;
244 | private CheckBox DecryptCheckBox;
245 | private CheckBox HideCheckBox;
246 | private CheckBox LoadCheckBox;
247 | private CheckBox EmbedCheckBox;
248 | private CheckBox ArchivedCheckBox;
249 | private CheckBox CleanupCheckBox;
250 | private CheckBox OrigCheckBox;
251 | private Button FAQButton;
252 | private Label LanguageLabel;
253 | private ComboBox LanguageBox;
254 | }
255 | }
--------------------------------------------------------------------------------
/NUSGrabberGUI/Settings.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Windows.Forms;
3 |
4 | namespace NUSGrabberGUI
5 | {
6 | public partial class SettingsForm : Form
7 | {
8 | public SettingsForm(bool debug)
9 | {
10 | InitializeComponent();
11 | UpdateButton.Enabled = !Properties.Settings.Default.Debug;
12 | RegionBox.Text = Properties.Settings.Default.Region;
13 | LanguageBox.Text = Properties.Settings.Default.Language;
14 | HideCheckBox.Checked = Properties.Settings.Default.HideNUS;
15 | LoadCheckBox.Checked = Properties.Settings.Default.LoadTitles;
16 | DecryptCheckBox.Checked = Properties.Settings.Default.AutoDecrypt;
17 | EmbedCheckBox.Checked = Properties.Settings.Default.UseEmbedNUS;
18 | ArchivedCheckBox.Checked = Properties.Settings.Default.ArchivedDatabase;
19 | if (Properties.Settings.Default.Debug) Properties.Settings.Default.Cleanup = false;
20 | CleanupCheckBox.Checked = Properties.Settings.Default.Cleanup;
21 | OrigCheckBox.Checked = Properties.Settings.Default.UseOrigNUS;
22 | CleanupCheckBox.Enabled = !debug;
23 | EmbedCheckBox.Visible = Properties.Settings.Default.Debug;
24 | HideCheckBox.Enabled = !EmbedCheckBox.Checked;
25 | }
26 |
27 | private void SaveCloseButton_Click(object sender, EventArgs e)
28 | {
29 | if (!RegionBox.Items.Contains(RegionBox.Text))
30 | if (MessageBox.Show("You have entered in a manual override to the region. If not an actual region, this can and will " +
31 | "cause errors. Are you sure you want to do this?", "Confirm Non-Standard Region",
32 | MessageBoxButtons.YesNo) == DialogResult.No) { RegionBox.Text = "USA"; return; }
33 | if (!LanguageBox.Items.Contains(LanguageBox.Text))
34 | if (MessageBox.Show("You have entered in a manual override to the language. If not an actual language, this can and " +
35 | "will cause errors. Are you sure you want to do this?", "Confirm Custom Language",
36 | MessageBoxButtons.YesNo) == DialogResult.No) { LanguageBox.Text = "en"; return; }
37 | Properties.Settings.Default.Region = RegionBox.Text;
38 | Properties.Settings.Default.Language = LanguageBox.Text;
39 | Properties.Settings.Default.HideNUS = HideCheckBox.Checked;
40 | Properties.Settings.Default.AutoDecrypt = DecryptCheckBox.Checked;
41 | Properties.Settings.Default.LoadTitles = LoadCheckBox.Checked;
42 | Properties.Settings.Default.UseEmbedNUS = EmbedCheckBox.Checked;
43 | Properties.Settings.Default.ArchivedDatabase = ArchivedCheckBox.Checked;
44 | Properties.Settings.Default.Cleanup = CleanupCheckBox.Checked;
45 | Properties.Settings.Default.UseOrigNUS = OrigCheckBox.Checked;
46 | Properties.Settings.Default.Save();
47 | Close();
48 | }
49 |
50 | private void AboutButton_Click(object sender, EventArgs e)
51 | {
52 | float version_float = (float)Properties.Settings.Default.Version / 100;
53 | MessageBox.Show("Created by: FoxMcloud5655\n" +
54 | "NUSgrabber/CDecrypt by: crediar\n" +
55 | "Original GUI by: Adr990\n" +
56 | "Contributors: akorb, Warix3\n\n" +
57 | "Version " + version_float + ' ' + Properties.Settings.Default.VersionType + (Properties.Settings.Default.Debug ? " DEBUG" : ""));
58 | }
59 |
60 | private void UpdateButton_Click(object sender, EventArgs e)
61 | {
62 | NUSGrabberForm update = new NUSGrabberForm(true);
63 | update.CheckForUpdates(false);
64 | update.Close();
65 | }
66 |
67 | private void EmbedCheckBox_CheckedChanged(object sender, EventArgs e)
68 | {
69 | if (EmbedCheckBox.Checked)
70 | {
71 | if (MessageBox.Show("This is an experimental feature which is not useful to the general public right now, as it " +
72 | "is configured to use the old method of file storage. Are you sure you want to disable using NUSGrabber.exe?",
73 | "Confirm Experimental Testing", MessageBoxButtons.YesNo) == DialogResult.No)
74 | {
75 | EmbedCheckBox.Checked = false;
76 | }
77 | }
78 | HideCheckBox.Enabled = !EmbedCheckBox.Checked;
79 | }
80 |
81 | private void FAQButton_Click(object sender, EventArgs e)
82 | {
83 | MessageBox.Show(
84 | "How to download a game update:\n" +
85 | "1. Update your versionlists by hitting \"Update Versionlists\" on the main screen of the program. " +
86 | "(You can skip updating the versionlists if you know they are up to date.)\n" +
87 | "2. Search for the title that you want to update and click on it.\n" +
88 | "3. Select a version from the list on the right side. (This step is optional if you want the latest version.)\n" +
89 | "4. Hit the download button and wait.\n\n" +
90 |
91 | "How to install a game update that was downloaded:\n" +
92 | "You'll need to put ALL the files that you downloaded (stored in the root directory of the program, in a subdirectory " +
93 | "with the titleid, and optionally a version if you selected one. Example: \"\\rootdir\\titleid\\version\\\") " +
94 | "from this program (WITHOUT decrypting them) onto your SD Card in a folder called \"install\". So, let's say that " +
95 | "your SD Card was mounted as the F: drive. An example of how the folder structure should look like this: (F:\\install\\)\n\n" +
96 |
97 | "How to decrypt a game update for use with Loadiine:\n" +
98 | "1. Hit the decrypt button.\n" +
99 | "2. Navigate to folder which was just created (if you selected a specific version, then it would be \"\\rootdir\\titleid\\version\\\", " +
100 | "but if you got the latest version, then it would be \"\\rootdir\\titleid\\\").\n" +
101 | "3. Select the \".bin\" of the Wii U Common key (which you have to obtain yourself).\n" +
102 | "4. Wait for the decryption to complete.\n\n" +
103 |
104 | "How to install a decrypted game update:\n" +
105 | "1. Copy all of the folders that were created in the decrypt process (located in the root directory of the program, in a " +
106 | "subdirectory with the titleid, and optionally a version if you selected one. [Example: \"\\rootdir\\titleid\\version\\\". " +
107 | "If you got the latest version, then instead it would be \"\\rootdir\\titleid\\\"])\n" +
108 | "2. Optionally, make a backup of the original files for the decrypted game on your SD Card.\n" +
109 | "3. Paste and overwrite the folders inside the game you are updating on your SD Card.\n\n" +
110 |
111 | "How to download a system title: (Instructions are a work in progress.)\n" +
112 | "Coming Soon... This feature isn't ready yet, but if you'd like to speed this part up, let me know on GitHub by opening an issue!\n\n" +
113 |
114 | "How to download a full title:\n" +
115 | "1. Search for the title that you want to download and click on it.\n" +
116 | "2. Hit the download button and wait.\n" +
117 | "Decrypting the full title uses the same process as the game updates.\n\n" +
118 |
119 | "How to install a full title: (Instructions are a work in progress.)\n" +
120 | "1. Copy all the folders that were created when you decrypted the title (stored in the root directory of the program, in a " +
121 | "subdirectory with the titleid. Example: \"\\rootdir\\titleid\\\").\n" +
122 | "2. Create a new directory on your SD Card where Loadiine loads from.\n" +
123 | "3. Paste the folders in your newly created directory.\n\n" +
124 |
125 | "If a question you have isn't answered here, hit me up on GBATemp! My username is FoxMcloud5655.");
126 | }
127 | }
128 | }
129 |
--------------------------------------------------------------------------------
/NUSGrabberGUI/Settings.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
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 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
--------------------------------------------------------------------------------
/NUSGrabberGUI/Shared.cs:
--------------------------------------------------------------------------------
1 | /* This file is part of libWiiSharp
2 | * Copyright (C) 2009 Leathl
3 | *
4 | * libWiiSharp is free software: you can redistribute it and/or
5 | * modify it under the terms of the GNU General Public License as published
6 | * by the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * libWiiSharp is distributed in the hope that it will be
10 | * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
11 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 |
18 | using System;
19 | using System.Collections.Generic;
20 | using System.Net;
21 |
22 | namespace libWiiSharp
23 | {
24 | public static class Shared
25 | {
26 | ///
27 | /// Merges two string arrays into one without double entries.
28 | ///
29 | ///
30 | ///
31 | ///
32 | public static string[] MergeStringArrays(string[] a, string[] b)
33 | {
34 | List sList = new List(a);
35 |
36 | foreach (string currentString in b)
37 | if (!sList.Contains(currentString)) sList.Add(currentString);
38 |
39 | sList.Sort();
40 | return sList.ToArray();
41 | }
42 |
43 | ///
44 | /// Compares two byte arrays.
45 | ///
46 | ///
47 | ///
48 | ///
49 | ///
50 | ///
51 | ///
52 | public static bool CompareByteArrays(byte[] first, int firstIndex, byte[] second, int secondIndex, int length)
53 | {
54 | if (first.Length < length || second.Length < length) return false;
55 |
56 | for (int i = 0; i < length; i++)
57 | if (first[firstIndex + i] != second[secondIndex + i]) return false;
58 |
59 | return true;
60 | }
61 |
62 | ///
63 | /// Compares two byte arrays.
64 | ///
65 | ///
66 | ///
67 | ///
68 | public static bool CompareByteArrays(byte[] first, byte[] second)
69 | {
70 | if (first.Length != second.Length) return false;
71 | else
72 | for (int i = 0; i < first.Length; i++)
73 | if (first[i] != second[i]) return false;
74 |
75 | return true;
76 | }
77 |
78 | ///
79 | /// Turns a byte array into a string, default separator is a space.
80 | ///
81 | ///
82 | ///
83 | ///
84 | public static string ByteArrayToString(byte[] byteArray, char separator = ' ')
85 | {
86 | string res = string.Empty;
87 |
88 | foreach (byte b in byteArray)
89 | res += b.ToString("x2").ToUpper() + separator;
90 |
91 | return res.Remove(res.Length - 1);
92 | }
93 |
94 | ///
95 | /// Turns a hex string into a byte array.
96 | ///
97 | ///
98 | ///
99 | public static byte[] HexStringToByteArray(string hexString)
100 | {
101 | byte[] ba = new byte[hexString.Length / 2];
102 |
103 | for (int i = 0; i < hexString.Length / 2; i++)
104 | ba[i] = byte.Parse(hexString.Substring(i * 2, 2), System.Globalization.NumberStyles.HexNumber);
105 |
106 | return ba;
107 | }
108 |
109 | ///
110 | /// Counts how often the given char exists in the given string.
111 | ///
112 | ///
113 | ///
114 | ///
115 | public static int CountCharsInString(string theString, char theChar)
116 | {
117 | int count = 0;
118 |
119 | foreach (char thisChar in theString)
120 | if (thisChar == theChar)
121 | count++;
122 |
123 | return count;
124 | }
125 |
126 | ///
127 | /// Pads the given value to a multiple of the given padding value, default padding value is 64.
128 | ///
129 | ///
130 | ///
131 | public static long AddPadding(long value)
132 | {
133 | return AddPadding(value, 64);
134 | }
135 |
136 | ///
137 | /// Pads the given value to a multiple of the given padding value, default padding value is 64.
138 | ///
139 | ///
140 | ///
141 | ///
142 | public static long AddPadding(long value, int padding)
143 | {
144 | if (value % padding != 0)
145 | {
146 | value = value + (padding - (value % padding));
147 | }
148 |
149 | return value;
150 | }
151 |
152 | ///
153 | /// Pads the given value to a multiple of the given padding value, default padding value is 64.
154 | ///
155 | ///
156 | ///
157 | public static int AddPadding(int value)
158 | {
159 | return AddPadding(value, 64);
160 | }
161 |
162 | ///
163 | /// Pads the given value to a multiple of the given padding value, default padding value is 64.
164 | ///
165 | ///
166 | ///
167 | ///
168 | public static int AddPadding(int value, int padding)
169 | {
170 | if (value % padding != 0)
171 | {
172 | value = value + (padding - (value % padding));
173 | }
174 |
175 | return value;
176 | }
177 |
178 | ///
179 | /// Swaps endianness.
180 | ///
181 | ///
182 | ///
183 | public static ushort Swap(ushort value)
184 | {
185 | return (ushort)IPAddress.HostToNetworkOrder((short)value);
186 | }
187 |
188 | ///
189 | /// Swaps endianness.
190 | ///
191 | ///
192 | ///
193 | public static uint Swap(uint value)
194 | {
195 | return (uint)IPAddress.HostToNetworkOrder((int)value);
196 | }
197 |
198 | ///
199 | /// Swaps endianness
200 | ///
201 | ///
202 | ///
203 | public static ulong Swap(ulong value)
204 | {
205 | return (ulong)IPAddress.HostToNetworkOrder((long)value);
206 | }
207 |
208 | ///
209 | /// Turns a ushort array into a byte array.
210 | ///
211 | ///
212 | ///
213 | public static byte[] UShortArrayToByteArray(ushort[] array)
214 | {
215 | List results = new List();
216 | foreach (ushort value in array)
217 | {
218 | byte[] converted = BitConverter.GetBytes(value);
219 | results.AddRange(converted);
220 | }
221 | return results.ToArray();
222 | }
223 |
224 | ///
225 | /// Turns a uint array into a byte array.
226 | ///
227 | ///
228 | ///
229 | public static byte[] UIntArrayToByteArray(uint[] array)
230 | {
231 | List results = new List();
232 | foreach (uint value in array)
233 | {
234 | byte[] converted = BitConverter.GetBytes(value);
235 | results.AddRange(converted);
236 | }
237 | return results.ToArray();
238 | }
239 |
240 | ///
241 | /// Turns a byte array into a uint array.
242 | ///
243 | ///
244 | ///
245 | public static uint[] ByteArrayToUIntArray(byte[] array)
246 | {
247 | UInt32[] converted = new UInt32[array.Length / 4];
248 | int j = 0;
249 |
250 | for (int i = 0; i < array.Length; i += 4)
251 | converted[j++] = BitConverter.ToUInt32(array, i);
252 |
253 | return converted;
254 | }
255 |
256 | ///
257 | /// Turns a byte array into a ushort array.
258 | ///
259 | ///
260 | ///
261 | public static ushort[] ByteArrayToUShortArray(byte[] array)
262 | {
263 | ushort[] converted = new ushort[array.Length / 2];
264 | int j = 0;
265 |
266 | for (int i = 0; i < array.Length; i += 2)
267 | converted[j++] = BitConverter.ToUInt16(array, i);
268 |
269 | return converted;
270 | }
271 | }
272 | }
273 |
--------------------------------------------------------------------------------
/NUSGrabberGUI/Ticket.cs:
--------------------------------------------------------------------------------
1 | /* This file is part of libWiiSharp
2 | * Copyright (C) 2009 Leathl
3 | *
4 | * libWiiSharp is free software: you can redistribute it and/or
5 | * modify it under the terms of the GNU General Public License as published
6 | * by the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * libWiiSharp is distributed in the hope that it will be
10 | * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
11 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 |
18 | using System;
19 | using System.IO;
20 | using System.Security.Cryptography;
21 |
22 | namespace libWiiSharp
23 | {
24 | public enum CommonKeyType : byte
25 | {
26 | Standard = 0x00,
27 | Korean = 0x01,
28 | }
29 |
30 | public class Ticket : IDisposable
31 | {
32 | private byte newKeyIndex = (byte)CommonKeyType.Standard;
33 | private byte[] decryptedTitleKey = new byte[16];
34 | private bool fakeSign = false;
35 | private bool titleKeyChanged = false;
36 | private byte[] newEncryptedTitleKey = new byte[0];
37 | private bool reDecrypt = false;
38 |
39 | private uint signatureExponent = 0x00010001;
40 | private byte[] signature = new byte[256];
41 | private byte[] padding = new byte[60];
42 | private byte[] issuer = new byte[64];
43 | private byte[] unknown = new byte[63];
44 | private byte[] encryptedTitleKey = new byte[16];
45 | private byte unknown2;
46 | private ulong ticketId;
47 | private uint consoleId;
48 | private ulong titleId;
49 | private ushort unknown3 = 0xFFFF;
50 | private ushort numOfDlc;
51 | private ulong unknown4;
52 | private byte padding2;
53 | private byte commonKeyIndex = (byte)CommonKeyType.Standard;
54 | private byte[] unknown5 = new byte[48];
55 | private byte[] unknown6 = new byte[32]; //0xFF
56 | private ushort padding3;
57 | private uint enableTimeLimit;
58 | private uint timeLimit;
59 | private byte[] padding4 = new byte[88];
60 |
61 | private bool dsitik = false;
62 |
63 | ///
64 | /// The Title Key the WADs content is encrypted with.
65 | ///
66 | public byte[] TitleKey { get { return decryptedTitleKey; } set { decryptedTitleKey = value; titleKeyChanged = true; reDecrypt = false; } }
67 | ///
68 | /// Defines which Common Key is used (Standard / Korean).
69 | ///
70 | public CommonKeyType CommonKeyIndex { get { return (CommonKeyType)newKeyIndex; } set { newKeyIndex = (byte)value; } }
71 | ///
72 | /// The Ticket ID.
73 | ///
74 | public ulong TicketID { get { return ticketId; } set { ticketId = value; } }
75 | ///
76 | /// The Console ID.
77 | ///
78 | public uint ConsoleID { get { return consoleId; } set { consoleId = value; } }
79 | ///
80 | /// The Title ID.
81 | ///
82 | public ulong TitleID { get { return titleId; } set { titleId = value; if (reDecrypt) reDecryptTitleKey(); } }
83 | ///
84 | /// Number of DLC.
85 | ///
86 | public ushort NumOfDLC { get { return numOfDlc; } set { numOfDlc = value; } }
87 | ///
88 | /// If true, the Ticket will be fakesigned while saving.
89 | ///
90 | public bool FakeSign { get { return fakeSign; } set { fakeSign = value; } }
91 | ///
92 | /// True if the Title Key was changed.
93 | ///
94 | public bool TitleKeyChanged { get { return titleKeyChanged; } }
95 |
96 | ///
97 | /// If true, the Ticket will utilize the DSi CommonKey.
98 | ///
99 | public bool DSiTicket { get { return dsitik; } set { dsitik = value; decryptTitleKey(); } }
100 |
101 | #region IDisposable Members
102 | private bool isDisposed = false;
103 |
104 | ~Ticket()
105 | {
106 | Dispose(false);
107 | }
108 |
109 | public void Dispose()
110 | {
111 | Dispose(true);
112 | GC.SuppressFinalize(this);
113 | }
114 |
115 | protected virtual void Dispose(bool disposing)
116 | {
117 | if (disposing && !isDisposed)
118 | {
119 | decryptedTitleKey = null;
120 | newEncryptedTitleKey = null;
121 | signature = null;
122 | padding = null;
123 | issuer = null;
124 | unknown = null;
125 | encryptedTitleKey = null;
126 | unknown5 = null;
127 | unknown6 = null;
128 | padding4 = null;
129 | }
130 |
131 | isDisposed = true;
132 | }
133 | #endregion
134 |
135 | #region Public Functions
136 | ///
137 | /// Loads a tik file.
138 | ///
139 | ///
140 | ///
141 | public static Ticket Load(string pathToTicket)
142 | {
143 | return Load(File.ReadAllBytes(pathToTicket));
144 | }
145 |
146 | ///
147 | /// Loads a tik file.
148 | ///
149 | ///
150 | ///
151 | public static Ticket Load(byte[] ticket)
152 | {
153 | Ticket tik = new Ticket();
154 | MemoryStream ms = new MemoryStream(ticket);
155 |
156 | try { tik.parseTicket(ms); }
157 | catch { ms.Dispose(); throw; }
158 |
159 | ms.Dispose();
160 | return tik;
161 | }
162 |
163 | ///
164 | /// Loads a tik file.
165 | ///
166 | ///
167 | ///
168 | public static Ticket Load(Stream ticket)
169 | {
170 | Ticket tik = new Ticket();
171 | tik.parseTicket(ticket);
172 | return tik;
173 | }
174 |
175 |
176 |
177 | ///
178 | /// Loads a tik file.
179 | ///
180 | ///
181 | public void LoadFile(string pathToTicket)
182 | {
183 | LoadFile(File.ReadAllBytes(pathToTicket));
184 | }
185 |
186 | ///
187 | /// Loads a tik file.
188 | ///
189 | ///
190 | public void LoadFile(byte[] ticket)
191 | {
192 | MemoryStream ms = new MemoryStream(ticket);
193 |
194 | try { parseTicket(ms); }
195 | catch { ms.Dispose(); throw; }
196 |
197 | ms.Dispose();
198 | }
199 |
200 | ///
201 | /// Loads a tik file.
202 | ///
203 | ///
204 | public void LoadFile(Stream ticket)
205 | {
206 | parseTicket(ticket);
207 | }
208 |
209 |
210 |
211 | ///
212 | /// Saves the Ticket.
213 | ///
214 | ///
215 | public void Save(string savePath)
216 | {
217 | Save(savePath, false);
218 | }
219 |
220 | ///
221 | /// Saves the Ticket. If fakeSign is true, the Ticket will be fakesigned.
222 | ///
223 | ///
224 | ///
225 | public void Save(string savePath, bool fakeSign)
226 | {
227 | if (fakeSign) this.fakeSign = true;
228 | if (File.Exists(savePath)) File.Delete(savePath);
229 |
230 | using (FileStream fs = new FileStream(savePath, FileMode.Create))
231 | writeToStream(fs);
232 | }
233 |
234 | ///
235 | /// Returns the Ticket as a memory stream.
236 | ///
237 | ///
238 | public MemoryStream ToMemoryStream()
239 | {
240 | return ToMemoryStream(false);
241 | }
242 |
243 | ///
244 | /// Returns the Ticket as a memory stream. If fakeSign is true, the Ticket will be fakesigned.
245 | ///
246 | ///
247 | ///
248 | public MemoryStream ToMemoryStream(bool fakeSign)
249 | {
250 | if (fakeSign) this.fakeSign = true;
251 | MemoryStream ms = new MemoryStream();
252 |
253 | try { writeToStream(ms); }
254 | catch { ms.Dispose(); throw; }
255 |
256 | return ms;
257 | }
258 |
259 | ///
260 | /// Returns the Ticket as a byte array.
261 | ///
262 | ///
263 | public byte[] ToByteArray()
264 | {
265 | return ToByteArray(false);
266 | }
267 |
268 | ///
269 | /// Returns the Ticket as a byte array. If fakeSign is true, the Ticket will be fakesigned.
270 | ///
271 | ///
272 | ///
273 | public byte[] ToByteArray(bool fakeSign)
274 | {
275 | if (fakeSign) this.fakeSign = true;
276 | MemoryStream ms = new MemoryStream();
277 |
278 | try { writeToStream(ms); }
279 | catch { ms.Dispose(); throw; }
280 |
281 | byte[] res = ms.ToArray();
282 | ms.Dispose();
283 | return res;
284 | }
285 |
286 | ///
287 | /// This will set a new encrypted Title Key (i.e. the one that you can "read" in the Ticket).
288 | ///
289 | ///
290 | public void SetTitleKey(string newTitleKey)
291 | {
292 | SetTitleKey(newTitleKey.ToCharArray());
293 | }
294 |
295 | ///
296 | /// This will set a new encrypted Title Key (i.e. the one that you can "read" in the Ticket).
297 | ///
298 | ///
299 | public void SetTitleKey(char[] newTitleKey)
300 | {
301 | if (newTitleKey.Length != 16)
302 | throw new Exception("The title key must be 16 characters long!");
303 |
304 | for (int i = 0; i < 16; i++)
305 | encryptedTitleKey[i] = (byte)newTitleKey[i];
306 |
307 | decryptTitleKey();
308 | titleKeyChanged = true;
309 |
310 | reDecrypt = true;
311 | newEncryptedTitleKey = encryptedTitleKey;
312 | }
313 |
314 | ///
315 | /// This will set a new encrypted Title Key (i.e. the one that you can "read" in the Ticket).
316 | ///
317 | ///
318 | public void SetTitleKey(byte[] newTitleKey)
319 | {
320 | if (newTitleKey.Length != 16)
321 | throw new Exception("The title key must be 16 characters long!");
322 |
323 | encryptedTitleKey = newTitleKey;
324 | decryptTitleKey();
325 | titleKeyChanged = true;
326 |
327 | reDecrypt = true;
328 | newEncryptedTitleKey = newTitleKey;
329 | }
330 |
331 | ///
332 | /// Returns the Upper Title ID as a string.
333 | ///
334 | ///
335 | public string GetUpperTitleID()
336 | {
337 | byte[] titleBytes = BitConverter.GetBytes(Shared.Swap((uint)titleId));
338 | return new string(new char[] { (char)titleBytes[0], (char)titleBytes[1], (char)titleBytes[2], (char)titleBytes[3] });
339 | }
340 | #endregion
341 |
342 | #region Private Functions
343 | private void writeToStream(Stream writeStream)
344 | {
345 | fireDebug("Writing Ticket...");
346 |
347 | fireDebug(" Encrypting Title Key...");
348 | encryptTitleKey();
349 | fireDebug(" -> Decrypted Title Key: {0}", Shared.ByteArrayToString(decryptedTitleKey));
350 | fireDebug(" -> Encrypted Title Key: {0}", Shared.ByteArrayToString(encryptedTitleKey));
351 |
352 | if (fakeSign)
353 | { fireDebug(" Clearing Signature..."); signature = new byte[256]; } //Clear Signature if we fake Sign
354 |
355 | MemoryStream ms = new MemoryStream();
356 | ms.Seek(0, SeekOrigin.Begin);
357 |
358 | fireDebug(" Writing Signature Exponent... (Offset: 0x{0})", ms.Position.ToString("x8").ToUpper());
359 | ms.Write(BitConverter.GetBytes(Shared.Swap(signatureExponent)), 0, 4);
360 |
361 | fireDebug(" Writing Signature... (Offset: 0x{0})", ms.Position.ToString("x8").ToUpper());
362 | ms.Write(signature, 0, signature.Length);
363 |
364 | fireDebug(" Writing Padding... (Offset: 0x{0})", ms.Position.ToString("x8").ToUpper());
365 | ms.Write(padding, 0, padding.Length);
366 |
367 | fireDebug(" Writing Issuer... (Offset: 0x{0})", ms.Position.ToString("x8").ToUpper());
368 | ms.Write(issuer, 0, issuer.Length);
369 |
370 | fireDebug(" Writing Unknown... (Offset: 0x{0})", ms.Position.ToString("x8").ToUpper());
371 | ms.Write(unknown, 0, unknown.Length);
372 |
373 | fireDebug(" Writing Title Key... (Offset: 0x{0})", ms.Position.ToString("x8").ToUpper());
374 | ms.Write(encryptedTitleKey, 0, encryptedTitleKey.Length);
375 |
376 | fireDebug(" Writing Unknown2... (Offset: 0x{0})", ms.Position.ToString("x8").ToUpper());
377 | ms.WriteByte(unknown2);
378 |
379 | fireDebug(" Writing Ticket ID... (Offset: 0x{0})", ms.Position.ToString("x8").ToUpper());
380 | ms.Write(BitConverter.GetBytes(Shared.Swap(ticketId)), 0, 8);
381 |
382 | fireDebug(" Writing Console ID... (Offset: 0x{0})", ms.Position.ToString("x8").ToUpper());
383 | ms.Write(BitConverter.GetBytes(Shared.Swap(consoleId)), 0, 4);
384 |
385 | fireDebug(" Writing Title ID... (Offset: 0x{0})", ms.Position.ToString("x8").ToUpper());
386 | ms.Write(BitConverter.GetBytes(Shared.Swap(titleId)), 0, 8);
387 |
388 | fireDebug(" Writing Unknwon3... (Offset: 0x{0})", ms.Position.ToString("x8").ToUpper());
389 | ms.Write(BitConverter.GetBytes(Shared.Swap(unknown3)), 0, 2);
390 |
391 | fireDebug(" Writing NumOfDLC... (Offset: 0x{0})", ms.Position.ToString("x8").ToUpper());
392 | ms.Write(BitConverter.GetBytes(Shared.Swap(numOfDlc)), 0, 2);
393 |
394 | fireDebug(" Writing Unknwon4... (Offset: 0x{0})", ms.Position.ToString("x8").ToUpper());
395 | ms.Write(BitConverter.GetBytes(Shared.Swap(unknown4)), 0, 8);
396 |
397 | fireDebug(" Writing Padding2... (Offset: 0x{0})", ms.Position.ToString("x8").ToUpper());
398 | ms.WriteByte(padding2);
399 |
400 | fireDebug(" Writing Common Key Index... (Offset: 0x{0})", ms.Position.ToString("x8").ToUpper());
401 | ms.WriteByte(commonKeyIndex);
402 |
403 | fireDebug(" Writing Unknown5... (Offset: 0x{0})", ms.Position.ToString("x8").ToUpper());
404 | ms.Write(unknown5, 0, unknown5.Length);
405 |
406 | fireDebug(" Writing Unknown6... (Offset: 0x{0})", ms.Position.ToString("x8").ToUpper());
407 | ms.Write(unknown6, 0, unknown6.Length);
408 |
409 | fireDebug(" Writing Padding3... (Offset: 0x{0})", ms.Position.ToString("x8").ToUpper());
410 | ms.Write(BitConverter.GetBytes(Shared.Swap(padding3)), 0, 2);
411 |
412 | fireDebug(" Writing Enable Time Limit... (Offset: 0x{0})", ms.Position.ToString("x8").ToUpper());
413 | ms.Write(BitConverter.GetBytes(Shared.Swap(enableTimeLimit)), 0, 4);
414 |
415 | fireDebug(" Writing Time Limit... (Offset: 0x{0})", ms.Position.ToString("x8").ToUpper());
416 | ms.Write(BitConverter.GetBytes(Shared.Swap(timeLimit)), 0, 4);
417 |
418 | fireDebug(" Writing Padding4... (Offset: 0x{0})", ms.Position.ToString("x8").ToUpper());
419 | ms.Write(padding4, 0, padding4.Length);
420 |
421 | byte[] tik = ms.ToArray();
422 | ms.Dispose();
423 |
424 | //fake Sign
425 | if (fakeSign)
426 | {
427 | fireDebug(" Fakesigning Ticket...");
428 |
429 | byte[] hash = new byte[20];
430 | SHA1 s = SHA1.Create();
431 |
432 | for (ushort i = 0; i < 0xFFFF; i++)
433 | {
434 | byte[] bytes = BitConverter.GetBytes(i);
435 | tik[498] = bytes[1]; tik[499] = bytes[0];
436 |
437 | hash = s.ComputeHash(tik);
438 | if (hash[0] == 0x00)
439 | { fireDebug(" -> Signed ({0})", i); break; } //Win! It's signed...
440 |
441 | if (i == 0xFFFF - 1)
442 | { fireDebug(" -> Signing Failed..."); throw new Exception("Fakesigning failed..."); }
443 | }
444 |
445 | s.Clear();
446 | }
447 |
448 | writeStream.Seek(0, SeekOrigin.Begin);
449 | writeStream.Write(tik, 0, tik.Length);
450 |
451 | fireDebug("Writing Ticket Finished...");
452 | }
453 |
454 | private void parseTicket(Stream ticketFile)
455 | {
456 | fireDebug("Parsing Ticket...");
457 |
458 | ticketFile.Seek(0, SeekOrigin.Begin);
459 | byte[] temp = new byte[8];
460 |
461 | fireDebug(" Reading Signature Exponent... (Offset: 0x{0})", ticketFile.Position.ToString("x8").ToUpper());
462 | ticketFile.Read(temp, 0, 4);
463 | signatureExponent = Shared.Swap(BitConverter.ToUInt32(temp, 0));
464 |
465 | fireDebug(" Reading Signature... (Offset: 0x{0})", ticketFile.Position.ToString("x8").ToUpper());
466 | ticketFile.Read(signature, 0, signature.Length);
467 |
468 | fireDebug(" Reading Padding... (Offset: 0x{0})", ticketFile.Position.ToString("x8").ToUpper());
469 | ticketFile.Read(padding, 0, padding.Length);
470 |
471 | fireDebug(" Reading Issuer... (Offset: 0x{0})", ticketFile.Position.ToString("x8").ToUpper());
472 | ticketFile.Read(issuer, 0, issuer.Length);
473 |
474 | fireDebug(" Reading Unknown... (Offset: 0x{0})", ticketFile.Position.ToString("x8").ToUpper());
475 | ticketFile.Read(unknown, 0, unknown.Length);
476 |
477 | fireDebug(" Reading Title Key... (Offset: 0x{0})", ticketFile.Position.ToString("x8").ToUpper());
478 | ticketFile.Read(encryptedTitleKey, 0, encryptedTitleKey.Length);
479 |
480 | fireDebug(" Reading Unknown2... (Offset: 0x{0})", ticketFile.Position.ToString("x8").ToUpper());
481 | unknown2 = (byte)ticketFile.ReadByte();
482 |
483 | fireDebug(" Reading Ticket ID.. (Offset: 0x{0})", ticketFile.Position.ToString("x8").ToUpper());
484 | ticketFile.Read(temp, 0, 8);
485 | ticketId = Shared.Swap(BitConverter.ToUInt64(temp, 0));
486 |
487 | fireDebug(" Reading Console ID... (Offset: 0x{0})", ticketFile.Position.ToString("x8").ToUpper());
488 | ticketFile.Read(temp, 0, 4);
489 | consoleId = Shared.Swap(BitConverter.ToUInt32(temp, 0));
490 |
491 | fireDebug(" Reading Title ID... (Offset: 0x{0})", ticketFile.Position.ToString("x8").ToUpper());
492 | ticketFile.Read(temp, 0, 8);
493 | titleId = Shared.Swap(BitConverter.ToUInt64(temp, 0));
494 |
495 | fireDebug(" Reading Unknown3... (Offset: 0x{0})", ticketFile.Position.ToString("x8").ToUpper());
496 | fireDebug(" Reading NumOfDLC... (Offset: 0x{0})", ticketFile.Position.ToString("x8").ToUpper());
497 | ticketFile.Read(temp, 0, 4);
498 | unknown3 = Shared.Swap(BitConverter.ToUInt16(temp, 0));
499 | numOfDlc = Shared.Swap(BitConverter.ToUInt16(temp, 2));
500 |
501 | fireDebug(" Reading Unknown4... (Offset: 0x{0})", ticketFile.Position.ToString("x8").ToUpper());
502 | ticketFile.Read(temp, 0, 8);
503 | unknown4 = Shared.Swap(BitConverter.ToUInt64(temp, 0));
504 |
505 | fireDebug(" Reading Padding2... (Offset: 0x{0})", ticketFile.Position.ToString("x8").ToUpper());
506 | padding2 = (byte)ticketFile.ReadByte();
507 |
508 | fireDebug(" Reading Common Key Index... (Offset: 0x{0})", ticketFile.Position.ToString("x8").ToUpper());
509 | commonKeyIndex = (byte)ticketFile.ReadByte();
510 |
511 | newKeyIndex = commonKeyIndex;
512 |
513 | fireDebug(" Reading Unknown5... (Offset: 0x{0})", ticketFile.Position.ToString("x8").ToUpper());
514 | ticketFile.Read(unknown5, 0, unknown5.Length);
515 |
516 | fireDebug(" Reading Unknown6... (Offset: 0x{0})", ticketFile.Position.ToString("x8").ToUpper());
517 | ticketFile.Read(unknown6, 0, unknown6.Length);
518 |
519 | fireDebug(" Reading Padding3... (Offset: 0x{0})", ticketFile.Position.ToString("x8").ToUpper());
520 | ticketFile.Read(temp, 0, 2);
521 | padding3 = Shared.Swap(BitConverter.ToUInt16(temp, 0));
522 |
523 | fireDebug(" Reading Enable Time Limit... (Offset: 0x{0})", ticketFile.Position.ToString("x8").ToUpper());
524 | fireDebug(" Reading Time Limit... (Offset: 0x{0})", ticketFile.Position.ToString("x8").ToUpper());
525 | ticketFile.Read(temp, 0, 8);
526 | enableTimeLimit = Shared.Swap(BitConverter.ToUInt32(temp, 0));
527 | timeLimit = Shared.Swap(BitConverter.ToUInt32(temp, 4));
528 |
529 | fireDebug(" Reading Padding4... (Offset: 0x{0})", ticketFile.Position.ToString("x8").ToUpper());
530 | ticketFile.Read(padding4, 0, padding4.Length);
531 |
532 | fireDebug(" Decrypting Title Key...");
533 | decryptTitleKey();
534 | fireDebug(" -> Encrypted Title Key: {0}", Shared.ByteArrayToString(encryptedTitleKey));
535 | fireDebug(" -> Decrypted Title Key: {0}", Shared.ByteArrayToString(decryptedTitleKey));
536 |
537 | fireDebug("Parsing Ticket Finished...");
538 | }
539 |
540 | private void decryptTitleKey()
541 | {
542 | byte[] ckey = CommonKey.GetStandardKey();
543 | byte[] iv = BitConverter.GetBytes(Shared.Swap(titleId));
544 | Array.Resize(ref iv, 16);
545 |
546 | RijndaelManaged rm = new RijndaelManaged();
547 | rm.Mode = CipherMode.CBC;
548 | rm.Padding = PaddingMode.None;
549 | rm.KeySize = 128;
550 | rm.BlockSize = 128;
551 | rm.Key = ckey;
552 | rm.IV = iv;
553 |
554 | ICryptoTransform decryptor = rm.CreateDecryptor();
555 |
556 | MemoryStream ms = new MemoryStream(encryptedTitleKey);
557 | CryptoStream cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read);
558 |
559 | cs.Read(decryptedTitleKey, 0, decryptedTitleKey.Length);
560 |
561 | cs.Dispose();
562 | ms.Dispose();
563 | decryptor.Dispose();
564 | rm.Clear();
565 | }
566 |
567 | private void encryptTitleKey()
568 | {
569 | commonKeyIndex = newKeyIndex;
570 | byte[] ckey = CommonKey.GetStandardKey();
571 | byte[] iv = BitConverter.GetBytes(Shared.Swap(titleId));
572 | Array.Resize(ref iv, 16);
573 |
574 | RijndaelManaged rm = new RijndaelManaged();
575 | rm.Mode = CipherMode.CBC;
576 | rm.Padding = PaddingMode.None;
577 | rm.KeySize = 128;
578 | rm.BlockSize = 128;
579 | rm.Key = ckey;
580 | rm.IV = iv;
581 |
582 | ICryptoTransform encryptor = rm.CreateEncryptor();
583 |
584 | MemoryStream ms = new MemoryStream(decryptedTitleKey);
585 | CryptoStream cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Read);
586 |
587 | cs.Read(encryptedTitleKey, 0, encryptedTitleKey.Length);
588 |
589 | cs.Dispose();
590 | ms.Dispose();
591 | encryptor.Dispose();
592 | rm.Clear();
593 | }
594 |
595 | private void reDecryptTitleKey()
596 | {
597 | encryptedTitleKey = newEncryptedTitleKey;
598 | decryptTitleKey();
599 | }
600 | #endregion
601 |
602 | #region Events
603 | ///
604 | /// Fires debugging messages. You may write them into a log file or log textbox.
605 | ///
606 | public event EventHandler Debug;
607 |
608 | private void fireDebug(string debugMessage, params object[] args)
609 | {
610 | EventHandler debug = Debug;
611 | if (debug != null)
612 | debug(new object(), new MessageEventArgs(string.Format(debugMessage, args)));
613 | }
614 | #endregion
615 | }
616 | }
617 |
--------------------------------------------------------------------------------
/NUSGrabberGUI/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # NEW-NUSGrabberGUI
2 | An updated version of NUSGrabberGUI that allows people to acquire and decrypt updates to Wii U software on their computer.
3 |
4 | You will need Visual Studio 2017 (or higher) to edit the source code.
5 |
6 | The original post on GBATemp can be found here: https://gbatemp.net/threads/download-the-new-nusgrabbergui.411228
7 |
--------------------------------------------------------------------------------
/packages/HtmlAgilityPack.1.4.9/HAPIcon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FoxMcloud5655/NEW-NUSGrabberGUI/69047f56db6d545107751590e60f97a53bde6c77/packages/HtmlAgilityPack.1.4.9/HAPIcon.png
--------------------------------------------------------------------------------
/packages/HtmlAgilityPack.1.4.9/HtmlAgilityPack.1.4.9.nupkg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FoxMcloud5655/NEW-NUSGrabberGUI/69047f56db6d545107751590e60f97a53bde6c77/packages/HtmlAgilityPack.1.4.9/HtmlAgilityPack.1.4.9.nupkg
--------------------------------------------------------------------------------
/packages/HtmlAgilityPack.1.4.9/lib/Net20/HtmlAgilityPack.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FoxMcloud5655/NEW-NUSGrabberGUI/69047f56db6d545107751590e60f97a53bde6c77/packages/HtmlAgilityPack.1.4.9/lib/Net20/HtmlAgilityPack.dll
--------------------------------------------------------------------------------
/packages/HtmlAgilityPack.1.4.9/lib/Net20/HtmlAgilityPack.pdb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FoxMcloud5655/NEW-NUSGrabberGUI/69047f56db6d545107751590e60f97a53bde6c77/packages/HtmlAgilityPack.1.4.9/lib/Net20/HtmlAgilityPack.pdb
--------------------------------------------------------------------------------
/packages/HtmlAgilityPack.1.4.9/lib/Net40-client/HtmlAgilityPack.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FoxMcloud5655/NEW-NUSGrabberGUI/69047f56db6d545107751590e60f97a53bde6c77/packages/HtmlAgilityPack.1.4.9/lib/Net40-client/HtmlAgilityPack.dll
--------------------------------------------------------------------------------
/packages/HtmlAgilityPack.1.4.9/lib/Net40-client/HtmlAgilityPack.pdb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FoxMcloud5655/NEW-NUSGrabberGUI/69047f56db6d545107751590e60f97a53bde6c77/packages/HtmlAgilityPack.1.4.9/lib/Net40-client/HtmlAgilityPack.pdb
--------------------------------------------------------------------------------
/packages/HtmlAgilityPack.1.4.9/lib/Net40/HtmlAgilityPack.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FoxMcloud5655/NEW-NUSGrabberGUI/69047f56db6d545107751590e60f97a53bde6c77/packages/HtmlAgilityPack.1.4.9/lib/Net40/HtmlAgilityPack.dll
--------------------------------------------------------------------------------
/packages/HtmlAgilityPack.1.4.9/lib/Net40/HtmlAgilityPack.pdb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FoxMcloud5655/NEW-NUSGrabberGUI/69047f56db6d545107751590e60f97a53bde6c77/packages/HtmlAgilityPack.1.4.9/lib/Net40/HtmlAgilityPack.pdb
--------------------------------------------------------------------------------
/packages/HtmlAgilityPack.1.4.9/lib/Net45/HtmlAgilityPack.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FoxMcloud5655/NEW-NUSGrabberGUI/69047f56db6d545107751590e60f97a53bde6c77/packages/HtmlAgilityPack.1.4.9/lib/Net45/HtmlAgilityPack.dll
--------------------------------------------------------------------------------
/packages/HtmlAgilityPack.1.4.9/lib/Net45/HtmlAgilityPack.pdb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FoxMcloud5655/NEW-NUSGrabberGUI/69047f56db6d545107751590e60f97a53bde6c77/packages/HtmlAgilityPack.1.4.9/lib/Net45/HtmlAgilityPack.pdb
--------------------------------------------------------------------------------
/packages/HtmlAgilityPack.1.4.9/lib/NetCore45/HtmlAgilityPack.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FoxMcloud5655/NEW-NUSGrabberGUI/69047f56db6d545107751590e60f97a53bde6c77/packages/HtmlAgilityPack.1.4.9/lib/NetCore45/HtmlAgilityPack.dll
--------------------------------------------------------------------------------
/packages/HtmlAgilityPack.1.4.9/lib/NetCore45/HtmlAgilityPack.pdb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FoxMcloud5655/NEW-NUSGrabberGUI/69047f56db6d545107751590e60f97a53bde6c77/packages/HtmlAgilityPack.1.4.9/lib/NetCore45/HtmlAgilityPack.pdb
--------------------------------------------------------------------------------
/packages/HtmlAgilityPack.1.4.9/lib/NetCore45/HtmlAgilityPack.pri:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FoxMcloud5655/NEW-NUSGrabberGUI/69047f56db6d545107751590e60f97a53bde6c77/packages/HtmlAgilityPack.1.4.9/lib/NetCore45/HtmlAgilityPack.pri
--------------------------------------------------------------------------------
/packages/HtmlAgilityPack.1.4.9/lib/portable-net45+netcore45+wp8+MonoAndroid+MonoTouch/HtmlAgilityPack.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FoxMcloud5655/NEW-NUSGrabberGUI/69047f56db6d545107751590e60f97a53bde6c77/packages/HtmlAgilityPack.1.4.9/lib/portable-net45+netcore45+wp8+MonoAndroid+MonoTouch/HtmlAgilityPack.dll
--------------------------------------------------------------------------------
/packages/HtmlAgilityPack.1.4.9/lib/portable-net45+netcore45+wp8+MonoAndroid+MonoTouch/HtmlAgilityPack.pdb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FoxMcloud5655/NEW-NUSGrabberGUI/69047f56db6d545107751590e60f97a53bde6c77/packages/HtmlAgilityPack.1.4.9/lib/portable-net45+netcore45+wp8+MonoAndroid+MonoTouch/HtmlAgilityPack.pdb
--------------------------------------------------------------------------------
/packages/HtmlAgilityPack.1.4.9/lib/portable-net45+netcore45+wpa81+wp8+MonoAndroid+MonoTouch/HtmlAgilityPack.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FoxMcloud5655/NEW-NUSGrabberGUI/69047f56db6d545107751590e60f97a53bde6c77/packages/HtmlAgilityPack.1.4.9/lib/portable-net45+netcore45+wpa81+wp8+MonoAndroid+MonoTouch/HtmlAgilityPack.dll
--------------------------------------------------------------------------------
/packages/HtmlAgilityPack.1.4.9/lib/portable-net45+netcore45+wpa81+wp8+MonoAndroid+MonoTouch/HtmlAgilityPack.pdb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FoxMcloud5655/NEW-NUSGrabberGUI/69047f56db6d545107751590e60f97a53bde6c77/packages/HtmlAgilityPack.1.4.9/lib/portable-net45+netcore45+wpa81+wp8+MonoAndroid+MonoTouch/HtmlAgilityPack.pdb
--------------------------------------------------------------------------------
/packages/HtmlAgilityPack.1.4.9/lib/sl3-wp/_._:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/packages/HtmlAgilityPack.1.4.9/lib/sl4/HtmlAgilityPack.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FoxMcloud5655/NEW-NUSGrabberGUI/69047f56db6d545107751590e60f97a53bde6c77/packages/HtmlAgilityPack.1.4.9/lib/sl4/HtmlAgilityPack.dll
--------------------------------------------------------------------------------
/packages/HtmlAgilityPack.1.4.9/lib/sl4/HtmlAgilityPack.pdb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FoxMcloud5655/NEW-NUSGrabberGUI/69047f56db6d545107751590e60f97a53bde6c77/packages/HtmlAgilityPack.1.4.9/lib/sl4/HtmlAgilityPack.pdb
--------------------------------------------------------------------------------
/packages/HtmlAgilityPack.1.4.9/lib/sl5/HtmlAgilityPack.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FoxMcloud5655/NEW-NUSGrabberGUI/69047f56db6d545107751590e60f97a53bde6c77/packages/HtmlAgilityPack.1.4.9/lib/sl5/HtmlAgilityPack.dll
--------------------------------------------------------------------------------
/packages/HtmlAgilityPack.1.4.9/lib/sl5/HtmlAgilityPack.pdb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FoxMcloud5655/NEW-NUSGrabberGUI/69047f56db6d545107751590e60f97a53bde6c77/packages/HtmlAgilityPack.1.4.9/lib/sl5/HtmlAgilityPack.pdb
--------------------------------------------------------------------------------
/packages/HtmlAgilityPack.1.4.9/readme.txt:
--------------------------------------------------------------------------------
1 | ----------------------------------------------------
2 | ---------- Html Agility Pack Nuget Readme ----------
3 | ----------------------------------------------------
4 |
5 | ----Silverlight 4 and Windows Phone 7.1+ projects-----
6 | To use XPATH features: System.Xml.Xpath.dll from the Silverlight 4 SDK must be referenced.
7 | This is normally found at
8 | %ProgramFiles(x86)%\Microsoft SDKs\Microsoft SDKs\Silverlight\v4.0\Libraries\Client
9 | or
10 | %ProgramFiles%\Microsoft SDKs\Microsoft SDKs\Silverlight\v4.0\Libraries\Client
11 |
12 | ----Silverlight 5 projects-----
13 | To use XPATH features: System.Xml.Xpath.dll from the Silverlight 5 SDK must be referenced.
14 | This is normally found at
15 | %ProgramFiles(x86)%\Microsoft SDKs\Microsoft SDKs\Silverlight\v5.0\Libraries\Client
16 | or
17 | %ProgramFiles%\Microsoft SDKs\Microsoft SDKs\Silverlight\v5.0\Libraries\Client
18 |
--------------------------------------------------------------------------------