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/27 23:55] – [Examining the main application creator3-arm] adminprojects:3dprinting:flashforge_creator_3_pro_fan_fix [2025/05/02 22:57] (current) – [Examining the main application creator3-arm] admin
Line 1: Line 1:
-f 
 ====== Flashforge Creator 3 Pro - fan fix ====== ====== Flashforge Creator 3 Pro - fan fix ======
  
Line 57: 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 120: 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 220: 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 229: Line 234:
 </code> </code>
 \\  \\ 
-Then to get more information about the ELF sections, we use:+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)). 
 + 
 +  readelf --program-headers creator3-arm 
 + 
 +Which outputs the following: 
 +<code bash> 
 +Elf file type is EXEC (Executable file) 
 +Entry point 0x28199 
 +There are 8 program headers, starting at offset 52 
 + 
 +Program Headers: 
 +    Type      Offset   VirtAddr   PhysAddr   FileSiz  MemSiz   Flg Align 
 +    EXIDX     0x32795c 0x0033795c 0x0033795c 0x009128 0x09128  R   0x4 
 +    PHDR      0x000034 0x00010034 0x00010034 0x000100 0x00100  R E 0x4 
 +    INTERP    0x000134 0x00010134 0x00010134 0x000013 0x00013  R   0x1 
 +        [Requesting program interpreter: /lib/ld-linux.so.3] 
 +    LOAD      0x000000 0x00010000 0x00010000 0x330a88 0x330a88 R E 0x10000 
 +    LOAD      0x331000 0x00351000 0x00351000 0x001798 0x047dc  RW 0x10000 
 +    DYNAMIC   0x3311dc 0x003511dc 0x003511dc 0x000148 0x00148  RW 0x4 
 +    NOTE      0x000148 0x00010148 0x00010148 0x000044 0x00044  R  0x4 
 +    GNU_STACK 0x000000 0x00000000 0x00000000 0x000000 0x00000  RW 0x10 
 + 
 +Section to Segment mapping: 
 +    Segment Sections... 
 +        00  .ARM.exidx 
 +        01 
 +        02  .interp 
 +        03  .interp .note.ABI-tag .note.gnu.build-id .hash .dynsym .dynstr 
 +            .gnu.version .gnu.version_r .rel.dyn .rel.plt .init .plt .text 
 +            .fini .rodata .ARM.extab .ARM.exidx .eh_frame 
 +        04  .init_array .fini_array .jcr .dynamic .got .data .bss 
 +        05  .dynamic 
 +        06  .note.ABI-tag .note.gnu.build-id 
 +        07 
 +</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. 
 + 
 +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
  
-\\ \\  +\\  
-which shows: +which outputs the following:\\  
-\\ \\  +<code bash> 
-|There are 29 section headers, starting at offset 0x332934:  ||||||||||| +There are 29 section headers, starting at offset 0x332934: 
-Section Headers: ^^^^^^^^^^^ +Section Headers: 
-[Nr]  Name          Type         ^ Addr  Off  Size  ES  Flg  Lk  Inf  Al  +  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al 
-[ 0]                NULL         | 00000000 000000 000000 00 |    | | +  [ 0]                   NULL            00000000 000000 000000 00         
-[ 1]  .interp       | PROGBITS     | 00010134 000134 000013 00 |  | +  [ 1] .interp           PROGBITS        00010134 000134 000013 00       
-| ...   ...           | ...          | ...      | ...    | ...    | .. | .| . | . | . | +  [ 2] .note.ABI-tag     NOTE            00010148 000148 000020 00   A  0   
-[ 5]  .dynsym       | DYNSYM       | 00012338 002338 004830 10 |  | +  [ 3] .note.gnu.build-i NOTE            00010168 000168 000024 00    0   
-[ 6]  .dynstr       | STRTAB       | 00016b68 006b68 0081ae 00 |  | +  [ 4] .hash             HASH            0001018c 00018c 0021ac 04    5    4 
-| ...   | ...           | ...          | ...      | ...    | ...    | .. | .. | . | . | . | +  [ 5] .dynsym           DYNSYM          00012338 002338 004830 10       
-[ 9]  .rel.dyn      REL          0001f74c 00f74c 000160 08 |  | +  [ 6] .dynstr           STRTAB          00016b68 006b68 0081ae 00       
-[10]  .rel.plt      REL          0001f8ac 00f8ac 001fe8 08 |  12 | +  [ 7] .gnu.version      VERSYM          0001ed16 00ed16 000906 02    5   
-| ...   ...           | ...          | ...      | ...    | ...    | .. | .. | . | . | . | +  [ 8] .gnu.version_r    VERNEED         0001f61c 00f61c 000130 00    6    4 
-[13]  .text         | PROGBITS     | 00024938 014938 1a863c 00 AX | +  [ 9] .rel.dyn          REL             0001f74c 00f74c 000160 08       
-[14]  .fini         | PROGBITS     | 001ccf74 1bcf74 000008 00 AX | +  [10] .rel.plt          REL             0001f8ac 00f8ac 001fe8 08     12  
-[15]  .rodata       | PROGBITS     | 001ccf80 1bcf80 13b5d4 00 |  | +  [11] .init             PROGBITS        00021894 011894 00000c 00  AX  0   0  4 
-| ...   ...           | ...          | ...      ...    | ...    | .. | .. | . | . | . | +  [12] .plt              PROGBITS        000218a0 0118a0 003098 04  AX  0    4 
-[24]  .data         | PROGBITS     | 0035232c 33232c 00046c 00 WA | +  [13] .text             PROGBITS        00024938 014938 1a863c 00  AX     
-[25]  .bss          | NOBITS       00352798 332798 003044 00 WA | +  [14] .fini             PROGBITS        001ccf74 1bcf74 000008 00  AX     
-| ...   | ...           | ...          | ...      | ...    | ...    | .. | .. | . | . | . | +  [15] .rodata           PROGBITS        001ccf80 1bcf80 13b5d4 00       
-[28]  .shstrtab     | STRTAB       | 00000000 332833 000101 00 |    | | +  [16] .ARM.extab        PROGBITS        00308554 2f8554 02f408 00   A  0   
-Key to Flags:\\ W (write), A (alloc), X (execute)  |||||||||||+  [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 279: 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.1745790950.txt.gz · Last modified: 2025/04/27 23:55 by admin