Пишем упаковщик по шагам. Шаг 11. Интерфейс командной строки. Финальная версия.

Предыдущий шаг здесь.

Пишем упаковщик по шагам. Шаг 11. Интерфейс командной строки. Финальная версия.

Появилась новая версия библиотеки для работы с PE-файлами (0.1.9). Никакие баги там поправлены не были, был добавлен функционал, который упаковщик не использует, так что ваше дело, перекачивать ее или нет :)

В этом шаге мы запилим нашему упаковщику хороший интерфейс командной строки. Я возьму вариант из старого упаковщика и модифицирую его.

Сперва нам потребуется собранная библиотека Boost. Если вы разбирали предыдущие шаги, то она уже должна у вас быть. Если вы ее еще не собрали, то поясню, как это делается. Например, вы распаковали архив с библиотекой в директорию C:\boost. Заходим в эту директорию и запускаем файл bootstrap.bat. Через какое-то время в той же директории появится файл bjam.exe. Запустим консоль (cmd) и перейдем в директорию C:\boost с помощью команды cd. Наберем команду

bjam variant=debug link=static threading=multi runtime-link=static

и подождем, пока соберется debug-вариант со статической линковкой, а затем наберем

bjam variant=release link=static threading=multi runtime-link=static

и соберем аналогично release-вариант. Boost собран, и можно переходить к упаковщику (проект simple_pe_packer). В файл main.cpp добавим два include:

#include <boost/program_options.hpp>#include <boost/timer.hpp>

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

//Говорим пользователю, как использовать наш упаковщик//На текущем шаге никаких опций упаковки не будет, просто//необходимо будет запускать упаковщик, передав через командную строку//имя файла, который мы хотим упаковатьif(argc !=2){
    std::cout<<"Usage: simple_pe_packer.exe PE_FILE"<< std::endl;return0;}

на такие:

//Чтобы не писать всегда полное имя неймспейсаnamespace po = boost::program_options;
 
  //Таймер будет считать, сколько времени//ушло на упаковку файла
  boost::timer pack_timer;
 
  //Принудительная упаковка - будет упакован даже//потенциально некорректный файлbool force_mode =false;//Перепаковывать ли ресурсыbool repack_resources;//Перепаковывать ли директорию конфигурации загрузкиbool rebuild_load_config;//Обрезать ли DOS-заголовокbool strip_dos_headers;//Файловое выравнивание после упаковкиunsignedlong file_alignment;
 
  //Путь к исходному файлу
  std::string input_file_name;//Путь для упакованного файла
  std::string output_file_name;
 
  //Создаем описание опций
  po::options_description visible_options("DXPack Packer 1.0\nCommand Line Options");
 
  try{//Создаем список допустимых опций//Добавляем для них дефолтовые значения (не для всех)
    po::options_description cmdline;
 
    //out-file,o - значит, что имя опции "--out-file"//и короткий ее псевдоним "-o"
    visible_options.add_options()("out-file,o", po::value<std::string>(&output_file_name), "Output file name")("file-align,a", po::value<unsignedlong>(&file_alignment)->default_value(512), "Packed file alignment")("strip-dos,s", po::value<bool>(&strip_dos_headers)->default_value(true), "Strip DOS headers")("repack-res,r", po::value<bool>(&repack_resources)->default_value(true), "Repack resources")("build-load-config,l", po::value<bool>(&rebuild_load_config)->default_value(true), "Rebuild Load Config directory")("force,f", "Force packing of possibly incorrect binaries");
 
    cmdline.add(visible_options);//Скрытая опция - имя файла для упаковки
    cmdline.add_options()("image", po::value<std::string>(&input_file_name), "PE image to pack");    
 
    //Безымянная (имя файла для упаковки должно стоять на первой позиции)
    po::positional_options_description desc_pos;
    desc_pos.add("image", 1);
 
    //Парсим командную строку
    po::variables_map vm;
    po::store(po::command_line_parser(argc, argv).
      options(cmdline).positional(desc_pos).run(), vm);
    po::notify(vm);
 
    //Если не указан путь к исходному файлуif(input_file_name.empty())throw std::runtime_error("No input file specified");
 
    //Если указан режим принудительной упаковкиif(vm.count("force")){
      std::cout<<"Force mode is active!"<< std::endl;
      force_mode =true;}}catch(const std::exception& e){//Если что-то пошло не так - выведем описание опций
    std::cout<< e.what()<< std::endl<< std::endl;
    std::cout<< visible_options << std::endl;system("pause");return0;}

Не буду подробно описывать этот кусок кода, скажу лишь, что здесь мы удобно и просто с помощью библиотеки boost::program_options обрабатываем командную строку нашего упаковщика. Все опции, доступные через командную строку (bool force_mode, bool repack_resources, bool rebuild_load_config, bool strip_dos_headers, unsigned long file_alignmen, std::string input_file_name, std::string output_file_name), я рассовал в исходник упаковщика, и не буду пояснять, что именно изменилось, так как по мелочам поменялись многие части кода. Кроме того, в конце исходника я сделал вывод затраченного на упаковку времени, просчитанного с помощью библиотеки boost::timer. Все изменения вы, как всегда, сможете оценить, скачав полный солюшен упаковщика.

Пожалуй, эту версию упаковщика уже можно назвать законченной. Да, он создает подозрительные импорты и, возможно, имеет еще какие-то недостатки, однако он полностью работоспособен, поддерживает то, чего некоторые другие упаковщики не умеют (например, TLS с коллбэками или перепаковку конфигурации загрузки) и имеет интерфейс командной строки. Поэтому помимо полного исходного кода я выложу и exe-файл упаковщика, вдруг кому-то пригодится. На этом я закрываю цикл статей про написание упаковщика.

Полный солюшен для этого шага: own-packer-step-11
Упаковщик в собранном виде (EXE): DXPack.zip

Также рекомендую почитать

Пишем упаковщик по шагам. Шаг 11. Интерфейс командной строки. Финальная версия. Обсудить на форуме


Источник: http://feedproxy.google.com/~r/kaimi/dev/~3/DG6TdodPu9E/

Читать комменты и комментировать

Добавить комментарий / отзыв



Защитный код
Обновить

Пишем упаковщик по шагам. Шаг 11. Интерфейс командной строки. Финальная версия. | | 2012-10-04 11:31:00 | | Блоги и всяко-разно | | Предыдущий шаг здесь.Появилась новая версия библиотеки для работы с PE-файлами (0.1.9). Никакие баги там поправлены не были, был добавлен функционал, который упаковщик не использует, так что ваше | РэдЛайн, создание сайта, заказать сайт, разработка сайтов, реклама в Интернете, продвижение, маркетинговые исследования, дизайн студия, веб дизайн, раскрутка сайта, создать сайт компании, сделать сайт, создание сайтов, изготовление сайта, обслуживание сайтов, изготовление сайтов, заказать интернет сайт, создать сайт, изготовить сайт, разработка сайта, web студия, создание веб сайта, поддержка сайта, сайт на заказ, сопровождение сайта, дизайн сайта, сайт под ключ, заказ сайта, реклама сайта, хостинг, регистрация доменов, хабаровск, краснодар, москва, комсомольск |
 
Поделиться с друзьями: