Jump to content
Click here if you are having website access problems ×

Decoding & Cloning The Lucas 5AS Immobiliser - PART II ADDED


revilla

Recommended Posts

So for my next challenge…

100_0.jpg.12971c9d9a95b0c896d9a41b3003f5ec.jpg

Not my photograph - https://blackbox-solutions.com/help/SM034_ecu.jpg

The Lucas 5AS Immobiliser as used with the K Series engine comes in a number of different flavours. With the correct tools it is highly configurable. However, other than for matching remote key fobs and changing the EKA code, the tools with are able to configure the 5AS are generally very expensive and very hard to come by, e.g. the Rover Testbook T4 system. These are beyond the reach of individual owners wishing simply to change configuration settings.

The immobiliser in my car is configured for passive arming. After a period of approximately 10 minutes has elapsed after turning off the ignition switch, the immobiliser arms itself automatically. The alarm functionality of the 5AS does not arm unless manually armed by the key fob, but the engine is immobilised. I planned to do some modifications to implement the alarm functionality which is not generally present in a Caterham and for this it was important for me to retain the passive arming of the immobiliser and I was happy with the way it was configured.

I have a few spare immobiliser units, mostly picked up cheap on eBay with unknown histories and from unknown donor cars, with a variety of different configurations, some of which do arm passively and some which do not. They all arm after a few seconds of turning off the ignition switch and the opening and closing the driver’s door (in a Rover! I tested this functionality by wiring up a mock door switch) but the passive arming in a Caterham setup was inconsistent. They also displayed quite a range of different behaviours in terms of the dash LED signalling, how they responded when the key fob battery was getting low (some gave a visual warning by flashing the LED rapidly, some did not, and some required two presses of the key fob each time to bring the low battery to the attention of the user, some did not). Ideally I would like to modify or configure all of the spare immobilisers to work exactly like the one in my car as spares as I was completely happy with all of the settings and behaviours of this one. But as described above, there is no easy way to access the settings.

One possibility would be to access the EEPROM memory (non-volatile memory inside the microcontroller chip in the immobiliser) directly. The main problem with this approach is simply that there is simply no way for me to know which memory addresses correspond to which settings and how the values for the various configuration settings are stored. What I could do though would be to copy the entire EEPROM contents across from one immobiliser to another, hopefully transferring all settings without having to understand them. However, this would mean that all of my immobilisers would probably then have the same “unique” MEMS codes and “secret” EKA codes. Now this could be seen as an advantage as I would be able to swap immobilisers without having to code them into the ECU again, but if I were ever to sell one or do the same modifications for somebody else, I wouldn’t want to be handing out immobilisers which would run my car without coding, and since I have key programming tools which make it easy to code an immobiliser into an ECU I really wanted to do it properly - copy all settings but preserve the original serial number and MEMS and EKA codes. The serial number is printed on the label of the 5AS so should be easy enough to find in the EEPROM data and the EKA code is readable with a key programmer but the MEMS code is only accessible through the coded signal sent to the MEMS3 ECU. Other than by attempting to decode this signal, there is no easy way that I know of to know what the MEMS code for a given immobiliser is and therefore no way to know what to look for in the EEPROM data.

Now at this point you may be wondering why I don’t just take a spare immobiliser to somebody who has a T4 and can reprogram it for me and give him £25? Well I have to admit that part of it is just that I like a challenge, and the tougher the better. But I firmly believe that the more we can as a community understand and document the systems on our cars, the better we will be able to support them in the longer term when the experts have packed up and gone home. There is precious little information out there on the web at the moment about the detailed working of the standard engine management and immobiliser systems on the K Series. For my liking there are far too many cases on the various Rover forums where questions about particular systems just come to the conclusion that “X is your man”, and X happily fixes things for a wad of cash and keeps the information on how he did it very close to his chest indeed. I would much rather know how to produce a spare immobiliser to the required specification at will than just have a spare immobiliser of the required specification.

Hacking these systems is always a bit like trying to get the cellophane wrapper off a CD … once you’ve got one edge up it’s a lot easier to get the rest off.

So I set about the challenge of cracking the encoding of the signals passed from the 5AS immobiliser to the MEMS3 ECU from first principles. From what I can see, the signal encoding is identical for all 5AS units and all generations of Rover MEMS engine management. My test cases include six 5AS immobilisers and an assortment of MEMS3 ECUs, mostly VVC 160 but also Rover 214 and 216.

From the sample I have here, and from one or two others I’ve looked at, the 5AS immobiliser comes in two major flavours. The later ones are referred to as “98MY”. My guess would be that this refers to “Model Year” but I have one 98MY unit with a date code of 28/96 (Week 28, 1996) stamped on the front label and an earlier non-98MY unit with a date code of 39/97, so I’m really not sure how the transition between the two occurred. All of those with date codes later than 1998 seem to be reliably 98MY variants. As far as I can tell, all of the later 98MY immobilisers are for all practical purposes identical from a hardware perspective. All of my 98MY immobilisers had a part number of YWC106240 but I’m sure there are other part numbers which differ only in configuration. The circuit boards seem only to differ in cosmetic ways and the only variations I have seen in the components mounted on the board look to be just variations between different suppliers of essentially the same generic components. The pre-98MY immobilisers seem to show more variation. Very early units only had a single connector socket, but even between dual socket units I can see variations in the exact microcontroller chip used, with different part numbers and mask codes. The microcontroller chips on all 98MY immobilisers that I have seen have been Motorola ZC503347CFN, stamped with Lucas 53873824 and a mask code of 0D60J.

400.thumb.jpg.9ff0b77b9ff60a41c5c7f3a804e51e28.jpg

For these reasons, I have decided to focus on the 98MY immobilisers. I am reasonably confident at this point that the EEPROM contents should be transferable between units and should work properly with any firmware and hardware on the new unit. The message decoding work I have documented below is applicable to all variants, but I’m only going to try to transfer EEPROM settings between 98MY variants.

500_0.thumb.jpg.de5228158e9e4e91f1ecb43547583519.jpg

Research on the Internet identifies the ZC503347CFN microcontroller used as a Motorola MC68HC05B16. The mask code 0D60J refers to the minor revision (I believe that minor revisions were made to the chip designs to fix issues, and that the detailed hardware behaviour may vary slightly in certain documented cases between processors with different mask codes). These are very much a “Computer on a Chip” and the 5AS circuit board contains little else other than some generic HC logic “glue”, ULN2003 driver chips, power supply circuitry, the radio receiver module and various bits that look to be associated with driving external circuits, such as a large power MOSFET, some power diodes and a couple of relays. There do not appear to be any other programmable memory elements so all settings must be stored within the microcontroller in the internal EEPROM.

The MC68HC05B16 contains mask-programmed ROM, which is basically memory which is pre-programmed as part of the design and manufacturing process and cannot subsequently be modified. My assumption is that the “Lucas 53873824” stamping on the chip identifies the ROM program which will have been developed by Lucas and supplied to Motorola for programming during manufacture. I’m hoping that as all of my immobilisers are stamped “Lucas 53873824”, the programming will be identical and therefore the EEPROM contents will be compatible.

The MC68HC05B16 also has a built in security mechanism to protect the internal memory contents from external access using programmers etc. Being a complete “Computer on a Chip”, there is no need for the internal data to be externally accessible in normal operation; the code on the device supports external programming of options and settings as required through communications interfaces and does not make the internal storage of these available. The microcontroller can operate normally in “user mode” or be switched into “non-user” or “test” mode, which allows access to the internals. There is one bit in the first byte of the EEPROM memory which, when set, prevents the microcontroller from switching to “non-user” mode. This is designed to prevent the use of universal programmers to access the data. The idea is that the only way to reset this bit is to erase the memory, which also erases the protected data.

However, over time hardware issues have been discovered which allow certain techniques to bypass this security. The MC68HC05B16 has been found to be vulnerable to clock glitching and other fault injection attacks. These involve running the system clock, voltages or other parameters out of specification for a very short period at critical times to cause the processor to miss-execute a particular instruction, exploiting oddities in the internal timing as different transistors within the chip switch. Using such techniques it is possible to trick the microcontroller into switching into “non-user” mode even when the security bit is set. Some universal programmers such as the XPROG-M (and cheap Chinese clones of these) are able to exploit these vulnerabilities to both read and write the protected memory. With these programmers, the processes require to bypass the security are fully automated and routine, and the programmers allow access to the internal contents of secured chips almost as though there was no security implemented.

So my overall plan of attack at this stage is:

  • Open up the case.
  • Record the communications between the 5AS and MEMS3 using a digital storage oscilloscope.
  • Figure out how to decode this to discover the unique MEMS codes for my immobilisers.
  • Desolder the microcontroller and mount it in an XPROG-M programmer.
  • Bypass the microcontroller security to read the EEPROM data and save it as a .BIN (raw binary) file.
  • Find locations used for the MEMS code, EKA code and serial number in the EEPROM data.
  • Do the same for another 5AS box.
  • Update the data read from the first 5AS with the MEMS code, EKA code and serial number from the second 5AS.
  • Write the modified data to the second 5AS microcontroller.
  • Solder the microcontroller back into the second 5AS.
  • Hopefully the second 5AS will then retain its unique IDs but have all of the settings of the first.

Opening the case up was easier than it looked. There are 8 plastic clips around the edge and I thought it might be awkward to release them all at the same time, but in reality the case is flexible enough to allow you to release the clips at one end and then hold them slightly apart as you work down the sides until the case comes apart. I released each clip simply by slipping a small flat screwdriver into the clip to depress the latching tongue.

600_0.jpg.0cd2c1340aa050efd238045a021c3e97.jpg

Not my photograph - https://www.mgfcar.de/alarm_blipper/dcp_1556.jpg

The only information I really knew about the MEMS code was that it was 16 bits in size, from sites such as this: https://blackbox-solutions.com/help/SM034.html (I have since had it confirmed that the code is 16 bits in size, that any code other than 0x0000, 0xFFFF and 0xF0F0 is valid and the transmission rate is 125 bits per second).

So I connected an oscilloscope to Pin 9 of the immobiliser to record the communications between the 5AS and the ECU. All of this work was done with an immobiliser and an ECU connected to a test wiring harness on the bench for convenience but could equally be done in situ with the immobiliser plugged into the car wiring loom.

900_0.thumb.jpg.8bbcc0fc35aeb4adc2f8adcf1430a3e7.jpg

The result was clearly a digital signal, switching between a high “1” and a low “0” voltage. Initially it appeared to be just a constant data stream with no obvious beginning or end to the messages, so to make life a little easier on myself I turned off the ignition, set the oscilloscope to trigger on the voltage falling though a voltage midway between the two levels and to capture a single sweep, then turned on the ignition. The oscilloscope then captured the very first part of the communication - which I guessed represented the start of the first message. The captured waveform was as shown below. The “T” indicator at the top of the display is the trigger point. With the ignition turned off, a continuous “1” was transmitted. The trigger point is the point where the voltage first switched to a “0” and represents the start of the first message.

1000.thumb.png.0d0f7dbea1c9948c1a097e4ded9ba4c8.png

I repeated this same procedure for the six immobilisers I had to hand, and collated the waveforms as shown below, in order to look for patterns. So, what could I learn from these six waveforms?

The first thing I noticed was that they clearly all consisted of a number of “bits” of equal duration. I added the red lines in the picture below as an equally spaced grid using the Paint.NET image editor. They correspond to approximately 4ms time intervals and you can see that the transitions between the “1” and “0” levels all take place at these fixed intervals. This was the clock signal recovered from the waveform.

1100.png.486e2d90ab4265e3d8d8d5e2d744aa31.png

The second thing I noticed was that the different signals all started off in the same way, with the first 4 bits of the sequence being “0111”. This looked like some sort of message header (actually the first 5 bits of the sequence were always “01110”, but I’ll come back to that later). After that the patterns differed.

The third thing I noticed was that each of the patterns repeated after a period of time. So it didn’t look like any kind of two way conversation between the 5AS and the ECU, just a repeated broadcast of the same message by the 5AS over and over again. And there obviously wasn’t any attempt to obfuscate the message using some kind of rolling encoding (which would mean that subsequent transmissions of the same message content were encoded differently, as is done for example with remote key fobs to foil code-sniffing attacks). So I was left with the challenge of simply decoding the formatting of the message content and the encoding scheme used.

The fourth thing I noticed was that, although the first bit of each message was always a “0”, the last bit could either be a “0” or a “1”. Now I had been expecting find a standard UART-type serial signal, with “start bits” of one type and “stop bits” of the other - basically the line would sit at one level, presumably the high 5V level in this case as that is what I saw before the start of the first message, for a minimum of a set number of bit periods at the end of one message before switching to the other level to signal the start of the next message. In this case, other than being able to determine the start of the message by capturing the first transition after switching on the ignition, there was no obvious way for the ECU to break the data stream into messages.

The next thing that struck me as strange at first was that the repeat periods for the different immobilisers differed. Some patterns repeated every 36 bits, some repeated every 72 bits. This difference didn’t seem to correlate with any differences in the versions of the immobiliser or anything else I could see. One closer inspection I spotted something rather curious. In those patterns which repeated every 72 bits, the last 36 bits of the pattern were in fact simply a repeat of the first 36 bits, but inverted. So every time a “0” appeared in the first set of 36 bits, a “1” appeared in the second set of 36 bits. The last 36 bits of the pattern therefore contained no new information, and in fact the information content was repeating every 36 bits for all immobilisers, just some of them were inverting every second transmission of the message and some were not.

The repeated sequences generated by the six immobilisers are show below:

Immobiliser 1: 011100110010110010101100101100101011011100110010110010101100101100101011
Immobiliser 2: 011101010011001011010100101011010100100010101100110100101011010100101011
Immobiliser 3: 011100110011001010110100101101001101011100110011001010110100101101001101
Immobiliser 4: 011101010011010010110101010101010011011101010011010010110101010101010011
Immobiliser 5: 011100101010110010101011001010110100100011010101001101010100110101001011
Immobiliser 6: 011100110010110010110101001101001100100011001101001101001010110010110011

This set me thinking, and I realised that the only way it made sense was if the information was encoded in the transitions between levels, and not in the levels themselves. So the actual logical “1”s and “0” could be represented by “switch” or “no switch” between the levels at each clock point, rather than by the high and low voltages themselves. This would mean that for a message with an even number of transitions, the voltage at the end of the message would be the same as the voltage at the start of the message, so the second message would be starting from the same level and would be exactly the same as the first. For a message with an odd number of transitions, the voltage at the end of the message would be the inverse of the voltage at the start of the message, so the second message would be an inverted copy of the first message, the third would be the same as the first etc. This is exactly what I was seeing.

This rang a distant bell in my memory and a bit of digging on the Internet brought up the specification for NRZ-S line-encoding, often used in telecommunications. This is “Non Return to Zero, Space” encoding. “Non Return to Zero” means simply that the voltage doesn’t return to the “0” state between bits, it just switches directly between the “0” and “1” states. This has the disadvantage that, for long runs of consecutive “0”s or “1”s there are no transitions and therefore no clock signal - then sending and receiving clocks can get out of step. The “Space” part means exactly what I had worked out above - a “0” is encoded by switching between levels and a “1” is encoded by remaining at the same level at each clock interval. In this case, long runs of “0”s cause the signal to switch at every clock point which means the receiver is still able to remain synchronised to the transmitter’s clock, however long runs of “1”s still result in no transitions. In order to get around this, it is normal to insert some “0”s into the transmitted data stream according to some predefined pattern. NB: There is an alternative encoding called NRZ-M, or “Non Return to Zero, Mark” which is identical except that transitions occur for “1”s rather than “0”s. At this point I have no way of distinguishing which of these encodings may be used here, which is something I will need to bear in mind when trying to find the decoded bytes in the EEPROM data.

So it looked as though the messages being transmitted by the 5AS were 36 bit NRZ-S encoded, so the next thing I did was to decode the line-encoding to see the underlying byte streams being transmitted:

Immobiliser 1: 001101010100010100000101000101000001 001101010100010100000101000101000001
Immobiliser 2: 001100000101010001000001000001000001 001100000101010001000001000001000001
Immobiliser 3: 001101010101010000010001000100010100 001101010101010000010001000100010100
Immobiliser 4: 001100000101000100010000000000000101 001100000101000100010000000000000101
Immobiliser 5: 001101000000010100000001010000010001 001101000000010100000001010000010001
Immobiliser 6: 001101010100010100010000010100010101 001101010100010100010000010100010101

Looking at these there were now two clear patterns.

Firstly, as expected, the messages now all repeat every 36 bits. The difference between those patterns which repeated every 36 bits and those which repeated every 72 bits when line-encoded was purely a result of the encoding and whether they contained and odd or even number of transitions, as discussed previously.

Secondly, if you look the even numbered bits (numbering from 0 on the left, so the first, third, fifth, seventh bits etc.) they are all “0”, except for the third bit which is a “1” in every case. These even numbered bits were not actually part of the message as they contained no information (i.e. we know what they will be in advance, and they will be the same in every message, so they don’t tell us anything we didn’t already know). I mentioned before that it was normal to insert some fixed “0”s into the data stream for NRZ-S line-encoding according to some predefined scheme, and it looks in this case that there is simply one “0” inserted before each data bit of the message, except for the one bit in the message header which is set to “1” - and this marks the start of the message.

This solved the issue noted previously when I said there was no obvious way for the ECU to break the continuous data stream into messages. The ECU just needs to decode the NRZ-S encoding on the incoming data stream the identify which are the even numbered bits (a repeating sequence of “010000000000000000”) and which are the odd bits (the others). The actual message data is then encoded in the odd numbered bits, starting with the bit following the “1” marker in the even numbered bits.

