def match(self, *args, **kwargs): """ Patched to use our patched Match() object and allow for automatically running on IDB input file. Besides the default yara parameters, this implementation also includes: :param bool input_offset: Whether to apply input file offset to string offsets. :param int offset: Optional offset to offset string offsets by. :param str|int segment: Name or EA of segment to match to. """ input_offset = kwargs.pop('input_offset', False) offset = kwargs.pop('offset', None) segment = kwargs.pop('segment', None) # Run on segment. if segment: kwargs['data'] = utils.get_segment_bytes(segment) offset = offset or utils.get_segment_start(segment) # Run on input file. elif not (args or kwargs): args = (idc.get_input_file_path(),) input_offset = True return [Match(match, offset=offset, file_offset=input_offset) for match in self._rules.match(*args, **kwargs)]
def getInputFilepath_ida7(): '''Returns None if the uesr cancels. Updates the filepath in the idb on success''' filePath = idc.get_input_file_path() if not os.path.exists(filePath): print 'IDB input file not found. Prompting for new one: %s' % filePath filePath = idaapi.ask_file(False, '*.*', 'Enter path to idb input file') if filePath is not None: idc.set_root_filename(filePath) return filePath
def generate(self): idaapi.visit_patched_bytes(0, idaapi.BADADDR, self.get_patch_byte) if len(self.patched_bytes) == 0: msg = 'Cannot generate patch because there is no patch applied.' print('genpatch: %s' % msg) ida_kernwin.warning(msg) return False template_path = '' for path in sys.path: if 'plugins' in path: template_path = os.path.join(path, 'patch_template.txt') patch_path = idc.get_input_file_path() + '_patch.py' template_data = None with open(template_path, "r") as f: template_data = f.readlines() lines = 13 with open(patch_path, "w") as f: for data in self.patched_bytes: template_data.insert(lines, "# address: 0x%x\n" % data['begin_addr']) lines += 1 template_data.insert(lines, "# function name: %s\n" % data['name']) lines += 1 template_data.insert( lines, "# comment: %s\n" % data['comment'].replace('\n', ' ')) lines += 1 template_data.insert( lines, "matches = re.findall('%s', target_data)\n" % data['original']) lines += 1 template_data.insert(lines, "if len(matches) == 1:\n") lines += 1 template_data.insert( lines, " target_data = target_data.replace('%s', '%s')\n" % (data['original'], data['patched'])) lines += 1 template_data.insert(lines, "else:\n") lines += 1 template_data.insert( lines, ' print("Patch pattern isn\'t unique")\n') lines += 1 template_data.insert(lines, " sys.exit()\n") lines += 1 f.writelines(template_data) msg = 'Successfully generated patch to %s from Patched Bytes' % patch_path print('genpatch: %s' % msg) ida_kernwin.info(msg) return True
def activate(self, ctx): if ctypes.windll.shell32.IsUserAnAdmin() == 0: print("Admin privileges required") return #name = idc.GetInputFile().split('.')[0] name = idc.get_input_file_path().split('.')[0] driver = driverlib.Driver(idc.GetInputFilePath(), name) driver.stop() driver.unload()
def _parse_exe_file(): input_file_path = ida_kernwin.ask_file(False, idc.get_input_file_path(), 'Input file') parsed_file = tdinfo_structs.DOS_MZ_EXE_STRUCT.parse_file(input_file_path) print('Borland TLink symbolic information version: {}.{}'.format( parsed_file.tdinfo_header.major_version, parsed_file.tdinfo_header.minor_version)) return parsed_file
def load_as_exefs(li, options): dirname = os.path.dirname(idc.get_input_file_path()) binaries = LOAD_EXEFS_NAMES binaries = [os.path.join(dirname, i) for i in binaries] binaries = [i for i in binaries if os.path.exists(i)] for idx, fname in enumerate(binaries): with open(fname, 'rb') as f: if not load_one_file(f, options, idx, os.path.basename(fname)): return False return True
def __init__(self, input_path=None): import idc super().__init__(idc.get_input_file_path()) # Input path is not required when inside IDA, but if provided # let's use it to validate we are looking at the right file. if input_path and pathlib.Path(input_path).resolve() != self.input_path: raise ValueError( f"Expected input path isn't the same as the file loaded in IDA: {input_path} != {self.input_path}") self.start()
def get_define(ioctl_code): """Decodes an ioctl code and returns a C define for it using the CTL_CODE macro""" function = get_function(ioctl_code) device_name, device_code = get_device(ioctl_code) method_name, method_code = get_method(ioctl_code) access_name, access_code = get_access(ioctl_code) #name = "%s_0x%08X" % (idc.GetInputFile().split('.')[0], ioctl_code) name = "%s_0x%08X" % (idc.get_input_file_path().split('.')[0], ioctl_code) return "#define %s CTL_CODE(0x%X, 0x%X, %s, %s)" % (name, device_code, function, method_name, access_name)
def get_pat_file(): logger = logging.getLogger("idb2pat:get_pat_file") name, _extension = os.path.splitext(idc.get_input_file_path()) name = name + ".pat" filename = idaapi.ask_file(1, name, "Enter the name of the pattern file") if filename is None: logger.debug("User did not choose a pattern file") return None return filename
def test_basic(strings_exe): """Tests some basic functionality and stability.""" strings_exe = str(strings_exe) with kordesii.IDA(strings_exe): import idc from kordesii.utils import utils from kordesii.utils import ida_re assert idc.get_input_file_path() == strings_exe assert idc.print_insn_mnem(0x00401525) == 'mov' assert utils.get_function_addr('GetProcAddress') == 0x40a028 assert utils.get_string(0x0040C000) == b'Idmmn!Vnsme ' regex = ida_re.Pattern(b'Idmmn!Vnsme') match = regex.search() assert match assert match.start() == 0x0040C000 assert match.group() == b'Idmmn!Vnsme' # Ensure we can only start one at a time. with pytest.raises(ValueError): kordesii.IDA(r'C:\dummy.exe').start() pass # Ensure we can't use modules after closing. with pytest.raises(AttributeError): idc.print_insn_mnem(0x00401525) # Now test that we can spin it up again. with kordesii.IDA(strings_exe): # import idc # reimporting is not required. assert idc.get_input_file_path() == strings_exe # Now test manually starting and stopping. ida = kordesii.IDA(strings_exe) ida.start() import idc assert idc.get_input_file_path() == strings_exe ida.stop() # can't access imports outside with pytest.raises(AttributeError): idc.get_input_file_path() # now try starting the same instance again. ida.start() assert idc.get_input_file_path() == strings_exe ida.stop() # Try opening a file that is not actually an exe. # It should still work, just not be very helpful. with kordesii.IDA(__file__): assert idc.get_input_file_path() == __file__ assert idc.print_insn_mnem(0x00401525) == ''
def update_progress_bars(self): try: data = self.get_data() ent = entropy(data) norm_ent = ent/8*100 comp_ratio = calc_compression_ratio(data) self.pb_entropy.setValue(norm_ent) self.pb_entropy.setFormat("%0.2f" % ent) self.pb_comp_ratio.setValue(comp_ratio) except FileNotFoundError: idaapi.warning("Input file doesn't exist: %s" % idc.get_input_file_path()) except Exception as e: idaapi.warning("%s" % traceback.format_exc())
def get_unicode_device_names(): """Returns all Unicode strings within the binary currently being analysed in IDA which might be device names""" #path = idc.GetInputFile() path = idc.get_input_file_path() min_length = 4 possible_names = set() with open(path, "rb") as f: b = mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ) for s in extract_unicode_strings(b, n=min_length): s_str = str(s.s) if s_str.startswith('\\Device\\') or s_str.startswith( '\\DosDevices\\'): possible_names.add(str(s.s)) return possible_names
def update_config(config): logger = logging.getLogger("idb2pat:update_config") name, _extension = os.path.splitext(idc.get_input_file_path()) name = name + ".conf" if not os.path.exists(name): logger.debug("No configuration file provided, using defaults") return with open(name, "rb") as f: t = f.read() try: vals = json.loads(t) except Exception as e: logger.exception(e) logger.warning("Configuration file invalid") return config.update(vals) return
def extract_vtable_pac_codes(vtable_ea): pac_codes = [] # Open the file. path = idc.get_input_file_path() with open(path, "rb") as kernelcache_file: # Seek to the offset of the vtable. offset = idaapi.get_fileregion_offset(vtable_ea) kernelcache_file.seek(offset) # Loop over each entry in the vtable. ea = vtable_ea while True: # Break if we've reached the end of the vtable. vmethod = idc.get_qword(ea) if vmethod == 0: break # Get the original value from the original file. original = kernelcache_file.read(8) value, = struct.unpack("<Q", original) # Extract the type code and add it to the list. pac_code = (value & 0x0000ffff00000000) >> 32 pac_codes.append(pac_code) # Advance. ea += 8 return pac_codes
INVALID = None UNUSED = None # Codecs used to detect encoding of strings. CODE_PAGES = [ 'ascii', 'utf-32-be', 'utf-32-le', 'utf-16-be', 'utf-16-le', 'utf-8', # General (utf-7 omitted) 'gb18030', 'gbk', # Unified Chinese 'gb2312', 'hz', # Simplified Chinese 'big5hkscs', 'big5', # Traditional Chinese (cp950 omitted) 'koi8-r', 'iso8859-5', 'cp1251', 'mac-cyrillic', # Cyrillic (cp866, cp855 omitted) 'cp949', # Korean (johab, iso2022-kr omitted) 'iso8859-6', 'cp1256', # Arabic (cp864, cp720 omitted) 'latin1', # If all else fails, latin1 is always is successful. ] INPUT_FILE_PATH = idc.get_input_file_path() # Put these here for increased robustness. Please don't depend on these very often. ENCODED_STRINGS = [] DECODED_STRINGS = [] # CODEC to use for displaying strings in IDA, etc. DISPLAY_CODE = 'cp437' if sys.platform == 'win32' else 'ascii' class SuperFunc_t(object): """ Description: Effectively extends func_t to also know its name and all its non-recursive xrefs and knows how to rename itself. Fields:
import idc import idautils functions = idautils.Functions() f = open(idc.ARGV[1], 'a') if len(idc.ARGV) > 1 else sys.stdout log = f.write # log current file path log(idc.get_input_file_path() + '\n') # wait for auto-analysis to complete idc.auto_wait() for f in functions: log(idc.get_func_name(f) + "\n") print idc.get_func_name(f) idc.qexit(4)
def test_basic(strings_exe): """Tests some basic functionality and stability.""" strings_exe = str(strings_exe) with kordesii.IDA(strings_exe): import idc from kordesii.utils import utils from kordesii.utils import ida_re assert idc.get_input_file_path() == strings_exe assert idc.print_insn_mnem(0x00401525) == 'mov' assert utils.get_function_addr('GetProcAddress') == 0x40a028 assert utils.get_string(0x0040C000) == b'Idmmn!Vnsme ' regex = ida_re.Pattern(b'Idmmn!Vnsme') match = regex.search() assert match assert match.start() == 0x0040C000 assert match.group() == b'Idmmn!Vnsme' # Ensure we can only start one at a time. with pytest.raises(ValueError): kordesii.IDA(r'C:\dummy.exe').start() pass # Test that we can also use submodules (the utils in utils) from kordesii import utils assert utils.get_function_addr('GetProcAddress') == 0x40a028 assert utils.get_string(0x0040C000) == b'Idmmn!Vnsme ' # Test that importing a class doesn't cause things to explode. try: from ida_gdl import BasicBlock except ImportError as e: # FIXME pytest.xfail(f"Known bug of IDA proxy: {e}") with pytest.raises(NotImplementedError) as exec_info: BasicBlock(1, 2, 3) assert str( exec_info.value ) == "Initializing the class ida_gdl.BasicBlock is not supported." # Ensure we can't use modules after closing. with pytest.raises(AttributeError): idc.print_insn_mnem(0x00401525) # Now test that we can spin it up again. with kordesii.IDA(strings_exe): # import idc # reimporting is not required. assert idc.get_input_file_path() == strings_exe # Now test manually starting and stopping. ida = kordesii.IDA(strings_exe) ida.start() import idc assert idc.get_input_file_path() == strings_exe ida.stop() # can't access imports outside with pytest.raises(AttributeError): idc.get_input_file_path() # now try starting the same instance again. ida.start() assert idc.get_input_file_path() == strings_exe ida.stop() # Try opening a file that is not actually an exe. # It should still work, just not be very helpful. with kordesii.IDA(__file__): assert idc.get_input_file_path() == __file__ assert idc.print_insn_mnem(0x00401525) == ''
""" Stub used to run tests within IDA. """ import pytest import kordesii if __name__ == "__main__" and kordesii.in_ida: import idc idc.auto_wait() print(idc.get_input_file_path()) print(idc.ARGV) args = idc.ARGV[1:] print("Running: pytest {}".format(" ".join(args))) idc.qexit(pytest.main(args))
def OnCreate(self, form): # get parent widget parent = self.FormToPyQtWidget(form) # checkboxes self.cb_restore = QtWidgets.QCheckBox('Restore .idata section') self.cb_restore.move(20, 20) self.cb_restore.stateChanged.connect(self.cb_restore_toggle) self.cb_verify = QtWidgets.QCheckBox("Verify target dll .NET Native "\ "framework version") self.cb_verify.move(20, 20) # default is checked self.cb_verify.toggle() label_sharedlibrary = QtWidgets.QLabel("Path to target dll "\ "(SharedLibrary.dll):") # create input field for SharedLibrary.dll self.dll_input_path = QtWidgets.QLineEdit(parent) self.dll_input_path.setMaxLength = 256 self.dll_input_path.setFixedWidth(300) # create buttons self.btn_run = QtWidgets.QPushButton("Run", parent) self.btn_run.setToolTip("Proceed to import or restore.") self.btn_run.clicked.connect(self.cb_btn_run) self.btn_browse = QtWidgets.QPushButton("Browse", parent) self.btn_browse.setToolTip('Browse to "SharedLibrary.dll" location.') self.btn_browse.clicked.connect(self.cb_btn_browse) # we try to guess .NET Native framework version ida_kernwin.show_wait_box("HIDECANCEL\nIdentifying .NET "\ "Native framework version...") dotnet_version_full_text = ".NET Native framework version: " dotnet_version_full = "unknown" if not os.path.exists(idc.get_input_file_path()): ida_kernwin.warning("%s could not be found.\n.NIET must identify .NET"\ " Native framework version of the original binary "\ "in order to work properly."\ % idc.get_input_file_path()) else: dotnet_version_full = utils.get_NET_Native_version( idc.get_input_file_path()) if dotnet_version_full == "unknown": ida_kernwin.warning(".NET Native framework could not be identified.\n"\ ".NIET needs it to work properly.") # assume pefile raised an error elif "Error" in dotnet_version_full: ida_kernwin.hide_wait_box() ida_kernwin.warning("pefile: %s" % dotnet_version_full) self.disable_plugin_options() dotnet_version_full = "unsupported" self.dotnet_version_full = dotnet_version_full dotnet_version_full_text += dotnet_version_full ida_kernwin.hide_wait_box() label_dotnet_version_full = QtWidgets.QLabel(dotnet_version_full_text) # then we check if SharedLibrary.dll is an import imported_modules = [ idaapi.get_import_module_name(i) for i in range(idaapi.get_import_module_qty()) ] if not "SharedLibrary" in imported_modules: ida_kernwin.warning("This binary does not import symbols from " "'SharedLibrary.dll' at runtime.\n.NIET is not"\ " required") self.disable_plugin_options() # create layout spacerItem = QtWidgets.QSpacerItem(5, 16) layout = QtWidgets.QGridLayout() layout.addWidget(label_dotnet_version_full, 0, 0) layout.addItem(spacerItem) layout.addWidget(label_sharedlibrary, 1, 0) layout.addWidget(self.dll_input_path, 2, 0) layout.addWidget(self.btn_browse, 2, 1) spacerItem = QtWidgets.QSpacerItem(5, 16) layout.addItem(spacerItem) layout.addWidget(self.cb_restore, 4, 0) layout.addWidget(self.btn_run, 5, 0) layout.addWidget(self.cb_verify, 5, 1, 1, 2) layout.setColumnStretch(4, 1) layout.setRowStretch(6, 1) parent.setLayout(layout)
def create_segment_with_binary(self): segm_name = self.config.entropy['segm_name'] if load_file_in_segment(idc.get_input_file_path(), segm_name): self.config.segm_exists = True self.check_if_segm_exists()
def get_disk_binary(): data = None with open(idc.get_input_file_path(), 'rb') as f: data = f.read() return data
def cmd_get_input_path(self): return idc.get_input_file_path()