BMW M5 Forum and M6 Forums banner

61 - 80 of 84 Posts

·
Registered
Joined
·
1,345 Posts
Discussion Starter #61
I'll see if I can follow the code through at some point this weekend, if you don't see anything else obvious.
 

·
Registered
Joined
·
94 Posts
:1080B000020000000100D9FE030000000400FFFEE2
:0A80C0100600DAFE020000FF0200C5
:020000020000FC
:020000040007F3
:1080CA0020000000F765336EA85DAE3FB1EA716B20
:1080DA00AAFE64BBDADC1E39166F067EB572481832
:1080EA00401923BD8FAC07A855444295DC33E5BE41
:1080FA000417360263F512835CE2B1A4CEA98A1989
:10810A00ED3D4E415309D95D60F04586685937B552
:10811A00B0DF507E0EC782BC5D91691A76051F4991
:10812A001AC2676B1FB71D10B1D711F9F94CA9858F
:10813A00C091F6C7249939EC746385FC86255B2ABD
:04814A10ECD3E0483A
Looks fine to me..
 

·
Registered
Joined
·
225 Posts
Yeah that looks okay.

@Ferris - just to be sure, did you modify anything in the program space with your eeprom burner?

Edit: So I think I found the code that does the RSA validation. As far as I can tell, it's not doing anything differently than what other contemporary BMW modules do. I'm at a loss as to what's going wrong.
 

·
Registered
Joined
·
1,345 Posts
Discussion Starter #65
Yeah that looks okay.

@Ferris - just to be sure, did you modify anything in the program space with your eeprom burner?

Edit: So I think I found the code that does the RSA validation. As far as I can tell, it's not doing anything differently than what other contemporary BMW modules do. I'm at a loss as to what's going wrong.
I'll give it another go, maybe it was user error ;)

Nothing is modified in the program.
 

·
Registered
Joined
·
1,345 Posts
Discussion Starter #66
Well sadly I can't edit the first post so I'm going to have just drop info in subsequent posts...

Byte 0x782d1 is mode memory 1 enabled 0 disabled.

I think the last bytes in that row are the settings when there is no memory.
Don't do this.. I think it may have prevented power down or the car to sleep, as the car was completely dead this morning when I went to do some more tests. Back to the drawing board I guess.
 

·
Registered
Joined
·
1,345 Posts
Discussion Starter #67
When the Data area is flashed if it passes the RSA check it writes to 0x78000, I was hoping to just set the pass bytes in the 0da but it triggers a security error in WINKFP. So it's back the drawing board in an easy for anyone just to flash.

In the meantime, it makes sense to make progress on the maps and data . So I went down the Minimon path, I was able to get it to connect and map the ROM and RAM, My fear about the watch dog on the pmic was valid but I was able to bypass it and not fire the reset. I will however have to write a custom flash driver as the distributed one won't work because what Siemens did with the data lines.

Once I'm able to flash with minimon the plan is to bypass the RSA check, @terrapham pointed me in the right direction and I'll flash the change with minimon and then use winkfp to flash data changes.

It'll be nice to not have to remove rom or drill the rivets anymore. Plus I can modify and restore TCUs ... btw there is also a UIF write limit, I haven't figure it out the number but just a general warning.
 

·
Registered
Joined
·
1,387 Posts
It'll be nice to not have to remove rom or drill the rivets anymore. Plus I can modify and restore TCUs ... btw there is also a UIF write limit, I haven't figure it out the number but just a general warning.
Jim has mentioned the UIF limit being not applicable to TCUs. Now whether he's actually tested whether you can keep on writing or not I doubt it. But why must you update the UIF? Winkfp allows you to flash without updating UIF.
 

·
Registered
Joined
·
1,345 Posts
Discussion Starter #69
Jim has mentioned the UIF limit being not applicable to TCUs. Now whether he's actually tested whether you can keep on writing or not I doubt it. But why must you update the UIF? Winkfp allows you to flash without updating UIF.
Meh there really would be no reason to write the uif and it's not like we have 100s of tunes to try and play with it. So I'm sure no one will ever hit it, but it's still good to know it exists. I should look into if there is a max write limit,regardless of the UIF, like some dme's have. If anyone would hit it I'd assume I will so then we'll know for sure. It's just a general observation
 