It also resolved a point which I rather glossed over earlier, and that is why the first 5 bits of data are the same in every message, when it seems improbable that there would be a 5-bit header and a 31-bit message rather than a 4-bit header and a 32-bit message (5 and 31 not being round numbers in computer binary terms as 4 and 32 are, and 31 bits not being an obvious way to represent a 16-bit MEMS code); the fifth bit is always one of the padding “0”s, the first 4 bits of header and 1 bit of padding making 5 bits in total will have fixed values.

So I knew that the MEMS code transmitted by the 5AS was supposed to be a 16-bit number transmitted at a rate of 125 bits per second, and I now had identifiable 36-bit messages which appeared to consist of a 4-bit header followed by 32 bits, of which the even numbered bits were purely for framing leaving 16 bits of data. So it appears that the scheme used by the 5AS to transmit the 16-bit MEMS code to the ECU is roughly:

  • Take the 16 bits of the MEMS code.
  • Insert a “0” before each bit, to give 32 bits.
  • Prepend a header of “0011” to give 36 bits.
  • Transmit this using NRZ-S encoding.
  • Use 4ms per bit, giving a rate of 250 bits per second (but only every second bit is data, so 125 actual data bits per second).

There were still a number of unknown variables which I needed to take into account when trying to decode the MEMS code from the data stream of each immobiliser and to find the decoded bytes in the EEPROM data:

  • The serial data could either be streamed with least significant bit first, or the most significant bit first (2 likely possibilities, although most serial protocols stream the least significant bit first so I went with this as a working assumption for now).
  • The 16 bit value would most probably be stored in EEPROM as two consecutive bytes, these could be stored as least significant byte first or most significant byte first (2 possibilities, but most likely to be the default byte order for the microprocessor - Freescale microcontrollers generally use the Big Endian convention, with the most significant byte stored first, at the lowest address).
  • NRZ-M encoding could be used rather than NRZ-S (2 likely possibilities).

But taking all of these into account, there were still only eight possibilities; if I could calculate the MEMS code according to each of these schemes and find the corresponding bytes at the same location in the EEPROM data in each of the immobilisers, I could be confident that I had fully identified the encoding scheme and the location of the MEMS code in the EEPROM data. There are only 256 bytes of EEPROM on the microcontroller so the chances of a “false hit” are very slim even looking at just one immobiliser, and any hits at the same addresses in multiple immobilisers will certainly be genuine.

I put together an Excel spreadsheet which can decode the 5AS data stream just to prove all of the above concepts and to allow me to work out the possible MEMS codes and EEPROM bytes for each of my immobilisers. I felt that the chances of making a mistake decoding them all by hand were too high, and even a 1-bit error could lead me down a blind alley. The spreadsheet allows you to enter any 72 consecutive bits of data from the data stream, not necessarily starting at the start of a message, and implements all of the logic above for decoding NRZ-S or NRZ-M, determining the odd and even bit streams, determining the offset to the start of the message and decoding the hexadecimal 16-bit data word transmitted and the corresponding EEPROM bytes. It also allows any of the unknown encoding options listed above to be selected.

1500.thumb.png.4d5bb9ce236e5211bbeefc0a3e136a58.png

For completeness I also added a tab which performs the complementary encoding, taking the two consecutive EEPROM bytes and generating the MEMS code and 72-bit repeating sequence transmitted. This allowed me to test the decoder functionality above to make sure I hadn’t made any mistakes coding it.

1600_0.thumb.png.ec099f307e4e7c7172ee969cea78507e.png

Note that when encoding, there is a further assumption to be made. Each “0” bit causes the output state to toggle, each “1” bit keeps the previous output state, but if the very first bit to be encoded is “1”, what is the output state? There is no previous output state to maintain. So we have to make an assumption about the initial output state of the encoder.

The two possible initial states give two different encoded output bit sequences, both of which correctly encode the same message and both of which can be decoded correctly and identically. For MEMS codes which have an odd number of transitions (those which repeat every 72 bits), we see both of these bit sequences in the streamed data, alternately beginning with “01110” and “10001”. However, for MEMS codes which have an even number of transitions (those which repeat every 36 bits), we only ever see one of these bit sequences in the streamed data, always beginning with “01110”. Using the spreadsheet above, I found that assuming an initial “1” state always produced the “01110” sequence which is seen in the 5AS output; assuming an initial “0” state always produced the “10001” Sequence which is not seen in the 5AS output in the initial message or in any message with an even number of transitions, so it was clear that the encoder in the 5AS assumes an initial state of “1”.

Unfortunately, an initial state of “1” generates sequences beginning with “01110” irrespective of whether NRZ-S or NRZ-M encoding is used, so this gave no clues as to the correct assumption here.

So now that I had a good idea what I was looking for in the EEPROM data it was time to desolder the microcontroller chip and have a look at it in a programmer to see if I could find the MEMS codes I had decoded. This was a lot easier than when I had previously desoldered memory chips from the ECU as the circuit board was quite conventional, rather than being a large metal heatsink. I again used a temperature controlled hot air gun from a solder rework station. In order to protect surrounding components from becoming detached, I masked the area immediately around the microcontroller with high temperature Kapton tape. This provided both a degree of heat shielding and some mechanical adhesion and support to prevent parts from moving if the solder did melt.

2000.thumb.jpg.4ddb85af0ddf183580457bade79ee771.jpg

The microcontroller was then removed quite easily using a reasonably high flow of 350°C air. I wanted to use the highest temperature I could as this would result in removing the component in the least time, which somewhat counter-intuitively means that the chip internals do not get as hot during the process as when using cooler air. Anything over 400°C risks scorching a fibreglass PCB so 350°C seemed to be a good compromise.

2100_0.thumb.jpg.fc7597a055767593353f826c5eb29897.jpg

The programmer I chose to use was an XPROG-M - or more accurately I believe a Chinese clone of an XPROG-M with some very dodgy software indeed (it would only work on Windows XP or Windows 7 32-bit which cannot be on a virtual machine, it came with instructions saying you must disable your virus scanner and sure enough when I tried to install it without doing so the scanner identified various threats, and instructions that you must diasable your internet connection as presumably if you don’t, it will download updates up the proper official software without all the hacks which would stop it working). Because I was only using this for my own hobby use and because I couldn’t actually find anything else at price that was at all reasonable for single hobby use which was capable of defeating the security protection systems on the microcontroller I persevered with it - on an old, no longer required XP laptop which I disconnected from everything else and would be quite happy to wipe clean once I was finished!

2200_0.thumb.jpg.91a250e7e91decb583feed8c708bea62.jpg

The programmer comes with an adapter for the MC68HC05B16 with a convenient PLCC52 socket so I didn’t need to solder the it to the board. Here is a picture of the microcontroller mounted in the adapter on the programmer:

2300_0.thumb.jpg.a33b9b7e6a6f542f131e5f979c602150.jpg

After jumping through all of the required hoops specified in the instructions, which included installing a very old Chinese language copy of Adobe Reader (oddly the software won’t even launch if you uninstall or update this) and importing a file of registry hacks, the software actually loaded and worked well. First of all I selected the device (Type, “MCU/MPU”, Subtype “Freescale HC05”, Device “MC68HC05B4/B6/B8/B16/B32”) which reassuringly listed mask code 0D60J as being supported.

2400.thumb.png.7df400aef27524bab9a2a114b4b170cc.png

Then I created a new project and clicked “Read”. It worked through “Check device…”

2500.thumb.png.c2d5448a2141cc4826076d6d1b36d79b.png

“Initialising device …”

2600.thumb.png.eeff9c63d68d296f95b817c5784215c1.png

“Bypass security” - this is where it had determined that the security bit was set preventing a switch to “non user” mode and set up the clock glitching attack to effect the switch using “back door” methods. It only took a couple of seconds.

2700.thumb.png.0bdb0d00c283f1edcc7a075fea1fbcd5.png

And finally repeated the whole cycle again, verifying the read.

This left me with a dump of the EEPROM data from the microncontroller, displayed in hexadecimal format, which I saved to a .BIN (raw binary) file. The microncontroller has 256 bytes of EEPROM, starting at address 0x100. So in the data displayed, offset 0x00 in the data file is actually at address 0x100 in the address space of the microcontroller etc. And sure enough … at offset 0x3B (address 0x13B) there were the two consecutive bytes 0x9F, 0x6A of the MEMS code 6A9F which I had decoded for this immobiliser! The only issue was that they were in reverse order, which means that my assumption that the storage order would follow the Big Endian convention of the processor was wrong.

2800_0.thumb.png.ecbe51312645f1b54bc44a8efc645505.png

