How do I extract, modify and overwrite dtb directly in the router memory

Hi, I extracted some parts of the firmware MTK-OPENWRT M7623-7623a-unielec-u7623-02-emmc-512m-squashfs-sysupgrade-emmc (1).bin using binwalk and now I would like to extract the dtb to decompile it, modify it and overwrite it directly into the router memory so I need to know where exactly it is located in the router memory. I tried the following to extract the dtb but it didn't work. I don't have the sources of this firmware

Scan Time:     2025-09-30 12:14:58
Target File:   /UniElec_U7623-06/UniElec_stock_firmware/MTK-OPENWRT M7623-7623a-unielec-u7623-02-emmc-512m-squashfs-sysupgrade-emmc (1).bin
MD5 Checksum:  31be8ce11cb742e75e312117c66e4e46
Signatures:    391

DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
0             0x0             uImage header, header size: 64 bytes, header CRC: 0x100E82C3, created: 2020-05-16 18:32:20, image size: 2494231 bytes, Data Address: 0x80008000, Entry Point: 0x80008000, data CRC: 0xB52022D9, OS: Linux, CPU: ARM, image type: OS Kernel Image, compression type: none, image name: "ARM OpenWrt Linux-4.14.180"
64            0x40            Linux kernel ARM boot executable zImage (little-endian)
2400          0x960           device tree image (dtb)
15220         0x3B74          xz compressed data
15452         0x3C5C          xz compressed data
2470608       0x25B2D0        device tree image (dtb)
44826624      0x2AC0000       Squashfs filesystem, little endian, version 4.0, compression:xz, size: 3380660 bytes, 1956 inodes, blocksize: 262144 bytes, created: 2020-05-16 18:32:20


Scan Time:     2025-09-30 12:15:05
Target File:   /UniElec_U7623-06/_MTK-OPENWRT M7623-7623a-unielec-u7623-02-emmc-512m-squashfs-sysupgrade-emmc (1).bin.extracted/3C5C
MD5 Checksum:  deeea9aa760ea2ba9534a93cb62d0ea3
Signatures:    391

DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
468           0x1D4           device tree image (dtb)
1852085       0x1C42B5        Certificate in DER format (x509 v3), header length: 4, sequence length: 774
2514377       0x265DC9        Certificate in DER format (x509 v3), header length: 4, sequence length: 8194
3445037       0x34912D        Certificate in DER format (x509 v3), header length: 4, sequence length: 8193
4975521       0x4BEBA1        Certificate in DER format (x509 v3), header length: 4, sequence length: 5376
5719545       0x5745F9        Certificate in DER format (x509 v3), header length: 4, sequence length: 1284
6358656       0x610680        CRC32 polynomial table, little endian
6443195       0x6250BB        Intel x86 or x64 microcode, sig 0x03000000, pf_mask 0x01, 20C0-18-20, rev 0x707b0400, size 192
7250452       0x6EA214        xz compressed data
7319928       0x6FB178        Unix path: /lib/firmware/updates/4.14.180
7409829       0x7110A5        Copyright string: "Copyright(c) Pierre Ossman"
7416940       0x712C6C        Unix path: /sys/firmware/devicetree/base
7417821       0x712FDD        Unix path: /sys/firmware/fdt': CRC check failed
7429105       0x715BF1        Neighborly text, "neighbor table overflow!tics"
7448740       0x71A8A4        Neighborly text, "NeighborSolicitsports"
7448760       0x71A8B8        Neighborly text, "NeighborAdvertisements"
7451694       0x71B42E        Neighborly text, "neighbor %.2x%.2x.%pM lost rename link %s to %s"
8537296       0x8244D0        ASCII cpio archive (SVR4 with no CRC), file name: "dev", file name length: "0x00000004", file size: "0x00000000"
8537412       0x824544        ASCII cpio archive (SVR4 with no CRC), file name: "dev/console", file name length: "0x0000000C", file size: "0x00000000"
8537536       0x8245C0        ASCII cpio archive (SVR4 with no CRC), file name: "root", file name length: "0x00000005", file size: "0x00000000"
8537652       0x824634        ASCII cpio archive (SVR4 with no CRC), file name: "TRAILER!!!", file name length: "0x0000000B", file size: "0x00000000"

Results 1

$ dd if=MTK-OPENWRT\ M7623-7623a-unielec-u7623-02-emmc-512m-squashfs-sysupgrade-emmc\ \(1\).bin of=dtb.bin skip=64 count=$((2400 - 64 + 1))
2337+0 records in
2337+0 records out
1196544 bytes transferred in 0.014775 secs (80984365 bytes/sec)
$ dtc -f -I dtb -O dts dtb.bin
FATAL ERROR: Blob has incorrect magic number

Result 2

$ rm dtb.bin 
$ dd if=MTK-OPENWRT\ M7623-7623a-unielec-u7623-02-emmc-512m-squashfs-sysupgrade-emmc\ \(1\).bin of=dtb.bin skip=15452 count=$((2470608 - 15452 + 1))
78958+1 records in
78958+1 records out
40426932 bytes transferred in 0.219497 secs (184179884 bytes/sec)
$ dtc -f -I dtb -O dts dtb.bin
FATAL ERROR: Blob has incorrect magic number

Result 3

