Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

16 Bit Checksum for Embedded System, Need Help With Identifying Algorithm and Mem. Address

25 views
Skip to first unread message

mattsf...@adelphia.net

unread,
Dec 16, 2006, 4:59:25 AM12/16/06
to
Hello,

I am working on reverse engineering an engine computer for a 91-95
Acura Legend. I am trying to determine what algorithm is used and the
checksummed addresses within the ROM. I have no knowledge of
programming and a limited knowledge of hex. Any information would be
greatly appreciated.

What I know/research:
It is a 16bit arithmetic checksum
It is a word at 0x00

I have an aftermarket ROM chip manufactured by a company that knew the
correct checksum routine. All that was modified were 2 ignition maps
and a rev limiter. I have the exact same stock ROM chip to compare
against. The 32K ROM chip is split into two different parts on the ECU.
The first part 0x0000-0x3FFF is for Manual Transmission cars, the
Second part 0x4000-0x7FFF is for Automatic Transmission cars. There are
various settings and tables that are changed between the two, but the
aftermarket company made the EXACT same changes in each ROM. So, I
split the stock rom into two portions and the aftermarket ROM into two
portions. The engine computer only sees one portion depending on
whether it is set up to be automatic or standard by swiching the high
memory address (A14) to ground (m/t) or +5 (a/t) with a resistor.
Therefore, the checksum is calculated for the indivual 16K portions and
not the entire 32K ROM. The split files are available here:

http://users.adelphia.net/~sr5guy/Legend.zip

WORD at 0x00
-----------------------------------------
#1 Stock AT.bin: 0xF8CD
#1 Aftermarket AT.bin: 0xD2A9

0xF8CD - 0xD2A9 = 0x2624
------------------------------------------
#2 Stock MT.bin: 0x0AD7
#2 Aftermarket AT.bin: 0xE4B3

0x0AD7 - 0xE4B3 = 0x2624
-------------------------------------------

The fact that both of these equations have the same sum leads me to
believe that an arithmetic, non CRC, 16 bit checksum is used. Please
help me to find out what algorithm it is (Plain 16 bit, Little Endian,
Big Endian, XOR, ETC) and what memory addresses it references. I think
this may be found easily via a brute force method, disassembly, etc. At
this stage, it is over my head!


More information:

The ECU's micro is an Hitachi H8/500 series. There is 32KB of masked
internal ROM inside of this MCU. I have no access to this internal ROM
at this time. I do sincerely hope that this checksum, located in the
EXTERNAL ROM, is not a computation of the internal and external ROM put
toghether.

The method to disable the checksum routine is at 0x1060. You change the
value of 0xCA to 0x80. For certain cars, this method of disabling the
checksum causes errors with other systems in the car, namely the
traction control system. The only option of repair is to correct the
checksum located at 0x00.

Threads:

This thread contains links to the dis-assembler, programming and
datasheet for the Micro.
http://forum.pgmfi.org/viewtopic.php?t=12362

This thread contains links to the Acura Legend ECU project, a search of
this forum should provide any needed information.
http://www.acura-legend.com/vbulletin/showthread.php?t=93859


Thanks again for taking the time to read this!

-Matt
mattsf...@adelphia.net

moi

unread,
Dec 17, 2006, 7:01:14 AM12/17/06
to


It is hust plain addition, modulo 16 bit, just as in TCP/IP.
Treating all the rom's contents as 16-bit unsigned values
and adding them up should yield zero.

Here she goes:
------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>

#define ROM_SIZE (16* 1024)
unsigned char bank1[ROM_SIZE];
unsigned char bank2[ROM_SIZE];

void read_one(unsigned char *buff, char *name);

int main(int argc, char **argv)

{
int fd, rc;
unsigned short sum1, sum2, val1, val2;
unsigned idx;

read_one(bank1, argv[1] );
read_one(bank2, argv[2] );

sum1 = sum2 = 0;
for (idx = 0 ; idx < ROM_SIZE; idx += 2) {
/* Silly way to impose byte ordering ... */
val1 = (unsigned)bank1[idx+1] + (bank1[idx+0] <<8);
val2 = (unsigned)bank2[idx+1] + (bank2[idx+0] <<8);
sum1 += val1; sum2 += val2;
if (val1 == val2) continue;
fprintf(stdout, "%4x %04hx %04hx\n", idx, val1, val2);
}
fprintf(stdout, "Sum = %04hx/%04hx\n", sum1, sum2);
exit(0);
}

void read_one(unsigned char *buff, char *name)
{
unsigned pos;
int fd, rc;

fd = open(name, O_RDONLY);
if (fd < 0) exit(1);

for (pos = 0; pos < ROM_SIZE; pos += rc) {
rc = read(fd, buff+pos, ROM_SIZE - pos);
if (rc <= 0) break;
}

close (fd);
if (pos < ROM_SIZE) exit(2);
}

----------------------------------

Note: please dont put spaces in your filenames ;-]


HTH,
AvK

sr5guy

unread,
Dec 17, 2006, 1:36:08 PM12/17/06
to
Great, this is awesome thank you so much for your help!

When the checksum is calculated, does this routine replace the word at
0x00 with all 0's?

Would it be possible for someone to make a quick and dirty .exe utility
with this code for the dos/windows platform, so that I can make use of
it? I don't have any idea of what needs to be done.

Sorry about the spaces in the filenames, I was trying to make it easier
to differentiate between the files.

-Matt

moi

unread,
Dec 17, 2006, 2:07:03 PM12/17/06
to
On Sun, 17 Dec 2006 10:36:08 -0800, sr5guy wrote:

> Great, this is awesome thank you so much for your help!
>
> When the checksum is calculated, does this routine replace the word at
> 0x00 with all 0's?

No, off course not. ( I cannot write into your ROMS, anyway :-)
The program just calculates the checksum.
All the four files you supplied seem to add up to zero,
anyway. (I don't know what the checksum *should* be, could be
anything, basically. But zero seems natural.)


>
> Would it be possible for someone to make a quick and dirty .exe utility
> with this code for the dos/windows platform, so that I can make use of
> it? I don't have any idea of what needs to be done.

If I/my program is correct, you should do nothing: the files
have the same (correct?) checksum: they all add up to zero.


> Sorry about the spaces in the filenames, I was trying to make it easier
> to differentiate between the files.
>

No sweat. shit happens.

BTW: the program's output *after omitting the first two bytes in the
calculation*
"if (idx) { sum1 += val1; sum2 += val2; }"

:::::::::::::::::::::

