Beispiel #1
1
    def search_retns(self):

        if not self.debug: print("found %d modules" % len(self.modules))
        for m in self.modules:

            # Iterate over segments in the module
            # BUG: Iterating over all loaded segments is more stable than looking up by address
            if not self.debug: print("found %d segments" % idaapi.get_segm_qty())
            for n in xrange(idaapi.get_segm_qty()):
                seg = idaapi.getnseg(n)

                # Locate executable segments in a selected modules
                # NOTE: Each module may have multiple executable segments
                if seg and seg.startEA >= m.addr and seg.endEA <= (m.addr + m.size):
                    # If the debugger is attached then we can check if the segment is executable, else
                    # just check if it is code or not.
                    if idaapi.dbg_can_query() and idaapi.get_process_state() < 0:
                        if seg.perm & idaapi.SEGPERM_EXEC == 0:
                            continue
                    elif seg.type & idaapi.SEG_CODE == 0:
                        continue

                    #######################################################
                    # Search for ROP gadgets
                    if self.searchRop:

                        #Search all instances of BLR
                        ea = seg.startEA
                        while True:
                            ea = idaapi.find_binary(ea + 1, seg.endEA, "4E 80 00 20", 16, idaapi.SEARCH_DOWN)
                            if ea == idaapi.BADADDR: break

                            self.retns.append((ea, m.file))

                        # Search all instances of BTCTR
                        ea = seg.startEA
                        while True:
                            ea = idaapi.find_binary(ea + 1, seg.endEA, "4E 80 04 20", 16, idaapi.SEARCH_DOWN)
                            if ea == idaapi.BADADDR: break

                            self.retns.append((ea, m.file))

                        # Search all instances of BTCTRL
                        ea = seg.startEA
                        while True:
                            ea = idaapi.find_binary(ea + 1, seg.endEA, "4E 80 04 21", 16, idaapi.SEARCH_DOWN)
                            if ea == idaapi.BADADDR: break

                            self.retns.append((ea, m.file))
Beispiel #2
0
def main():
    if not idaapi.is_debugger_on():
        idc.Warning("Please run the process first!")
        return
    if idaapi.get_process_state() != -1:
        idc.Warning("Please suspend the debugger first!")
        return

    # only avail from IdaPython r232
    if hasattr(idaapi, "NearestName"):
        # get all debug names
        dn = idaapi.get_debug_names(idaapi.cvar.inf.minEA, idaapi.cvar.inf.maxEA)
        # initiate a nearest name search (using debug names)
        nn = idaapi.NearestName(dn)
    else:
        nn = None

    ret, callstack = CallStackWalk(nn)
    if ret:
        title = "Call stack walker (thread %X)" % (GetCurrentThreadId())
        idaapi.close_chooser(title)
        c = CallStackWalkChoose(callstack, title)
        c.choose()
    else:
        idc.Warning("Failed to walk the stack:" + callstack)
Beispiel #3
0
def start():
    process_is_suspended = False

    #check if process is suspended
    if idaapi.is_debugger_on():
        if idaapi.get_process_state() == -1:
            process_is_suspended = True
        else:
            idaapi.warning("Please suspend the debugger!")
    else:
        idaapi.warning("Please run the process!")

    #then start a stack checking
    if process_is_suspended:
        is_success, call_list, call_addr_list = get_all_calls()
        if is_success and call_list is not None:
            curr_thread = ida_dbg.get_current_thread()
            title = "CallStack - thread: {}".format(curr_thread)
            idaapi.close_chooser(title)
            c = MyChoose(call_list, call_addr_list, title)
            c.Show()
        else:
            idaapi.warning(
                "Something wrong. There is no functions. Set DEBUG flag in the script and check what is going on"
            )
def main():
    if not idaapi.is_debugger_on():
        idc.Warning("Please run the process first!")
        return
    if idaapi.get_process_state() != -1:
        idc.Warning("Please suspend the debugger first!")
        return

    info = idaapi.get_inf_structure()
    if info.is_64bit():
        long_size = 8
    elif info.is_32bit():
        long_size = 4
    else:
        idc.Warning("Only 32 or 64 bit is supported!")
        return

    # only avail from IdaPython r232
    if hasattr(idaapi, "NearestName"):
        # get all debug names
        dn = idaapi.get_debug_names(idaapi.cvar.inf.minEA,
                                    idaapi.cvar.inf.maxEA)
        # initiate a nearest name search (using debug names)
        nn = idaapi.NearestName(dn)
    else:
        nn = None

    RetAddrStackWalk(nn, long_size)
Beispiel #5
0
def main():
    if not idaapi.is_debugger_on():
        print("Please run the process first!")
        return
    if idaapi.get_process_state() != -1:
        print("Please suspend the debugger first!")
        return

    dn = idaapi.get_debug_names(idaapi.cvar.inf.min_ea, idaapi.cvar.inf.max_ea)
    for i in dn:
        print("%08x: %s" % (i, dn[i]))
Beispiel #6
0
 def watchdog():
     while True:
         process_state = idaapi.get_process_state()
         if process_state == idc.DSTATE_RUN:
             self._resume_jdb()
             break
         elif process_state == idc.DSTATE_NOTASK:
             break
         else:
             time.sleep(0.5)
     self.unhook()
def check_memory_region(is_arch64):
    if ida_dbg.is_debugger_on():
        if ida_kernwin.ask_buttons(
                "Yes", "No", "Cancel", -1,
                "Add auto memory region (without memory region go to EIP/RIP can fail)"
        ) == -1:
            raise UICancel
        ida_dbg.enable_manual_regions(1)
        infos = ida_idd.meminfo_vec_t()
        info = ida_idd.memory_info_t()
        info.perm = 7
        if is_arch64:
            info.end_ea = 18446744073709551614
            info.bitness = 2
        else:
            info.end_ea = 4294967294
            info.bitness = 1
        info.sbase = 0
        info.sclass = 'UNK'
        info.name = 'MEMORY'
        info.start_ea = 0
        infos.push_back(info)
        ida_dbg.set_manual_regions(infos)
        # enable manual regions workarr:
        ida_dbg.enable_manual_regions(0)
        ida_dbg.refresh_debugger_memory()
        ida_dbg.enable_manual_regions(1)
        ida_dbg.refresh_debugger_memory()
        ida_dbg.edit_manual_regions()
        if idaapi.get_process_state() == -1:
            if is_arch64:
                cipreg = idaapi.get_reg_val('RIP')
            else:
                cipreg = idaapi.get_reg_val('EIP')
            ida_ua.create_insn(cipreg)
            ida_kernwin.jumpto(cipreg)
            ida_kernwin.refresh_idaview_anyway()
Beispiel #8
0
def is_process_suspended():
    return (idaapi.get_process_state() == DSTATE_SUSP)
Beispiel #9
0
def is_process_suspended():
    return (idaapi.get_process_state() == -1)
Beispiel #10
0
    def search_retns(self):

        if not self.debug: print("found %d modules" % len(self.modules))
        for m in self.modules:

            # Iterate over segments in the module
            # BUG: Iterating over all loaded segments is more stable than looking up by address
            if not self.debug: print("found %d segments" % idaapi.get_segm_qty())
            for n in xrange(idaapi.get_segm_qty()):
                seg = idaapi.getnseg(n)

                # Locate executable segments in a selected modules
                # NOTE: Each module may have multiple executable segments
                if seg and seg.startEA >= m.addr and seg.endEA <= (m.addr + m.size):
                    # If the debugger is attached then we can check if the segment is executable, else
                    # just check if it is code or not.
                    if idaapi.dbg_can_query() and idaapi.get_process_state() < 0:
                        if seg.perm & idaapi.SEGPERM_EXEC == 0:
                            continue
                    elif seg.type & idaapi.SEG_CODE == 0:
                        continue

                    #######################################################
                    # Search for ROP gadgets
                    if self.searchRop:

                        # Search all instances of RETN
                        ea = seg.startEA
                        while True:
                            ea = idaapi.find_binary(ea + 1, seg.endEA, "C3", 16, idaapi.SEARCH_DOWN)
                            if ea == idaapi.BADADDR: break
                            self.retns.append((ea, m.file))

                        # Search all instances of RETN imm16
                        ea = seg.startEA
                        while True:
                            ea = idaapi.find_binary(ea + 1, seg.endEA, "C2", 16, idaapi.SEARCH_DOWN)
                            if ea == idaapi.BADADDR: break

                            # Read imm16 value and filter large values
                            retn_imm16 = read_module_memory(ea + 1, 0x2)
                            retn_imm16 = unpack("<H", retn_imm16)[0]

                            if retn_imm16 <= self.maxRetnImm:
                                self.retns.append((ea, m.file))

                    #######################################################
                    # Search for JOP gadgets
                    if self.searchJop:

                        # Search all instances of JMP reg (FF /4) and CALL reg (FF /2)
                        ea = seg.startEA
                        while True:
                            ea = idaapi.find_binary(ea + 1, seg.endEA, "FF", 16, idaapi.SEARCH_DOWN)
                            if ea == idaapi.BADADDR: break

                            # Read possible ModR/M, SIB, and IMM8/IMM32 bytes
                            jop = read_module_memory(ea + 1, 0x6)
                            if jop == None or len(jop) == 0:
                                continue

                            ###################################################
                            # JMP/CALL reg
                            if jop[0] in ["\xe0", "\xe1", "\xe2", "\xe3", "\xe4", "\xe5", "\xe6", "\xe7",
                                          "\xd0", "\xd1", "\xd2", "\xd3", "\xd4", "\xd5", "\xd6", "\xd7"]:
                                self.retns.append((ea, m.file))

                            ###################################################
                            # JMP/CALL [reg] no SIB
                            # NOTE: Do not include pure [disp] instruction.

                            # JMP/CALL [reg] no *SP,*BP
                            elif jop[0] in ["\x20", "\x21", "\x22", "\x23", "\x26", "\x27",
                                            "\x10", "\x11", "\x12", "\x13", "\x16", "\x17"]:
                                self.retns.append((ea, m.file))

                            # JMP/CALL [reg + imm8] no *SP
                            elif jop[0] in ["\x60", "\x61", "\x62", "\x63", "\x65", "\x66", "\x67",
                                            "\x50", "\x51", "\x52", "\x53", "\x55", "\x56", "\x57"]:
                                jop_imm8 = jop[1]
                                jop_imm8 = unpack("b", jop_imm8)[0]  # signed

                                if jop_imm8 <= self.maxJopImm:
                                    self.retns.append((ea, m.file))


                            # JMP/CALL [reg + imm32] no *SP
                            elif jop[0] in ["\xa0", "\xa1", "\xa2", "\xa3", "\xa5", "\xa6", "\xa7",
                                            "\x90", "\x91", "\x92", "\x93", "\x95", "\x96", "\x97"]:
                                jop_imm32 = jop[1:5]
                                jop_imm32 = unpack("<i", jop_imm32)[0]  # signed

                                if jop_imm32 <= self.maxJopImm:
                                    self.retns.append((ea, m.file))

                            ###################################################
                            # JMP/CALL [reg] with SIB
                            # NOTE: Do no include pure [disp] instructions in SIB ([*] - none)
                            elif (jop[0] in ["\x24", "\x64", "\xa4"] and not jop[1] in ["\x25", "\x65", "\xad",
                                                                                        "\xe5"]) or \
                                    (jop[0] in ["\x14", "\x54", "\x94"] and not jop[1] in ["\x25", "\x65", "\xad",
                                                                                           "\xe5"]):

                                # Check for displacement
                                if jop[0] in ["\x64", "\x54"]:
                                    jop_imm8 = jop[2]
                                    jop_imm8 = unpack("b", jop_imm8)[0]  # signed

                                    if jop_imm8 <= self.maxJopImm:
                                        self.retns.append((ea, m.file))

                                elif jop[0] in ["\xa4", "\x94"]:
                                    jop_imm32 = jop[2:6]
                                    jop_imm32 = unpack("<i", jop_imm32)[0]  # signed

                                    if jop_imm32 <= self.maxJopImm:
                                        self.retns.append((ea, m.file))

                                else:
                                    self.retns.append((ea, m.file))

        print "[idasploiter] Found %d returns" % len(self.retns)