Ford 6.4 08 Powerstroke Checksum
Ford 6.4 08 Powerstroke Checksum
Was wondering if anyone knew how to find the checksum ranges on a PHF file Ford 6.4 08 . . I'm modifying the speed limiter and need to correct the checksum. Any help would be appreciated or possibly point me in the right direction. I uploaded the calibration file(stripped phf).
- Attachments
-
- 8C3A-14C204-AK.BIN
- (1.94 MiB) Downloaded 353 times
Re: Ford 6.4 08 Powerstroke Checksum
08 will be a PPC checksum if its an oak processor. Do you know how to use IDA?
If its a typical oak processor the checksum pointers are hard coded here:
0x10224
0x1022C
0x10234
The addresses point to a start/end address and then the checksum is a 16 bit rolling checksum.
Here is some C# code to do it
There will also be 3 more 32bit checksums, the addresses for these are dynamic however but I think you can normally turn this off.
If its a typical oak processor the checksum pointers are hard coded here:
0x10224
0x1022C
0x10234
The addresses point to a start/end address and then the checksum is a 16 bit rolling checksum.
Here is some C# code to do it
Code: Select all
private readonly List<uint> _checksumSegmentPointers = new List<uint>
{
0x10224,
0x1022C,
0x10234,
};
private long GetSegmentChecksum()
{
unchecked
{
long checksummer = 0;
foreach (var c in _checksumSegmentPointers)
{
checksummer += Calculate16bitSegmentCheckSum(c);
}
long checksum = ~checksummer + 1u;
return checksum;
}
}
private uint Calculate16bitSegmentCheckSum(uint checksumPtr)
{
if(!_rawBinary.AddressIsWithinSegment(checksumPtr, 8)) return 0;
uint checkSum = 0;
uint start = _rawBinary.UInt32[checksumPtr];
uint end = _rawBinary.UInt32[checksumPtr + 4u];
//For some reason the first segment needs to start 4 bytes later
//because these bytes are a checksum?
if (start == 0x10220) start = 0x10224;
//Range check
try
{
checked
{
uint length = end - start;
if (!_rawBinary.AddressIsWithinSegment(start, (int)length)) return 0;
}
}
catch (OverflowException)
{
return 0;
}
uint address = start;
unchecked
{
while (address < end)
{
checkSum += (uint)(_rawBinary[address] << 8) + _rawBinary[address + 1];
address += 2;
}
}
return checkSum;
}