diff options
| author | Dennis Brentjes <d.brentjes@gmail.com> | 2016-09-10 19:44:33 +0200 |
|---|---|---|
| committer | Dennis Brentjes <d.brentjes@gmail.com> | 2016-09-10 19:44:33 +0200 |
| commit | f69d884353a23986ee40b108997ba155235d7529 (patch) | |
| tree | 8c98b26445a9e54fbf30095d653cb6b94c92dbdb | |
| parent | 4f65043e40dbaf8e4cc290327e34270645dedce3 (diff) | |
| download | openwar-f69d884353a23986ee40b108997ba155235d7529.tar.gz openwar-f69d884353a23986ee40b108997ba155235d7529.tar.bz2 openwar-f69d884353a23986ee40b108997ba155235d7529.zip | |
Working function extract, ugly but it works.
| -rw-r--r-- | disasm/extractfunction.cpp | 94 |
1 files changed, 87 insertions, 7 deletions
diff --git a/disasm/extractfunction.cpp b/disasm/extractfunction.cpp index 4fb675c..1af481e 100644 --- a/disasm/extractfunction.cpp +++ b/disasm/extractfunction.cpp @@ -2,6 +2,8 @@ #include "leparseutil.hpp" +#include "output.hpp" + #include <distorm.h> #include <iomanip> @@ -28,22 +30,100 @@ void extract_function(std::string file_path, binparse::Value32 object_id, binpar ci.codeLen = code_buf.size() - buffer_offset; ci.codeOffset = base_reloc_offset + buffer_offset; ci.dt = dt; - ci.features = DF_NONE; + ci.features = DF_RETURN_FC_ONLY | DF_STOP_ON_FLOW_CONTROL; + + std::cout << "Function starts at: " << function_offset << std::endl; - while(true) { + binparse::Offset32 furthestjmp; + + bool done = false; + while(!done) { distorm_decompose64(&ci, &decinst, 1, &decodedInstructionsCount); if(decinst.flags == FLAG_NOT_DECODABLE) { - break; + throw std::runtime_error("Could not decode the next instruction"); } - + + switch(META_GET_FC(decinst.meta)) { + case FC_CALL: { + //std::cout << "Call:\t"; + break; + } + case FC_CMOV: { + //std::cout << "CMOV /care:\t"; + break; + } + case FC_CND_BRANCH: { + binparse::Offset32 target = binparse::Offset32(INSTRUCTION_GET_TARGET(&decinst)); + if(target > furthestjmp) { + furthestjmp = target; + } + //std::cout << "CJMP:\t"; + break; + } + case FC_INT: { + //std::cout << "Int:\t"; + break; + } + case FC_RET: { + if(binparse::Offset32(ci.nextOffset) > furthestjmp) { + done = true; + } + //std::cout << "Return:\t"; + break; + } + case FC_SYS: { + //std::cout << "SYS?!?:\t"; + break; + } + case FC_UNC_BRANCH: { + binparse::Offset32 target = binparse::Offset32(INSTRUCTION_GET_TARGET(&decinst)); + if(target > furthestjmp) { + furthestjmp = target; + } + //std::cout << "JMP:\t"; + break; + } + case FC_NONE: + default: { + 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; - ci.code += decinst.size; - ci.codeLen -= decinst.size; - ci.codeOffset += decinst.size; + ci.code += distance; + ci.codeLen -= distance; + ci.codeOffset += distance; + } + } + std::cout << "Function ends at: " << binparse::Offset32(ci.nextOffset) << std::endl; + + std::vector<_DecodedInst> instructions; + instructions.resize(100000); + unsigned int read_inst; + + auto result = distorm_decode64( + file.object_table.entries[object_id].reloc_base_address + buffer_offset, + code_buf.data() + buffer_offset, + ci.nextOffset - function_offset, + Decode32Bits, + instructions.data(), + instructions.size(), + &read_inst + ); + + instructions.resize(read_inst); + instructions.shrink_to_fit(); + + 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; } } |
