Skip to content

Commit c7bf120

Browse files
committed
Format files to pass tests
1 parent ef8b16d commit c7bf120

File tree

6 files changed

+101
-29
lines changed

6 files changed

+101
-29
lines changed

src/karta/config/utils.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -459,18 +459,42 @@ def isMatching():
459459
return matching_mode
460460

461461
def addDisassembler(name, path):
462+
"""Add an installation of a dissasembler.
463+
464+
Args:
465+
name (str): name of the installation file
466+
path (str): directory of the disassembler installtion
467+
"""
462468
with open(os.path.join(CONFIG_DIR, name), "w") as f:
463469
f.write(path)
464470

465471
def disassemblerInstallationExists(name):
472+
"""Check whether there is an existing installation with the filename.
473+
474+
Args:
475+
name (str): filename of the installtion to check
476+
477+
Return Value:
478+
return true if such installtion exists
479+
"""
466480
return os.path.exists(os.path.join(CONFIG_DIR, name))
467481

468482
def getDisassembler(name):
483+
"""Get directory of disassembler from configuration by it's configuration file name.
484+
485+
Args:
486+
name (str): name of the disassembler to search for
487+
"""
469488
if disassemblerInstallationExists(name):
470489
with open(os.path.join(CONFIG_DIR, name), "r") as f:
471490
return f.read()
472491

473492
def setDefaultDisassembler(name):
493+
"""Set the default disassembler in the configuration file.
494+
495+
Args:
496+
name (str): name of the file that contains the default disassembler to use.
497+
"""
474498
with open(os.path.join(CONFIG_DIR, DEFAULT_DISASSEMBLER), "w") as f:
475499
if os.path.isfile(os.path.join(CONFIG_DIR, name)):
476500
f.write(name)

src/karta/disassembler/IDA/ida_cmd_api.py

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ def name():
3333

3434
# Overridden base function
3535
async def createDatabase(self, binary_file, is_windows):
36-
"""Create a database file for the given binary file, compiled to windows or linux as specified.
36+
"""Create a database file asynchonously for the given binary file , compiled to windows or linux as specified.
3737
3838
Args:
3939
binary_file (path): path to the input binary (*.o / *.obj) file
@@ -56,7 +56,7 @@ async def createDatabase(self, binary_file, is_windows):
5656

5757
# Overridden base function
5858
async def executeScript(self, database, script):
59-
"""Execute the given script over the given database file that was created earlier.
59+
"""Execute the given script asynchonously over the given database file that was created earlier.
6060
6161
Args:
6262
database (path): path to a database file created by the same program
@@ -66,9 +66,24 @@ async def executeScript(self, database, script):
6666
await process.wait()
6767

6868
def isSupported(self, feature_name):
69+
"""Check if feature is enabled.
70+
71+
Args:
72+
feature_name (str): name of the feature to check if enabled
73+
74+
Return Value:
75+
returns whether the current class has a member name "feature_name"
76+
"""
6977
return hasattr(self, feature_name)
7078

7179
async def createAndExecute(self, binary_file, is_windows, script):
80+
"""Execute the given script over the given database asynchonously without closing it first.
81+
82+
Args:
83+
binary_file (str): filename of the binary to analyze
84+
is_windows (bool): whether the file is a windows compiled file or linux compiled file
85+
script (str): filename of the script to use on the binary in ida
86+
"""
7287
type = "elf" if not is_windows else "coff"
7388

7489
if not hasattr(self, "is64"):
@@ -79,6 +94,12 @@ async def createAndExecute(self, binary_file, is_windows, script):
7994
await process.wait()
8095

8196
def decideArchitecureChoices(self, binary_file, is_windows):
97+
"""Automate deciding whether to send the files to ida64 or ida.
98+
99+
Args:
100+
binary_file (str): filename of the file to be a test case for analysis
101+
is_windows (bool): whether the test file is a linux or windows binary
102+
"""
82103
# machine type header of pe
83104
# specified in that order, amd64, arm64, ia64, loongarch64, riscv64
84105
ARCH64PE = [b"\x64\x86", b"\x64\xaa", b"\x00\x02", b"\x64\x62", b"\x64\x50"]

src/karta/disassembler/disas_api.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -553,7 +553,7 @@ def name():
553553
raise NotImplementedError("Subclasses should implement this!")
554554

555555
async def createDatabase(self, binary_file, is_windows):
556-
"""Create a database file for the given binary file, compiled to windows or linux as specified.
556+
"""Create a database file asynchonously for the given binary file, compiled to windows or linux as specified.
557557
558558
Args:
559559
binary_file (path): path to the input binary (*.o / *.obj) file
@@ -565,7 +565,7 @@ async def createDatabase(self, binary_file, is_windows):
565565
raise NotImplementedError("Subclasses should implement this!")
566566

567567
async def executeScript(self, database, script):
568-
"""Execute the given script over the given database file that was created earlier.
568+
"""Execute the given script asynchonously over the given database file that was created earlier.
569569
570570
Args:
571571
database (path): path to a database file created by the same program
@@ -574,6 +574,11 @@ async def executeScript(self, database, script):
574574
raise NotImplementedError("Subclasses should implement this!")
575575

576576
def isSupported(self, feature_name):
577+
"""Allow script to query whether a feature is enabled in it's disas_api.
578+
579+
Return Value:
580+
False, no featue is supported on this Abstract class
581+
"""
577582
return False
578583

579584
class DisasVerifier(object):

src/karta/installers/common_installer.py

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,8 @@
44
from ..config.utils import addDisassembler, getDisassembler, setDefaultDisassembler
55

66