So I updated my encoder and decoder spreadsheets with FALSE for “MSByte First in EEPROM” as shown below. I then repeated the whole procedure with a couple of other immobilisers just to convince myself and in each case the MEMS code which I decoded from the bit stream appeared at these same addresses in the EEPROM in the same format, which they did. This effectively confirmed all of the other assumptions I had made and my method for decoding the immobiliser data stream, so I was now sure which bytes I would need to preserve in order to retain the original MEMS code when copying the EEPROM settings from one immobiliser to another - or conversely, which bytes to change if I wanted to copy the MEMS code from one immobiliser to another so that the ECU would see them as the same unit.

2850.thumb.png.a0bf5ef543f73f0e84b492d3846f8b1b.png

From this site: https://blackbox-solutions.com/help/SM034.html I was also aware that the alarm serial number printed on the label on the case should also be found in the EEPROM somewhere. In this case the serial number was 5810549 (decimal) …

2900_0.thumb.jpg.edd313cf4b2a2a1d3ee686750c02619c.jpg

Which is 0x58A975 in hexadecimal, and this number also showed up at offset 0x9C (address 0x19C) … unusally stored as a 3-byte number (neither of the bytes either side were 0 as would be expected if it was in a 4-byte format) and again with the least significant byte first (75, A9, 58) confirming that this seemed to be the order in which the microcontroller software was storing the bytes of integers. A 3-byte number is very unlikely to be written by any of the microcontroller instructions directly (I may be wrong, I haven’t studied the HC05 family instruction set in detail), so my guess is that the sofware is writing multi-byte integer values explicitly one byte at a type, in Little Endian order with the least significant byte first.

3000.thumb.png.e4f637e810350eb48bc6190628ad4dd3.png

The EKA code was also recognisable at offset 0xA0 (address 0x1A0), with a length of two bytes. The EKA is an Emergency Key Access code which, on a Rover, allowed the immobiliser to be disarmed through a sequence of turns of the key in the driver’s door lock, and was of particular interest to me for some other work I’m doing. This is a four digit code, each digit being 1-9. Each byte here is storing one digit in the upper four bits and one digit in the lower four bits. The EKA is readable and writable using my T300+ key programmer, and I was able to match up the codes in the different immobilisers at this location. In this case the code was 5-4-5-4. With this particular immobiliser it’s hard to tell which order the bytes are stored in as theey are both the same (0x54) due to the repetitive code, but on another immobiliser which showed an EKA code of 2574 on the T300+, the bytes were 0x25, 0x74 which means the first two digits of the EKA code are stored in the first byte and the second two digits of the EKA code are stored in the second byte. If you think of the EKA code as being a hexadecimal integer but only using the digits 1-9, this is actually the reverse of the order used for other integers I found with the most significant byte first.

3100.thumb.png.5715b346f09898c01b1aa691d80ea3b8.png

Somewhere in the data there should also be the week and year of build, but I couldn’t see anything obvious. They could be encoded in so many ways. There were no consecutive integers corresponding to the week and year, but it could just be a number of weeks since a given date etc. I didn’t waste a lot of time looking for it for now. I don’t really need to be able to reset the date of manufacture; it’s on the label on the cover anyway. There should also be a count of the number of matched key fobs and the corresponding key IDs; these are things that I will come back to hunting for later. Even though my T300+ key programmer is easily able to match keys to immobilisers this does require all of the keys to be physically present, and sometimes I get involved with helping people with immobiliser issues remotely so an option to match a key directly in memory could be useful.

So the next question I needed to answer was this: Is there any kind of checksum protection on the EEPROM data? Given that the EEPROM is also used to hold alram trigger event logging information and updated at run time, it seemed unlikely, but before I went any further I decided to check that I was able to make changes to the EEPROM contents and still get the immobiliser working properly again.

At this point I decided to avoid making mistakes when editing the files, I would put together a little software utility for editing 5AS .BIN files:

3200.png.5afab687f698487afe248fe08f2fa5df.png

This allows me to open a .BIN file dumped from an immobiliser EEPROM and manually edit the identified settings, or to load one .BIN file as a template and then load the settings from another and save the merged file. So, using the above utility I updated the .BIN file downloaded from one of the immobilisers and changed the MEMS code and EKA code to 5678 and the serial number to 5667788, and used the XPROG-M programmer to upload this back to the microcontroller to see whether it still worked properly, whether the transmitted data stream matched my encoding of the new MEMS code 5678 as expected and whether the ECU could then be matched to this new code.

3300.png.1318ef7f708aa48e91fc055fc768e14c.png

Before attempting to solder the microcontroller chip back onto the circuit board I cleaned up the solder pads on the circuit board with solder mop braid and then a good clean with pure isopropyl alcohol. Then I masked around the microcontroller with high temperature Kapton tape and laid a “sausage” of solder paster long each set of pads. It didn’t matter that the paste bridged across the pads as the flux in the solder paste would allow it to pull back into the terminals and solder pads under surface tension once it melted.

8000.thumb.jpg.ce72f3ccc12a58e5cc633c8433f10297.jpg

I then used hot air at 350°C and a moderate flow rate, working along each side until the chip was neatly soldered back into place. I inspected the finished soldering carefully with a jeweller's loupe to make sure there were no dry joints, bridges of solder between pins or misaligned contacts but all looked good.

I then let everything cool back down to room temperature before applying power as the chip was well outside its allowed operating temperature range once I had finished soldering and powering it up in this condition could do irreversible damage.

8100.thumb.jpg.06f39557fd6b8c733330fbef8ff4efc2.jpg

Time for testing and the immobiliser came to life straight away, I matched it to a couple of key fobs and an ECU using the T300+ key programmer on my key programing interface and everything worked exactly as expected. The ECU was perfectly happy with the new signal but need to be matched again, which was a promising sign that I had given the immobiliser a new but valid MEMS code. This confirmed that there were no checksums to update, at least none which covered the MEMS code, EKA code and serial number areas of the EEPROM.

Once again I hooked up an oscilloscope to Pin 9 of the immobiliser to record the communications between the 5AS and the ECU. Here is the captured encoded waveform:

8200.thumb.png.4092a8a3164964aaff4c05f12661fb8d.png

And here is the decoding of the above signal in the spreadsheet, confirming that it is a valid signal representing the new MEMS code of 5678 which I had programmed into the EEPROM:

8300.thumb.png.be9233028f6be637a567a79488b67a23.png

So far, so good. I had proved that I was able to find all the relevant settings in the EEPROM data and update them on a single ECU. But having proved the concept by updating a single ECU, the next task was to check that the EEPROM data could be copied between immobilisers without causing any issues. This would only be possible if the Lucas 53873824 stamping on the microcontroller chip did indeed mean that the software was identical; or at least the software was sufficiently similar between the immobilisers which I had that it used the same memory layout in EEPROM for all of the parameters that impacted on features used in the Caterham installation. This was the ultimate goal, to allow me to copy my ideal settings from one immobiliser to others whilst preserving their unique identities. It seems such a long time ago that I set out on that mission that it’s easy to forget what the original objective was!

Using my software utility, I loaded the template .BIN file taken from the immobiliser whose behaviour I wanted to copy and updated it with the MEMS code, EKA code and serial number taken from the .BIN file downloaded from one of the other immobilisers, which was not showing the passive arming behaviour that I wanted.

8400.png.c6b89665996b8bb248f0e083b3b3c154.png

I then burned it back to the microcontroller of the second immobiliser, soldered it back into place and tested as before. Bingo! The second immobiliser new displayed all of the same passive arming behaviour as the first but still retained its unique IDs. All of the other configuration options and behaviours seemed completely consistent too as expected.

I repeated this for each of my spare immobilisers, with complete success every time. Mission accomplished.

Well, not quite …

For completeness, I said earlier that I wanted to try to work out the location and layout of the key fob coding data in order to allow me to copy the key fob programming from one immobiliser to another. I didn’t have any information on the key codes so my plan of attack on this one was:

  • Dig out a few spare keys (I have a large bag of key circuit boards, all remanufactured, testing and working, but that’s another write-up!) and label them up as A, B, C, D and E.
  • Program one immobiliser to accept keys A, B, C and D (the immobiliser can accept a maximum of 4 key fobs at a time).
  • Remove the microcontroller and download the EEPROM contexts.
  • Avoid triggering any alarm events as far as possible as these could update other memory locations with logging which might confuse the search.
  • Put it all back together and program it to accept keys B, D and E.
  • Remove the microcontroller and download the EEPROM contexts.
  • Compare the two files and try to identify changes consistent with:
    • The number of keys changing from 4 to 3.
    • Two of the original key codes (B & D) still being present but appearing in different positions (corresponding to slots 2 and 4 in the first case and 1 and 2 in the second case).
    • A new key code being added (E).
  • Once I had a theory, test it by making predictions about the memory contents I would expect to see with other key combinations and then setting these up and inspecting as above.

I figured this pattern would give me a good chance of spotting what was what.

