@@ -988,8 +988,6 @@ def perc(v: float) -> str:
988988 exit (0 )
989989
990990
991-
992-
993991def report_buffer_bounds (args : argparse .Namespace ) -> NoReturn :
994992
995993 # arguments
@@ -1122,3 +1120,84 @@ def write_json_result(
11221120 reverse = True ):
11231121 print (name .ljust (24 ) + str (count ).rjust (5 ))
11241122 exit (0 )
1123+
1124+
1125+ def report_patch_candidates (args : argparse .Namespace ) -> NoReturn :
1126+
1127+ # arguments
1128+ xname = args .xname
1129+ xoutput : Optional [str ] = args .output
1130+ xjson : bool = args .json
1131+ xverbose : bool = args .verbose
1132+ xtargets : List [str ] = args .targets
1133+ loglevel : str = args .loglevel
1134+ logfilename : Optional [str ] = args .logfilename
1135+ logfilemode : str = args .logfilemode
1136+
1137+ try :
1138+ (path , xfile ) = UC .get_path_filename (xname )
1139+ UF .check_analysis_results (path , xfile )
1140+ except UF .CHBError as e :
1141+ print (str (e .wrap ()))
1142+ exit (1 )
1143+
1144+ UC .set_logging (
1145+ loglevel ,
1146+ path ,
1147+ logfilename = logfilename ,
1148+ mode = logfilemode ,
1149+ msg = "report_patch_candidates invoked" )
1150+
1151+ xinfo = XI .XInfo ()
1152+ xinfo .load (path , xfile )
1153+
1154+ app = UC .get_app (path , xfile , xinfo )
1155+
1156+ n_calls : int = 0
1157+ libcalls = LibraryCallCallsites ()
1158+
1159+ for (faddr , blocks ) in app .call_instructions ().items ():
1160+ fn = app .function (faddr )
1161+
1162+ for (baddr , instrs ) in blocks .items ():
1163+ for instr in instrs :
1164+ n_calls += 1
1165+ calltgt = instr .call_target
1166+ if calltgt .is_so_target and calltgt .name in xtargets :
1167+ libcalls .add_library_callsite (faddr , instr )
1168+
1169+ print ("Number of calls: " + str (n_calls ))
1170+
1171+ patchcallsites = libcalls .patch_callsites ()
1172+
1173+ for pc in sorted (patchcallsites , key = lambda pc :pc .faddr ):
1174+ instr = cast ("ARMInstruction" , pc .instr )
1175+ dstarg = pc .dstarg
1176+ if dstarg is None :
1177+ chklogger .logger .warning (
1178+ "No expression found for destination argument: %s" ,
1179+ str (instr ))
1180+ continue
1181+ dstoffset = dstarg .stack_address_offset ()
1182+ fn = instr .armfunction
1183+ stackframe = fn .stackframe
1184+ stackbuffer = stackframe .get_stack_buffer (dstoffset )
1185+ if stackbuffer is None :
1186+ chklogger .logger .warning (
1187+ "No stackbuffer found for %s at offset %s" ,
1188+ str (instr ), str (dstoffset ))
1189+ continue
1190+ buffersize = stackbuffer .size
1191+
1192+ print (" " + pc .instr .iaddr + " " + pc .instr .annotation )
1193+ print (" - faddr: " + pc .faddr )
1194+ print (" - iaddr: " + pc .instr .iaddr )
1195+ print (" - target function: " + str (pc .summary .name ))
1196+ print (" - stack offset: " + str (dstoffset ))
1197+ print (" - length argument: " + str (pc .lenarg ))
1198+ print (" - buffersize: " + str (buffersize ))
1199+ print ("" )
1200+
1201+ print ("Number of patch callsites: " + str (len (patchcallsites )))
1202+
1203+ exit (0 )
0 commit comments