Skip to content

Commit 8c2c593

Browse files
committed
CMD: add command to collect md5s from disassembly
1 parent 662eaec commit 8c2c593

File tree

6 files changed

+94
-7
lines changed

6 files changed

+94
-7
lines changed

chb/arm/opcodes/ARMStoreRegister.py

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,10 @@ def is_lhsvar_unknown(self) -> bool:
8585
def is_lhsvar_known(self) -> bool:
8686
return self.xdata.vars_r[1] is not None
8787

88+
@property
89+
def is_xxrtc_known(self) -> bool:
90+
return self.xdata.xprs_r[4] is not None
91+
8892
@property
8993
def vrn(self) -> "XVariable":
9094
return self.var(1, "vrn")
@@ -105,25 +109,30 @@ def xrt(self) -> "XXpr":
105109
def xxrt(self) -> "XXpr":
106110
return self.xpr(3, "xxrt")
107111

112+
@property
113+
def xxrtc(self) -> "XXpr":
114+
return self.xpr(4, "xxrtc")
115+
108116
@property
109117
def xaddr(self) -> "XXpr":
110-
return self.xpr(4, "xaddr")
118+
return self.xpr(5, "xaddr")
111119

112120
@property
113121
def is_address_known(self) -> bool:
114-
return self.xdata.xprs_r[4] is not None
122+
return self.xdata.xprs_r[5] is not None
115123

116124
@property
117125
def xaddr_updated(self) -> "XXpr":
118-
return self.xpr(5, "xaddr_updated")
126+
return self.xpr(6, "xaddr_updated")
119127

120128
@property
121129
def annotation(self) -> str:
122130
wbu = self.writeback_update()
131+
rhs = self.xxrtc if self.is_xxrtc_known else self.xxrt
123132
if self.is_ok or self.is_vmem_known:
124-
assignment = str(self.vmem) + " := " + str(self.xxrt)
133+
assignment = str(self.vmem) + " := " + str(rhs)
125134
elif self.is_vmem_unknown and self.is_address_known:
126-
assignment = "*(" + str(self.xaddr) + ") := " + str(self.xxrt)
135+
assignment = "*(" + str(self.xaddr) + ") := " + str(rhs)
127136
else:
128137
assignment = "Error value"
129138
return self.add_instruction_condition(assignment + wbu)

chb/arm/opcodes/ARMStoreRegisterHalfword.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,10 @@ def xrt(self) -> "XXpr":
7979
def xxrt(self) -> "XXpr":
8080
return self.xpr(3, "xxrt")
8181

82+
@property
83+
def is_xxrt_known(self) -> bool:
84+
return self.xdata.xprs_r[3] is not None
85+
8286
@property
8387
def xaddr(self) -> "XXpr":
8488
return self.xpr(4, "xaddr")
@@ -92,6 +96,8 @@ def annotation(self) -> str:
9296
wbu = self.writeback_update()
9397
if self.is_ok:
9498
assignment = str(self.vmem) + " := " + str(self.xxrt)
99+
elif not self.is_xxrt_known:
100+
assignment = "(*" + str(self.xaddr) + ") := Error value"
95101
elif self.is_vmem_unknown and self.is_address_known:
96102
assignment = "*(" + str(self.xaddr) + ") := " + str(self.xxrt)
97103
else:

chb/cmdline/AnalysisManager.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
#
77
# Copyright (c) 2016-2020 Kestrel Technology LLC
88
# Copyright (c) 2020 Henny Sipma
9-
# Copyright (c) 2021-2023 Aarno Labs LLC
9+
# Copyright (c) 2021-2025 Aarno Labs LLC
1010
#
1111
# Permission is hereby granted, free of charge, to any person obtaining a copy
1212
# of this software and associated documentation files (the "Software"), to deal

