Unify export functionality
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
Dmitry Isaenko 2023-01-06 17:38:05 +03:00
parent 3262fb2360
commit e47d977779
9 changed files with 159 additions and 278 deletions

View file

@ -0,0 +1,47 @@
package libKonogonka.Tools;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class ExportAble {
protected BufferedInputStream stream;
protected boolean export(String saveTo, String fileName, long skip, long size) throws Exception{
if (skip != stream.skip(skip))
throw new Exception("Can't seek to start position: "+skip);
File location = new File(saveTo);
location.mkdirs();
try (BufferedOutputStream extractedFileBOS = new BufferedOutputStream(
Files.newOutputStream(Paths.get(saveTo+File.separator+fileName)))){
int blockSize = 0x200;
if (size < 0x200)
blockSize = (int) size;
long i = 0;
byte[] block = new byte[blockSize];
int actuallyRead;
while (true) {
if ((actuallyRead = stream.read(block)) != blockSize)
throw new Exception("Read failure. Block Size: "+blockSize+", actuallyRead: "+actuallyRead);
extractedFileBOS.write(block);
i += blockSize;
if ((i + blockSize) > size) {
blockSize = (int) (size - i);
if (blockSize == 0)
break;
block = new byte[blockSize];
}
}
}
stream.close();
return true;
}
}

View file

@ -203,6 +203,8 @@ public class KernelAccessControlProvider {
canDebugOthers = (block >> 18 & 1) != 0;
log.trace("DEBUGFLAGS "+canBeDebugged+" "+canDebugOthers);
break;
case 0x20:
break;
default:
log.warn("INVALID ind:0b"+Integer.toBinaryString(block));
}

View file

