Форум программистов, компьютерный форум, киберфорум
Наши страницы

Batch (CMD/BAT)

Войти
Регистрация
Восстановить пароль
 
Dragokas
Эксперт WindowsАвтор FAQ
16600 / 6985 / 845
Регистрация: 25.12.2011
Сообщений: 10,781
Записей в блоге: 16
#1

Упаковка бинарных ресурсов в батник ("CBI method" by Dragokas) - CMD/BAT

10.08.2014, 17:14. Просмотров 1226. Ответов 0
Метки нет (Все метки)

Cabinet's Batch inline. "CBI method" by Dragokas

Метод предоставляет возможность встраивать бинарную информацию (любые файлы)
в качестве ресурсов BAT-файла, получая на выходе 1 комбинированный файл
с расширением BAT или CMD.
Батник затем сможет распаковать свой ресурс при необходимости его использования.

В статье представлены описание метода и программная реализация.

Описание метода

Оригинальная идея принадлежит человеку с ником: Somebody.

Она звучала так:
Можно сделать cab архив с расширением bat, а в конце - пустую строку и extrac32 /e %0.
extrac32 в винде вроде всегда есть. Побочный эффект - попытка запуска "MSCF"
(заголовок .cab).
Данный способ не подходит для случаев упаковки бинарных ресурсов различного содержания,
т.к. некоторые комбинации символов для формата CMD являются недоспустимым и
приводят к его "падению" прежде, чем BAT-файл начнет исполнение своей части кода
из конца Cabinet архива.

К счастью структура формат CAB предоставляет возможность резервирования произвольного
количества байт (начиная со смещения 0x28) для хранения цифровой подписи.

Эту область мы задействуем под свой нужны, расположив в ней основной код
и команду распаковки.

Техническая часть

Код батника будет содержать команду для распаковки себя же:
Код
@extrac32.exe /E /Y /L "папка, куда распаковуем" "%~f0"
/e - распаковать все
/y - без подтверждения при замене

Структура формата Cabinet архива описана в статье базы знаний: MSKB417343

Она разделена на 4 блока:
  • CFHEADER
  • CFFOLDER
  • CFFILE
  • CFDATA

Описание первого блока:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// Размер | имя параметра | смещене | описание параметра
 
struct CFHEADER
{
  u1  signature[4]  // 0x00 - сигнатура архива "MSCF"
  u4  reserved1     // 0x04 - зарезервировано
  u4  cbCabinet     // 0x08 - размер архива в байтах
  u4  reserved2     // 0x0С - зарезервировано
  u4  coffFiles     // 0x10 - смещение первого вхождения блока CFFILE
  u4  reserved3     // 0x14 - зарезервировано
 
  u1  versionMinor  // 0x18 - версия формата архива (minor)
  u1  versionMajor  // 0x19 - версия формата архива (major)
 
  u2  cFolders      // 0x1A - количество блоков CFFOLDER
  u2  cFiles        // 0x1C - количество блоков CFFILE
  u2  flags         /* 0x1E - флаги наличия или отсутствия зарезервированной областей
                              abReserve[], szCabinetPrev[], szDiskPrev[], szCabinetNext[], szDiskNext[]   */
  u2  setID         // 0x20 - должен быть одинаковый для всех частей составного архива
  u2  iCabinet;     // 0x22 - порядковий номер этого файла в составном архиве
  u2  cbCFHeader;   // 0x24 - (опционально) размер зарезервированной под ЭЦП области архива
 
  u1  cbCFFolder;       // 0x26 - (опционально) размер зарезервированной области каждой папки
  u1  cbCFData;         // 0x27 - (опционально) размер зарезервированной области каждого блока данных
  u1  abReserve[];      // 0x28 - (опционально) область, зарезервированная под ЭЦП (сюда будем записывать батник)
  u1  szCabinetPrev[];  // (опционально) имя предыдущего файла CAB
  u1  szDiskPrev[];     // (опционально) имя предыдущего диска
  u1  szCabinetNext[];  // (опционально) имя следующего файла CAB
  u1  szDiskNext[];     // (опционально) имя следующего диска
};
Чтобы создать скомбинированный файл, сперва нужен сам архив.
Наиболее родной способ - воспользоваться встроенной в систему утилитой makecab.
Синтаксис у нее непростой, поэтому лучше воспользоваться готовой реализацией:

