Ford 6.4 08 Powerstroke Checksum

Ford information and tools can be found here
Post Reply
eric28
Posts: 3
Joined: Sat Oct 27, 2018 6:46 am
cars: ford

Ford 6.4 08 Powerstroke Checksum

Post by eric28 »

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 351 times
User avatar
rolls
Posts: 407
Joined: Wed Sep 07, 2016 11:22 am
cars: bf xr6t falcon

Re: Ford 6.4 08 Powerstroke Checksum

Post by rolls »

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

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;
        }
There will also be 3 more 32bit checksums, the addresses for these are dynamic however but I think you can normally turn this off.
Post Reply