·
Registered
Joined
·
225 Posts
When the Data area is flashed if it passes the RSA check it writes to 0x78000, I was hoping to just set the pass bytes in the 0da but it triggers a security error in WINKFP. So it's back the drawing board in an easy for anyone just to flash.
Yeah those bytes are protected. I know on the BMW automatic transmissions, the strategy used is to modify a RAM variable that stores the allowable writeable segments, and then just write the pass values - I'm not sure that's an option here. I'd have to reload my IDA files with the proper memory map to see what's going on in RAM.

Another trick that might be worth giving a shot is just writing a stock tune to 0x70000 (if not protected) and changing the RSA pointers to there. Though I suspect that will fail too even if there's no write protection since the pointers to the program space should have worked as well.
 

·
Registered
Joined
·
1,345 Posts
Discussion Starter #71 (Edited)
Minimon turned out to be major pain, but I got it to work for flashing. I had to write the actual flash code ,and because of the way minimon works and limited ram, I have to break up whatever sector I want to flash into small chunks and use a custom script to read a chunk, upload it, and call my flash routine , rinse and repeat , but it works and that's all that matters.

Tomorrow I'm going change the code that does the RSA check and flash it, hopefully this will bypass the checks and I can get to actual tuning. I'd love to get back to the startup mode, mode memory, and the shift points, If all this works on my dev tcu, I'll recover the donate dTCU's UIF, patch the code, and use that as my in car TCU.

Interesting to note, The flash has two BUSCONS, Buscon 0 and 2, I found that it only works if you read on it's buscon0's address but write to it's buscon's 2 address. I assume this is done for a reason, and might help make more sense of some the IDA routines. I have to look back at them but I think it does answer a few things I've noticed.
 

·
Registered
Joined
·
883 Posts
My brain hurts reading this lol!

Tell me when the engineers code this stuff do they have some sort of proprietary software that mumbos everything up like this? Lol
 

·
Registered
Joined
·
1,345 Posts
Discussion Starter #74
My brain hurts reading this lol!

Tell me when the engineers code this stuff do they have some sort of proprietary software that mumbos everything up like this? Lol
LOL not at all we're dealing with the binaries on production hardware, so it's a matter of reverse engineering the whole system with no insight from effectively machine code. The engineers have the full source, emulators, debuggers ect ect. I'd give my left nut for the factory code.

When it comes to DMEs a lot of stuff is already known or leaked(or can be bought) and there is a whole tuning support market born from it. You can buy programmers, flash tools ect ect that already handle security bypass and flashing, it's actually big money and now with everything going turbo it's even more profitable. Most Tuners are just buying these tools, and off the shelf tunes and simply reselling them,but that's a story for another day...... but no one cares about the transmission. so we're pretty much on day one here. Hence the excitement from even the smallest milestones.

Fortunately the there is a ton of community knowledge from what the E46 M3 guys learned from their MSS54 reverse engineering project, They went way behind the typical maps and into how BMW/Siemens/Bosch handles security and data validation, how the actual DME works ect ect. The knowledge they have is beyond valuable and I'm happy they pop in here to share what they know. The only other person I know with that kind of knowledge is Jim Comforti(shark injector) and Steve Dinan, but I think they have the actual source code.
 

·
Registered
Joined
·
1,345 Posts
Discussion Starter #75 (Edited)
Progress Made

With help from @terraphantm pointing out the bootloader CRC location, I was able to patch the bootloader to bypass the security check so I no longer have to remove the TCU for flashing. Basically I changed a jmp to a nop and a return from -1 to 0, and now it'll take data updates from winkfp. I also wrote a program that converts the bin back to 0da using an existing 0da as a template. This allows me make changes in tuner pro , correct the crc then export it so I can flash it with winkfp.

I've also identified the start mode for auto and manual, my car now starts in D5 and S5. I also think I have a few other things working but am working on verifying them this week. The next goals are to change the shift maps, I personally think the car bogs itself and cruise at too low of an rpm in auto mode. Followed by the shift characteristics and maybe eliminate that damn second gear start( though I'll never be in D1 again :)


My plan is to put together an xdf and host all this on github instead of updating files here.

If anyone has a spare tcu and would like to join, I'll gladly patch it and mail it back to you.

