Вроде были вопросы о том, как сделать программу работоспособной только на одном/нескольких контроллерах, то есть предотвратить её выполнение на других контроллерах той же модели с той же прошивкой. Консенсус был таков, что уникальных ключей у идентичных контроллеров нет, и нужно использовать внешний (аппаратный) ключ.
Но кажется, у меня получилось организовать чисто программную проверку заводского MAC-адреса ПЛК серий 110 и 160. Вкратце: заводской MAC-адрес обнаружился по адресам 2069CD2E у ПЛК160 и 2060E5B0 у ПЛК110-32.
Подробнее... Я поставил задачу найти заводской MAC-адрес в оперативной памяти ПЛК после того, как адрес в файле local_addres.dat был изменён (естественно, не натыкаясь на константы в своей же программе). На коленке был написан вот такой сканирующий память код:
Код:
VAR
i, g, c: DWORD;
go: BOOL;
mac0: ARRAY[0..5] OF BYTE;
END_VAR
VAR CONSTANT
MAC: ARRAY[0..5] OF BYTE := 16#6A, 16#77, 16#00, 16#00, 16#00, 16#F8;
END_VAR
IF go THEN
g := i + 2000;
FOR i := i TO g DO
SysMemCpy(ADR(mac0), i, SIZEOF(mac0));
go := NOT(mac0[0] = MAC[0] AND mac0[1] = MAC[1] AND mac0[5] = MAC[5] AND i <> ADR(MAC));
IF NOT go THEN
c := i;
i := i + 1;
EXIT;
END_IF
END_FOR
END_IF
В константах записан заводской адрес контроллера с изменёнными 4 и 5 байтами. Программа ищет совпадение в памяти по первому, второму и шестому байтам. Если при нахождении адреса мы наблюдаем в mac0 заводской адрес, и после перезагрузки результат получается тот же самый, то можно из своей программы удостоверяться в подлинности контроллера по этому адресу. Что-то вроде genuine := SysMemCmp(16#2060E5B0, ADR(MAC), SIZEOF(MAC)) = 0; Конечно, в боевой программе MAC-адрес лучше хранить не в открытом виде как показано выше, а хэшем константы с солью, чтобы исключить атаку тупой подменой байтов в бинарнике с пересчётом контрольной суммы. Обход такой защиты уже может оказаться нетривиальным и оттого нецелесообразным.
Дальше исследовать способ предлагаю заинтересованным в защите лицам.