Previous step is here.
At this step we will develop nice command line interface for our packer.
At first we need compiled Boost library. If you studied previous steps, you should have it already. If you have not built it yet, I will explain how to do that. For example, you unpacked the library archive to C:\boost directory. Open this directory and run bootstrap.bat file. bjam.exe file will appear in this directory in some time. Run the console (cmd) and go to C:\boost directory with cd command. Type the command
bjam variant=debug link=static threading=multi runtime-link=static
wait for debug version with static linking to be built, and then type
bjam variant=release link=static threading=multi runtime-link=static
to build the release version. Boost is built and we can turn to the packer (simple_pe_packer project). Add two includes to main.cpp:
First one is necessary to implement command line interface, the second one is used to count file packing time. Replace lines
//Tell the user how to use our packer
//No packing options at this step
//You just need to pass a name of the file to pack
//via command line
if(argc != 2)
std::cout << "Usage: simple_pe_packer.exe PE_FILE" << std::endl;
to these ones:
//To use short namespace alias
namespace po = boost::program_options;
//Timer counts the time
//required for packing
//Forced packing - even potentially incorrect file
//will be packed
bool force_mode = false;
//Whether resources should be packed
//Whether loading configuration directory should be packed
//Whether DOS header should be stripped
//File alignment after packing
unsigned long file_alignment;
//Path to source file
//Path to packed file
//Create options description
po::options_description visible_options("DXPack Packer 1.0\nCommand Line Options");
//Create allowed options list
//Add default values (not for all of them)
//out-file,o - means that option name is "--out-file"
//and its short alias is "-o"
("out-file,o", po::value<std::string>(&output_file_name), "Output file name")
("file-align,a", po::value<unsigned long>(&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")
//Hidden option - name of the file to pack
("image", po::value<std::string>(&input_file_name), "PE image to pack")
//Unnamed (name of the file to pack should go first)
//Parse the command line
//If the path to source file is not specified
throw std::runtime_error("No input file specified");
//If forced packing mode is specified
std::cout << "Force mode is active!" << std::endl;
force_mode = true;
catch(const std::exception& e)
//If something went wrong - output options description
std::cout << e.what() << std::endl << std::endl;
std::cout << visible_options << std::endl;
I will not describe the piece of code in detail, just say that we here process our packer command line easily and conveniently using boost::program_options library. I put all options available via command line (bool force_mode, bool repack_resources, bool rebuild_load_config, bool strip_dos_headers, unsigned long file_alignment, std::string input_file_name, std::string output_file_name) to the packer source code, and I will not explain what exactly has changed, because many parts of the code were slightly modified. Besides that, at the end of the source code I made output of the elapsed packing time, which was counted with boost::timer library. You can view all changes as always by downloading the full packer solution.
This version of the packer could be perhaps considered completed. Yes, it creates suspicious imports and probably has other issues, but it is fully operable, it supports things that other packers can’t do (for example, TLS with callbacks or loading configuration repacking) and it has command line interface. So, besides the source code I will share the packer EXE file, in case it will be useful for someone.
UPD: New version with fixed bugs is here.