Как я читерил с помощью ИИ в реверс-инжиниринге промышленного ПО

Наша команда занимается разработкой и внедрением систем предиктивной диагностики промышленного оборудования на предприятиях нефтегазохимического комплекса. Поскольку значительная доля технологического оборудования и промышленных информационных систем на таких предприятиях имеет зарубежное происхождение, интеграция с ними никогда не была простой задачей, а в условиях санкционного давления заметно усложнилась.
Нередко нам приходится анализировать и разбирать закрытые протоколы передачи данных и форматы хранения исторических архивов. Это всегда кропотливая и во многом рутинная работа, которой сложно дать первоначальную оценку, поэтому запланировать сроки её выполнения заранее не удаётся. Более того, очень мало специалистов, которые обладают необходимым опытом и кругозором (экспертными знаниями разных промышленных информационных систем) для эффективного решения этих задач. Однако результат этой работы крайне важен: данные, которые хранятся в исторических архивах, требуются для обучения ML-моделей, которые используются в предиктивной диагностике, а интеграция в существующие информационные системы нужна для получения доступа к сырым текущим данным, необходимым для анализа.
В итоге неопределённость сроков реверс-инжиниринга мешает эффективно планировать все последующие этапы внедрения. Именно поэтому, рассматривая генеративный ИИ как способ повысить эффективность нашей команды в целом, было принято решение в первую очередь попробовать применить его именно в реверс-инжиниринге.
Постановка задачи
В системах управления газотурбинными установками Solar Turbines используется программно-аппаратный комплекс TT4000, который выполняет функции сбора данных, ведения журналов событий и алармов, а также архивирования исторических значений параметров. Исторические данные сохраняются в бинарные файлы с расширением «.log». Каждый файл соответствует определённому временному окну и определённой дискретности записи – например, час, минута, десять секунд и т.д.
Формат файлов (*.log) системы TT4000 является проприетарным и закрытым. Разработчик (Solar Turbines) не публикует спецификации формата, не предоставляет SDK для его чтения и не документирует структуру записей.
Необходимо разработать программный конвертер на языке Python, который:
принимает на вход путь к бинарному файлу архива (*.log) системы TT4000;
разбирает структуру файла;
извлекает исторические значения всех аналоговых параметров (тэгов);
сохраняет результат в формате CSV.
Выходной CSV-файл должен удовлетворять следующим требованиям:
Первый столбец должен иметь заголовок DateTime и содержать метки времени в формате «год-месяц-день часы:минуты:секунды» (например, 2006-01-02 04:05:00), соответствующие моментам записи значений.
Каждый последующий столбец должен иметь в качестве заголовка наименование тэга (параметра). Ниже в этом столбце должны располагаться значения данного тэга для соответствующих меток времени из первого столбца.
Для каждой метки времени в строке должен присутствовать хотя бы один непустой тэг. Обратное не требуется: допускается, что в один момент времени часть тэгов не имеет значения (для них ячейки остаются пустыми).
Все записи в файле должны быть отсортированы по метке времени от меньшей к большей.
Первый опыт: попытка решить в лоб
Я решил начать с бесплатных online-сервисов, среди которых рассматривал GigaChat, Алису, Qwen и DeepSeek.
У GigaChat нельзя прикрепить к промпту файл размером более 5Mb, но даже с бинарным файлом архивных данных на 3Mb бот не дал ответа, а сообщил об ошибке «Не удалось получить ответ модели». После удаления вложения я получил скрипт с функциями сортировки и записи в CSV результатов разбора бинарного файла архивов. Однако вместо самой логики парсинга GigaChat оставил только «заглушки» и указал, что эту часть кода мне необходимо написать самостоятельно. Такой результат дают как режим «Гига», так и режим «Рассуждения», ознакомиться с диалогами можно по ссылкам:
режим «Гига»: https://giga.chat/link/gcsMloaIVy;
режим «Рассуждения»: https://giga.chat/link/gcsGCejWoZ.
Это совершенно не решает поставленную задачу – запись уже готовых данных в CSV не является сколь-нибудь сложной задачей.
При работе с Алисой не получилось прикрепить к промпту исходный файл архива (.log), но, в отличие от GigaChat, Алиса сообщила о неподдерживаемом формате, и я попробовал переименовать расширение файла в «.txt» – это сработало. При решении задачи Алиса сразу включила режим «Эксперт» и довольно долго рассуждала – целых 33 итерации. Забавно, завершив серию рассуждений, Алиса сообщила о готовности скрипта с комментариями, но сам код показала только после отдельной просьбы.
Я запустил скрипт, указав на прикреплённый к промпту файл, и он завершился с ошибкой: «'utf-16-le' codec can't decode byte 0x5f in position 14: truncated data». Текст ошибки указывает на то, что при чтении файла была выбрана 16-разрядная кодировка (UTF-16 LE), тогда как фактически используется 8-разрядная: из-за нечётного количества байтов последний символ представлен неполным кодом (одним байтом), что и приводит к сбою.
Открыв один из бинарных файлов в HEX-редакторе, я обнаружил, что заголовок файла соответствует 8-разрядной кодировке (один байт на символ), а далее в файле явно видны строки записанные в 16-разрядной кодировке (см. рис. 1):
«This is Binary File for TT4000 Data Format Version 5.0 Created on Thu Mar 20 00:00:00 2025. V.5.0.0.666 SP 44» – текст в 8-разрядной кодировке (без учета символов переноса строки и возврата каретки);
«Turbotronic Gateway» – строка в 16-разрядной кодировке.

