From 15a04b6f62b7b31bb66ccaf5073a7daaaf2edb32 Mon Sep 17 00:00:00 2001 From: doronz88 Date: Mon, 7 Oct 2024 18:32:40 +0300 Subject: [PATCH 1/2] gitignore: add `.idea` --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 6769e21..2dc53ca 100644 --- a/.gitignore +++ b/.gitignore @@ -157,4 +157,4 @@ cython_debug/ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore # and can be added to the global gitignore or merged into this file. For a more nuclear # option (not recommended) you can uncomment the following to ignore the entire idea folder. -#.idea/ \ No newline at end of file +.idea/ From 33740bd1997e71bd2fffc3115b6675d1b77dda28 Mon Sep 17 00:00:00 2001 From: doronz88 Date: Tue, 8 Oct 2024 13:27:48 +0300 Subject: [PATCH 2/2] cli: add `-f` option to choose ftype --- src/headless_ida/cli.py | 6 +++++- src/headless_ida/client.py | 21 ++++++++++++--------- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/src/headless_ida/cli.py b/src/headless_ida/cli.py index 063bdb6..0e62656 100644 --- a/src/headless_ida/cli.py +++ b/src/headless_ida/cli.py @@ -1,5 +1,6 @@ import argparse import code + from rpyc.utils.server import ThreadedServer from . import HeadlessIda, HeadlessIdaRemote, HeadlessIdaServer @@ -10,6 +11,9 @@ def headlessida_cli(): 'idat_path', help='Path to IDA Pro TUI executable / Host:Port of remote HeadlessIDA server') parser.add_argument('binary_path', help='Path to binary to analyze') parser.add_argument('script_path', nargs='?', help='Path to script to run') + parser.add_argument('-f', '--ftype', nargs='?', + help='interpret the input file as the specified file type The file type is specified as a ' + 'prefix of a file type visible in the "load file" dialog box') parser.add_argument('-c', '--command', help='Command to run after script') args = parser.parse_args() @@ -18,7 +22,7 @@ def headlessida_cli(): host, port = args.idat_path.split(":") headlessida = HeadlessIdaRemote(host, int(port), args.binary_path) else: - headlessida = HeadlessIda(args.idat_path, args.binary_path) + headlessida = HeadlessIda(args.idat_path, args.binary_path, ftype=args.ftype) headlessida_dict = {"headlessida": headlessida, "HeadlessIda": HeadlessIda} if args.script_path: diff --git a/src/headless_ida/client.py b/src/headless_ida/client.py index 57b9c43..948d33f 100644 --- a/src/headless_ida/client.py +++ b/src/headless_ida/client.py @@ -10,6 +10,7 @@ from ctypes import cdll import rpyc +from typing import Optional from .helpers import ForwardIO, escape_path @@ -62,29 +63,29 @@ class HeadlessIda(): }, } - def __init__(self, ida_dir, binary_path, override_import=True, bits=64): + def __init__(self, ida_dir, binary_path, override_import=True, bits=64, ftype: Optional[str] = None) -> None: binary_names = self.IDA_BINARY_NAMES[platform.system()] self.backend = None if os.path.isfile(ida_dir): filename = os.path.basename(ida_dir) if filename == binary_names["idalib64"]: - return self._idalib_backend(ida_dir, binary_path, override_import) + return self._idalib_backend(ida_dir, binary_path, override_import, ftype=ftype) if filename in [binary_names[key] for key in ["ida64", "idat64", "ida", "idat"]]: - return self._ida_backend(ida_dir, binary_path, override_import) + return self._ida_backend(ida_dir, binary_path, override_import, ftype=ftype) if os.path.isdir(ida_dir): idalib64_path = os.path.join(ida_dir, binary_names["idalib64"]) if os.path.exists(idalib64_path): - return self._idalib_backend(idalib64_path, binary_path, override_import) - + return self._idalib_backend(idalib64_path, binary_path, override_import, ftype=ftype) + idat_key = "idat64" if bits == 64 else "idat" idat_path = os.path.join(ida_dir, binary_names[idat_key]) - return self._ida_backend(idat_path, binary_path, override_import) + return self._ida_backend(idat_path, binary_path, override_import, ftype=ftype) raise Exception("Invalid IDA directory") - def _idalib_backend(self, idalib_path, binary_path, override_import=True): + def _idalib_backend(self, idalib_path, binary_path, override_import=True, ftype: Optional[str] = None): assert self.backend is None self.backend = "idalib" sys.path.insert(0, os.path.join(os.path.dirname(idalib_path), "python/3/ida_64")) @@ -96,7 +97,7 @@ def _idalib_backend(self, idalib_path, binary_path, override_import=True): shutil.copy(binary_path, tempdir) self.libida.open_database(str(os.path.join(tempdir, os.path.basename(binary_path))).encode(), True) - def _ida_backend(self, idat_path, binary_path, override_import=True): + def _ida_backend(self, idat_path, binary_path, override_import=True, ftype: Optional[str] = None) -> None: assert self.backend is None self.backend = "ida" server_path = os.path.join(os.path.realpath( @@ -115,7 +116,9 @@ def _ida_backend(self, idat_path, binary_path, override_import=True): command = f'"{idat_path}" -A -S"{escape_path(server_path)} {port}" -P+ "{binary_path}"' else: tempidb = tempfile.NamedTemporaryFile() - command = f'"{idat_path}" -o"{tempidb.name}" -A -S"{escape_path(server_path)} {port}" -P+ "{binary_path}"' + command = f'"{idat_path}" -o"{tempidb.name}" -A -S"{escape_path(server_path)} {port}" "{binary_path}"' + if ftype is not None: + command += f' -T "{ftype}"' p = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) while True: if p.poll() is not None: