Finally able to detect FW17+ Kernel Map
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful

This commit is contained in:
Dmitry Isaenko 2025-02-17 23:37:30 +03:00
parent 620ae15693
commit 6f04213307
2 changed files with 67 additions and 26 deletions

View file

@ -1,5 +1,5 @@
/* /*
Copyright 2019-2023 Dmitry Isaenko Copyright 2019-2025 Dmitry Isaenko
This file is part of libKonogonka. This file is part of libKonogonka.
@ -50,8 +50,6 @@ public class KernelMap {
public static KernelMap constructKernelMap(byte[] mapBytes, int offset, int maxSize) { public static KernelMap constructKernelMap(byte[] mapBytes, int offset, int maxSize) {
KernelMap kernelMap = new KernelMap(); KernelMap kernelMap = new KernelMap();
kernelMap.textStartOffset = Converter.getLEint(mapBytes, offset); kernelMap.textStartOffset = Converter.getLEint(mapBytes, offset);
if (kernelMap.textStartOffset != 0)
return null;
kernelMap.textEndOffset = Converter.getLEint(mapBytes, offset + 0x4); kernelMap.textEndOffset = Converter.getLEint(mapBytes, offset + 0x4);
kernelMap.rodataStartOffset = Converter.getLEint(mapBytes, offset + 0x8); kernelMap.rodataStartOffset = Converter.getLEint(mapBytes, offset + 0x8);
kernelMap.rodataEndOffset = Converter.getLEint(mapBytes, offset + 0xC); kernelMap.rodataEndOffset = Converter.getLEint(mapBytes, offset + 0xC);
@ -65,38 +63,67 @@ public class KernelMap {
kernelMap.initArrayEndOffset = Converter.getLEint(mapBytes, offset + 0x2C); kernelMap.initArrayEndOffset = Converter.getLEint(mapBytes, offset + 0x2C);
kernelMap.systemRegistersOffset = Converter.getLEint(mapBytes, offset + 0x30); kernelMap.systemRegistersOffset = Converter.getLEint(mapBytes, offset + 0x30);
// taken from hactool if (isValid(kernelMap, maxSize))
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; return kernelMap;
return null;
}
public static KernelMap constructKernelMap17(byte[] mapBytes, int offset, int branchTarget, int maxSize) {
KernelMap kernelMap = new KernelMap();
final int realOffset = offset + branchTarget;
kernelMap.textStartOffset = Converter.getLEint(mapBytes, offset)+realOffset;
kernelMap.textEndOffset = Converter.getLEint(mapBytes, offset + 0x4)+realOffset;
kernelMap.rodataStartOffset = Converter.getLEint(mapBytes, offset + 0x8)+realOffset;
kernelMap.rodataEndOffset = Converter.getLEint(mapBytes, offset + 0xC)+realOffset;
kernelMap.dataStartOffset = Converter.getLEint(mapBytes, offset + 0x10)+realOffset;
kernelMap.dataEndOffset = Converter.getLEint(mapBytes, offset + 0x14)+realOffset;
kernelMap.bssStartOffset = Converter.getLEint(mapBytes, offset + 0x18)+realOffset;
kernelMap.bssEndOffset = Converter.getLEint(mapBytes, offset + 0x1C)+realOffset;
kernelMap.ini1Offset = Converter.getLEint(mapBytes, offset + 0x20)+realOffset; // 0x08d000
kernelMap.dynamicOffset = Converter.getLEint(mapBytes, offset + 0x24)+realOffset;
kernelMap.initArrayStartOffset = Converter.getLEint(mapBytes, offset + 0x28)+realOffset;
kernelMap.initArrayEndOffset = Converter.getLEint(mapBytes, offset + 0x2C)+realOffset;
kernelMap.systemRegistersOffset = Converter.getLEint(mapBytes, offset + 0x30)+realOffset;
if (isValid(kernelMap, maxSize))
return kernelMap;
return null;
}
private static boolean isValid(KernelMap kernelMap, int maxSize){
// taken from hactool
if (kernelMap.textStartOffset != 0)
return false;
if (kernelMap.textStartOffset >= kernelMap.textEndOffset)
return false;
if ((kernelMap.textEndOffset & 0xFFF) > 0)
return false;
if (kernelMap.textEndOffset > kernelMap.rodataStartOffset)
return false;
if ((kernelMap.rodataStartOffset & 0xFFF) > 0)
return false;
if (kernelMap.rodataStartOffset >= kernelMap.rodataEndOffset)
return false;
if ((kernelMap.rodataEndOffset & 0xFFF) > 0)
return false;
if (kernelMap.rodataEndOffset > kernelMap.dataStartOffset)
return false;
if ((kernelMap.dataStartOffset & 0xFFF) > 0)
return false;
if (kernelMap.dataStartOffset >= kernelMap.dataEndOffset)
return false;
if (kernelMap.dataEndOffset > kernelMap.bssStartOffset)
return false;
if (kernelMap.bssStartOffset > kernelMap.bssEndOffset)
return false;
if (kernelMap.bssEndOffset > kernelMap.ini1Offset)
return false;
if (kernelMap.ini1Offset > maxSize - 0x80)
return false;
return true;
} }
public int getTextStartOffset() { return textStartOffset; } public int getTextStartOffset() { return textStartOffset; }

View file

@ -1,5 +1,5 @@
/* /*
Copyright 2019-2022 Dmitry Isaenko Copyright 2019-2025 Dmitry Isaenko
This file is part of libKonogonka. This file is part of libKonogonka.
@ -20,7 +20,6 @@ package libKonogonka.fs.other.System2;
import libKonogonka.Converter; import libKonogonka.Converter;
import libKonogonka.KeyChainHolder; import libKonogonka.KeyChainHolder;
import libKonogonka.RainbowDump;
import libKonogonka.fs.ExportAble; import libKonogonka.fs.ExportAble;
import libKonogonka.fs.other.System2.ini1.Ini1Provider; import libKonogonka.fs.other.System2.ini1.Ini1Provider;
import libKonogonka.aesctr.InFileStreamProducer; import libKonogonka.aesctr.InFileStreamProducer;
@ -121,12 +120,27 @@ public class System2Provider extends ExportAble {
int branchTarget = (Converter.getLEint(searchField, 0) & 0x00FFFFFF) << 2; int branchTarget = (Converter.getLEint(searchField, 0) & 0x00FFFFFF) << 2;
int toSkip = branchTarget - 0x1000; int toSkip = branchTarget - 0x1000;
System.out.println("To skip = " + toSkip + " ");
if (toSkip != stream.skip(toSkip)) if (toSkip != stream.skip(toSkip))
throw new Exception("Unable to skip offset of " + toSkip); throw new Exception("Unable to skip offset of " + toSkip);
// TODO: really cursed shit byteBuffer.clear();
throw new Exception("FW 17+ not supported. WIP");
for (int j = 0; j < 8; j++) {
byte[] block = new byte[0x200];
int actuallyRead;
if ((actuallyRead = stream.read(block)) != 0x200)
throw new Exception("Read failure " + actuallyRead);
byteBuffer.put(block);
}
searchField = byteBuffer.array();
for (int i = 0; i < 0x1000; i += 4) {
kernelMap = KernelMap.constructKernelMap17(searchField, i, branchTarget, header.getSection0size());
if (kernelMap != null)
return;
}
System.out.println();
} }
else { else {
for (int i = 0; i < 0x1000; i += 4) { for (int i = 0; i < 0x1000; i += 4) {