This plan would involve repeatedly soldering and desoldering the microcontroller on one immobiliser quite a few times. I’m really not sure how well the chip and the circuit board will take the punishment but there’s only one way to find out. I think by the time I’ve finished this process, that one immobiliser will be clearly marked as for experimentation only and not to be used in a car as I have no idea how the reliability may have been affected. On the plus side, I’m getting quite practised at soldering and desoldering these chips now and can do it in a few seconds, usually getting it right first time, so the heat exposure involved is going down.

Here is the data I got. I have highlighted in red the bytes which changed between the two data sets.

8450.png.aada36967267ae4ec3f68f09f1cea15c.png

What can be seen here? Well there is a block of changes in the middle starting at offset 0x42 which makes a lot of sense and looks exactly like the key coding data I was expecting. There are several other bytes which have also changed which I don’t understand, but these are probably just event logging, key rolling code counters or something like that. Since the block of changes in the middle were exactly what I was expecting, I went with the theory that these were exactly what they appeared to be and the rest was just irrelevant noise.

In the first data set we see four blocks of four bytes each, which appear to be the key codes for keys A, B, C and D. Assuming these are in Little Endian format as normal with the least significant bytes first (and to be honest it makes no difference, it’s just a matter of convention how we choose to make key codes out of these as the codes are never seen anywhere else, so as long as we are consistent it will all work) they give 32-bit codes 0xA84B0DCE, 0xCE4D7DEA, 0x9D6C0ACE and 0xEE0A1B9A for keys A, B, C and D. We also see at offset 0x53 a count of 4 keys.

In the second data set we see in the same four blocks of addresses the key codes for keys B and D, followed by a new key code 0x891B39C9 which must be key E. After this is the key code for key D again. The fourth key code slot is not used as the count at 0x53 specifies that 3 keys are matched; it looks as though the data has simply not been overwritten by a new key so the old key D data remains.

8500.png.edd3e1a938f2663460a0ffdba129e6c6.png

So on that basis, the writing the following data should leave the immobiliser matched to keys A, C and E only:

8600.png.1fa2f9a43c96ee8972b79a2d20c30a96.png

I extended my software utility to include the key count and codes (and quite a bit else, such as full display, highlighting and editing of all of the binary data as you will see in the picture below) and used this to prepare a data set similar to the one shown above, with a key count of 3 and the key codes for keys A, C and E only:

8700.png.d7c4736ebfe7195c9c29938fe0cb06bd.png

I then uploaded this test .BIN to the microcontroller and tested the immobiliser. As expected, keys A, C and E now worked. But there was a catch, in that keys C and E worked immediately, key A did not. Eventually after pressing it many, many times (I didn’t count) it started working. So I can only assume that as I suspected earlier, some of the other bytes which changed were used by the rolling code generation and stored some kind of internal state of the key, and my changes had left the sequence counts in the immobiliser and key badly out of synchronisation and the key needed to roll right around a full sequence until it dropped back into line.

It seems logical that such key states would be stored somewhere close to the key codes in the same block of EEPROM memory, so my guess at this stage would be that the five changed bytes at offset 0x0A would still just be some kind of event recording and that the three changed bytes at offsets 0x57, 0x59 and 0x5D would be key state information. There three bytes are spaced out by 2 bytes then 4 bytes. I would also guess at this stage that there are actually four bytes representing the four keys in sequence, equally spaced by 2 bytes each, at offsets 0x57, 0x59, 0x5B and 0x5D - and that the byte at 0x5B just happened to take the same values in the two data sets I was comparing, which is not unlikely as they all seem to be small numbers. It further made sense as the last of these was set to 0 in the case where there were only three keys programmed, so my guess would be that this state information is cleared down at the start of the programming process and updates as the key signals are received.

However, I don’t think I really have enough information about all of this works to make it worthwhile trying to copy the key state information. So I think for now I will live with the fact that keys may need to be clicked quite a few times to resynchronise the first time they are used after programming directly in EEPROM. After all, I should imagine that 99% of the keys I will ever program will be done through the T300+ and key learning mode on the immobiliser where the problem does not arise.

This work has allowed me to achieve everything practical I set to do with the immobiliser programming. In addition to fully understanding the key data, there are still a few ideas I’d like to play with in the future. For example, I have been told that MEMS codes 0x0000, 0xF0F0 and 0xFFFF are not allowed, but as far as I can see they don’t break the coding scheme so I can only assume that they have some special meaning in the ECU. As a complete guess at the moment … I wonder if the ECU uses one these codes for “factory mode” (where it learns the code of the first immobiliser it gets a valid signal from)? And if so, can I trick an ECU to go into factory mode by putting one of these special codes into an immobiliser and then getting the ECU to learn the code from it? Probably not … but worth a try!

If anyone has any inside info on the Lucas 5AS that might help me understand I’d love to hear from them please. I could then expand this for future reference.

Link to comment
Share on other sites

Haha it has been suggested to me already. Several times...

l'm afraid I'd make a terrible spy, I'm far too much of a maverick. I never do what I'm told. I'm sure I'm a pain in the ass to manage. And I wouldn't be able to post about achievements on BlatChat or anywhere else!

My current job brings me plenty of intellectual challenges of this sort, and my boss is several thousand miles away and leaves me to get on with it - he knows when I go off-piste I'll usually come back with something interesting so he seems to tolerate me.

On a more serious note, two ex-colleagues left to work for the intelligence services over the years. Both quit after some time, both citing stress and disillusionment with the ethics of what they spent their time doing. Can't comment further as they couldn't say any more, but neither of them ended up happy and one I think suffered with depression and related issues for a long time afterwards.

I'll stick to tinkering in my garage I think. Doing things just because I can, because I choose to and because I enjoy them *smile*

I've still got a couple more of my projects to date to write up.

Link to comment
Share on other sites

No you don't, you just think you do! Whip that pedal box cover and have a look and you'll see. And at the throttle body end you just unclip the square plastic bush from the metal bracket and unwind the cable around the "snail" until it lines up with the little slot and slips out sideways. The new one goes back on in the same way in reverse. Even that makes it sound a lot harder than it is, give it a go and you'll see what I mean!
Link to comment
Share on other sites

And when adjusting the screw on the end of the outer cable at the engine end .... leave a little bit of slack in the inner cable to make sure the butterfly stays shut against the stop. Also put a spot of oil on the throttle pedal pivot and swing the pedal back and forth a few times before you fit the new cable to work the oil in.
Link to comment
Share on other sites

This really made me laugh:

Think how I feel... I need help replacing a throttle cable!!!

*thumb_up*

Andrew,

You've done it again.

One thought: Couldn't you reset the "service bit" to enable you to read the eeprom without having to de-solder again to re-read?

Link to comment
Share on other sites

Hi Regin,

While the XPROG-M will support in-circuit programming for unsecured devices only, it would still need one or two pins desoldering from the board and bending up which sounded messy. The Vpp programming voltage needs 9V and in normal use this is tied to the 5V supply so feeding in 9V would damage other circuitry.

I suppose what I could do would be to disable that security bit on a test mule immobiliser, permanently lift that programming voltage pin and solder in the required wires with a header connector for the programmer. That would give me one immobiliser that was permanently reprogrammable for experimentation.

I might just try that...

Cheers!

Andrew

Link to comment
Share on other sites

Andrew, 

When I read some of your posts I'm left with a mixed sense of awe, bemusement and inadequacy, but please don't let that stop you (as if!).  I am speaking as one who has good reason to be grateful for your assistance.  

I also wonder if you've found the secret to living without sleep?!  *sleep*

Ezzer

Link to comment
Share on other sites

Andrew,

It was something like that I thought of. Having a test mule.

I haven't looked closely, but another way of making one could, if space allow, be solder in a PLCC socket rather than the uP and then flick it out every time you need to read the content.

Just ramblings though.

/r-)

Link to comment
Share on other sites

@Ezzer: Some of these projects have taken me a long time to get through as I just have to spend a few minutes on them when I get a chance. But having young kids has trained me well on surviving without sleep!

@Regin: Yes possibly, looks a bit awkward to solder in a socket with the same footprint and contact pattern though.

Whilst thinking about the idea of making up a test mule in permanent reprogrammable configuration I've just noticed something rather odd though ...

All of the downloads I have from all of the devices I've played with start with the byte 0x03. This is the options register in the first byte of the EEPROM, with bits 1 and 0 set to 1. Bit 1 is EEPROM protection, which prevents internal program code from overwriting a portion of the EEPROM. Bit 0 is the security bit. But quoting the MC68HC05B16 manual:

EE1P – EEPROM protect bit

In order to achieve a higher degree of protection, the EEPROM is effectively split into two parts,
both working from the VPP1 charge pump. Part 1 of the EEPROM array (32 bytes from $0100 to
$011F) cannot be protected; part 2 (224 bytes from $0120 to $01FF) is protected by the EE1P bit
of the options register.

