Compare commits

...

7 Commits

Author SHA1 Message Date
Maschell
6a6afff21d Improve dev common key detection, fix splitted file support on non-windows machines 2022-02-01 23:27:30 +01:00
Maschell
1443db9cdf Remove circleci 2020-12-20 15:15:50 +01:00
Maschell
b19809c3b6
Create maven.yml 2020-12-20 15:14:03 +01:00
Maschell
51cc20eaf9 Use latest JNUSLib version, fix support for multiple partitions with the same name, version bump to 0.4 2020-12-20 15:12:46 +01:00
Maschell
92978d4a69
Merge pull request #7 from agilly1989/master
Fixed the -titlekey argument
2020-12-20 12:39:19 +01:00
agilly1989
27aad40261
Fixed the -titlekey argument
the correct arg is titleKey as per Main.java:40
2020-12-20 00:11:11 +10:00
Maschell
1e4a56cd6f Update README 2019-04-26 21:17:57 +02:00
5 changed files with 79 additions and 111 deletions

View File

@ -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
View 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

View File

@ -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
```

View File

@ -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 -->

View File

@ -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();