ASCII-коды латинских символов в 8-разрядных кодировках идентичны одному из байтов аналогичного символа в 16-разрядных кодировках. Какому именно – первому (Little Endian) или второму (Big Endian), определяется маркером порядка байт (BOM), который должен находиться в начале файла (если весь файл текстовый) или в начале текстового фрагмента (если файл содержит как бинарные данные так и текстовые – наш случай):
0xFF 0xFE – для UTF-16LE (Little Endian);
0xFE 0xFF – для UTF-16BE (Big Endian).
Однако, как видно из рис. 1, в представленном фрагменте файла не встречается ни одна из этих последовательностей 2 байт.
Поскольку задача заключалась в попытке выполнить реверс-инжиниринг исключительно силами ИИ, следующим промптом я просто передал Алисе текст ошибки, с которой упал скрипт. Снова пошли итерации рассуждений – дважды они завершались полной тишиной, но короткий промпт «Покажи текст итогового скрипта» возвращал Алису к жизни. В итоге ещё через 29 итераций я получил: обновлённую версию скрипта, подробное описание структуры бинарного файла и готовый CSV‑файл с результатом обработки исходных бинарных данных (см. рис. 2).

То, что в ответе появился результирующий CSV-файл, означает, что у Алисы есть доступ к среде исполнения, где она может отлаживать написанный код.
Диалог с Алисой доступен по ссылке: https://alice.yandex.ru/?share=ba3fc479-32d2-d923-edac-4c338ec815a1.
Я выполнил скрипт для каждого бинарного файла архивов системы TT4000 и каждый раз получал CSV-файл с необходимыми историческими данными – это было похоже на какое-то читерство! Кропотливая работа, которая раньше могла занимать недели, была выполнена за 15 минут.
Такой результат при столь малых усилиях вызывает эйфорию – хочется сразу взять все полученные CSV-файлы и начать обучать на них ML-модели. Но где гарантии, что данные корректны? Что значения конкретного тэга (параметра) действительно находятся в столбце с соответствующим заголовком? Что нет смещений по меткам времени? Что сами значения достоверны – ведь промышленные данные «шумные»: в измерительных каналах возникают помехи, датчики, работающие в агрессивных средах, отказывают и так далее. Если обучить ML‑модели на некорректных данных, в лучшем случае они не будут давать никаких прогнозов. Гораздо хуже – они начнут выдавать ложные предсказания, которые введут в заблуждение эксплуатирующий персонал, и в конечном счёте доверие к системе будет утрачено.
Я изучил полученные файлы и убедился в их корректности. Для верификации я использовал проприетарное ПО HistoryView от StripchartOPC LLC – оно умеет открывать бинарные архивы TT4000, но в демонстрационном режиме работает лишь 20 минут после запуска и не позволяет экспортировать исторические данные. Впрочем, для проверки результатов этого функционала хватило: я сравнил выборочные последовательности значений некоторых параметров из полученных CSV‑файлов с тем, что показывает HistoryView, – данные оказались идентичными (см. рис. 3).

К моему большому удивлению, попытка решить задачу в лоб оказалась успешной. В отдельном диалоге я спросил у Алисы про структуру файла, приложив к промпту все тот же бинарный файл архивов (с расширением «.txt»), а также указав ссылку на предыдущий диалог, где она сгенерировала скрипт для парсинга. И через 5 итераций рассуждений я получил содержательный ответ, фрагмент которого представлен на рис. 4.

