mirror of
https://github.com/Maschell/JNUSTool.git
synced 2025-01-07 05:48:18 +01:00
-Fixed creating title.cert
-Fixed downloading .h3 files -Improves logging
This commit is contained in:
parent
6e54967dd5
commit
6e595b9305
BIN
jar/JNUSTool.jar
BIN
jar/JNUSTool.jar
Binary file not shown.
BIN
release.zip
BIN
release.zip
Binary file not shown.
@ -47,12 +47,16 @@ public class Content {
|
|||||||
if(f.exists()){
|
if(f.exists()){
|
||||||
if(f.length() == size){
|
if(f.length() == size){
|
||||||
Logger.log("Skipping Content: " + String.format("%08X", ID));
|
Logger.log("Skipping Content: " + String.format("%08X", ID));
|
||||||
progress.addCurrent((int) size);
|
if(progress != null){
|
||||||
return;
|
progress.addCurrent((int) size);
|
||||||
|
}
|
||||||
}else{
|
}else{
|
||||||
if(Settings.downloadWhenCachedFilesMissingOrBroken){
|
if(Settings.downloadWhenCachedFilesMissingOrBroken){
|
||||||
Logger.log("Content " +String.format("%08X", ID) + " is broken. Downloading it again.");
|
Logger.log("Content " +String.format("%08X", ID) + " has a different filesize and may be broken. Downloading it again.");
|
||||||
Downloader.getInstance().downloadContent(tmd.titleID,ID,tmpPath,progress);
|
new File(tmpPath).delete();
|
||||||
|
Logger.log("Downloading Content: " + String.format("%08X", ID));
|
||||||
|
Downloader.getInstance().downloadContent(tmd.titleID,ID,tmpPath,progress);
|
||||||
|
|
||||||
}else{
|
}else{
|
||||||
if(Settings.skipBrokenFiles){
|
if(Settings.skipBrokenFiles){
|
||||||
Logger.log("Content " +String.format("%08X", ID) + " is broken. Ignoring it.");
|
Logger.log("Content " +String.format("%08X", ID) + " is broken. Ignoring it.");
|
||||||
@ -63,11 +67,17 @@ public class Content {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
Logger.log("Download Content: " + String.format("%08X", ID));
|
Logger.log("Downloading Content: " + String.format("%08X", ID));
|
||||||
Downloader.getInstance().downloadContent(tmd.titleID,ID,tmpPath,progress);
|
Downloader.getInstance().downloadContent(tmd.titleID,ID,tmpPath,progress);
|
||||||
}
|
}
|
||||||
if ((type & 0x02) == 0x02){
|
if ((type & 0x02) == 0x02){
|
||||||
Downloader.getInstance().downloadContentH3(tmd.titleID,ID,tmpPath,null);
|
f = new File(tmpPath + "/" + String.format("%08X", ID ) + ".h3");
|
||||||
|
if(!f.exists()){
|
||||||
|
Logger.log("Downloading H3: " + String.format("%08X.h3", ID));
|
||||||
|
Downloader.getInstance().downloadContentH3(tmd.titleID,ID,tmpPath,null);
|
||||||
|
}else{
|
||||||
|
Logger.log("Skipping H3: " + String.format("%08X.h3", ID));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,7 +45,12 @@ public class ContentDownloader implements Callable<Integer>
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Integer call() throws Exception {
|
public Integer call() throws Exception {
|
||||||
this.content.download(progress);
|
try{
|
||||||
|
this.content.download(progress);
|
||||||
|
}catch(Exception e){
|
||||||
|
e.printStackTrace();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,30 +2,35 @@ package de.mas.jnustool;
|
|||||||
|
|
||||||
import java.util.concurrent.Callable;
|
import java.util.concurrent.Callable;
|
||||||
|
|
||||||
public class FEntryDownloader implements Callable<Integer>
|
public class FEntryDownloader implements Callable<Integer>{
|
||||||
{
|
FEntry f;
|
||||||
FEntry f;
|
|
||||||
Progress progress = null;
|
Progress progress = null;
|
||||||
|
|
||||||
public void setTitle(FEntry f){
|
public void setTitle(FEntry f){
|
||||||
this.f = f;
|
this.f = f;
|
||||||
}
|
}
|
||||||
|
|
||||||
public FEntryDownloader(FEntry f,Progress fatherProgress){
|
public FEntryDownloader(FEntry f,Progress fatherProgress){
|
||||||
setTitle(f);
|
setTitle(f);
|
||||||
createProgressListener(fatherProgress);
|
createProgressListener(fatherProgress);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void createProgressListener(Progress fatherProgress) {
|
private void createProgressListener(Progress fatherProgress) {
|
||||||
if(fatherProgress != null){
|
if(fatherProgress != null){
|
||||||
progress = new Progress();
|
progress = new Progress();
|
||||||
fatherProgress.add(progress);
|
fatherProgress.add(progress);
|
||||||
progress.addTotal(f.getFileLength());
|
progress.addTotal(f.getFileLength());
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Integer call() throws Exception {
|
public Integer call() throws Exception {
|
||||||
f.downloadAndDecrypt(progress);
|
try{
|
||||||
|
f.downloadAndDecrypt(progress);
|
||||||
|
}catch(Exception e){
|
||||||
|
e.printStackTrace();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,11 +83,7 @@ public class FST {
|
|||||||
private void parse(byte[] decrypteddata, TitleMetaData tmd) throws IOException {
|
private void parse(byte[] decrypteddata, TitleMetaData tmd) throws IOException {
|
||||||
|
|
||||||
if(!Arrays.equals(Arrays.copyOfRange(decrypteddata, 0, 3), new byte[]{0x46,0x53,0x54})){
|
if(!Arrays.equals(Arrays.copyOfRange(decrypteddata, 0, 3), new byte[]{0x46,0x53,0x54})){
|
||||||
Logger.log(Util.ByteArrayToString(Arrays.copyOfRange(decrypteddata, 0, 3)));
|
throw new IllegalArgumentException("Not a FST. Maybe a wrong key? Don't worry if you only want to download encrypted files!");
|
||||||
|
|
||||||
System.err.println("Not a FST. Maybe a wrong key?");
|
|
||||||
throw new IllegalArgumentException("File not a FST");
|
|
||||||
|
|
||||||
}
|
}
|
||||||
this.totalContentCount = Util.getIntFromBytes(decrypteddata, 8);
|
this.totalContentCount = Util.getIntFromBytes(decrypteddata, 8);
|
||||||
int base_offset = 0x20+totalContentCount*0x20;
|
int base_offset = 0x20+totalContentCount*0x20;
|
||||||
|
@ -220,34 +220,63 @@ public class NUSTitle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void downloadEncryptedFiles(Progress progress) throws IOException {
|
public void downloadEncryptedFiles(Progress progress) throws IOException {
|
||||||
|
|
||||||
Util.createSubfolder(getContentPath());
|
Util.createSubfolder(getContentPath());
|
||||||
|
|
||||||
Downloader.getInstance().downloadTMD(titleID,version,getContentPath());
|
Logger.log("---Downloading encrypted files---");
|
||||||
|
Downloader.getInstance().downloadTMD(titleID,version,getContentPath());
|
||||||
|
Logger.log("Downloaded title.tmd");
|
||||||
tmd.downloadContents(progress);
|
tmd.downloadContents(progress);
|
||||||
try{
|
Logger.log("Downloaded content files");
|
||||||
File f = new File(getContentPath() + "/" + "title.tik");
|
|
||||||
if(!f.exists()){
|
File f = new File(getContentPath() + "/" + "title.tik");
|
||||||
|
if(!f.exists()){
|
||||||
|
try{
|
||||||
Downloader.getInstance().downloadTicket(titleID,getContentPath());
|
Downloader.getInstance().downloadTicket(titleID,getContentPath());
|
||||||
|
Logger.log("Downloaded title.tik");
|
||||||
|
}catch(Exception e){
|
||||||
|
Logger.log("!!!Missing file: title.tik. You need to add it manually before you can install this title.!!!");
|
||||||
}
|
}
|
||||||
|
}else{
|
||||||
FileOutputStream fos = new FileOutputStream(getContentPath() + "/title.cert");
|
Logger.log("Skipped title.tik");
|
||||||
fos.write(ticket.cert0);
|
}
|
||||||
fos.write(tmd.cert);
|
|
||||||
fos.write(ticket.cert1);
|
f = new File(getContentPath() + "/" + "title.tik");
|
||||||
fos.close();
|
byte[] defaultcert = null;
|
||||||
if(version > 0 && Settings.DL_ALL_VERSIONS){
|
|
||||||
fos = new FileOutputStream(getContentPath() + "/title.cert." + version);
|
Logger.log("Trying to create title.cert");
|
||||||
fos.write(ticket.cert0);
|
if(!f.exists()){
|
||||||
fos.write(tmd.cert);
|
try{
|
||||||
fos.write(ticket.cert1);
|
defaultcert = Util.getDefaultCert();
|
||||||
fos.close();
|
}catch(Exception e){
|
||||||
}
|
Logger.log("Failed to get missing cert from OSv10 cetk =(. Couldn't create title.cert");
|
||||||
|
e.printStackTrace();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Logger.log("Got missing cert from OSv10 title");
|
||||||
|
}else{
|
||||||
|
defaultcert = ticket.cert1;
|
||||||
|
}
|
||||||
|
|
||||||
|
try{
|
||||||
|
FileOutputStream fos = new FileOutputStream(getContentPath() + "/title.cert");
|
||||||
|
fos.write(tmd.cert1);
|
||||||
|
fos.write(tmd.cert2);
|
||||||
|
fos.write(defaultcert);
|
||||||
|
fos.close();
|
||||||
|
if(version > 0 && Settings.DL_ALL_VERSIONS){
|
||||||
|
fos = new FileOutputStream(getContentPath() + "/title.cert." + version);
|
||||||
|
fos.write(tmd.cert1);
|
||||||
|
fos.write(tmd.cert2);
|
||||||
|
fos.write(defaultcert);
|
||||||
|
fos.close();
|
||||||
|
}
|
||||||
}catch(Exception e){
|
}catch(Exception e){
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
Logger.log("Error while creating ticket files.");
|
Logger.log("Error while creating ticket files.");
|
||||||
}
|
}
|
||||||
|
Logger.log("Created title.cert");
|
||||||
|
Logger.log("---Successfully downloaded encrypted files---");
|
||||||
}
|
}
|
||||||
|
|
||||||
public NUSTitleInformation readMeta(InputStream bis) {
|
public NUSTitleInformation readMeta(InputStream bis) {
|
||||||
|
@ -25,7 +25,7 @@ public class Starter {
|
|||||||
private static String updateCSVPath;
|
private static String updateCSVPath;
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
Logger.log("JNUSTool 0.0.8 - alpha - by Maschell");
|
Logger.log("JNUSTool 0.0.8b - alpha - by Maschell");
|
||||||
Logger.log("");
|
Logger.log("");
|
||||||
try {
|
try {
|
||||||
readConfig();
|
readConfig();
|
||||||
|
@ -37,7 +37,8 @@ public class TitleMetaData {
|
|||||||
byte[] SHA2 = new byte[32]; // 0x1E4
|
byte[] SHA2 = new byte[32]; // 0x1E4
|
||||||
ContentInfo[] contentInfos = new ContentInfo[64]; // 0x1E4
|
ContentInfo[] contentInfos = new ContentInfo[64]; // 0x1E4
|
||||||
Content[] contents; // 0x1E4
|
Content[] contents; // 0x1E4
|
||||||
byte[] cert = new byte[0x300];
|
byte[] cert1 = new byte[0x400];
|
||||||
|
byte[] cert2 = new byte[0x300];
|
||||||
|
|
||||||
private NUSTitle nus;
|
private NUSTitle nus;
|
||||||
|
|
||||||
@ -130,8 +131,11 @@ public class TitleMetaData {
|
|||||||
this.contents[i] = new Content(ID,index,type,size,buffer,this);
|
this.contents[i] = new Content(ID,index,type,size,buffer,this);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(f.read(cert,0, 0x300) != 0x300){
|
if(f.read(cert2,0, 0x300) != 0x300){
|
||||||
Logger.log("Error reading TMD cert");
|
Logger.log("Error reading TMD cert2");
|
||||||
|
}
|
||||||
|
if(f.read(cert1,0, 0x400) != 0x400){
|
||||||
|
Logger.log("Error reading TMD cert1");
|
||||||
}
|
}
|
||||||
f.close();
|
f.close();
|
||||||
}
|
}
|
||||||
@ -155,7 +159,8 @@ public class TitleMetaData {
|
|||||||
sb.append("contentCount: " + contentCount +"\n");
|
sb.append("contentCount: " + contentCount +"\n");
|
||||||
sb.append("bootIndex: " + bootIndex +"\n");
|
sb.append("bootIndex: " + bootIndex +"\n");
|
||||||
sb.append("SHA2: " + Util.ByteArrayToString(SHA2) +"\n");
|
sb.append("SHA2: " + Util.ByteArrayToString(SHA2) +"\n");
|
||||||
sb.append("cert: " + Util.ByteArrayToString(cert) +"\n");
|
sb.append("cert1: " + Util.ByteArrayToString(cert1) +"\n");
|
||||||
|
sb.append("cert2: " + Util.ByteArrayToString(cert2) +"\n");
|
||||||
sb.append("contentInfos: \n");
|
sb.append("contentInfos: \n");
|
||||||
|
|
||||||
for(int i = 0; i<contents.length-1;i++){
|
for(int i = 0; i<contents.length-1;i++){
|
||||||
|
@ -22,7 +22,6 @@ public class Util {
|
|||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static String ByteArrayToString(byte[] ba)
|
public static String ByteArrayToString(byte[] ba)
|
||||||
{
|
{
|
||||||
if(ba == null) return null;
|
if(ba == null) return null;
|
||||||
@ -133,4 +132,9 @@ public class Util {
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static byte[] getDefaultCert() throws IOException {
|
||||||
|
byte [] ticket = Downloader.getInstance().downloadTicketToByteArray(0x000500101000400AL); //Downloading cetk from OSv10
|
||||||
|
return Arrays.copyOfRange(ticket, 0x350, 0x350+0x300);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user