./check StockMT.bin AftermarketMT.bin
0 0ad7 e4b3
1550 1964 1b58
1d60 9090 9293
1d62 9090 9495
1d64 8e8c 9493
1d66 8a88 9291
1d68 8684 908f
1d6a 8281 8e8e
1d6c 807e 8e8d
1d6e 7d7c 8c8b
1d70 9090 9293
1d72 9090 9495
1d74 8e8c 9493
1d76 8a88 9291
1d78 8684 908f
1d7a 8281 8e8e
1d7c 807e 8e8d
1d7e 7d7c 8c8b
1d80 9090 9293
1d82 9090 9495
1d84 8e8c 9493
1d86 8a88 9291
1d88 8684 908f
1d8a 8281 8e8e
1d8c 807e 8e8d
1d8e 7c79 8b88
1d90 8585 8788
1d92 8585 898a
1d94 8482 8a89
1d96 8180 8989
1d98 7e7d 8888
1d9a 7c7b 8888
1d9c 7a79 8888
1d9e 7873 8782
1da0 8c8c 8e8f
1da2 8c8c 9091
1da4 8a7e 9085
1da6 7c7a 8483
1da8 7a7a 8485
1daa 7a7a 8687
1dac 7974 8783
1dae 6e6a 7d79
1db0 8f8f 9192
1db2 8f8f 9394
1db4 8c80 9287
1db6 7e7b 8684
1db8 7b7b 8586
1dba 7b7b 8788
1dbc 7a78 8887
1dbe 7470 837f
1dc0 8a8a 8c8d
1dc2 8a8a 8e8f
1dc4 887c 8e83
1dc6 7a78 8281
1dc8 7878 8283
1dca 7878 8485
1dcc 7874 8683
1dce 716c 807b
1dd0 8686 8889
1dd2 8686 8a8b
1dd4 8479 8a80
1dd6 7775 7f7e
1dd8 7575 7f80
1dda 7575 8182
1ddc 7573 8382
1dde 6c69 7b78
1de0 8787 898a
1de2 8787 8b8c
1de4 857a 8b81
1de6 7876 807f
1de8 7676 8081
1dea 7675 8282
1dec 736e 817d
1dee 6963 7872
1df0 8888 8a8b
1df2 8888 8c8d
1df4 877c 8d83
1df6 7a78 8281
1df8 7878 8283
1dfa 7874 8481
1dfc 6c66 7a75
1dfe 6360 726f
1e00 8787 898a
1e02 8787 8b8c
1e04 8582 8b89
1e06 807d 8886
1e08 7b79 8584
1e0a 7771 837e
1e0c 6963 7772
1e0e 5d59 6c68
1e10 8686 8889
1e12 8686 8a8b
1e14 8380 8987
1e16 7e7b 8684
1e18 7976 8381
1e1a 736b 7f78
1e1c 6662 7471
1e1e 5f5c 6e6b
1e20 8888 8a8b
1e22 8888 8c8d
1e24 8683 8c8a
1e26 807e 8887
1e28 7b79 8584
1e2a 7674 8281
1e2c 6860 766f
1e2e 5d5b 6c6a
1e30 8686 8889
1e32 8686 8a8b
1e34 8280 8887
1e36 7d7a 8583
1e38 7876 8281
1e3a 7371 7f7e
1e3c 665f 746e
1e3e 5c59 6b68
1e40 8484 8687
1e42 8484 8889
1e44 827e 8885
1e46 7b77 8380
1e48 7571 7f7c
1e4a 6f6c 7b79
1e4c 5a4f 685e
1e4e 4d48 5c57
1e50 7878 7a7b
1e52 7878 7c7d
1e54 7572 7b79
1e56 6f6c 7775
1e58 6967 7372
1e5a 6455 7062
1e5c 4a42 5851
1e5e 3e3a 4d49
1e60 7171 7374
1e62 7171 7576
1e64 6f6b 7572
1e66 6965 716e
1e68 6360 6d6b
1e6a 574a 6357
1e6c 4037 4e46
1e6e 3431 4340
1e70 5959 5b5c
1e72 5959 5d5e
1e74 5755 5d5c
1e76 5351 5b5a
1e78 4f4c 5957
1e7a 3d31 493e
1e7c 2827 3636
1e7e 221f 312e
1e80 5858 5a5b
1e82 5858 5c5d
1e84 5654 5c5b
1e86 514f 5958
1e88 4e4c 5857
1e8a 3d30 493d
1e8c 2727 3536
1e8e 221f 312e
1e90 5656 5859
1e92 5656 5a5b
1e94 5451 5a58
1e96 4f4d 5756
1e98 4a49 5454
1e9a 392d 453a
1e9c 2220 302f
1e9e 1a14 2923
1ea0 9090 9293
1ea2 9090 9495
1ea4 8e8c 9493
1ea6 8a88 9291
1ea8 8684 908f
1eaa 8281 8e8e
1eac 807e 8e8d
1eae 7d7c 8c8b
1eb0 9090 9293
1eb2 9090 9495
1eb4 8e8c 9493
1eb6 8a88 9291
1eb8 8684 908f
1eba 8281 8e8e
1ebc 807e 8e8d
1ebe 7d7c 8c8b
1ec0 9090 9293
1ec2 9090 9495
1ec4 8e8c 9493
1ec6 8a88 9291
1ec8 8684 908f
1eca 8281 8e8e
1ecc 807e 8e8d
1ece 7c79 8b88
1ed0 8585 8788
1ed2 8585 898a
1ed4 8482 8a89
1ed6 8180 8989
1ed8 7e7d 8888
1eda 7c7b 8888
1edc 7a79 8888
1ede 7873 8782
1ee0 8c8c 8e8f
1ee2 8c8c 9091
1ee4 8a7e 9085
1ee6 7c7a 8483
1ee8 7a7a 8485
1eea 7a7a 8687
1eec 7974 8783
1eee 6e6a 7d79
1ef0 8f8f 9192
1ef2 8f8f 9394
1ef4 8c80 9287
1ef6 7e7b 8684
1ef8 7b7b 8586
1efa 7b7b 8788
1efc 7a78 8887
1efe 7470 837f
1f00 8a8a 8c8d
1f02 8a8a 8e8f
1f04 887c 8e83
1f06 7a78 8281
1f08 7878 8283
1f0a 7878 8485
1f0c 7874 8683
1f0e 716c 807b
1f10 8686 8889
1f12 8686 8a8b
1f14 8479 8a80
1f16 7775 7f7e
1f18 7575 7f80
1f1a 7575 8182
1f1c 7573 8382
1f1e 6c69 7b78
1f20 8787 898a
1f22 8787 8b8c
1f24 857a 8b81
1f26 7876 807f
1f28 7676 8081
1f2a 7675 8282
1f2c 736e 817d
1f2e 6963 7872
1f30 8888 8a8b
1f32 8888 8c8d
1f34 877c 8d83
1f36 7a78 8281
1f38 7878 8283
1f3a 7874 8481
1f3c 6c66 7a75
1f3e 6360 726f
1f40 8787 898a
1f42 87a0 8ba5
1f44 9c98 a29f
1f46 9490 9c99
1f48 897d 9388
1f4a 746d 807a
1f4c 6963 7772
1f4e 5d59 6c68
1f50 8686 8889
1f52 86a1 8aa6
1f54 9e99 a4a0
1f56 9591 9d9a
1f58 8d82 978d
1f5a 776f 837c
1f5c 6962 7771
1f5e 5f5c 6e6b
1f60 8888 8a8b
1f62 88a0 8ca5
1f64 9d99 a3a0
1f66 9693 9e9c
1f68 908e 9a99
1f6a 7f75 8b82
1f6c 6e60 7c6f
1f6e 5d5b 6c6a
1f70 8686 8889
1f72 86a3 8aa8
1f74 a09c a6a3
1f76 9995 a19e
1f78 9188 9b93
1f7a 776e 837b
1f7c 695f 776e
1f7e 5c59 6b68
1f80 8484 8687
1f82 849a 889f
1f84 9794 9d9b
1f86 918f 9998
1f88 8c85 9690
1f8a 746c 8079
1f8c 664f 745e
1f8e 4d48 5c57
1f90 7878 7a7b
1f92 7897 7c9c
1f94 928f 9896
1f96 8b88 9391
1f98 857a 8f85
1f9a 6e66 7a73
1f9c 5d42 6b51
1f9e 3e3a 4d49
1fa0 7171 7374
1fa2 7196 759b
1fa4 918b 9792
1fa6 8581 8d8a
1fa8 7a69 8474
1faa 5d55 6962
1fac 4c37 5a46
1fae 3431 4340
1fb0 5959 5b5c
1fb2 5959 5d5e
1fb4 5755 5d5c
1fb6 5351 5b5a
1fb8 4f4c 5957
1fba 3d31 493e
1fbc 2827 3636
1fbe 221f 312e
1fc0 5858 5a5b
1fc2 5858 5c5d
1fc4 5654 5c5b
1fc6 514f 5958
1fc8 4e4c 5857
1fca 3d30 493d
1fcc 2727 3536
1fce 221f 312e
1fd0 5656 5859
1fd2 5656 5a5b
1fd4 5451 5a58
1fd6 4f4d 5756
1fd8 4a49 5454
1fda 392d 453a
1fdc 2220 302f
1fde 1a14 2923
Sum = f529/1b4d

