some days ago i want to update firmware of my TP-LINK router. In update
instruction a warning was written to choose the right firmware version to
avoid damage of router when updating. So i run trid command on dozens of
TP-LINK router firmware (*.bin) to identify correct version, but all are
only described as "Unknown!" (see appended trid-old.txt).
The newest file(1) command does classify that examples as correctly firmware
(see appended file-tmp.txt)
Luckily in OpenWrt Wiki that file format used as firmware in many TP-LINK
router is described. So i add to new trid definitions this URL by line:
<RefURL>
https://wiki.openwrt.org/doc/techref/header</RefURL>
More information can be seen in source of firmware utility mktplinkfw.c
mentioned on that website. With that information i was able to refine
definitions generated by tridscan.
Found file name extension was always "bin". This is expressed by line
<Ext>BIN</Ext>
So i also add a user defined mime type by line:
<Mime>application/x-tplink-bin</Mime>
At the beginning header version is stored. For inspected examples this
value was always 1. This is expressed by XML construct:
<Bytes>01000000</Bytes>
<Pos>0</Pos>
So trid definition are named like bin-tplink-v1.trid.xml. According to newer
sources mktplinkfw.c also value 2 ( see HEADER_VERSION_V2) can occur. So for
such possible cases maybe also additional variants are needed like
bin-tplink-v2.trid.xml.
Afterwards vendor name is stored as string with maximal 24 bytes. So for
router TL-WR940N firmware wr940nv6_us_3_18_1_up_boot(171030).bin found at
URL like
http://www.tp-link.com/us/download/TL-WR940N.html this was "TP-LINK
Technologies", but for alternative firmware "OpenWrt" is often found. So
mention this fact in remark line. Because maximal string length (24) was not
used in inspected examples i got in tridscan generated definitions XML
construct like:
<Bytes>00000000</Bytes>
<Pos>24</Pos>
which i removed.
Afterwards at offset 28 firmware version is stored in string form with
maximal 36 bytes. In above mentioned example this was "ver. 1.0". In OpenWrt
firmware that is often an alphanumerical string like "r49389". So mention
this fact in remark line. Because maximal string length (36) was not used in
inspected examples i got in tridscan generated definitions XML construct
like:
<Bytes>00000000000000000000000000000000000000000000000000000000</Bytes>
<Pos>36</Pos>
So i removed this pattern.
At offset 128 offset of embedded kernel is stored. In theory all value may
appear but for all inspected sample kernel is stored directly after 512 byte
sized header. For me this is always reasonable. So value should always be
200h. This expressed by XML construct:
<Bytes>00000200</Bytes>
<Pos>128</Pos>
For many firmware kernel is stored in gzipped compressed form ( see
gzip/output/file-tmp.txt ). So such examples start with gzip magic
( see also ark-gz.trid.xml). This is expressed by XML construct:
<Bytes>1F8B</Bytes>
<Pos>512</Pos>
in trid variant bin-tplink_gz-v1.trid.xml.
But i also found many examples where kernel is stored in other form. ( see
gzip_NO/output/file-tmp.txt). These examples are described by generic trid
definition bin-tplink-v1.trid.xml without above mentioned pattern.
At offset 64 hardware id is stored as value like 09410006. For above
mentioned example this means it is router model TL-WR940N hardware version
V6. So mention this fact in remark line. For inspected examples i only found
hardware version in range from 1 to 6. This was expressed by construct:
<Bytes>00</Bytes>
<Pos>66</Pos>
But this become false if bigger hardware version are produced in future. So
i removed that pattern.
According to source file after variables header is filled with 354 padding
bytes to 512 end range. This is expressed by construct like:
<Bytes>000000000000000000000000000000000000000000000000000000000...</Bytes>
<Pos>158</Pos>
The documentation is no official of TP-LINK but based on OpenWrt developers.
So maybe other unknown value to community are stored in that
range. Unfortunately i found examples where at offset 0x120 18 non null bytes
appear like in wr940nv6_us_3_18_1_up_boot(171030).bin . So in generic
bin-tplink-v1.trid.xml changed this to constructs like:
<Bytes>0000000000000000000000000000000000000000000000000000000000...</Bytes>
<Pos>158</Pos>
<Bytes>0000000000000000000000000000000000000000000000000000000000...</Bytes>
<Pos>306</Pos>
At offset 136 the offset of root file system is stored. For some examples we
find here string "qshs". According to web site
https://github.com/ReFirmLabs/binwalk/blob/master/src/binwalk/magic/filesystemsthis means the Squashfs lzma compressed files system is used for root. So
mention this fact in remark line and create variant bin-tplink_gz_lzma-v1.trid.xml
with additional construct in global string section:
<String>QSHS</String>
For remaining examples with gzipped kernel string "hsqs" is found. That
means little endian Squashfs file system is used for root. So mention this
fact in remark line and add to bin-tplink_gz-v1.trid.xml additional
construct in global string section:
<String>HSQS</String>
All firmware file are now identified by new trid definitions ( see appended
trid-new.txt).
TrID definitions, and output are stored in archive tplink.zip. I hope that my
3 XML files can be used in future version of triddefs.
With best wishes
J?rg Jenderek