I'm also including my new and improved hex to bin utility, BMW uses some special codes I didn't account for and the file should be filled with ffs.
 

Attachments

·
Registered
Joined
·
225 Posts
Awesome, glad it worked! Bypassing security without having to remove the module ever would be the ideal situation of course, but this at least allows you to experiment much more readily.

When you were examining the code, did you see any reason why the previously attempted RSA bypass didn't work?

Also here's the latest variant of the python code:

Code:
import sys
import struct
import hashlib

def swap(x):
    upper = x << 8
    lower = x >> 8

    return (upper + lower) & 0xFFFF

def reverse(text):
    if len(text) <= 2:
        return text

    return reverse(text[2:]) + text[0:2]

def crc_16_fast(crc,msg):
    
    table = (
    0x0000, 0xc0c1, 0xc181, 0x0140, 0xc301, 0x03c0, 0x0280, 0xc241,
    0xc601, 0x06c0, 0x0780, 0xc741, 0x0500, 0xc5c1, 0xc481, 0x0440,
    0xcc01, 0x0cc0, 0x0d80, 0xcd41, 0x0f00, 0xcfc1, 0xce81, 0x0e40,
    0x0a00, 0xcac1, 0xcb81, 0x0b40, 0xc901, 0x09c0, 0x0880, 0xc841,
    0xd801, 0x18c0, 0x1980, 0xd941, 0x1b00, 0xdbc1, 0xda81, 0x1a40,
    0x1e00, 0xdec1, 0xdf81, 0x1f40, 0xdd01, 0x1dc0, 0x1c80, 0xdc41,
    0x1400, 0xd4c1, 0xd581, 0x1540, 0xd701, 0x17c0, 0x1680, 0xd641,
    0xd201, 0x12c0, 0x1380, 0xd341, 0x1100, 0xd1c1, 0xd081, 0x1040,
    0xf001, 0x30c0, 0x3180, 0xf141, 0x3300, 0xf3c1, 0xf281, 0x3240,
    0x3600, 0xf6c1, 0xf781, 0x3740, 0xf501, 0x35c0, 0x3480, 0xf441,
    0x3c00, 0xfcc1, 0xfd81, 0x3d40, 0xff01, 0x3fc0, 0x3e80, 0xfe41,
    0xfa01, 0x3ac0, 0x3b80, 0xfb41, 0x3900, 0xf9c1, 0xf881, 0x3840,
    0x2800, 0xe8c1, 0xe981, 0x2940, 0xeb01, 0x2bc0, 0x2a80, 0xea41,
    0xee01, 0x2ec0, 0x2f80, 0xef41, 0x2d00, 0xedc1, 0xec81, 0x2c40,
    0xe401, 0x24c0, 0x2580, 0xe541, 0x2700, 0xe7c1, 0xe681, 0x2640,
    0x2200, 0xe2c1, 0xe381, 0x2340, 0xe101, 0x21c0, 0x2080, 0xe041,
    0xa001, 0x60c0, 0x6180, 0xa141, 0x6300, 0xa3c1, 0xa281, 0x6240,
    0x6600, 0xa6c1, 0xa781, 0x6740, 0xa501, 0x65c0, 0x6480, 0xa441,
    0x6c00, 0xacc1, 0xad81, 0x6d40, 0xaf01, 0x6fc0, 0x6e80, 0xae41,
    0xaa01, 0x6ac0, 0x6b80, 0xab41, 0x6900, 0xa9c1, 0xa881, 0x6840,
    0x7800, 0xb8c1, 0xb981, 0x7940, 0xbb01, 0x7bc0, 0x7a80, 0xba41,
    0xbe01, 0x7ec0, 0x7f80, 0xbf41, 0x7d00, 0xbdc1, 0xbc81, 0x7c40,
    0xb401, 0x74c0, 0x7580, 0xb541, 0x7700, 0xb7c1, 0xb681, 0x7640,
    0x7200, 0xb2c1, 0xb381, 0x7340, 0xb101, 0x71c0, 0x7080, 0xb041,
    0x5000, 0x90c1, 0x9181, 0x5140, 0x9301, 0x53c0, 0x5280, 0x9241,
    0x9601, 0x56c0, 0x5780, 0x9741, 0x5500, 0x95c1, 0x9481, 0x5440,
    0x9c01, 0x5cc0, 0x5d80, 0x9d41, 0x5f00, 0x9fc1, 0x9e81, 0x5e40,
    0x5a00, 0x9ac1, 0x9b81, 0x5b40, 0x9901, 0x59c0, 0x5880, 0x9841,
    0x8801, 0x48c0, 0x4980, 0x8941, 0x4b00, 0x8bc1, 0x8a81, 0x4a40,
    0x4e00, 0x8ec1, 0x8f81, 0x4f40, 0x8d01, 0x4dc0, 0x4c80, 0x8c41,
    0x4400, 0x84c1, 0x8581, 0x4540, 0x8701, 0x47c0, 0x4680, 0x8641,
    0x8201, 0x42c0, 0x4380, 0x8341, 0x4100, 0x81c1, 0x8081, 0x4040
    )
    
    for byte in msg:
        if sys.version_info[0] < 3:
            crc = table[(crc^ord(byte))&0xff] ^ (crc >>8)
        else:
            crc = table[(crc^byte)&0xff] ^ (crc >>8)
    return crc & 0xFFFF

if len(sys.argv) == 1:
    if sys.version_info[0] < 3:
        filename = raw_input("Enter path/filename: ")
    else:
        filename = input("Enter path/filename: ")
    print ("Note: You can also give filename as a command line argument")
else:
    filename = sys.argv[1]

def getChecksums(address, file):
    file.seek(address)
    storedCS = struct.unpack('>H',file.read(2))[0]
    file.seek(address + 2)
    numberOfSegments = struct.unpack('<H',file.read(2))[0]
    calcCS = 0x5858
    
    for x in range(numberOfSegments):
        file.seek(address + 4 + 8*x)
        start = struct.unpack('<L',file.read(4))[0]
        file.seek(address + 8 + 8*x)
        end = struct.unpack('<L',file.read(4))[0]
        file.seek(start)
        calcCS = crc_16_fast(calcCS,file.read((end - start) + 1))

    return storedCS, swap(calcCS)

def verifySignature(address, file):
    file.seek(address)
    numberOfSegments = struct.unpack('<H',file.read(2))[0]
    md5 = hashlib.md5()
    
    for x in range(numberOfSegments):
        file.seek(address + 2 + 8*x)
        start = struct.unpack('<L',file.read(4))[0]
        file.seek(address + 18 + 4*x)
        length = struct.unpack('<L',file.read(4))[0]
        file.seek(start)
        md5.update(file.read(length))

    signature = 0
    for x in range (0x20):
        file.seek(address + 26 + (0x80 - x*4))
        signature = (signature << 32) + struct.unpack('<L',file.read(4))[0]
        
    n = 0xAB76AA1E9E5B37269D53883564E991BB9CD9DEDDC8BEE75CEB847A3F77965480DBEF70365D7448E396380618E7B3E3657AB58079C1CB0B1169690EE865581236D81947C8EADE9EA65EB3D510AA3818034BDE4323B29AF2139E0260C96ABBFB4B569894AAA270A36151FDA214ABAD1BE4737C72704D048E2D767866C8B1550549
    decryptedSig = pow(signature, 3, n)
    
    return reverse(format((decryptedSig),'02x')), md5.hexdigest()
    
    
in_file = open(filename,"rb")

bootStored, bootCalc = getChecksums(0x3eec, in_file)
progStored, progCalc = getChecksums(0x3fda6, in_file)
dataStored, dataCalc = getChecksums(0x78090, in_file)

progSigDecrypted, progmd5 = verifySignature(0x3fec0, in_file)
dataSigDecrypted, datamd5 = verifySignature(0x780b0, in_file)

print ("Boot Checksum (stored): " + hex(bootStored))
print ("Boot Checksum (calculated): " + hex(bootCalc))
print ("Program Checksum (stored): " + hex(progStored))
print ("Program Checksum (calculated): " + hex(progCalc))
print ("Data Checksum (stored): " + hex(dataStored))
print ("Data Checksum (calculated): " + hex(dataCalc))
print ('')
print ("Program MD5 (decrypted): " + progSigDecrypted)
print ("Program MD5 (calculated): " + progmd5)
print ("Data MD5 (decrypted): " + dataSigDecrypted)
print ("Data MD5 (calculated): " + datamd5)
It will show all 3 checksums as well as the program and data MD5s (along with the MD5s from the decrypted signatures). Naturally if you change anything, the hashes will no longer match.

