@@ -43,6 +43,8 @@ class AnalysisConfig:
4343 force_reanalyze: Force re-analysis even if already completed
4444 thunk_depth: Maximum depth for thunk resolution
4545 min_conf: Minimum confidence for function call validation
46+ loop_analysis_max_depth: Maximum recursion depth for loop analysis graph traversal
47+ max_xrefs: Maximum xrefs serialized per JSON xref field
4648
4749 # Computed file metadata
4850 file_hashes: MD5/SHA256 hashes of the input file
@@ -76,6 +78,8 @@ class AnalysisConfig:
7678 force_reanalyze : bool = False
7779 thunk_depth : Optional [int ] = None
7880 min_conf : Optional [int ] = None
81+ loop_analysis_max_depth : Optional [int ] = None
82+ max_xrefs : Optional [int ] = None
7983
8084 # Advanced analysis options
8185 use_interprocedural_analysis : bool = True # Enable deeper indirect call resolution
@@ -134,6 +138,16 @@ def __post_init__(self):
134138 raise ValueError (f"min_conf must be a number, got: { type (self .min_conf )} " )
135139 if not 10 <= self .min_conf <= 100 :
136140 raise ValueError (f"min_conf must be between 10 and 100, got: { self .min_conf } " )
141+
142+ if self .loop_analysis_max_depth is not None :
143+ if not isinstance (self .loop_analysis_max_depth , int ) or self .loop_analysis_max_depth < 1 :
144+ raise ValueError (
145+ f"loop_analysis_max_depth must be a positive integer, got: { self .loop_analysis_max_depth } "
146+ )
147+
148+ if self .max_xrefs is not None :
149+ if not isinstance (self .max_xrefs , int ) or self .max_xrefs < 1 :
150+ raise ValueError (f"max_xrefs must be a positive integer, got: { self .max_xrefs } " )
137151
138152 # Validate boolean flags
139153 bool_fields = [
@@ -237,6 +251,24 @@ def from_ida_args(cls, args: dict, input_file: str) -> 'AnalysisConfig':
237251 raise ValueError (f"min_conf must be 10-100, got: { min_conf } " )
238252 except (TypeError , ValueError ) as e :
239253 raise ValueError (f"Invalid min_conf: { e } " )
254+
255+ loop_analysis_max_depth = args .get ('loop_analysis_max_depth' )
256+ if loop_analysis_max_depth is not None :
257+ try :
258+ loop_analysis_max_depth = int (loop_analysis_max_depth )
259+ if loop_analysis_max_depth < 1 :
260+ raise ValueError (f"loop_analysis_max_depth must be positive, got: { loop_analysis_max_depth } " )
261+ except (TypeError , ValueError ) as e :
262+ raise ValueError (f"Invalid loop_analysis_max_depth: { e } " )
263+
264+ max_xrefs = args .get ('max_xrefs' )
265+ if max_xrefs is not None :
266+ try :
267+ max_xrefs = int (max_xrefs )
268+ if max_xrefs < 1 :
269+ raise ValueError (f"max_xrefs must be positive, got: { max_xrefs } " )
270+ except (TypeError , ValueError ) as e :
271+ raise ValueError (f"Invalid max_xrefs: { e } " )
240272
241273 return cls (
242274 sqlite_db_path = sqlite_db_path ,
@@ -258,6 +290,8 @@ def from_ida_args(cls, args: dict, input_file: str) -> 'AnalysisConfig':
258290 use_interprocedural_analysis = bool (args .get ('use_interprocedural_analysis' , True )),
259291 thunk_depth = thunk_depth ,
260292 min_conf = min_conf ,
293+ loop_analysis_max_depth = loop_analysis_max_depth ,
294+ max_xrefs = max_xrefs ,
261295 )
262296
263297 def to_dict (self ) -> dict :
@@ -286,6 +320,8 @@ def to_dict(self) -> dict:
286320 'use_interprocedural_analysis' : self .use_interprocedural_analysis ,
287321 'thunk_depth' : self .thunk_depth ,
288322 'min_conf' : self .min_conf ,
323+ 'loop_analysis_max_depth' : self .loop_analysis_max_depth ,
324+ 'max_xrefs' : self .max_xrefs ,
289325 }
290326
291327 def to_analysis_flags_json (self ) -> str :
@@ -318,5 +354,7 @@ def get_analysis_args_dict(self) -> dict:
318354 'force_reanalyze' : self .force_reanalyze ,
319355 'generate_cpp' : self .generate_cpp ,
320356 'generate_asm' : self .generate_asm ,
357+ 'loop_analysis_max_depth' : self .loop_analysis_max_depth ,
358+ 'max_xrefs' : self .max_xrefs ,
321359 }
322360
0 commit comments