Skip to content

Commit

Permalink
Merge branch 'main' into refactor/versioning
Browse files Browse the repository at this point in the history
  • Loading branch information
DennyDai authored Oct 11, 2024
2 parents 2e30c74 + 11ff06f commit 77acd79
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 11 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,8 @@ 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/

# auto-generated by setuptools-scm
src/headless_ida/_version.py

.idea/
6 changes: 5 additions & 1 deletion src/headless_ida/cli.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import argparse
import code

from rpyc.utils.server import ThreadedServer
from . import HeadlessIda, HeadlessIdaRemote, HeadlessIdaServer

Expand All @@ -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()
Expand All @@ -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:
Expand Down
21 changes: 12 additions & 9 deletions src/headless_ida/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from ctypes import cdll

import rpyc
from typing import Optional

from .helpers import ForwardIO, escape_path

Expand Down Expand Up @@ -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"))
Expand All @@ -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(
Expand All @@ -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:
Expand Down

0 comments on commit 77acd79

Please sign in to comment.