OBDX Development - Developer Tools and Suggestions

Programs / Tools / Scripts
kur4o
Posts: 1044
Joined: Sun Apr 10, 2016 9:20 pm

Re: OBDX Development - Developer Tools and Suggestions

Post by kur4o »

I think that the key logic resides within pcm code. A full binary may be used to reverse engineer it.
It gets a free rolling counter as seed, calculates key on its own and if there is a match proceed.
With FEPS do you need to cycle ignition, like the sci chrysler stuff[There is 20v I think, pulsing on sci pins].
User avatar
Tazzi
Posts: 3550
Joined: Thu May 17, 2012 8:53 pm
cars: VE SS Ute
Location: WA
Contact:

Re: OBDX Development - Developer Tools and Suggestions

Post by Tazzi »

kur4o wrote:I think that the key logic resides within pcm code. A full binary may be used to reverse engineer it.
It gets a free rolling counter as seed, calculates key on its own and if there is a match proceed.
With FEPS do you need to cycle ignition, like the sci chrysler stuff[There is 20v I think, pulsing on sci pins].
Thats correct, it is a rolling key. Mine does roll, but only 1 byte changes.

I can always decompile the code and just do it that way. So if you have a full dump, I could always look through that.

As for FEPs, yes I do need to ignition cycle. Basically FEPS on, ignition off, then ignition on, and it 'should' be in its bootloader mode.
Your Local Aussie Reverse Engineer
Contact for Software/Hardware development and Reverse Engineering
Site:https://www.envyouscustoms.com
Mob:+61406 140 726
Image
User avatar
Tazzi
Posts: 3550
Joined: Thu May 17, 2012 8:53 pm
cars: VE SS Ute
Location: WA
Contact:

Re: OBDX Development - Developer Tools and Suggestions

Post by Tazzi »

Well.. this should help... so... I am on the right path!! :D
FordECUAlgosEECV.PNG
FordECUAlgosEECV.PNG (10.29 KiB) Viewed 1458 times
*edit
It appears it passes a name which is actually a unique value which indicates which algo to use.

Theres a bunch of other parameters. Realistically I would want to step through the code to see what is being send in and sent out.

I did see under a few subfunctions for different algos that it used XOR. So I am wondering if the 2byte stuff is just a simple XOR.
Your Local Aussie Reverse Engineer
Contact for Software/Hardware development and Reverse Engineering
Site:https://www.envyouscustoms.com
Mob:+61406 140 726
Image
In-Tech
Posts: 785
Joined: Mon Mar 09, 2020 4:35 pm
Location: California

Re: OBDX Development - Developer Tools and Suggestions

Post by In-Tech »

Hiya Folks,
The conglomeration of ideas and testing... I really think this will end up super stupid/smart/simple when we get there. At the end of the day it's just us understanding the required protocol.

I am out for the night. 1:39am for me. I bet it's all simple if we can just log enough data for comparison/learning.
User avatar
Tazzi
Posts: 3550
Joined: Thu May 17, 2012 8:53 pm
cars: VE SS Ute
Location: WA
Contact:

Re: OBDX Development - Developer Tools and Suggestions

Post by Tazzi »

In-Tech wrote:Hiya Folks,
The conglomeration of ideas and testing... I really think this will end up super stupid/smart/simple when we get there. At the end of the day it's just us understanding the required protocol.

I am out for the night. 1:39am for me. I bet it's all simple if we can just log enough data for comparison/learning.
Yeah I dont function tool well at early mornings either :lol:

Going through the security function that has the EECV defined, it does look like there is a bit going on. Since Im trying to do this with minimal time spent, I think generating all 65k combinations will be a faster and smarter outcome, that way a lookup table can just be used.

The function I can attach to shows the following:
undefined SECALG_ComputeSecurityKey(int SecurityType,undefined1 *param_2,undefined2 param_3,undefined3 param_4,undefined4 param_5,
undefined5 param_6)

I know the first parameter is an integer, as it compares the value against predefined names (What I screenshot previously), where value of 1000 (0x3E8) is for the EECV's.
Its understanding what the rest of the values are.

