Это просто история о том, как реверс мне помог решить производственную задачу. Здесь не будет полезных рекомендаций или фрагментов кода, это лишь рассказ о проблеме и решении.

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 завелся с полпинка, то это не принесло бы мне столько положительных эмоций. А при сложившихся обстоятельствах я эти эмоции получил :-)

Наверняка у вас тоже бывало нечто подобное - расскажите в коментах.