Edit: I might be hitting some m5board limit since not all of my code is showing up above, but the full thing is visible if you quote this post.
 

·
Registered
Joined
·
1,345 Posts
Discussion Starter #77 (Edited)
Awesome, glad it worked! Bypassing security without having to remove the module ever would be the ideal situation of course, but this at least allows you to experiment much more readily.

When you were examining the code, did you see any reason why the previously attempted RSA bypass didn't work?

Also here's the latest variant of the python code:

Code:
import sys
import struct
import hashlib

def swap(x):
    upper = x << 8
    lower = x >> 8

    return (upper + lower) & 0xFFFF

def reverse(text):
    if len(text) <= 2:
        return text

    return reverse(text[2:]) + text[0:2]

def crc_16_fast(crc,msg):
    
    table = (
    0x0000, 0xc0c1, 0xc181, 0x0140, 0xc301, 0x03c0, 0x0280, 0xc241,
    0xc601, 0x06c0, 0x0780, 0xc741, 0x0500, 0xc5c1, 0xc481, 0x0440,
    0xcc01, 0x0cc0, 0x0d80, 0xcd41, 0x0f00, 0xcfc1, 0xce81, 0x0e40,
    0x0a00, 0xcac1, 0xcb81, 0x0b40, 0xc901, 0x09c0, 0x0880, 0xc841,
    0xd801, 0x18c0, 0x1980, 0xd941, 0x1b00, 0xdbc1, 0xda81, 0x1a40,
    0x1e00, 0xdec1, 0xdf81, 0x1f40, 0xdd01, 0x1dc0, 0x1c80, 0xdc41,
    0x1400, 0xd4c1, 0xd581, 0x1540, 0xd701, 0x17c0, 0x1680, 0xd641,
    0xd201, 0x12c0, 0x1380, 0xd341, 0x1100, 0xd1c1, 0xd081, 0x1040,
    0xf001, 0x30c0, 0x3180, 0xf141, 0x3300, 0xf3c1, 0xf281, 0x3240,
    0x3600, 0xf6c1, 0xf781, 0x3740, 0xf501, 0x35c0, 0x3480, 0xf441,
    0x3c00, 0xfcc1, 0xfd81, 0x3d40, 0xff01, 0x3fc0, 0x3e80, 0xfe41,
    0xfa01, 0x3ac0, 0x3b80, 0xfb41, 0x3900, 0xf9c1, 0xf881, 0x3840,
    0x2800, 0xe8c1, 0xe981, 0x2940, 0xeb01, 0x2bc0, 0x2a80, 0xea41,
    0xee01, 0x2ec0, 0x2f80, 0xef41, 0x2d00, 0xedc1, 0xec81, 0x2c40,
    0xe401, 0x24c0, 0x2580, 0xe541, 0x2700, 0xe7c1, 0xe681, 0x2640,
    0x2200, 0xe2c1, 0xe381, 0x2340, 0xe101, 0x21c0, 0x2080, 0xe041,
    0xa001, 0x60c0, 0x6180, 0xa141, 0x6300, 0xa3c1, 0xa281, 0x6240,
    0x6600, 0xa6c1, 0xa781, 0x6740, 0xa501, 0x65c0, 0x6480, 0xa441,
    0x6c00, 0xacc1, 0xad81, 0x6d40, 0xaf01, 0x6fc0, 0x6e80, 0xae41,
    0xaa01, 0x6ac0, 0x6b80, 0xab41, 0x6900, 0xa9c1, 0xa881, 0x6840,
    0x7800, 0xb8c1, 0xb981, 0x7940, 0xbb01, 0x7bc0, 0x7a80, 0xba41,
    0xbe01, 0x7ec0, 0x7f80, 0xbf41, 0x7d00, 0xbdc1, 0xbc81, 0x7c40,
    0xb401, 0x74c0, 0x7580, 0xb541, 0x7700, 0xb7c1, 0xb681, 0x7640,
    0x7200, 0xb2c1, 0xb381, 0x7340, 0xb101, 0x71c0, 0x7080, 0xb041,
    0x5000, 0x90c1, 0x9181, 0x5140, 0x9301, 0x53c0, 0x5280, 0x9241,
    0x9601, 0x56c0, 0x5780, 0x9741, 0x5500, 0x95c1, 0x9481, 0x5440,
    0x9c01, 0x5cc0, 0x5d80, 0x9d41, 0x5f00, 0x9fc1, 0x9e81, 0x5e40,
    0x5a00, 0x9ac1, 0x9b81, 0x5b40, 0x9901, 0x59c0, 0x5880, 0x9841,
    0x8801, 0x48c0, 0x4980, 0x8941, 0x4b00, 0x8bc1, 0x8a81, 0x4a40,
    0x4e00, 0x8ec1, 0x8f81, 0x4f40, 0x8d01, 0x4dc0, 0x4c80, 0x8c41,
    0x4400, 0x84c1, 0x8581, 0x4540, 0x8701, 0x47c0, 0x4680, 0x8641,
    0x8201, 0x42c0, 0x4380, 0x8341, 0x4100, 0x81c1, 0x8081, 0x4040
    )
    
    for byte in msg:
        if sys.version_info[0] < 3:
            crc = table[(crc^ord(byte))&0xff] ^ (crc >>8)
        else:
            crc = table[(crc^byte)&0xff] ^ (crc >>8)
    return crc & 0xFFFF

