mirror of
https://github.com/Maschell/JWUDTool.git
synced 2024-06-02 07:18:46 +02:00
Compare commits
7 Commits
v0.3-night
...
master
Author | SHA1 | Date | |
---|---|---|---|
|
6a6afff21d | ||
|
1443db9cdf | ||
|
b19809c3b6 | ||
|
51cc20eaf9 | ||
|
92978d4a69 | ||
|
27aad40261 | ||
|
1e4a56cd6f |
|
@ -1,60 +0,0 @@
|
|||
# Java Maven CircleCI 2.0 configuration file
|
||||
#
|
||||
# Check https://circleci.com/docs/2.0/language-java/ for more details
|
||||
#
|
||||
version: 2
|
||||
jobs:
|
||||
build:
|
||||
docker:
|
||||
# specify the version you desire here
|
||||
- image: circleci/openjdk:8-jdk
|
||||
|
||||
# Specify service dependencies here if necessary
|
||||
# CircleCI maintains a library of pre-built images
|
||||
# documented at https://circleci.com/docs/2.0/circleci-images/
|
||||
# - image: circleci/postgres:9.4
|
||||
|
||||
working_directory: ~/repo
|
||||
|
||||
environment:
|
||||
# Customize the JVM maximum heap limit
|
||||
MAVEN_OPTS: -Xmx3200m
|
||||
|
||||
steps:
|
||||
- checkout
|
||||
|
||||
# Download and cache dependencies
|
||||
- restore_cache:
|
||||
keys:
|
||||
- v1-dependencies-{{ checksum "pom.xml" }}
|
||||
# fallback to using the latest cache if no exact match is found
|
||||
- v1-dependencies-
|
||||
|
||||
- run:
|
||||
command: |
|
||||
mvn dependency:go-offline
|
||||
sudo apt-get update
|
||||
sudo apt-get -y upgrade
|
||||
wget https://dl.google.com/go/go1.10.linux-amd64.tar.gz
|
||||
sudo tar -xvf go1.10.linux-amd64.tar.gz
|
||||
sudo mv go /usr/local
|
||||
|
||||
- save_cache:
|
||||
paths:
|
||||
- ~/.m2
|
||||
key: v1-dependencies-{{ checksum "pom.xml" }}
|
||||
|
||||
- run: mvn package -Dci-build=true
|
||||
|
||||
- deploy:
|
||||
name: Deploy
|
||||
command: |
|
||||
mkdir ~/go
|
||||
export GOPATH=~/go
|
||||
export GOROOT=/usr/local/go
|
||||
export PATH=$GOPATH/bin:$GOROOT/bin:$PATH
|
||||
go get github.com/tcnksm/ghr
|
||||
ghr -t $GITHUB_TOKEN -u $CIRCLE_PROJECT_USERNAME -r $CIRCLE_PROJECT_REPONAME -prerelease -b 'Nightly release - Use caution!' `echo "v0.3-nightly-$(git rev-parse --short=7 HEAD)"` ci/
|
||||
|
||||
- store_artifacts:
|
||||
path: ci/
|
24
.github/workflows/maven.yml
vendored
Normal file
24
.github/workflows/maven.yml
vendored
Normal file
|
@ -0,0 +1,24 @@
|
|||
# This workflow will build a Java project with Maven
|
||||
# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven
|
||||
|
||||
name: Java CI with Maven
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Set up JDK 1.8
|
||||
uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: 1.8
|
||||
- name: Build with Maven
|
||||
run: mvn -B package --file pom.xml
|
10
README.md
10
README.md
|
@ -1,4 +1,4 @@
|
|||
# JWUDTool 0.2
|
||||
# JWUDTool
|
||||
|
||||
Here is just a simple program that uses the (http://gbatemp.net/threads/jnuslib-java-nus-library.452954/).
|
||||
The usage should be pretty self explaining.
|
||||
|
@ -9,11 +9,11 @@ The usage should be pretty self explaining.
|
|||
|
||||
* Compressing .wud and splitted wud files into .wux
|
||||
* Decompressing a .wux back to .wud
|
||||
* Extracting from the GI or GM partition
|
||||
* Extracting titles from the GI or GM partition
|
||||
* Extracting .app/-h3/.tmd/.cert/.tik files from a .wud/.wux or splitted .wud
|
||||
* Extracting just the contents/hashes/ticket.
|
||||
* Decrypting the full game partition from a .wud/.wux or splitted .wud
|
||||
* Decrypting specific files the game partition from a .wud/.wux or splitted .wud
|
||||
* Decrypting the full partitions from a .wud/.wux or splitted .wud
|
||||
* Decrypting specific files any partition from a .wud/.wux or splitted .wud
|
||||
* Verify a image / Compare two images (for example a .wud with .wux to make sure its legit)
|
||||
|
||||
## Usage
|
||||
|
@ -39,7 +39,7 @@ usage:
|
|||
-noVerify Disables verification after (de)compressing
|
||||
-out <output path> The path where the result will be saved
|
||||
-overwrite Optional. Overwrites existing files
|
||||
-titlekey <WUD title key> Optional. HexString. Will be used if no "game.key" in the
|
||||
-titleKey <WUD title key> Optional. HexString. Will be used if no "game.key" in the
|
||||
folder of the wud image is found
|
||||
-verify <wudimage1|wudimage2> Compares two WUD images to find differences
|
||||
```
|
||||
|
|
5
pom.xml
5
pom.xml
|
@ -4,7 +4,7 @@
|
|||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>de.mas</groupId>
|
||||
<artifactId>jwudtool</artifactId>
|
||||
<version>0.3</version>
|
||||
<version>0.5</version>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
|
@ -31,7 +31,6 @@
|
|||
</profiles>
|
||||
|
||||
<build>
|
||||
<sourceDirectory>src</sourceDirectory>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
|
@ -80,7 +79,7 @@
|
|||
<dependency>
|
||||
<groupId>com.github.Maschell</groupId>
|
||||
<artifactId>JNUSLib</artifactId>
|
||||
<version>3eb299d</version>
|
||||
<version>822cf2d</version>
|
||||
</dependency>
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
|
||||
|
|
|
@ -5,6 +5,8 @@ import java.io.IOException;
|
|||
import java.nio.file.Files;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
|
||||
import org.apache.commons.cli.CommandLine;
|
||||
import org.apache.commons.cli.CommandLineParser;
|
||||
|
@ -21,7 +23,7 @@ import de.mas.wiiu.jnus.NUSTitle;
|
|||
import de.mas.wiiu.jnus.WUDLoader;
|
||||
import de.mas.wiiu.jnus.WUDService;
|
||||
import de.mas.wiiu.jnus.implementations.wud.WUDImage;
|
||||
import de.mas.wiiu.jnus.implementations.wud.parser.WUDInfo;
|
||||
import de.mas.wiiu.jnus.implementations.wud.WiiUDisc;
|
||||
import de.mas.wiiu.jnus.interfaces.FSTDataProvider;
|
||||
import de.mas.wiiu.jnus.utils.Utils;
|
||||
import lombok.val;
|
||||
|
@ -46,7 +48,7 @@ public class Main {
|
|||
private static final String HOMEPATH = System.getProperty("user.home") + File.separator + ".wiiu";
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
System.out.println("JWUDTool 0.2a - Maschell");
|
||||
System.out.println("JWUDTool 0.4 - Maschell");
|
||||
System.out.println();
|
||||
Options options = getOptions();
|
||||
|
||||
|
@ -56,7 +58,7 @@ public class Main {
|
|||
}
|
||||
|
||||
CommandLineParser parser = new DefaultParser();
|
||||
CommandLine cmd = null;
|
||||
CommandLine cmd;
|
||||
try {
|
||||
cmd = parser.parse(options, args);
|
||||
} catch (MissingArgumentException e) {
|
||||
|
@ -74,14 +76,18 @@ public class Main {
|
|||
boolean devMode = false;
|
||||
byte[] titlekey = null;
|
||||
|
||||
readKey(new File(HOMEPATH + File.separator + "common.key")).ifPresent(key -> Main.commonKey = key);
|
||||
readKey(new File("common.key")).ifPresent(key -> Main.commonKey = key);
|
||||
|
||||
if (cmd.hasOption(OPTION_HELP)) {
|
||||
showHelp(options);
|
||||
return;
|
||||
}
|
||||
|
||||
if (cmd.hasOption(OPTION_DEVMODE)) {
|
||||
devMode = true;
|
||||
}
|
||||
|
||||
readKey(new File(HOMEPATH + File.separator + (devMode ? "devcommon.key" : "common.key"))).ifPresent(key -> Main.commonKey = key);
|
||||
readKey(new File("common.key")).ifPresent(key -> Main.commonKey = key);
|
||||
|
||||
if (cmd.hasOption(OPTION_IN)) {
|
||||
input = cmd.getOptionValue(OPTION_IN);
|
||||
}
|
||||
|
@ -112,10 +118,6 @@ public class Main {
|
|||
overwrite = true;
|
||||
}
|
||||
|
||||
if (cmd.hasOption(OPTION_DEVMODE)) {
|
||||
devMode = true;
|
||||
}
|
||||
|
||||
if (cmd.hasOption(OPTION_COMPRESS)) {
|
||||
boolean verify = true;
|
||||
System.out.println("Compressing: " + input);
|
||||
|
@ -169,6 +171,7 @@ public class Main {
|
|||
return;
|
||||
}
|
||||
}
|
||||
System.out.println("Done!");
|
||||
}
|
||||
|
||||
private static void extract(String input, String output, boolean devMode, boolean overwrite, byte[] titlekey, String arg) throws Exception {
|
||||
|
@ -181,39 +184,35 @@ public class Main {
|
|||
boolean extractHashes = false;
|
||||
|
||||
switch (arg) {
|
||||
case "all":
|
||||
extractAll = true;
|
||||
break;
|
||||
case "content":
|
||||
extractContent = true;
|
||||
break;
|
||||
case "ticket":
|
||||
extractTicket = true;
|
||||
break;
|
||||
case "hashes":
|
||||
extractHashes = true;
|
||||
break;
|
||||
default:
|
||||
System.out.println("Argument not found:" + arg);
|
||||
return;
|
||||
case "all":
|
||||
extractAll = true;
|
||||
break;
|
||||
case "content":
|
||||
extractContent = true;
|
||||
break;
|
||||
case "ticket":
|
||||
extractTicket = true;
|
||||
break;
|
||||
case "hashes":
|
||||
extractHashes = true;
|
||||
break;
|
||||
default:
|
||||
System.out.println("Argument not found:" + arg);
|
||||
return;
|
||||
}
|
||||
|
||||
assert input != null;
|
||||
File inputFile = new File(input);
|
||||
|
||||
System.out.println("Extracting: " + inputFile.getAbsolutePath());
|
||||
|
||||
WUDInfo wudInfo = null;
|
||||
WiiUDisc wudInfo;
|
||||
if (!devMode) {
|
||||
wudInfo = WUDLoader.load(inputFile.getAbsolutePath(), titlekey);
|
||||
} else {
|
||||
wudInfo = WUDLoader.loadDev(inputFile.getAbsolutePath());
|
||||
}
|
||||
|
||||
if (wudInfo == null) {
|
||||
System.out.println("Failed to load WUX " + inputFile.getAbsolutePath());
|
||||
return;
|
||||
}
|
||||
|
||||
List<NUSTitle> titles = WUDLoader.getGamePartionsAsNUSTitles(wudInfo, Main.commonKey);
|
||||
System.out.println("Found " + titles.size() + " titles on the Disc.");
|
||||
for (val title : titles) {
|
||||
|
@ -246,33 +245,39 @@ public class Main {
|
|||
private static void decryptFile(String input, String output, String regex, boolean devMode, boolean overwrite, byte[] titlekey) throws Exception {
|
||||
if (input == null) {
|
||||
System.out.println("You need to provide an input file");
|
||||
return;
|
||||
}
|
||||
File inputFile = new File(input);
|
||||
|
||||
System.out.println("Decrypting: " + inputFile.getAbsolutePath());
|
||||
|
||||
WUDInfo wudInfo = null;
|
||||
WiiUDisc wudInfo;
|
||||
if (!devMode) {
|
||||
wudInfo = WUDLoader.load(inputFile.getAbsolutePath(), titlekey);
|
||||
} else {
|
||||
wudInfo = WUDLoader.loadDev(inputFile.getAbsolutePath());
|
||||
}
|
||||
|
||||
if (wudInfo == null) {
|
||||
System.out.println("Failed to load Wii U Disc Image " + inputFile.getAbsolutePath());
|
||||
return;
|
||||
}
|
||||
|
||||
List<FSTDataProvider> partitions = WUDLoader.getPartitonsAsFSTDataProvider(wudInfo, Main.commonKey);
|
||||
System.out.println("Found " + partitions.size() + " titles on the Disc.");
|
||||
|
||||
Set<String> paritionNames = new TreeSet<>();
|
||||
for (val dp : partitions) {
|
||||
String partitionName = dp.getName();
|
||||
|
||||
int i = 0;
|
||||
while (paritionNames.contains(partitionName)) {
|
||||
partitionName = dp.getName() + "_" + i++;
|
||||
}
|
||||
|
||||
paritionNames.add(partitionName);
|
||||
|
||||
String newOutput = output;
|
||||
System.out.println("Decrypting files in partition " + dp.getName());
|
||||
System.out.println("Decrypting files in partition " + partitionName);
|
||||
if (newOutput == null) {
|
||||
newOutput = dp.getName();
|
||||
newOutput = partitionName;
|
||||
} else {
|
||||
newOutput += File.separator + dp.getName();
|
||||
newOutput += File.separator + partitionName;
|
||||
}
|
||||
|
||||
File outputFolder = new File(newOutput);
|
||||
|
@ -314,7 +319,7 @@ public class Main {
|
|||
}
|
||||
System.out.println("Parsing WUD image.");
|
||||
WUDImage image = new WUDImage(inputImage);
|
||||
Optional<File> outputFile = Optional.empty();
|
||||
Optional<File> outputFile;
|
||||
if (!decompress) {
|
||||
outputFile = WUDService.compressWUDToWUX(image, output, overwrite);
|
||||
if (outputFile.isPresent()) {
|
||||
|
@ -346,10 +351,10 @@ public class Main {
|
|||
byte[] key;
|
||||
try {
|
||||
key = Files.readAllBytes(file.toPath());
|
||||
if (key != null && key.length == 16) {
|
||||
if (key.length == 16) {
|
||||
return Optional.of(key);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
} catch (IOException ignored) {
|
||||
}
|
||||
}
|
||||
return Optional.empty();
|
||||
|
|
Loading…
Reference in New Issue
Block a user