diff --git a/src/rp/arm.hpp b/src/rp/arm.hpp index e9bd030..586ea31 100644 --- a/src/rp/arm.hpp +++ b/src/rp/arm.hpp @@ -43,9 +43,6 @@ class ArmCapstone : public DisassEngineWrapper { instr.virtual_address_in_memory = uintptr_t(vaddr); instr.disassembly = mnemonic + ' ' + std::string(insn[0].op_str); instr.size = insn[0].size; - - instr.cap_is_branch = false; - instr.cap_is_valid_ending_instr = false; ret = AllRight; if (insn[0].detail == nullptr) { @@ -54,28 +51,28 @@ class ArmCapstone : public DisassEngineWrapper { } if (cs_insn_group(m_handle, insn, ARM_GRP_JUMP)) { - instr.cap_is_branch = true; - instr.cap_is_valid_ending_instr = + instr.is_branch = true; + instr.is_valid_ending_instr = insn[0].detail->arm.op_count == 1 && insn[0].detail->arm.operands[0].type != ARM_OP_IMM; } else if (mnemonic == "b" || mnemonic == "bl" || mnemonic == "blx" || mnemonic == "cb" || mnemonic == "cbz") { - instr.cap_is_branch = true; + instr.is_branch = true; } else if (mnemonic == "swi" || mnemonic == "svc") { - instr.cap_is_branch = true; - instr.cap_is_valid_ending_instr = true; + instr.is_branch = true; + instr.is_valid_ending_instr = true; } else if (mnemonic == "mov" && insn[0].detail->arm.op_count >= 1 && insn[0].detail->arm.operands[0].type == ARM_OP_REG && insn[0].detail->arm.operands[0].reg == ARM_REG_PC) { - instr.cap_is_branch = true; - instr.cap_is_valid_ending_instr = true; + instr.is_branch = true; + instr.is_valid_ending_instr = true; } else if (mnemonic == "bx") { - instr.cap_is_branch = true; - instr.cap_is_valid_ending_instr = + instr.is_branch = true; + instr.is_valid_ending_instr = insn[0].detail->arm.operands[0].type == ARM_OP_REG; } else if (mnemonic == "blx") { - instr.cap_is_branch = true; - instr.cap_is_valid_ending_instr = true; + instr.is_branch = true; + instr.is_valid_ending_instr = true; } else if (mnemonic == "pop") { bool has_pc = false; for (size_t i = 0; i < insn[0].detail->arm.op_count; ++i) { @@ -87,8 +84,8 @@ class ArmCapstone : public DisassEngineWrapper { } if (has_pc) { - instr.cap_is_branch = true; - instr.cap_is_valid_ending_instr = true; + instr.is_branch = true; + instr.is_valid_ending_instr = true; } } @@ -96,16 +93,6 @@ class ArmCapstone : public DisassEngineWrapper { return instr; } - bool is_valid_ending_instruction( - const InstructionInformation &instr) const override { - return instr.cap_is_valid_ending_instr; - } - - bool - is_valid_instruction(const InstructionInformation &instr) const override { - return instr.cap_is_branch == false; - } - uint32_t get_size_biggest_instruction() const override { return 4; } uint32_t get_alignement() const override { diff --git a/src/rp/arm64.hpp b/src/rp/arm64.hpp index 18657ca..bca5b45 100644 --- a/src/rp/arm64.hpp +++ b/src/rp/arm64.hpp @@ -37,9 +37,6 @@ class Arm64Capstone : public DisassEngineWrapper { instr.virtual_address_in_memory = uintptr_t(vaddr); instr.disassembly = mnemonic + ' ' + std::string(insn[0].op_str); instr.size = insn[0].size; - - instr.cap_is_branch = false; - instr.cap_is_valid_ending_instr = false; ret = AllRight; if (insn[0].detail == nullptr) { @@ -51,8 +48,8 @@ class Arm64Capstone : public DisassEngineWrapper { const bool Call = cs_insn_group(m_handle, insn, ARM64_GRP_CALL); const bool Ret = cs_insn_group(m_handle, insn, ARM64_GRP_RET); const bool Int = cs_insn_group(m_handle, insn, ARM64_GRP_INT); - instr.cap_is_branch = Jump || Call || Ret || Int; - instr.cap_is_valid_ending_instr = + instr.is_branch = Jump || Call || Ret || Int; + instr.is_valid_ending_instr = Ret || Int || ((Jump || Call) && insn[0].detail->arm64.op_count == 1 && insn[0].detail->arm64.operands[0].type != ARM64_OP_IMM); @@ -61,16 +58,6 @@ class Arm64Capstone : public DisassEngineWrapper { return instr; } - bool is_valid_ending_instruction( - const InstructionInformation &instr) const override { - return instr.cap_is_valid_ending_instr; - } - - bool - is_valid_instruction(const InstructionInformation &instr) const override { - return instr.cap_is_branch == false; - } - uint32_t get_size_biggest_instruction() const override { return 4; } uint32_t get_alignement() const override { return 4; } diff --git a/src/rp/disassenginewrapper.hpp b/src/rp/disassenginewrapper.hpp index cbe40f6..1b52e4f 100644 --- a/src/rp/disassenginewrapper.hpp +++ b/src/rp/disassenginewrapper.hpp @@ -6,22 +6,14 @@ #include struct InstructionInformation { - // Generic fields std::string disassembly; std::string mnemonic; uint32_t size = 0; uintptr_t address = 0; uintptr_t virtual_address_in_memory = 0; std::vector bytes; - - // Capstone field - bool cap_is_branch = false; - bool cap_is_valid_ending_instr = false; - - // BeaEngine fields - uint32_t bea_branch_type = 0; // This is used by BeaEngine ; and this will - // hold DISASM.Instruction.BranchType - uint64_t bea_addr_value = 0; // This is used by BeaEngine, DISASM.Instruction + bool is_branch = false; + bool is_valid_ending_instr = false; }; enum DisassEngineReturn { UnknownInstruction, OutOfBlock, AllRight }; @@ -39,10 +31,6 @@ class DisassEngineWrapper { virtual InstructionInformation disass(const uint8_t *data, uint64_t len, const uint64_t vaddr, DisassEngineReturn &ret) = 0; - virtual bool - is_valid_ending_instruction(const InstructionInformation &instr) const = 0; - virtual bool - is_valid_instruction(const InstructionInformation &instr) const = 0; virtual uint32_t get_size_biggest_instruction() const = 0; virtual uint32_t get_alignement() const = 0; }; diff --git a/src/rp/gadget.hpp b/src/rp/gadget.hpp index 39b4e02..2458e92 100644 --- a/src/rp/gadget.hpp +++ b/src/rp/gadget.hpp @@ -142,34 +142,18 @@ class Gadget { return true; } - const auto ¤t_a_bytes = a.m_instructions[current_a_idx].bytes(); - const size_t current_a_bytes_size = current_a_bytes.size(); - const auto ¤t_b_bytes = b.m_instructions[current_b_idx].bytes(); - const size_t current_b_bytes_size = current_b_bytes.size(); - while (1) { - if (current_a_bytes_idx >= current_a_bytes_size) { - current_a_idx++; - current_a_bytes_idx = 0; - break; - } - - if (current_b_bytes_idx >= current_b_bytes_size) { - current_b_idx++; - current_b_bytes_idx = 0; - break; - } - - if (current_a_bytes[current_a_bytes_idx] != - current_b_bytes[current_b_bytes_idx]) { - return current_a_bytes[current_a_bytes_idx] < - current_b_bytes[current_b_bytes_idx]; - } - - current_a_bytes_idx++; - current_b_bytes_idx++; + const auto ¤t_a_disass = + a.m_instructions[current_a_idx].get_disassembly(); + const auto ¤t_b_disass = + b.m_instructions[current_b_idx].get_disassembly(); + const int compare = current_a_disass.compare(current_b_disass); + if (compare != 0) { + return (compare < 0) ? true : false; } + + current_a_idx++; + current_b_idx++; } - return false; } }; @@ -186,8 +170,8 @@ class Gadget { uint32_t m_size; /*!< the size in byte of the gadget*/ std::vector - m_instructions; /*!< the list of the different instructions composing the - gadget*/ + m_instructions; /*!< the list of the different instructions composing + the gadget*/ mutable std::vector m_info_gadgets; /*!< the vector which stores where you can find the same diff --git a/src/rp/intelbeaengine.hpp b/src/rp/intelbeaengine.hpp index 329a7c5..b87aa31 100644 --- a/src/rp/intelbeaengine.hpp +++ b/src/rp/intelbeaengine.hpp @@ -44,49 +44,33 @@ class IntelBeaEngine : public DisassEngineWrapper { instr.disassembly = m_disasm.CompleteInstr; instr.mnemonic = m_disasm.Instruction.Mnemonic; instr.size = len_instr; - instr.bea_branch_type = m_disasm.Instruction.BranchType; - instr.bea_addr_value = m_disasm.Instruction.AddrValue; - return instr; - } - bool is_valid_ending_instruction( - const InstructionInformation &instr) const override { - const uint32_t branch_type = instr.bea_branch_type; - const uint64_t addr_value = instr.bea_addr_value; - const char *mnemonic_s = instr.mnemonic.c_str(); + const auto branch_type = m_disasm.Instruction.BranchType; + const auto addr_value = m_disasm.Instruction.AddrValue; + const char *mnemonic_s = m_disasm.Instruction.Mnemonic; + const char *disass_s = instr.disassembly.c_str(); - const std::string &disass = instr.disassembly; - const char *disass_s = disass.c_str(); + instr.is_branch = branch_type != 0; const bool is_good_branch_type = // We accept all the ret type instructions (except retf/iret) (branch_type == RetType && (strncmp(mnemonic_s, "retf", 4) != 0) && (strncmp(mnemonic_s, "iretd", 5) != 0)) || - // call reg32 / call [reg32] (branch_type == CallType && addr_value == 0) || - // jmp reg32 / jmp [reg32] (branch_type == JmpType && addr_value == 0) || - // int 0x80 & int 0x2e ((strncmp(disass_s, "int 0x80", 8) == 0) || (strncmp(disass_s, "int 0x2e", 8) == 0) || (strncmp(disass_s, "syscall", 7) == 0)); - return is_good_branch_type && - // Yeah, we don't accept jmp far/call far - disass.find("far") == std::string::npos; - } + instr.is_valid_ending_instr = + is_good_branch_type && + // Yeah, we don't accept jmp far/call far + instr.disassembly.find("far") == std::string::npos; - bool - is_valid_instruction(const InstructionInformation &instr) const override { - const Int32 branch_type = instr.bea_branch_type; - const uint64_t addr_value = instr.bea_addr_value; - return branch_type != RetType && branch_type != JmpType && - ((branch_type == CallType && addr_value == 0) || - branch_type != CallType) && - instr.disassembly.find("far") == std::string::npos; + return instr; } uint32_t get_size_biggest_instruction() const override { return 15; } diff --git a/src/rp/ropsearch_algorithm.cpp b/src/rp/ropsearch_algorithm.cpp index 5b104f0..9c940ee 100644 --- a/src/rp/ropsearch_algorithm.cpp +++ b/src/rp/ropsearch_algorithm.cpp @@ -46,9 +46,7 @@ void find_all_gadget_from_ret(const std::vector &memory, InstructionInformation instr = disass_engine.disass(EIP_, end_data - EIP_, VirtualAddr, ret); - const bool is_valid = g_opts.allow_branches - ? true - : disass_engine.is_valid_instruction(instr); + const bool is_valid = g_opts.allow_branches || (!instr.is_branch); // if the instruction isn't valid, ends this function if (ret == UnknownInstruction || ret == OutOfBlock || !is_valid) { break; @@ -126,7 +124,7 @@ void find_rop_gadgets(const std::vector §ion, const uint64_t vaddr, continue; } - if (!disass_engine.is_valid_ending_instruction(ret_instr)) { + if (!ret_instr.is_valid_ending_instr) { continue; }