chb/cmdline/chkx

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -473,6 +473,12 @@ def parse() -> argparse.Namespace:
473473
"--analyze_all_named",
474474
help="include all functions named in userdata in the analysis",
475475
action="store_true")
476+
analyzecmd.add_argument(
477+
"--analyze_range_entry_points",
478+
help=("include all functions whose address is in the given range and "
479+
+ "listed in the userdata function entry points"),
480+
nargs="*",
481+
default=[])
476482
analyzecmd.add_argument(
477483
"--gc_compact",
478484
type=int,
@@ -574,6 +580,11 @@ def parse() -> argparse.Namespace:
574580
ddatagvars.add_argument("xname", help="name of executable")
575581
ddatagvars.set_defaults(func=UCC.ddata_gvars)
576582

583+
# -- ddata md5s --
584+
ddatamd5s = ddataparsers.add_parser("md5s")
585+
ddatamd5s.add_argument("xname", help="name of executable")
586+
ddatamd5s.set_defaults(func=UCC.ddata_md5s)
587+
577588
# ----------------------------------------------------------------- results --
578589
resultscmd = subparsers.add_parser('results')
579590
resultscmd.set_defaults(func=resultscommand)

chb/cmdline/commandutil.py

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,7 @@ def analyzecmd(args: argparse.Namespace) -> NoReturn:
412412
fns_exclude: List[str] = args.fns_exclude # function hex addresses
413413
fns_include: List[str] = args.fns_include # function hex addresses
414414
analyze_all_named: bool = args.analyze_all_named
415+
analyze_range_entry_points: List[str] = args.analyze_range_entry_points
415416
gc_compact: int = args.gc_compact
416417
construct_all_functions: bool = args.construct_all_functions
417418
show_function_timing: bool = args.show_function_timing
@@ -492,7 +493,21 @@ def analyzecmd(args: argparse.Namespace) -> NoReturn:
492493
if analyze_all_named:
493494
fnnamed_addrs = userhints.rev_function_names().values()
494495
fns_include = fns_include + list(fnnamed_addrs)
495-
chklogger.logger.warning("Include %d functions", len(fns_include))
496+
chklogger.logger.info("Include %d functions", len(fns_include))
497+
498+
if len(analyze_range_entry_points) == 2:
499+
festart = int(analyze_range_entry_points[0], 16)
500+
fefin = int(analyze_range_entry_points[1], 16)
501+
fentrypoints = userhints.function_entry_points()
502+
feincludes: List[str] = []
503+
for fe in fentrypoints:
504+
eint = int(fe, 16)
505+
if eint >= festart and eint <= fefin:
506+
feincludes.append(fe)
507+
fns_include = fns_include + feincludes
508+
chklogger.logger.info(
509+
"Include %d entry point functions in range %s - %s",
510+
len(feincludes), hex(festart), hex(fefin))
496511

497512
am = AnalysisManager(
498513
path,
@@ -2448,3 +2463,36 @@ def ddata_gvars(args: argparse.Namespace) -> NoReturn:
24482463
print("Coverage: " + str(coverage) + " (typed: " + str(count) + ")")
24492464

24502465
exit(0)
2466+
2467+
2468+
def ddata_md5s(args: argparse.Namespace) -> NoReturn:
2469+
2470+
# arguments
2471+
xname: str = str(args.xname)
2472+
2473+
try:
2474+
(path, xfile) = get_path_filename(xname)
2475+
except UF.CHBError as e:
2476+
print(str(e.wrap()))
2477+
exit(1)
2478+
2479+
xinfo = XI.XInfo()
2480+
xinfo.load(path, xfile)
2481+
2482+
app = get_app(path, xfile, xinfo)
2483+
md5s = app.function_md5s
2484+
2485+
result: Dict[str, int] = {}
2486+
2487+
for md5 in md5s.values():
2488+
result.setdefault(md5, 0)
2489+
result[md5] += 1
2490+
2491+
print("Number of functions: " + str(len(md5s)))
2492+
print("Distinct md5s : " + str(len(result)))
2493+
2494+
for (md5, count) in result.items():
2495+
if count > 10:
2496+
print(md5 + ": " + str(count))
2497+
2498+
exit(0)

chb/userdata/UserHints.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1457,6 +1457,14 @@ def rev_function_names(self) -> Dict[str, str]:
14571457
else:
14581458
return {}
14591459

1460+
def function_entry_points(self) -> List[str]:
1461+
if "function-entry-points" in self.astdata:
1462+
entry = cast(FunctionEntryPointsHints,
1463+
self.astdata["function-entry-points"])
1464+
return entry.entrypoints
1465+
else:
1466+
return []
1467+
14601468
def add_hints(self, hints: Dict[str, Any]) -> None:
14611469
"""Process a user provided dictionary with user hint dictionaries.
14621470
@@ -1527,6 +1535,11 @@ def add_hints(self, hints: Dict[str, Any]) -> None:
15271535
self.userdata[tag].update(fepoints)
15281536
else:
15291537
self.userdata[tag] = FunctionEntryPointsHints(fepoints)
1538+
if tag in self.astdata:
1539+
self.astdata[tag].update(fepoints)
1540+
else:
1541+
self.astdata[tag] = FunctionEntryPointsHints(fepoints)
1542+
15301543

15311544
if "function-annotations" in hints:
15321545
tag = "function-annotations"

0 commit comments

Comments
 (0)