Ключевые слова:hardware, (найти похожие документы)
From: Nikola Krasnoyarsky <nikl@fannet.ru>
Subject: Восстановление содержимого микросхемы EEPROM типа 93c46 в сетевой карте HomePNA
Для хранения информации по настройкам, адресу MAC и прочему
карта использует весьма распространенную микросхему памяти eeprom
серии 93c46 с объемом памяти 128 байт. Для реальной работы bcm4210
используется первая половина памяти, 64 байта. Это предисловие.
Реальная история. Работала-работала карточка, потом ее владелец
сказал что работать перестала и действительно, при прохождении
тестов последние утверждали, что карта мертвая.
Перед тем, как выкинуть ее или пустить в расход на радиодетали,
высказалось предположение, что возможно, всего-лишь "полетела" eeprom.
Найденная в интернете схема программатора для LPT-порта оказалась
очень простой в изготовлении (6 проводков, разъем, и панелька на 8 ног).
Считанная область памяти являла собой полный мусор. Считанная память из
другой карточки (живой) была перешита в чистую микросхему, вставлена
в "мертвую" карту и.. о, чудо! заработала.
Далее вариантов два. Если не планируется использовать карты в одном сегменте
сети (на пирпарах), то можно просто залить в них одинаковые дампы и гонять
на здоровье. Для пирпары ситуация с двумя одинаковыми адресами MAC непреемлема.
Берем любой редактор двоичных файлов, в дампе меняем адрес MAC и заливаем
дамп назад в карту. Встречаем ошибку: ilc_chipattach: bad sys sprom crc8
Видимо (и это правильно) в драйвере есть проверка целостности дампа памяти.
Так как драйвера для карточек поставляются в бинарном виде (на исходный
текст, видимо, наложены какие-то лицензионные ограничения), то подсмотреть
"правильность" работы я не мог и пришлось воспользоваться хакерскими
навыками, используя дизассемблер IDA Pro.
Последним было выявлено, что идет начитка первых 64 байт памяти, подсчет
функции crc8 и сравнением результата с волшебным числом 0x9F.
Взятые с интернета примеры расчета crc8 не работали. Той же IDA Pro
узнал, что в реализации функции crc8 используется нестандартная таблица.
"Правильную" я вырезал из тех-же драйверов. Из теории crc8 известно, чтобы
"подогнать" данные под "нужную" crc, достаточно исправить один байт, причем
с любого смещения данных. Байт по смещению 64 и оказался "козлом отпущения".
Итак, что мы имеем. В дампе можно прописать нужный нам адрес MAC, и "подогнать"
последний байт под значение, верное для crc8 = 0x9F.
Программа на языке C: (параметром ей передается имя файла с дампом,
на выходе имеем правильное значение байта по смещению 64. Исправляем
в редакторе. заливаем дамп в карточку, включаем и радуемся жизни.
Разумеется все гарантии идут лесом. Какой путь выбрать, это ваше личное дело)
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
static unsigned char crc8_table[256] =
{
0x00,0xf7,0xb9,0x4e,0x25,0xd2,0x9c,0x6b,
0x4a,0xbd,0xf3,0x04,0x6f,0x98,0xd6,0x21,
0x94,0x63,0x2d,0xda,0xb1,0x46,0x08,0xff,
0xde,0x29,0x67,0x90,0xfb,0x0c,0x42,0xb5,
0x7f,0x88,0xc6,0x31,0x5a,0xad,0xe3,0x14,
0x35,0xc2,0x8c,0x7b,0x10,0xe7,0xa9,0x5e,
0xeb,0x1c,0x52,0xa5,0xce,0x39,0x77,0x80,
0xa1,0x56,0x18,0xef,0x84,0x73,0x3d,0xca,
0xfe,0x09,0x47,0xb0,0xdb,0x2c,0x62,0x95,
0xb4,0x43,0x0d,0xfa,0x91,0x66,0x28,0xdf,
0x6a,0x9d,0xd3,0x24,0x4f,0xb8,0xf6,0x01,
0x20,0xd7,0x99,0x6e,0x05,0xf2,0xbc,0x4b,
0x81,0x76,0x38,0xcf,0xa4,0x53,0x1d,0xea,
0xcb,0x3c,0x72,0x85,0xee,0x19,0x57,0xa0,
0x15,0xe2,0xac,0x5b,0x30,0xc7,0x89,0x7e,
0x5f,0xa8,0xe6,0x11,0x7a,0x8d,0xc3,0x34,
0xab,0x5c,0x12,0xe5,0x8e,0x79,0x37,0xc0,
0xe1,0x16,0x58,0xaf,0xc4,0x33,0x7d,0x8a,
0x3f,0xc8,0x86,0x71,0x1a,0xed,0xa3,0x54,
0x75,0x82,0xcc,0x3b,0x50,0xa7,0xe9,0x1e,
0xd4,0x23,0x6d,0x9a,0xf1,0x06,0x48,0xbf,
0x9e,0x69,0x27,0xd0,0xbb,0x4c,0x02,0xf5,
0x40,0xb7,0xf9,0x0e,0x65,0x92,0xdc,0x2b,
0x0a,0xfd,0xb3,0x44,0x2f,0xd8,0x96,0x61,
0x55,0xa2,0xec,0x1b,0x70,0x87,0xc9,0x3e,
0x1f,0xe8,0xa6,0x51,0x3a,0xcd,0x83,0x74,
0xc1,0x36,0x78,0x8f,0xe4,0x13,0x5d,0xaa,
0x8b,0x7c,0x32,0xc5,0xae,0x59,0x17,0xe0,
0x2a,0xdd,0x93,0x64,0x0f,0xf8,0xb6,0x41,
0x60,0x97,0xd9,0x2e,0x45,0xb2,0xfc,0x0b,
0xbe,0x49,0x07,0xf0,0x9b,0x6c,0x22,0xd5,
0xf4,0x03,0x4d,0xba,0xd1,0x26,0x68,0x9f
};
unsigned char crc8(unsigned char *data, size_t len) {
size_t i;
unsigned char crc = 0xff;
for (i=0; i<len; i++)
crc = crc8_table[ (crc ^ *data++) & 0xff] ;
return crc;
}
int main(int argc, char *argv[]) {
#define MAGIC_CRC 0x9F
FILE *f;
unsigned char i=0, array64[64];
if (argc < 2) {
printf("%s\n"," Usage: me <input_file>");
exit(-1);
}
f = fopen(argv[1], "rb");
fread(array64,sizeof(array64),1,f);
array64[63] = '\0';
while (crc8((unsigned char *)array64,64) != MAGIC_CRC)
array64[63] = ++i;
printf("64th byte must be 0x%02X\n", i--);
fclose(f);
return 0;
}