360trev
Full Member
Karma: +68/-2
Offline
Posts: 235
|
|
« Reply #75 on: January 03, 2013, 05:51:01 AM »
|
|
|
You can find at least 3 checksums, and then see if there are any other matches, and if there are other matches, then see if any of them are around there 6 bytes off, if you want to do it. As for other then VAG roms, I am clueless. I just mainly tune VAG for now. However, if you donated me a Ferrari, I might be more inclined to figure things about Ferraris. There is no "actual CRC32 routine" it just compares the calculated sum to stored value... If you looked and understood the ECU routine, you'd see what I mean. For now you will have to trust me and implement it the way I say I'd love to be able to donate a Ferrari to you but then I'd be Ferrari-less so it would be a bit pointless really ...It took me many years to get that toy i can tell you that! Just to clarify the "no actual crc32 routine" point. Are you saying they have 'in-lined' the calculated sum function in the code? You describe it compares the 'calculated' sum with the 'stored' value - so where exactly did it 'calculate' it? inline or in a subroutine? (or multiple subroutines?). I can see you have considerable experience with this architecture and I appreciate all the help. I aim to get up to speed quickly (due to my asm background I'm confident I will). In terms of the routines, I'd love to explore them, what rom file are we talking about and can you give me a byte offset? Also what the segmentation register values should be... -T
|
|
|
Logged
|
|
|
|
prj
|
|
« Reply #76 on: January 03, 2013, 06:11:25 AM »
|
|
|
Okay basically it calculates one sum at a time per pass of the routine. 1st pass, calculate 1st sum. 2nd pass, check 1st sum against stored ROM value. 3rd pass, calculate 2nd sum. 4th pass, check 2nd sum against stored ROM value. etc. This is probably done to reduce load on the ECU as it is a very computation intensive process. So while there is a CRC routine, it's not called where the calculated value is checked, the routine at 0x7ED8 (which is in CPU ROM btw), just loads stuff from ROM to RAM. Damn you and your curiosity I was unable to locate this in the Ferrari 360 binary btw. At least not in the 15 minutes I spent looking at it. Because I do not tune Ferraris, it is not in my interest to allocate more time to it at the moment :/
|
|
|
Logged
|
|
|
|
phila_dot
|
|
« Reply #77 on: January 03, 2013, 06:48:07 AM »
|
|
|
There are nested loops.
Outer loop starts at the beginning of it's designated region/zone and calculates current start address to pass to CRC routine. The outer loop also passes number of bytes to be processed per iteration of the CRC routine, which is 176 (B0h) in the ME7 files that I looked at. The outer loop runs until the end of the desinated region is reached. The start address, end address - 1, and number of bytes to process per inner loop iteration are hardcoded in this portion of code.
The inner loop is the CRC routine itself. It runs from the start address passed from the outer for the number of bytes passed (176 except final iteration). This calculates the actual CRC. The hash table location is hardcoded in this routine.
On the final iteration of the outer loop, a flag is set signalling the calculated CRC to be compared to the checksum stored in the file. After the checks are compared, the flag is changed again to signal for the next region's calculation to begin. It continues like this until all regions are complete.
I hope that makes sense, it was from memory.
It shouldn't be hard at all to use a pattern to find everything needed. The code is unique and everything needed is hardcoded. The code for the different regions is duplicated sequentially.
I took a quick peek at the K-box and it is a little different. The third regions end address was different and there was another portion that gets processed after the final loop of the third region. I didn't get a chance to really go through it though.
Also looked at the Op's file briefly and found similar checking routines. Again, didn't really get a chance to go through it.
|
|
|
Logged
|
|
|
|
360trev
Full Member
Karma: +68/-2
Offline
Posts: 235
|
|
« Reply #78 on: January 03, 2013, 06:50:12 AM »
|
|
|
Okay basically it calculates one sum at a time per pass of the routine. 1st pass, calculate 1st sum. 2nd pass, check 1st sum against stored ROM value. 3rd pass, calculate 2nd sum. 4th pass, check 2nd sum against stored ROM value. etc. This is probably done to reduce load on the ECU as it is a very computation intensive process. So while there is a CRC routine, it's not called where the calculated value is checked, the routine at 0x7ED8 (which is in CPU ROM btw), just loads stuff from ROM to RAM. Damn you and your curiosity I was unable to locate this in the Ferrari 360 binary btw. At least not in the 15 minutes I spent looking at it. Because I do not tune Ferraris, it is not in my interest to allocate more time to it at the moment :/ Thanks for the explanation. It makes sense now. Ah, okay, so in addition to the 512kbyte FIRMWARE DUMP file I pulled using Bootmode there is in fact also some resident ROM functions too! (How big is this rom in kbytes, any idea?). This actual CRC function code is one of them in the ROM then! ... So, these rom functions are referenced by the upgradable Firmware but they themselves are not upgradable (sort of like a re-usable utils library). Hmmm, so if I can dump the rom functions I should be able to understand exactly what they do.... Q. Has anyone dumped the ROM regions (and reversed them?), are they read protected? If not I assume someone could write a similar tool to the dump EEPROM one for this purpose (anyone actually done it?). I can only assume the VAG rom is quite a bit different than the 360 one hence the reason why the searching didn't find anything. Its probably in a different location and may even be a different variant of the function (slightly modified or older/newer version of the routine). Last question then (sorry to have consumed so much time!) how necessary are these additional checks? could I not just 'nop' them out? since they seem to be crc's on top of crc's (i.e possibly a bit of overkill...) -T
|
|
|
Logged
|
|
|
|
prj
|
|
« Reply #79 on: January 03, 2013, 07:40:15 AM »
|
|
|
Thanks for the explanation.
It makes sense now. Ah, okay, so in addition to the 512kbyte FIRMWARE DUMP file I pulled using Bootmode there is in fact also some resident ROM functions too! (How big is this rom in kbytes, any idea?). 32kb, you can pull it out through minimon. This actual CRC function code is one of them in the ROM then! No, the only thing in the ROM here is the function that loads some values from a specified offset into RAM. So, these rom functions are referenced by the upgradable Firmware but they themselves are not upgradable (sort of like a re-usable utils library). Correct. Q. Has anyone dumped the ROM regions (and reversed them?), are they read protected? If not I assume someone could write a similar tool to the dump EEPROM one for this purpose (anyone actually done it?). Yes, there are a few different ROM versions. Some VAG ME7 flash firmware files actually have the ROM image embedded in the first 0x0000-0x7FFF, but in others 0x0000-0x7FFF already contains different user area code. I can only assume the VAG rom is quite a bit different than the 360 one hence the reason why the searching didn't find anything. Its probably in a different location and may even be a different variant of the function (slightly modified or older/newer version of the routine). The CRC32 stuff is entirely in flash. Last question then (sorry to have consumed so much time!) how necessary are these additional checks? could I not just 'nop' them out? since they seem to be crc's on top of crc's (i.e possibly a bit of overkill...) You can do whatever you want. It's just a computer and you are capable of programming.
|
|
« Last Edit: January 03, 2013, 07:42:08 AM by prj »
|
Logged
|
|
|
|
nyet
|
|
« Reply #80 on: January 03, 2013, 10:38:32 AM »
|
|
|
And the mask you have to find: E6 F4 FF FF E6 F5 FF FF DA 00 D8 7E FF - masked out byte. You need to find all matches of that mask, the first FF FF is the low word of the address, the second FF FF is the high word. There should be three sequential ones, where the the pointed values are 6 bytes apart, these are the checksum locations. I am sure you guys can adapt this function or the idea behind it to work on a file instead of RAM Yes. I have a needle/haystack/mask function, but it works a bit differently since it is based on chipselect algorithms (and i'm using this to detect checksum block descriptor areas) static int memcmp_mask(const void *ptr1, const void *ptr2, const void *mask, size_t len) { const uint8_t *p1 = (const uint8_t*)ptr1; const uint8_t *p2 = (const uint8_t*)ptr2; const uint8_t *m = (const uint8_t*)mask;
while(len--) { int diff = m?(*p2 & *m)-(*p1 & *m):*p2-*p1; if (diff) return diff>0?1:-1; p1++; p2++; if (m) m++; } return 0; }
The idea is that it can mask out individual bits, not just whole bytes, and also search for bytes that match 0xff (if both needle and mask are 0xff) so "E6 F4 FF FF E6 F5 FF FF DA 00 D8 7E" becomes needle = E6 F4 00 00 E6 F5 00 00 DA 00 D8 7E mask = ff ff 00 00 ff ff 00 00 ff ff ff ff
I'll work on it now. Question is, how to find block start/end?
|
|
« Last Edit: January 03, 2013, 11:11:32 AM by nyet »
|
Logged
|
ME7.1 tuning guideECUx PlotME7Sum checksumTrim heatmap toolPlease do not ask me for tunes. I'm here to help people make their own. Do not PM me technical questions! Please, ask all questions on the forums! Doing so will ensure the next person with the same issue gets the opportunity to learn from your ex
|
|
|
nyet
|
|
« Reply #81 on: January 03, 2013, 11:02:51 AM »
|
|
|
Ok. Code works Searching for main ROM CRC offsets... Found CRC #1 at 0x86bd8a (decoded from 0x6c18e) Found CRC #2 at 0x86bd90 (decoded from 0x6c220) Found CRC #3 at 0x86bd96 (decoded from 0x6c2b0) Adr: 0x010000-0x013FFF @0x6bd8a CRC: 0x22402F9B CalcCRC: 0x22402F9B CRC OK Adr: 0x014300-0x017F67 @0x6bd90 CRC: 0xE359D549 CalcCRC: 0xE359D549 CRC OK Adr: 0x018191-0x01FBFF @0x6bd96 CRC: 0x3E37E205 CalcCRC: 0x3E37E205 CRC OK
thanks prj. we just need the regions now ..
|
|
« Last Edit: January 03, 2013, 11:16:17 AM by nyet »
|
Logged
|
ME7.1 tuning guideECUx PlotME7Sum checksumTrim heatmap toolPlease do not ask me for tunes. I'm here to help people make their own. Do not PM me technical questions! Please, ask all questions on the forums! Doing so will ensure the next person with the same issue gets the opportunity to learn from your ex
|
|
|
prj
|
|
« Reply #82 on: January 03, 2013, 12:07:29 PM »
|
|
|
Ok for block start/end it is a bit more tricky.
I masked out bytes with XX and marked high word and low word with HH and LL.
For 29F800: Offset start positions: E6 F8 LL LL E6 F9 HH 00 F2 F4 XX XX 24 8F Offset end positions: 10 9B E6 F4 LL LL E6 F5 HH 00 26 F4
29F400 routines are a wee bit different, but I think for 29F400 just assume the same locations every time, the ones that worked for C box. Test it with a few binaries, but I think all 29F400 are the same.
|
|
|
Logged
|
|
|
|
nyet
|
|
« Reply #83 on: January 03, 2013, 01:05:46 PM »
|
|
|
Ok. summary time:
these worked: 4B0907551L 4Z7907551K 8D0907551A 8D0907551B 8D0907551D 8D0907551G 8D0907551H 8D0907551J 8D0907551L 8D0907551M
these didn't find any: 4Z7907551S 8D0907551C 8D0907551T
these found more than 3 (they found 4), and none of them match up 8D0907551F 8D0907551K 8D0907551Q
obviously, ferrari's didn't work at all.
|
|
|
Logged
|
ME7.1 tuning guideECUx PlotME7Sum checksumTrim heatmap toolPlease do not ask me for tunes. I'm here to help people make their own. Do not PM me technical questions! Please, ask all questions on the forums! Doing so will ensure the next person with the same issue gets the opportunity to learn from your ex
|
|
|
phila_dot
|
|
« Reply #84 on: January 03, 2013, 01:12:48 PM »
|
|
|
Ok. summary time:
these worked: 4B0907551L 4Z7907551K 8D0907551A 8D0907551B 8D0907551D 8D0907551G 8D0907551H 8D0907551J 8D0907551L 8D0907551M
these didn't find any: 4Z7907551S 8D0907551C 8D0907551T
these found more than 3 (they found 4), and none of them match up 8D0907551F 8D0907551K 8D0907551Q
obviously, ferrari's didn't work at all.
As I stated above, the K box had something extra at the end. I didn't get to analyze it, but it ran after the final iteration of the third region, before the check IIRC.
|
|
|
Logged
|
|
|
|
phila_dot
|
|
« Reply #85 on: January 03, 2013, 04:08:04 PM »
|
|
|
On the K box, the third region runs from 0x818192 everything the same as before except the end address is 0x81FBDD. At the final iteration, the iteration counter gets cleared and the flag gets set to calculate a fourth region instead of signalling to compare the check values.
The fourth region from 0x826A00 to 0x82FFD gets calculated and then checked at 0x89000C.
There is also an intialization, so if the control byte or flag as I've been referring to it isn't set to indicate calculation of any of the regions or check value comparisons, then the CRC value gets an intial calculation from start address 0x8183E9 for ten bytes.
I can try to explain the "control byte" better if this is confusing.
|
|
|
Logged
|
|
|
|
nyet
|
|
« Reply #86 on: January 03, 2013, 04:17:56 PM »
|
|
|
Thanks for the info, phila Here is what I have (using prj's matching pattern) // LL LL HH uint8_t n0[] = {0xE6, 0xF8, 0x00, 0x00, 0xE6, 0xF9, 0x00, 0x00, 0xF2, 0xF4, 0x00, 0x00, 0x24, 0x8F}; uint8_t m0[] = {0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff}; // LL LL HH uint8_t n1[] = {0x10, 0x9B, 0xE6, 0xF4, 0x00, 0x00, 0xE6, 0xF5, 0x00, 0x00, 0x26, 0xF4}; uint8_t m1[] = {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff};
And here are the results for K box: Step #1: Reading main ROM CRC... Searching for main ROM CRC block starts... Found possible CRC block starts #1 at 0x810002 (from 0x9029e) Found possible CRC block starts #2 at 0x814252 (from 0x90318) Found possible CRC block starts #3 at 0x818192 (from 0x90392) Found possible CRC block starts #4 at 0x826a00 (from 0x90410) Too many matches (4). CRC block start find failed Searching for main ROM CRC block ends... Found possible CRC block end #1 at 0x813ffe (from 0x902c0) Found possible CRC block end #2 at 0x817f4e (from 0x9033a) Found possible CRC block end #3 at 0x81fbdc (from 0x903b4) Found possible CRC block end #4 at 0x82fffc (from 0x90432) Too many matches (4). CRC block end find failed Searching for main ROM CRC offsets... Found possible CRC offset #1 at 0x890000 (from 0x904a2) Found possible CRC offset #2 at 0x890006 (from 0x90522) Found possible CRC offset #3 at 0x89000c (from 0x905aa) Found CRC #1 at 0x890000 Found CRC #2 at 0x890006 Found CRC #3 at 0x89000c
What should i do to detect that its different, and should be handled as you describe? Even the first two regions dont work right Adr: 0x810002-0x813FFE @0x90000 CRC: 0x13BFD815 CalcCRC: 0xA13F9F2B ** NOT OK ** Adr: 0x814252-0x817F4E @0x90006 CRC: 0x8C92421A CalcCRC: 0xC52D9DB4 ** NOT OK **
|
|
« Last Edit: January 03, 2013, 04:23:19 PM by nyet »
|
Logged
|
ME7.1 tuning guideECUx PlotME7Sum checksumTrim heatmap toolPlease do not ask me for tunes. I'm here to help people make their own. Do not PM me technical questions! Please, ask all questions on the forums! Doing so will ensure the next person with the same issue gets the opportunity to learn from your ex
|
|
|
phila_dot
|
|
« Reply #87 on: January 03, 2013, 04:28:25 PM »
|
|
|
Add the intial CRC for the ten bytes from 0x8183E9 and see if that fixes the first two. E6 FC LL LL E6 FD HH HH E0 sE DA XX XX XX F6 F4
s == length in bytes
|
|
« Last Edit: January 03, 2013, 04:57:05 PM by phila_dot »
|
Logged
|
|
|
|
360trev
Full Member
Karma: +68/-2
Offline
Posts: 235
|
|
« Reply #88 on: January 03, 2013, 04:52:21 PM »
|
|
|
Nyet, I have been studying 8D0907551C dump and I have found the full Multipoint checksum routine and from this we should be able to derive the addresses (physical file offset which contains the actual values). In this rom the function which initializes the multipoint checksum with the START and END addresses looks like this.... // // FYI: It starts at file offset 0x6B972 in 8D0907551C dump // // // [physical memory start offset = 0x86b972, dump file byte offset = x6b972] // _InitMultipoint: mov initvar1, ZEROS ; {F6} 8E, {FA 80} offset+x80fa mov initvar2, ZEROS ; {F6} 8E, {FC 80} offset+x80fc movb initvar3, ZEROS ; {F7} 8E, {03 81} offset+x0381
extp #518, #2 ; {D7} 50 06 02 mov r4, MainRom_Checksum_START_Low ; {F2} F4,{ E6 3F } offset+x3fe6 [file offset=x6b982] mov r5, MainRom_Checksum_START_High ; {F2} F5,{ E8 3F } offset+x3fe8 [file offset=x6b986]
mov MainRom_Checksum_START_Low_cpy, r4 ; {F6} F4,{ FE 80 } offset+x80fe [file offset=x6b98a] mov MainRom_Checksum_START_High_cpy, r5 ; {F6} F5,{ 00 81 } offset+x8100 [file offset=x6b98e]
movb rl4, #1 ; {E1} 18 movb loop_counter, rl4 ; {F7} F8 { 02 81 } offset+x8102 extp #518, #2 ; {D7} 50 { 06 02 } ;x0206 == 518 decimal
mov r4, MainRom_Checksum_END_Low ; {F2} F4 { EA 3F } offset+x3fea [file offset=x6b99c] mov r5, MainRom_Checksum_END_High ; {F2} F5 { EC 3F } offset+x3fec [file offset=x6b9a0]
mov MainRom_Checksum_End_Low_Cpy, r4 ; {F6} F4 { 04 81 } offset+x8104 mov MainRom_Checksum_End_High_Cpy, r5 ; {F6} F5 { 06 81 } offset+x8106
rets ; {DB 00}
// I further noticed the field referenced by the code are in these locations // asm offset x3fe6 - (1bfe6 is MainRom_Checksum_START_Low) - phy addr 81bfe6, file offset 1bfe6 // asm offset x3fe8 - (1bfe8 is MainRom_Checksum_START_Low) - phy addr 81bfe8, file offset 1bfe8 // asm offset x3fea - (1bfe6 is MainRom_Checksum_END_Low) - phy addr 81bfea, file offset 1bfea // asm offset x3fec - (1bfe8 is MainRom_Checksum_END_Low) - phy addr 81bfec, file offset 1bfec The question now is how to convert the asm instruction relative offsets to byte offsets in the file? ...I believe a clue is to do with the segmented memory model of the C167, [c167 asm guys help me out here!]. I can provide the full routine I reversed if anyones interested, it does the full multi-point checksum and starts in this rom at byte offset x6b9ae.
|
|
|
Logged
|
|
|
|
nyet
|
|
« Reply #89 on: January 03, 2013, 04:56:30 PM »
|
|
|
Phila: that fixed the first block, but nothing else. Adr: 0x810002-0x813FFE @0x90000 CRC: 0x13BFD815 CalcCRC: 0x13BFD815 CRC OK Adr: 0x814252-0x817F4E @0x90006 CRC: 0x8C92421A CalcCRC: 0x1382383A ** NOT OK ** Adr: 0x818192-0x81FBDC+0x826A00-0x82FFFC @0x9000c CRC: 0xC95513B5 CalcCRC: 0xFF232A87 ** NOT OK **
the other 2 two still dont work (with or without the added crc)
360: it already detects the multipoint no problem; i just loosened the matching parameters some (see latest git checkin).. what i cant' find is the CRC blocks
|
|
|
Logged
|
ME7.1 tuning guideECUx PlotME7Sum checksumTrim heatmap toolPlease do not ask me for tunes. I'm here to help people make their own. Do not PM me technical questions! Please, ask all questions on the forums! Doing so will ensure the next person with the same issue gets the opportunity to learn from your ex
|
|
|
|