RomFsEncryptedProvider complete
This commit is contained in:
parent
8225f0fcba
commit
416e5280a6
1 changed files with 67 additions and 19 deletions
|
@ -26,7 +26,7 @@ import java.util.Arrays;
|
||||||
|
|
||||||
public class RomFsEncryptedProvider implements IRomFsProvider{
|
public class RomFsEncryptedProvider implements IRomFsProvider{
|
||||||
|
|
||||||
private static long level6Offset;
|
private long level6Offset;
|
||||||
|
|
||||||
private File file;
|
private File file;
|
||||||
private Level6Header header;
|
private Level6Header header;
|
||||||
|
@ -189,33 +189,80 @@ public class RomFsEncryptedProvider implements IRomFsProvider{
|
||||||
Thread workerThread;
|
Thread workerThread;
|
||||||
|
|
||||||
PipedInputStream streamIn = new PipedInputStream(streamOut);
|
PipedInputStream streamIn = new PipedInputStream(streamOut);
|
||||||
|
|
||||||
workerThread = new Thread(() -> {
|
workerThread = new Thread(() -> {
|
||||||
System.out.println("RomFsDecryptedProvider -> getContent(): Executing thread");
|
System.out.println("RomFsDecryptedProvider -> getContent(): Executing thread");
|
||||||
try {
|
try {
|
||||||
long subFileRealPosition = level6Offset + header.getFileDataOffset() + entry.getFileOffset();
|
|
||||||
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
|
|
||||||
bis.skip(subFileRealPosition);
|
|
||||||
|
|
||||||
int readPice = 8388608; // 8mb NOTE: consider switching to 1mb 1048576
|
byte[] encryptedBlock;
|
||||||
|
byte[] dectyptedBlock;
|
||||||
|
|
||||||
long readFrom = 0;
|
RandomAccessFile raf = new RandomAccessFile(file, "r");
|
||||||
long realFileSize = entry.getFileSize();
|
|
||||||
|
|
||||||
byte[] readBuf;
|
//0
|
||||||
|
AesCtrDecryptSimple decryptor = new AesCtrDecryptSimple(key, sectionCTR, mediaStartOffset * 0x200);
|
||||||
|
|
||||||
while (readFrom < realFileSize) {
|
long startBlock = (entry.getFileOffset() + header.getFileDataOffset()) / 0x200;
|
||||||
if (realFileSize - readFrom < readPice)
|
|
||||||
readPice = Math.toIntExact(realFileSize - readFrom); // it's safe, I guarantee
|
decryptor.skipNext(level6Offset / 0x200 + startBlock);
|
||||||
readBuf = new byte[readPice];
|
|
||||||
if (bis.read(readBuf) != readPice) {
|
long abosluteOffsetPosition = romFSoffsetPosition + (mediaStartOffset * 0x200);
|
||||||
System.out.println("RomFsDecryptedProvider -> getContent(): Unable to read requested size from file.");
|
|
||||||
|
raf.seek(abosluteOffsetPosition + level6Offset + startBlock * 0x200);
|
||||||
|
|
||||||
|
//1
|
||||||
|
long ignoreBytes = (entry.getFileOffset() + header.getFileDataOffset()) - startBlock * 0x200;
|
||||||
|
|
||||||
|
if (ignoreBytes > 0) {
|
||||||
|
encryptedBlock = new byte[0x200];
|
||||||
|
if (raf.read(encryptedBlock) == 0x200) {
|
||||||
|
dectyptedBlock = decryptor.dectyptNext(encryptedBlock);
|
||||||
|
// If we have extra-small file that is less then a block and even more
|
||||||
|
if ((0x200 - ignoreBytes) > entry.getFileSize()){
|
||||||
|
streamOut.write(dectyptedBlock, (int)ignoreBytes, (int) entry.getFileSize()); // safe cast
|
||||||
|
raf.close();
|
||||||
|
streamOut.close();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
streamOut.write(readBuf);
|
else {
|
||||||
readFrom += readPice;
|
streamOut.write(dectyptedBlock, (int) ignoreBytes, 0x200 - (int) ignoreBytes);
|
||||||
}
|
}
|
||||||
bis.close();
|
}
|
||||||
|
else {
|
||||||
|
throw new Exception("RomFsEncryptedProvider(): Unable to get 512 bytes from 1st bock for Directory Metadata Table");
|
||||||
|
}
|
||||||
|
startBlock++;
|
||||||
|
}
|
||||||
|
long endBlock = (entry.getFileSize() + ignoreBytes) / 0x200 + startBlock; // <- pointing to place where any data related to this media-block ends
|
||||||
|
|
||||||
|
//2
|
||||||
|
int extraData = (int) ((endBlock - startBlock)*0x200 - (entry.getFileSize() + ignoreBytes));
|
||||||
|
|
||||||
|
if (extraData < 0)
|
||||||
|
endBlock--;
|
||||||
|
//3
|
||||||
|
while ( startBlock < endBlock ) {
|
||||||
|
encryptedBlock = new byte[0x200];
|
||||||
|
if (raf.read(encryptedBlock) == 0x200) {
|
||||||
|
dectyptedBlock = decryptor.dectyptNext(encryptedBlock);
|
||||||
|
streamOut.write(dectyptedBlock);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw new Exception("RomFsEncryptedProvider(): Unable to get 512 bytes from block for Directory Metadata Table");
|
||||||
|
|
||||||
|
startBlock++;
|
||||||
|
}
|
||||||
|
|
||||||
|
//4
|
||||||
|
if (extraData != 0){ // In case we didn't get what we want
|
||||||
|
encryptedBlock = new byte[0x200];
|
||||||
|
if (raf.read(encryptedBlock) == 0x200) {
|
||||||
|
dectyptedBlock = decryptor.dectyptNext(encryptedBlock);
|
||||||
|
streamOut.write(dectyptedBlock, 0, Math.abs(extraData));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw new Exception("RomFsEncryptedProvider(): Unable to get 512 bytes from block for Directory Metadata Table");
|
||||||
|
}
|
||||||
|
raf.close();
|
||||||
streamOut.close();
|
streamOut.close();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
System.out.println("RomFsDecryptedProvider -> getContent(): Unable to provide stream");
|
System.out.println("RomFsDecryptedProvider -> getContent(): Unable to provide stream");
|
||||||
|
@ -226,6 +273,7 @@ public class RomFsEncryptedProvider implements IRomFsProvider{
|
||||||
workerThread.start();
|
workerThread.start();
|
||||||
return streamIn;
|
return streamIn;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public File getFile() {
|
public File getFile() {
|
||||||
return file;
|
return file;
|
||||||
|
|
Loading…
Reference in a new issue