Даже если бы Алиса не смогла сгенерировать рабочий скрипт парсинга бинарных архивов, один этот ответ существенно помог бы в реверс-инжиниринге.
Поставленная цель достигнута, но становится интересно, а что могут другие ИИ-сервисы, такие как DeepSeek и Qwen.
Второй заход: DeepSeek выходит на арену
Для DeepSeek я подготовил тот же промпт, что и для Алисы с GigaChat, и приложил бинарный файл архива с его оригинальным расширением «.log». Хотя режим «DeepThink» был включён сразу, на размышления DeepSeek потратил заметно меньше времени, чем Алиса.
В ответе DeepSeek привёл полный текст сгенерированного скрипта и указал, что «Скрипт не гарантирует корректную работу на всех файлах TT4000, но может служить отправной точкой». Также ответ содержал пояснения с явно ошибочными утверждениями (см. рис. 5).

Во-первых, DeepSeek заявил, что в файле отсутствует секция исторических данных, хотя она там заведомо есть: её обнаружила Алиса, и в HistoryView исторические данные для этого файла отображаются корректно. Во-вторых, он неверно определил формат временных меток, посчитав их UnixTime (double), тогда как на самом деле это Delphi TDateTime – именно это указала Алиса в одном из своих ответов (см. рис. 2). Проверка подтвердила: во всех метках времени результирующего файла, полученного скриптом Алисы, значения полностью соответствовали исходным из бинарного архива (см. рис. 3).
Метка времени в формате TDateTime в Delphi – это переменная типа double, которая состоит из 8 байт, и представляет число с плавающей точкой двойной точности, где целая часть соответствует количеству дней, прошедших с 01.01.1899, а дробная – времени суток как доля от 24 часов. Для своего времени (начало 1990-х) это элегантное решение: дата и время хранятся одним числом. Однако сегодня куда шире распространены целочисленные представления времени (тики, секунды, наносекунды) с явным указанием часового пояса – например, UnixTime (long). Реже UnixTime хранят и как double – именно такой вариант DeepSeek ошибочно принял за используемый в бинарном файле архивов. Но даже UnixTime (double) существенно отличается от TDateTime:
в любом варианте UnixTime (long, double) нулевое значение соответствует дате 1 января 1970 года и времени 0:00:00.000, тогда как в TDateTime нулевое значение соответствует дате 1 января 1899 года и времени 0:00:00.000 (разница – 71 год);
в UnixTime дробная часть кодирует конкретную единицу - секунды, миллисекунды, наносекунды и т.д. (единица должна быть явно определена), а в TDateTime дробная часть – это время суток как доля от 24 часов.
Скорее всего, именно из-за неверного предположения о формате временных меток DeepSeek и посчитал, что секции исторических данных в файле нет: он просто не нашёл ни одной байтовой последовательности, соответствующей текущему диапазону дат в формате UnixTime (double).
Я запустил скрипт, который сгенерировал DeepSeek; в отличие от первого скрипта Алисы, этот выполнился без ошибок, но в выводе, помимо прочего, было указано, что «Аналоговые теги не найдены. Невозможно извлечь исторические значения.». У Алисы тоже не с первого раза все получилось, поэтому в следующий промпт я поместил вывод сгенерированного скрипта и указал, что файл наверняка содержит исторические данные и необходимо проанализировать его заново.
На этот раз DeepSeek размышлял дольше. В ответе я получил код скрипта, пояснение улучшений и последовательность дальнейших действий, если исторические данные не найдутся (см. рис. 6).

