Skip to content

Commit

Permalink
Merge branch 'dev'
Browse files Browse the repository at this point in the history
  • Loading branch information
knight-ryu12 committed Mar 17, 2018
2 parents a80754d + 6c73d01 commit 7e81ef3
Show file tree
Hide file tree
Showing 12 changed files with 434 additions and 191 deletions.
3 changes: 1 addition & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,4 @@ build/
movable.sed
movable.sed.*
*.bin
src/main/resources/
src/test/

4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# TADpole-java
***
This is the representation of zoogie/TADpole in Java.

12 changes: 7 additions & 5 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@

plugins {
id 'java'
id 'application'
//id 'com.gorylenko.gradle-git-properties' version '1.4.17'
id 'com.sedmelluq.jdaction' version '1.0.2' //check for unused RestActions
id 'com.github.johnrengelman.shadow' version '2.0.1'
id 'com.github.ksoichiro.build.info' version '0.2.0'
id 'com.palantir.git-version' version '0.10.1'
}
mainClassName = "faith.elguadia.tadpool.start"

Expand All @@ -14,9 +16,7 @@ runShadow{
}

group 'faith.elguadia'
version '1.0-SNAPSHOT'

apply plugin: 'java'
version gitVersion()

sourceCompatibility = 1.8

Expand All @@ -36,6 +36,8 @@ dependencies {
// https://mvnrepository.com/artifact/com.google.guava/guava
compile group: 'com.google.guava', name: 'guava', version: '23.6-jre'
// https://mvnrepository.com/artifact/org.bouncycastle/bcprov-jdk16
compile group: 'org.bouncycastle', name: 'bcprov-jdk16', version: '1.46'
compile group: 'org.bouncycastle', name: 'bcprov-jdk15on', version: '1.46'
// https://mvnrepository.com/artifact/org.bouncycastle/bcpkix-jdk15on
compile group: 'org.bouncycastle', name: 'bcpkix-jdk15on', version: '1.59'

}
Binary file removed ctr-dsiwaretool.exe
Binary file not shown.
Binary file removed libcrypto-1_1-x64__.dll
Binary file not shown.
18 changes: 9 additions & 9 deletions src/main/java/faith/elguadia/tadpool/Constants.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,15 @@ public class Constants {
//public static BigInteger C_bigint;
public static BigInteger cmac_keyx;
public static String default_dir = "decrypted_sections/";
public static int BM = 0x20;
public static int banner = 0x0;
public static int banner_size = 0x4000;
public static int header = banner + banner_size + BM;
public static int header_size = 0xF0;
public static int footer = header + header_size + BM;
public static int footer_size = 0x4E0;
public static int TMD = footer + footer_size + BM;
public static int TMD_SIZE = 0xB40;
static int BM = 0x20;
private static int banner = 0x0;
private static int banner_size = 0x4000;
private static int header = banner + banner_size + BM;
private static int header_size = 0xF0;
private static int footer = header + header_size + BM;
private static int footer_size = 0x4E0;
static int TMD = footer + footer_size + BM;
private static int TMD_SIZE = 0xB40;
public static int SRL = TMD + TMD_SIZE + BM;
public static int SRL_SIZE = 0x0; // Need INIT THIS PLEASE
public static int SAV = 0x0;
Expand Down
9 changes: 6 additions & 3 deletions src/main/java/faith/elguadia/tadpool/api.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,10 @@
import static faith.elguadia.tadpool.Constants.*;

public class api {
private final static char[] hexArray = "0123456789ABCDEF".toCharArray();
public static BigInteger add_128(BigInteger a,BigInteger b){
private static BigInteger add_128(BigInteger a, BigInteger b){
return a.add(b).and(F128);
}
public static BigInteger rol_128(BigInteger n, int shift) {
private static BigInteger rol_128(BigInteger n, int shift) {
BigInteger left = n.shiftLeft(shift % 128);
BigInteger right = n.shiftRight(128 - (shift % 128));
return left.or(right).and(F128);
Expand Down Expand Up @@ -58,4 +57,8 @@ public static byte[] encryptMessage(byte[] s,byte[] key, byte[] iv) throws NoSuc
cipher.init(Cipher.ENCRYPT_MODE,sk,new IvParameterSpec(iv));
return cipher.update(s);
}




}
180 changes: 8 additions & 172 deletions src/main/java/faith/elguadia/tadpool/start.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import java.util.*;

import static faith.elguadia.tadpool.Constants.*;
import static faith.elguadia.tadpool.tad.tadModification.*;

public class start {
public static void main(String[] args) {
Expand Down Expand Up @@ -49,186 +50,21 @@ public static void main(String[] args) {
}
} else if (args[1].equals("r")) {
try {
signFooter();
fixHash(new File(default_dir + "header.bin"), new File(default_dir + "footer.bin"));
signFooter(new File("ctcert.bin"),new File(default_dir+"footer.bin"));
rebuildTad(args[0]);
} catch (Exception e) {
e.printStackTrace();
// Empty.
}
}
}
}

private static void rebuildTad(String id) throws IOException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidAlgorithmParameterException, InvalidKeyException {
List<String> full_namelist = new ArrayList<>();
full_namelist.add("banner.bin");
full_namelist.add("header.bin");
full_namelist.add("footer.bin");
Collections.addAll(full_namelist, content_list);
File target = new File(id+".patched");
byte[] key = api.getNormalKey(keyx,keyy);
byte[] bm;
byte[] content;
byte[] section;
byte[] iv = new byte[0x10];
//tad_section = new ArrayList<>(14);
File f;
try(FileOutputStream fos = new FileOutputStream(target)) {
for (String s : full_namelist) {
f = new File(default_dir + s);
if (f.exists()) {
System.out.println("Encrypting:" + s);
content = Files.readAllBytes(f.toPath());
bm = generateBlockMetadata(content); // 0x0+10 = AES MAC over SHA256(SHA256 of PlainData), 0x10+10 = IV (RandGen)
System.arraycopy(bm, 0x10, iv, 0, iv.length); // bm -> IV
System.out.println("L92IV:"+Hex.encodeHexString(iv)); // is IV Okay?
content = api.encryptMessage(content, key, iv); // Encrypt.
System.out.println("Length:"+content.length); // contentLength
section = new byte[content.length + bm.length]; // section is content+bm
System.out.println("New Length:"+section.length);
if(section.length == content.length+0x20){ // checing.
System.arraycopy(content, 0, section, 0, content.length); // Merge1
System.arraycopy(bm, 0, section, content.length, bm.length); // Merge2
fos.write(section);
}
}
}
fos.flush();
}
//System.out.println(tad_section);
}


private static void signFooter() throws IOException {
//Process p = Runtime.getRuntime().exec("ctr-dsiwaretool.exe "+default_dir+footerName+" ctcert.bin --write");
ProcessBuilder pb = new ProcessBuilder("ctr-dsiwaretool.exe",""+default_dir+ "footer.bin","ctcert.bin","--write")
.inheritIO()
.directory(new File(System.getProperty("user.dir")));

pb.start();
//System.out.println(p.getInputStream().read());
}

private static byte[] generateBlockMetadata(byte[] content) throws NoSuchAlgorithmException { //Get ContentBlock
System.out.println("Entry generateBM.");
MessageDigest md = MessageDigest.getInstance("SHA-256");
SecureRandom sr = SecureRandom.getInstanceStrong();
byte[] ret = new byte[0x20];
byte[] hash = md.digest(content);
System.out.println("Hash:"+Hex.encodeHexString(hash));
byte[] key = api.getNormalKey(cmac_keyx,keyy);
System.out.println("CMACKey:"+Hex.encodeHexString(key));
// Generating CMAC here.
CipherParameters cp = new KeyParameter(key);
//BlockCipher aes = new AESEngine();
CMac mac = new CMac(new AESEngine(),128);
mac.init(cp);
mac.update(hash,0,hash.length);
mac.doFinal(ret,0);
System.out.println(Hex.encodeHexString(ret));
//Generate IV here
byte[] iv = new byte[0x10];
sr.nextBytes(iv);
System.arraycopy(iv, 0, ret, 0x10, iv.length);
System.out.println("IV:"+Hex.encodeHexString(iv));
System.out.println("Ret:"+Hex.encodeHexString(ret));
return ret;

}

} else {
System.out.println("TADpole-Java By Chromaryu: https://github.com/knight-ryu12");
System.out.println("in support of jason0594, saibotu, Kartik");
System.out.println("Usage: java -jar TADpole.jar <DSiware export.bin> <r/d>");
System.out.println("r = rebuild, d = dump");
System.exit(0);

private static void fixHash(File header, File footer) throws NoSuchAlgorithmException, IOException, DecoderException {
MessageDigest md = MessageDigest.getInstance("SHA-256");
File tmp;
int i = 0;
int[] sizes = new int[11];
String[] hash = new String[13];
List<String> footer_namelist = new ArrayList<>();
footer_namelist.add("banner.bin");
footer_namelist.add("footer.bin");
Collections.addAll(footer_namelist, content_list);
for (String s : content_list) {
tmp = new File(default_dir + s);
sizes[i] = tmp.exists() ? (int) tmp.length() : 0;
if (tmp.length() == 0xB40) sizes[i] = 0xB34;
i++;
}
//sizes[0] = 0xB34;

System.out.println(Arrays.toString(sizes)); // Debug
i = 0; // Reset Counter.
for (String s : footer_namelist) {
tmp = new File(default_dir + s);
hash[i] = tmp.exists() ? Hex.encodeHexString(md.digest(Files.readAllBytes(tmp.toPath()))) : "0000000000000000000000000000000000000000000000000000000000000000";
i++;
}
System.out.println(Arrays.toString(hash));

//System.out.println(sizes);
try(RandomAccessFile raf = new RandomAccessFile(header,"rwd")) {
ByteBuffer buf = ByteBuffer.allocate(4).order(ByteOrder.LITTLE_ENDIAN);
int off = 0x48;
for(int sz : sizes) {
buf.putInt(sz);
buf.rewind();
raf.seek(off);
raf.write(buf.array());
off+=4;
}
}
System.out.println("Header fixed.");
try(RandomAccessFile raf = new RandomAccessFile(footer,"rwd")) {
int off = 0;
for(String s : hash) {
raf.seek(off);
raf.write(Hex.decodeHex(s));
off+=0x20;
}
}
System.out.println("Footer fixed.");
}

private static void getDump(File f,int data_offset,int size,String filename) throws IOException,NoSuchAlgorithmException,NoSuchPaddingException,InvalidAlgorithmParameterException,InvalidKeyException {
MessageDigest md = MessageDigest.getInstance("SHA-256");
System.out.println("Dumping:"+filename);
byte[] key = api.getNormalKey(keyx, keyy);
System.out.println("Using NK:"+Hex.encodeHexString(key));
byte[] iv = new byte[16];
byte[] enc = new byte[size];
byte[] dec;
try(FileInputStream fis = new FileInputStream(f); BufferedInputStream bis = new BufferedInputStream(fis)) {
bis.skip(data_offset);
bis.read(enc,0,size); // Data skipped data_offset+size.
bis.skip(0x10); // We don't need BM 0x0-0x10. = AES MAC
bis.read(iv,0,0x10); // Read BM 0x10-0x20. = 16Byte IV!
}
System.out.println("Using IV:"+Hex.encodeHexString(iv));
dec = api.decryptMessage(enc,key,iv);
System.out.println("SHA-256:"+Hex.encodeHexString(md.digest(dec)));
File out = new File(Constants.default_dir+filename);
System.out.println("Writing to file:"+filename);
try(FileOutputStream fos = new FileOutputStream(out)) {
IOUtils.write(dec, fos);
}
}

private static void getContentSize(File header){
try {
byte[] h = Files.readAllBytes(header.toPath());
System.out.println(h.length);
ByteBuffer buffer = ByteBuffer.allocate(0x2C).order(ByteOrder.LITTLE_ENDIAN).put(h, 0x48, 0x2C);
buffer.rewind();
for(int i =0; i<11; i++) {
long c = Integer.toUnsignedLong(buffer.getInt());
if(c == 0xB34) {
c = 0xB40; //Dirtyhaxx
}
content_sizelist[i] = c;
}
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(Arrays.toString(content_sizelist));
}
}
Loading

0 comments on commit 7e81ef3

Please sign in to comment.