@ -19,6 +19,7 @@
package libKonogonka.Tools.PFS0;
import libKonogonka.RainbowDump;
import libKonogonka.Tools.ExportAble;
import libKonogonka.Tools.ISuperProvider;
import libKonogonka.Tools.NCA.NCASectionTableBlock.SuperBlockPFS0;
import libKonogonka.ctraes.InFileStreamProducer;
@ -30,14 +31,13 @@ import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.LinkedList;
public class PFS0Provider implements ISuperProvider {
public class PFS0Provider extends ExportAble implements ISuperProvider {
private final static Logger log = LogManager.getLogger(PFS0Provider.class);
private final long rawBlockDataStart;
private long offsetPositionInFile;
private final InFileStreamProducer producer;
private BufferedInputStream stream;
private SuperBlockPFS0 superBlockPFS0;
private long mediaStartOffset;
@ -108,47 +108,16 @@ public class PFS0Provider implements ISuperProvider {
}
@Override
public boolean exportContent(String saveToLocation, int subFileNumber){
try {
PFS0subFile subFile = header.getPfs0subFiles()[subFileNumber];
File location = new File(saveToLocation);
location.mkdirs();
try (BufferedOutputStream extractedFileBOS = new BufferedOutputStream(
Files.newOutputStream(Paths.get(saveToLocation+File.separator+subFile.getName())))){
this.stream = producer.produce();
long subFileSize = subFile.getSize();
long toSkip = subFile.getOffset() + mediaStartOffset * 0x200 + rawBlockDataStart;
if (toSkip != stream.skip(toSkip))
throw new Exception("Unable to skip offset: "+toSkip);
int blockSize = 0x200;
if (subFileSize < 0x200)
blockSize = (int) subFileSize;
long i = 0;
byte[] block = new byte[blockSize];
int actuallyRead;
while (true) {
if ((actuallyRead = stream.read(block)) != blockSize)
throw new Exception("Read failure. Block Size: "+blockSize+", actuallyRead: "+actuallyRead);
extractedFileBOS.write(block);
i += blockSize;
if ((i + blockSize) > subFileSize) {
blockSize = (int) (subFileSize - i);
if (blockSize == 0)
break;
block = new byte[blockSize];
}
}
return export(saveToLocation, subFile.getName(), toSkip, subFile.getSize());
}
catch (Exception e){
log.error("File export failure", e);
return false;
}
return true;
}
@Override

View file

@ -18,7 +18,7 @@
*/
package libKonogonka.Tools.RomFs;
import libKonogonka.Tools.PFS0.PFS0subFile;
import libKonogonka.Tools.ExportAble;
import libKonogonka.Tools.RomFs.view.DirectoryMetaTablePlainView;
import libKonogonka.Tools.RomFs.view.FileMetaTablePlainView;
import libKonogonka.ctraes.InFileStreamProducer;
@ -26,9 +26,8 @@ import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.io.*;
import java.nio.file.Files;
public class RomFsProvider{
public class RomFsProvider extends ExportAble {
private final static Logger log = LogManager.getLogger(RomFsProvider.class);
private final InFileStreamProducer producer;
@ -99,36 +98,9 @@ public class RomFsProvider{
}
private void exportSingleFile(FileSystemEntry entry, String saveToLocation) throws Exception {
File contentFile = new File(saveToLocation + entry.getName());
try(BufferedOutputStream extractedFileBOS = new BufferedOutputStream(Files.newOutputStream(contentFile.toPath()));
BufferedInputStream stream = producer.produce()) {
stream = producer.produce();
long skipBytes = entry.getOffset() + mediaStartOffset * 0x200 + level6Header.getFileDataOffset() + level6Offset;
if (skipBytes != stream.skip(skipBytes))
throw new Exception("Can't skip");
int blockSize = 0x200;
if (entry.getSize() < 0x200)
blockSize = (int) entry.getSize();
long i = 0;
byte[] block = new byte[blockSize];
int actuallyRead;
while (true) {
if ((actuallyRead = stream.read(block)) != blockSize)
throw new Exception("Read failure. Block Size: "+blockSize+", actuallyRead: "+actuallyRead);
extractedFileBOS.write(block);
i += blockSize;
if ((i + blockSize) >= entry.getSize()) {
blockSize = (int) (entry.getSize() - i);
if (blockSize == 0)
break;
block = new byte[blockSize];
}
}
}
export(saveToLocation, entry.getName(), skipBytes, entry.getSize());
}
public InFileStreamProducer getStreamProducer(FileSystemEntry entry) throws Exception{

View file

@ -18,6 +18,7 @@
*/
package libKonogonka.Tools.XCI;
import libKonogonka.Tools.ExportAble;
import libKonogonka.Tools.ISuperProvider;
import libKonogonka.ctraes.InFileStreamProducer;
import org.apache.logging.log4j.LogManager;
@ -34,7 +35,7 @@ import static libKonogonka.Converter.*;
/**
* HFS0
* */
public class HFS0Provider implements ISuperProvider {
public class HFS0Provider extends ExportAble implements ISuperProvider {
private final static Logger log = LogManager.getLogger(HFS0Provider.class);
private final String magic;
@ -140,41 +141,8 @@ public class HFS0Provider implements ISuperProvider {
@Override
public boolean exportContent(String saveToLocation, int subFileNumber) throws Exception {
HFS0File subFile = hfs0Files[subFileNumber];
File location = new File(saveToLocation);
location.mkdirs();
try (BufferedOutputStream extractedFileBOS = new BufferedOutputStream(
Files.newOutputStream(Paths.get(saveToLocation+File.separator+subFile.getName())));
BufferedInputStream stream = getStreamProducer(subFileNumber).produce()){
long subFileSize = subFile.getSize();
int blockSize = 0x200;
if (subFileSize < 0x200)
blockSize = (int) subFileSize;
long i = 0;
byte[] block = new byte[blockSize];
int actuallyRead;
while (true) {
if ((actuallyRead = stream.read(block)) != blockSize)
throw new Exception("Read failure. Block Size: "+blockSize+", actuallyRead: "+actuallyRead);
extractedFileBOS.write(block);
i += blockSize;
if ((i + blockSize) > subFileSize) {
blockSize = (int) (subFileSize - i);
if (blockSize == 0)
break;
block = new byte[blockSize];
}
}
}
catch (Exception e){
log.error("File export failure", e);
return false;
}
return true;
stream = getStreamProducer(subFileNumber).produce();
return export(saveToLocation, subFile.getName(), 0, subFile.getSize());
}
@Override
public InFileStreamProducer getStreamProducer(String subFileName) throws FileNotFoundException{

View file

@ -19,21 +19,21 @@
package libKonogonka.Tools.other.System2;
import libKonogonka.KeyChainHolder;
import libKonogonka.Tools.ExportAble;
import libKonogonka.Tools.other.System2.ini1.Ini1Provider;
import libKonogonka.ctraesclassic.AesCtrClassicBufferedInputStream;
import libKonogonka.ctraesclassic.AesCtrDecryptClassic;
import libKonogonka.ctraesclassic.AesCtrStream;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import javax.crypto.CipherInputStream;
import java.io.*;
import java.nio.ByteBuffer;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
public class System2Provider {
private final static Logger log = LogManager.getLogger(System2Provider.class);
public class System2Provider extends ExportAble {
private byte[] rsa2048signature;
private System2Header header;
private KernelMap kernelMap;
@ -46,20 +46,20 @@ public class System2Provider {
this.pathToFile = pathToFile;
this.keyChainHolder = keyChainHolder;
try (BufferedInputStream stream = new BufferedInputStream(Files.newInputStream(Paths.get(pathToFile)))) {
readSignatures(stream);
readHeader(stream);
this.stream = new BufferedInputStream(Files.newInputStream(Paths.get(pathToFile)));
readSignatures();
readHeader();
findIni1KernelMap();
}
this.stream.close();
}
private void readSignatures(BufferedInputStream stream) throws Exception{
private void readSignatures() throws Exception{
rsa2048signature = new byte[0x100];
if (0x100 != stream.read(rsa2048signature))
throw new Exception("Unable to read System2 RSA-2048 signature bytes");
}
private void readHeader(BufferedInputStream stream) throws Exception{
private void readHeader() throws Exception{
byte[] headerBytes = new byte[0x100];
if (0x100 != stream.read(headerBytes))
throw new Exception("Unable to read System2 header bytes");
@ -74,11 +74,11 @@ public class System2Provider {
throw new Exception("Unable to skip offset: " + toSkip);
ByteBuffer byteBuffer = ByteBuffer.allocate(0x1000);
try (CipherInputStream stream = AesCtrStream.getStream(header.getKey(), header.getSection0Ctr(), fis);) {
try (CipherInputStream cipherInputStream = AesCtrStream.getStream(header.getKey(), header.getSection0Ctr(), fis);) {
for (int j = 0; j < 8; j++) {
byte[] block = new byte[0x200];
int actuallyRead;
if ((actuallyRead = stream.read(block)) != 0x200)
if ((actuallyRead = cipherInputStream.read(block)) != 0x200)
throw new Exception("Read failure " + actuallyRead);
byteBuffer.put(block);
}
@ -95,47 +95,15 @@ public class System2Provider {
}
public boolean exportKernel(String saveTo) throws Exception{
File location = new File(saveTo);
location.mkdirs();
Path filePath = Paths.get(pathToFile);
AesCtrDecryptClassic decryptor = new AesCtrDecryptClassic(header.getKey(), header.getSection0Ctr());
stream = new AesCtrClassicBufferedInputStream(decryptor,
0x200,
Files.size(filePath), // size of system2
Files.newInputStream(filePath),
Files.size(filePath));
InputStream fis = Files.newInputStream(Paths.get(pathToFile));
// Encrypted section comes next
long toSkip = 0x200;
if (toSkip != fis.skip(toSkip))
throw new Exception("Unable to skip offset: "+toSkip);
try (CipherInputStream stream = AesCtrStream.getStream(header.getKey(), header.getSection0Ctr(), fis);
BufferedOutputStream extractedFileBOS = new BufferedOutputStream(
Files.newOutputStream(Paths.get(saveTo+File.separator+"Kernel.bin")))){
long kernelSize = header.getSection0size();
int blockSize = 0x200;
if (kernelSize < 0x200)
blockSize = (int) kernelSize;
long i = 0;
byte[] block = new byte[blockSize];
int actuallyRead;
while (true) {
if ((actuallyRead = stream.read(block)) != blockSize)
throw new Exception("Read failure. Block Size: "+blockSize+", actuallyRead: "+actuallyRead);
extractedFileBOS.write(block);
i += blockSize;
if ((i + blockSize) > kernelSize) {
blockSize = (int) (kernelSize - i);
if (blockSize == 0)
break;
block = new byte[blockSize];
}
}
}
catch (Exception e){
log.error("File export failure", e);
return false;
}
return true;
return export(saveTo, "Kernel.bin", 0x200, header.getSection0size());
}
public byte[] getRsa2048signature() { return rsa2048signature; }

View file

@ -18,6 +18,7 @@
*/
package libKonogonka.Tools.other.System2.ini1;
import libKonogonka.Tools.ExportAble;
import libKonogonka.Tools.other.System2.KernelMap;
import libKonogonka.Tools.other.System2.System2Header;
import libKonogonka.ctraesclassic.AesCtrClassicBufferedInputStream;
@ -25,25 +26,19 @@ import libKonogonka.ctraesclassic.AesCtrDecryptClassic;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.io.BufferedOutputStream;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
public class Ini1Provider {
private final static Logger log = LogManager.getLogger(Ini1Provider.class);
public class Ini1Provider extends ExportAble {
private final System2Header system2Header;
private final String pathToFile;
private final KernelMap kernelMap;
private Ini1Header ini1Header;
private List<Kip1> kip1List;
private AesCtrClassicBufferedInputStream stream;
public Ini1Provider(System2Header system2Header, String pathToFile, KernelMap kernelMap) throws Exception{
this.system2Header = system2Header;
this.pathToFile = pathToFile;
@ -100,80 +95,14 @@ public class Ini1Provider {
public boolean exportIni1(String saveTo) throws Exception{
makeStream();
File location = new File(saveTo);
location.mkdirs();
try (BufferedOutputStream extractedFileBOS = new BufferedOutputStream(
Files.newOutputStream(Paths.get(saveTo+File.separator+"INI1.bin")))){
long iniSize = ini1Header.getSize();
int blockSize = 0x200;
if (iniSize < 0x200)
blockSize = (int) iniSize;
long i = 0;
byte[] block = new byte[blockSize];
int actuallyRead;
while (true) {
if ((actuallyRead = stream.read(block)) != blockSize)
throw new Exception("Read failure. Block Size: "+blockSize+", actuallyRead: "+actuallyRead);
extractedFileBOS.write(block);
i += blockSize;
if ((i + blockSize) > iniSize) {
blockSize = (int) (iniSize - i);
if (blockSize == 0)
break;
block = new byte[blockSize];
}
}
}
catch (Exception e){
log.error("File export failure", e);
return false;
}
return true;
return export(saveTo, "INI1.bin", 0, ini1Header.getSize());
}
public boolean exportKip1(String saveTo, Kip1 kip1) throws Exception{
makeStream();
long startOffset = 0x10 + kip1.getStartOffset();
if (startOffset != stream.skip(startOffset))
throw new Exception("Can't seek to start position of KIP1: "+startOffset);
File location = new File(saveTo);
location.mkdirs();
try (BufferedOutputStream extractedFileBOS = new BufferedOutputStream(
Files.newOutputStream(Paths.get(saveTo+File.separator+kip1.getName()+".kip1")))){
long size = kip1.getEndOffset()-kip1.getStartOffset();
int blockSize = 0x200;
if (size < 0x200)
blockSize = (int) size;
long i = 0;
byte[] block = new byte[blockSize];
int actuallyRead;
while (true) {
if ((actuallyRead = stream.read(block)) != blockSize)
throw new Exception("Read failure. Block Size: "+blockSize+", actuallyRead: "+actuallyRead);
extractedFileBOS.write(block);
i += blockSize;
if ((i + blockSize) > size) {
blockSize = (int) (size - i);
if (blockSize == 0)
break;
block = new byte[blockSize];
}
}
}
catch (Exception e){
log.error("File export failure", e);
return false;
}
return true;
return export(saveTo,
kip1.getName()+".kip1",
0x10 + kip1.getStartOffset(),
kip1.getEndOffset()-kip1.getStartOffset());
}
}

View file

@ -25,55 +25,70 @@ import libKonogonka.Tools.NSO.SegmentHeader;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;
public class Kip1 {
private final static Logger log = LogManager.getLogger(Kip1.class);
private final String magic;
private final String name;
private final byte[] programId;
private final int version;
private final byte mainThreadPriority;
private final byte mainThreadCoreNumber;
private final byte reserved1;
private final byte flags; // bit0=TextCompress, bit1=RoCompress, bit2=DataCompress, bit3=Is64BitInstruction, bit4=ProcessAddressSpace64Bit, bit5=[2.0.0+] UseSecureMemory
private final SegmentHeader textSegmentHeader;
private final int threadAffinityMask;
private final SegmentHeader roDataSegmentHeader;
private final int mainThreadStackSize ;
private final SegmentHeader rwDataSegmentHeader;
private final byte[] reserved2;
private final SegmentHeader bssSegmentHeader;
private final byte[] reserved3;
private final KernelAccessControlProvider kernelCapabilityData;
private String magic;
private String name;
private byte[] programId;
private int version;
private byte mainThreadPriority;
private byte mainThreadCoreNumber;
private byte reserved1;
private byte flags;
private SegmentHeader textSegmentHeader;
private int threadAffinityMask;
private SegmentHeader roDataSegmentHeader;
private int mainThreadStackSize ;
private SegmentHeader rwDataSegmentHeader;
private byte[] reserved2;
private SegmentHeader bssSegmentHeader;
private byte[] reserved3;
private KernelAccessControlProvider kernelCapabilityData;
private final long startOffset;
private final long endOffset;
private long startOffset;
private long endOffset;
public Kip1(byte[] kip1Bytes, long kip1StartOffset) throws Exception{
this.magic = new String(kip1Bytes, 0, 0x4);
this.name = new String(kip1Bytes, 0x4, 0xC).trim();
this.programId = Arrays.copyOfRange(kip1Bytes, 0x10, 0x18);
this.version = Converter.getLEint(kip1Bytes, 0x18);
this.mainThreadPriority = kip1Bytes[0x1c];
this.mainThreadCoreNumber = kip1Bytes[0x1d];
this.reserved1 = kip1Bytes[0x1e];
this.flags = kip1Bytes[0x1f];
this.textSegmentHeader = new SegmentHeader(kip1Bytes, 0x20);
this.threadAffinityMask = Converter.getLEint(kip1Bytes, 0x2c);
this.roDataSegmentHeader = new SegmentHeader(kip1Bytes, 0x30);
this.mainThreadStackSize = Converter.getLEint(kip1Bytes, 0x3c);
this.rwDataSegmentHeader = new SegmentHeader(kip1Bytes, 0x40);
this.reserved2 = Arrays.copyOfRange(kip1Bytes, 0x4c, 0x50);
this.bssSegmentHeader = new SegmentHeader(kip1Bytes, 0x50);
this.reserved3 = Arrays.copyOfRange(kip1Bytes, 0x5c, 0x80);
this.kernelCapabilityData = new KernelAccessControlProvider(Arrays.copyOfRange(kip1Bytes, 0x80, 0x100));
public Kip1(String fileLocation) throws Exception{
try (BufferedInputStream stream = new BufferedInputStream(Files.newInputStream(Paths.get(fileLocation)));) {
byte[] kip1HeaderBytes = new byte[0x100];
if (0x100 != stream.read(kip1HeaderBytes))
throw new Exception("Unable to read KIP1 file header");
makeHeader(kip1HeaderBytes, 0);
}
}
public Kip1(byte[] kip1HeaderBytes, long kip1StartOffset) throws Exception{
makeHeader(kip1HeaderBytes, kip1StartOffset);
}
private void makeHeader(byte[] kip1HeaderBytes, long kip1StartOffset) throws Exception{
this.magic = new String(kip1HeaderBytes, 0, 0x4);
this.name = new String(kip1HeaderBytes, 0x4, 0xC).trim();
this.programId = Arrays.copyOfRange(kip1HeaderBytes, 0x10, 0x18);
this.version = Converter.getLEint(kip1HeaderBytes, 0x18);
this.mainThreadPriority = kip1HeaderBytes[0x1c];
this.mainThreadCoreNumber = kip1HeaderBytes[0x1d];
this.reserved1 = kip1HeaderBytes[0x1e];
this.flags = kip1HeaderBytes[0x1f];
this.textSegmentHeader = new SegmentHeader(kip1HeaderBytes, 0x20);
this.threadAffinityMask = Converter.getLEint(kip1HeaderBytes, 0x2c);
this.roDataSegmentHeader = new SegmentHeader(kip1HeaderBytes, 0x30);
this.mainThreadStackSize = Converter.getLEint(kip1HeaderBytes, 0x3c);
this.rwDataSegmentHeader = new SegmentHeader(kip1HeaderBytes, 0x40);
this.reserved2 = Arrays.copyOfRange(kip1HeaderBytes, 0x4c, 0x50);
this.bssSegmentHeader = new SegmentHeader(kip1HeaderBytes, 0x50);
this.reserved3 = Arrays.copyOfRange(kip1HeaderBytes, 0x5c, 0x80);
this.kernelCapabilityData = new KernelAccessControlProvider(Arrays.copyOfRange(kip1HeaderBytes, 0x80, 0x100));
this.startOffset = kip1StartOffset;
this.endOffset = 0x100 + kip1StartOffset + textSegmentHeader.getSizeAsDecompressed() + roDataSegmentHeader.getSizeAsDecompressed() +
rwDataSegmentHeader.getSizeAsDecompressed() + bssSegmentHeader.getSizeAsDecompressed();
}
public String getMagic() { return magic; }
@ -134,7 +149,13 @@ public class Kip1 {
"Main thread priority : " + String.format("0x%x", mainThreadPriority) + "\n" +
"Main thread core number : " + String.format("0x%x", mainThreadCoreNumber) + "\n" +
"Reserved 1 : " + String.format("0x%x", reserved1) + "\n" +
"Flags : " + flags + "\n" +
"Flags : " + Converter.intToBinaryString(flags) + "\n" +
" 0| .text compress : " + ((flags & 1) == 1 ? "YES" : "NO") + "\n" +
" 1| .ro compress : " + ((flags >> 1 & 1) == 1 ? "YES" : "NO") + "\n" +
" 2| .rw compress : " + ((flags >> 2 & 1) == 1 ? "YES" : "NO") + "\n" +
" 3| Is 64-bit instruction : " + ((flags >> 3 & 1) == 1 ? "YES" : "NO") + "\n" +
" 4| Process addr. space 64-bit : " + ((flags >> 4 & 1) == 1 ? "YES" : "NO") + "\n" +
" 5| Use secure memory : " + ((flags >> 5 & 1) == 1 ? "YES" : "NO") + "\n" +
".text segment header\n" +
" Segment offset : " + RainbowDump.formatDecHexString(textSegmentHeader.getSegmentOffset()) + "\n" +
" Memory offset : " + RainbowDump.formatDecHexString(textSegmentHeader.getMemoryOffset()) + "\n" +
@ -145,7 +166,7 @@ public class Kip1 {
" Memory offset : " + RainbowDump.formatDecHexString(roDataSegmentHeader.getMemoryOffset()) + "\n" +
" Size : " + RainbowDump.formatDecHexString(roDataSegmentHeader.getSizeAsDecompressed()) + "\n" +
"Main thread stack size : " + RainbowDump.formatDecHexString(mainThreadStackSize) + "\n" +
".data segment header\n" +
".rw segment header\n" +
" Segment offset : " + RainbowDump.formatDecHexString(rwDataSegmentHeader.getSegmentOffset()) + "\n" +
" Memory offset : " + RainbowDump.formatDecHexString(rwDataSegmentHeader.getMemoryOffset()) + "\n" +
" Size : " + RainbowDump.formatDecHexString(rwDataSegmentHeader.getSizeAsDecompressed()) + "\n" +

View file

@ -103,7 +103,6 @@ public class Package2UnpackedTest {
ini1Provider.getIni1Header().printDebug();
for (Kip1 kip1 : ini1Provider.getKip1List())
kip1.printDebug();
boolean exported = provider.exportKernel("/home/loper/Projects/libKonogonka/FilesForTests/own/");
System.out.println("Exported = "+exported);
@ -115,4 +114,10 @@ public class Package2UnpackedTest {
System.out.println("Exported KIP1s "+ kip1.getName() +" = " + exported + String.format(" Size 0x%x", Files.size(Paths.get("/home/loper/Projects/libKonogonka/FilesForTests/own/KIP1s/"+kip1.getName()+".kip1"))));
}
}
@DisplayName("KIP1 read reference")
@Test
void checkReference() throws Exception{
Kip1 kip1 = new Kip1("/home/loper/Projects/libKonogonka/FilesForTests/");
kip1.printDebug();
}
}