MEMS3 Firmware Immobiliser Delete –
Including Rover 75 / MG ZT / Freelander BMW EWS 3.D
Download
Link: https://andrewrevill.co.uk/Downloads/MEMSTools.zip
Using my MEMS Mapper you can now
easily delete the immobiliser functionality, even with the BMW EWS 3.D secure immobiliser
system.
This is something that quite a few people
have asked me for. For ECUs that are set up to use the Lucas 5AS or Pektron
immobiliser systems, there is a scalar in the map which allows the ECU to run
without needing a coded signal from an immobiliser. For ECUs that are set up to
use the BMW EWS 3.D immobiliser system, this does not work. These ECUs are
found in some Rover 75, MG ZT and Land Rover Freelander models. Once the ECU
has been paired with one BME EWS immobiliser, it cannot be paired with another.
This makes it very difficult to replace ECUs, either in case of failure or when
doing turbo conversions and engine swaps etc. People have been asking me if it
was possible to replace the BMW EWS functionality in the ECU with the equivalent
Lucas 5AS routines (too complicated at the moment!) or alternatively to delete
the immobiliser functionality altogether, leaving the ECU set to “free run”.
By following the instruction below, you
will be able disable the immobiliser functionality in any MEMS3 ECU with any
immobiliser system.
Basic Instructions
You will need to download the latest
version (5.54 or later) of my MEMS Tools from here: https://andrewrevill.co.uk/Downloads/MEMSTools.zip
Using this version, perform a full read
(both Firmware & Map) from the
ECU.
Finding the immobiliser code which needs
to be modified is a little bit complicated, so I’ve added a wizard to do it for
you.
Click Tools, Wizards, Firmware
Immobiliser Delete and you should see a dialog like this:
If there are three green tick marks
shown, the wizard has been able to trace the immobiliser code (it finds them
correctly in every unmodified firmware that I’ve ever seen).
Check Delete Immobiliser Functionality and then click OK.
This deletes the immobiliser
functionality in the current project in MEMS Mapper – you now need to write
the Firmware & Map back to the ECU in the normal way.
Technical Details
All of the ECUs fuelling calculations end
up with one single number – the injector pulse width. This is the time for
which the injector needs to be open in order to inject an appropriate quantity
of fuel. One of the very last things the ECU does is to check a number of flags
which control engine immobilisation under different conditions (some of which
were related to factory development mode code). If any of these flags result in
immobilisation being disabled, it skips over the critical instruction,
otherwise it overwrites the calculated injector pulse width with 0, meaning
that the injector is open for zero time (doesn’t open at all). You can see the
various tests being done here in green in a ksr3p004, NNN000160 VVC 160 ECU. The instruction that
effectively immobilises the engine is shown in yellow.
LAB_00130382
00130382 08 38
00 btst.b 0x7
,(BYTE_0000131f ).w
07 13 1f
00130388 66 08
bne.b LAB_00130392
0013038a 08 38
00 btst.b 0x7
,(varBitFlags1323 ).w
07 13 23
00130390 67 14
beq.b LAB_001303a6
LAB_00130392
00130392 08 38
00 btst.b 0x7
,(BYTE_0000131a ).w
07 13 1a
00130398 66 0c
bne.b LAB_001303a6
0013039a 21 bc
00 move.l
#0x0 ,(BYTE_000009b8 ,-,D0w *0x4 )
00 00 00
05
a0 09 b8
001303a4 60 06
bra.b LAB_001303ac
LAB_001303a6
The instruction show in blue is the last chance to
skip over the instruction. It’s a “conditional branch” instruction “bne” which
means “jump forward by a set number of instructions if the bit tested in the
last test was 1”.
Engine immobilisation can be disabled
simply by changing this one instruction from a “conditional branch” instruction
“bne” (branch if not equal) to an “unconditional branch” instruction “bra”
(branch always). This means changing a single byte from $66 to $60 and means
that the immobilisation instruction is always skipped, irrespective of the
immobilisation flags.
The complicated part is finding this
particular instruction, as it will be at a different memory address in every
different MEMS3 firmware version (of which there were hundreds), and there will
be many very similar instructions throughout the firmware. The good news is
that the code was highly conserved right across the MEMS3 product line and
therefore we know what we are looking for and know what to do with it when we
find it.
In my article on TestBook T4 (Main Dealer) Level Support for MEMS3
I described how I was using Service $21 "Request Data By Local ID" to
request live data from the ECU. Inside the firmware there is a table of
definitions, listing the fields (mostly RAM variable addresses) for the
response record for each local identifier. My code searches for this table by
scanning the whole firmware for instructions of the form LEA (NNNNNN).L,AN.
Whenever it finds one, it examines the address loaded to see if it looks like
it points to the table. It puts some pretty tough conditions on what can and
cannot be considered to be the table so it should get it right every time. It
tries to walk the whole table from start to end and only accepts it if it finds
plausible records all the way through, the expected $FFFF “end of table marker”
at the end, no duplicate identifiers and all of the mandatory record
identifiers expected.
Once it’s found that, it extracts the
Injector 1 Pulse Width variable address from the record definition for
identifier $0C and then scans the firmware for a conditional branch followed
immediately by the instruction that zeroes that out, as shown above.