7-
def common_locations():
8-
"""
9-
Gets a list of common places where a disassembler may be installed
10-
"""
7+
def commonLocations():
8+
"""Get a list of common places where a disassembler may be installed on any os."""
119
location_list = list()
1210
# based on the operating system installation location may vary
1311
system_lower = platform.system().lower()
@@ -30,18 +28,21 @@ def common_locations():
3028
return location_list
3129

3230

33-
def detect_installation(pattern, installation_file):
34-
"""
35-
If already installed get the installation path
36-
Detect installation of a disassembler by a regex provided by its specific installer
37-
Save it into a file so you may use it as a default
38-
If its not in any of the common locations ask the user to enter it
31+
def detectInstallation(pattern, installation_file):
32+
"""Detect a disassembler's installation by regex, if not found get it with input.
33+
34+
Args:
35+
pattern (re.Pattern): pattern to detect an installation
36+
installation_file (str): name of the file to save the disassembler name in
37+
38+
Return Value:
39+
Directory of the disassembler file
3940
"""
4041
disassembler = getDisassembler(installation_file)
4142
if disassembler is not None:
4243
return disassembler
4344

44-
for location in common_locations():
45+
for location in commonLocations():
4546
for directory in next(os.walk(location))[1]:
4647
if pattern.match(directory):
4748
install_directory = os.path.join(location, directory)
@@ -59,5 +60,6 @@ def detect_installation(pattern, installation_file):
5960
exit(0)
6061

6162

62-
def set_default_disassembler(disassembler_name):
63+
def commonSetDefaultDisassembler(disassembler_name):
64+
"""Call config utils setDefaultDisassembler function."""
6365
setDefaultDisassembler(disassembler_name)

src/karta/installers/ida_installer.py

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,27 @@
22
import re
33
from shutil import copyfile
44

5-
from .common_installer import detect_installation, set_default_disassembler
5+
from .common_installer import detectInstallation, commonSetDefaultDisassembler
66

77

88
disassembler_name = "ida_path"
99

10-
def detect_ida(save_file):
11-
"""
12-
find where ida is installed by this regex, should work for both windows and linux
10+
def detectIda(save_file):
11+
"""Find where ida is installed by this regex, should work for both windows and linux.
12+
13+
Args:
14+
save_file (str): name of the file which will save the path to the disassembler directory
15+
16+
Return Value:
17+
Installation folder for the ida pro disassembler
1318
"""
1419
pattern = re.compile("ida( pro )?-?\d\.\d", re.IGNORECASE)
15-
return detect_installation(pattern, save_file)
20+
return detectInstallation(pattern, save_file)
1621

1722
def main():
18-
"""
19-
detect ida copy library files into its plugins directory and add the plugin to be run on start
20-
"""
21-
path = detect_ida(disassembler_name)
22-
set_default_disassembler(disassembler_name)
23+
"""Detect ida copy plugin file into its plugins directory."""
24+
path = detectIda(disassembler_name)
25+
commonSetDefaultDisassembler(disassembler_name)
2326
src_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), '..')
2427
ida_plugin = os.path.join(src_dir, "plugins", "ida_plugin.py")
2528
plugin_dst = os.path.join(path, "plugins", "ida_karta.py")

src/karta/karta_analyze_src.py

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ def locateFiles(bin_dir, file_list, suffix):
4848
yield path.abspath(path.join(root, file)), file
4949

5050
async def analyzeFile(full_file_path, is_windows):
51-
"""Analyze a single file using analyzer script.
51+
"""Analyze a single file asynchonously using analyzer script.
5252
5353
Args:
5454
full_file_path (str): full path to the specific (*.obj / *.o) file
@@ -61,6 +61,16 @@ async def analyzeFile(full_file_path, is_windows):
6161
await disas_cmd.executeScript(database_path, SCRIPT_PATH)
6262

6363
async def processFile(full_file_path, is_windows, compiled_file, progress_bar, prompter, semaphore):
64+
"""Analyze a file asynchonously using a disassembler and parse the file stats.
65+
66+
Args:
67+
full_file_path (str): full path to the specific (*.obj / *.o) file
68+
is_windows (bool): True iff a windows compilation (*.obj or *.o)
69+
compiled_file (str): file name of the compiled_file
70+
progress_bar (progressBar): progress bar to update once file processing is finished
71+
prompter (prompter): notify the user when an error occured
72+
semaphore (semaphore): release it when the disassembler finished processing our file
73+
"""
6474
# run the analsys on the files in an asynchrnous way
6575
prompter.debug(f"{full_file_path} - {compiled_file}")
6676
if progress_bar is None:
@@ -261,7 +271,14 @@ async def analyzeLibrary(config_name, bin_dirs, compiled_ars, concurrency, promp
261271
prompter.info(f"Anchor to function ratio is: {len(anchors_list)}/{len(src_functions_list)}")
262272
prompter.removeIndent()
263273

264-
def verify_archives_and_objects(using_archives, couples, prompter):
274+
def verifyArchivesAndObjects(using_archives, couples, prompter):
275+
"""Verify that the archive and object files karta processes are valid.
276+
277+
Args:
278+
using_archives (bool): is karta analyzing object files only or library files too
279+
couples (list): couples of dir and lib files or only bin dirs according to the using_archives parameter
280+
prompter (prompter): prompter to notify the user if any error occures
281+
"""
265282
bin_dirs = []
266283
archive_paths = []
267284
error_occured = False
@@ -333,7 +350,7 @@ def main(args=None):
333350
if len(couples) % 2 != 0:
334351
parser.error("Odd length in list of dir,archive couples, should be: [(directory, archive name), ...]")
335352

336-
paths = verify_archives_and_objects(using_archives, couples, prompter)
353+
paths = verifyArchivesAndObjects(using_archives, couples, prompter)
337354

338355
if paths is None:
339356
return

0 commit comments

Comments
 (0)