Hi uklad,
interesting i spent some time trying to get port 2 active with no luck..
One trick is as follows:
Copy that file
/etc/config/defaultvalue.gz from the squashfs read-only root file system to a read-write file system (e.g. a ramdisk).
Modify that read-writable copy with the desired configurations.
Re-mount the modified file over the top of the original in the read-only squashfs.
(See the Linux/busybox manpage for
mount, and the
--bind option.)
Force the config software - the firmware utility that actually reads the contents of that file - to re-load it.
Since this doesn't modify the
squashfs system it is non-destructive. The hack is described well by paul at sbrk.co.uk at [1].
do you know what files are failing during the decompression..
One of those two bad LZMA data blocks is in the middle of the 461,960 byte
busybox binary. It is block #7 of 8, @ 0x32edc in
ecirootfs2
Igor Pavlov's suggestions are currently under test. His theory is that maybe just the data block headers are corrupted, while the data in those blocks is actually okay.
Each data block in the
squashfs-lzma file system is prepended with a 13-byte LZMA header. This header contains an 8-bit field in which the lc, lp and pb parameters for the LZMA decoder are stored, as well as a 32-bit field to hold the dictionary size, and a 64-bit field for the uncompressed size of the block.
Below we can see the header from a good block (
test1.lzma) and then the header of a bad block (
test2.lzma). Both headers are clearly identical. Both have a decoder configuration of 0x5d, both use a dictionary size of 0x800000 (8Mbytes), and both blocks apparently uncompress to a size of 0x10000 (65,536) bytes.
$ cd ~/Documents/btinfinity/eci_asbo001/lzma439_asbo002/C/7zip/Compress/LZMA_C
$ xxd -l 13 test1.lzma
0000000: 5d00 0080 0000 0001 0000 0000 00 ]............
$ xxd -l 13 test2.lzma
0000000: 5d00 0080 0000 0001 0000 0000 00 ]............
What
Igor Pavlov is suggesting is that perhaps the value in the uncompressed size field of a bad block has been faked. When the LZMA decoder discovers at run-time that the uncompressed size is not what it expected, the decoder aborts with an error.
Igor Pavlov says that perhaps this is the method used for locking the
squashfs file system in the ECI.
The easiest way to test that theory is to repeatedly feed the same bad data block through the LZMA decoder. In each iteration, the uncompressed size field is increased. This is repeated until an error is reported by the LZMA decoder.
That's what is shown below. We can see that the compressed bitstream in the bad data block can be decoded up until byte 31,869. Remember, however, that in the header of that data block, the uncompressed size of the block was recorded as 65,536 bytes.
This identifies one of two things.
Either it reveals the genuine uncompressed size of the data block, or it reveals the point at which the compressed bitstream is corrupted (forcing the decoder to abort.)
$ ./lzmadec test2.lzma test2.bin
Opened test2.lzma
compressedSize = 17129
outSizeFull = 65536
Calling LzmaDecode(compressedSize = 17129, estimOutSize = 17079) : returned res = 0 (success) -- inProcessed = 7525, outProcessed = 17079
Calling LzmaDecode(compressedSize = 17129, estimOutSize = 17080) : returned res = 0 (success) -- inProcessed = 7525, outProcessed = 17080
Calling LzmaDecode(compressedSize = 17129, estimOutSize = 17081) : returned res = 0 (success) -- inProcessed = 7525, outProcessed = 17081
Calling LzmaDecode(compressedSize = 17129, estimOutSize = 17082) : returned res = 0 (success) -- inProcessed = 7525, outProcessed = 17082
Calling LzmaDecode(compressedSize = 17129, estimOutSize = 17083) : returned res = 0 (success) -- inProcessed = 7527, outProcessed = 17083
[.. snipped ..]
Calling LzmaDecode(compressedSize = 17129, estimUncompSize = 31866) : returned res = 0 (success) -- inProcessed = 12067, outProcessed = 31866
Calling LzmaDecode(compressedSize = 17129, estimUncompSize = 31867) : returned res = 0 (success) -- inProcessed = 12067, outProcessed = 31867
Calling LzmaDecode(compressedSize = 17129, estimUncompSize = 31868) : returned res = 0 (success) -- inProcessed = 12069, outProcessed = 31868
Calling LzmaDecode(compressedSize = 17129, estimUncompSize = 31869) : returned res = 0 (success) -- inProcessed = 12069, outProcessed = 31869
Calling LzmaDecode(compressedSize = 17129, estimUncompSize = 31870) : returned res = 1 (fail) -- inProcessed = 0, outProcessed = 0
Calling LzmaDecode(compressedSize = 17129, estimUncompSize = 31871) : returned res = 1 (fail) -- inProcessed = 0, outProcessed = 0
Calling LzmaDecode(compressedSize = 17129, estimUncompSize = 31872) : returned res = 1 (fail) -- inProcessed = 0, outProcessed = 0
Calling LzmaDecode(compressedSize = 17129, estimUncompSize = 31873) : returned res = 1 (fail) -- inProcessed = 0, outProcessed = 0
Calling LzmaDecode(compressedSize = 17129, estimUncompSize = 31874) : returned res = 1 (fail) -- inProcessed = 0, outProcessed = 0
Calling LzmaDecode(compressedSize = 17129, estimUncompSize = 31875) : returned res = 1 (fail) -- inProcessed = 0, outProcessed = 0
[.. snipped ..]
By way of reference, here is the output from the same test performed on the good data block. We can see that it successfully decodes the block up until byte 65,536. That is correct insofar as it matches the uncompressed size reported in the block header.
$ ./lzmadec test1.lzma test1.bin
Opened test1.lzma
compressedSize = 25826
outSizeFull = 65536
Calling LzmaDecode(compressedSize = 25826, estimUncompSize = 25776) : returned res = 0 (success) -- inProcessed = 10700, outProcessed = 25776
Calling LzmaDecode(compressedSize = 25826, estimUncompSize = 25777) : returned res = 0 (success) -- inProcessed = 10701, outProcessed = 25777
Calling LzmaDecode(compressedSize = 25826, estimUncompSize = 25778) : returned res = 0 (success) -- inProcessed = 10701, outProcessed = 25778
Calling LzmaDecode(compressedSize = 25826, estimUncompSize = 25779) : returned res = 0 (success) -- inProcessed = 10701, outProcessed = 25779
Calling LzmaDecode(compressedSize = 25826, estimUncompSize = 25780) : returned res = 0 (success) -- inProcessed = 10702, outProcessed = 25780
[.. snipped ..]
Calling LzmaDecode(compressedSize = 25826, estimUncompSize = 65530) : returned res = 0 (success) -- inProcessed = 25824, outProcessed = 65530
Calling LzmaDecode(compressedSize = 25826, estimUncompSize = 65531) : returned res = 0 (success) -- inProcessed = 25824, outProcessed = 65531
Calling LzmaDecode(compressedSize = 25826, estimUncompSize = 65532) : returned res = 0 (success) -- inProcessed = 25824, outProcessed = 65532
Calling LzmaDecode(compressedSize = 25826, estimUncompSize = 65533) : returned res = 0 (success) -- inProcessed = 25826, outProcessed = 65533
Calling LzmaDecode(compressedSize = 25826, estimUncompSize = 65534) : returned res = 0 (success) -- inProcessed = 25826, outProcessed = 65534
Calling LzmaDecode(compressedSize = 25826, estimUncompSize = 65535) : returned res = 0 (success) -- inProcessed = 25826, outProcessed = 65535
Calling LzmaDecode(compressedSize = 25826, estimUncompSize = 65536) : returned res = 0 (success) -- inProcessed = 25826, outProcessed = 65536
Calling LzmaDecode(compressedSize = 25826, estimUncompSize = 65537) : returned res = 1 (fail) -- inProcessed = 0, outProcessed = 0
Calling LzmaDecode(compressedSize = 25826, estimUncompSize = 65538) : returned res = 1 (fail) -- inProcessed = 0, outProcessed = 0
Calling LzmaDecode(compressedSize = 25826, estimUncompSize = 65539) : returned res = 1 (fail) -- inProcessed = 0, outProcessed = 0
Calling LzmaDecode(compressedSize = 25826, estimUncompSize = 65540) : returned res = 1 (fail) -- inProcessed = 0, outProcessed = 0
Calling LzmaDecode(compressedSize = 25826, estimUncompSize = 65541) : returned res = 1 (fail) -- inProcessed = 0, outProcessed = 0
Calling LzmaDecode(compressedSize = 25826, estimUncompSize = 65542) : returned res = 1 (fail) -- inProcessed = 0, outProcessed = 0
Calling LzmaDecode(compressedSize = 25826, estimUncompSize = 65543) : returned res = 1 (fail) -- inProcessed = 0, outProcessed = 0
[.. snipped ..]
It looks like the hack goes deeper than just faking the LZMA header fields. The compressed bitstream itself has been tweaked.
In those tests where the bad data block was repeatedly fed to the LZMA decoder, we can study the last good iteration before a decoding error occurred:
Calling LzmaDecode(compressedSize = 17129, estimUncompSize = 31869) : returned res = 0 (success) -- inProcessed = 12069, outProcessed = 31869
We can see that the decoder has only processed 12069 bytes out of 17129 bytes in the compressed datastream. For the hacked header theory to be correct, it would mean here that the compressed block has 5060 'dead' bytes of padding. (17129-12069 = 5060).
If the hack just involved a header hack, there would be no point in doing that. It would be unnecessary and wasteful. The uncompressed block size only needs to be faked by one byte. That will still cause a decode failure. There's no point in faking the size by 5060 bytes, and then padding the compressed datastream with all those pointless bytes.
It's still a working theory though, so there may be something in it.. :-)
cheers, a
[1]
http://www.sbrk.co.uk/hw553/general/rofs.html