1 (set) – Part 2 of the EEPROM array is not protected; all 256 bytes of EEPROM
can be accessed for any read, erase or programming operations
0 (clear) – Part 2 of the EEPROM array is protected; any attempt to erase or
program a location will be unsuccessful
When this bit is set to 1 (erased), the protection will remain until the next power-on or external
reset. EE1P can only be written to ‘0’ when the ELAT bit in the EEPROM control register is set.

SEC – Security bit

This high security bit allows the user to secure the EEPROM data from external accesses. When
the SEC bit is at ‘0’, the EEPROM contents are secured by preventing any entry to test mode. The
only way to erase the SEC bit to ‘1’ externally is to enter self-check mode, at which time the entire
EEPROM contents will be erased. When the SEC bit is changed, its new value will have no effect
until the next external or power-on reset. 

So with both bits set to 1, the device isn't actually secured, despite the XPROG-M going through the motions of "Bypass security...". No wonder it finds it so easy to bypass the security ... there isn't any!

Link to comment
Share on other sites

Regin - I didn't need to for this so haven't tried. Decompiling and reverse engineering the software sounded like more effort than I had time for. But I think in principle yes, once in test mode the microcontroller lets you read any address. There's probably a configuration file somewhere in the software for the programmer which specifies the address ranges. I'll have a look!
Link to comment
Share on other sites

Looks like all the different chip configurations are in some proprietary binary file format with a .BOO extension. No idea what to make if them, they vary widely in size and I can't see the known address range inside the HC05 files. I went for the XPROG-M clone because it could bypass the security; now I know the security is disabled, a different programmer with a more open configuration might be a better choice.
Link to comment
Share on other sites

Thanks RJ, the 68HC705 (programmable version) has a slightly different memory layout to the 68HC05 (pre-programmed version) I think which might complicate things a bit. I don't have access to code at the moment but I don't think I really want to go there, too much work for the remaining gain to be had.

For now there are still a few useful fields I want to identify such as the passive flag and delay time, low key battery behaviour etc. I've got a list of the available fields and I know most of them vary across the set of immobilisers I've got which will give me some clues.

I've done a bit more analysis:

8800.png.08e393b8fe286cfd40060fa3a1e489b9.png

Bytes in red are 00 or FF in every single immobiliser that I've seen, so these are most likely to be unused. Bytes in blue have fixed values other than 00 or FF in every single immobiliser that I've seen, so these are unlikely to be very interesting and certainly aren't controlling the properties that I'm seeing variation in. Bytes in green correspond to the known fields editable on the left. That just leaves 44 bytes in white may be doing something but I don't know what.

If I rig up a programmable immobiliser test mule as discussed earlier it should bring the cycle time right down and allow me to tinker with these bytes and see what happens. I should be able to correlate some of the values with known behaviours from my existing downloads too. At least by programming the microcontroller directly I'm in no danger of bricking it by loading values that crash it; I can reload a known good set of data at any time, so I'm free to experiment. If I was talking to the assembled 5AS through a serial interface, anything I uploaded that it couldn't cope with might render it uncommunicative and leave me unable to put it back again.

Unfortunately my "quality" Chinese clone programmer has lasted about as long as expected and died due to poor soldering somewhere - for a while it still worked if I pressed my finger down on one corner but now even that is on the way out. I've gone over the board and resoldered everything that looked dodgy but it's still no good, so I've managed to get a full refund and I'm waiting for a replacement.

In the meantime I'll make sure I know exactly what I need to do to set up the test mule.

Link to comment
Share on other sites

Andrew,

I am well aware of the differences between the '05 and the '705, however this would be re-mapable if one wanted to.

I have checked that I no longer have any PLCC sockets; when I was repairing PC's on component level we had sockets that were lifted sligthly from the board to be able to use the same footprint as the IC in question. I can't find any info on them though.

Link to comment
Share on other sites

  • 1 month later...

Decoding & Cloning The Lucas 5AS Immobiliser - Part II

So you get what you paid for, and my Chinese clone XPROG-M programmer died. It was never very healthy, there was clearly a dry joint or bad connection somewhere on the board that made it work intermittently but I failed to find it and it eventually packed up completely. OK, I’ll be honest, I tried to reflow solder it to fix the problem and fried it! So I had to order another one and had a bit of a battle with UK customs which involved it being returned to China twice, but eventually it arrived and I was back in business. This one seemed a lot more reliable.

In the meantime I wasn’t twiddling my thumbs on this project though.

Firstly, I set up a test mule 5AS immobiliser. As several people correctly pointed out, repeatedly soldering and desoldering the microcontroller was not a practical solution when it came to tracking down the configurable properties in the EEPROM data. I was going to have to try out many different configurations to work out what some of the settings did (I would thing I’ve actually reprogrammed it several hundred times in total now). One alternative was to try to crack the communications protocol which is used to configure the unit. This however had three drawbacks:

  • I didn’t know where to start. If I had a tool that could program the 5AS I would at least have some communications to look at and attempt to decode, but I didn’t - and if I did, I wouldn’t need to crack the communications protocol anyway!
  • I would then be limited to changing only those parameters supported by the protocol. Whilst this would have helped me in providing some guidance as to what was possible, it may also have limited me and prevented me from playing with things that were never really intended to be configurable.
  • If I “bricked” an immobiliser by applying settings which prevented it from operating normally, I may not then be able to communicate with it to put things back as they were to recover it.

So instead I opted to remove the microcontroller chip and replace it with a socket that would allow me to just plug the chips in and out without soldering. This turned out to work really well. Once I’d got into practice, I could shut my test system down, unplug the chip and plug it into my programmer, load a new configuration and then return the chip to the immobiliser and power it back up in about 20 seconds, so it really took all of the pain out of the cycle.

9000_0.thumb.jpg.5c0282a00bd63548c07a79ed23db5521.jpg

Learning the best way to solder the socket in took a little time, but once I’d got it cracked it was straightforward so I went ahead and soldered sockets into all of my spare immobilisers, making them all easily programmable now. I would normally use 350°C hot air for desoldering the microcontroller quickly to avoid damage but using anything like that just melted the plastic socket. In the end I worked out that anything less than 200°C would not get the solder paste to melt and flow properly but anything more than 200°C damaged the socket; 200°C exactly though was spot on, it needed slow and careful working to make sure that all of the solder paste had fully fused on all of the connections but it really didn’t impact on the plastic socket at all so I could take my time.

9100_0.thumb.jpg.d8ac78c374ba4e59f222b1d7b9ddcae2.jpg

Secondly, I used the time to develop the software utility I wrote earlier into to a fully configurable 5AS editor and hacking tool.

In basic mode, it now acts as proper editor for setting the properties of an immobiliser. It lets you open one BIN file, downloaded from the microcontroller EEPROM, and update the various properties. The properties are defined using an external text file so additional properties can be added as found without recompiling the tool, unless they behave in some way not seen previously. Each property is edited in the appropriate format (e.g. binary, binary coded decimal, decimal or Boolean check box) and validated according to defined minimum and maximum values, allowed digits etc.

9200_0.png.f8845e28c224cfeae0ccb03bfaa87bdc.png

In advanced mode it allows me to open up multiple files at once and compare them. It highlights the areas for the storage of properties defined in the text file described above (in green, with a dark blue highlight showing the current property when you click into the editor grid). It also highlights in red any areas which are always 00 or FF in all of the open files (and are probably unused) and in blue any areas which hold other fixed values across all files (and probably correspond to common settings). White areas hold variable data which gives me a clue where to look when I have properties which vary between immobilisers. It allows me to edit property values as above, or to directly manipulate individual bytes and even single bits. I can edit anything anywhere in any grid and the others update to reflect the changes.

9300_0.png.feb6144ae33b3146e2e7d0a7c10c6e07.png

In addition I built in a number of tools to make it easier to hunt down correlations of data with known features. In the top right hand grid in the picture below I have set correlation flags for the superlocking feature. From testing, I knew that the first two immobilisers had superlocking enabled and the others didn’t (each flag can be set to “True”, “False” or “Don’t Care” where it is not known whether a certain feature is present in a given immobiliser or where I want to exclude one form the comparison for one reason or another).

9400_0.png.0d5ffc62090eadcc49a04410a7d5bbb1.png

The scrolling down, you can see it immediately highlights the byte at offset 0x35 as being strongly correlated (you can see below that bit 6, highlighted in red, could possibly be controlling superlocking if a 0 turns it on, and bits 4 and 3, highlighted in blue, could possibly be controlling superlocking if a 1 turns it on). The byte at offset 0x36 was also highlighted as being somewhat correlated, with one single bit matching the pattern set.

9500_0.png.227da49481b25932ca204db0f466bc8c.png

The only other byte that it highlighted was at offset 0x9A, where bit 6 appeared to be correlated. This immediately narrowed down my search to 5 bits across 3 bytes and made it very easy to try toggling these bits to see what effect they had. In this case it turned out that the two single bits at offsets 0x36 and 0x9A together controlled superlocking.