::::::::::::::::::::::::

If you manually add the first two fields(0ad7 e4b3) to the corresponding
sums (f529,1b4d), the sums would both become 0x10000. But the '1' falls
off, of course. The result for the other pair of files is similar, but
omitted to save *some* bandwidth.

HTH,
AvK

sr5guy

unread,
Dec 17, 2006, 2:38:58 PM12/17/06
to
> > Would it be possible for someone to make a quick and dirty .exe utility
> > with this code for the dos/windows platform, so that I can make use of
> > it? I don't have any idea of what needs to be done.
>
> If I/my program is correct, you should do nothing: the files
> have the same (correct?) checksum: they all add up to zero.


Let me clarify, I want to make my own custom changes to the ROM file
and then have the checksum add back up to zero by modifying the word at
0x00. I need some type of utility to do this.

Thanks,
Matt

Message has been deleted
Message has been deleted

moi

unread,
Dec 17, 2006, 4:01:01 PM12/17/06
to
On Sun, 17 Dec 2006 11:40:14 -0800, sr5guy wrote:

>> > Would it be possible for someone to make a quick and dirty .exe utility
>> > with this code for the dos/windows platform, so that I can make use of
>> > it? I don't have any idea of what needs to be done.
>>
>> If I/my program is correct, you should do nothing: the files
>> have the same (correct?) checksum: they all add up to zero.
>
>

> Let me clarify, I want to make my own custom changes to the ROM file
> and then have the checksum add back up to zero by modifying the word at
> 0x00. I need some type of utility to do this.
>
> Thanks,
> Matt

Oops, sorry I misunderstood you.
Anyway, we seem to agree on the checksum algorithm :-)

New, *updated* program will also calculate the bytes you need to put
into the first two spots of the ROM.
I cannot provide you with a .EXE file, cause I have no access to a
dos/windows machine...
The code should compile fine, I guess.

There she goes ....

_______________________________________

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>

#define ROM_SIZE (16* 1024)
unsigned char bank1[ROM_SIZE];
unsigned char bank2[ROM_SIZE];

void read_one(unsigned char *buff, char *name);

int main(int argc, char **argv)

{


unsigned short sum1, sum2, val1, val2;
unsigned idx;

read_one(bank1, argv[1] );
read_one(bank2, argv[2] );

sum1 = sum2 = 0;
for (idx = 0 ; idx < ROM_SIZE; idx += 2) {
/* Silly way to impose byte ordering ... */

val1 = bank1[idx+1] + (bank1[idx+0] <<8);
val2 = bank2[idx+1] + (bank2[idx+0] <<8);


if (idx) { sum1 += val1; sum2 += val2; }

if (val1 == val2) continue;
fprintf(stdout, "%4x %04hx %04hx\n", idx, val1, val2);
}
fprintf(stdout, "Sum = %04hx/%04hx\n", sum1, sum2);

fprintf(stdout, "First bytes should be : %04hx/%04hx\n", 0x10000 - sum1, 0x10000 - sum2);
fprintf(stdout, "But in lo.hi-byte notation, this will appear as \"%02hx.%02hx\" and \"%02hx.%02hx\", respectively\n"
, 0xff &(0x10000 - sum1), 0xff & ( 0x10000 - sum1) >>8
, 0xff &(0x10000 - sum2), 0xff & ( 0x10000 - sum2) >>8
);
exit(0);
}

void read_one(unsigned char *buff, char *name)
{
unsigned pos;
int fd, rc;

fd = open(name, O_RDONLY);
if (fd < 0) exit(1);

for (pos = 0; pos < ROM_SIZE; pos += rc) {
rc = read(fd, buff+pos, ROM_SIZE - pos);
if (rc <= 0) break;
}

close (fd);
if (pos < ROM_SIZE) exit(2);
}

__________________________________________-

HTH,
AvK

sr5guy

unread,
Dec 18, 2006, 3:28:39 AM12/18/06
to
> Oops, sorry I misunderstood you.
> Anyway, we seem to agree on the checksum algorithm :-)
>
> New, *updated* program will also calculate the bytes you need to put
> into the first two spots of the ROM.
> I cannot provide you with a .EXE file, cause I have no access to a
> dos/windows machine...
> The code should compile fine, I guess.

I tried to download a windows compiler and compile this code.
Unfortunetly, it did not work out for me. Just in case, what type of
operating system are you running and what compiler did you use to
succesfully compile and use the program?

Thanks,
Matt

moi

unread,
Dec 18, 2006, 3:33:45 AM12/18/06
to
On Mon, 18 Dec 2006 00:28:39 -0800, sr5guy wrote:


>> I cannot provide you with a .EXE file, cause I have no access to a
>> dos/windows machine...
>> The code should compile fine, I guess.
>
> I tried to download a windows compiler and compile this code.
> Unfortunetly, it did not work out for me. Just in case, what type of
> operating system are you running and what compiler did you use to
> succesfully compile and use the program?

GNU/Linux/gcc.

AvK

sr5guy

unread,
Dec 18, 2006, 3:39:40 AM12/18/06
to

Thanks again for all of your help.

Happy holidays to you and your family!

sr5guy

unread,
Dec 18, 2006, 3:50:51 AM12/18/06
to

> Oops, sorry I misunderstood you.
> Anyway, we seem to agree on the checksum algorithm :-)

I missed this one before, yes I do agree with you. This seems very
similiar to the way that the honda civics compute their 8 bit
checksums. Check this wiki out.
http://www.pgmfi.org/twiki/bin/view/Library/CheckSum

-Matt

Sjouke Burry

unread,
Dec 18, 2006, 4:09:51 AM12/18/06
to
microsoft 16 bit c6:7 warnings,and an exe,
watcom 32 bit:one warning and an exe.
0 new messages