summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDennis Brentjes <d.brentjes@gmail.com>2016-09-07 20:11:57 +0200
committerDennis Brentjes <d.brentjes@gmail.com>2016-09-07 20:11:57 +0200
commit35be012af254617b72ecbe4bca718f3ce96c1fd2 (patch)
tree34745f1537181d800e8da5ef19d6dccfe535d952
parenta10cf47a9701a4d0be83940a23a8edf9a5ed7b5e (diff)
downloadopenwar-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.txt1
-rw-r--r--disasm/disasm.cpp127
-rw-r--r--disasm/dumpobject.cpp47
-rw-r--r--disasm/dumpobject.hpp6
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