This commit is contained in:
parent
80152e119c
commit
620ae15693
2 changed files with 106 additions and 77 deletions
|
@ -26,32 +26,77 @@ import org.apache.logging.log4j.Logger;
|
|||
public class KernelMap {
|
||||
private final static Logger log = LogManager.getLogger(KernelMap.class);
|
||||
|
||||
private final int textStartOffset;
|
||||
private final int textEndOffset;
|
||||
private final int rodataStartOffset;
|
||||
private final int rodataEndOffset;
|
||||
private final int dataStartOffset;
|
||||
private final int dataEndOffset;
|
||||
private final int bssStartOffset;
|
||||
private final int bssEndOffset;
|
||||
private final int ini1Offset;
|
||||
private final int dynamicOffset;
|
||||
private final int initArrayStartOffset;
|
||||
private final int initArrayEndOffset;
|
||||
private int textStartOffset;
|
||||
private int textEndOffset;
|
||||
private int rodataStartOffset;
|
||||
private int rodataEndOffset;
|
||||
private int dataStartOffset;
|
||||
private int dataEndOffset;
|
||||
private int bssStartOffset;
|
||||
private int bssEndOffset;
|
||||
private int ini1Offset;
|
||||
private int dynamicOffset;
|
||||
private int initArrayStartOffset;
|
||||
private int initArrayEndOffset;
|
||||
private int systemRegistersOffset; // 17.0.0+
|
||||
|
||||
public KernelMap(byte[] mapBytes, int offset){
|
||||
textStartOffset = Converter.getLEint(mapBytes, offset);
|
||||
textEndOffset = Converter.getLEint(mapBytes, offset + 0x4);
|
||||
rodataStartOffset = Converter.getLEint(mapBytes, offset + 0x8);
|
||||
rodataEndOffset = Converter.getLEint(mapBytes, offset + 0xC);
|
||||
dataStartOffset = Converter.getLEint(mapBytes, offset + 0x10);
|
||||
dataEndOffset = Converter.getLEint(mapBytes, offset + 0x14);
|
||||
bssStartOffset = Converter.getLEint(mapBytes, offset + 0x18);
|
||||
bssEndOffset = Converter.getLEint(mapBytes, offset + 0x1C);
|
||||
ini1Offset = Converter.getLEint(mapBytes, offset + 0x20);
|
||||
dynamicOffset = Converter.getLEint(mapBytes, offset + 0x24);
|
||||
initArrayStartOffset = Converter.getLEint(mapBytes, offset + 0x28);
|
||||
initArrayEndOffset = Converter.getLEint(mapBytes, offset + 0x2C);
|
||||
private KernelMap() { }
|
||||
|
||||
/**
|
||||
* Construct KernelMap
|
||||
*
|
||||
* @return null if mapBytes is an invalid data set and KernelMap object otherwise
|
||||
*/
|
||||
public static KernelMap constructKernelMap(byte[] mapBytes, int offset, int maxSize) {
|
||||
KernelMap kernelMap = new KernelMap();
|
||||
kernelMap.textStartOffset = Converter.getLEint(mapBytes, offset);
|
||||
if (kernelMap.textStartOffset != 0)
|
||||
return null;
|
||||
kernelMap.textEndOffset = Converter.getLEint(mapBytes, offset + 0x4);
|
||||
kernelMap.rodataStartOffset = Converter.getLEint(mapBytes, offset + 0x8);
|
||||
kernelMap.rodataEndOffset = Converter.getLEint(mapBytes, offset + 0xC);
|
||||
kernelMap.dataStartOffset = Converter.getLEint(mapBytes, offset + 0x10);
|
||||
kernelMap.dataEndOffset = Converter.getLEint(mapBytes, offset + 0x14);
|
||||
kernelMap.bssStartOffset = Converter.getLEint(mapBytes, offset + 0x18);
|
||||
kernelMap.bssEndOffset = Converter.getLEint(mapBytes, offset + 0x1C);
|
||||
kernelMap.ini1Offset = Converter.getLEint(mapBytes, offset + 0x20); // 0x08d000
|
||||
kernelMap.dynamicOffset = Converter.getLEint(mapBytes, offset + 0x24);
|
||||
kernelMap.initArrayStartOffset = Converter.getLEint(mapBytes, offset + 0x28);
|
||||
kernelMap.initArrayEndOffset = Converter.getLEint(mapBytes, offset + 0x2C);
|
||||
kernelMap.systemRegistersOffset = Converter.getLEint(mapBytes, offset + 0x30);
|
||||
|
||||
// taken from hactool
|
||||
if (kernelMap.textStartOffset >= kernelMap.textEndOffset)
|
||||
return null;
|
||||
if ((kernelMap.textEndOffset & 0xFFF) > 0)
|
||||
return null;
|
||||
if (kernelMap.textEndOffset > kernelMap.rodataStartOffset)
|
||||
return null;
|
||||
if ((kernelMap.rodataStartOffset & 0xFFF) > 0)
|
||||
return null;
|
||||
if (kernelMap.rodataStartOffset >= kernelMap.rodataEndOffset)
|
||||
return null;
|
||||
if ((kernelMap.rodataEndOffset & 0xFFF) > 0)
|
||||
return null;
|
||||
if (kernelMap.rodataEndOffset > kernelMap.dataStartOffset)
|
||||
return null;
|
||||
if ((kernelMap.dataStartOffset & 0xFFF) > 0)
|
||||
return null;
|
||||
if (kernelMap.dataStartOffset >= kernelMap.dataEndOffset)
|
||||
return null;
|
||||
if (kernelMap.dataEndOffset > kernelMap.bssStartOffset)
|
||||
return null;
|
||||
if (kernelMap.bssStartOffset > kernelMap.bssEndOffset)
|
||||
return null;
|
||||
if (kernelMap.bssEndOffset > kernelMap.ini1Offset)
|
||||
return null;
|
||||
/*
|
||||
if (kernelMap.ini1Offset > maxSize - 0x80)
|
||||
return null;
|
||||
*/
|
||||
System.out.println("FOUND AT:" + RainbowDump.formatDecHexString(offset));
|
||||
kernelMap.printDebug();
|
||||
return kernelMap;
|
||||
}
|
||||
|
||||
public int getTextStartOffset() { return textStartOffset; }
|
||||
|
@ -67,40 +112,7 @@ public class KernelMap {
|
|||
public int getInitArrayStartOffset() { return initArrayStartOffset; }
|
||||
public int getInitArrayEndOffset() { return initArrayEndOffset; }
|
||||
|
||||
//taken from hactool
|
||||
public boolean isValid(long maxSize) { // section0 size
|
||||
if (textStartOffset != 0)
|
||||
return false;
|
||||
if (textStartOffset >= textEndOffset)
|
||||
return false;
|
||||
if ((textEndOffset & 0xFFF) > 0)
|
||||
return false;
|
||||
if (textEndOffset > rodataStartOffset)
|
||||
return false;
|
||||
if ((rodataStartOffset & 0xFFF) > 0)
|
||||
return false;
|
||||
if (rodataStartOffset >= rodataEndOffset)
|
||||
return false;
|
||||
if ((rodataEndOffset & 0xFFF) > 0)
|
||||
return false;
|
||||
if (rodataEndOffset > dataStartOffset)
|
||||
return false;
|
||||
if ((dataStartOffset & 0xFFF) > 0)
|
||||
return false;
|
||||
if (dataStartOffset >= dataEndOffset)
|
||||
return false;
|
||||
if (dataEndOffset > bssStartOffset)
|
||||
return false;
|
||||
if (bssStartOffset > bssEndOffset)
|
||||
return false;
|
||||
if (bssEndOffset > ini1Offset)
|
||||
return false;
|
||||
if (ini1Offset > maxSize - 0x80)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
public void printDebug(){
|
||||
public void printDebug() {
|
||||
log.debug("_ Kernel map _\n" +
|
||||
" .text Start Offset " + RainbowDump.formatDecHexString(textStartOffset) + "\n" +
|
||||
" .text End Offset " + RainbowDump.formatDecHexString(textEndOffset) + "\n" +
|
||||
|
@ -113,6 +125,7 @@ public class KernelMap {
|
|||
" INI1 Offset " + RainbowDump.formatDecHexString(ini1Offset) + "\n" +
|
||||
" Dynamic Offset " + RainbowDump.formatDecHexString(dynamicOffset) + "\n" +
|
||||
" Init array Start Offset " + RainbowDump.formatDecHexString(initArrayStartOffset) + "\n" +
|
||||
" Init array End Offset " + RainbowDump.formatDecHexString(initArrayEndOffset));
|
||||
" Init array End Offset " + RainbowDump.formatDecHexString(initArrayEndOffset) + "\n" +
|
||||
" System registers offset (FW 17.0.0+) " + RainbowDump.formatDecHexString(systemRegistersOffset));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,7 +18,9 @@
|
|||
*/
|
||||
package libKonogonka.fs.other.System2;
|
||||
|
||||
import libKonogonka.Converter;
|
||||
import libKonogonka.KeyChainHolder;
|
||||
import libKonogonka.RainbowDump;
|
||||
import libKonogonka.fs.ExportAble;
|
||||
import libKonogonka.fs.other.System2.ini1.Ini1Provider;
|
||||
import libKonogonka.aesctr.InFileStreamProducer;
|
||||
|
@ -112,13 +114,27 @@ public class System2Provider extends ExportAble {
|
|||
throw new Exception("Read failure " + actuallyRead);
|
||||
byteBuffer.put(block);
|
||||
}
|
||||
|
||||
byte[] searchField = byteBuffer.array();
|
||||
for (int i = 0; i < 1024; i += 4) {
|
||||
kernelMap = new KernelMap(searchField, i);
|
||||
if (kernelMap.isValid(header.getSection0size()))
|
||||
|
||||
if (Converter.getLEint(searchField, 3) == 0x14){ // If FW 17.0.0+
|
||||
// Calculate new location of the 'kernel beginning'
|
||||
int branchTarget = (Converter.getLEint(searchField, 0) & 0x00FFFFFF) << 2;
|
||||
|
||||
int toSkip = branchTarget - 0x1000;
|
||||
System.out.println("To skip = " + toSkip + " ");
|
||||
if (toSkip != stream.skip(toSkip))
|
||||
throw new Exception("Unable to skip offset of " + toSkip);
|
||||
|
||||
// TODO: really cursed shit
|
||||
throw new Exception("FW 17+ not supported. WIP");
|
||||
}
|
||||
else {
|
||||
for (int i = 0; i < 0x1000; i += 4) {
|
||||
kernelMap = KernelMap.constructKernelMap(searchField, i, header.getSection0size());
|
||||
if (kernelMap != null)
|
||||
return;
|
||||
}
|
||||
}
|
||||
throw new Exception("Kernel map not found");
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue