libKonogonka/src/main/java/libKonogonka/Tools/other/System2/ini1/Kip1.java

168 lines
10 KiB
Java

/*
Copyright 2019-2023 Dmitry Isaenko
This file is part of libKonogonka.
libKonogonka is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
libKonogonka is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with libKonogonka. If not, see <https://www.gnu.org/licenses/>.
*/
package libKonogonka.Tools.other.System2.ini1;
import libKonogonka.Converter;
import libKonogonka.RainbowDump;
import libKonogonka.Tools.NPDM.KernelAccessControlProvider;
import libKonogonka.Tools.NSO.SegmentHeader;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
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 dataSegmentHeader;
private final byte[] reserved2;
private final SegmentHeader bssSegmentHeader;
private final byte[] reserved3;
private final KernelAccessControlProvider kernelCapabilityData;
public Kip1(byte[] kip1Bytes) throws Exception{
this.magic = new String(kip1Bytes, 0, 0x4);
this.name = new String(kip1Bytes, 0x4, 0xC);
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.dataSegmentHeader = 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 String getMagic() { return magic; }
public String getName() { return name; }
public byte[] getProgramId() { return programId; }
public int getVersion() { return version; }
public byte getMainThreadPriority() { return mainThreadPriority; }
public byte getMainThreadCoreNumber() { return mainThreadCoreNumber; }
public byte getReserved1() { return reserved1; }
public byte getFlags() { return flags; }
public SegmentHeader getTextSegmentHeader() { return textSegmentHeader; }
public int getThreadAffinityMask() { return threadAffinityMask; }
public SegmentHeader getRoDataSegmentHeader() { return roDataSegmentHeader; }
public int getMainThreadStackSize() { return mainThreadStackSize; }
public SegmentHeader getDataSegmentHeader() { return dataSegmentHeader; }
public byte[] getReserved2() { return reserved2; }
public SegmentHeader getBssSegmentHeader() { return bssSegmentHeader; }
public byte[] getReserved3() { return reserved3; }
public KernelAccessControlProvider getKernelCapabilityData() { return kernelCapabilityData; }
public void printDebug(){
StringBuilder mapIoOrNormalRange = new StringBuilder();
StringBuilder interruptPairs = new StringBuilder();
StringBuilder syscallMasks = new StringBuilder();
kernelCapabilityData.getMapIoOrNormalRange().forEach((bytes, aBoolean) -> {
mapIoOrNormalRange.append(" ");
mapIoOrNormalRange.append(Converter.byteArrToHexStringAsLE(bytes));
mapIoOrNormalRange.append(" : ");
mapIoOrNormalRange.append(aBoolean);
mapIoOrNormalRange.append("\n");
});
kernelCapabilityData.getInterruptPairs().forEach((aInteger, bytes) -> {
interruptPairs.append(" #");
interruptPairs.append(aInteger);
for (byte[] innerArray : bytes) {
interruptPairs.append("\n |- ");
interruptPairs.append(Converter.byteArrToHexStringAsLE(innerArray));
}
interruptPairs.append("\n");
});
kernelCapabilityData.getSyscallMasks().forEach((aByte, bytes) -> {
syscallMasks.append(" ");
syscallMasks.append(String.format("0x%x", aByte));
syscallMasks.append(" : ");
syscallMasks.append(Converter.byteArrToHexStringAsLE(bytes));
syscallMasks.append("\n");
});
log.debug(" ..:: KIP1 ::..\n" +
"Magic : " + magic + "\n" +
"Name : " + name + "\n" +
"ProgramId : " + Converter.byteArrToHexStringAsLE(programId) + "\n" +
"Version : " + RainbowDump.formatDecHexString(version) + "\n" +
"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" +
".text segment header\n" +
" Segment offset : " + RainbowDump.formatDecHexString(textSegmentHeader.getSegmentOffset()) + "\n" +
" Memory offset : " + RainbowDump.formatDecHexString(textSegmentHeader.getMemoryOffset()) + "\n" +
" Size : " + RainbowDump.formatDecHexString(textSegmentHeader.getSizeAsDecompressed()) + "\n" +
"Thread affinity mask : " + RainbowDump.formatDecHexString(threadAffinityMask) + "\n" +
".ro segment header\n" +
" Segment offset : " + RainbowDump.formatDecHexString(roDataSegmentHeader.getSegmentOffset()) + "\n" +
" 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" +
" Segment offset : " + RainbowDump.formatDecHexString(dataSegmentHeader.getSegmentOffset()) + "\n" +
" Memory offset : " + RainbowDump.formatDecHexString(dataSegmentHeader.getMemoryOffset()) + "\n" +
" Size : " + RainbowDump.formatDecHexString(dataSegmentHeader.getSizeAsDecompressed()) + "\n" +
"Reserved 2 : " + Converter.byteArrToHexStringAsLE(reserved2) + "\n" +
".bss segment header\n" +
" Segment offset : " + RainbowDump.formatDecHexString(bssSegmentHeader.getSegmentOffset()) + "\n" +
" Memory offset : " + RainbowDump.formatDecHexString(bssSegmentHeader.getMemoryOffset()) + "\n" +
" Size : " + RainbowDump.formatDecHexString(bssSegmentHeader.getSizeAsDecompressed()) + "\n" +
"Reserved 3 : " + Converter.byteArrToHexStringAsLE(reserved3) + "\n" +
"Kernel capability data\n" +
" Kernel flags available? : " + kernelCapabilityData.isKernelFlagsAvailable() + "\n" +
" |- CPU ID Hi : " + kernelCapabilityData.getKernelFlagCpuIdHi() + "\n" +
" |- CPU ID Low : " + kernelCapabilityData.getKernelFlagCpuIdLo() + "\n" +
" |- Thread priority Hi : " + kernelCapabilityData.getKernelFlagThreadPrioHi() + "\n" +
" |- Thread priority Low : " + kernelCapabilityData.getKernelFlagThreadPrioLo()+ "\n" +
"Map IO or Normal Range:\n" + mapIoOrNormalRange +
"Interrupt pairs\n" + interruptPairs +
"Map normal page : " + Converter.byteArrToHexStringAsLE(kernelCapabilityData.getMapNormalPage()) + "\n" +
"Application type : " + RainbowDump.formatDecHexString(kernelCapabilityData.getApplicationType()) + "\n" +
" Kernel rel. version available? : " + kernelCapabilityData.isKernelRelVersionAvailable() + "\n" +
" |- Version Major : " + kernelCapabilityData.getKernelRelVersionMajor() + "\n" +
" |- Version Minor : " + kernelCapabilityData.getKernelRelVersionMinor() + "\n" +
"Handle table size : " + RainbowDump.formatDecHexString(kernelCapabilityData.getHandleTableSize()) + "\n" +
" Debug flags available? : " + kernelCapabilityData.isDebugFlagsAvailable() + "\n" +
" |- Can be debugged : " + kernelCapabilityData.isCanBeDebugged() + "\n" +
" |- Can debug others : " + kernelCapabilityData.isCanDebugOthers() + "\n" +
"Syscall masks\n" + syscallMasks
);
}
}