Pages: 1 2 [3]
Author Topic: Volvo 3.0 T6 Denso tunning files Including Polestar (P3 Platform)  (Read 8791 times)
PoleStarPete
Newbie
*

Karma: +3/-0
Offline Offline

Posts: 12


« Reply #30 on: April 29, 2023, 02:12:38 AM »

there is defiantly DHA for p3, getting it is the hard part :-(
I've got some dha databases for some of the common platform fords of the correct era.  might be useful . i'll add it to the Google drive.

I have also added a can log of an ecm reload by Vida. https://drive.google.com/file/d/1rho2kS1vriuaOxVd_zI-F7GZx7b2HmOy/view?usp=share_link
Logged
prj
Hero Member
*****

Karma: +1072/-480
Offline Offline

Posts: 6035


« Reply #31 on: April 29, 2023, 03:11:27 AM »

It's for SDA not DHA now.

I've only seen one file for a 2016, and I don't have any contacts where to get anything else.
Logged

PM's will not be answered, so don't even try.
Log your car properly - WinOLS database - Tools/patches
PoleStarPete
Newbie
*

Karma: +3/-0
Offline Offline

Posts: 12


« Reply #32 on: April 29, 2023, 03:12:40 AM »

ive added all the dha / sda stuff i have
https://drive.google.com/file/d/1IlaN9Lp_Ne4GhKn1fmaz7BGOO0CPbIZl/view?usp=share_link
Logged
dikidera
Full Member
***

Karma: +8/-8
Offline Offline

Posts: 149


« Reply #33 on: April 30, 2023, 11:26:57 PM »

I never said that such software doesn't exist, but that it isn't readily available for us.

When I first started, without DHA, I had to manually probe the ECU PCB, attach an oscilloscope, to map what each pin does and then later try to correlate my measurements with the logic in the code. Then later on when rkam gave me a list of variables and memory addresses, even with over 100+ named variables, there were pieces of code, logic, which I don't fully understand. Which is why I could only name my variables "Related_to_<X>" and add question marks on possible behaviour.

I wonder if in such cases, it's better to write a whole system SH<x> emulator. I have done some basic boilerplating by adding a new build option for SH2 rather than the SH4 in QEMU. My next step was removing the MMU, but I still couldn't quite figure out the QEMU API. The idea was to get SH2 code executing and fixing whatever snags I hit until for instance we get to the streaming CAN data part and then finally a fully emulated ECU of a running car. Of course QEMU is not cycle accurate and I am not sure if this will be a problem or not. Hope someone has more information on this. In any case I have done nothing beyond just adding a different build option for SH2. The CPU model needs to be changed to implement various interrupts, exceptions etc. I am juggling so many things right now from fixing my entire car to family issues that I simply do not have time.

So far, with just basic emulation with GhidraEmu I have managed to further my knowledge of the Denso internals. I managed to find an opaque CAN interface which is where it was all indirectly used, along with the dynamically constructed data at address FFFF7448.
« Last Edit: May 01, 2023, 04:42:12 AM by dikidera » Logged
prometey1982
Sr. Member
****

Karma: +70/-60
Offline Offline

Posts: 323



WWW
« Reply #34 on: May 15, 2023, 06:17:41 AM »

Generate key for Denso T6 ECM reversed from Pete's PIN application:

Code:
unsigned int __cdecl GenerateKey(unsigned __int8 *PinArray, unsigned __int8 *SeedArray, _BYTE *KeyArray)
{
  char ShiftsCountForSeed; // bl
  unsigned int PinValue; // edx
  unsigned int SeedValue; // ecx
  unsigned int ProcessedResult; // eax
  char SeedValueOld; // di
  char IsEvenSeed; // di
  char ShiftsCountForPid; // cl
  char PinValueOld; // si
  char IsEvenPid; // si
  unsigned int result; // eax

  ShiftsCountForSeed = 32;
  PinValue = (PinArray[2] << 8) | PinArray[1] | (PinArray[4] << 24) | (PinArray[3] << 16);
  SeedValue = (*PinArray << 24) | *SeedArray | (SeedArray[2] << 16) | (SeedArray[1] << 8);
  ProcessedResult = 0xC541A9;
  do
  {
    SeedValueOld = SeedValue;
    SeedValue >>= 1;
    IsEvenSeed = ProcessedResult ^ SeedValueOld;
    ProcessedResult >>= 1;
    if ( (IsEvenSeed & 1) != 0 )
      ProcessedResult = (ProcessedResult | 0x800000) ^ 0x109028;
    --ShiftsCountForSeed;
  }
  while ( ShiftsCountForSeed );
  ShiftsCountForPid = 32;
  do
  {
    PinValueOld = PinValue;
    PinValue >>= 1;
    IsEvenPid = ProcessedResult ^ PinValueOld;
    ProcessedResult >>= 1;
    if ( (IsEvenPid & 1) != 0 )
      ProcessedResult = (ProcessedResult | 0x800000) ^ 0x109028;
    --ShiftsCountForPid;
  }
  while ( ShiftsCountForPid );
  result = ((ProcessedResult & 0xF00000) >> 12) | ProcessedResult & 0xF000 | (unsigned __int8)(16 * ProcessedResult) | ((ProcessedResult & 0xFF0) << 12) | ((ProcessedResult & 0xF0000) >> 16);
  KeyArray[2] = result;
  *KeyArray = BYTE2(result);
  KeyArray[1] = BYTE1(result);
  return result;
}
Logged

Россия - Великая страна!
https://youtu.be/fup5GzIFdXk
prometey1982
Sr. Member
****

Karma: +70/-60
Offline Offline

Posts: 323



WWW
« Reply #35 on: December 23, 2023, 02:24:02 AM »

Algorithm described below is standard algo for Volvo P3 platform. It used for CEM and ECM ME9. Looks like other modules also use it. Tool from PoleStarPete can find PIN for ME9.
Logged

Россия - Великая страна!
https://youtu.be/fup5GzIFdXk
prometey1982
Sr. Member
****

Karma: +70/-60
Offline Offline

Posts: 323



WWW
« Reply #36 on: December 23, 2023, 03:08:52 AM »

Slightly modified P3 hash function from vtl

Code:
uint32_t p3_hash(uint8_t pin[5], uint8_t seed[3])
{
    uint32_t n = 0xc541a9, m = 0x1212050;
    uint64_t k;
    uint8_t* in = (unsigned char*)&k;

    in[0] = seed[0];
    in[1] = seed[1];
    in[2] = seed[2];
    in[3] = pin[0];
    in[4] = pin[1];
    in[5] = pin[2];
    in[6] = pin[3];
    in[7] = pin[4];

    for (size_t i = 0; i < 64; i++, n >>= 1, k >>= 1) {
        if ((n ^ k) & 0x1)
            n ^= m;
    }
    return ((n & 0xF00000) >> 12) | n & 0xF000 | (uint8_t)(16 * n) | ((n & 0xFF0) << 12) | ((n & 0xF0000) >> 16);
}
Code:
   // Then you can you this code to send response to ECM:
   const auto hash = p3_hash(pin, seed);
   uint8_t hash_array[4];
   hash_array[0] = hash & 0xFF;
   hash_array[1] = (hash >> 8) & 0xFF;
   hash_array[2] = (hash >> 16) & 0xFF;
   hash_array[3] = (hash >> 24) & 0xFF;
                WriteDataToChannel_402420(
                  ChannelId_40E00C,
                  7,
                  0xE0,
                  5,
                  0x27,
                  2,
                  hash_array[0],
                  hash_array[1],
                  hash_array[2],
                  hash_array[3],
                  0);

Logged

Россия - Великая страна!
https://youtu.be/fup5GzIFdXk
dikidera
Full Member
***

Karma: +8/-8
Offline Offline

Posts: 149


« Reply #37 on: December 24, 2023, 09:09:53 AM »

If I had a P3 car I could have contributed more with a fat IDB, it would be most difficult without a DHA, but this has never stopped me into sinking hundreds even thousands of hours into reverse engineering a project.
Logged
prometey1982
Sr. Member
****

Karma: +70/-60
Offline Offline

Posts: 323



WWW
« Reply #38 on: December 25, 2023, 02:06:35 PM »

ME9 is not simple as Denso T6 ECM. ME9 has 5 digit PIN code. For example here one my firmware for ME9:
Code:
ROM:000029C0 pin_29C0:       .byte 0x70, 8, 0, 0x82, 0x47

// This value is passed to check key function:

void __fastcall sub_90D0C(int a1, char **a2)
{
  char *v3; // r3
  int v4; // r5
  int v5; // r29
  int v6; // r29
  int v7; // r3
  char v8; // r31
  unsigned __int8 v9[4]; // [sp+8h] [-10h] BYREF

  if ( byte_800004 )
  {
    v8 = 54;
    goto LABEL_25;
  }
  if ( byte_800005 )
  {
    v8 = 55;
    goto LABEL_25;
  }
  v3 = *a2;
  v4 = (unsigned __int8)**a2;
  if ( (v4 & 1) == 0 )
  {
    if ( v4 == 2 )
    {
      if ( *((_WORD *)a2 + 3) == 4 )
      {
        if ( ((HIBYTE(flt_8076FC) >> 1) & 1) != 0 )
        {
          HIBYTE(flt_8076FC) &= 0xFDu;
          v9[0] = v3[1];
          v9[1] = (*a2)[2];
          v9[2] = (*a2)[3];
[b]          if ( checkKey_9B580(pin_29C0, seed, v9) )
[/b]          {
            sub_967C8(1);
            *((_BYTE *)a2 + 10) = 1;
            *((_WORD *)a2 + 4) = 1;
            return;
          }
          byte_800004 = 1;
          byte_800005 = 100;
          byte_800006 = 100;
          v8 = 53;
        }
        else
        {
          v8 = 36;
        }
      }
      else
      {
        v8 = 19;
      }
      goto LABEL_25;
    }
    goto LABEL_22;
  }
  if ( v4 != 1 )
  {
LABEL_22:
    v8 = 18;
    goto LABEL_25;
  }
  if ( *((_WORD *)a2 + 3) != 1 )
  {
    v8 = 19;
LABEL_25:
    **a2 = v8;
    *((_WORD *)a2 + 4) = 1;
    *((_BYTE *)a2 + 10) = 2;
    return;
  }
  if ( (unsigned __int8)sub_967EC() == 1 )
  {
    v5 = 0;
  }
  else
  {
    v6 = seed;
    do
    {
      do
        v7 = sub_9B55C();
      while ( v6 == v7 );
    }
    while ( (v7 & 0xFFFFFF) == 0 );
    v5 = v7 & 0xFFFFFF;
  }
  seed = v5;
  HIBYTE(flt_8076FC) |= 2u;
  (*a2)[1] = v5;
  (*a2)[2] = BYTE2(v5);
  (*a2)[3] = BYTE1(v5);
  *((_BYTE *)a2 + 10) = 1;
  *((_WORD *)a2 + 4) = 4;
}


So it's not easy to find key by bruteforce. I found some analysis of CEM PIN code from SPA platform https://v-spa.net/forum/viewtopic.php?p=245#p245
maybe ME9 ECM has similar limitations on PIN.
Logged

Россия - Великая страна!
https://youtu.be/fup5GzIFdXk
Pages: 1 2 [3]
  Print  
 
Jump to:  

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines Page created in 0.019 seconds with 17 queries. (Pretty URLs adds 0s, 0q)