Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Invalid G codes? #55

Open
erickphd opened this issue Jun 8, 2017 · 51 comments
Open

Invalid G codes? #55

erickphd opened this issue Jun 8, 2017 · 51 comments

Comments

@erickphd
Copy link

erickphd commented Jun 8, 2017

Installed firmware on Micro then connected to MatterControl, latest stable version. Tried to run calibration cube. Job stalls after bed level and preheat. Log shows invalid G codes -
print_log.txt
Is this iMe firmware or MatterControl?

@donovan6000
Copy link
Owner

iMe doesn't have the M400 command implemented, and that's what's causing the problem.. It used to not send that command back when we were testing iMe with MatterControl, so it was never implemented. I can add it to iMe if there's no way to disable it in MatterControl.

@erickphd
Copy link
Author

erickphd commented Jun 9, 2017

Thanks! I'll check with MatterControl and see if it can be disabled. I am using the Micro-specific profile that is labeled "iMe firmware on M3D." Will let you know what I find. However, as I'm sure you know, the meaning of this code is to wait until all sent moves are finished - wouldn't this be needed in the case of the Micro which is rather slow? I've sent in a support ticket to MatterControl because I can't find anything on their support pages about this or on their forum.

@donovan6000
Copy link
Owner

iMe will always finish the command that it's currently processing before running the next command, so sending an M400 command to it wont change it's behaviour. I added support for the M400 command in iMe's devel branch, and you can use M33 Manager to install a firmware from this file to use it.

@erickphd
Copy link
Author

erickphd commented Jun 10, 2017 via email

@donovan6000
Copy link
Owner

Glad I could help. Getting our own firmware to run on the Micro+ or M3D Pro printers first requires figuring out how to decrypt M3D's official firmware for each of those printer. This had to be done for the Micro 3D printer as well, and after doing that we can then reverse engineer their firmware and encrypt our own firmware.

M3D's official software comes with their encrypted firmware and a CRC32 of the decrypted firmware. The software sends the encrypted firmware to the printer, and the printer's bootloader uses a one-to-one loop up table to decrypt each byte it receives before writing the decrypted byte to its flash. The software then sends the CRC32 to the printer and the printer confirms it the contents in its flash match that CRC32 as a way to verify that the firmware was installed correctly.

I've been attempting to brute force the decryption byte permutation for the M3D Pro over the last few weeks, but it's similar to the travelling salesman problem in that there's factorial(255) permutations for me to try. After a couple weeks of optimizing my brute force algorithm, I'm still only about to compute approximately 302000 permutations per second which would still take trillions and trillions of years to try a them all. I am looking at increasing my throughput via the use of FPGAs and general purpose GPU computing, but I doubt that I'll ever be able to brute force it with the resources that I have available.

The reason I was able to figure out the decryption byte permutation for the Micro 3D printer is because I was able to leverage the way that it confirms if its flash contents match a provided CRC32 to give me the ability to brute force a single byte at a time. I can't do that same thing for the Micro+ or M3D Pro printers since I don't physically have access to those printers or know anyone who owns one yet.

@erickphd
Copy link
Author

erickphd commented Jun 11, 2017 via email

@donovan6000
Copy link
Owner

Awesome, you have a Micro+ and you'll eventually have an M3D Pro!!! :) You want to help crack their encryption?

The microcontroller in both the Micro+ and M3D Pro printers is the STM32F070CB. M3D's firmware for those printer's is most likely using the microcontroller's builtin CRC calculation unit like they did with the Micro 3D's ATxmega32C4 microcontroller. Page 13 of the STM32 family CRC application notes shows that the only configurable setting for the STM32F0 series is the initial CRC32 seed value, so we'll have to figure that out first.

The trick with the Micro 3D printer is that it could return the CRC32 of its flash contents. So the initial CRC32 seed could be determined by erasing the flash which sets it to all 0xFF, getting the CRC32 of that from the printer, and then brute forcing a file that's the same size as the flash all filled with 0xFF values using all 4294967295 possible seed values until a CRC32 that matches the one that the printer returned was obtained. It turned out that M3D used the ATxmega32C4's default seed value, 0xFFFFFFFF, so I'm leaning toward them using the STM32F070CB's default seed value, 0xFFFFFFFF, as well. But we wont know until we test it. However M3D did changed one thing about their Micro+ and M3D Pro printer which complicates things a little bit. The printer can no longer return the CRC32 of its flash contents, but instead can verify that a provided CRC32 stored in its flash simulated EEPROM matches the CRC32 of a section of its flash contents. So that just makes it so that we'll have to brute force the CRC32 seed by sending our guesses to the printer and seeing which ones confirms that the currently guessed seed was correct.

Unfortunately page 14 of the STM32F070CB EEPROM emulation application notes states that the write endurance of the microcontroller's flash is a reliable for up to 10000 times. Since the guessed CRC32 values have to be written to the microcontroller's flash simulated EEPROM, then each guess we made will slowly diminish the reliability of the microcontroller's flash eventually. Knowing that the worst case scenario is that it'll take 4294967295 guesses just brute force the seed value makes me feel uneasy about that flash endurance.

I'll try to get some Micro+ CRC32 brute forcing software ready for you to run in the next couple of days if your interested in helping :)

@rytz
Copy link

rytz commented Jun 12, 2017

M400 is pretty important to the way MatterControl's macro features, so it's not really something we'd like to be able to disable. If the firmware can support M400 that would probably be best.

@erickphd
Copy link
Author

erickphd commented Jun 12, 2017 via email

@erickphd
Copy link
Author

erickphd commented Jun 13, 2017 via email

@donovan6000
Copy link
Owner

Thanks! That gives me plenty of time to get everything figured out. I'll keep you updated.

@donovan6000
Copy link
Owner

@erickphd Sorry this took so long. Here's a program that's to test if communicating with the Micro+'s bootloader works and that reading/writing to the printer's EEPROM works. While the printer is connected to your computer, run the Test Windows, Test macOS, or Test Linux file depending on the operating system that your using. The program just creates a file called output in the same directory as the executable that contains some debug output. Upload that file here so we can see if everything is working so far.

Thanks again!

@erickphd
Copy link
Author

erickphd commented Jul 4, 2017 via email

@erickphd
Copy link
Author

erickphd commented Jul 16, 2017 via email

@erickphd
Copy link
Author

erickphd commented Jul 20, 2017 via email

@donovan6000
Copy link
Owner

Wow, that sucks. Hopefully there's no issues with it in the future after you get it back. And feel free to take all the time you need. I'm just glad that there's someone willing to help in reverse engineering the printers, so there's no need for you to rush.

@erickphd
Copy link
Author

erickphd commented Jul 21, 2017 via email

@donovan6000
Copy link
Owner

I can't seem to find where you sent the output test file. I don't think github's email reply feature supports displaying attachments.

@erickphd
Copy link
Author

erickphd commented Jul 22, 2017 via email

@erickphd
Copy link
Author

erickphd commented Jul 22, 2017 via email

@donovan6000
Copy link
Owner

donovan6000 commented Jul 22, 2017

Thanks. It looks like the bootloaders for the Micro+ differs from the Micro 3D's in that it periodically sends wait responses when it hasn't received a request for for a set amount of time. And it's either using a different kind of protocol or it's just being very picky about interpreting M115 as an M command.

Try out this one now. It removes leading wait text from all the received responses and just sends M instead of M115.

Also what color is your printer? The first 2 characters in the serial number have been used to indicate the printer's color for the Micro 3D printer, but the SC in SC17061401010001 isn't one of the know color codes: BK, WH, BL, GR, OR, CL, SL, PL.

@erickphd
Copy link
Author

erickphd commented Jul 22, 2017 via email

@erickphd
Copy link
Author

erickphd commented Jul 22, 2017 via email

@donovan6000
Copy link
Owner

donovan6000 commented Jul 23, 2017

I'm starting to think that the Micro+ uses the same Repetier protocol that the Micro 3D uses. I wonder if their Micro+ firmware is just a port of their Micro 3D firmware made to run on the STM32 microcontroller.

Well this test should give us some kind of results. This one sends the command to switch the printer into bootloader mode in both RepRap protocol and Repetier protocol so it should at least react to one of those. Also make sure that M3D's software, including the spooler, is completely closed when running the test programs. Their software could potentially try to communicate with the printer while the test program is which would definitely lead to some weird results in the output file.

I've been reverse engineering their latest Micro+/M3D Pro software, V1.7.0.74, to keep up to date about what changes they made. Their Windows drivers look like it should work with all 3 kinds of printers since it includes the correct USB VIDs and PIDs. Based on the past I wouldn't trust M3D's software engineers to get anything right the first time though, so they could have messed up the driver.

@erickphd
Copy link
Author

erickphd commented Jul 23, 2017 via email

@donovan6000
Copy link
Owner

Lol M3D has always loved to boast about accomplishments that they haven't actually achieved. In one of their Kickstarter updates they mentioned how they were planning to release their first ever cross platform software release that supports Windows, macOS, and Linux that month, and that didn't actually happen for another 9 months.

Can you post the output file's contents directly here? Even viewing your replies in my email doesn't show any attachments. Turns out that one of the caveats of github's email reply feature is that it ignores email attachments :(

@erickphd
Copy link
Author

erickphd commented Jul 23, 2017 via email

@erickphd
Copy link
Author

erickphd commented Jul 23, 2017 via email

@donovan6000
Copy link
Owner

Awesome! :) That confirmed that we can read/write to the printer's EEPROM. The only part that I don't like it this part.

Verifying flash CRC32
Response: 

It should have responded with ok\r. The receiving response function probably timed out before the printer had a chance to reply though. So try this one now. It just hangs indefinitely until it receives a response from the printer when verifying the flash CRC32 so that we can see what it actually replies with.

@promise8000
Copy link

Hello @donovan6000, thank you for your all great work 👍

Here is the decryption table for the M3D Pro:

