Track instruction verification bounds only for matched methods

This commit is contained in:
ZacharyZcR
2026-09-10 22:39:42 +08:00
parent cba375bddf
commit 07c4e5222f
2 changed files with 14 additions and 3 deletions
@@ -175,7 +175,7 @@ class InsnLocator(BaseLocator):
insn_maps = self.insn_maps
buf = self.buf
method_bounds = self.method_bounds.copy()
method_bounds = {}
for off in offsets:
midx = insn_maps.get(off >> 4)
"""
@@ -190,10 +190,10 @@ class InsnLocator(BaseLocator):
# which means there is no possible to backtracking inside one method, so we can update method
# start insn offset once we fullmatch an insn, avoid re-fullmatch from start of method
# bugfix for insn mismatch issue 20260729
if isinstance(midx, int) and InsnLocator.INSN_VERIFY.fullmatch(buf, method_bounds[midx], off):
if isinstance(midx, int) and InsnLocator.INSN_VERIFY.fullmatch(buf, method_bounds.get(midx, self.method_bounds[midx]), off):
ret_table.append(midx)
method_bounds[midx] = off
elif isinstance(midx, list) and InsnLocator.INSN_VERIFY.fullmatch(buf, method_bounds[midx[0]], off):
elif isinstance(midx, list) and InsnLocator.INSN_VERIFY.fullmatch(buf, method_bounds.get(midx[0], self.method_bounds[midx[0]]), off):
ret_table.append(midx)
method_bounds[midx[0]] = off
else:
+11
View File
@@ -24,6 +24,17 @@ class ReferenceTests(unittest.TestCase):
self.assertEqual(len(results), 1)
self.assertEqual(set(results[0]), {0, 1})
def test_repeated_scans_preserve_method_bounds(self):
locator = InsnLocator(DEX.parse(memoryview(make_dex()), 'fixture.dex'))
locator.parse()
original_bounds = dict(locator.method_bounds)
scanner = CodeItemScanner(locator)
for _ in range(2):
query = {'string': {5}}
scanner.scan(query)
self.assertEqual(set(query['string'][0]), {0, 1})
self.assertEqual(locator.method_bounds, original_bounds)
def test_fallback_without_class_data_map_entry(self):
data = bytearray(make_dex())
map_off = struct.unpack_from('<I', data, 52)[0]