Open SamusAranX opened 2 weeks ago
Absolutely - extracting from firmware itself sounds like a very welcome feature! (That error definitely needs improvement as well - some recent commits add further validation, but more certainly needs to be done.)
646e4b7dc7c3fe8ccc82730dd6c762282bb642e5 (and future commits) introduce a scrape
subcommand that attempts to detect multiple SilverDBs throughout firmware based on its header format. It extracts them to their YAML representation directly, naming after the offset they were found within firmware.
It seems bitmap images are handled a little differently under classical firmware. There should now be support for its slightly-different bitmap metadata, alongside ARGB4444 and 2-bit grayscale images. I see that a quite few of the RGB images are messed up - seemingly due to the rendered/display width not being a multiple of the bitmap's width.
Please let me know if you find anything not working, or have success on other formats!
iPod nanos only have one internal SilverDB within their RetailOS firmware (holding some bitmaps + English (US) localization). The function to load such has the exact length of the database. In contrast like you noted, it seems iPods classics embed locale translations as separate databases within the binary itself. However, it appears that no functions/tables specify their exact length, or associated language. (Would love to learn more about how its firmware is structured, perhaps I missed this from a quick glance!)
Thank you so much for putting this in!
Some of the bitmaps found in the firmware I was looking at are indeed a little messed up, but I assume that's what you mentioned.
Do you think this can be fixed? I tried fixing some of these manually but sadly, the last rows of image data are just missing.
Also, I found an issue using the scrape
command on the 7th gen iPod nano's rsrc.fw.
(Using firmware iPod_1.0.4_37A40005.ipsw)
It keeps finding databases and images without actually writing any to the output directory, then eventually crashes like this:
229443404 is RgbEight
Color depth: 8
Dimensions: 64x1 (rendered at 1)
229443405 is Argb8888
Color depth: 32
Dimensions: 60x1 (rendered at 4)
thread 'main' panicked at src/cli/src/scrape.rs:50:23:
failed to parse scraped SilverDB: Failed to parse file format: failed to fill whole buffer
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
There's a different crash happening when trying to scrape the 2nd gen iPod mini's firmware (iPod_7.1.4.1.ipsw):
silverutil scrape Firmware-7.2.6.1 test
Found a database at offset 1499244...
Found a database at offset 1511036...
Found a database at offset 1512364...
Found a database at offset 1524476...
Found a database at offset 1536616...
Found a database at offset 1548452...
Found a database at offset 1549804...
Found a database at offset 1551156...
Found a database at offset 1563540...
Found a database at offset 1575264...
Found a database at offset 1589792...
Found a database at offset 1602360...
Found a database at offset 1603696...
Found a database at offset 1615712...
Found a database at offset 1627432...
Found a database at offset 1628800...
Found a database at offset 1640584...
Found a database at offset 1652776...
Found a database at offset 1665220...
thread 'main' panicked at src/cli/src/scrape.rs:61:23:
failed to parse scraped SilverDB: Invalid bitmap resource entry encountered!
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Though with the iPod mini's monochrome display, it'd make sense the bitmaps would use a different format than the later iPods.
To answer out of order: Absolutely, having complete iPod support would be wonderful. If you encounter any other firmwares with errors, please feel free to file another issue so it's easier to keep track of! I'm tracking support in #5 - that's all still a work in progress, but some images load.
Regarding the 7th gen iPod nano - the rsrc
image is a FAT16 partition! There's a large chance that the image SilverDB doesn't appear linearly within the partition's clusters. Adding FAT support sounds like it might be out of scope for this tool, but you can use 7-Zip/p7zip
/other tools to extract it.
(It would be highly ideal to improve that error, though! Perhaps scrape
should have some sort of detection of file headers like that to inform the user?)
Regarding the first - not entirely sure what's going on there. It definitely feels like the difference between rendered width and width isn't purely DPI related. (Topical to the above, this isn't limited to RGB images in the iPod Video - the 7th gen iPod nano on 1.0.4 also encounters this in e.g. resource ID 229442870
/0xDAD0536
.)
Going off the idea of multiples, it appears that any image whose rendered width isn't a multiple of two appears in that corrupted state. This also seems to applies to grayscale images, who we already override the specified width to what their rendered width is...
Modifying the following: https://github.com/spotlightishere/silverutil/blob/9dd52e85cd04aa5c4d3a5a9bcacb0531d9936050/src/bitmap/image.rs#L56-L64
to look similar to the following:
// (make `width` mutable!)
let mut width: u32 = match raw_format.image_type {
// [...]
};
let rendered_width = raw_format.rendered_width as u32;
if rendered_width != 0
&& (rendered_width / width) == 2
&& (rendered_width % width) != 0
&& raw_format.image_type != RawBitmapType::GrayscaleTwo
&& raw_format.image_type != RawBitmapType::GrayscaleFour
&& raw_format.image_type != RawBitmapType::GrayscaleEight
{
let difference: u32 = (rendered_width / 2).abs_diff(width);
width += difference;
println!("Adjusting width to {}", width);
}
appears to work, albeit adding an extra black column:
Obviously this is a hack so I won't commit it, but better understanding the relationship there would be quite beneficial 😅 It's unclear on how firmware handles it.
Having previously used this tool on firmware for the 6th gen iPod nano, I thought I'd try my luck with files from the last firmware for the 5th gen iPod Classic (iPod_25.1.3.ipsw). Alas, while its osos.fw seems to be unencrypted and I can find a bunch of
paMB
entries in it, silverutil crashes with this message:I realize this is because I'm feeding it the osos.fw file directly instead of the kind of file it's looking for, but there doesn't seem to be a way to split this specific osos.fw into smaller parts. Would it be at all possible to add a mode to this tool that scans arbitrary files for relevant data?