Кликните здесь для просмотра всего текста

Bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
@echo off
SetLocal
:: Имя для CAB-архива
set "CabinetName=test.cab"
:: Путь к папке, которую упаковуем
set src=C:\Users\Alex\Desktop\gardening\gardening
 
chcp 1251 >NUL
For /F "delims=" %%a in ('dir /B /a-d "%src%\*.*"') do echo "%src%\%%a">>"%Temp%\list.txt"
chcp 866 >NUL
 
set .=
set .=%.% /D FolderSizeThreshold=50000000
set .=%.% /D DestinationDir=.
set .=%.% /D MaxDiskSize=0
set .=%.% /D cabinet=on
set .=%.% /D compression=on
set .=%.% /D CabinetDir=\.
set .=%.% /D CabinetNameTemplate="%CabinetName%"
set .=%.% /D CabinetName="%CabinetName%"
set .=%.% /D InfFileName=NUL
set .=%.% /D RptFileName=NUL
set .=%.% /D CompressionMemory=21
set .=%.% /D DiskDirectoryTemplate=.
set .=%.% /D UniqueFiles=Off
set .=%.% /D CompressionType=LZX
 
makecab %.% /V1 /F "%Temp%\list.txt"
 
del /F "%Temp%\list.txt"
pause


Тем не менее, у Microsoft есть и другая утилита из состава Resource Kit
под названием CabArc.

Ввел в YANDEX слово Cabarc и получил "Сфинкс". Круто! M$ отдыхает
Создать архив CAB можно такой простой командой:
Код
cabarc N test.cab *.*
Упакует все файлы в текущей папке в архив test.cab

Чтобы вставить код Batch в такой архив, нам нужно зарезервировать область
соответствующего размера, и здесь Cabarc будет как нельзя кстати.

Описание возможностей Cabarc


Синтаксис:
Код
CABARC [опции] команда cabfile [@список] [файлы] [папка назначения\]
Основных каманды всего три:

L - просмотр
X - разархивировать
N - архивировать

Код
Опции:
  -c   подтверждать операции с файлами
  -o   во время распаковки не запрашивать подтверждения при замене
  -m   алгоритм сжатия [LZX:<15..21>|MSZIP|NONE], (по-умолчанию - MSZIP)
  -p   сохранять пути файлов (абсолютные пути не поддерживаются)
  -P   урезать указанный префикс из файлов при добавлении в архив
  -r   рекурсивно с подкаталогами при добавлени в архив (см. также -p)
  -s   зарезервировать место под цифровую подпись (например, -s 6144 резервирует 6 КБ.)
  -i   Устанавливает ID архива при создании (по-умолчанию - 0)
  -d   установить размер частей (по-умолчанию, размер не определен, т.е. создается единый архив)


Ключ -s позволяет установить произвольный размер зарезервированного под ЭЦП блока
(от 1 до 65535 байт (0xFFFF)).

Теперь смотрим, какой размер у батника, к которому мы хотим добавить ресурс.
Пусть будет 250 байт (0xFA).

Прибавляем 6 байт (ниже узнаете зачем).
250 + 6 = 256 (0x100).

Создаем архив с резервной областью в 256 байт:

Код
cabarc -s 256 N test.cab *.*
Принцип слияния кода батника с архивом такой:

Берем смещение архива 0x28 (блок abReserve[]).
Добавляем туда 2 переноса строки (0x0D, 0x0A, 0x0D, 0x0A) - 4 байта.

Далее вставляем сам код и еще + перенос строки (0x0D, 0x0A) - 2 байта.

4 + 2 = 6 байт, о которых мы говорили выше.

В коде батника должна быть предусмотрена команда распаковки архива из себя
и очистка сообщения о неверной команде (когда батник попытается исполнить хидер CAB-архива):

Код
@cls & @extrac32.exe /E /Y /L .\ "%~f0"
Комбинированный CBI-файл готов.
Нужно переименовать его расширение в CMD.