if len(sys.argv) == 1:
    if sys.version_info[0] < 3:
        filename = raw_input("Enter path/filename: ")
    else:
        filename = input("Enter path/filename: ")
    print ("Note: You can also give filename as a command line argument")
else:
    filename = sys.argv[1]

def getChecksums(address, file):
    file.seek(address)
    storedCS = struct.unpack('>H',file.read(2))[0]
    file.seek(address + 2)
    numberOfSegments = struct.unpack('<H',file.read(2))[0]
    calcCS = 0x5858
    
    for x in range(numberOfSegments):
        file.seek(address + 4 + 8*x)
        start = struct.unpack('<L',file.read(4))[0]
        file.seek(address + 8 + 8*x)
        end = struct.unpack('<L',file.read(4))[0]
        file.seek(start)
        calcCS = crc_16_fast(calcCS,file.read((end - start) + 1))

    return storedCS, swap(calcCS)

def verifySignature(address, file):
    file.seek(address)
    numberOfSegments = struct.unpack('<H',file.read(2))[0]
    md5 = hashlib.md5()
    
    for x in range(numberOfSegments):
        file.seek(address + 2 + 8*x)
        start = struct.unpack('<L',file.read(4))[0]
        file.seek(address + 18 + 4*x)
        length = struct.unpack('<L',file.read(4))[0]
        file.seek(start)
        md5.update(file.read(length))

    signature = 0
    for x in range (0x20):
        file.seek(address + 26 + (0x80 - x*4))
        signature = (signature << 32) + struct.unpack('<L',file.read(4))[0]
        
    n = 0xAB76AA1E9E5B37269D53883564E991BB9CD9DEDDC8BEE75CEB847A3F77965480DBEF70365D7448E396380618E7B3E3657AB58079C1CB0B1169690EE865581236D81947C8EADE9EA65EB3D510AA3818034BDE4323B29AF2139E0260C96ABBFB4B569894AAA270A36151FDA214ABAD1BE4737C72704D048E2D767866C8B1550549
    decryptedSig = pow(signature, 3, n)
    
    return reverse(format((decryptedSig),'02x')), md5.hexdigest()
    
    
in_file = open(filename,"rb")

bootStored, bootCalc = getChecksums(0x3eec, in_file)
progStored, progCalc = getChecksums(0x3fda6, in_file)
dataStored, dataCalc = getChecksums(0x78090, in_file)

progSigDecrypted, progmd5 = verifySignature(0x3fec0, in_file)
dataSigDecrypted, datamd5 = verifySignature(0x780b0, in_file)

