Login Register

Vida CEM swapping

A mid-size luxury crossover SUV, the Volvo XC90 made its debut in 2002 at the Detroit Motor Show. Recognized for its safety, practicality, and comfort, the XC90 is a popular vehicle around the world. The XC90 proved to be very popular, and very good for Volvo's sales numbers, since its introduction in model year 2003 (North America). P2 platform.
Post Reply
dikidera
Posts: 1304
Joined: 15 August 2022
Year and Model: S60 2005
Location: Galaxy far far away
Has thanked: 67 times
Been thanked: 175 times

Re: Vida CEM swapping

Post by dikidera »

MY2005 with 500kbps CEM with chassis ID 483189.

A while back I also bought a 2.5 head with Dual VVT, but it's the head where the VVT solenoids face each other.

https://cdn.izap24.ru/images/prodacts/s ... 5254t2.jpg

So from a B5254T2 most likely. Since this was a while back, the car is no longer available, all that is left is to research which harness cable and ECM combination, apart from said motor, are compatible.

T5Luke
Posts: 142
Joined: 11 November 2020
Year and Model: S60 T5 2001
Location: DE
Has thanked: 11 times
Been thanked: 130 times

Post by T5Luke »

So you should buy a used ECM which was build in a car with same engine configuration. MY of donor car should be 2005- . About the automatic gearbox module i'm not 100% certain, it could be yours will work, otherwise just buy another module of a car with same engine type and same MY 2005- , all modules from 2005 and up are compatible to each other, it is easier to buy modules with software on than software for modules...

T5Luke
Posts: 142
Joined: 11 November 2020
Year and Model: S60 T5 2001
Location: DE
Has thanked: 11 times
Been thanked: 130 times

Post by T5Luke »

ECM you need should be 30668478A 0261208289
some standard Bosch petrol ETM. The rest should stay the same. About the TCM i'm not 100% certain but think it should also stay...

User avatar
prometey1982
Posts: 46
Joined: 5 June 2021
Year and Model: 2010 XC90
Location: Novosibirsk
Has thanked: 4 times
Been thanked: 5 times
Contact:

Post by prometey1982 »

Just by EC.2 ECM and 29.1 version of TCM. It's hardware numbers. TCM can be flashed for your type of gearbox. ECM too. And you already have 29.1 TCM. Just buy an ECM. I'll flash needed version to your ECM.
Они просто сдохнут, а мы попадем в рай.

dikidera
Posts: 1304
Joined: 15 August 2022
Year and Model: S60 2005
Location: Galaxy far far away
Has thanked: 67 times
Been thanked: 175 times

Post by dikidera »

The Denso ECU is employing quite a lot of obfuscation. Even such where it modifies the return value in the stack to trick the control flow.

And address FFFF7448 is at the heart of all this. It almost feels like a mini virtual machine simply because anytime this address comes up it's in a function/handler which saves the entire registers of the CPU, all of them. It's setup in routine 0x200c and code jumps to 0xc3a0 without being easily identified unless you do dynamic execution.

Even if it's not a VM, almost all interrupts are handled by a function which includes address FFFF7448. Several versions of the function exist for specific use-cases so it's not super generic like most "VMEnter" I have seen which contain a single Prologue and dispatch to handlers, this is just a general overview and not very specific.

I am attaching the most recent and up-to-date so far IDB of the results so far of my research.
I have seen that the sensors are updated when an Interrupt is generated on the ADC channels, although I have yet to see how and where it checks the specific source, however I saw that it immediately converts the data from the ADC to usable data, but only depending on specific flags set at RAM address FFFF96B6 which is why I've named it in that name.

The flow is the following. An interrupt is generated by an on chip module. A generic handler is located at the custom vector table, this generic handler has a specific offsets associated with the type of interrupt, this number is multiplied by 4.
Remember when I said the address FFFF7448 is accessed by specialized functions? This generic handler for a portion of the interrupt vectors has a 2 or 3 special offsets.

Code: Select all

    mov.l   #SomeFunctionTable_FFFF7448, r0
                mov.l   #0x84, r12
                mov.l   @(r0,r12), r11
                shll2   r14
                tst     r11, r11
                bf      loc_2746
0x84 is again some flag.

But furher down is our most important part

Code: Select all

 ldc     r13, sr
                mov.l   #SomeFunctionTable_FFFF7448, r1
                mov.l   @(0x38,r1), r0
                mov.l   @(r0,r14), r0
                jsr     @r0
                nop
FFFF7448 + 0x38 = an address 3081a4, which points to a table full of the actual handlers. Then 3081a4 + handler_offset*4 = actual_handler.

Looking at the handler which updates our very very important variables,

Code: Select all

mov.l   #MAP_Sensor_FFFF9676, r6
                mov.l   #adc_convert_opt???_FFFF96B6, r3
Address FFFF96B6 seems to specify IF only the MAP sensor is updated, OR a function is executed which increments r6 by 2 and does bulk update+conversion.

Code: Select all