I believe the return function value is a pointer, but I will need to step through this function being used to better understand what is going on.

One of the more effective methods is making a little shim dll that will sit in its place. This will allow seeing what data is being passed into the function which can be matched up with the seed passed in and other details found.

A guess at some of the other parameters:
1) Seed bytes (Could be in an array, Maybe param2?)
2) Security level (1,3,5 ect).
3) Fix bytes (what is normally used for 3byte).

There is usually 5bytes used for the fix. this could be passed as a pointer to a array.

Next step forward is either to either see if my Ford ecus on the bench also call to this function (Which I believe they do), and then log what is being passed into the function. so that it can be replicated for EECV.


I do see something of interest although again, I am not 100% certain yet what exactly is being passed in.:

Code: Select all

undefined4 __fastcall FUN_10001400(int param_1)

{
  ushort uVar1; //16bit
  int iVar2; //32bit signed
  
  if (1 < *(uint *)(param_1 + 0x10c)) { //if 1 < *PointerValue(Param1+0x10C)
    iVar2 = ((uint)*(ushort *)(param_1 + 8) * 2 + -0xfd) * (uint)*(ushort *)(param_1 + 8); //(*PointerValue(Param1+8) *2 -0xFD) * (*PointerValue(Param1+8)  
    uVar1 = (ushort)(iVar2 >> 0x1f); //shift 0x1F bits right
    **(short **)(param_1 + 4) = ((ushort)iVar2 ^ uVar1) - uVar1; //store key at offset 4 0
  }
  return DAT_1000d10c; //value is 2
}
I believe this is the EECV algorithm. I have added some of my own comments here.
A memory array of 0x10C is alloated, I believe our first if statement is validating that it does have the memory space available.

This next part is where it gets a little hazy due to the memory pointer not being exactly well descrived.
My understanding here is the seed which is 2bytes, or also titled as ushort, is stroed at offset 8 in the memory pointer.
It then multiples by 2, minus 0xFD, then multiple by the original value. This value is then shifted 0x1F to the right (31 bits).
Finally we do an XOR between the two variables then stores the key at offset 0x4 of the pointer.
Your Local Aussie Reverse Engineer
Contact for Software/Hardware development and Reverse Engineering
Site:https://www.envyouscustoms.com
Mob:+61406 140 726
Image
User avatar
Tazzi
Posts: 3550
Joined: Thu May 17, 2012 8:53 pm
cars: VE SS Ute
Location: WA
Contact:

Re: OBDX Development - Developer Tools and Suggestions

Post by Tazzi »

I know I am so damn close here.

Using the example from Intech:
Seed: EF F1
Key: 64 BE

var2 = EF F1*2 - FD * EFF1 = C0DA A095 (4bytes max).
var 1 = C0DA A095 >> 1F (Circular shift right) = 81B5412B
Keys = Var2 XOR var1 -var1 = (A095 XOR 412B) - 412B = A093

So.. not the right answer... but A095 XOR 412B = E1BE..... second byte is correct. Could be a coincidence.

*Edit, I think the legacy EECV might be what my AU falcon ECU uses.... so If I did an example of seed 003E..

var2 = 003E*2 - FD * 003D = 1EC2 = FFFF E0C9 (Since var2 is an int, it can be negative)
var1 = FFFF E0C9 >> 1F = FFFFC193
keys = E0C9 XOR C193 = 215A
Your Local Aussie Reverse Engineer
Contact for Software/Hardware development and Reverse Engineering
Site:https://www.envyouscustoms.com
Mob:+61406 140 726
Image
User avatar
Tazzi
Posts: 3550
Joined: Thu May 17, 2012 8:53 pm
cars: VE SS Ute
Location: WA
Contact:

Re: OBDX Development - Developer Tools and Suggestions

Post by Tazzi »

There is another calc which is labelled as EECV (Not LegacyEECV), its quite a bit longer, so itll take a bit longer to work out:

Part 1:

Code: Select all

uint __fastcall EECV_NormalCalc(int param_1)

