diff --git a/README.md b/README.md index 75a78d4..59aa9e4 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,14 @@ JRE/JDK 8u60 or higher. ### Checklist +* [X] NSP (PFS0) +* [X] XCI (+HFS0) +* [X] TIK +* [X] XML + * [ ] LogPrinter to singleton implementation * [ ] NPDM support * [ ] CNMT support -* [ ] NSO support \ No newline at end of file +* [ ] NSO support +* [ ] RomFS deep-dive +* [ ] 'Save to folder' option \ No newline at end of file diff --git a/src/main/java/konogonka/Controllers/NPDM/FSAccessControlController.java b/src/main/java/konogonka/Controllers/NPDM/FSAccessControlController.java new file mode 100644 index 0000000..b94e238 --- /dev/null +++ b/src/main/java/konogonka/Controllers/NPDM/FSAccessControlController.java @@ -0,0 +1,188 @@ +package konogonka.Controllers.NPDM; + +import javafx.fxml.FXML; +import javafx.fxml.Initializable; +import javafx.scene.control.Label; +import javafx.scene.control.TextField; +import konogonka.Tools.NPDM.FSAccessControlProvider; + +import java.net.URL; +import java.util.ResourceBundle; + +import static konogonka.LoperConverter.byteArrToHexString; + +public class FSAccessControlController implements Initializable { + @FXML + private Label ACID_FSAcccessControlVersionLbl, + ACID_FSAcccessControlPaddingLbl, + ACID_FSAcccessControlBitbaskLbl; + @FXML + private TextField ACID_FSAcccessControlReservedTf; + + @FXML + private Label mask0, + mask1, + mask2, + mask3, + mask4, + mask5, + mask6, + mask7, + mask8, + mask9, + mask10, + mask11, + mask12, + mask13, + mask14, + mask15, + mask16, + mask17, + mask18, + mask19, + mask20, + mask21, + mask22, + mask23, + mask24, + mask25, + mask26, + mask27, + mask28, + mask29, + mask30, + mask31, + mask32, + mask33, + mask34, + mask35, + mask36, + mask37, + mask38, + mask39, + mask40, + mask41, + mask42, + mask43, + mask44, + mask45, + mask46, + mask47, + mask48, + mask49, + mask50, + mask51, + mask52, + mask53, + mask54, + mask55, + mask56, + mask57, + mask58, + mask59, + mask60, + mask61, + mask62, + mask63; + + private Label[] masksArr; + @Override + public void initialize(URL url, ResourceBundle resourceBundle) { + masksArr = new Label[64]; + masksArr[0] = mask0; + masksArr[1] = mask1; + masksArr[2] = mask2; + masksArr[3] = mask3; + masksArr[4] = mask4; + masksArr[5] = mask5; + masksArr[6] = mask6; + masksArr[7] = mask7; + masksArr[8] = mask8; + masksArr[9] = mask9; + masksArr[10] = mask10; + masksArr[11] = mask11; + masksArr[12] = mask12; + masksArr[13] = mask13; + masksArr[14] = mask14; + masksArr[15] = mask15; + masksArr[16] = mask16; + masksArr[17] = mask17; + masksArr[18] = mask18; + masksArr[19] = mask19; + masksArr[20] = mask20; + masksArr[21] = mask21; + masksArr[22] = mask22; + masksArr[23] = mask23; + masksArr[24] = mask24; + masksArr[25] = mask25; + masksArr[26] = mask26; + masksArr[27] = mask27; + masksArr[28] = mask28; + masksArr[29] = mask29; + masksArr[30] = mask30; + masksArr[31] = mask31; + masksArr[32] = mask32; + masksArr[33] = mask33; + masksArr[34] = mask34; + masksArr[35] = mask35; + masksArr[36] = mask36; + masksArr[37] = mask37; + masksArr[38] = mask38; + masksArr[39] = mask39; + masksArr[40] = mask40; + masksArr[41] = mask41; + masksArr[42] = mask42; + masksArr[43] = mask43; + masksArr[44] = mask44; + masksArr[45] = mask45; + masksArr[46] = mask46; + masksArr[47] = mask47; + masksArr[48] = mask48; + masksArr[49] = mask49; + masksArr[50] = mask50; + masksArr[51] = mask51; + masksArr[52] = mask52; + masksArr[53] = mask53; + masksArr[54] = mask54; + masksArr[55] = mask55; + masksArr[56] = mask56; + masksArr[57] = mask57; + masksArr[58] = mask58; + masksArr[59] = mask59; + masksArr[60] = mask60; + masksArr[61] = mask61; + masksArr[62] = mask62; + masksArr[63] = mask63; + } + + public void resetTab() { + ACID_FSAcccessControlVersionLbl.setText("-"); + ACID_FSAcccessControlPaddingLbl.setText("-"); + ACID_FSAcccessControlBitbaskLbl.setText("-"); + ACID_FSAcccessControlReservedTf.setText("-"); + + for (int i = 0; i < 64; i++) + masksArr[i].setText("-"); + } + + public void populateFields(FSAccessControlProvider provider){ + ACID_FSAcccessControlVersionLbl.setText(String.format("0x%02x", provider.getVersion())); + ACID_FSAcccessControlPaddingLbl.setText(byteArrToHexString(provider.getPadding())); + ACID_FSAcccessControlBitbaskLbl.setText(byteArrToHexString(provider.getPermissionsBitmask())); + ACID_FSAcccessControlReservedTf.setText(byteArrToHexString(provider.getReserved())); + + byte[] permissionsBitmask = provider.getPermissionsBitmask(); + String mask = + String.format("%8s", Integer.toBinaryString(permissionsBitmask[7] & 0xFF)).replace(' ', '0')+ + String.format("%8s", Integer.toBinaryString(permissionsBitmask[6] & 0xFF)).replace(' ', '0')+ + String.format("%8s", Integer.toBinaryString(permissionsBitmask[5] & 0xFF)).replace(' ', '0')+ + String.format("%8s", Integer.toBinaryString(permissionsBitmask[4] & 0xFF)).replace(' ', '0')+ + String.format("%8s", Integer.toBinaryString(permissionsBitmask[3] & 0xFF)).replace(' ', '0')+ + String.format("%8s", Integer.toBinaryString(permissionsBitmask[2] & 0xFF)).replace(' ', '0')+ + String.format("%8s", Integer.toBinaryString(permissionsBitmask[1] & 0xFF)).replace(' ', '0')+ + String.format("%8s", Integer.toBinaryString(permissionsBitmask[0] & 0xFF)).replace(' ', '0'); + + for (int i = 0; i < 64; i++) + masksArr[i].setText(mask.substring(i, i+1)); + } +} diff --git a/src/main/java/konogonka/Controllers/NPDM/NPDMController.java b/src/main/java/konogonka/Controllers/NPDM/NPDMController.java index 2224100..21a8ddb 100644 --- a/src/main/java/konogonka/Controllers/NPDM/NPDMController.java +++ b/src/main/java/konogonka/Controllers/NPDM/NPDMController.java @@ -55,7 +55,8 @@ public class NPDMController implements ITabController { aci0KernelAccessControlSizeLbl, aci0Reserved3Lbl; // ACID - @FXML TextField acidRsa2048signatureTf, + @FXML + TextField acidRsa2048signatureTf, acidRsa2048publicKeyTf; @FXML private Label acidMagicNumLbl, @@ -74,6 +75,8 @@ public class NPDMController implements ITabController { acidKernelAccessControlOffsetLbl, acidKernelAccessControlSizeLbl, acidReserved2Lbl; + @FXML + private FSAccessControlController FSAccessControlTableController; @Override public void initialize(URL url, ResourceBundle resourceBundle) { } @@ -158,6 +161,8 @@ public class NPDMController implements ITabController { acidKernelAccessControlOffsetLbl.setText("-"); acidKernelAccessControlSizeLbl.setText("-"); acidReserved2Lbl.setText("-"); + + FSAccessControlTableController.resetTab(); } private void setData(NPDMProvider npdmProvider, File file) { if (npdmProvider == null) @@ -217,5 +222,7 @@ public class NPDMController implements ITabController { acidKernelAccessControlOffsetLbl.setText(Integer.toString(acid.getKernelAccessControlOffset())); acidKernelAccessControlSizeLbl.setText(Integer.toString(acid.getKernelAccessControlSize())); acidReserved2Lbl.setText(byteArrToHexString(acid.getReserved2())); + + FSAccessControlTableController.populateFields(acid.getFSAccessControlProvider()); } } \ No newline at end of file diff --git a/src/main/java/konogonka/Tools/ASuperInFileProvider.java b/src/main/java/konogonka/Tools/ASuperInFileProvider.java index 7813a09..79fc333 100644 --- a/src/main/java/konogonka/Tools/ASuperInFileProvider.java +++ b/src/main/java/konogonka/Tools/ASuperInFileProvider.java @@ -4,8 +4,9 @@ import java.io.IOException; import java.io.PipedInputStream; /** - * Create prototype of the provider that created and works with pipes only + * Any class of this type must be able to accept data from stream (and file as any other). * */ + public abstract class ASuperInFileProvider { protected byte[] readFromStream(PipedInputStream pis, int size) throws IOException { byte[] buffer = new byte[size]; diff --git a/src/main/java/konogonka/Tools/ISuperProvider.java b/src/main/java/konogonka/Tools/ISuperProvider.java index 730bc30..aad2ef6 100644 --- a/src/main/java/konogonka/Tools/ISuperProvider.java +++ b/src/main/java/konogonka/Tools/ISuperProvider.java @@ -2,7 +2,9 @@ package konogonka.Tools; import java.io.File; import java.io.PipedInputStream; - +/** + * Any class of this type must provide streams + * */ public interface ISuperProvider { PipedInputStream getProviderSubFilePipedInpStream(String subFileName) throws Exception; PipedInputStream getProviderSubFilePipedInpStream(int subFileNumber) throws Exception; diff --git a/src/main/java/konogonka/Tools/NPDM/ACI0Provider.java b/src/main/java/konogonka/Tools/NPDM/ACI0Provider.java index 4c8bd0f..6acd59a 100644 --- a/src/main/java/konogonka/Tools/NPDM/ACI0Provider.java +++ b/src/main/java/konogonka/Tools/NPDM/ACI0Provider.java @@ -18,7 +18,7 @@ public class ACI0Provider { private int kernelAccessControlSize; private byte[] reserved3; - public ACI0Provider(byte[] aci0bytes) throws Exception{ + public ACI0Provider(byte[] aci0bytes) throws Exception { if (aci0bytes.length < 0x40) throw new Exception("ACI0 size is too short"); magicNum = new String(aci0bytes, 0, 0x4, StandardCharsets.UTF_8); diff --git a/src/main/java/konogonka/Tools/NPDM/ACIDProvider.java b/src/main/java/konogonka/Tools/NPDM/ACIDProvider.java index c1f68fe..bed9327 100644 --- a/src/main/java/konogonka/Tools/NPDM/ACIDProvider.java +++ b/src/main/java/konogonka/Tools/NPDM/ACIDProvider.java @@ -26,9 +26,12 @@ public class ACIDProvider { private int kernelAccessControlSize; private byte[] reserved2; + private FSAccessControlProvider fsAccessControlProvider; + + public ACIDProvider(byte[] acidBytes) throws Exception{ if (acidBytes.length < 0x240) - throw new Exception("ACI0 size is too short"); + throw new Exception("ACIDProvider -> ACI0 size is too short"); rsa2048signature = Arrays.copyOfRange(acidBytes, 0, 0x100); rsa2048publicKey = Arrays.copyOfRange(acidBytes, 0x100, 0x200); magicNum = new String(acidBytes, 0x200, 0x4, StandardCharsets.UTF_8); @@ -47,6 +50,9 @@ public class ACIDProvider { kernelAccessControlOffset = getLEint(acidBytes, 0x230); kernelAccessControlSize = getLEint(acidBytes, 0x234); reserved2 = Arrays.copyOfRange(acidBytes, 0x238, 0x240); + if (fsAccessControlOffset > serviceAccessControlOffset || serviceAccessControlOffset > kernelAccessControlOffset ) + throw new Exception("ACIDProvider -> blocks inside the ACID are not sorted in ascending order. Only ascending order supported."); + fsAccessControlProvider = new FSAccessControlProvider(Arrays.copyOfRange(acidBytes, fsAccessControlOffset, fsAccessControlOffset+fsAccessControlSize)); } public byte[] getRsa2048signature() { return rsa2048signature; } @@ -67,4 +73,7 @@ public class ACIDProvider { public int getKernelAccessControlOffset() { return kernelAccessControlOffset; } public int getKernelAccessControlSize() { return kernelAccessControlSize; } public byte[] getReserved2() { return reserved2; } + + public FSAccessControlProvider getFSAccessControlProvider() { return fsAccessControlProvider; } + } \ No newline at end of file diff --git a/src/main/java/konogonka/Tools/NPDM/FSAccessControlProvider.java b/src/main/java/konogonka/Tools/NPDM/FSAccessControlProvider.java new file mode 100644 index 0000000..543e1ed --- /dev/null +++ b/src/main/java/konogonka/Tools/NPDM/FSAccessControlProvider.java @@ -0,0 +1,26 @@ +package konogonka.Tools.NPDM; + +import java.util.Arrays; + +/** + * For ACID Provider + * */ +public class FSAccessControlProvider { + + private byte version; + private byte[] padding; + private byte[] permissionsBitmask; // ??? Where each byte representing 255-long bit-bask of the thing it representing. Like 0x01 bit-mask for ApplicationInfo + private byte[] reserved; + + public FSAccessControlProvider(byte[] bytes) { + version = bytes[0]; + padding = Arrays.copyOfRange(bytes, 1, 0x4); + permissionsBitmask = Arrays.copyOfRange(bytes, 0x4, 0xC); + reserved = Arrays.copyOfRange(bytes, 0xC, 0x2C); + } + + public byte getVersion() { return version; } + public byte[] getPadding() { return padding; } + public byte[] getPermissionsBitmask() { return permissionsBitmask; } + public byte[] getReserved() { return reserved; } +} diff --git a/src/main/resources/FXML/NPDM/FSAccessControlTable.fxml b/src/main/resources/FXML/NPDM/FSAccessControlTable.fxml new file mode 100644 index 0000000..9113685 --- /dev/null +++ b/src/main/resources/FXML/NPDM/FSAccessControlTable.fxml @@ -0,0 +1,1317 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/FXML/NPDM/NPDMTab.fxml b/src/main/resources/FXML/NPDM/NPDMTab.fxml index 7c79b0d..7196e98 100644 --- a/src/main/resources/FXML/NPDM/NPDMTab.fxml +++ b/src/main/resources/FXML/NPDM/NPDMTab.fxml @@ -439,447 +439,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -1175,6 +734,449 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +