Site Tools


projects:3dprinting:flashforge_creator_3_pro_fan_fix

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
projects:3dprinting:flashforge_creator_3_pro_fan_fix [2025/04/29 23:28] adminprojects:3dprinting:flashforge_creator_3_pro_fan_fix [2025/05/02 22:57] (current) – [Examining the main application creator3-arm] admin
Line 56: Line 56:
  
 ===== System Software Details ===== ===== System Software Details =====
-The Flashforge linux based system is made with an old version of [[https://buildroot.org/|buildroot]] (2016). For better understanding the systemssh access would be helpfulbut an ssh server (like dropbear) is not installed. However shell access is still possible using a serial cable at the circuit board at connector J2.+The Flashforge linux based system is made with an old version of [[https://buildroot.org/|buildroot]] (2016), as we can see when we try to login, using a serial cable at the circuit board at connector J2:
  
 +<code bash>
 +Welcome to flashforge
 +buildroot login: root
 +Password: 
 +Login incorrect
 +</code>
  
-Instructions about how to get root accesscan be found on the internet.((See for example:\\ [[https://github.com/moonglow/flashforge_fan_fix]], \\ [[https://github.com/micfogas/CrashForge]]\\ [[https://github.com/neggles/CrashForge]] and\\  [[https://coalfire.com/the-coalfire-blog/with-iot-common-devices-pose-new-threats]]))You may also see [[projects:3dprinting:flashforge_creator_3_pro_fan_fix:root_access|following page]] to see what I used. +With the correct passwordwe would get an opportunity to analyze the system. It would be easier though if we can access the system with sshBut from a port scan with nmap, it looks like there is no ssh server (dropbear) installed per defaultThis assumption was also confirmed later ononce we got into the systemSo we would need to build dropbear ourselves first, which can be easily done using buildroot.
  
-Please click on [[projects:3dprinting:flashforge_creator_3_pro_fan_fix:dropbear|this link]] for more information about installing dropbear to get ssh working.+Either way, without a username and password we will not get access to the system. Details about getting a username and password can be found on the internet.((See for example:\\ [[https://github.com/moonglow/flashforge_fan_fix]], \\ [[https://github.com/micfogas/CrashForge]], \\ [[https://github.com/neggles/CrashForge]] and\\  [[https://coalfire.com/the-coalfire-blog/with-iot-common-devices-pose-new-threats]])). You may also see [[projects:3dprinting:flashforge_creator_3_pro_fan_fix:root_access|following page]] to see what I used.
  
 +Please click on [[projects:3dprinting:flashforge_creator_3_pro_fan_fix:dropbear|this link]] for more information about how to build dropbear and install it to get ssh working.
  
-Once a terminal connection is made to the printer, serious reverse engineering can start. There are several great tools for reverse engineering. I highly recommend [[https://ghidra-sre.org/|Ghidra]]. It is an open-source disassembler and can do a few things which make it so much easier to understand what is going on. It is able to create from the raw binary ELF file an abstract kind of C code. It automatically adds labels to variables and memory locations, is able to create function graphs which shows the flow of the code and much more.+Once a terminal connection is made to the printer, and we have a chance to look at the start-up procedure and system setup, more serious reverse engineering can start. There are several great tools for reverse engineering. I highly recommend [[https://ghidra-sre.org/|Ghidra]]. It is an open-source disassembler and can do a few things which make it so much easier to understand what is going on. It is able to create from the raw binary ELF file an abstract kind of C code. It automatically adds labels to variables and memory locations, is able to create function graphs which shows the flow of the code and much more.
  
 ==== Reverse engineering - I ==== ==== Reverse engineering - I ====
Line 119: Line 125:
 </code> </code>
  
-This contains a reference to the printer application which among others handles the user interface. Interestingly there are also arguments provided, from which -qws starts a qt windowing system. The application itself then serves as a front-end, sending commands to the motion controller, to control the printers' mechanics. The placeholder %VERSION% points to a version number formatted like: "1.4.0". So the full path for the binary creator3-arm would be then:+This contains a reference to the printer application which among others handles the user interface. Interestingly there are also arguments provided, from which -qws let the application use the qt windowing system. The application itself then serves as a front-end, sending commands to the motion controller, to control the printers' mechanics. The placeholder %VERSION% points to a version number formatted like: "1.4.0". So the full path for the binary creator3-arm would be then:
  
   /opt/software/1.4.0/creator3-arm   /opt/software/1.4.0/creator3-arm
Line 219: Line 225:
   * [[https://github.com/compilepeace/BINARY_DISSECTION_COURSE/blob/master/ELF/SECTION_HEADER_TABLE/SECTIONS_DESCRIPTION/SECTIONS_DESCRIPTION.md|BINARY_DISSECTION_COURSE]]   * [[https://github.com/compilepeace/BINARY_DISSECTION_COURSE/blob/master/ELF/SECTION_HEADER_TABLE/SECTIONS_DESCRIPTION/SECTIONS_DESCRIPTION.md|BINARY_DISSECTION_COURSE]]
  
-When inspecting the creator3-arm file with the file command it reveals:+When inspecting creator3-arm((Version 1.4.0)) with the file command it reveals the following:
  
 <code bash> <code bash>
Line 228: Line 234:
 </code> </code>
 \\  \\ 
-The ELF program headers table describes to the loader how to bring the binary into memory space for execution. The table defines a series of segments, where each segment contains specific information for the kernel, like where and how to map ELF file's data into memory, whether the program needs a so-called runtime loader for bootstrapping which is done by the systems' ELF interpreter (As indicated by the file command from above: "interpreter /lib/ld-linux.so.3"), what the initial layout of the primary thread's thread-local-storage (TLS) should look like, and other kernel-relevant metadata such as whether the program should be given executable thread stacks.+The ELF program headers table describes to the loader how to bring the binary into memory space for execution. The table defines a series of segments, where each segment contains specific information for the kernel, like where and how to map ELF file's data into memory, whether the program needs a so-called runtime loader for bootstrapping which is done by the systems' ELF interpreter (As can be seen at the output of the file command from above: "interpreter /lib/ld-linux.so.3"), what the initial layout of the primary thread's thread-local-storage (TLS) should look like, and other kernel-relevant metadata such as whether the program should be given executable thread stacks((ARM ASSEMBLY, Internals & Reverse Engineering, Maria Markstedter, Wiley, 2023)).
  
-, how to interpret the main thread's thread local storage  +  readelf --program-headers creator3-arm
- +
-  readelf --program-headers creator3-arm_V1.4.0+
  
 +Which outputs the following:
 <code bash> <code bash>
 Elf file type is EXEC (Executable file) Elf file type is EXEC (Executable file)
Line 265: Line 270:
 </code> </code>
  
 +From the output we can see this creator3-arm has nine program headers, from which the following is probably noteworthy:
  
 +  * PHDR program header, which contains the program header table and its concerning metadata.
 +  * INTERP program header, which tells the kernel that the file depends on an external loader file (/lib/ld-linux.so.3) to bring itself into memory. The other important task of the loader is that if dynamically linked libraries are used, a relocation process is done, using the global symbol table.
 +  * LOAD program headers, tell the kernel and the loader how to get the program's data into memory. Each LOAD header directs the loader to create a region of memory with a given size, memory permissions, and alignment criteria, and tells the loader which bytes in the file to place in that region. The first LOAD header region is 0x330a88 bytes long and occupies the same size in memory, placed at virtual address 0x10000 with 64KB alignment and read + executable permissions. Given the large size, it is expected to find here the executable code which needs to be examined. Luckily, as we will see later on, the size is not using a full 64K alignment boundary, which means, that if we would need some extra space for additional code, we could increase the size until it aligns without the necessity to relocate higher adjacent regions.
 +  * DYNAMIC program header, which is used by the loader to create links to their shared library dependencies. It is also used by the loader to fix relocations for program code and pointers, if the program resides at a different place in memory than it expects based on its virtual address.
 +  * NOTE program header potentially contains vendor-specific metadata about the program itself, describing a table of key-value pairs where each entry has a string name mapped to a sequence of bytes that describe the entry.
 +  * GNU_STACK program header defining memory regions where the stack is marked with a no-execute flag. With this flag code cannot be executed if it is on the stack.
  
-Then to get more information about the ELF sections, we use:+The section headers, in contrast to the program headers, describe in more detail how the ELF file is divided into logical units. To get more information about the ELF sections, we use:
  
   readelf --section-headers creator3-arm   readelf --section-headers creator3-arm
Line 273: Line 285:
 \\  \\ 
 which outputs the following:\\  which outputs the following:\\ 
-|There are 29 section headers, starting at offset 0x332934:  ||||||||||| +<code bash> 
-Section Headers: ^^^^^^^^^^^ +There are 29 section headers, starting at offset 0x332934: 
-[Nr]  Name          Type         ^ Addr  Off  Size  ES  Flg  Lk  Inf  Al  +Section Headers: 
-[ 0]                NULL         | 00000000 000000 000000 00 |    | | +  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al 
-[ 1]  .interp       | PROGBITS     | 00010134 000134 000013 00 |  | +  [ 0]                   NULL            00000000 000000 000000 00         
-| ...   ...           | ...          | ...      | ...    | ...    | .. | .. | . | . | . | +  [ 1] .interp           PROGBITS        00010134 000134 000013 00       
-[ 5]  .dynsym       | DYNSYM       | 00012338 002338 004830 10 |  | +  [ 2] .note.ABI-tag     NOTE            00010148 000148 000020 00   A  0   
-[ 6]  .dynstr       | STRTAB       | 00016b68 006b68 0081ae 00 |  | +  [ 3] .note.gnu.build-i NOTE            00010168 000168 000024 00    0   
-| ...   | ...           | ...          | ...      | ...    | ...    | .. | .. | . | . | . | +  [ 4] .hash             HASH            0001018c 00018c 0021ac 04    5    4 
-[ 9]  .rel.dyn      | REL          0001f74c 00f74c 000160 08 |  | +  [ 5] .dynsym           DYNSYM          00012338 002338 004830 10       
-[10]  .rel.plt      REL          0001f8ac 00f8ac 001fe8 08 |  12 | +  [ 6] .dynstr           STRTAB          00016b68 006b68 0081ae 00       
-| ...   | ...           | ...          | ...      | ...    | ...    | .. | .. | . | . | . | +  [ 7] .gnu.version      VERSYM          0001ed16 00ed16 000906 02   A  5   
-[13]  .text         | PROGBITS     | 00024938 014938 1a863c 00 AX | +  [ 8] .gnu.version_r    VERNEED         0001f61c 00f61c 000130 00    6    4 
-[14]  .fini         | PROGBITS     | 001ccf74 1bcf74 000008 00 AX | +  [ 9] .rel.dyn          REL             0001f74c 00f74c 000160 08       
-[15]  .rodata       | PROGBITS     | 001ccf80 1bcf80 13b5d4 00 |  | +  [10] .rel.plt          REL             0001f8ac 00f8ac 001fe8 08     12  
-| ...   ...           | ...          | ...      | ...    | ...    | .| .. | . | . | . | +  [11] .init             PROGBITS        00021894 011894 00000c 00  AX  0   
-[24]  .data         | PROGBITS     | 0035232c 33232c 00046c 00 WA | +  [12] .plt              PROGBITS        000218a0 0118a0 003098 04  AX  0   0  4 
-[25]  .bss          | NOBITS       00352798 332798 003044 00 WA | +  [13] .text             PROGBITS        00024938 014938 1a863c 00  AX     
-| ...   | ...           | ...          | ...      | ...    | ...    | .. | .. | . | . | . | +  [14] .fini             PROGBITS        001ccf74 1bcf74 000008 00  AX     
-[28]  .shstrtab     | STRTAB       | 00000000 332833 000101 00 |    | | +  [15] .rodata           PROGBITS        001ccf80 1bcf80 13b5d4 00       
-Key to Flags:\\ W (write), A (alloc), X (execute)  |||||||||||+  [16] .ARM.extab        PROGBITS        00308554 2f8554 02f408 00   A  0   
 +  [17] .ARM.exidx        ARM_EXIDX       0033795c 32795c 009128 00  AL 13   
 +  [18] .eh_frame         PROGBITS        00340a84 330a84 000004 00    0   
 +  [19] .init_array       INIT_ARRAY      00351000 331000 0001d4 00  WA  0   
 +  [20] .fini_array       FINI_ARRAY      003511d4 3311d4 000004 00  WA  0   
 +  [21] .jcr              PROGBITS        003511d8 3311d8 000004 00  WA  0   
 +  [22] .dynamic          DYNAMIC         003511dc 3311dc 000148 08  WA  6   
 +  [23] .got              PROGBITS        00351324 331324 001008 04  WA  0    4 
 +  [24] .data             PROGBITS        0035232c 33232c 00046c 00  WA     
 +  [25] .bss              NOBITS          00352798 332798 003044 00  WA     
 +  [26] .comment          PROGBITS        00000000 332798 00006a 01  MS  0   
 +  [27] .ARM.attributes   ARM_ATTRIBUTES  00000000 332802 000031 00      0    1 
 +  [28] .shstrtab         STRTAB          00000000 332833 000101 00         
 +Key to Flags: 
 +  W (write), A (alloc), X (execute), M (merge), S (strings), I (info), 
 +  L (link order), O (extra OS processing required), G (group), T (TLS), 
 +  C (compressed), x (unknown), o (OS specific), E (exclude), 
 +  y (purecode), p (processor specific) 
 +</code>
  
 For clarity some sections have been left out. Most of the time the following sections are interesting for reverse engineering: For clarity some sections have been left out. Most of the time the following sections are interesting for reverse engineering:
Line 316: Line 346:
  
  
 +When looking at the program headers in the ELF file, we can see the following information:
 +
 +<code>
 +  Start of program headers:          52 (bytes into file)
 +  Size of this header:               52 (bytes)
 +  Size of program headers:           32 (bytes)
 +  Number of program headers:         8
 +</code>
 +
 +Then, when looking at the all of the eight program headers, and verifying the permissions at the p-flags, only program header 3 ist executable and contains the actual program.
 +
 +<code>
 +# program header 3
 +00000094: 0100 0000 0000 0000 0000 0100 0000 0100  ................
 +000000a4: 880a 3300 880a 3300 0500 0000 0000 0100  ..3...3.........
 +p_type:   (4 bytes) PT::LOAD
 +p_offset: (4 bytes) 0x000000 (      0)
 +p_vaddr:  (4 bytes) 0x010000 (  65536)
 +p_paddr:  (4 bytes) 0x010000 (  65536)
 +p_filesz: (4 bytes) 0x330a88 (3345032)
 +p_memsz:  (4 bytes) 0x330a88 (3345032)
 +p_flags:  (4 bytes) X | R
 +p_align:  (4 bytes) 0x010000 (  65536)
 +p_data:   0x00 - 0x330a87 (3345032 bytes)
 +</code>
 +
 +Interestingly this program header has a p_align of 65536 bytes, which means that at the end 1398 bytes should be available:
 +
 +With a hex Editor one can observe that this area indeed is filled with 0x00:
 +From 0x330a88 to 0x330fff (3345032 - 3346431 = 1399 bytes)
  
 +With that it should be possible to inject Code from the M104 command (979 bytes) into this area and adapt for the M106 command.
 ===== Flashprint Wireshark ===== ===== Flashprint Wireshark =====
 When clicking a button in Flashprint to start or stop a fan, a network command is sent to the printer, which can be captured with tcpdump and analyzed with wireshark. Interestingly, Flashprint does actually differentiate between the left and right cooling fan by sending also the index to the printer. It is just looks like the printer does not interpret that parameter. When clicking a button in Flashprint to start or stop a fan, a network command is sent to the printer, which can be captured with tcpdump and analyzed with wireshark. Interestingly, Flashprint does actually differentiate between the left and right cooling fan by sending also the index to the printer. It is just looks like the printer does not interpret that parameter.
projects/3dprinting/flashforge_creator_3_pro_fan_fix.1745962097.txt.gz · Last modified: 2025/04/29 23:28 by admin