В пояснениях среди прочего было указано:
что улучшен поиск временных меток – ищутся 8-байтовые double (UnixTime) в диапазоне 2025-2026 гг;
предусмотрен диагностический вывод.
Что касается меток времени, это снова неверное направление: хотя в последовательности дальнейших действий (рис. 6) DeepSeek всё же допускает, что метки могут храниться не как UnixTime (double), и предлагает в случае неудачи проверить их формат.
Запустив скрипт, я получил вывод с отладочной информацией и сообщением о том, что временные метки не найдены. К этому моменту DeepSeek уже проиграл Алисе, так как за два промпта не решил задачу.
Тот факт, что в «дальнейших действиях» DeepSeek явно просит приложить вывод работы скрипта, вероятно, говорит о том, что у самого чат-бота нет среды исполнения для отладки своих скриптов. Возможно, именно поэтому DeepSeek может потребоваться больше промптов, чтобы добиться того же результата, что и Алисе.
Как и в прошлый раз, я включил в новый промпт вывод скрипта – уже с диагностической информацией. После недолгого рассуждения DeepSeek выдал ответ, в котором уже не сомневался в ошибочности своего определения формата меток времени. Однако на этот раз вместе с ответом был приложен код исключительно диагностического скрипта, вывод которого предлагалось добавить в следующий промпт – это уже прямо говорит о том, что у DeepSeek нет доступа к среде исполнения для отладки собственного кода.
Далее в ходе диалога DeepSeek последовательно сгенерировал три диагностических скрипта, вывод каждого из них я передавал в очередном промпте. В итоге был получен финальный скрипт, но после его запуска нужный мне результат я так и не увидел. К сожалению, продолжить работу в начатом диалоге не удалось: появилось сообщение о превышении ограничения по продолжительности («Length limit reached. Please start a new chat.»). Сам диалог с DeepSeek доступен по ссылке: https://chat.deepseek.com/share/3urq5gihzkt877k4w2.
Можно, конечно, открыть новый диалог, вставить в промпт ссылку на предыдущий и продолжить, но в успех верится с трудом: во всех предыдущих итерациях DeepSeek топтался на одном месте с метками времени, заключив, что эти метки в данных вообще отсутствуют – время вычисляется как начальный момент, взятый из имени файла, и 10 секундные дельты, но это неверное утверждение.
Челлендж для Qwen: сможет ли он?
Чтобы прикрепить бинарный файл архива к промпту для Qwen пришлось прибегнуть к той же хитрости, что и с Алисой, – переименовать расширение в «.txt». Диалог был запущен на модели Qwen-3.8-MAX в режиме «Размышление». Размышлял Qwen значительно дольше всех остальных – целых 135 итераций, фрагмент ответа приведен на рис. 7.

Скрипт отработал без ошибок, однако сумел распознать лишь 59 значений параметров для пяти меток времени:
07.08.2000 22:37;
16.04.2004 15:47;
04.01.2012 12:03;
13.10.2018 9:54;
04.10.2025 6:35.
Такой результат, конечно же, некорректен, указываю это в новом промпте и прилагаю вывод скрипта. И снова крайне длительное рассуждение из 103 итераций, результатом которого стал код нового скрипта-конвертера. При этом в ответе Qwen указал, что, если достоверные встроенные временные метки не будут найдены, время будет сформировано от имени файла с шагом 10 секунд – то, к чему и пришёл в итоге DeepSeek.
После запуска скрипт работал довольно долго, а по завершении выдал CSV-файл подозрительно большого размера – 8,5Mb, хотя размер исходного бинарного – 2,9Mb, а размер аналогичного CSV-файла полученного с помощью скрипта Алисы – 3,1Mb.
После открытия файла стало сразу очевидно, что данные некорректны: несмотря на то что метки времени в первом столбце соответствуют диапазону времени и дискретности, значения самих параметров неестественны (см. Рис. 8):
значения большинства параметров лежат в диапазоне от −9,(9) до 9,(9), чего не может быть, поскольку у разных параметров разные диапазоны значений;
значения одного параметра в соседних временных срезах меняются скачкообразно;
отдельные значения параметров явно выходили за допустимые диапазоны (в промышленности избегают использования величин свыше ста тысяч — они неудобны для восприятия, для работы с большими значениями используют кратные единицы измерения: кило-, мега-, гига‑ и др).

