diff options
| author | Dennis Brentjes <d.brentjes@gmail.com> | 2016-09-07 20:11:57 +0200 |
|---|---|---|
| committer | Dennis Brentjes <d.brentjes@gmail.com> | 2016-09-07 20:11:57 +0200 |
| commit | 35be012af254617b72ecbe4bca718f3ce96c1fd2 (patch) | |
| tree | 34745f1537181d800e8da5ef19d6dccfe535d952 | |
| parent | a10cf47a9701a4d0be83940a23a8edf9a5ed7b5e (diff) | |
| download | openwar-35be012af254617b72ecbe4bca718f3ce96c1fd2.tar.gz openwar-35be012af254617b72ecbe4bca718f3ce96c1fd2.tar.bz2 openwar-35be012af254617b72ecbe4bca718f3ce96c1fd2.zip | |
cleaned up disasm, and prepared it to handle multiple commands.
| -rw-r--r-- | disasm/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | disasm/disasm.cpp | 127 | ||||
| -rw-r--r-- | disasm/dumpobject.cpp | 47 | ||||
| -rw-r--r-- | disasm/dumpobject.hpp | 6 |
4 files changed, 139 insertions, 42 deletions
diff --git a/disasm/CMakeLists.txt b/disasm/CMakeLists.txt index e9cd3d2..d65f522 100644 --- a/disasm/CMakeLists.txt +++ b/disasm/CMakeLists.txt @@ -1,6 +1,7 @@ add_executable(disasm disasm.cpp + dumpobject.hpp dumpobject.cpp ) find_package(Boost COMPONENTS filesystem program_options system REQUIRED) diff --git a/disasm/disasm.cpp b/disasm/disasm.cpp index 09b9b02..53c74eb 100644 --- a/disasm/disasm.cpp +++ b/disasm/disasm.cpp @@ -1,31 +1,98 @@ -#include "le_file.hpp" - -#include <distorm.h> +#include "dumpobject.hpp" #include <boost/filesystem.hpp> #include <boost/program_options.hpp> #include <iostream> -#include <istream> -#include <iomanip> +#include <fstream> + +int parse_dumpobject_options(std::vector<std::string> 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; +} int main(int argc, char* argv[]) { - boost::program_options::options_description description; + boost::program_options::options_description global("Global options"); + + global.add_options() + ("help,h", "Show this help message") + ("command", boost::program_options::value<std::string>(), "command to execute") + ("subargs", boost::program_options::value<std::vector<std::string> >(), "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::string>(); + } + + std::vector<std::string> 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::basename(argv[0]); + + 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 { + print_top_level_help(program_name); + return 0; + } +} + +int parse_dumpobject_options(std::vector<std::string> arguments) { + boost::program_options::options_description description; description.add_options() ("help,h", "produces this help message") - ("exe,e", boost::program_options::value<std::string>(), "The LE executable to parse the header for.") + ("exe,e", boost::program_options::value<std::string>()->required(), "The LE executable to parse the header for.") + ("object_id,o", boost::program_options::value<uint32_t>()->required(), "The object number to disassemble") ; boost::program_options::variables_map vm; - boost::program_options::store(boost::program_options::parse_command_line(argc, argv, description), vm); - boost::program_options::notify(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(vm.count("exe")) { std::string exe_file = vm["exe"].as<std::string>(); @@ -45,42 +112,18 @@ int main(int argc, char* argv[]) { std::cerr << description << std::endl; return -1; } - } else { - std::cerr << "Option \"exe_file\" is required"; - std::cerr << std::endl; - std::cerr << description << std::endl; - return -1; } - std::ifstream file(file_path.string()); - auto x = le::parse_file(file); - file.close(); - - std::basic_ifstream<char> code_file(file_path.string()); - std::vector<uint8_t> code(std::istreambuf_iterator<char>(code_file), {}); - - std::vector<_DecodedInst> instructions; - instructions.resize(100000); - unsigned int read_inst; - - auto eip_object = x.object_table.entries[x.le_header.EIP_object]; - auto index = eip_object.page_table_index; - auto page = x.object_page_table.entries[index]; - - binparse::Offset32 offset = x.le_header.data_page_offset; - - auto result = distorm_decode64(0x00010000, code.data() + offset, x.object_table.entries[1].nr_page_table_entries * x.le_header.page_size, Decode32Bits, instructions.data(), instructions.size(), &read_inst); - - instructions.resize(read_inst); - instructions.shrink_to_fit(); - - if(result) { - + uint32_t object_id; + if(vm.count("object_id")) { + object_id = vm["object_id"].as<uint32_t>(); + if(object_id == 0) { + std::cerr << "object id cannot be 0" << std::endl; + return -1; + } } - for(auto&& inst : instructions) { - std::cout << std::hex << std::setw(8) << std::setfill('0') << inst.offset << ":\t" << inst.mnemonic.p << " " << inst.operands.p << std::endl; - } + std::ifstream file_stream(file_path.string()); - return 0; + dump_object(file_stream, object_id); } diff --git a/disasm/dumpobject.cpp b/disasm/dumpobject.cpp new file mode 100644 index 0000000..85fbf43 --- /dev/null +++ b/disasm/dumpobject.cpp @@ -0,0 +1,47 @@ +#include "dumpobject.hpp" + +#include "le_file.hpp" + +#include <distorm.h> + +#include <iomanip> + +void dump_object(std::ifstream& ifs, uint32_t object_id) +{ + auto x = le::parse_file(ifs); + + ifs.clear(); + ifs.seekg(0, std::ios::beg); + + std::vector<uint8_t> code(std::istreambuf_iterator<char>(ifs), {}); + + std::vector<_DecodedInst> instructions; + instructions.resize(100000); + unsigned int read_inst; + + auto object = x.object_table.entries[object_id]; + auto index = object.page_table_index; + + binparse::Offset32 offset = x.le_header.data_page_offset; + + auto result = distorm_decode64( + object.reloc_base_address, + code.data() + offset + (index - 1) * x.le_header.page_size, + x.object_table.entries[1].nr_page_table_entries * x.le_header.page_size, + Decode32Bits, + instructions.data(), + instructions.size(), + &read_inst + ); + + instructions.resize(read_inst); + instructions.shrink_to_fit(); + + if(result) { + + } + + for(auto&& inst : instructions) { + std::cout << std::hex << std::setw(8) << std::setfill('0') << inst.offset << ":\t" << inst.mnemonic.p << " " << inst.operands.p << std::endl; + } +} diff --git a/disasm/dumpobject.hpp b/disasm/dumpobject.hpp new file mode 100644 index 0000000..b8042b1 --- /dev/null +++ b/disasm/dumpobject.hpp @@ -0,0 +1,6 @@ +#pragma once + +#include <fstream> +#include <cstdint> + +void dump_object(std::ifstream& ifs, uint32_t object_id);
\ No newline at end of file |