Правка упакованного батника напрямую

Также можно выделить резервную область путем правки определенных байт CAB-архива:

1. В структуре CFHEADER:

C++
1
2
3
4
  u4  cbCabinet     // 0x08 - размер архива в байтах
  u4  coffFiles     // 0x10 - смещение первого вхождения блока CFFILE
  u2  flags         // 0x1E - флаги наличия или отсутствия зарезервированной областей
  u2  cbCFHeader;   // 0x24 - (опционально) размер зарезервированной под ЭЦП области архива
flags должен содержать константу:
C++
1
#define cfhdrRESERVE_PRESENT    0x0004
cbCFHeader - для архива с флагом = 0 (нет резервных областей) имеет смещение 0x2C.

2. В каждой из структур CFFOLDER:

C++
1
u4  coffCabStart;   // смещение первого вхождения блока CFDATA для этой папки
Программная реализация

В дополнение к статье готовая программа для прикрепления к батнику ресурса из указанных файлов и/или каталогов.
8
Миниатюры
Упаковка бинарных ресурсов в батник ("CBI method" by Dragokas)  
Вложения
Тип файла: zip BAT.Res.Packer.zip (1.29 Мб, 44 просмотров)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
10.08.2014, 17:14
Я подобрал для вас темы с готовыми решениями и ответами на вопрос Упаковка бинарных ресурсов в батник ("CBI method" by Dragokas) (CMD/BAT):

Обсуждение скрипта "Codepage Repair" by Dragokas - CMD/BAT
В данной теме ведётся обсуждение скрипта &quot;Codepage Repair&quot; Ссылка: http://www.cyberforum.ru/post6661782.html . Данное сообщение...

Как "научить" батник делать элементарный анализ интернет-страницы? - CMD/BAT
Хотелось бы знать возможно ли в принципе написать батник, который через определённый промежуток времени выходит на определённую страницу,...

Батник для поиска файла в папке "Temp" и его запуска - CMD/BAT
Здравствуйте, коллеги! Встал вопрос, над который подкипела голова. Задача: В 1С при обновлении курсов валют качается файл bnk.exe,...

Почему не работает батник содержания "cmd"? - CMD/BAT
Друзья! У меня в очень многих папках лежит батник такого содержания, и когда мне нужно я захожу папку, тычу в него и работаю. Но надо же...

Избавиться от сообщений "Файл не найден", "Системе не удается найти указанный путь", "Устройство не готово" - CMD/BAT
Здравствуйте. В батнике присутствует поиск файлов: for %%i in (c d e f g h i j k l m n o p q r s t u v w x y z) do dir /b /s %%i:\lol*.*...

for /f "delims=" %%b in ('dir !DirName! /b /s /a-d') do () жрёт символы "!" и "^" - CMD/BAT
Добрый день, коллеги. День сегодня убил, но так и не понял что делать, может поможете добрым советом. Кусок батничка: @ECHO OFF...

0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
10.08.2014, 17:14
Привет! Вот еще темы с ответами:

Поиск файлов с атрибутом "скрытый" ("hidden") на заданном дисковом томе с целью их дальнейшего удаления - CMD/BAT
Всем здравствуйте!!! Помогите пожалуйста создать батник. Задание: Поиск файлов с атрибутом &quot;скрытый&quot; (&quot;hidden&quot;) на заданном...

"tokens=*" "съедает" одну строчку при обработке вывода результата выполнения команды ping :) - CMD/BAT
Друзья, нашел батничек для пинга узла и вывода инфо в файл, кое что подправил под себя, но остался вопрос такого плана: Если просто...

Установить для пользователя значение "FALSE" параметра "PasswordExpires" командой WMIC - CMD/BAT
wmic useraccount where &quot;name='имя_пользователя' &quot; set passwordexpires=false это строка не работает

Разработать "универсальную" программу, позволяющую "динамически" изменять параметры окружения среды - CMD/BAT
Разработать &quot;универсальную&quot; программу позволяющую пользователю &quot;динамически&quot; (во время работы процедурного файла) изменять параметры...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
1
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru