#include "dumpobject.hpp" #include "extractfunction.hpp" #include #include #include #include int parse_dumpobject_options(std::vector arguments); int parse_extractfunction_options(std::vector arguments); void print_top_level_help(std::string program_name) { std::cout << "Usage " << program_name << ":" << std::endl; std::cout << std::endl; std::cout << "\t" << program_name << " " << "help" << std::endl; std::cout << "\t" << program_name << " " << "dumpobject" << std::endl; std::cout << "\t" << program_name << " " << "extractfunction" << std::endl; } int main(int argc, char* argv[]) { boost::program_options::options_description global("Global options"); global.add_options() ("help,h", "Show this help message") ("command", boost::program_options::value(), "command to execute") ("subargs", boost::program_options::value >(), "Arguments for command"); boost::program_options::positional_options_description pos; pos.add("command", 1). add("subargs", -1); boost::program_options::variables_map vm; boost::program_options::parsed_options parsed = boost::program_options::command_line_parser(argc, argv). options(global). positional(pos). allow_unregistered(). run(); boost::program_options::store(parsed, vm); boost::program_options::notify(vm); std::string command; if(vm.count("command")) { command = vm["command"].as(); } std::vector options; if(vm.count("subargs")) { options = boost::program_options::collect_unrecognized(parsed.options, boost::program_options::include_positional); options.erase(options.begin()); } std::string program_name = boost::filesystem::path(argv[0]).stem().string(); if(command == "help" || vm.count("help")) { if(!vm.count("command")) { print_top_level_help(program_name); return 0; } else { options.push_back("--help"); } } if(command == "dumpobject") { return parse_dumpobject_options(options); } else if (command == "extractfunction") { return parse_extractfunction_options(options); } else { print_top_level_help(program_name); return 0; } } int parse_exe_file_option(boost::program_options::variables_map const& vm, boost::filesystem::path& file_path) { if(vm.count("exe")) { std::string exe_file = vm["exe"].as(); if(boost::filesystem::exists(exe_file)) { if(!boost::filesystem::is_directory(exe_file)) { file_path = exe_file; } else { std::cerr << exe_file << " is a folder" << std::endl; return -1; } } else { std::cerr << "file: " << exe_file << " does not exist" << std::endl; return -1; } } else { std::cerr << "exe_file option is required" << std::endl; return -1; } return 0; } int parse_object_id_option(boost::program_options::variables_map const& vm, uint32_t& object_id) { if(vm.count("object_id")) { object_id = vm["object_id"].as(); if(object_id == 0) { std::cerr << "object id cannot be 0" << std::endl; return -1; } } else { std::cerr << "object_id option is required" << std::endl; return -1; } return 0; } int parse_function_offset_option(boost::program_options::variables_map const& vm, uint32_t& function_offset) { if(vm.count("function_offset")) { std::string str = vm["function_offset"].as(); function_offset = std::stoul(str, nullptr, 16); } else { std::cerr << "function_offset option is required" << std::endl; return -1; } return 0; } int parse_dumpobject_options(std::vector arguments) { boost::program_options::options_description description; description.add_options() ("help,h", "produces this help message") ("exe,e", boost::program_options::value()->required(), "The LE executable to parse the header for.") ("object_id,o", boost::program_options::value()->required(), "The object number to disassemble") ; boost::program_options::variables_map vm; boost::program_options::store(boost::program_options::command_line_parser(arguments).options(description).run(), vm); if(vm.count("help")) { std::cout << description << std::endl; return 0; } try { boost::program_options::notify(vm); } catch(boost::program_options::required_option const& e) { std::cout << e.what() << std::endl; return -1; } boost::filesystem::path file_path; if(int ret = parse_exe_file_option(vm, file_path)) { return ret; } binparse::Value32 object_id; if(int ret =parse_object_id_option(vm, object_id)) { return ret; } dump_object(file_path.string(), object_id); return 0; } int parse_extractfunction_options(std::vector arguments) { boost::program_options::options_description description; description.add_options() ("help,h", "produces this help message") ("exe,e", boost::program_options::value()->required(), "The LE executable to parse the header for.") ("object_id,o", boost::program_options::value()->required(), "The object number to disassemble") ("function_offset,f", boost::program_options::value()->required(), "The function start offset in hexadecimal notation") ; boost::program_options::variables_map vm; boost::program_options::store(boost::program_options::command_line_parser(arguments).options(description).run(), vm); if(vm.count("help")) { std::cout << description << std::endl; return 0; } try { boost::program_options::notify(vm); } catch(boost::program_options::required_option const& e) { std::cout << e.what() << std::endl; return -1; } boost::filesystem::path file_path; if(int ret = parse_exe_file_option(vm, file_path)) { return ret; } binparse::Value32 object_id; if(int ret =parse_object_id_option(vm, object_id)) { return ret; } binparse::Offset32 function_offset; if(int ret = parse_function_offset_option(vm, function_offset)) { return ret; } extract_function(file_path.string(), object_id, function_offset); return 0; }