Ticket reader implemented
This commit is contained in:
parent
e8755fbe2f
commit
5c7a9f1dc8
18 changed files with 1134 additions and 45 deletions
|
@ -7,6 +7,7 @@ import javafx.scene.image.Image;
|
|||
import javafx.stage.Stage;
|
||||
import konogonka.Controllers.IRowModel;
|
||||
import konogonka.Controllers.NCA.NCAController;
|
||||
import konogonka.Controllers.TIK.TIKController;
|
||||
import konogonka.Tools.ISuperProvider;
|
||||
|
||||
import java.io.IOException;
|
||||
|
@ -25,6 +26,9 @@ public class ChildWindow {
|
|||
if (model.getFileName().endsWith(".nca")){
|
||||
loaderSettings = new FXMLLoader(getClass().getResource("/FXML/NCA/NCATab.fxml"));
|
||||
}
|
||||
else if(model.getFileName().endsWith(".tik")){
|
||||
loaderSettings = new FXMLLoader(getClass().getResource("/FXML/TIK/TIKTab.fxml"));
|
||||
}
|
||||
else if(model.getFileName().endsWith(".cert")){
|
||||
// TODO: IMPLEMENT
|
||||
return;
|
||||
|
@ -51,6 +55,10 @@ public class ChildWindow {
|
|||
NCAController ncaController = loaderSettings.<NCAController>getController();
|
||||
ncaController.analyze(provider.getFile(), provider.getRawFileDataStart()+model.getFileOffset());
|
||||
}
|
||||
else if(model.getFileName().endsWith(".tik")){
|
||||
TIKController tikController = loaderSettings.<TIKController>getController();
|
||||
tikController.analyze(provider.getFile(), provider.getRawFileDataStart()+model.getFileOffset());
|
||||
}
|
||||
|
||||
|
||||
stageSettings.setTitle(model.getFileName());
|
||||
|
|
|
@ -7,6 +7,6 @@ import java.io.File;
|
|||
|
||||
public interface ITabController extends Initializable {
|
||||
void analyze(File file);
|
||||
void analyze(ISuperProvider provider, int subFileNumber);
|
||||
void analyze(File file, long offset);
|
||||
void resetTab();
|
||||
}
|
||||
|
|
|
@ -9,10 +9,12 @@ import konogonka.AppPreferences;
|
|||
import konogonka.Child.ChildWindow;
|
||||
import konogonka.Controllers.NCA.NCAController;
|
||||
import konogonka.Controllers.NSP.NSPController;
|
||||
import konogonka.Controllers.TIK.TIKController;
|
||||
import konogonka.Controllers.XCI.XCIController;
|
||||
import konogonka.MediatorControl;
|
||||
import konogonka.Settings.SettingsWindow;
|
||||
import konogonka.Tools.ISuperProvider;
|
||||
import konogonka.Tools.TIK.TIKProvider;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.URL;
|
||||
|
@ -43,6 +45,8 @@ public class MainController implements Initializable {
|
|||
private XCIController XCITabController;
|
||||
@FXML
|
||||
private NCAController NCATabController;
|
||||
@FXML
|
||||
private TIKController TIKTabController;
|
||||
|
||||
private File selectedFile;
|
||||
|
||||
|
@ -76,7 +80,7 @@ public class MainController implements Initializable {
|
|||
else
|
||||
fileChooser.setInitialDirectory(new File(System.getProperty("user.home")));
|
||||
|
||||
fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("NS ROM", "*.nsp", "*.xci", "*.nca"));
|
||||
fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("NS files", "*.nsp", "*.xci", "*.nca", "*.tik"));
|
||||
|
||||
this.selectedFile = fileChooser.showOpenDialog(analyzeBtn.getScene().getWindow());
|
||||
|
||||
|
@ -84,6 +88,7 @@ public class MainController implements Initializable {
|
|||
NSPTabController.resetTab();
|
||||
XCITabController.resetTab();
|
||||
NCATabController.resetTab();
|
||||
TIKTabController.resetTab();
|
||||
|
||||
if (this.selectedFile != null && this.selectedFile.exists()) {
|
||||
filenameSelected.setText(this.selectedFile.getAbsolutePath());
|
||||
|
@ -95,6 +100,8 @@ public class MainController implements Initializable {
|
|||
tabPane.getSelectionModel().select(1);
|
||||
else if (this.selectedFile.getName().toLowerCase().endsWith(".nca"))
|
||||
tabPane.getSelectionModel().select(2);
|
||||
else if (this.selectedFile.getName().toLowerCase().endsWith(".tik"))
|
||||
tabPane.getSelectionModel().select(3);
|
||||
}
|
||||
|
||||
logArea.clear();
|
||||
|
@ -109,6 +116,8 @@ public class MainController implements Initializable {
|
|||
XCITabController.analyze(selectedFile);
|
||||
else if (selectedFile.getName().toLowerCase().endsWith("nca"))
|
||||
NCATabController.analyze(selectedFile);
|
||||
else if (selectedFile.getName().toLowerCase().endsWith("tik"))
|
||||
TIKTabController.analyze(selectedFile);
|
||||
}
|
||||
@FXML
|
||||
private void showHideLogs(){
|
||||
|
|
|
@ -5,7 +5,6 @@ import javafx.scene.control.Label;
|
|||
import javafx.scene.control.TextField;
|
||||
import konogonka.AppPreferences;
|
||||
import konogonka.Controllers.ITabController;
|
||||
import konogonka.Tools.ISuperProvider;
|
||||
import konogonka.Tools.NCA.NCAContentPFS0;
|
||||
import konogonka.Tools.NCA.NCAProvider;
|
||||
import konogonka.Workers.AnalyzerNCA;
|
||||
|
@ -72,11 +71,8 @@ public class NCAController implements ITabController {
|
|||
public void initialize(URL url, ResourceBundle resourceBundle) {
|
||||
|
||||
}
|
||||
@Override
|
||||
public void analyze(ISuperProvider provider, int subFileNumber){
|
||||
// TODO
|
||||
}
|
||||
|
||||
@Override
|
||||
public void analyze(File file, long offset) {
|
||||
this.selectedFile = file;
|
||||
HashMap<String, String> keysMap = new HashMap<>();
|
||||
|
@ -201,13 +197,13 @@ public class NCAController implements ITabController {
|
|||
// TODO: FIX: This code executes getNCAContentPFS0() method twice
|
||||
NCAContentPFS0 ncaContentPFS0;
|
||||
ncaContentPFS0 = ncaProvider.getNCAContentPFS0(0);
|
||||
NCASectionContentFirstController.populateFields(ncaContentPFS0.getPfs0(), selectedFile, ncaContentPFS0.getSHA256hashes());
|
||||
NCASectionContentFirstController.populateFields(ncaContentPFS0.getPfs0(), ncaContentPFS0.getSHA256hashes());
|
||||
ncaContentPFS0 = ncaProvider.getNCAContentPFS0(1);
|
||||
NCASectionContentSecondController.populateFields(ncaContentPFS0.getPfs0(), selectedFile, ncaContentPFS0.getSHA256hashes());
|
||||
NCASectionContentSecondController.populateFields(ncaContentPFS0.getPfs0(), ncaContentPFS0.getSHA256hashes());
|
||||
ncaContentPFS0 = ncaProvider.getNCAContentPFS0(2);
|
||||
NCASectionContentThirdController.populateFields(ncaContentPFS0.getPfs0(), selectedFile, ncaContentPFS0.getSHA256hashes());
|
||||
NCASectionContentThirdController.populateFields(ncaContentPFS0.getPfs0(), ncaContentPFS0.getSHA256hashes());
|
||||
ncaContentPFS0 = ncaProvider.getNCAContentPFS0(3);
|
||||
NCASectionContentFourthController.populateFields(ncaContentPFS0.getPfs0(), selectedFile, ncaContentPFS0.getSHA256hashes());
|
||||
NCASectionContentFourthController.populateFields(ncaContentPFS0.getPfs0(), ncaContentPFS0.getSHA256hashes());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,6 @@ import konogonka.Controllers.NSP.NSPController;
|
|||
import konogonka.LoperConverter;
|
||||
import konogonka.Tools.PFS0.IPFS0Provider;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.LinkedList;
|
||||
|
||||
public class NCASectionContentController{
|
||||
|
@ -23,9 +22,9 @@ public class NCASectionContentController{
|
|||
sha256pane.getChildren().clear();
|
||||
}
|
||||
|
||||
public void populateFields(IPFS0Provider pfs0, File file, LinkedList<byte[]> sha256hashList) {
|
||||
public void populateFields(IPFS0Provider pfs0, LinkedList<byte[]> sha256hashList) {
|
||||
resetTab();
|
||||
SectionPFS0Controller.setData(pfs0, file);
|
||||
SectionPFS0Controller.setData(pfs0, null);
|
||||
if (sha256hashList != null){
|
||||
for (int i = 0; i < sha256hashList.size(); i++){
|
||||
Label numberLblTmp = new Label(String.format("%10d", i));
|
||||
|
|
|
@ -51,7 +51,7 @@ public class NSPController implements ITabController {
|
|||
ISuperProvider provider = tableFilesListController.getProvider();
|
||||
if (models != null && !models.isEmpty() && (provider != null)){
|
||||
|
||||
File dir = new File(System.getProperty("user.dir")+File.separator+selectedFile.getName()+" extracted");
|
||||
File dir = new File(System.getProperty("user.dir")+File.separator+selectedFile.getName()+" extracted"); // todo: move option to settings
|
||||
try {
|
||||
dir.mkdir();
|
||||
}
|
||||
|
@ -92,17 +92,16 @@ public class NSPController implements ITabController {
|
|||
* Start analyze NSP
|
||||
* */
|
||||
@Override
|
||||
public void analyze(ISuperProvider provider, int subFileNumber){
|
||||
public void analyze(File selectedFile, long offset){
|
||||
// TODO: IMPLEMENT
|
||||
return;
|
||||
}
|
||||
@Override
|
||||
public void analyze(File selectedFile){
|
||||
this.selectedFile = selectedFile;
|
||||
AnalyzerNSP analyzerNSP = new AnalyzerNSP(selectedFile);
|
||||
analyzerNSP.setOnSucceeded(e->{
|
||||
PFS0Provider pfs0 = analyzerNSP.getValue();
|
||||
this.setData(pfs0, null);
|
||||
this.setData(pfs0, selectedFile);
|
||||
});
|
||||
Thread workThread = new Thread(analyzerNSP);
|
||||
workThread.setDaemon(true);
|
||||
|
@ -112,14 +111,15 @@ public class NSPController implements ITabController {
|
|||
* Just populate fields by already analyzed PFS0
|
||||
* */
|
||||
public void setData(IPFS0Provider pfs0, File fileWithNca){
|
||||
if (pfs0 != null){
|
||||
if (fileWithNca != null)
|
||||
if (pfs0 == null)
|
||||
return;
|
||||
this.selectedFile = fileWithNca;
|
||||
|
||||
filesCountLbl.setText(Integer.toString(pfs0.getFilesCount()));
|
||||
RawDataStartLbl.setText(Long.toString(pfs0.getRawFileDataStart()));
|
||||
rawFileDataStart = pfs0.getRawFileDataStart();
|
||||
tableFilesListController.setNSPToTable(pfs0);
|
||||
if (fileWithNca != null)
|
||||
if (fileWithNca == null)
|
||||
NSPSizeLbl.setText("skipping calculation for in-file PFS0");
|
||||
else
|
||||
NSPSizeLbl.setText(Long.toString(selectedFile.length()));
|
||||
|
@ -134,5 +134,4 @@ public class NSPController implements ITabController {
|
|||
stringsTableOffsetLbl.setText(String.format("0x%02x", 0x18* pfs0.getFilesCount()+0x10));
|
||||
rawFileDataOffsetLbl.setText(String.format("0x%02x", 0x18* pfs0.getFilesCount()+0x10+ pfs0.getStringTableSize())); // same to RawFileDataStart for NSP ONLY
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
154
src/main/java/konogonka/Controllers/TIK/TIKController.java
Normal file
154
src/main/java/konogonka/Controllers/TIK/TIKController.java
Normal file
|
@ -0,0 +1,154 @@
|
|||
package konogonka.Controllers.TIK;
|
||||
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.TextField;
|
||||
import konogonka.Controllers.ITabController;
|
||||
import konogonka.Tools.TIK.TIKProvider;
|
||||
import konogonka.Workers.AnalyzerTIK;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.URL;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
import static konogonka.LoperConverter.byteArrToHexString;
|
||||
|
||||
public class TIKController implements ITabController {
|
||||
|
||||
@FXML
|
||||
private Label sigTypeLbl,
|
||||
sigTypeStrLbl,
|
||||
tikSizeLbl,
|
||||
sSizeLbl, // cosmetic
|
||||
pOffsetLbl, // cosmetic
|
||||
pSizeLbl, // cosmetic
|
||||
|
||||
unknown1Lbl,
|
||||
titleKeyTypeLbl,
|
||||
unknown2Lbl,
|
||||
masterKeyRevisionLbl,
|
||||
unknown3Lbl,
|
||||
ticketIdLbl,
|
||||
deviceIdLbl,
|
||||
accountIdLbl,
|
||||
unknown4Lbl;
|
||||
@FXML
|
||||
private TextField signatureTF,
|
||||
issuerTf,
|
||||
titleKeyBlockTf,
|
||||
rightsIdTf;
|
||||
|
||||
@Override
|
||||
public void initialize(URL url, ResourceBundle resourceBundle) { }
|
||||
|
||||
@Override
|
||||
public void analyze(File file) { analyze(file, 0); }
|
||||
|
||||
@Override
|
||||
public void analyze(File file, long offset) {
|
||||
AnalyzerTIK analyzerTIK = new AnalyzerTIK(file, offset);
|
||||
analyzerTIK.setOnSucceeded(e->{
|
||||
TIKProvider tik = analyzerTIK.getValue();
|
||||
if (offset == 0)
|
||||
setData(tik, file);
|
||||
else
|
||||
setData(tik, null);
|
||||
});
|
||||
Thread workThread = new Thread(analyzerTIK);
|
||||
workThread.setDaemon(true);
|
||||
workThread.start();
|
||||
}
|
||||
|
||||
private void setData(TIKProvider tikProvider, File file){
|
||||
if (tikProvider == null)
|
||||
return;
|
||||
|
||||
if (file != null)
|
||||
tikSizeLbl.setText(Long.toString(file.length()));
|
||||
else
|
||||
tikSizeLbl.setText("skipping calculation for in-file ticket");
|
||||
|
||||
sigTypeLbl.setText(byteArrToHexString(tikProvider.getSigType()));
|
||||
switch (sigTypeLbl.getText()){
|
||||
case "00000100":
|
||||
sigTypeStrLbl.setText("RSA_4096 SHA1");
|
||||
sSizeLbl.setText("0x200");
|
||||
pOffsetLbl.setText("0x240");
|
||||
pSizeLbl.setText("0x3c");
|
||||
break;
|
||||
case "01000100":
|
||||
sigTypeStrLbl.setText("RSA_2048 SHA1");
|
||||
sSizeLbl.setText("0x100");
|
||||
pOffsetLbl.setText("0x104");
|
||||
pSizeLbl.setText("0x3c");
|
||||
break;
|
||||
case "02000100":
|
||||
sigTypeStrLbl.setText("ECDSA SHA1");
|
||||
sSizeLbl.setText("0x3c");
|
||||
pOffsetLbl.setText("0x40");
|
||||
pSizeLbl.setText("0x40");
|
||||
break;
|
||||
case "03000100":
|
||||
sigTypeStrLbl.setText("RSA_4096 SHA256");
|
||||
sSizeLbl.setText("0x200");
|
||||
pOffsetLbl.setText("0x240");
|
||||
pSizeLbl.setText("0x3c");
|
||||
break;
|
||||
case "04000100":
|
||||
sigTypeStrLbl.setText("RSA_2048 SHA256");
|
||||
sSizeLbl.setText("0x100");
|
||||
pOffsetLbl.setText("0x104");
|
||||
pSizeLbl.setText("0x3c");
|
||||
break;
|
||||
case "05000100":
|
||||
sigTypeStrLbl.setText("ECDSA SHA256");
|
||||
sSizeLbl.setText("0x3c");
|
||||
pOffsetLbl.setText("0x40");
|
||||
pSizeLbl.setText("0x40");
|
||||
break;
|
||||
default:
|
||||
sigTypeStrLbl.setText("???");
|
||||
sSizeLbl.setText("???");
|
||||
pOffsetLbl.setText("???");
|
||||
pSizeLbl.setText("???");
|
||||
break;
|
||||
}
|
||||
signatureTF.setText(byteArrToHexString(tikProvider.getSignature()));
|
||||
|
||||
issuerTf.setText(byteArrToHexString(tikProvider.getIssuer()));
|
||||
titleKeyBlockTf.setText(byteArrToHexString(tikProvider.getTitleKeyBlock()));
|
||||
unknown1Lbl.setText(String.format("0x%02x", tikProvider.getUnknown1()));
|
||||
titleKeyTypeLbl.setText(String.format("0x%02x", tikProvider.getTitleKeyType()));
|
||||
unknown2Lbl.setText(byteArrToHexString(tikProvider.getUnknown2()));
|
||||
masterKeyRevisionLbl.setText(String.format("0x%02x", tikProvider.getMasterKeyRevision()));
|
||||
unknown3Lbl.setText(byteArrToHexString(tikProvider.getUnknown3()));
|
||||
ticketIdLbl.setText(byteArrToHexString(tikProvider.getTicketId()));
|
||||
deviceIdLbl.setText(byteArrToHexString(tikProvider.getDeviceId()));
|
||||
rightsIdTf.setText(byteArrToHexString(tikProvider.getRightsId()));
|
||||
accountIdLbl.setText(byteArrToHexString(tikProvider.getAccountId()));
|
||||
unknown4Lbl.setText(byteArrToHexString(tikProvider.getUnknown4()));
|
||||
}
|
||||
@Override
|
||||
public void resetTab() {
|
||||
sigTypeLbl.setText("-");
|
||||
sigTypeStrLbl.setText("-");
|
||||
tikSizeLbl.setText("-");
|
||||
sSizeLbl.setText("...");
|
||||
pOffsetLbl.setText("...");
|
||||
pSizeLbl.setText("...");
|
||||
signatureTF.setText("-");
|
||||
|
||||
issuerTf.setText("-");
|
||||
titleKeyBlockTf.setText("-");
|
||||
unknown1Lbl.setText("-");
|
||||
titleKeyTypeLbl.setText("-");
|
||||
unknown2Lbl.setText("-");
|
||||
masterKeyRevisionLbl.setText("-");
|
||||
unknown3Lbl.setText("-");
|
||||
ticketIdLbl.setText("-");
|
||||
deviceIdLbl.setText("-");
|
||||
rightsIdTf.setText("-");
|
||||
accountIdLbl.setText("-");
|
||||
unknown4Lbl.setText("-");
|
||||
}
|
||||
}
|
|
@ -90,7 +90,7 @@ public class XCIController implements ITabController {
|
|||
* Start analyze XCI
|
||||
* */
|
||||
@Override
|
||||
public void analyze(ISuperProvider provider, int subFileNumber){
|
||||
public void analyze(File selectedFile, long offset){
|
||||
// TODO: IMPLEMENT
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -244,7 +244,12 @@ public class NCAProvider {
|
|||
public NCASectionBlock getSectionBlock1() { return sectionBlock1; }
|
||||
public NCASectionBlock getSectionBlock2() { return sectionBlock2; }
|
||||
public NCASectionBlock getSectionBlock3() { return sectionBlock3; }
|
||||
|
||||
public boolean isKeyAvailable(){ // TODO: USE
|
||||
if (Arrays.equals(rightsId, new byte[0x10]))
|
||||
return true;
|
||||
else
|
||||
return keys.containsKey(byteArrToHexString(rightsId));
|
||||
}
|
||||
/**
|
||||
* Get content for the selected section
|
||||
* @param sectionNumber should be 1-4
|
||||
|
|
161
src/main/java/konogonka/Tools/TIK/TIKProvider.java
Normal file
161
src/main/java/konogonka/Tools/TIK/TIKProvider.java
Normal file
|
@ -0,0 +1,161 @@
|
|||
package konogonka.Tools.TIK;
|
||||
|
||||
import konogonka.RainbowHexDump;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.Arrays;
|
||||
|
||||
import static konogonka.LoperConverter.*;
|
||||
/*
|
||||
|
||||
DON'T TRUST WIKI. Ticket size always (?) equal 0x02c0 (704 bytes)
|
||||
|
||||
File structure byte-by-byte parsing
|
||||
|
||||
Starting:
|
||||
0x4 - Signature type
|
||||
Signature type == 00 00 01 00 ?
|
||||
Next:
|
||||
0x200 - Signature size
|
||||
Signature type == 01 00 01 00 ?
|
||||
0x100 - Signature size
|
||||
Signature type == 02 00 01 00 ?
|
||||
0x3c - Signature size
|
||||
Signature type == 03 00 01 00 ?
|
||||
0x200 - Signature size
|
||||
Signature type == 04 00 01 00 ?
|
||||
0x100 - Signature size
|
||||
Signature type == 05 00 01 00 ?
|
||||
0x3c - Signature size
|
||||
Next:
|
||||
Signature type == 01 00 01 00 ?
|
||||
0x3c - padding
|
||||
Signature type == 01 00 01 00 ?
|
||||
0x3c - padding
|
||||
Signature type == 02 00 01 00 ?
|
||||
0x40 - padding
|
||||
Signature type == 03 00 01 00 ?
|
||||
0c3c - padding
|
||||
Signature type == 04 00 01 00 ?
|
||||
0c3c - padding
|
||||
Signature type == 05 00 01 00 ?
|
||||
0x40 - padding
|
||||
Next:
|
||||
0x02c0 - Signature data ????? WTF? MUST BE AND IMPLEMENTED AS 0x180
|
||||
*/
|
||||
/**
|
||||
* TIKProvider is not a container, thus not a content-provider but provider of values-only
|
||||
* */
|
||||
public class TIKProvider {
|
||||
// Signature-related
|
||||
private byte[] sigType;
|
||||
private byte[] signature;
|
||||
// Ticket
|
||||
private byte[] Issuer;
|
||||
private byte[] TitleKeyBlock; // Actually 32 bytes. Check against WIKI
|
||||
private byte Unknown1;
|
||||
private byte TitleKeyType;
|
||||
private byte[] Unknown2;
|
||||
private byte MasterKeyRevision;
|
||||
private byte[] Unknown3;
|
||||
private byte[] TicketId;
|
||||
private byte[] DeviceId;
|
||||
private byte[] RightsId;
|
||||
private byte[] AccountId;
|
||||
private byte[] Unknown4;
|
||||
|
||||
public TIKProvider(File file) throws Exception{ this(file, 0); }
|
||||
|
||||
public TIKProvider(File file, long offset) throws Exception {
|
||||
|
||||
if (file.length() - offset < 0x02c0)
|
||||
throw new Exception("TIKProvider: File is too small.");
|
||||
|
||||
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
|
||||
if (bis.skip(offset) != offset) {
|
||||
bis.close();
|
||||
throw new Exception("TIKProvider: Unable to skip requested range - " + offset);
|
||||
}
|
||||
|
||||
sigType = new byte[0x4];
|
||||
if (bis.read(sigType) != 4) {
|
||||
bis.close();
|
||||
throw new Exception("TIKProvider: Unable to read requested range - " + offset);
|
||||
}
|
||||
|
||||
byte[] readChunk;
|
||||
|
||||
switch (getLEint(sigType, 0)){
|
||||
case 65536: // RSA_4096 SHA1
|
||||
case 65539: // RSA_4096 SHA256
|
||||
readChunk = new byte[0x23c];
|
||||
if (bis.read(readChunk) != 0x23c) {
|
||||
bis.close();
|
||||
throw new Exception("TIKProvider: Unable to read requested range - 0x23c");
|
||||
}
|
||||
signature = Arrays.copyOfRange(readChunk, 0, 0x200);
|
||||
break;
|
||||
case 65537: // RSA_2048 SHA1
|
||||
case 65540: // RSA_2048 SHA256
|
||||
readChunk = new byte[0x13c];
|
||||
if (bis.read(readChunk) != 0x13c) {
|
||||
bis.close();
|
||||
throw new Exception("TIKProvider: Unable to read requested range - 0x13c");
|
||||
}
|
||||
signature = Arrays.copyOfRange(readChunk, 0, 0x100);
|
||||
break;
|
||||
case 65538: // ECDSA SHA1
|
||||
case 65541: // ECDSA SHA256
|
||||
readChunk = new byte[0x7c];
|
||||
if (bis.read(readChunk) != 0x7c) {
|
||||
bis.close();
|
||||
throw new Exception("TIKProvider: Unable to read requested range - 0x7c");
|
||||
}
|
||||
signature = Arrays.copyOfRange(readChunk, 0, 0x3c);
|
||||
break;
|
||||
default:
|
||||
bis.close();
|
||||
throw new Exception("TIKProvider: Unknown ticket (Signature) type. Aborting.");
|
||||
}
|
||||
// Let's read ticket body itself
|
||||
readChunk = new byte[0x180];
|
||||
|
||||
if (bis.read(readChunk) != 0x180) {
|
||||
bis.close();
|
||||
throw new Exception("TIKProvider: Unable to read requested range - Ticket data");
|
||||
}
|
||||
bis.close();
|
||||
|
||||
Issuer = Arrays.copyOfRange(readChunk, 0, 0x40);
|
||||
TitleKeyBlock = Arrays.copyOfRange(readChunk, 0x40, 0x140);
|
||||
Unknown1 = readChunk[0x140];
|
||||
TitleKeyType = readChunk[0x141];
|
||||
Unknown2 = Arrays.copyOfRange(readChunk, 0x142, 0x145);
|
||||
MasterKeyRevision = readChunk[0x145];
|
||||
Unknown3 = Arrays.copyOfRange(readChunk, 0x146, 0x150);
|
||||
TicketId = Arrays.copyOfRange(readChunk, 0x150, 0x158);
|
||||
DeviceId = Arrays.copyOfRange(readChunk, 0x158, 0x160);
|
||||
RightsId = Arrays.copyOfRange(readChunk, 0x160, 0x170);
|
||||
AccountId = Arrays.copyOfRange(readChunk,0x170, 0x174);
|
||||
Unknown4 = Arrays.copyOfRange(readChunk, 0x174, 0x180);
|
||||
}
|
||||
|
||||
public byte[] getSigType() { return sigType; }
|
||||
public byte[] getSignature() { return signature; }
|
||||
|
||||
public byte[] getIssuer() { return Issuer; }
|
||||
public byte[] getTitleKeyBlock() { return TitleKeyBlock; }
|
||||
public byte getUnknown1() { return Unknown1; }
|
||||
public byte getTitleKeyType() { return TitleKeyType; }
|
||||
public byte[] getUnknown2() { return Unknown2; }
|
||||
public byte getMasterKeyRevision() { return MasterKeyRevision; }
|
||||
public byte[] getUnknown3() { return Unknown3; }
|
||||
public byte[] getTicketId() { return TicketId; }
|
||||
public byte[] getDeviceId() { return DeviceId; }
|
||||
public byte[] getRightsId() { return RightsId; }
|
||||
public byte[] getAccountId() { return AccountId; }
|
||||
public byte[] getUnknown4() { return Unknown4; }
|
||||
}
|
45
src/main/java/konogonka/Workers/AnalyzerTIK.java
Normal file
45
src/main/java/konogonka/Workers/AnalyzerTIK.java
Normal file
|
@ -0,0 +1,45 @@
|
|||
package konogonka.Workers;
|
||||
|
||||
import javafx.concurrent.Task;
|
||||
import konogonka.ModelControllers.EMsgType;
|
||||
import konogonka.ModelControllers.LogPrinter;
|
||||
import konogonka.Tools.TIK.TIKProvider;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class AnalyzerTIK extends Task<TIKProvider> {
|
||||
|
||||
private File file;
|
||||
private long offset;
|
||||
private LogPrinter logPrinter;
|
||||
|
||||
public AnalyzerTIK(File file){
|
||||
this(file, 0);
|
||||
}
|
||||
|
||||
public AnalyzerTIK(File file, long offset){
|
||||
this.file = file;
|
||||
this.offset = offset;
|
||||
this.logPrinter = new LogPrinter();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected TIKProvider call() {
|
||||
logPrinter.print("\tStart chain: TIK", EMsgType.INFO);
|
||||
try{
|
||||
return new TIKProvider(file, offset);
|
||||
}
|
||||
catch (Exception e){
|
||||
logPrinter.print("\tException: "+e.getMessage(), EMsgType.FAIL);
|
||||
return null;
|
||||
}
|
||||
finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
private void close(){
|
||||
logPrinter.print("\tEnd chain: TIK", EMsgType.INFO);
|
||||
logPrinter.close();
|
||||
}
|
||||
}
|
|
@ -27,7 +27,7 @@ public class NspXciExtractor extends Task<Void> {
|
|||
@Override
|
||||
protected Void call() {
|
||||
for (IRowModel model : models) {
|
||||
logPrinter.print("\tStart extracting: "+model.getFileName(), EMsgType.INFO);
|
||||
logPrinter.print("\tStart extracting: \n"+filesDestPath+model.getFileName(), EMsgType.INFO);
|
||||
File contentFile = new File(filesDestPath + model.getFileName());
|
||||
try {
|
||||
BufferedOutputStream extractedFileBOS = new BufferedOutputStream(new FileOutputStream(contentFile));
|
||||
|
|
705
src/main/resources/FXML/TIK/TIKTab.fxml
Normal file
705
src/main/resources/FXML/TIK/TIKTab.fxml
Normal file
|
@ -0,0 +1,705 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.geometry.Insets?>
|
||||
<?import javafx.scene.control.Label?>
|
||||
<?import javafx.scene.control.ScrollPane?>
|
||||
<?import javafx.scene.control.TextField?>
|
||||
<?import javafx.scene.layout.AnchorPane?>
|
||||
<?import javafx.scene.layout.ColumnConstraints?>
|
||||
<?import javafx.scene.layout.GridPane?>
|
||||
<?import javafx.scene.layout.HBox?>
|
||||
<?import javafx.scene.layout.RowConstraints?>
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<?import javafx.scene.text.Font?>
|
||||
|
||||
<ScrollPane fitToWidth="true" xmlns="http://javafx.com/javafx/8.0.141" xmlns:fx="http://javafx.com/fxml/1" fx:controller="konogonka.Controllers.TIK.TIKController">
|
||||
<VBox spacing="5.0">
|
||||
<Label text="Signature data">
|
||||
<font>
|
||||
<Font name="System Bold" size="13.0" />
|
||||
</font>
|
||||
</Label>
|
||||
<GridPane>
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="60.0" minWidth="55.0" />
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="60.0" minWidth="55.0" />
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="180.0" minWidth="170.0" />
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="100.0" prefWidth="100.0" />
|
||||
</columnConstraints>
|
||||
<rowConstraints>
|
||||
<RowConstraints maxHeight="30.0" minHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints maxHeight="30.0" minHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints maxHeight="30.0" minHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints maxHeight="30.0" minHeight="30.0" vgrow="SOMETIMES" />
|
||||
</rowConstraints>
|
||||
<children>
|
||||
<AnchorPane styleClass="customGrid" GridPane.rowIndex="2">
|
||||
<children>
|
||||
<Label text="0x4" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane styleClass="customGrid" GridPane.rowIndex="3">
|
||||
<children>
|
||||
<Label fx:id="pOffsetLbl" text="..." AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane styleClass="customGrid" GridPane.rowIndex="1">
|
||||
<children>
|
||||
<Label text="0x0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane styleClass="customGrid" GridPane.columnIndex="1" GridPane.rowIndex="3">
|
||||
<children>
|
||||
<Label fx:id="pSizeLbl" text="..." AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane styleClass="customGrid" GridPane.columnIndex="1" GridPane.rowIndex="2">
|
||||
<children>
|
||||
<Label fx:id="sSizeLbl" text="..." AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane styleClass="customGrid" GridPane.columnIndex="1" GridPane.rowIndex="1">
|
||||
<children>
|
||||
<Label text="0x4" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane styleClass="customGrid" GridPane.columnIndex="2" GridPane.rowIndex="1">
|
||||
<children>
|
||||
<Label text="Signature type" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane styleClass="customGrid" GridPane.columnIndex="2" GridPane.rowIndex="2">
|
||||
<children>
|
||||
<Label text="Signature" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane styleClass="customGrid" GridPane.columnIndex="2" GridPane.rowIndex="3">
|
||||
<children>
|
||||
<Label text="Padding" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane styleClass="customGrid" GridPane.columnIndex="3" GridPane.rowIndex="3">
|
||||
<children>
|
||||
<Label text="---" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane styleClass="customGrid" GridPane.columnIndex="3" GridPane.rowIndex="1">
|
||||
<children>
|
||||
<HBox alignment="CENTER_LEFT" layoutX="-30.0" layoutY="-42.0" spacing="5.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<children>
|
||||
<Label fx:id="sigTypeLbl" text="-">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
<Label text=":" />
|
||||
<Label fx:id="sigTypeStrLbl" text="-">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
</children>
|
||||
</HBox>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane styleClass="customGrid" GridPane.columnIndex="3" GridPane.rowIndex="2">
|
||||
<children>
|
||||
<TextField fx:id="signatureTF" editable="false" layoutX="-47.0" layoutY="2.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane styleClass="customTitleGrid" GridPane.columnIndex="1">
|
||||
<children>
|
||||
<Label layoutX="38.0" layoutY="6.0" text="Size" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<font>
|
||||
<Font name="System Bold" size="13.0" />
|
||||
</font>
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane styleClass="customTitleGrid" GridPane.columnIndex="2">
|
||||
<children>
|
||||
<Label layoutX="14.0" layoutY="7.0" text="Description" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<font>
|
||||
<Font name="System Bold" size="13.0" />
|
||||
</font>
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane styleClass="customTitleGrid" GridPane.columnIndex="3">
|
||||
<children>
|
||||
<Label layoutY="6.0" text="Value" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<font>
|
||||
<Font name="System Bold" size="13.0" />
|
||||
</font>
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane styleClass="customTitleGrid">
|
||||
<children>
|
||||
<Label layoutX="2.0" layoutY="7.0" text="Offset" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<font>
|
||||
<Font name="System Bold" size="13.0" />
|
||||
</font>
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
</children>
|
||||
</GridPane>
|
||||
<Label text="Ticket data">
|
||||
<font>
|
||||
<Font name="System Bold" size="13.0" />
|
||||
</font>
|
||||
</Label>
|
||||
<GridPane>
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="60.0" minWidth="55.0" />
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="60.0" minWidth="55.0" />
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="180.0" minWidth="170.0" />
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="100.0" prefWidth="100.0" />
|
||||
</columnConstraints>
|
||||
<rowConstraints>
|
||||
<RowConstraints maxHeight="30.0" minHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints maxHeight="30.0" minHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints maxHeight="30.0" minHeight="30.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints maxHeight="30.0" minHeight="30.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints maxHeight="30.0" minHeight="30.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints maxHeight="30.0" minHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints maxHeight="30.0" minHeight="30.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints maxHeight="30.0" minHeight="30.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints maxHeight="30.0" minHeight="30.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints maxHeight="30.0" minHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints maxHeight="30.0" minHeight="30.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints maxHeight="30.0" minHeight="30.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints maxHeight="30.0" minHeight="30.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
</rowConstraints>
|
||||
<children>
|
||||
<AnchorPane styleClass="customGrid" GridPane.rowIndex="5">
|
||||
<children>
|
||||
<Label text="0x142" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane styleClass="customGrid" GridPane.rowIndex="9">
|
||||
<children>
|
||||
<Label text="0x158" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane styleClass="customGrid" GridPane.rowIndex="1">
|
||||
<children>
|
||||
<Label text="0x0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane styleClass="customGrid" GridPane.columnIndex="1" GridPane.rowIndex="9">
|
||||
<children>
|
||||
<Label text="0x8" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane styleClass="customGrid" GridPane.columnIndex="1" GridPane.rowIndex="5">
|
||||
<children>
|
||||
<Label text="0x3" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane styleClass="customGrid" GridPane.columnIndex="1" GridPane.rowIndex="1">
|
||||
<children>
|
||||
<Label text="0x40" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane styleClass="customGrid" GridPane.columnIndex="2" GridPane.rowIndex="1">
|
||||
<children>
|
||||
<Label text="Issuer" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane styleClass="customGrid" GridPane.columnIndex="2" GridPane.rowIndex="5">
|
||||
<children>
|
||||
<Label text="Unknown" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane styleClass="customGrid" GridPane.columnIndex="2" GridPane.rowIndex="9">
|
||||
<children>
|
||||
<Label text="Device ID" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane styleClass="customGrid" GridPane.columnIndex="3" GridPane.rowIndex="9">
|
||||
<children>
|
||||
<Label fx:id="deviceIdLbl" layoutX="3.0" layoutY="5.0" text="-" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
</children></AnchorPane>
|
||||
<AnchorPane styleClass="customGrid" GridPane.columnIndex="3" GridPane.rowIndex="1">
|
||||
<children>
|
||||
<TextField fx:id="issuerTf" editable="false" layoutX="-50.0" layoutY="3.0" promptText="-" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
|
||||
</children></AnchorPane>
|
||||
<AnchorPane styleClass="customGrid" GridPane.columnIndex="3" GridPane.rowIndex="5">
|
||||
<children>
|
||||
<Label fx:id="unknown2Lbl" layoutX="50.0" layoutY="8.0" text="-" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
</children></AnchorPane>
|
||||
<AnchorPane styleClass="customTitleGrid" GridPane.columnIndex="1">
|
||||
<children>
|
||||
<Label layoutX="38.0" layoutY="6.0" text="Size" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<font>
|
||||
<Font name="System Bold" size="13.0" />
|
||||
</font>
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane styleClass="customTitleGrid" GridPane.columnIndex="2">
|
||||
<children>
|
||||
<Label layoutX="14.0" layoutY="7.0" text="Description" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<font>
|
||||
<Font name="System Bold" size="13.0" />
|
||||
</font>
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane styleClass="customTitleGrid" GridPane.columnIndex="3">
|
||||
<children>
|
||||
<Label layoutY="6.0" text="Value" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<font>
|
||||
<Font name="System Bold" size="13.0" />
|
||||
</font>
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane styleClass="customTitleGrid">
|
||||
<children>
|
||||
<Label layoutX="2.0" layoutY="7.0" text="Offset" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<font>
|
||||
<Font name="System Bold" size="13.0" />
|
||||
</font>
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane styleClass="customGrid" GridPane.rowIndex="2">
|
||||
<children>
|
||||
<Label text="0x40" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane styleClass="customGrid" GridPane.columnIndex="1" GridPane.rowIndex="2">
|
||||
<children>
|
||||
<Label text="0x100" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane styleClass="customGrid" GridPane.columnIndex="2" GridPane.rowIndex="2">
|
||||
<children>
|
||||
<Label text="Title key block" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane styleClass="customGrid" GridPane.columnIndex="3" GridPane.rowIndex="2">
|
||||
<children>
|
||||
<TextField fx:id="titleKeyBlockTf" editable="false" layoutX="-59.0" layoutY="2.0" promptText="-" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane styleClass="customGrid" GridPane.rowIndex="3">
|
||||
<children>
|
||||
<Label text="0x140" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane styleClass="customGrid" GridPane.columnIndex="1" GridPane.rowIndex="3">
|
||||
<children>
|
||||
<Label text="0x1" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane styleClass="customGrid" GridPane.columnIndex="2" GridPane.rowIndex="3">
|
||||
<children>
|
||||
<Label text="Unknown" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane styleClass="customGrid" GridPane.columnIndex="3" GridPane.rowIndex="3">
|
||||
<children>
|
||||
<Label fx:id="unknown1Lbl" text="-" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane styleClass="customGrid" GridPane.rowIndex="4">
|
||||
<children>
|
||||
<Label text="0x141" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane styleClass="customGrid" GridPane.columnIndex="1" GridPane.rowIndex="4">
|
||||
<children>
|
||||
<Label text="0x1" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane styleClass="customGrid" GridPane.columnIndex="2" GridPane.rowIndex="4">
|
||||
<children>
|
||||
<Label text="Title key type" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane styleClass="customGrid" GridPane.columnIndex="3" GridPane.rowIndex="4">
|
||||
<children>
|
||||
<Label fx:id="titleKeyTypeLbl" text="-" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane styleClass="customGrid" GridPane.rowIndex="6">
|
||||
<children>
|
||||
<Label text="0x145" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane styleClass="customGrid" GridPane.columnIndex="1" GridPane.rowIndex="6">
|
||||
<children>
|
||||
<Label text="0x1" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane styleClass="customGrid" GridPane.rowIndex="7">
|
||||
<children>
|
||||
<Label text="0x146" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane styleClass="customGrid" GridPane.columnIndex="1" GridPane.rowIndex="7">
|
||||
<children>
|
||||
<Label text="0xA" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane styleClass="customGrid" GridPane.rowIndex="8">
|
||||
<children>
|
||||
<Label text="0x150" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane styleClass="customGrid" GridPane.columnIndex="1" GridPane.rowIndex="8">
|
||||
<children>
|
||||
<Label text="0x8" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane styleClass="customGrid" GridPane.columnIndex="2" GridPane.rowIndex="6">
|
||||
<children>
|
||||
<Label text="Master key revision" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane styleClass="customGrid" GridPane.columnIndex="2" GridPane.rowIndex="7">
|
||||
<children>
|
||||
<Label text="Unknown" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane styleClass="customGrid" GridPane.columnIndex="2" GridPane.rowIndex="8">
|
||||
<children>
|
||||
<Label text="Ticket ID" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane styleClass="customGrid" GridPane.columnIndex="3" GridPane.rowIndex="6">
|
||||
<children>
|
||||
<Label fx:id="masterKeyRevisionLbl" text="-" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane styleClass="customGrid" GridPane.rowIndex="10">
|
||||
<children>
|
||||
<Label text="0x160" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane styleClass="customGrid" GridPane.rowIndex="11">
|
||||
<children>
|
||||
<Label text="0x170" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane styleClass="customGrid" GridPane.rowIndex="12">
|
||||
<children>
|
||||
<Label text="0x174" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane styleClass="customGrid" GridPane.columnIndex="1" GridPane.rowIndex="10">
|
||||
<children>
|
||||
<Label text="0x10" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane styleClass="customGrid" GridPane.columnIndex="1" GridPane.rowIndex="11">
|
||||
<children>
|
||||
<Label text="0x4" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane styleClass="customGrid" GridPane.columnIndex="1" GridPane.rowIndex="12">
|
||||
<children>
|
||||
<Label text="0xC" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane styleClass="customGrid" GridPane.columnIndex="2" GridPane.rowIndex="10">
|
||||
<children>
|
||||
<Label text="Rights ID" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane styleClass="customGrid" GridPane.columnIndex="2" GridPane.rowIndex="11">
|
||||
<children>
|
||||
<Label text="Account ID" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane styleClass="customGrid" GridPane.columnIndex="2" GridPane.rowIndex="12">
|
||||
<children>
|
||||
<Label text="Unknown" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane styleClass="customGrid" GridPane.columnIndex="3" GridPane.rowIndex="7">
|
||||
<children>
|
||||
<Label fx:id="unknown3Lbl" text="-" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane styleClass="customGrid" GridPane.columnIndex="3" GridPane.rowIndex="8">
|
||||
<children>
|
||||
<Label fx:id="ticketIdLbl" text="-" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane styleClass="customGrid" GridPane.columnIndex="3" GridPane.rowIndex="10">
|
||||
<children>
|
||||
<TextField fx:id="rightsIdTf" editable="false" layoutX="-65.0" layoutY="2.0" promptText="-" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane styleClass="customGrid" GridPane.columnIndex="3" GridPane.rowIndex="11">
|
||||
<children>
|
||||
<Label fx:id="accountIdLbl" text="-" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane styleClass="customGrid" GridPane.columnIndex="3" GridPane.rowIndex="12">
|
||||
<children>
|
||||
<Label fx:id="unknown4Lbl" text="-" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
</children>
|
||||
</GridPane>
|
||||
<HBox spacing="5.0">
|
||||
<children>
|
||||
<Label text="File size:" />
|
||||
<Label fx:id="tikSizeLbl" text="-" />
|
||||
</children>
|
||||
</HBox>
|
||||
<padding>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||
</padding>
|
||||
</VBox>
|
||||
</ScrollPane>
|
|
@ -71,6 +71,14 @@
|
|||
<Label text="NCA" />
|
||||
</graphic>
|
||||
</Tab>
|
||||
<Tab closable="false">
|
||||
<content>
|
||||
<fx:include fx:id="TIKTab" source="TIK/TIKTab.fxml" />
|
||||
</content>
|
||||
<graphic>
|
||||
<Label text="TIK" />
|
||||
</graphic>
|
||||
</Tab>
|
||||
</tabs>
|
||||
</TabPane>
|
||||
<AnchorPane fx:id="logPane" prefHeight="200.0" prefWidth="200.0">
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
btnFileOpen=Select NSP/XCI/NCA
|
||||
btnFileOpen=Select NSP/XCI/NCA/TIK
|
||||
btnAnalyze=Analyze
|
||||
lblNoFileSelected=No files selected.
|
||||
tableNumberLbl=#
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
btnFileOpen=Selectionner NSP/XCI/NCA
|
||||
btnFileOpen=Selectionner NSP/XCI/NCA/TIK
|
||||
btnAnalyze=Analyser
|
||||
lblNoFileSelected=Aucuns fichiers s\u00E9lectionn\u00E9s.
|
||||
tableUploadLbl=Extraire ?
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
btnFileOpen=\u0412\u044B\u0431\u0440\u0430\u0442\u044C NSP/XCI/NCA
|
||||
btnFileOpen=\u0412\u044B\u0431\u0440\u0430\u0442\u044C NSP/XCI/NCA/TIK
|
||||
btnAnalyze=\u0410\u043D\u0430\u043B\u0438\u0437\u0438\u0440\u043E\u0432\u0430\u0442\u044C
|
||||
lblNoFileSelected=\u0424\u0430\u0439\u043B\u044B \u043D\u0435 \u0432\u044B\u0431\u0440\u0430\u043D\u044B.
|
||||
tableUploadLbl=\u0420\u0430\u0441\u043F\u0430\u043A\u043E\u0432\u0430\u0442\u044C?
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
btnFileOpen=\u0412\u0438\u0431\u0440\u0430\u0442\u0438 NSP/XCI/NCA
|
||||
btnFileOpen=\u0412\u0438\u0431\u0440\u0430\u0442\u0438 NSP/XCI/NCA/TIK
|
||||
btnAnalyze=\u0410\u043D\u0430\u043B\u0456\u0437\u0443\u0432\u0430\u0442\u0438
|
||||
lblNoFileSelected=\u0424\u0430\u0439\u043B\u0438 \u043D\u0435 \u0432\u0438\u0431\u0440\u0430\u043D\u0456.
|
||||
tableNumberLbl=\u2116
|
||||
|
|
Loading…
Reference in a new issue