{
  uint uVar1;
  undefined8 uVar2;
  
  uVar1 = 0;
  if (DAT_1000d10c <= *(int *)(param_1 + 0x10c)) {
    uVar2 = (**(code **)**(undefined4 **)(param_1 + 0x218))();
    uVar1 = (uint)uVar2;
    if (0 < (int)uVar1) {
      FUN_10001020(param_1,(uint)((ulonglong)uVar2 >> 0x20),*(undefined4 **)(param_1 + 4),uVar1);
    }
  }
  return uVar1;
}
Then inside FUN_10001020 we have:

Code: Select all

void __fastcall FUN_10001020(undefined4 param_1,uint param_2,undefined4 *param_3,uint param_4)

{
  int iVar1;
  byte *pbVar2;
  uint extraout_EDX;
  undefined in_stack_fffffef8;
  uint local_8;
  
  local_8 = DAT_1000d388 ^ (uint)&stack0xfffffffc;
  iVar1 = param_4 - 1;
  if (-1 < iVar1) {
    pbVar2 = &stack0xfffffef7 + (param_4 - iVar1);
    do {
      param_2 = param_2 & 0xffffff00 | (uint)*(byte *)((int)param_3 + iVar1);
      *pbVar2 = *(byte *)((int)param_3 + iVar1);
      pbVar2 = pbVar2 + 1;
      iVar1 = iVar1 + -1;
    } while (-1 < iVar1);
  }
  if (0 < (int)param_4) {
    FUN_10002650(param_3,(undefined4 *)&stack0xfffffef8,param_4);
    param_2 = extraout_EDX;
  }
  FUN_10002638(local_8 ^ (uint)&stack0xfffffffc,param_2,in_stack_fffffef8);
  return;
}
Obviously theres also the functions inside the second one there to go through too. Quite a bit to decipher. But I believe I am onto the right track now.
Your Local Aussie Reverse Engineer
Contact for Software/Hardware development and Reverse Engineering
Site:https://www.envyouscustoms.com
Mob:+61406 140 726
Image
In-Tech
Posts: 785
Joined: Mon Mar 09, 2020 4:35 pm
Location: California

Re: OBDX Development - Developer Tools and Suggestions

Post by In-Tech »

Watching some stuff I don't quite get but it might throw a light on.

$31 'Perform Diagnostic Routine by Test Number' message with a test number of $A0 with four additional data bytes where XX looks to = the seed byte for the seed returned???
So, it appears you can seed the seed byte returned and the 3rd byte is added or XOR'd to the seed to calculate the key. I dunno, there is definately some trickery going on.

31 A0 00 D8 XX 00

$58 = 88 kb Flash
$70 = 112 kb Flash
$D8 = 224 kb Flash
User avatar
Tazzi
Posts: 3550
Joined: Thu May 17, 2012 8:53 pm
cars: VE SS Ute
Location: WA
Contact:

Re: OBDX Development - Developer Tools and Suggestions

Post by Tazzi »

Do you have a whole log of what is going on there?
Maybe the older EECVs do something funky with mode 31.

Im assuming the D8 is indicating the flash size in that frame. If thats the case, mine indicates:
C4 10 F5 31 A0 00 D8 39 01
So this would suggest 224Kb also.

Do the last two bytes change each time for you?
Your Local Aussie Reverse Engineer
Contact for Software/Hardware development and Reverse Engineering
Site:https://www.envyouscustoms.com
Mob:+61406 140 726
Image
In-Tech
Posts: 785
Joined: Mon Mar 09, 2020 4:35 pm
Location: California

Re: OBDX Development - Developer Tools and Suggestions

Post by In-Tech »

Tazzi wrote:Im assuming the D8 is indicating the flash size in that frame. If thats the case, mine indicates:
C4 10 F5 31 A0 00 D8 39 01 9F
So this would suggest 224Kb also.
I'm going to run some more tests shortly, I wasn't really watching earlier. I am looking through notes I saved that made no sense at the time. I tend to keep those cuz maybe it will some day. Is that today? :) See if your 9f xor'd or subtracted from FF makes the seed/key work.
Post Reply