コード例 #1
0
def decrypt_resource(verbose=True):
    if verbose:
        print("\n%s\n\tStarting the decryption of the resource\n%s\n" %
              ('~'*60, '~'*60))
    # Get information on all resources in JSON format
    rsrcs = cutter.cmdj('iRj')
    rsrc_101 = {}

    # Locate resource 101 and dump it to an array
    for rsrc in rsrcs:
        if rsrc['name'] == 101:
            rsrc_101 = cutter.cmdj("pxj %d @ %d" %
                                   (rsrc['size'], rsrc['vaddr']))

    # Decompress the zlibbed array
    decompressed_data = zlib.decompress(bytes(rsrc_101))

    decrypted_payload = []

    # Decrypt the payload
    for b in decompressed_data:
        decrypted_payload.append((ror(b, 3, 8)))

    # Write the payload (a PE binary) to a file
    open(r'./decrypted_rsrc.bin', 'wb').write(bytearray(decrypted_payload))

    if verbose:
        print("Saved the PE to ./decrypted_rsrc.bin")
コード例 #2
0
ファイル: util.py プロジェクト: CrackerCat/capa-explorer
def smart_rename_function(location, name):

    # Get function info
    function_info = cutter.cmdj('afij @%s' % location)

    if not len(function_info):
        # no function at location, trigger analysis
        # and refetch function info
        cutter.cmd('af @ %s' % location)
        function_info = cutter.cmdj('afij @%s' % location)

    old_fn_name = function_info[0]['name']

    # Sometimes the vivisect feature extractor identifies
    # adresses in the middle of functions as function starts
    # for some reason. We get the actual addr with r2.
    actual_offset = function_info[0]['offset']

    if old_fn_name.startswith('fcn.'):
        # Function has default name, replace all of it.
        cutter.cmd('afn {} @ {}'.format(name, actual_offset))
    else:
        # Function does not have generic name keep old name as prefix
        name = f'{old_fn_name}__{name}'
        cutter.cmd('afn {} @ {}'.format(name, actual_offset))
コード例 #3
0
    def update_content(self):
        current_line = cutter.cmdj("pdj 1")[0]

        # Running "ij" during DockWidget init causes a crash
        if not self.cutterref:
            info = cutter.cmdj("ij")["bin"]
            arch = info["arch"]
            self.cutterref = CutterRef(info["arch"] + "-" + str(info["bits"]))

        try:
            inst = current_line["disasm"].split()[0]
        except:
            return

        # Don't update the text box for the same instruction
        if inst != self.previous_inst:
            doc = self.cutterref.get_instruction_doc(inst)
            # Use r2's documentation if the instruction wasn't found in the loaded manual
            if not doc:
                doc = cutter.cmd("aod @ " + str(current_line["offset"]))

            self.view.setHtml(doc)
            self.previous_inst = inst

        return
コード例 #4
0
 def test_analyse_function(self, _):
     # Here, checking if cutter works as expected is out of scope but rather
     # what I am checking is given that cutter works as expected does my code
     # work as expected as well or not
     _, bbs = drcov.load("test_files/drcov2.4.log")
     function = cutter.cmdj("aflj")[0]
     base = cutter.cmdj("ij")['bin']['baddr']
     entry, hits = covtable.analyse_function(function, base, bbs[0])
     hardcoded_entry = ['76.923%', 'entry0', '0x08048060', '10/13', '3/4']
     self.assertEqual(entry, hardcoded_entry)
     self.assertEqual(hits, {0x8048060, 0x804808a, 0x8048074})
コード例 #5
0
ファイル: covTable.py プロジェクト: thestr4ng3r/CutterDRcov
def analyse(config):
    functions = cutter.cmdj("aflj")
    module = Path(cutter.cmdj("ij")['core']['file']).name
    idx = getModuleIdx(config['modules'], module)
    # [coverage, name, address, instruction hits, basic block hits]
    config['bb_hits'] = set()
    config['table'] = []
    for function in functions:
        entry, hits = analyse_function(function, config['bbs'][idx])
        if entry == None:
            continue
        config['table'].append(entry)
        config['bb_hits'].update(hits)
コード例 #6
0
ファイル: cutter_api.py プロジェクト: zha0/Hyara
 def get_string(self, start_address, end_address) -> list:
     result = []
     data = cutter.cmdj("Csj")  # get single line strings : C*.@addr
     for i in data:
         if i["offset"] >= start_address and i["offset"] <= end_address:
             result.append(base64.b64decode(i["name"]).decode())
     return result
コード例 #7
0
    def export_db(self):
        filename = self.file_dialog("Open new file for export", True)
        if not filename:
            return

        cutter.message("[x64dbg-cutter]: Exporting database to %s" % filename)
        
        db = {}
        
        base_addr = cutter.cmdj("elJ bin.baddr")[0]["value"]
        cutter.message("[x64dbg-cutter]: baddr is %d" % base_addr)
        
        # We can only export items from the main binary currently
        module = os.path.basename(cutter.cmdj("ij")["core"]["file"]).lower()
        
        # ref: {"addr":5368778842,"size":1,"prot":"--x","hw":false,"trace":false,"enabled":true,"data":"","cond":""}
        db["breakpoints"] = [{
            "address": hex(bp["addr"] - base_addr), # Comment address relative to the base of the module
            "enabled": bp["enabled"], # Whether the breakpoint is enabled
            "type": BPHARDWARE if bp["hw"] else BPNORMAL, # see https://github.com/x64dbg/x64dbg/blob/development/src/dbg/breakpoint.h#L13
            "module": module, # The module that the comment is in
        } for bp in cutter.cmdj("dbj")]
        cutter.message("[x64dbg-cutter]: %d breakpoint(s) exported" % len(db["breakpoints"]))
        
        # ref: {"offset":5368713216,"type":"CCu","name":"[00] -rwx section size 65536 named .textbss"}
        db["comments"] = [{
            "module": module, # The module that the comment is in
            "address": hex(c["offset"] - base_addr), # Comment address relative to the base of the module
            "manual": True, # Whether the comment was created by the user - set to True to show it in the comments window
            "text": c["name"], # Comment text
        } for c in cutter.cmdj("CCj")]
        cutter.message("[x64dbg-cutter]: %d comment(s) exported" % len(db["comments"]))

        # Set flagspace to all before iterating over fj to show all of the flags
        cutter.cmd("fs *")

        # ref: {"name":"fcn.1400113de","size":5,"offset":5368779742}
        db["labels"] = [{
            "module": module, # The module that the label is in
            "address": hex(label["offset"] - base_addr), # Label address relative to the base of the module
            "manual": False, # Whether the label was created by the user
            "text": label["name"], # Label text
        } for label in cutter.cmdj("fj") if (label["offset"] - base_addr) >= 0]
        cutter.message("[x64dbg-cutter]: %d labels(s) exported" % len(db["labels"]))

        with open(filename, "w") as outfile:
            json.dump(db, outfile, indent=1)
コード例 #8
0
ファイル: util.py プロジェクト: CrackerCat/capa-explorer
def get_disasm(location):
    feature_disasm = cutter.cmdj("pdj 1 @%s" % location)

    if feature_disasm[0].get('disasm'):
        disasm = feature_disasm[0].get('disasm')
    else:
        disasm = 'N/A'
    return disasm
コード例 #9
0
ファイル: cutter_api.py プロジェクト: zha0/Hyara
 def get_comment_hex(self, start_address, end_address) -> list:
     result = []
     current_start = start_address
     while current_start < end_address:
         cutter_data = cutter.cmdj(f"i. @ {current_start}")
         result.append(self.get_hex(current_start, cutter_data["next"]))
         current_start = cutter_data["next"]
     return result
コード例 #10
0
    def buildDecoderTable(self):
        self.decoder = {
            'addr': 0x41ba3c,
            'len':  0x41ba79 - 0x41ba3c,
            'fcn':  0x4012a0,
        }

        self.decoder['tbl'] = cutter.cmdj("pxj %d @ %d" % (self.decoder['len'], self.decoder['addr']))
コード例 #11
0
def analyse(config):
    config['bb_hits'] = set()
    config['table'] = []
    functions = cutter.cmdj("aflj")
    info = cutter.cmdj("ij")
    module = file_name(info['core']['file'])
    base = info["bin"]["baddr"]
    idx = get_module_idx(config['modules'], module)
    if idx == -1:
        return
    # [coverage, name, address, instruction hits, basic block hits]
    for function in functions:
        entry, hits = analyse_function(function, base, config['bbs'][idx])
        if entry is None:
            continue
        config['table'].append(entry)
        config['bb_hits'].update(hits)
コード例 #12
0
ファイル: util.py プロジェクト: CrackerCat/capa-explorer
def get_name(location):
    function_info = cutter.cmdj('afij @%s' % location)
    if len(function_info):
        fn_name = function_info[0]['name']
        match_name = f"{fn_name}"
    else:
        match_name = 'undefined.%s' % location
    return match_name
コード例 #13
0
def decode_strings(verbose=True):

    if verbose:
        print("\n%s\n\tStarting the decode of the encrypted strings\n%s\n\n" %
              ('~'*60, '~'*60))

    # Declaration of decryption-table related variables
    decryption_table = 0x41BA3C
    decryption_table_end = 0x41BA77
    decryption_table_len = decryption_table_end - decryption_table
    decryption_function = 0x4012A0

    # Analyze the binary to better detect functions and x-refs
    cutter.cmd('aa')

    # Rename the decryption function
    cutter.cmd('afn decryption_function %d' % decryption_function)

    # Dump the decryption table to a variable
    decryption_table_content = cutter.cmdj(
        "pxj %d @ %d" % (decryption_table_len, decryption_table))

    # Iterate x-refs to the decryption function
    for xref in cutter.cmdj('axtj %d' % decryption_function):
        # Get the arguments passed to the decryption function: length and encrypted string
        length_arg, offsets_arg = cutter.cmdj('pdj -2 @ %d' % (xref['from']))

        # String variable to store the decrypted string
        decrypted_string = ""

        # Guard rail to avoid exception
        if (not 'val' in length_arg):
            continue

        # Manually decrypt the encrypted string
        for i in range(0, length_arg['val']):
            decrypted_string += chr(decryption_table_content[cutter.cmdj(
                'pxj 1 @ %d' % (offsets_arg['val'] + (i*2)))[0]])

        # Print the decrypted and the address it was referenced to the console
        if verbose:
            print(decrypted_string + " @ " + hex(xref['from']))

        # Add comments to each call of the decryption function
        cutter.cmd('CC Decrypted: %s @ %d' % (decrypted_string, xref['from']))
コード例 #14
0
ファイル: cutter_api.py プロジェクト: hugmyndakassi/Hyara
 def get_disasm(self, start_address, end_address) -> list:
     result = []
     start = int(start_address, 16)
     end = int(end_address, 16)
     while start <= end:
         cutter_data = cutter.cmdj("aoj @ " + str(start))
         result.append(cutter_data[0]["disasm"])
         start += cutter_data[0]["size"]
     return result
コード例 #15
0
ファイル: cutter_api.py プロジェクト: hugmyndakassi/Hyara
 def get_hex(self, start_address, end_address) -> list:
     result = []
     start = int(start_address, 16)
     end = int(end_address, 16)
     while start <= end:
         cutter_data = cutter.cmdj("aoj @ " +
                                   str(start))  # or p8j size @ addr
         result.append(cutter_data[0]["bytes"])
         start += cutter_data[0]["size"]
     return result
コード例 #16
0
ファイル: debugger.py プロジェクト: yossizap/angrcutter
    def before_stateshot(self):
        self.vmmap = self._get_vmmap()
        self.base_addr = self.image_base()

        for sec in cutter.cmdj("iSj"):
            if sec["name"] == load_project(
            ).arch.got_section_name or sec["name"] == ".plt.got":
                self.got = (sec["vaddr"], sec["vaddr"] + sec["vsize"])
            elif sec["name"] == ".plt":
                self.plt = (sec["vaddr"], sec["vaddr"] + sec["vsize"])
            elif sec["name"] == ".idata":
                self.plt = (sec["vaddr"], sec["vaddr"] + sec["vsize"])
コード例 #17
0
    def decodeAll(self):
        # Start with analysis
        cutter.cmd('aa')

        # Build the decoder table
        self.buildDecoderTable()

        # Dump all the strings passed to decoder function
        for xref in cutter.cmdj("axtj %d" % self.decoder['fcn']):
            xref_addr = xref['from']
            arg_len, arg_offsets = cutter.cmdj("pdj -2 @ %d" % xref_addr)

            if not 'val' in arg_len:
                continue

            indexes = cutter.cmdj("pxj %d @ %d" % (arg_len['val'] * 2, arg_offsets['val']))
            decoded_str = self.decode(indexes)

            #print("%s @ %s" % (decoded_str, hex(xref_addr)))
            cutter.cmd("CC Decoded: %s @ %d" % (decoded_str, xref_addr))

        # Refresh interface
        cutter.refresh()
コード例 #18
0
 def generate_callgraph(self):
     # TODO: get user settings for the .dot graph instead of using this hardcoded settings
     self.graph_dot = """digraph code {
     rankdir=LR;
     outputorder=edgesfirst;
     graph [bgcolor=azure fontname="Courier" splines="curved"];
     node [fillcolor=white style=filled fontname="Courier New Bold" fontsize=14 shape=box];
     edge [arrowhead="normal" style=bold weight=2];"""
     self.used_nodes = []
     function_name = cutter.cmd('afi.')
     function_name = function_name.replace("\n", "")
     self.functions_list = cutter.cmdj('aflmj')
     self.get_calls(function_name)
     self.graph_dot += '\n}'