loc_A584:                               ! CODE XREF: convert_analog_to_digital_sub_A578+1C↓j
                mov.w   @r4+, r3
                add     #1, r7
                extu.w  r3, r3
                shlr2   r3
                shlr2   r3
                shlr2   r3
                mov.w   r3, @r6
                cmp/hs  r0, r7
                bf/s    loc_A584
                add     #2, r6
So I think this is how it mostly works....but remember, at some point FFFF96B6 will specify single update for every interrupt which means the variables might get updated elsewere in a different way.

Now, according to the docs, interrupt sources for HCAN0 and HCAN1 are 222 and 230 respectively. Multiplied by 4, I arrive at two handlers in the vector table, one is for HCAN0 and is an empty loop waiting for a different interrupt to take hold, but HCAN1 is different. I find this very very odd, because it is HCAN0 which for instance is read for processing of bootloader commands...unless it is operating in a single 32-bit buffer mode. But I am unsure if this means that HCAN1 and HCAN0 can be transparently used.

Moving on, if HCAN1 interrupt is the origin of processing bootloader and later, D2 commands, then the flow seems to be:
HCAN1 interrupt -> generic/global interrupt handler->HCAN1 handler which is located at 0xB720, from there it is almost certain it jumps to a function that is executed on startup, which is 0xB748 and is part of the main startup sequence when the ECU is first powered on. Of course the functions there re-initialize the CPU so it's not direct CAN message handling, it must happen waaay wayyy deep.
Attachments
Volvo 64F7055 Flash ORI BIFUEL.bin.idb.7z
(1.92 MiB) Downloaded 81 times

oscilloscope
Posts: 285
Joined: 20 May 2022
Year and Model: 2005
Location: uk
Has thanked: 27 times
Been thanked: 11 times

Post by oscilloscope »

all so i am messing around with chatGPT to see what it can do , and to see if i can get it to make a small application in python to decrypt a .bin file from a cem unit i have here which i am aware is encrypted. so far it would appear the decryption method given on here a while ago. doesn't seem to like being used in this manner. here is the code

import tkinter as tk
from tkinter import filedialog
import hashlib

def decrypt_file():
# Load the file contents
file_path = file_path_var.get()
with open(file_path, 'rb') as f:
file_data = f.read()

# Decrypt the file
key = 'my_secret_key'
crypto_key = hashlib.md5(key.encode()).digest()
len_data = len(file_data)
decrypted_data = bytearray()
for i in range(len_data):
decrypted_data.append(file_data ^ crypto_key[i % 0x3d] ^ (i // 7))

# Save the decrypted file
save_path = filedialog.asksaveasfilename(defaultextension='.bin')
if save_path:
with open(save_path, 'wb') as f:
f.write(decrypted_data)
status_label.config(text='File decrypted and saved: ' + save_path)
else:
status_label.config(text='File decryption canceled.')

def select_file():
# Prompt the user to select a .bin file
file_path = filedialog.askopenfilename(filetypes=[('Binary files', '*.bin')])
if file_path:
file_path_var.set(file_path)
decrypt_button.config(state='normal')
status_label.config(text='Selected file: ' + file_path)

# Create the GUI
root = tk.Tk()
root.title('File Decryptor')

file_path_var = tk.StringVar()
file_path_var.set('')
status_label = tk.Label(root, text='Please select a .bin file to decrypt.')
status_label.pack()

file_button = tk.Button(root, text='Select File', command=select_file)
file_button.pack(pady=10)

decrypt_button = tk.Button(root, text='Decrypt File', command=decrypt_file, state='disabled')
decrypt_button.pack(pady=10)

root.mainloop()

dikidera
Posts: 1304
Joined: 15 August 2022
Year and Model: S60 2005
Location: Galaxy far far away
Has thanked: 67 times
Been thanked: 175 times

Post by dikidera »

Because I am simply unfamiliar, I know that the immobilizer key is in the CEM, but is there a copy of it on the ECU as well?

I got my Bosch ECU and simply wish to be informed on how to handle the possible immo key mismatch.

oscilloscope
Posts: 285
Joined: 20 May 2022
Year and Model: 2005
Location: uk
Has thanked: 27 times
Been thanked: 11 times

Post by oscilloscope »

dikidera wrote: 08 Mar 2023, 02:31 Because I am simply unfamiliar, I know that the immobilizer key is in the CEM, but is there a copy of it on the ECU as well?

I got my Bosch ECU and simply wish to be informed on how to handle the possible immo key mismatch.
I think someone mentioned that some ecu variants do hold a copy of the key. But it was quite some pages back.

Or are you referring too what I wrote above ?

vtl
Posts: 4724
Joined: 16 August 2012
Year and Model: 2005 XC70
Location: Boston
Has thanked: 114 times
Been thanked: 603 times

Post by vtl »

ECM and CEM need to be "synchronized", otherwise no start.

dikidera
Posts: 1304
Joined: 15 August 2022
Year and Model: S60 2005
Location: Galaxy far far away
Has thanked: 67 times
Been thanked: 175 times

Post by dikidera »

Which would be the immobilizer key, yes? So I need to dump my CEM, the EEPROM? Copy that key to the ECU? I probably generalized the steps, but I am not sure what the steps are.

Post Reply
  • Similar Topics
    Replies
    Views
    Last post