Professional Documents
Culture Documents
Tutorial - Reverse Engineering IAW ECU
Tutorial - Reverse Engineering IAW ECU
html
Since buying my Lancia Delta Integrale (non-Evo 16V with ABS) I find this car already has a very advanced engine management ECU controlling
spark, fuel and boost. My ECU is labeled WH4W.08/90K-9B. I have archived more information about the basic hardware of the system on the
tools page GECU HARDWARE INFORMATION section..
Being in a country where these cars were not sold from new, local support is non-existent so I need to do everything myself. Since the ECU
appears to be at least as advanced as systems like megasquirt I figured it would be worthwhile to figure it out rather than replacing it.
Download these tools as a single zip file into the gecu directory you created in step 1 and extract them there.
These are the software tools necessary to interpret what’s in the EPROM. If for some reason you don’t have the ability to unzip then download
them one-by-one from the tools page GECU REVERSE ENGINEERING section.
You should now have a folder with the following files in it:
1. dasm.bat
2. dhc11.exe
3. diss.bat
4. gecu.bin
4: gecuadd.exe
5. gecudctl.txt
6. gecudiss.txt
7 gecuparse.exe
Open a file explorer window and navigate to the working directory (eg. c:\gecu). Run the 1st pass of the disassembler (double click on diss.bat).
A DOS window will temporarily open then close. I have redirected all output to log files so we can just do stuff from the windows environment
rather than having to go to DOS. This should have created 4 new files:
1. diss.log (this file tells you the results of running the diss batch file.)
2. gecu.cmt (this is an empty comment file needed for later)
3. GECU.DIS (this is the raw disassembled ECU file - but we won't be using this)
4. gecu.txt (this will eventually be the commented disassembly file - but right now its empty)
Run the disassembler using dasm.bat (double click dasm.bat). A DOS window temporarily opens and closes with the results in the log file
dasm.log.
Now the process of converting from a binary to something that is human readable begins. The process of disassembling the code can be aided in 2
ways;
1. Whenever we learn where things are in the memory map (internal or external RAM or internal or external device) we create an entry in
the disassembler control file so that the next time we run the dasm batch file we'll have an easier to understand english language name rather
than a number.
2. When we figure out how things are working in the code we can add comments to the commented disassembly file so we'll remember what
was going on the next time we look at this section of code (or when it happens to be used again - say as a subroutine)
This will be an iterative process until we've figured out the whole EPROM binary. That's all there is to it !
gecuparse
gecuadd
open the comment file and get the line number for the next comment
open the disassembler file and copy it to the commented disassembler file until you come to the line number of the next comment
add the comment field (the “*” and everything after it) to the end of the line
dhc11
-a: Show addresses on left of each disassembled line (I need this for the comments)
-op: Show opcodes for instructions disassembled
-ov: Forces output file to be overwritten if it already exists
The disassembler control file(s) deserves a little extra detail. The most important thing that happens in the control file is the creation of the
memory map for the disassembler. In the 1st pass of the disassembler (diss.bat) we don’t know anything about the system so all that we have
in there is the input and output file names. Have a look at gecudiss.txt and here’s what you’ll find:
input gecu.bin
output gecu.dis
Note that the disassembler uses “;” for its comment character. If you want to add comment information to the control file you have to use the
; character. Everything after the “;” is ignored.
The following commands, all within the control file, tell the disassembler information about the binary image it will process. The more
information that can be determined and supplied here, the better the resulting disassembly will be. Optional parameters are enclosed in
square [ ] brackets.
Mnemonics
And finally on the disassembler topic please note the following differences about the way the Tech Edge disassembler presents the
mnemonics compared to those specified by Motorola for the processor.
DHC11's Mnemonics Motorola's Function Performed
call JSR Call
callr BSR Call Relative (short call)
cmpD, cmpX cmpY CP? Compare (16 bit register)
decX, decY, decS DE? Decrement (16 bit register)
di SEI Disable Interrupts
ei CLI Enable Interrupts
incX, incY, incS IN? Increment (16 bit register)
jr BRA Jump Relative (short jump)
push, pushB, pushX, pushY PSH? Push on to stack
popA, popB, popX, popY PUL? Pop off stack
ret RTS Return (from subroutine)
reti RTI Return From Interrupt
xorA, xorB EOR? eXclusive Or
As you can see, DHC11's mnemonics use, at most, one extra character, but this makes their meaning much clearer, and is closer to a
majority of other assembler syntaxes. In addition, the mnemonics are displayed in a mixed case that is designed to highlight the registers use
by the instruction. For example, LDA, the Load A instruction is displayed as ldA to emphasise that the A register is used in this ld
instruction. The tAB and xgDY are examples of instructions that use two registers in the one mnemonic.
Now that we know the details of each tool lets have a look at each element in the process
The log file records the messages from the comment parser and adder and the disassembler. An initial log file might look like this:
DHC11 - 68HC11 Disassembler v1.1 (c) Copyright 2000 Tech Edge Pty. Ltd.
The next section is the internal memory mapped devices of the MC6803U4 processor
; MEMORY MAP
The next section is the internal RAM variable declarations. I've named a few that were easy to find since they are part of the serial command
interface.
; 0x40 to 0xFF internal RAM
; insert symbol names here
;
label $0048 cmd_throttle_valve_angle
label $0049 cmd_air_temp
label $004A cmd_water_temp
label $004B cmd_injection_duration_msb
label $004C cmd_injection_duration_lsb
label $004D cmd_ignition_advance
The next section is the external RAM variable declarations. Coincidentally a few are also part of the serial command interface.
; --- EXTERNAL DEVICES ---
This next section shows some examples of labeling code addresses as a jump table, parameter list and vector table. The first table was found as
part of the self-test commands, the next table is the list of memory addresses that are dumped as the diagnostic command responses and finally the
vector table at the top of memory again based on the MC6803U4 CPU.
; External EPROM (27128 - 16Kx8)
; 0xC000 to 0xFFFF
; jump table
; vectors $C3F9 5 jump jumpvectors ; works but doesn't give desired result
indirect $C3F9 DIAG_test_fuel_pump DIAG_jump_vectors
indirect $C3FB DIAG_test_injectors
indirect $C3FD DIAG_test_coil
indirect $C3FF DIAG_test_vae
indirect $C401 DIAG_test_overboost
This file is where we look to see what the ECU is doing to our car. We haven't inserted any comments yet so if we look at the log file (dasm.log)
we will see that it found 0 comments. The file is too large to list here but lets have a look at a few key sections and add a couple comments. To
look at the file I find it easiest to use notepad. Unless you've changed the default behavior of windows notepad will automatically open the file
when you double-click on gecu.txt.
;
; DHC11 - 68HC11 Disassembler v1.1 (c) Copyright 2000 Tech Edge Pty. Ltd.
;
; http://www.techedge.com.au/utils/dhc11.htm
;
;
; Disassembly of gecu.bin - from $C000 to $FFFF
;
*** Internal Registers as we defined in the disassembler contol file
PORT1_DDR = $0000
PORT2_DDR = $0001
PORT1_DATA = $0002
PORT2_DATA = $0003
TMR_CSR = $0008
TMR_CNTd = $0009
TMR_OCR1d = $000B
TMR_ICR1d = $000D
SCI_RMCR = $0010
SCI_TRCSR = $0011
SCI_RX = $0012
SCI_TX = $0013
TMR_CNTAd = $0015
TMR_CR1 = $0017
TMR_CR2 = $0018
TMR_SR = $0019
TMR_OCR2d = $001A
TMR_OCR3d = $001C
TMR_ICR2d = $001E
L0040 = $0040
L0041 = $0041
L0042 = $0042
L0043 = $0043
L0044 = $0044
L0045 = $0045
L0046 = $0046
L0047 = $0047
*** Internal RAM variables as we defined in the disassembler control file
cmd_throttle_valve_angle = $0048
cmd_air_temp = $0049
cmd_water_temp = $004A
cmd_injection_duration_msb = $004B
cmd_ignition_advance = $004D
<snip>
*** Start of code execution (notice code label)
C000 RESET_00:
C000 8E 00 FF ldS #$00FF
C003 4F clrA
C004 B7 18 12 staA L1812
C007 86 D6 ldaA #$D6
*** Instruction with a reference to a variable as defined in the disassembler control file
C009 97 02 staA PORT1_DATA
<snip>
*** This section is where the internal self test is activated - Lets add some comments !
C3C9 C4 7F LC3C9 andB #%01111111
C3CB C1 05 cmpB #$05
C3CD 24 AC bcc LC37B
C3CF 37 pushB
C3D0 BD ED F6 call LEDF6
C3D3 33 popB
C3D4 86 1A ldaA #$1A
C3D6 97 11 staA SCI_TRCSR
*** Go to this section in the listing file and type in the * and comment
C3D8 CE C3 F9 ldX #$C3F9 * load the base address of the diagnostic jump table
C3DB 58 lslB * double diagnostic test code to account for double word offset in table
C3DC 3A aBX * add offset to jump table base
C3DD EE 00 ldX 0, X * get jump address from table
C3DF AD 00 call 0, X * start execution from jump address
C3E1 86 0A LC3E1 ldaA #$0A
C3E3 97 11 staA SCI_TRCSR
C3E5 4F clrA
C3E6 5F clrB
C3E7 DD D3 stD L00D3
C3E9 96 D5 ldaA L00D5
C3EB 84 7C andA #%01111100
C3ED 97 D5 staA L00D5
C3EF C6 FF ldaB #$FF
C3F1 D7 D0 staB L00D0
C3F3 BD ED F6 call LEDF6
C3F6 7E C3 7B jmp LC37B
;
;
C3F9 DIAG_jump_vectors:
C3F9 dw DIAG_test_fuel_pump
C3FB LC3FB: dw DIAG_test_injectors
C3FD LC3FD: dw DIAG_test_coil
C3FF LC3FF: dw DIAG_test_vae
C401 LC401: dw DIAG_test_overboost
;
Once you have entered the 5 comments, save and close the commented disassembly file and try running the dasm.bat file again.
Now when you look at the log file you should see that 5 comments were parsed and subsequently added.
This process continues until you understand the sections of code you are interested in (or all of it).
Have fun !