コード例 #19
0
ファイル: debugger.py プロジェクト: yossizap/angrcutter
 def _get_vmmap(self):
     memory_map = cutter.cmdj("dmj")
     maps = []
     for m in memory_map:
         start = m["addr"]
         end = m["addr_end"]
         mapperm = 0
         if "r" in m["perm"]:
             mapperm |= SEG_PROT_R
         if "w" in m["perm"]:
             mapperm |= SEG_PROT_W
         if "x" in m["perm"]:
             mapperm |= SEG_PROT_X
         maps += [(start, end, mapperm, m["name"])]
     return maps
コード例 #20
0
ファイル: debugger.py プロジェクト: yossizap/angrcutter
 def resolve_name(self, name):
     try:
         modules = cutter.cmdj("dmmj")
         for m in modules[1:]:
             addr = m["address"]
             lib = os.path.basename(m["name"]).split(".")[0].split("-")[0]
             o = cutter.cmd("dmi* %s %s" % (lib, name))
             for line in o.split("\n"):
                 line = line.split()
                 if len(line) < 4:
                     continue
                 if line[1] == name or line[3] == "sym." + name:
                     return int(line[3], 16)
     except:
         pass
     return None
コード例 #21
0
 def get_disassembly_of(self, address):
     #disasm_callee = cutter.cmdj("pdrj @ $F")
     if address == 0x0:
         return ''
     
     disassembly = cutter.cmdj("pdrj @ " + str(address))
     disassembly_str = ''
     offset = ''
     fcn_addr = ''
     opcode = ''
     size = ''
     oldsize = 0
     
     for dis_dict in disassembly:
         for key in dis_dict:
             if key == 'offset':
                 offset = dis_dict['offset']
             elif key == 'fcn_addr':
                 fcn_addr = dis_dict['fcn_addr']
             elif key == 'size':
                 size = dis_dict['size']
             elif key == 'opcode':
                 opcode = dis_dict['opcode']
             elif key == 'disasm':
                 disasm = dis_dict['disasm']
                 
                 
         ## 0x0000000000001394 <+18>:    callq  0x1289 <my_function(int, char)>
         ## 0x00001394      call fcn.00001289
         
         ##{"offset":5012,"esil":"4745,rip,8,rsp,-=,rsp,=[],rip,=","refptr":false,"fcn_addr":4994,
         ##"fcn_last":5019,"size":5,"opcode":"call 0x1289","disasm":"call fcn.00001289","bytes":"e8f0feffff",
         ##"family":"cpu","type":"call","reloc":false,"type_num":3,"type2_num":0,"jump":4745,"fail":5017,
         ##"refs":[{"addr":4745,"type":"CALL"}]}
         
             
         if offset and fcn_addr and opcode and size:
             #disassembly_str = disassembly_str + f"{offset:#0{18}x}" + ' <+' + str(oldsize) + '>: ' + opcode + '\n'
             disassembly_str = disassembly_str + opcode + '\n'
             oldsize += size
         
         offset = ''
         fcn_addr = ''
         opcode = ''
         size = ''
         
     return disassembly_str
コード例 #22
0
ファイル: regtable.py プロジェクト: ITAYC0HEN/angrcutter
    def updateContents(self):
        try:
            registers = cutter.cmdj("drj gpr")
        except Exception as e:
            return

        self.setRowCount(0)
        for reg, value in registers.items():
            row_position = self.rowCount()
            self.insertRow(row_position)
            self.setItem(row_position, 0, QTableWidgetItem(reg))
            self.setItem(row_position, 1, QTableWidgetItem(str(value)))

            if reg in self.symRegs:
                # Color symbolic register in light blue
                self.item(row_position, 0).setBackground(QColor(52, 152, 219))
                self.item(row_position, 1).setBackground(QColor(52, 152, 219))
コード例 #23
0
def analyse_function(function, base, covbbs):
    entry = ["", function['name'], hex_pad(function['offset'], 8), "", ""]
    bbs = cutter.cmdj("afbj @" + function['name'])
    inst_count = 0
    inst_hits = 0
    bbs_count = 0
    bbs_hits = 0
    hit_set = set()
    to_be_added = {}
    for bblock in bbs:
        # radare2's basic block can't have jump inside it while that is
        # possible in DynamoRIO, for this reason we first need to check
        # if the size of the 2 basic block matches, if radare2's basic block
        # size is smaller thant we would add the next block untill the sizes
        # match. If dynamoRIO size is smaller then something is wrong with
        # r2 analysis or dynamoRIO coverage.
        bbs_count += 1
        inst_count += bblock['ninstr']
        dynamorio_size = 0
        covbbaddr = bblock['addr'] - base
        if covbbaddr in covbbs:
            dynamorio_size = covbbs[covbbaddr]
        if bblock['addr'] in to_be_added:
            dynamorio_size = to_be_added[bblock['addr']]
        if dynamorio_size == 0:
            continue
        bbs_hits += 1
        inst_hits += bblock['ninstr']
        hit_set.add(bblock['addr'])
        r2_size = bblock['size']
        if dynamorio_size > r2_size:
            to_be_added[bblock['addr'] + r2_size] = dynamorio_size - r2_size
    if bbs_hits == 0:
        return (None, hit_set)
    entry[3] = str(inst_hits) + "/" + str(inst_count)
    entry[4] = str(bbs_hits) + "/" + str(bbs_count)
    entry[0] = str(round(inst_hits * 100 / inst_count, 3)) + "%"
    return (entry, hit_set)
コード例 #24
0
    def file_dialog(self, title, new=False):
        if new:
            filename = QtWidgets.QFileDialog.getSaveFileName(
                self.main, title, self._last_directory, X64DBG_FILE_FILTERS)[0]
            # Append x64dbg's file prefix to the saved file
            # NOTE: This solution isn't ideal but preferred filename isn't available in
            # PySide's QtFileDialog constructor
            if not re.findall(".dd(64|32)", filename):
                bitness = cutter.cmdj("elJ asm.bits")[0]["value"]
                filename += f".dd{bitness}"
        else:
            filename = QtWidgets.QFileDialog.getOpenFileName(
                self.main, title, self._last_directory, X64DBG_FILE_FILTERS)[0]


        # Remember the last directory we were in (parsed from a selected file)
        # for the next time the user comes to load coverage files
        if filename:
            self._last_directory = os.path.dirname(filename) + os.sep

        cutter.message("[w64dbg-cutter] Received filename from file dialog:")
        cutter.message(" - %s" % filename)

        return filename
コード例 #25
0
 def update_contents(self):
     ### get actual loaded bin-filename
     ### cmdj('ij').get('Core').get('file')   or something like that
     
     self.set_new_radare2_e()
     
     ## find data/code references to this address with $F
     curr_pos = cutter.cmd('s')
     #print(f'curr_pos >{curr_pos}<')
     if curr_pos.strip() == '0x0':
         return
     
     current_func_disas = cutter.cmdj("pdrj $F")
     
     disas_str = ''
     offset = ''
     fcn_addr = ''
     opcode = ''
     size = ''
     oldsize = 0
     for dis_dict in current_func_disas:
         for key in dis_dict:
             if key == 'offset':
                 #print(f"offset >{dis_dict['offset']}<")
                 offset = dis_dict['offset']
         #print(f"esil >{dis_dict['esil']}<")
         #print(f"refptr >{dis_dict['refptr']}<")
             elif key == 'fcn_addr':
                 #print(f"fcn_addr >{dis_dict['fcn_addr']}<")
                 fcn_addr = dis_dict['fcn_addr']
             #elif key == 'fcn_last':
                 #print(f"fcn_last >{dis_dict['fcn_last']}<")
             elif key == 'size':
                 #print(f"size >{dis_dict['size']}<")
                 size = dis_dict['size']
             elif key == 'opcode':
                 #print(f"opcode >{dis_dict['opcode']}<")
                 opcode = dis_dict['opcode']
             #elif key == 'disasm':
                 #print(f"disasm >{dis_dict['disasm']}<")
         #print(f"bytes >{dis_dict['bytes']}<")
         #print(f"family >{dis_dict['family']}<")
         #print(f"type >{dis_dict['type']}<")
         #print(f"reloc >{dis_dict['reloc']}<")
         #print(f"type_num >{dis_dict['type_num']}<")
         #print(f"type2_num >{dis_dict['type2_num']}<")
         #print(f"flags >{dis_dict['flags']}<")
         #print(f"comment >{dis_dict['comment']}<")
         
         #f"{addr2:#0{18}x}"
         if offset and fcn_addr and opcode and size:
             disas_str = disas_str + f"{offset:#0{18}x}" + ' <+' + str(oldsize) + '>: ' + opcode + '\n'
             oldsize += size
         
         offset = ''
         fcn_addr = ''
         opcode = ''
         size = ''
         
     #a = current_func_disas.
     
     self._disasTextEdit.setPlainText("gdb-like disassembly:\n{}".format(disas_str))
コード例 #26
0
    def import_db(self):
        filename = self.file_dialog("Open x64dbg (Uncompressed) JSON database")
        if not filename:
            return

        cutter.message("[x64dbg-cutter]: Importing database %s" % filename)

        with open(filename) as dbdata:
            db = json.load(dbdata)

        # We can only import symbols for the main binary currently
        module = os.path.basename(cutter.cmdj("ij")["core"]["file"]).lower()
        base_addr = cutter.cmdj("evj bin.baddr")[0]["value"]

        count = 0
        breakpoints = db.get("breakpoints", [])
        for bp in breakpoints:
            try:
                if bp["module"] != module:
                    continue
                address = int(bp["address"], 16) + base_addr
                cutter.cmd("dbs " + str(address))
                # Breakpoints created by dbs are enabled by default
                if not bp["enabled"]:
                    cutter.cmd("dbd " + str(address))
                count += 1
            except:
                cutter.message("[x64dbg-cutter]: " + traceback.format_exc())
        cutter.message("[x64dbg-cutter]: %d/%d breakpoints(s) imported" %
                       (count, len(breakpoints)))

        count = 0
        comments = db.get("comments", [])
        for comment in comments:
            try:
                if comment["module"] != module:
                    continue
                address = int(comment["address"], 16) + base_addr
                text = base64.b64encode(
                    comment["text"].encode("utf-8")).decode()
                cutter.cmd("CCu base64:" + text + " @ " + str(address))
                count += 1
            except:
                cutter.message("[x64dbg-cutter]: " + traceback.format_exc())
        cutter.message("[x64dbg-cutter]: %d/%d comment(s) imported" %
                       (count, len(comments)))

        # Create a new flagspace for x64dbg labels and bookmarks to allow easy removal
        cutter.cmd("fs x64dbgcutter.labels")
        count = 0
        labels = db.get("labels", [])
        for label in labels:
            try:
                if label["module"] != module:
                    continue
                address = int(label["address"], 16) + base_addr
                # Spaces don't show up in flags, use underscore instead
                text = label["text"].replace(" ", "_")
                cutter.cmd("f " + text + " @ " + str(address))
                count += 1
            except:
                cutter.message("[x64dbg-cutter]: " + traceback.format_exc())
        cutter.message("[x64dbg-cutter]: %d/%d label(s) imported" %
                       (count, len(labels)))

        cutter.cmd("fs x64dbgcutter.bookmarks")
        count = 0
        bookmarks = db.get("bookmarks", [])
        for bookmark in bookmarks:
            try:
                if bookmark["module"] != module:
                    continue
                address = int(bookmark["address"], 16) + base_addr
                cutter.cmd("f " + "bookmark_" + str(address) + " @ " +
                           str(address))
                count += 1
            except:
                cutter.message("[x64dbg-cutter]: " + traceback.format_exc())
        cutter.message("[x64dbg-cutter]: %d/%d bookmark(s) imported" %
                       (count, len(bookmarks)))

        cutter.message("[x64dbg-cutter]: Done!")
コード例 #27
0
    def run(self):
        self.updateProgressBar.emit(1)
        
        curr_pos = cutter.cmd('s')
        if curr_pos.strip() == '0x0':
            print('runInference not from addr 0x0')
            return
         
        self.set_new_radare2_e()
        
        ### get name of current function
        current_func_name = cutter.cmdj("afdj $F").get('name')
         
        #print(f'current_func_name >{current_func_name}<')
        
        ## find data/code references to this address with $F
        current_func_header = cutter.cmdj("axtj $F")
        
        ## get addr of callee
        caller_addr = 0
        for item_dicts in current_func_header:
            print(f'item_dicts >{item_dicts}<')
            for elem in item_dicts:
                if elem == 'from':
                    caller_addr = item_dicts[elem]
                    #print(f'address of caller >{item_dicts[elem]}<')
                 
         
        ## get disassembly of current/callee function
        address = cutter.cmd('s').strip()
        #print(f'address >{address}<')
        if address == '0x0':
            self.updateProgressBar.emit(100)
            self.resultReady.emit('')
            self.summaryReady.emit('Current address is 0x0, choose other function')
            #print(f'address kicked >{address}<')
            return
        
        disasm_callee_str = self.get_disassembly_of(address)
        #print(f'disasm_callee_str >{disasm_callee_str}<')
        
        ### get disassembly of caller function
        disasm_caller_str = self.get_disassembly_of(caller_addr)
        #print(f'disasm_caller_str >{disasm_caller_str}<')
  
        ### split disas for the tf-model     
        disasm_caller_str = disassembly_lib.split_disassembly(disasm_caller_str)
        disasm_callee_str = disassembly_lib.split_disassembly(disasm_callee_str)

        ##check if we got caller and callee disassembly
        if (len(disasm_caller_str) == 0) or (len(disasm_callee_str) == 0):
            self.updateProgressBar.emit(100)
            self.resultReady.emit('')
            self.summaryReady.emit('No caller disassembly found, choose other function')
            
            #print(f'Not found callee and caller disassembly.')
            return
         
        ### the path were we cloned git repo to
        self._userHomePath = os.path.expanduser('~')
        #print(f'userHomePath >{self._userHomePath}<')
        
        func_sign_prob_git_path = self._userHomePath + "/git/func_sign_prob/"
        
        self.updateProgressBar.emit(9)
         
        callee_addr_split = [char if char != '0' else 'null' for char in address]
        callee_addr = ' '.join(callee_addr_split)
        disasm_caller_callee_predict_str = disasm_caller_str + ' caller_callee_separator ' + callee_addr + ' ' + disasm_callee_str
        ### predict now ret-type
        ret_type_prediction_summary_str = self.get_prediction('return_type/words_100000', 
                                                                disasm_caller_callee_predict_str, 
                                                                func_sign_prob_git_path)
        
        
          
        ## store for later, will be overridden
        ret_type_model_summary_str = self.model_summary_str
        ret_type_biggest_prob = self.biggest_prob
        ret_type_biggest_prob_type = self.biggest_prob_type
        ret_type_biggest_prob_percent = 100 * ret_type_biggest_prob
        self.updateProgressBar.emit(10)
                  
        ### predict now nr_of_args
        nr_of_args_prediction_summary_str = self.get_prediction('nr_of_args/words_100000', 
                                                                disasm_caller_callee_predict_str, 
                                                                func_sign_prob_git_path)
                   
                
        ## store for later, will be overridden
        nr_of_args_model_summary_str = self.model_summary_str
        nr_of_args_biggest_prob = self.biggest_prob
        nr_of_args_biggest_prob_type = self.biggest_prob_type
        self.updateProgressBar.emit(20)
           
        ###predict now arg_one
        arg_one_prediction_summary_str = self.get_prediction('arg_one', 
                                                                disasm_caller_callee_predict_str, 
                                                                func_sign_prob_git_path)
            

        ## store for later, will be overridden
        arg_one_model_summary_str = self.model_summary_str
        arg_one_biggest_prob = self.biggest_prob
        arg_one_biggest_prob_type = self.biggest_prob_type
        arg_one_biggest_prob_percent = 100 * arg_one_biggest_prob
        
            
        #nr_of_args_biggest_prob_type = 1
        if nr_of_args_biggest_prob_type == 1:
            
            self.set_stored_radare2_e()
            
            self.updateProgressBar.emit(100)
            
            self.summaryReady.emit(f"tf return type model summary:\n \
                                        {ret_type_model_summary_str}\n \
                                        {ret_type_prediction_summary_str}\n \
                                        tf nr_of_args model summary:\n \
                                         {nr_of_args_model_summary_str}\n \
                                         {nr_of_args_prediction_summary_str}\n \
                                         tf arg_one model summary:\n \
                                         {self.model_summary_str}\n \
                                         {arg_one_prediction_summary_str}")

            self.resultReady.emit(f'{ret_type_biggest_prob_type} \
                 <span style=\"background-color:red;\">({ret_type_biggest_prob_percent:3.1f}%)</span> \
                 {current_func_name} ( \
                 {arg_one_biggest_prob_type} \
                 <span style=\"background-color:red;\">({arg_one_biggest_prob_percent:3.1f}%)</span> \
                 )')
               
            
            return
        else:
            self.updateProgressBar.emit(30)   
              
        ###if more one args
        ###predict now arg_two
        arg_two_prediction_summary_str = self.get_prediction('arg_two', 
                                                                disasm_caller_callee_predict_str, 
                                                                func_sign_prob_git_path)
           
   
        ## store for later, will be overridden
        arg_two_model_summary_str = self.model_summary_str
        arg_two_biggest_prob = self.biggest_prob
        arg_two_biggest_prob_type = self.biggest_prob_type
        arg_two_biggest_prob_percent = 100 * arg_two_biggest_prob
        
          
        #nr_of_args_biggest_prob_type = 2 
        if nr_of_args_biggest_prob_type == 2:
            
            self.updateProgressBar.emit(100)
            
            self.summaryReady.emit(f"tf return type model summary:\n \
                                        {ret_type_model_summary_str}\n \
                                        {ret_type_prediction_summary_str}\n \
                                        tf nr_of_args model summary:\n \
                                        {nr_of_args_model_summary_str}\n \
                                        {nr_of_args_prediction_summary_str}\n \
                                        tf arg_one model summary:\n \
                                        {arg_one_model_summary_str}\n \
                                        {arg_one_prediction_summary_str}\n \
                                        tf arg_two model summary:\n \
                                        {arg_two_model_summary_str}\n \
                                        {arg_two_prediction_summary_str}")

            self.resultReady.emit(f'{ret_type_biggest_prob_type} \
                <span style=\"background-color:red;\">({ret_type_biggest_prob_percent:3.1f}%)</span> \
                {current_func_name} ( \
                {arg_one_biggest_prob_type} \
                <span style=\"background-color:red;\">({arg_one_biggest_prob_percent:3.1f}%)</span> , \
                {arg_two_biggest_prob_type} \
                <span style=\"background-color:red;\">({arg_two_biggest_prob_percent:3.1f}%)</span> \
                )')
            
              
            self.set_stored_radare2_e()
            return
        else:
            self.updateProgressBar.emit(40)
         
        ###if more than two args
        ###predict now arg_three
        arg_three_prediction_summary_str = self.get_prediction('arg_three', 
                                                                disasm_caller_callee_predict_str, 
                                                                func_sign_prob_git_path)
          
  
        ## store for later, will be overridden
        arg_three_model_summary_str = self.model_summary_str
        arg_three_biggest_prob = self.biggest_prob
        arg_three_biggest_prob_type = self.biggest_prob_type
        arg_three_biggest_prob_percent = 100 * arg_three_biggest_prob
         
                                              
        #nr_of_args_biggest_prob_type = 3
        if nr_of_args_biggest_prob_type >= 3:   #hack, if more args, need more models
              
            self.updateProgressBar.emit(100)
            
            self.summaryReady.emit(f"tf return type model summary:\n \
                                        {ret_type_model_summary_str}\n \
                                        {ret_type_prediction_summary_str}\n \
                                        tf nr_of_args model summary:\n \
                                        {nr_of_args_model_summary_str}\n \
                                        {nr_of_args_prediction_summary_str}\n \
                                        tf arg_one model summary:\n \
                                        {arg_one_model_summary_str}\n \
                                        {arg_one_prediction_summary_str}\n \
                                        tf arg_two model summary:\n \
                                        {arg_two_model_summary_str}\n \
                                        {arg_two_prediction_summary_str}\n \
                                        tf arg_three model summary:\n \
                                        {arg_three_model_summary_str}\n \
                                        {arg_three_prediction_summary_str}")

            self.resultReady.emit(f'{ret_type_biggest_prob_type} \
                <span style=\"background-color:red;\">({ret_type_biggest_prob_percent:3.1f}%)</span> \
                {current_func_name} ( \
                {arg_one_biggest_prob_type} \
                <span style=\"background-color:red;\">({arg_one_biggest_prob_percent:3.1f}%)</span> , \
                {arg_two_biggest_prob_type} \
                <span style=\"background-color:red;\">({arg_two_biggest_prob_percent:3.1f}%)</span> , \
                {arg_three_biggest_prob_type} \
                <span style=\"background-color:red;\">({arg_three_biggest_prob_percent:3.1f}%)</span> \
                )')
              
            self.set_stored_radare2_e()
            return
        else:
            self.updateProgressBar.emit(50)
         
        #for debug
        print('over')
         
        self.set_stored_radare2_e()
#         /* ... here is the expensive or blocking operation ... */
        self.resultReady.emit('')
コード例 #28
0
ファイル: util.py プロジェクト: CrackerCat/capa-explorer
def get_function_boundries_at_current_location():
    function_info = cutter.cmdj('afij')
    if len(function_info):
        return (function_info[0]['minbound'], function_info[0]['maxbound'])
    else:
        return None
コード例 #29
0
 def get_filename(self):
     """Returns working project from Cutter pipe."""
     binary_information = cutter.cmdj('ij')
     filename = binary_information['core']['file']
     return filename
コード例 #30
0
ファイル: cutter_api.py プロジェクト: zha0/Hyara
 def get_md5(self) -> str:
     return cutter.cmdj("itj").get("md5", None)