9600_0.png.a2028f230f5051699aa121f49aa44085.png

I also added a feature to decode the data at the current address as 1, 2, 3 and 4 byte integers in both most significant byte first and least significant byte format, both signed and unsigned. This turned out not to be so useful though as the only multi-byte integer I found was the serial number. Here you can see the serial number 1798446 decimal appearing as a 3 byte, least significant byte first, unsigned integer (row “3B LSF U”). In other cases, where integer numbers larger than 255 were needed (such as to set a 600 second passive arming time delay), a lower resolution was used (in this case the time delay is specified as a multiple of 8 seconds).

9700_0.png.8465d3c7f0292606d3bd513ac0521917.png

I also added a complete history log with full undo and redo functionality, which made it a lot easier to keep track of the changes I was making and what was affecting what.

9800_0.png.ada3475a5a474643eed70c5f10d6b119.png

So what did I manage to find using all of this?

Well my motivation for a lot of this is a project I have planned, which I will eventually write up separately, in which I want to enable the alarm functionality of the 5AS on my car. In order to do this and to make it work the way I want I need to be able to adjust certain settings, so I had a list of settings I really needed to find. I think I’ve found all of those, plus a few others. To be honest I think I’ve found most of the settings I’m aware of that might be at all interesting or useful in a Caterham installation (and some which are of no use at all).

I’ve listed below the properties which I’ve found so far. There’s a sneak preview summary of the list in the first picture of my software editor earlier in this post, but below I’ve listed the 23 identified properties in full, with their display and editing formats, offsets in the EEPROM, length in bytes, LSB or MSB arrangement where the length is greater than 1, active levels for bit flags and useful notes as appropriate.

There’s still a lot of data in the EEPROM that I haven’t decoded. A lot of this will turn out not to be configuration settings. I know for sure that the alarm records a certain amount of logging information about the last 5 events that triggered it and this will account for some of the bytes. There is also quite a bit of what I might call “dynamic configuration” data which will change at run time, such as rolling key states and other information used to maintain synchronisation with the key fobs, counts of the number of low battery transmissions received form each key fob etc. There is also information recording the current state of the immobiliser and alarm as all of this is preserved when the unit is powered off.

So far I’ve done quite a bit of probing of the areas highlighted in blue in the screenshots above, i.e. areas which hold values other than 00 or FF and which have the same values in all immobilisers I have seen, looking for behaviours which are the same across all the immobilisers I have but still configurable. I have tried setting blocks of these bytes to 00 and to FF to toggle all of the bits to see if I can trigger any strange behaviours to investigate but so far I haven’t turned up anything particularly useful. I seem to have managed to put it into an engineering test mode where it was reporting sensor states on the security LED. I also found a way of cleaning up the outputs by turning off the locking motor drive, but it seemed to disable the security LED so wasn’t particularly helpful; I think it was more a malfunction than a feature.

I haven’t yet played much with the areas in red, which are always 00 or FF. My first working assumption was that these were unused areas, but especially where they appear as single bytes they are equally likely to be bit flags which are always set one particular way as standard, or values which just happen to be 0 or 256, so there will probably be more to come when I get the time to play more, but I think I’ve got most of the important stuff already.

For now, when  program an immobiliser I’ll just leave all other unknown areas alone - or more likely, I’ll use one immobiliser which I know is working just as I want it to for my project as a template, only update those areas I understand and then import the coding data from other immobilisers to make up new files for them.

So here’s the full list so far:

Alarm Serial Number 1

Decimal Integer
Offset 0x9C
Length 3
LSB First
Repeated at Offset 0xC7

This is the serial number printed on the label on the front of the case. For some unknown reason it always appears twice in the EEPROM data at offsets 0x9C and 0xC7. The two copies are always identical. I believe this to be informational only. I don’t believe it affect functionality in any way.

Alarm Serial Number 2

Decimal Integer
Offset 0xC7
Length 3
LSB First
Repeated at Offset 0x9C

This is the serial number printed on the label on the front of the case. For some unknown reason it always appears twice in the EEPROM data at offsets 0x9C and 0xC7. The two copies are always identical. I believe this to be informational only. I don’t believe it affect functionality in any way.

MEMS ECU Code

Hexadecimal Integer
Offset 0x3B
Length 2
LSB First

This is the unique immobiliser identity code sent to the MEMS ECU. All values other than 0x0000, 0xFFFF and 0xF0F0 are permitted.

Emergency Key Access Code

Hexadecimal Integer
Offset 0xA0
Length 2
MSB First
BCD, MSD First

This is the code which can be entered using the driver’s door key to disable the alarm and immobiliser if the key is lost or inoperative.

Microcontroller Security Flag

Boolean Flag
Offset 0x00
Bit 0
Active Low

This is a feature implemented in the hardware of the microcontroller. When set to 0, this bit is designed to prevent the microcontroller being placed into non-user mode and prevents access to the memory contents by external programmers. Some programmers such as the XPROG-M claim to be able to circumvent this with glitching attacks. In the standard 5AS this bit is inactive (set to 1) and the microcontroller is therefore open.

NB: In my 5AS editor I added a confirmation prompt when changing this property as if set to 0, it may no longer be possible to program the microcontroller again.

EEPROM Protection Flag

Boolean Flag
Offset 0x00
Bit 1
Active Low

This is a feature implemented in the hardware of the microcontroller. When set to 0, this bit prevents write access to an area of the EEPROM to protect it against accidental overwriting. In the standard 5AS this bit is inactive (set to 1) and the EEPROM is therefore unprotected.

NB: In my 5AS editor I added a confirmation prompt when changing this property as if set to 0 it may prevent the normal operation of the immobiliser.

Week of Manufacture

Hexadecimal Integer
Offset 0xCF
Length 1
BCD (0-9 Only), MSD First

This is the week number printed on the label on the front of the case. I believe this to be informational only. I don’t believe it affect functionality in any way.

Year of Manufacture

Hexadecimal Integer

Offset 0xD0
Length 2
MSB First
BCD (0-9 Only), MSD First

This is the year number printed on the label on the front of the case. I believe this to be informational only. I don’t believe it affect functionality in any way.

Number of Key Fobs

Decimal Integer
Offset 0x53
Length 1
1-4

This is the number of key fobs that the 5AS is programmed to recognise. There are slots for four key codes in the EEPROM, so up to four keys may be programmed. The codes for the N programmed keys appear in the first N slots, the others are ignored.

Key Fob 1 Code

Hexadecimal Integer
Offset 0x42
Length 4
LSB First

This is the unique key code for the first key fob programmed.

Key Fob 2 Code

Hexadecimal Integer
Offset 0x46
Length 4
LSB First

This is the unique key code for the second key fob programmed.

Key Fob 3 Code

Hexadecimal Integer
Offset 0x4A
Length 4
LSB First

This is the unique key code for the third key fob programmed.

Key Fob 4 Code

Hexadecimal Integer
Offset 0x4E
Length 4
LSB First

This is the unique key code for the fourth key fob programmed.

Low Battery Flash LED On Unlock

Boolean Flag
Offset 0x38
Bit 2
Active High

When set to 1, the security LED flashes in a double pulse pattern for several seconds after unlocking to indicate that the key fob used transmitted a low battery warning. When set to 0, this feature is disabled. There is believed to be a further setting which configures the number of consecutive low battery messages which must be received before this warning is activated, although this has not been found yet.

Low Battery Double Key Press

Boolean Flag
Offset 0x38
Bit 3
Active High

When set to 1, the key fob button must be pressed twice when the key fob used transmits a low battery warning. This gives the impression to the user that the key fob is failing with a low battery. When set to 0, this feature is disabled.

In all immobilisers I have tested this has been set to 1 enabling the feature however as a personal preference I have disabled it.

Passive Arming Enabled

Boolean Flag
Offset 0x37
Bit 6
Active Low

When set to 0, the immobiliser functionality (not the alarm functionality) is engaged automatically after a certain timeout period has elapsed. There are three different timeout values. The first applies when the unit is unlocked but the ignition is not turned on. By default the immobiliser engages after 30 seconds. The second applies when the unit is unlocked and the ignition is turned on and off again. By default the immobiliser engages after 10 minutes. The third applies when the unit is unlocked, the ignition is turned on and off again and then the driver’s door is opened (in a Rover). By default the immobiliser engages after 30 seconds. When set to 1, this feature is disabled. If passive arming is disabled and the immobiliser is disengaged, it should never engage again on its own. The current state is maintained even when powered off and on again. This allows the immobiliser to be effectively removed in that the user should never need to interact with it.

For my planned alarm project, I wanted to be able to set either the immobiliser, or set both alarm and immobiliser. With passive arming, I can treat the key fob button as “disarm everything ready to go” and “set the alarm”. if I only want immobiliser functionality without setting the alarm I can just leave the passive immobiliser to engage on its own. Using the settings below I can set the timeouts appropriately.

Passive Arm Time (No Ignition)

