Finally able to detect FW17+ Kernel Map
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
This commit is contained in:
parent
620ae15693
commit
6f04213307
2 changed files with 67 additions and 26 deletions
|
@ -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; }
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
Loading…
Reference in a new issue