diff options
| author | Dennis Brentjes <d.brentjes@gmail.com> | 2016-09-16 12:54:20 +0200 |
|---|---|---|
| committer | Dennis Brentjes <d.brentjes@gmail.com> | 2016-09-16 12:54:20 +0200 |
| commit | abd5cfdd4a6c8e9979b2deb3c48304fb3d63a44c (patch) | |
| tree | 582bddd69e1c4c7a68642798b7702f4bf1ca9b4d | |
| parent | 563336ff1a4ed88401bf754ef7762542a4986d12 (diff) | |
| download | openwar-abd5cfdd4a6c8e9979b2deb3c48304fb3d63a44c.tar.gz openwar-abd5cfdd4a6c8e9979b2deb3c48304fb3d63a44c.tar.bz2 openwar-abd5cfdd4a6c8e9979b2deb3c48304fb3d63a44c.zip | |
Added relocation to disasm.
| -rw-r--r-- | disasm/extractfunction.cpp | 24 | ||||
| -rw-r--r-- | disasm/leparseutil.cpp | 66 | ||||
| -rw-r--r-- | disasm/leparseutil.hpp | 5 | ||||
| -rw-r--r-- | le/le_fixup_record_table.cpp | 2 |
4 files changed, 78 insertions, 19 deletions
diff --git a/disasm/extractfunction.cpp b/disasm/extractfunction.cpp index 3fc12e1..f2da04c 100644 --- a/disasm/extractfunction.cpp +++ b/disasm/extractfunction.cpp @@ -30,15 +30,12 @@ void extract_function(std::string file_path, binparse::Value32 object_id, binpar _DecodeType dt = Decode32Bits; unsigned int decodedInstructionsCount = 0; - std::vector<uint8_t> code_buf = read_object(ifs, file, object_id); - - binparse::Offset32 base_reloc_offset = file.object_table.entries[object_id].reloc_base_address; - binparse::Offset32 buffer_offset = binparse::Offset32(function_offset - base_reloc_offset); + std::vector<uint8_t> code_buf = load_binary(file); _CodeInfo ci; - ci.code = code_buf.data() + buffer_offset; - ci.codeLen = code_buf.size() - buffer_offset; - ci.codeOffset = base_reloc_offset + buffer_offset; + ci.code = code_buf.data() + function_offset; + ci.codeLen = code_buf.size() - function_offset; + ci.codeOffset = function_offset; ci.dt = dt; ci.features = DF_RETURN_FC_ONLY | DF_STOP_ON_FLOW_CONTROL; @@ -55,7 +52,6 @@ void extract_function(std::string file_path, binparse::Value32 object_id, binpar switch(META_GET_FC(decinst.meta)) { case FC_CALL: { binparse::Offset32 target = binparse::Offset32(INSTRUCTION_GET_TARGET(&decinst)); - std::cout << binparse::Offset32(ci.codeOffset) << " " << target << std::endl; extract_function(file_path, object_id, target); break; } @@ -99,12 +95,6 @@ void extract_function(std::string file_path, binparse::Value32 object_id, binpar throw std::runtime_error("This should never happen."); } } - /* - _DecodedInst inst; - distorm_format64(&ci, &decinst, &inst); - - std::cout << std::hex << std::setw(8) << std::setfill('0') << inst.offset << ":\t" << inst.mnemonic.p << " " << inst.operands.p << std::endl; - */ if(!done) { auto distance = ci.nextOffset - ci.codeOffset; @@ -119,10 +109,10 @@ void extract_function(std::string file_path, binparse::Value32 object_id, binpar auto end = ci.nextOffset; - ci.code = code_buf.data() + buffer_offset; + ci.code = code_buf.data() + function_offset; ci.nextOffset = 0; - ci.codeLen = code_buf.size() - buffer_offset; - ci.codeOffset = base_reloc_offset + buffer_offset; + ci.codeLen = code_buf.size() - function_offset; + ci.codeOffset = function_offset; ci.dt = dt; ci.features = DF_NONE; diff --git a/disasm/leparseutil.cpp b/disasm/leparseutil.cpp index 9c4e790..f2af13c 100644 --- a/disasm/leparseutil.cpp +++ b/disasm/leparseutil.cpp @@ -1,5 +1,7 @@ #include "leparseutil.hpp" +#include "parse.hpp" + std::vector<uint8_t> read_file_part(std::istream& is, std::streamsize offset, size_t length) { is.clear(); is.seekg(0, std::ios::beg); @@ -29,3 +31,67 @@ le::File parse_file(std::istream& is) return file; } + +void relocate(std::vector<le::FixupRecordTable::Entry> fixups, std::vector<uint8_t>& binary, binparse::Value32 page_nr, le::File const& file) { + binparse::Offset32 page_offset; + for(auto&& object : file.object_table.entries) { + if(page_nr >= object.second.page_table_index && page_nr < object.second.page_table_index + object.second.nr_page_table_entries) { + page_offset = object.second.reloc_base_address; + page_offset += ((page_nr - 1) - object.second.page_table_index) * file.le_header.page_size; + break; + } + } + + for(auto&& fixup : fixups) { + auto internal = boost::get<le::FixupRecordTable::Entry::Internal>(fixup.data); + + auto source_offset = boost::get<binparse::Offset16>(fixup.source_offset_or_source_list_count); + + auto target_object = boost::get<binparse::Value8>(internal.object_number); + + auto binary_offset = page_offset + (int32_t) source_offset; + + binparse::Offset32 dest_offset; + if(bit(4, fixup.target_flags)) { + dest_offset = boost::get<binparse::Offset32>(internal.target_offset); + } else { + dest_offset = binparse::Offset32(boost::get<binparse::Offset16>(internal.target_offset)); + } + dest_offset += file.object_table.entries.at(target_object).reloc_base_address; + for(int i = 0; i < 4; ++i) { + uint8_t& byte = *(binary.data() + binary_offset + i); + byte = ((dest_offset >> (i * 8)) & 255); + } + } +} + +std::vector<uint8_t> load_binary(le::File file) +{ + size_t binary_size = 0; + + for(auto&& object : file.object_table.entries) { + auto furthest_object_point = object.second.reloc_base_address + (object.second.nr_page_table_entries * file.le_header.page_size); + if (furthest_object_point > binary_size) { + binary_size = furthest_object_point; + } + } + + std::vector<uint8_t> binary(binary_size, 0x90); + + for(auto&& object : file.object_table.entries) { + auto index = object.second.page_table_index; + for(binparse::Value32 i = index ; i < index + object.second.nr_page_table_entries; ++i) { + auto page = file.pages.map[i]; + + binparse::Offset32 dest_offset = binparse::Offset32(object.second.reloc_base_address + ((i-1)-index) * file.le_header.page_size); + + std::copy(page.begin(), page.end(), binary.data() + dest_offset); + } + } + + for(auto&& relocation : file.fixup_record_table.entries) { + relocate(relocation.second, binary, relocation.first, file); + } + + return binary; +} diff --git a/disasm/leparseutil.hpp b/disasm/leparseutil.hpp index d44bc18..77bcaf1 100644 --- a/disasm/leparseutil.hpp +++ b/disasm/leparseutil.hpp @@ -8,4 +8,7 @@ le::File parse_file(std::istream& is); std::vector<uint8_t> read_file_part(std::istream& is, std::streamsize offset, size_t length); -std::vector<uint8_t> read_object(std::istream& is, le::File file, binparse::Value32 object_id);
\ No newline at end of file +std::vector<uint8_t> read_object(std::istream& is, le::File file, binparse::Value32 object_id); + +std::vector<uint8_t> relocate(le::File& file, std::vector<uint8_t> page, size_t index); +std::vector<uint8_t> load_binary(le::File file);
\ No newline at end of file diff --git a/le/le_fixup_record_table.cpp b/le/le_fixup_record_table.cpp index 8b52b82..e909203 100644 --- a/le/le_fixup_record_table.cpp +++ b/le/le_fixup_record_table.cpp @@ -66,7 +66,7 @@ FixupRecordTable::Entry::Internal parse_internal(std::istream& is, Value8 target FixupRecordTable::Entry::Internal internal; - if(bit(6, target_flags)) { + if(bit(7, target_flags)) { internal.object_number = parse<Value16>(is, "segment_number"); } else { internal.object_number = parse<Value8>(is, "segment_number"); |
