Это просто история о том, как реверс мне помог решить производственную задачу. Здесь не будет полезных рекомендаций или фрагментов кода, это лишь рассказ о проблеме и решении.
20 лет назад я работал на одном промышленном предприятии. За пару лет до моего прихода они закупили комплект автоматики у другого подобного предприятия. Как это часто бывает, сначала какая-то организация делает автоматику для решения своих задач, а затем, видя успешность своего решения, начинает продавать это решение себе подобным.
Так вот, автоматика закуплена, настроена и все работает. Это программно-аппаратный комплекс. Контроллеры, управляющие силовыми установками, и программа, со SCADA-подобным интерфейсом, которая схематично отражает производственный процесс на экране. Контроллеры общались со штатным ПО по modbus. У контроллеров есть небольшой экран и несколько кнопок. Контроллером можно управлять с его собственной панели управления, можно с пульта оператора или через modbus. У контроллера есть отдельный разъем для вывода его кнопок на обычный пульт оператора.
В чем основной смысл штатного ПО, помимо SCADA интерфейса. Оно позволяло отправить на контроллер последовательность операций, типа сделай "это", "это" и вот "это" и сказать "приступай". И контроллер начинал исполнять операции последовательно.
Руководство предприятия не устраивала та логика, которая была в коробочном ПО. Они хотели вкрутить свой процесс. Надо отметить, что в лучших традициях СССР вместе с контроллерами поставлялась подробная документация. Описание протокола, схемы подключения, команды, регистры.
Полистав документацию, я решил, что мы сможем реализовать дополнительную логику, о которой просило руководство. Правда, с modbus на тот момент я не был знаком.
Нашел спецификацию, почитал. Понял, как это работает. Чтобы не тратить время на написание своего экспериментального кода, я решил для пробы скачать готовую программу, чтобы просто отправить сообщение в порт. В доке было сказано, что устройство использует режим ASCII
.
Сформировал запрос ручками, рассчитал контрольную сумму, отправляю.
:1103006B00037E<CR><LF>
Устройство мне не отвечает. Хм..
Я скачал другую программу, итог тот же самый - нет ответа.
При этом штатная программа прямо в этот момент с того же компа общается без проблем.
Запустил снифер, стал смотреть, как они общаются. Ага, пакеты бегают. Запускаю из штатного ПО такую же операцию, которую собирал руками и вижу, что все значения как у меня - адрес, функция, регистр, но контрольная сумма отличается - 18
вместо 7E
.
:1103006B000318<CR><LF>
Если просто копирую это штатные сообщения из снифера и отправляю в порт, ответ от устройства приходит.
Странное дело. Еще раз перечитал спецификацию протокола, перепроверил свою LRC
- ну у меня все правильно! Откуда у контроллера получается 18
?
Поискал в интернетах. Нашел готовую софтину именно для modbus, там через выпадающие списки выбираются адрес, функция, регистр, а контрольная сумма вычисляется автоматически и она - такая же 7E
, как у меня! WTF?
Я пробовал разные варианты расчета, пытался подобрать принцип, но безуспешно.
Руководство жмет - ты же сказал, что там особых проблем не будет!
Выбора не было, запустил отладку в дизассемблере. Тогда опыта работы с ним тоже не было, максимум пробовал в студенческие годы менять je
на jne
, когда читал статейки про то, как ломают софт.
В общем, разобравшись с отладчиком, нашел в штатном ПО место обработки пакета и начал пошагово смотреть, что происходит.
О боги! Вот оно что!
Сообщение для отправки
11 03 00 6B 00 03
По спецификации вычислять надо просто
11 + 03 + 00 + 6B + 00 + 03 = 82
FF - 82 = 7D
7D + 01 = 7E
Ведь в сообщении уже HEX
А разработчики зачем-то сначала преобразовывали символы в их коды, то есть 1
в код символа 31
и суммировали преобразованные значения
31 + 31 + 30 + 33 + 30 + 30 + 36 + 42 + 30 + 30 + 30 + 33 = 2E8
После этого открытия обмен сообщениями пошел как надо. Моему счастью не было предела.
Если бы modbus завелся с полпинка, то это не принесло бы мне столько положительных эмоций. А при сложившихся обстоятельствах я эти эмоции получил :-)
Наверняка у вас тоже бывало нечто подобное - расскажите в коментах.