Диалог с Qwen доступен по ссылке: https://chat.qwen.ai/s/28678b58-681e-4e9d-9740-103d4a311944?fev=0.3.12.
Как и DeepSeek, Qwen не справился с задачей: оба сервиса споткнулись об одну и ту же проблему – неверное определение формата времени в бинарном файле архива.
Битва за второе место: DeepSeek или Qwen
Безусловный лидер – Алиса: ей хватило всего двух промптов, чтобы решить задачу; абсолютный аутсайдер – GigaChat: он не смог даже прочитать файл для разбора, а значит, не провёл никакого анализа. DeepSeek и Qwen приложили заметные усилия: первый генерировал диагностические скрипты, второй суммарно отработал 238 итераций рассуждений (на это ушло порядка 25-30 минут), но оба не достигли необходимого результата.
Чтобы понять, кто лучше – DeepSeek или Qwen, я открыл в каждом сервисе новый диалог и повторил самый первый промпт, добавив в него подсказку о том, что метки времени хранятся в формате TDateTime, и указав структуру файла из ответа Алисы (см. рис. 4).
И снова Qwen погрузился в пучину рассуждений – на этот раз целых 100 итераций, а DeepSeek сфокусировался на диагностике, успев за это время сгенерировать и проанализировать вывод двух скриптов-конвертеров и трех диагностических скриптов.
В итоге DeepSeek создал шесть диагностических скриптов и проанализировал их вывод, а также три скрипта‑конвертера (два в начале диалога, третий в конце), однако результата так и не добился: тэги найти не удалось. Диалог с подсказкой с DeepSeek доступен по ссылке: https://chat.deepseek.com/share/zku4pzd2cj5ns21f9g.
Qwen оказался скромнее по количеству артефактов: всего два скрипта‑конвертера. Первый упал с ошибкой, вывод которой я передал в следующем промпте; второй отработал без ошибок и сообщил, что нашёл 362 аналоговых тэга (фактически их 459) и лишь одно историческое значение (см. рис. 9).

Дальше я решил просто не продолжать. Диалог с подсказкой с Qwen доступен по ссылке: https://chat.qwen.ai/s/aaf9dccf-41b7-46f1-bf43-f96dbfb089b9?fev=0.3.12.
Хотя ни Qwen, ни DeepSeek не достигли поставленной цели, Qwen всё же сумел корректно распознать имена аналоговых тэгов – пусть и не все. А это уже серьёзная помощь в реверс‑инжиниринге. Поэтому Qwen занимает второе место, а DeepSeek третье.
Вывод
Эксперимент показал: генеративный ИИ уже сегодня способен решать задачи реверс‑инжиниринга закрытых промышленных форматов, но сервисы при этом заметно различаются по возможностям.
Алиса оказалась безоговорочным лидером – прежде всего за счёт доступа к среде исполнения кода. Возможность самой сгенерировать скрипт, запустить его на приложенном файле и увидеть реальный результат позволила ей за два промпта сделать то, что другие сервисы не смогли сделать и за десять. Не менее ценным оказалось подробное описание структуры бинарного файла, которое даже без рабочего скрипта существенно упростило бы дальнейший реверс‑инжиниринг.
DeepSeek и Qwen столкнулись с одной и той же проблемой – неверным определением формата временных меток: вместо Delphi TDateTime оба приняли его за UnixTime (double). Из‑за одной неверной гипотезы о структуре файла вся последующая работа ушла не туда – наглядная иллюстрация того, как критична в реверс‑инжиниринге исходная модель данных. При этом Qwen всё же продемонстрировал полезный побочный результат – корректное распознавание имён аналоговых тэгов, а упорство в диагностике DeepSeek так и не увенчалось успехом.
GigaChat в этом сравнении выпал из гонки на старте: не сумев принять бинарное вложение, он лишь сымитировал решение заглушками вместо реальной логики парсинга.
Доступ к среде исполнения – ключевое преимущество. Сервис, который может сам отладить свой код на ваших данных, кратно сокращает число итераций диалога.
Результат обязательно должен верифицироваться. Даже идеально отработавший скрипт – лишь гипотеза, пока данные не сверены с независимым источником; некорректные данные опаснее их отсутствия, ведь на них обучаются ML‑модели, влияющие на решения эксплуатирующего персонала.
Генеративный ИИ – усилитель, а не замена эксперта. Реверс‑инжиниринг, который раньше занимал недели, может быть выполнен за 15 минут, но направить анализ в правильную сторону и оценить корректность результата может только экспертиза живого специалиста.
Теперь, отработав методику на одной системе, мы планируем применить её к другим закрытым промышленным форматам.
Все скрипты, полученные в ходе этого исследования, доступны в публичном репозитории https://gitverse.ru/luntsev/TT4000-to-CSV.
P.S.
Ссылки на диалоги имеют ограниченный срок действия (во всяком случае у Алисы), я буду стараться их обновлять, но могу проморгать. Если Вы увидите что ссылка "протухла", но Вам хочется посмотреть диалог - напишите мне в личку - я поправлю.
KioskNews shows a cleaned-up reading view extracted from the publisher’s page — the original always lives on their site, not ours.