-
-
Save cleverca22/2a7e68d4a3d7802fcb3fe72c0aaa152a to your computer and use it in GitHub Desktop.
00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| | |
* | |
00000200 00 b0 00 01 f0 81 00 c0 e0 00 00 6d 82 18 0d 1f |...........m....| | |
00000210 1d c0 41 07 18 e8 00 e8 00 80 19 e8 67 e8 00 80 |..A.........g...| | |
00000220 31 68 f9 c0 01 cf 2d 1f 1d c0 40 07 18 e8 00 e8 |1h....-...@.....| | |
... |
[all] | |
BOOT_UART=0 | |
WAKE_ON_GPIO=1 | |
POWER_OFF_ON_HALT=0 | |
DHCP_TIMEOUT=45000 | |
DHCP_REQ_TIMEOUT=4000 | |
TFTP_FILE_TIMEOUT=30000 | |
TFTP_IP= | |
BOOT_ORDER=0x1 | |
SD_BOOT_MAX_RETRIES=3 | |
NET_BOOT_MAX_RETRIES=5 | |
[none] | |
FREEZE_VERSION=0 |
with import <nixpkgs> {}; | |
let | |
myghc = haskellPackages.ghcWithPackages (ps: with ps; [ formatting ]); | |
in runCommand "extractor" { buildInputs = [ myghc ]; } '' | |
mkdir -pv $out/bin | |
ghc ${./extractor.hs} -o $out/bin/extractor | |
'' |
{-# LANGUAGE DeriveGeneric #-} | |
{-# LANGUAGE OverloadedStrings #-} | |
{-# LANGUAGE NamedFieldPuns #-} | |
module Main where | |
import Data.Binary | |
import Data.Binary.Get | |
import qualified Data.ByteString as BS | |
import GHC.Generics | |
import Control.Applicative | |
import System.Environment | |
import Formatting ((%), sformat, hex, shown, stext) | |
import qualified Data.Text as T | |
import qualified Data.Text.Encoding as T | |
data FirmwareFile = FirmwareFile | |
{ firmwareEntries :: [ Entry ] | |
} deriving (Generic, Show) | |
instance Binary FirmwareFile where | |
get = FirmwareFile <$> many readEntry | |
put = undefined | |
data Entry = Entry | |
{ entryOffset :: ByteOffset | |
, entryMagic :: Word32 | |
, entrySize :: Word32 | |
, entryBody :: BS.ByteString | |
, entryPadding :: ByteOffset | |
} | FileEntry | |
{ entryFileMagic :: Word32 | |
, entryFileName :: T.Text | |
, entryFileBody :: BS.ByteString | |
} deriving Show | |
readEntry :: Get Entry | |
readEntry = do | |
offset <- bytesRead | |
magic <- getWord32be | |
len <- getWord32be | |
body <- getByteString $ fromIntegral len | |
tailOffset <- bytesRead | |
let | |
remainder = tailOffset `mod` 8 | |
paddingLen = if remainder == 0 then 0 else (8 - remainder) | |
padding <- getByteString $ fromIntegral paddingLen | |
if ( (magic == 0x55aaf22f) || (magic == 0x55aaf11f) ) | |
then do | |
let | |
filename :: T.Text | |
filename = T.decodeUtf8 $ BS.takeWhile (\c -> c /= 0) $ BS.take 16 body | |
filebody = BS.drop 16 body | |
pure $ FileEntry magic filename filebody | |
else | |
pure $ Entry offset magic len body tailOffset | |
decodeFirmware :: FilePath -> IO FirmwareFile | |
decodeFirmware = decodeFile | |
main :: IO () | |
main = do | |
args <- getArgs | |
let | |
prettyPrintEntry :: Entry -> IO () | |
prettyPrintEntry Entry{entryMagic, entryBody} = do | |
let | |
formatter = "Entry magic=" % hex % " initial_body=" % shown | |
putStrLn $ T.unpack $ sformat formatter entryMagic (BS.take 32 entryBody) | |
prettyPrintEntry FileEntry{entryFileMagic, entryFileName, entryFileBody} = do | |
let | |
formatter1 = "File Entry magic=" % hex % " name=" % stext % " body=" % shown | |
formatter2 = "File Entry magic=" % hex % " name=" % stext % " body=hidden" | |
go2 = putStrLn $ T.unpack $ sformat formatter1 entryFileMagic entryFileName (BS.take 100 entryFileBody) | |
go3 = putStrLn $ T.unpack $ sformat formatter2 entryFileMagic entryFileName | |
case entryFileName of | |
"bootconf.txt" -> go2 | |
_ -> go3 | |
go :: [String] -> IO () | |
go [file] = do | |
parsed <- decodeFirmware file | |
mapM_ prettyPrintEntry (firmwareEntries parsed) | |
mapM_ extractFiles (firmwareEntries parsed) | |
print "hello world" | |
go args | |
extractFiles :: Entry -> IO () | |
extractFiles Entry{entryMagic, entryBody} | |
| entryMagic == 0x55aaf00f = do | |
BS.writeFile "main-body.bin" entryBody | |
| otherwise = pure () | |
extractFiles FileEntry{entryFileName, entryFileBody} = do | |
BS.writeFile (T.unpack entryFileName) entryFileBody |
$ ./result/bin/extractor pieeprom-2019-10-16.bin | |
"hello world" | |
Entry magic=55aaf00f initial_body="\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL" | |
Entry magic=55aafeef initial_body="\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255" | |
File Entry magic=55aaf22f name=memsys00.bin body=hidden | |
File Entry magic=55aaf22f name=memsys01.bin body=hidden | |
File Entry magic=55aaf22f name=memsys02.bin body=hidden | |
File Entry magic=55aaf22f name=memsys03.bin body=hidden | |
File Entry magic=55aaf22f name=memsys04.bin body=hidden | |
File Entry magic=55aaf22f name=memsys05.bin body=hidden | |
File Entry magic=55aaf22f name=memsys06.bin body=hidden | |
File Entry magic=55aaf22f name=memsys07.bin body=hidden | |
File Entry magic=55aaf22f name=mcb.bin body=hidden | |
Entry magic=55aafeef initial_body="\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255" | |
File Entry magic=55aaf11f name=bootconf.txt body="[all]\nBOOT_UART=0\nWAKE_ON_GPIO=1\nPOWER_OFF_ON_HALT=0\nDHCP_TIMEOUT=45000\nDHCP_REQ_TIMEOUT=4000\nTFTP_F" |
-rw-r--r-- 1 clever users 61K Nov 11 19:29 main-body.bin | |
-rw-r--r-- 1 clever users 3.8K Nov 11 19:29 mcb.bin | |
-rw-r--r-- 1 clever users 21K Nov 11 19:29 memsys00.bin | |
-rw-r--r-- 1 clever users 21K Nov 11 19:29 memsys01.bin | |
-rw-r--r-- 1 clever users 21K Nov 11 19:29 memsys02.bin | |
-rw-r--r-- 1 clever users 21K Nov 11 19:29 memsys03.bin | |
-rw-r--r-- 1 clever users 21K Nov 11 19:29 memsys04.bin | |
-rw-r--r-- 1 clever users 21K Nov 11 19:29 memsys05.bin | |
-rw-r--r-- 1 clever users 21K Nov 11 19:29 memsys06.bin | |
-rw-r--r-- 1 clever users 21K Nov 11 19:29 memsys07.bin |
00000000 1c 00 00 00 40 06 00 00 80 0c 00 00 08 00 00 00 |....@...........| | |
00000010 00 00 00 00 00 00 00 00 98 00 00 00 ef a6 32 01 |..............2.| | |
00000020 00 00 00 00 00 00 00 00 89 4d 3a ea 02 02 00 00 |.........M:.....| | |
00000030 02 3d 00 00 21 5c 10 00 b0 11 27 00 50 b2 00 00 |.=..!\....'.P...| | |
... |
cleverca22
commented
Nov 11, 2019
•
the magic must be in the 55aaf__f
range, or bootcode.bin
will abort
the length must be <16mb (24bit int, not 32bit) or bootcode.bin
will abort
magic 55aaf33f
has some kind of 32 byte footer after the body??, probably a sha256 hash of the body?
As I poked around pieeprom for a bit as well: Did you by any chance figure out how the files are compressed? Looking at qrcode.bin
, you see that there's TRU\x00EVISION-\x00XFILE
in there, hinting that it's saved as a TGA file. But the zero-bytes within the string itself suggest that there's some kind of mangling/compression at work as well.
https://git.venev.name/hristo/rpi-eeprom-compress/
raspberrypi/rpi-eeprom#153
and i have since moved this code over to https://github.com/librerpi/rpi-tools/tree/master/eeprom
i think the reason the decompress code errors out, is because the sha256 of the uncompressed body was appended to the end, so i need to cut just the compressed payload out, decompress, then validate the hash
Thank you very much! I especially like that your compressor seems to be better than the one used to compress the existing files. :-)
wasnt my decompressor, somebody else made that comment
i still need to implement that decompression into my extraction code
i'm also on #raspberrypi-internals on freenode if you want to chat more about pi things
wasnt my decompressor, somebody else made that comment
i still need to implement that decompression into my extraction code
i'm also on #raspberrypi-internals on freenode if you want to chat more about pi things
Is there Pi eeprom extraction tool? I see vl805.bin inside and wondering if there's newer vl805 firmware inside?
I flashed vl805_fw_0138a1.bin from raspberry pi to a vl805 based PCIe card - it works but didn't fix UAS performance issues.
Wondering if the Pi has other firmware or tricks for this chipset.
@jpmorrison the vl805 firmware inside this eeprom is in a different format, and cant be flashed to the vl805 eeprom
it must instead be sideloaded at runtime, https://github.com/librerpi/rpi-open-firmware/blob/master/docs/vl805.txt partially explains how