const uint8_t romDecryptionTable[] = {0xF7, 0x52, 0x16, 0x78, 0xC6, 0xCA, 0xA4, 0xFA, 0x7A, 0x7B, 0x90, 0xF1, 0x12, 0x9E, 0x91, 0x40, 0xDC, 0x4B, 0xCB, 0xB3, 0xB9, 0x23, 0x7C, 0xE9, 0x87, 0x67, 0x01, 0x8B, 0xFD, 0x7F, 0x46, 0xFF, 0xAA, 0x06, 0x3B, 0x53, 0xAD, 0xCE, 0x4C, 0x4A, 0xA3, 0x8A, 0xE2, 0x62, 0x42, 0x2D, 0x36, 0x1E, 0x74, 0xD9, 0xEB, 0xB4, 0x4E, 0xED, 0x66, 0x71, 0xA1, 0x73, 0xD1, 0xA5, 0x1D, 0xE6, 0x6E, 0x43, 0xCD, 0xBE, 0x02, 0x48, 0x17, 0xD8, 0x54, 0x11, 0x27, 0x89, 0x72, 0x3D, 0x35, 0x38, 0x68, 0xD4, 0xE8, 0x98, 0x0D, 0x25, 0x31, 0x95, 0xBD, 0xA7, 0x26, 0xBB, 0xB6, 0xE4, 0xC4, 0x44, 0xF9, 0x2F, 0x1C, 0xB5, 0xFE, 0x33, 0xEE, 0x20, 0xB8, 0x1A, 0x21, 0x81, 0x19, 0xF3, 0xAB, 0x29, 0x05, 0xDB, 0x8C, 0xDD, 0xD7, 0x80, 0x97, 0xF2, 0x85, 0x63, 0x5C, 0xFC, 0xEC, 0x45, 0xA8, 0xF4, 0x92, 0x32, 0x07, 0xC5, 0xA2, 0x4F, 0x5D, 0x41, 0x22, 0xCC, 0xE7, 0xC0, 0x9B, 0x00, 0x79, 0xC3, 0x70, 0x4D, 0x5A, 0x58, 0x59, 0x2B, 0x08, 0x47, 0xD0, 0xC1, 0x3A, 0x96, 0x1B, 0xD3, 0x6B, 0x8F, 0x24, 0x6C, 0x0E, 0x94, 0xB0, 0x60, 0x8E, 0xF6, 0x9C, 0x10, 0xBF, 0xE3, 0xCF, 0x2E, 0x50, 0xD6, 0xEA, 0xB1, 0x2A, 0x09, 0xAF, 0x3E, 0x82, 0x83, 0x18, 0xF0, 0x39, 0xBC, 0x04, 0xAC, 0xA0, 0xDE, 0x55, 0x75, 0x3C, 0x5B, 0x0F, 0x65, 0x7D, 0xDA, 0xC8, 0xE1, 0xC2, 0xC9, 0xF5, 0x37, 0xB7, 0xC7, 0x9D, 0x8D, 0xD2, 0x0C, 0xEF, 0x3F, 0xE5, 0x15, 0x7E, 0x14, 0x5F, 0x57, 0xA6, 0x6A, 0x49, 0x2C, 0xF8, 0x6D, 0x9F, 0x1F, 0x9A, 0x5E, 0x88, 0x99, 0xFB, 0xD5, 0x51, 0x64, 0xB2, 0x56, 0x13, 0x84, 0x34, 0x0A, 0x76, 0x69, 0xE0, 0x86, 0xAE, 0x6F, 0xA9, 0x30, 0x03, 0x77, 0xDF, 0x61, 0x28, 0x93, 0xBA, 0x0B};

The code loads at address 0x08006000

@erickphd
Copy link
Author

erickphd commented Jul 23, 2017 via email

@donovan6000
Copy link
Owner

donovan6000 commented Jul 28, 2017

Sorry guys. Got kinda busy the last few days.

@promise8000 Awesome!!! That really helps a lot! Were you able to read the microcontroller's flash via the SWD debug pins? Or did you do something else to get access to the chip's firmware? Could you upload the chip's entire 128KB of flash here so that we can see where the bootloader, firmware, and simulated EEPROM are all located? The firmware updating mechanism only updates 0x18000 bytes of flash for the M3D Pro's main firmware, so there's still 0x8000 bytes that I want to see.

Also can you confirm if the M3D Pro has 2 STM32F070CB microcontrollers? One for the main firmware and one for the secondary firmware. Or is one of the chips a different microcontroller? Could you also upload the second microcontroller's entire flash here too if your able to get access to it?

I was able to verify that your keys are correct for decrypting both the M3D Pro's main and secondary firmwares. That also led me to confirm that M3D LLC is using the microcontroller's builtin CRC32 functionality to generate the CRC32 used in verifying if the firmware was flashed correctly.

