Извлечение текстов модулей из внешней обработки 1С

Программирование - Практика программирования

Лень в очередной раз сподвигла меня на доработку существующего инструментария. В публикации опишу свой опыт парсинга бинарного файла с данными обычной формы (выгруженного с помощью функционала платформы 1С "Выгрузить в файлы").

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

 

 

Для внешней обработки формируется следующая структура каталогов.

Текст модуля обработки выгружается в файл «\Ext\ObjectModule.bsl«.

 

Тексты модулей управляемых форм — в файлы с расширением «.bsl«: «\Forms\НазваниеФормы\Ext\Form\Module.bsl«.

 

А вот обычные (не управляемые) формы выгружаются в следующие двоичные файлы: «\Forms\НазваниеФормы\Ext\Form.bin«.

 

Пришлось повозиться с парсингом этих бинарных файлов. Зато опробовал новую (для меня) возможность платформы работы с бинарными файлами

 

Файл с данными обычной формы представляет из себя бинарный файл с блоками данных.

 

Блоки разделены секциями, состоящими из 3-х 16-ричных чисел, оканчивающихся числом 7fffffff.

 

В процессе анализа некоторого количества обработок обнаружилось 2 варианта расположения блоков.

 

Вариант 1

 

Вариант 2

Первые 3 блока в моей выборке обработок всегда начинались с одних и тех же адресов :  00000012(hex) или 18(dec), 00000231(hex) или 561(dec), 00000270(hex) или 624(dec).

 

Я остановился на следующем алгоритме определения необходимой секции, содержащей код модуля формы.

Данный алгоритм был получен империческим путем и не может слепо использоваться в продуктивной разработке!

Если Вы владеете информацией по данному формату, буду рад увидеть Ваш комментарий к данной публикации :)

Итак…

Если последнее число 3-го блока = 7fffffff, считаю, что это первый вариант расположения блоков. В остальных случаях — второй вариант.

 

Для первого варианта

Начало блока с текстом модуля формы совпадает с началом 4-го блока (необходимо только пропустить секцию с 3-мя цифрами), т.е. это в 10-чной системе счисления: 691(начало 4-го блока) + 8*3(3 16-чных числа)  + 2(пробелы между числами).

Т.е. считаю, что это всегда 717 (dec)

Адрес окончания текстового блока — второе число секции из 3-х чисел + смещение на константу 000002D2(hex) или 722(dec).

Для случая, приведенного на скриншоте (см. выше) получаем:

551(dec) + 722(dec),

где 551(dec) это 00000227(hex)

 

Для второго варианта

Анализируем секцию из 3-х чисел блока 3.

Адрес начала блока с кодом 1С — второе число (к этому числу необходимо еще добавить смещение на константу 722(dec)  и размер секции из 3-х чисел  26(dec)).

Для случая, приведенного на скриншоте (см. выше) получаем:

127773(dec) + 722(dec) + 26(dec),

где 127773(dec) — это 0001F31D(hex)

Адрес окончания блока с кодом 1С — третье число.

Для случая, приведенного на скриншоте (см. выше) получаем:

471603(dec),

где 471603(dec) — это 00073233(hex)

 

Для чтения из двоичного файла написал процедуру:

Функция ПрочитатьИзФайла(ИмяФайла, Знач Адрес, Знач Размер)	

	МаксимальныйРазмерБуфера = 5000;	

	Результат = "";
	
	Файл = Новый ЧтениеДанных(ИмяФайла);
	Файл.Пропустить(Адрес);			
	Пока Размер > 0 Цикл
		
		ТекущийРазмер = Мин(Размер, МаксимальныйРазмерБуфера);

		РезультатЧтения = Файл.Прочитать(ТекущийРазмер);
		ЧтениеЧасти     = Новый ЧтениеТекста(РезультатЧтения.ОткрытьПотокДляЧтения(), "utf-8");
		
		Результат = Результат + ЧтениеЧасти.Прочитать();
		
		ЧтениеЧасти.Закрыть();
		
		Адрес = Адрес + ТекущийРазмер;
		Размер = Размер - ТекущийРазмер;
		
	КонецЦикла;
	Файл.Закрыть();		
		
	Возврат Результат;
	
КонецФункции // ПрочитатьИзФайла()

 

Ну в заключении, чтобы не «бегать» в конфигуратор для выгрузки обработки в файлы, добавил выгрузку с помощью пакетного запуска конфигуратора 1С с выводом на экран результата выполнения данной выгрузки:

 

Ссылка на обработку на infostart и на github

Cсылки к публикации:

infostart.ru/public/806807/

http://v8.1c.ru/o7/201602bin/index.htm

https://github.com/evgenylavelin/analysProcFunc

https://its.1c.ru/db/v8312doc/bookmark/dev/TI000001825

https://wonderland.v8.1c.ru/blog/razvitie-vygruzki-zagruzki-konfiguratsii-v-iz-xml/?sphrase_id=34313

См. также

Комментарии
2. Андрей Овсянкин (Evil Beaver) 4985 29.04.18 11:37 Сейчас в теме
Кажется вы изобрели изобретенное, но все равно, уважуха
pbazeliuk; JohnyDeath; baton_pk; zenechka; binex; +5 Ответить
3. Виктория Дорохина (vikad) 79 29.04.18 11:42 Сейчас в теме
4. Андрей Овсянкин (Evil Beaver) 4985 29.04.18 11:49 Сейчас в теме
5. Евгений - (zenechka) 431 29.04.18 12:27 Сейчас в теме
(2) Андрей, спасибо За Вашу труд.
Я "наподал" на него ранее, но, без практического примера в меня он "не зашел".
В частности, в нем не описано (либо я это проглядел) смещение на 722, которое участвует в определении адреса границы блока. Теперь я обязуюсь перечитать более внимательно Вашу публикацию, скорее всего обнаружу для себя то, на что не обратил внимание раньше.
К тому же, азарт самому разобрать эту головоломку сыграл свою роль в рождении данной публикации.
Мне кажется, эта статья плюс практический пример демонстрирующий реализацию описанного алгоритма не должны навредить читателю.
6. Сергѣй Батанов (baton_pk) 338 29.04.18 22:47 Сейчас в теме
(5)
В частности, в нем не описано (либо я это проглядел) смещение на 722

Потому что нет "смещения на 722", есть таблица адресов, записанная первым файлом в контейнере - в этой таблице где-то написано это "722".

А за практическими примерами сюда: https://github.com/search?utf8=%E2%9C%93&q=v8unpack&type=
kirillkr; JohnyDeath; Evil Beaver; +3 Ответить
7. Андрей Овсянкин (Evil Beaver) 4985 30.04.18 09:45 Сейчас в теме
(5) Труд не мой, это просто компиляция в одном месте накопленного сообществом опыта. Но если уж вы делаете вытаскиватель модулей обычных форм, то сделайте его корректно, по документации иначе он где-нибудь упадет. (см. пояснение про 722 от @baton_pk ниже)
Оставьте свое сообщение