Decimal Integer
Offset 0x21
Length 1
Multiple of 1 Second

This is the number of seconds until the passive immobiliser engages, if enabled, when the unit is unlocked but the ignition is not turned on. This is a single byte and is multiples of 1 second, so usable values are from 1s to 255s (4 minutes 15 seconds). The default value is usually 30s. If set to 0, this does not wrap to 256s; it is treated as 0s and the immobiliser engages immediately as soon as it is disabled.

This timeout makes sense in a Caterham installation. It is intended to immobilise the car if it is accidentally unlocked.

From my planned alarm project, the alarm will be triggered if the driver enters the car without disengaging the alarm with the key fob. It would then be slightly annoying if the immobiliser reengaged before the driver has time to enter the car and insert the ignition key, so I have increased this from 30s to a round 240s (4 minutes).

Passive Arm Time (Ign. & Door)

Decimal Integer
Offset 0x20
Length 1
Multiple of 1 Second

This is the number of seconds until the passive immobiliser engages, if enabled, when the unit is unlocked, the ignition is turned on and off again and then the driver’s door is opened (in a Rover). This is a single byte and is multiples of 1 second, so usable values are from 1s to 255s (4 minutes 15 seconds). The default value is usually 30s. If set to 0, this does not wrap to 256s; it is treated as 0s and the immobiliser engages immediately as soon as it is disabled.

This timeout makes no sense in a Caterham installation as there is no driver’s door switch. It is intended to immobilise the car quickly after the driver leaves the vehicle, but in a Caterham the conditions under which it applies will never occur and it is therefore largely irrelevant.

Passive Arm Time (Ign. Only)

Decimal Integer
Offset 0xAD
Length 1
Multiple of 8 Seconds

This is the number of seconds until the passive immobiliser engages, if enabled, when the unit is unlocked and the ignition is turned on and off again. This is a single byte and is multiples of 8 seconds, so usable values are from 8s to 2040s (34 minutes). The default value is usually 600s (10 minutes). If set to 0, this does not wrap to 2048s; it is treated as 0s and the immobiliser engages immediately as soon as it is disabled.

In practice, the timing here seems to be approximate. It appears as though the number specified is the number of ticks to be counted from a clock which ticks once every 8 seconds, however as the time to the next tick can be anywhere between 0s and 8s when the user turns off the ignition at a random moment, the first tick may occur after a shorter elapsed time. So setting a value of 8s actually results in the immobiliser engaging anywhere between 0s and 8s, setting a value of 16s actually results in the immobiliser engaging anywhere between 8s and 16s etc. With a default value of 75 (x8=600 seconds) the immobiliser may engage anywhere between 9 minutes 52 seconds and 10 minutes after switching off the ignition.

This timeout makes sense in a Caterham installation.

Superlocking Enabled 1

Boolean Flag
Offset 0x36
Bit 2
Active Low
Inverted at Offset 0x9A, Bit 2

When set to 0, this enables the superlocking or deadlocking functionality found on later Rovers, where a double-click of the key fob lock button deadlocks the doors and prevents them from being opened mechanically. This feature is irrelevant in a Caterham installation but if enabled can be confusing as there are two different lock states (especially for my planned alarm project where the indicators will be wired to flash when the alarm is armed and different flash patterns would be produced which would be meaningless). When using  a 5AS from another vehicle, this feature may be enabled and may be disabled be setting this bit to 1.

For some unknown reason, superlocking appears to need both offset 0x9A bit 2 setting to 0 and offset 0x36 bit 2 setting to 1. In all immobilisers I have seen where superlocking is disabled, both of these bits are inverted.

Superlocking Enabled 2

Boolean Flag
Offset 0x9A
Bit 2
Active High
Inverted at Offset 0x36, Bit 2

When set to 1, this enables the superlocking or deadlocking functionality found on later Rovers, where a double-click of the key fob lock button deadlocks the doors and prevents them from being opened mechanically. This feature is irrelevant in a Caterham installation but if enabled can be confusing as there are two different lock states (especially for my planned alarm project where the indicators will be wired to flash when the alarm is armed and different flash patterns would be produced which would be meaningless). When using  a 5AS from another vehicle, this feature may be enabled and may be disabled be setting this bit to 0.

For some unknown reason, superlocking appears to need both offset 0x9A bit 2 setting to 0 and offset 0x36 bit 2 setting to 1. In all immobilisers I have seen where superlocking is disabled, both of these bits are inverted.

Hazards Flash With Alarm

Boolean Flag
Offset 0x36
Bit 1
Active Low

When set to 0, the hazard lights are flashed with the pulsating alarm sound (in a Rover).

In a Caterham the required wiring is not present but this is relevant to my planned alarm project as the additional wiring will be added in order to drive the hazard lights.

Switch Closed When Bonnet Open

Boolean Flag
Offset 0x3E
Bit 0
Active High

When set to 1, in a Rover the alarm recognises the bonnet as being closed when the input from the bonnet switch is open circuit and open when the switch is close and the input is short circuited to ground. When set to 0 the alarm recognises the bonnet as being open when the input from the bonnet switch is open circuit and closed when the switch is close and the input is short circuited to ground.

In a Caterham installation it is important this is set to 1 if the alarm functionality is to be activated, as the bonnet switch input is not connected. The alarm needs to see this as “bonnet closed” or it will not engage.

For my planned alarm project however, I wanted one trigger input which would activate the alarm when not shorted to ground. The bonnet switch input is the only input which may be programmed to operate in this way, by changing this bit to 0. This may then be used to activate the alarm if the handbrake is released, as the handbrake incorporates a switch which short circuits to ground when the handbrake is applied.

Link to comment
Share on other sites

I've managed to decode a couple more fields, which control the pattern flashed by the security LED when the immobiliser is armed (at offset 0x90) and disarmed (at offset 0x89). I had found that these bytes were affecting the LED flash patterns earlier but it took me a while to fathom out the encoding used. I had worked out that the position of the highest 1 bit in the byte determined the overall repeat time of the pattern and the position of the lowest 1 bit in the byte seemed to determine the "on" time when the LED flashed but this description was too complicated and didn't alow me to understand all of the timings so I carried on looking for a further, simpler explanation that matched these observations and explained everything else. 

It was more of an academic exercise (I don't like to be beaten) and probably not hugely useful at the end of the day, but I have on mine changed the flash pattern mask when armed from 0xFF to 0xBC as described below.

LED Pattern Mask (Armed)

Hexadecimal Integer
Offset 0x90
Length 1

This byte determines the LED flash pattern when the immobiliser is armed. The pattern encoding can generate a range of LED flash patterns with one or multiple flashes per cycle as well as permanently on or off. Some example flash patterns are listed below:

  • 0x00 $00000000 Permanently Off (Default Disarmed Pattern)
  • 0xFF $11111111 On for 8ms, Off for 1016ms (Default Armed Pattern)
  • 0xFE $11111110 On for 16ms, Off for 1008ms
  • 0xFC $11111100 On for 32ms, Off for 992ms
  • 0xF8 $11111000 On for 64ms, Off for 960ms
  • 0xF0 $11110000 On for 128ms, Off for 896ms
  • 0xE0 $11100000 On for 256ms, Off for 768ms
  • 0xC0 $11000000 On for 512ms, Off for 512ms
  • 0xBC $10111100 On for 32ms, Off for 480ms (My Preferred Armed Pattern)
  • 0xA0 $10100000 On for 256ms, Off for 256ms
  • 0x90 $10010000 On for 128ms, Off for 128ms
  • 0x88 $10001000 On for 64ms, Off for 64ms

The rules for determining the actual flash pattern from the mask byte took me a little time to fathom out but in fact the algorithm is fairly straightforward. In words:

  • Take a 7-bit bit binary counter, incrementing every 8ms (so wrapping back to 0 after 1024ms).
  • Bitwise AND the 7-bit counter with the lower 7 bits of the mask.
  • If the resulting bits are ALL 0, take the high bit of the mask, otherwise take its inverse.
  • If this is 1 the LED is ON, if this is 0 the LED is OFF.

As far as I can see, this generates the corresponding flash pattern for all of the mask bytes that I have tested. I put together an Excel spreadsheet that generates a text description of the flash pattern generated by any given mask byte:

9900.png.38ec321cdadb859c800d6ad0dd2018a5.png

As a matter of personal preference I have changed this from the standard value of 0xFF (8ms Pulse, Every 1024ms) to 0xBC (32ms Pulse, Every 512ms). This makes the flashing LED rather more obvious and visible and makes it clear that the car is protected by a security system.

LED Pattern Mask (Disarmed)

Hexadecimal Integer
Offset 0x89
Length 1

This byte determines the LED flash pattern when the immobiliser is disarmed. The pattern encoding can generate a range of LED flash patterns with one or multiple flashes per cycle as well as permanently on or off. The pattern is encoded exactly as for LED Pattern Mask (Armed) above.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...