So here's the CRC32 parameters:

  • Input Reflected: false
  • Output Reflected: false
  • Polynomial: 0x04C11DB7
  • Initial Value: 0xBCAD558B (Only for M3D Pro's main firmware. Works on all 3 released M3D Pro main firmwares, so it's definitely correct. Doesn't work with M3D Pro's secondary firmware, and probably wont work with the Micro+. If i knew the max size of the M3D Pro's updatable secondary firmware then I could guess this value for the M3D Pro's secondary firmware. So far I've tried the sizes 0x18000, 0x19800, and 0x20000, but none of those are correct)
  • Final Xor Value: 0x00000000

@erickphd Contrary to what we were hoping, M3D LLC is using non-default CRC32 initial values for the M3D Pro's main firmware, so they probably did the same thing for the Micro+. One of the ideas I had incase they didn't use the default value was to try to guess it with a timing attack, but I think USB CDC packets are transmitted at fixed intervals which would make that ineffective when a timing attack would require nanoseconds of accuracy for it to work on the STM32F070CB microcontroller running at 48MHz. We'll wait to see what @promise8000 says about how he accessed the Pro's firmware before deciding how to proceed with the Micro+.

@erickphd
Copy link
Author

erickphd commented Jul 28, 2017 via email

@erickphd
Copy link
Author

erickphd commented Jul 31, 2017 via email

@donovan6000
Copy link
Owner

donovan6000 commented Aug 18, 2017

@erickphd I was just about to give up on this since I thought that we needed either the decryption keys or initial CRC32 value to be able to brute force the other, but I think I finally thought of a way to brute force the decryption keys without having to know the initial CRC32 value!

So try out this program and upload the resulting output file. The program will stop if it goes past 80% of the total number of writes that the micrcontroller's flash can endure, so you'll still have 2000 writes left if that happens. Also, it could potentially take up to 5 minutes to brute force each byte, so the program might be running for 20+ hours. I'm pretty sure it'll hit the 80% write endurance limit within the first 2 hours though.

@donovan6000
Copy link
Owner

donovan6000 commented Aug 18, 2017

Oops, the last program I posted didn't allow an encrypted byte to be equal to its decrypted value since that didn't happen with the Micro 3D's firmware encryption. However it does happen with the M3D Pro's encryption, so it might also happen for the Micro+'s. So run this program instead (fixing more issues. I'll post the new program soon).

@erickphd
Copy link
Author

erickphd commented Aug 18, 2017 via email

@donovan6000
Copy link
Owner

donovan6000 commented Aug 19, 2017

Thanks. I've been making some progress on guessing a lot of the alphanumeric character's encryption keys today, so don't run any programs until I post a new program in a few hours that includes all the new found keys :)

@donovan6000
Copy link
Owner

donovan6000 commented Aug 19, 2017

Here the newest program (program removed since we don't need anyone else to run it)

@erickphd
Copy link
Author

erickphd commented Aug 19, 2017 via email

@erickphd
Copy link
Author

erickphd commented Aug 20, 2017 via email

@donovan6000
Copy link
Owner

Hopefully it got a good amount of them. Otherwise we might have to find another Micro+ owner to find the rest.

Can you paste the contents of the output file here? Email attachments still aren't working with github.

@erickphd
Copy link
Author

erickphd commented Aug 20, 2017 via email

@donovan6000
Copy link
Owner

@erickphd Awesome, so we know 92 / 256 keys now! I'll start asking around on some of the M3D related forums to try to get a few more people to help us get the remaining keys.

Also have you received your M3D Pro yet? it'd be nice to be able to verify that this new brute force method also works on it.

@erickphd
Copy link
Author

erickphd commented Aug 27, 2017 via email

@donovan6000
Copy link
Owner

I got the rest of the decryption keys last week! Now can you run this program while your Micro+ is connected to your computer? The program should extract all the contents of all the printer's nonvolatile memory, like its bootloader and option bytes, to an output file. Send me that output file when it's done. The whole process should take about 3 minutes. Also let me know if the printer's front LED flashes when the program finishes. I guessed on which pin the LED is connected to, so I want to know if I'm right.

If this all works then it shows that we've gotten to the point where we can successfully run our own firmware on the printer, and we'll have access to the printer's bootloader so there's nothing else that's hidden from us.

@erickphd
Copy link
Author

erickphd commented Sep 14, 2017 via email

@erickphd
Copy link
Author

erickphd commented Sep 14, 2017 via email

@THansen123
Copy link

How can I help! -Tom

@jgueydan
Copy link

Has this gone any further with the M3D Micro+?

@Kivo0
Copy link

Kivo0 commented Jun 11, 2021

For Anyone used the flasher on the Micro+ printer and the printer shutted down
: to reinstall the factory software

  1. open the M3D software then connect the printer power
  2. press on update fast before printer shuts down

Good luck

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants