LINUX.ORG.RU

GPT, UUID и CRS32

 , , ,


0

1

Здравствуйте!

Возникла необходимость изменить UUID в LBA2 (по смещению 0x10) в Pri GPT table и, соответственно в Sec GPT table. В принципе я могу это сделать, но не знаю как подсчитать CRC32 of header и CRC32 of partition array (обе по четыре байта) в GPT header (LBA1).

Имеющаяся в OS X утилита CRS32 если я считаю контрольную сумму с обнулёнными 4 байтами по смещению 0x10 в LBA1 даёт не соответствующий результат.

Вопрос:

ЧЯДНТ и как победить?

Заранее благодарен за помощь!

P.S.

Это нужно т.к. в NVRAM в частности записано:

efi-apple-recovery <array><dict><key>IOMatch</key><dict><key>IOProviderClass</key><string>IOMedia</string><key>IOPropertyMatch</key><dict><key>UUID</key><string>92C9B4A1-7CC2-4841-9EAC-C19FF21B06EB</string></dict></dict><key>BLLastBSDName</key><string>disk0s1</string></dict><dict><key>IOEFIDevicePathType</key><string>MediaFilePath</string><key>Path</key><string>\EFI\APPLE\FIRMWARE\MBA41_0077_B15_LOCKED.scap</string></dict></array>%00

мне нужно заменить SSD, а терять возможность восстановления при сбое в BootROM не хочеться, а как БЕЗОШИБОЧНО переписать эту переменную в NVRAM я не знаю, а экспериментировать стрёмно.

как победить?

Не лазить руками, использовать софт под задачу.

$ sudo hexdump -C -s 512 -n 512 /dev/sdb
00000200  45 46 49 20 50 41 52 54  00 00 01 00 5c 00 00 00  |EFI PART....\...|
00000210  56 38 e3 04 00 00 00 00  01 00 00 00 00 00 00 00  |V8..............|
00000220  af 6d 70 74 00 00 00 00  22 00 00 00 00 00 00 00  |.mpt....".......|
00000230  8e 6d 70 74 00 00 00 00  00 4d 5f 76 80 39 c2 4b  |.mpt.....M_v.9.K|
00000240  91 b2 84 96 f2 78 a4 e0  02 00 00 00 00 00 00 00  |.....x..........|
00000250  80 00 00 00 80 00 00 00  40 d7 06 1e 00 00 00 00  |........@.......|
00000260  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000400

$ sudo dd if=/dev/sdb bs=1 skip=512 count=$((0x5c)) of=/tmp/pri
92+0 records in
92+0 records out
92 bytes copied, 0.000398295 s, 231 kB/s

$ sudo dd if=/dev/zero of=/tmp/pri bs=1 count=4 seek=16 conv=notrunc
4+0 records in
4+0 records out
4 bytes copied, 0.000122002 s, 32.8 kB/s

$ crc32 /tmp/pri 
04e33856
d ★★★ ()
Ответ на: комментарий от d

Так я так и делал, но ЗАБЫЛ про LITTLE-ENDIAN!!!

sudo hexdump -C -s 512 -n 512 /dev/disk0
Password:
00000200  45 46 49 20 50 41 52 54  00 00 01 00 5c 00 00 00  |EFI PART....\...|
00000210  c5 41 b0 73 00 00 00 00  01 00 00 00 00 00 00 00  |.A.s............|
00000220  ff ff 1f 0e 00 00 00 00  22 00 00 00 00 00 00 00  |........".......|
00000230  de ff 1f 0e 00 00 00 00  ce 79 14 9a fc 30 8d 4a  |.........y...0.J|
00000240  8f 57 22 76 71 75 78 06  02 00 00 00 00 00 00 00  |.W"vqux.........|
00000250  80 00 00 00 80 00 00 00  f5 e9 b7 9e 00 00 00 00  |................|
00000260  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000400

crc32 /NV/lba1copy
73b041c5

Про little-endian забыл!!!

Cave-Canem ()
Ответ на: Так я так и делал, но ЗАБЫЛ про LITTLE-ENDIAN!!! от Cave-Canem

Решение, пусть здесь полежит:

#Запись в переменную sec_gpt_table значения начала Sec GPT table:
sec_gpt_table=$(sudo gpt show disk0 | grep "Sec GPT table" | awk '{print $1}')

#Запись в переменную sec_gpt_header значения начала Sec GPT header:
sec_gpt_header=$(sudo gpt show disk0 | grep "Sec GPT header" | awk '{print $1}')

#-------------------------------------------------------------------------------

#Сохранение LBA1:
sudo dd bs=1b if=/dev/disk0 of=/TMP/LBA1 skip=1 count=1

#Сохранение значимой для CRC части LBA1
dd bs=1 if=/TMP/LBA1 of=/TMP/LBA1-header count=$((0x5c))

#Сохранение LBA2:
sudo dd if=/dev/disk0 bs=1b skip=2 count=1 of=/TMP/LBA2

#Сохранение старого EFI UUID:
sudo dd if=/dev/disk1 bs=1 skip=1040 count=16 of=/TMP/EFI_UUID

#Запись 16 байт старого UUID по смещению 0x10  в файл LBA2:
dd if=/TMP/EFI_UUID bs=1 seek=16 count=16 conv=notrunc of=/TMP/LBA2

#Запись LBA2 — Pri GPT table:
sudo dd if=/TMP/LBA2 bs=1b seek=2 count=1 /dev/disk0

#Запись LBA2 в  Sec GPT table:
sudo dd if=/TMP/LBA2 bs=1b seek=${sec_gpt_table} count=1 /dev/disk0

#Подсчет и запись котрольной суммы изменённого Partition Entry Array, а так же
#преобразование ASCII в binary little-endian
sudo dd if=/dev/disk0 bs=1b skip=2 count=32 of=/TMP/LBA2-32
crc32 /TMP/LBA2-32 | perl -e 'print pack "V", hex(<STDIN>)' > /TMP/CRC_LBA2

#Изменение в файле LBA-header по смещению 0x58 (crc):
dd if=/TMP/CRC_LBA2 bs=1 seek=$((0x58)) count=4 conv=notrunc of=/TMP/LBA1-header

#Обнуление crc по смещению 0x10 4 байт в LBA1-header
dd if=/dev/zero of=/TMP/LBA1-header bs=1 count=4 seek=16 conv=notrunc

#Подсчёт и запись контрольной суммы измененного Partition table header (LBA1) 
#с изменённым CRC (с преобразованием ASCII в binary little-endian):
crc32 /TMP/LBA1-header | perl -e 'print pack "V", hex(<STDIN>)' > /TMP/CRC_LBA1-header
dd if=/TMP/CRC_LBA1-header bs=1 seek=$((0x10)) count=4 conv=notrunc of=/TMP/LBA1-header

#Запись в /TMP/LBA1:
dd if=/TMP/LBA1-header count=1 conv=sync of=/TMP/LBA1

#Запись в Partition table header (LBA 1) — Pri GPT header
sudo dd if=/TMP/LBA1 bs=1b seek=1 count=1 of=/dev/disk0

#Запись в Sec GPT header
sudo dd if =/TMP/LBA1 bs=1b seek=${sec_gpt_header} count=1 of=/dev/disk0

ВСЁ!

Cave-Canem ()