print ("Boot Checksum (stored): " + hex(bootStored))
print ("Boot Checksum (calculated): " + hex(bootCalc))
print ("Program Checksum (stored): " + hex(progStored))
print ("Program Checksum (calculated): " + hex(progCalc))
print ("Data Checksum (stored): " + hex(dataStored))
print ("Data Checksum (calculated): " + hex(dataCalc))
print ('')
print ("Program MD5 (decrypted): " + progSigDecrypted)
print ("Program MD5 (calculated): " + progmd5)
print ("Data MD5 (decrypted): " + dataSigDecrypted)
print ("Data MD5 (calculated): " + datamd5)
It will show all 3 checksums as well as the program and data MD5s (along with the MD5s from the decrypted signatures). Naturally if you change anything, the hashes will no longer match.

Edit: I might be hitting some m5board limit since not all of my code is showing up above, but the full thing is visible if you quote this post.
Awesome thanks for the update.... I have to poke around the code a bit more and figure out why the original idea didn't work, I speculate it has to do with the C166 and crossing segments, again just an idea I really have to look.

My hope is there is enough changeable that it's worth putting time into finding a good way for all to change. It's funny it seems some were selling a "tune" way back when for a bucket of cash and it's thought it was just repackaged euro tunes, not sure if anyone bought them though. I personally think there is a bit of improvement but nothing earth shattering so we'll see. I think the car would be improvement with better shift points and lean cruise but that's another story for another day.

Of course all of it will be out there but if it gets used :dunno:

edit: the TCU project for the auto seemed to find away around it all, but then they went into sell it mode I think never releasing the details. So it's at least possible
 

·
Registered
Joined
·
225 Posts
Awesome thanks for the update.... I have to poke around the code a bit more and figure out why the original idea didn't work, I speculate it has to do with the C166 and crossing segments, again just an idea I really have to look.

My hope is there is enough changeable that it's worth putting time into finding a good way for all to change. It's funny it seems some were selling a "tune" way back when for a bucket of cash and it's thought it was just repackaged euro tunes, not sure if anyone bought them though. I personally think there is a bit of improvement but nothing earth shattering so we'll see. I think the car would be improvement with better shift points and lean cruise but that's another story for another day.

Of course all of it will be out there but if it gets used :dunno:

edit: the TCU project for the auto seemed to find away around it all, but then they went into sell it mode I think never releasing the details. So it's at least possible
Yeah that's my suspicion too. Need to dig more.

xhpflash decompiles pretty cleanly - not hard to see their methods. Basically there's a RAM value that stores a pointer to a table containing the addresses you're allowed to write to. Their strategy is to change that pointer to a different address, write a table that allows writes anywhere, and simply write the "RSA Passed" message.

That said, those auto ECUs are fairly different from the SMG3 ECU. As far as I'm aware, the only reason that table pointer is loaded from RAM rather than the ROM itself is because that ECU uses code compression.
 

·
Registered
Joined
·
1,345 Posts
Discussion Starter #79
Yeah that's my suspicion too. Need to dig more.

xhpflash decompiles pretty cleanly - not hard to see their methods. Basically there's a RAM value that stores a pointer to a table containing the addresses you're allowed to write to. Their strategy is to change that pointer to a different address, write a table that allows writes anywhere, and simply write the "RSA Passed" message.

That said, those auto ECUs are fairly different from the SMG3 ECU. As far as I'm aware, the only reason that table pointer is loaded from RAM rather than the ROM itself is because that ECU uses code compression.
If I had to bet R0 is setup as a pointer to struct/table about the flash/verify going into that function(the modded one). If you look how it's used it makes sense. I have to figure out who is calling that function. Ida pro doesn't do that great of job of mapping out the code without a lot of hints, with this processor. unless I'm missing something

xhpflash's approach is worth looking into, I assume this does something similar esp if the TCU supports boot sector flash, you'd need to relocate the write function and data for obvious reasons and having two separate code paths would be silly.


Yeah the crossing segments thing: most of the sub routines are optimized to say just access this segment for x instructions, I assume they assume the signature table and what it's checking are in the same segments and that's where the failure happens.
 
61 - 80 of 84 Posts
About this Discussion
83 Replies
12 Participants
Ferris
BMW M5 Forum and M6 Forums
M5Board is the best forum community for information on the BMW M5 E60 (V-10), E39 (V-8), E34 (straight 6), E28, F90 and F10. Discuss performance, specs, reviews and more!
Full Forum Listing
Top