$ rm dtb.bin 
$ dd if=_MTK-OPENWRT\ M7623-7623a-unielec-u7623-02-emmc-512m-squashfs-sysupgrade-emmc\ \(1\).bin.extracted/3C5C of=dtb.bin count=469
469+0 records in
469+0 records out
240128 bytes transferred in 0.004282 secs (56078468 bytes/sec)
$ dtc -f -I dtb -O dts dtb.bin
FATAL ERROR: Blob has incorrect magic number

Nothing changed with the surely wrong commands

dd if=MTK-OPENWRT\ M7623-7623a-unielec-u7623-02-emmc-512m-squashfs-sysupgrade-emmc\ \(1\).bin of=dtb.bin skip=2400 count=$((15220 - 2400))
dd if=MTK-OPENWRT\ M7623-7623a-unielec-u7623-02-emmc-512m-squashfs-sysupgrade-emmc\ \(1\).bin of=dtb.bin skip=2470608 count=$((44826624 - 2470608))
dd if=_MTK-OPENWRT\ M7623-7623a-unielec-u7623-02-emmc-512m-squashfs-sysupgrade-emmc\ \(1\).bin.extracted/3C5C skip=468 of=dtb.bin count=$((1852085 - 468))

Can anyone help me?

bs=1 skip=2400 count=12820

1 Like

Tried already, it doesn't work :smiling_face_with_tear:

Nothing changed with the surely wrong commands

dd if=MTK-OPENWRT\ M7623-7623a-unielec-u7623-02-emmc-512m-squashfs-sysupgrade-emmc\ \(1\).bin of=dtb.bin skip=2400 count=$((15220 - 2400))
dd if=MTK-OPENWRT\ M7623-7623a-unielec-u7623-02-emmc-512m-squashfs-sysupgrade-emmc\ \(1\).bin of=dtb.bin skip=2470608 count=$((44826624 - 2470608))
dd if=_MTK-OPENWRT\ M7623-7623a-unielec-u7623-02-emmc-512m-squashfs-sysupgrade-emmc\ \(1\).bin.extracted/3C5C skip=468 of=dtb.bin count=$((1852085 - 468))

I always get "FATAL ERROR: Blob has incorrect magic number"

# dd if=MTK-OPENWRT\ M7623-7623a-unielec-u7623-02-emmc-512m-squashfs-sysupgrade-emmc\ \(1\).bin of=dtb.bin skip=2400 count=$((15220 - 2400))
12820+0 records in
12820+0 records out
6563840 bytes (6.6 MB, 6.3 MiB) copied, 0.0411272 s, 160 MB/s
# du -h dtb.bin 
6.3M    dtb.bin
# dtc -f -I dtb -O dts dtb.bin
FATAL ERROR: Blob has incorrect magic number
# du -h dtb.bin 
6.3M    dtb.bin

the uboot tool "dumpimage" is likely a more suitable approach, depending on the image type.

default blocksize is half kilobyte, try really and be careful

Still doesn't work but image size now is 16K...

# dd if=MTK-OPENWRT\ M7623-7623a-unielec-u7623-02-emmc-512m-squashfs-sysupgrade-emmc\ \(1\).bin of=dtb.bin skip=2400 count=$((15220 - 2400)) bs=1
12820+0 records in
12820+0 records out
12820 bytes (13 kB, 13 KiB) copied, 0.0313918 s, 408 kB/s
# du -h dtb.bin 
16K     dtb.bin
# dtc -f -I dtb -O dts dtb.bin
FATAL ERROR: EOF before reading 77398784 bytes of DT blob

I might be wrong but I think that "dumpimage" works with *.its U-boot images. This is a much older image that the *.itb "era"...

I anyway need to do the same job for a router with CFE, so it would be better if I can accomplish the task with more general tools like binwalk and dd

I suggest dumpimage because it will calculate the new checksum for the modified dtb, IMO, its allows a much cleaner extraction and analysis.

I am busy with work so i can't offer much help at the moment, however, there is an abundance of documentation and articles to aid you.

a quick search for extracting the parts of an itb image using dumpimage.
How to extract kernel, rootfs, and dtb images from Linux ITB image
You may need to be more specific in you r queries. Also, you may need to use an older version of dump-image.

As a first step, install the dumpimage package and run it with the -l flag to see if it can identify the parts.

ex

dumpimage -l openwrt-qualcommax-ipq50xx-glinet_gl-b3000-squashfs-factory.img
FIT description: Flashing nand 800 20000
Created:         Sun Mar 16 15:25:43 2025
 Image 0 (script)
  Description:  Flashing nand 800 20000
  Created:      Sun Mar 16 15:25:43 2025
  Type:         Script
  Compression:  uncompressed
  Data Size:    1413 Bytes = 1.38 KiB = 0.00 MiB
  Hash algo:    crc32
  Hash value:   e694aa95
 Image 1 (ubi)
  Description:  GL.iNET GL-B3000 Openwrt Firmware
  Created:      Sun Mar 16 15:25:43 2025
  Type:         Firmware
  Compression:  uncompressed
  Data Size:    18219008 Bytes = 17792.00 KiB = 17.38 MiB
  Architecture: ARM
  OS:           Linux
  Load Address: unavailable
  Hash algo:    crc32
  Hash value:   19d81b98

if you get similar output, it should be a pretty straight forward process to pull it apart, modify it, and put it back together using dumpiamge