scientific-method-engine 0.9.0__tar.gz → 0.9.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {scientific_method_engine-0.9.0 → scientific_method_engine-0.9.1}/PKG-INFO +1 -1
- {scientific_method_engine-0.9.0 → scientific_method_engine-0.9.1}/pyproject.toml +1 -1
- {scientific_method_engine-0.9.0 → scientific_method_engine-0.9.1}/src/scientific_method_engine/x86/trace.py +5 -2
- {scientific_method_engine-0.9.0 → scientific_method_engine-0.9.1}/tests/test_table_continuations.py +49 -0
- {scientific_method_engine-0.9.0 → scientific_method_engine-0.9.1}/.gitignore +0 -0
- {scientific_method_engine-0.9.0 → scientific_method_engine-0.9.1}/LICENSE +0 -0
- {scientific_method_engine-0.9.0 → scientific_method_engine-0.9.1}/README.md +0 -0
- {scientific_method_engine-0.9.0 → scientific_method_engine-0.9.1}/src/scientific_method_engine/__init__.py +0 -0
- {scientific_method_engine-0.9.0 → scientific_method_engine-0.9.1}/src/scientific_method_engine/__main__.py +0 -0
- {scientific_method_engine-0.9.0 → scientific_method_engine-0.9.1}/src/scientific_method_engine/cli.py +0 -0
- {scientific_method_engine-0.9.0 → scientific_method_engine-0.9.1}/src/scientific_method_engine/ghidra/ClearNoReturnFunctions.java +0 -0
- {scientific_method_engine-0.9.0 → scientific_method_engine-0.9.1}/src/scientific_method_engine/ghidra/CreateFunctions.java +0 -0
- {scientific_method_engine-0.9.0 → scientific_method_engine-0.9.1}/src/scientific_method_engine/ghidra/ExportBoundedFlow.java +0 -0
- {scientific_method_engine-0.9.0 → scientific_method_engine-0.9.1}/src/scientific_method_engine/ghidra/ExportCallEdges.java +0 -0
- {scientific_method_engine-0.9.0 → scientific_method_engine-0.9.1}/src/scientific_method_engine/ghidra/ExportFunctionFingerprints.java +0 -0
- {scientific_method_engine-0.9.0 → scientific_method_engine-0.9.1}/src/scientific_method_engine/ghidra/ExportFunctionInventory.java +0 -0
- {scientific_method_engine-0.9.0 → scientific_method_engine-0.9.1}/src/scientific_method_engine/ghidra/MergeFallThroughFragment.java +0 -0
- {scientific_method_engine-0.9.0 → scientific_method_engine-0.9.1}/src/scientific_method_engine/ghidra/RecoverCitedFunctions.java +0 -0
- {scientific_method_engine-0.9.0 → scientific_method_engine-0.9.1}/src/scientific_method_engine/ghidra/RepairReturningCallers.java +0 -0
- {scientific_method_engine-0.9.0 → scientific_method_engine-0.9.1}/src/scientific_method_engine/ghidra/ReportCallArguments.java +0 -0
- {scientific_method_engine-0.9.0 → scientific_method_engine-0.9.1}/src/scientific_method_engine/ghidra/ReportCallPaths.java +0 -0
- {scientific_method_engine-0.9.0 → scientific_method_engine-0.9.1}/src/scientific_method_engine/ghidra/ReportCallSitesWithScalars.java +0 -0
- {scientific_method_engine-0.9.0 → scientific_method_engine-0.9.1}/src/scientific_method_engine/ghidra/ReportCallsToRange.java +0 -0
- {scientific_method_engine-0.9.0 → scientific_method_engine-0.9.1}/src/scientific_method_engine/ghidra/ReportConstantFirstArgumentCalls.java +0 -0
- {scientific_method_engine-0.9.0 → scientific_method_engine-0.9.1}/src/scientific_method_engine/ghidra/ReportDataBytes.java +0 -0
- {scientific_method_engine-0.9.0 → scientific_method_engine-0.9.1}/src/scientific_method_engine/ghidra/ReportDecompileMatches.java +0 -0
- {scientific_method_engine-0.9.0 → scientific_method_engine-0.9.1}/src/scientific_method_engine/ghidra/ReportDecompileWindow.java +0 -0
- {scientific_method_engine-0.9.0 → scientific_method_engine-0.9.1}/src/scientific_method_engine/ghidra/ReportFilePatternInMemory.java +0 -0
- {scientific_method_engine-0.9.0 → scientific_method_engine-0.9.1}/src/scientific_method_engine/ghidra/ReportFirstArgumentCallSummary.java +0 -0
- {scientific_method_engine-0.9.0 → scientific_method_engine-0.9.1}/src/scientific_method_engine/ghidra/ReportFunctionScalarConstants.java +0 -0
- {scientific_method_engine-0.9.0 → scientific_method_engine-0.9.1}/src/scientific_method_engine/ghidra/ReportFunctionSummary.java +0 -0
- {scientific_method_engine-0.9.0 → scientific_method_engine-0.9.1}/src/scientific_method_engine/ghidra/ReportInstructionContext.java +0 -0
- {scientific_method_engine-0.9.0 → scientific_method_engine-0.9.1}/src/scientific_method_engine/ghidra/ReportInstructionWindow.java +0 -0
- {scientific_method_engine-0.9.0 → scientific_method_engine-0.9.1}/src/scientific_method_engine/ghidra/ReportMemoryBlockForFileOffset.java +0 -0
- {scientific_method_engine-0.9.0 → scientific_method_engine-0.9.1}/src/scientific_method_engine/ghidra/ReportMemoryBlocks.java +0 -0
- {scientific_method_engine-0.9.0 → scientific_method_engine-0.9.1}/src/scientific_method_engine/ghidra/ReportRandomnessCandidates.java +0 -0
- {scientific_method_engine-0.9.0 → scientific_method_engine-0.9.1}/src/scientific_method_engine/ghidra/ReportReferences.java +0 -0
- {scientific_method_engine-0.9.0 → scientific_method_engine-0.9.1}/src/scientific_method_engine/ghidra/ReportScalarConstants.java +0 -0
- {scientific_method_engine-0.9.0 → scientific_method_engine-0.9.1}/src/scientific_method_engine/ghidra/ReportStringReferences.java +0 -0
- {scientific_method_engine-0.9.0 → scientific_method_engine-0.9.1}/src/scientific_method_engine/ghidra/ReportSymbolReferences.java +0 -0
- {scientific_method_engine-0.9.0 → scientific_method_engine-0.9.1}/src/scientific_method_engine/x86/__init__.py +0 -0
- {scientific_method_engine-0.9.0 → scientific_method_engine-0.9.1}/src/scientific_method_engine/x86/dispatch.py +0 -0
- {scientific_method_engine-0.9.0 → scientific_method_engine-0.9.1}/src/scientific_method_engine/x86/effect_order.py +0 -0
- {scientific_method_engine-0.9.0 → scientific_method_engine-0.9.1}/src/scientific_method_engine/x86/image.py +0 -0
- {scientific_method_engine-0.9.0 → scientific_method_engine-0.9.1}/src/scientific_method_engine/x86/machine.py +0 -0
- {scientific_method_engine-0.9.0 → scientific_method_engine-0.9.1}/src/scientific_method_engine/x86/pcode.py +0 -0
- {scientific_method_engine-0.9.0 → scientific_method_engine-0.9.1}/src/scientific_method_engine/x86/pcode_backend.py +0 -0
- {scientific_method_engine-0.9.0 → scientific_method_engine-0.9.1}/src/scientific_method_engine/x86/pe.py +0 -0
- {scientific_method_engine-0.9.0 → scientific_method_engine-0.9.1}/src/scientific_method_engine/x86/reports.py +0 -0
- {scientific_method_engine-0.9.0 → scientific_method_engine-0.9.1}/src/scientific_method_engine/x86/result_flow.py +0 -0
- {scientific_method_engine-0.9.0 → scientific_method_engine-0.9.1}/src/scientific_method_engine/x86/values.py +0 -0
- {scientific_method_engine-0.9.0 → scientific_method_engine-0.9.1}/tests/oracle.py +0 -0
- {scientific_method_engine-0.9.0 → scientific_method_engine-0.9.1}/tests/test_dispatch.py +0 -0
- {scientific_method_engine-0.9.0 → scientific_method_engine-0.9.1}/tests/test_effect_order.py +0 -0
- {scientific_method_engine-0.9.0 → scientific_method_engine-0.9.1}/tests/test_nested_frame_request.py +0 -0
- {scientific_method_engine-0.9.0 → scientific_method_engine-0.9.1}/tests/test_oracle.py +0 -0
- {scientific_method_engine-0.9.0 → scientific_method_engine-0.9.1}/tests/test_pe.py +0 -0
- {scientific_method_engine-0.9.0 → scientific_method_engine-0.9.1}/tests/test_x86.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: scientific-method-engine
|
|
3
|
-
Version: 0.9.
|
|
3
|
+
Version: 0.9.1
|
|
4
4
|
Summary: Bounded instruction-derived x86 evidence reports for segmented MZ/FBOV and PE32/i386 code.
|
|
5
5
|
Project-URL: Source, https://github.com/kibertoad/refurbished-dinosaurs-toolkit/tree/main/packages/scientific-method-engine
|
|
6
6
|
Author: kibertoad
|
|
@@ -5,7 +5,7 @@ build-backend = "hatchling.build"
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "scientific-method-engine"
|
|
7
7
|
# The release workflow writes the published version from the package's release tag.
|
|
8
|
-
version = "0.9.
|
|
8
|
+
version = "0.9.1"
|
|
9
9
|
description = "Bounded instruction-derived x86 evidence reports for segmented MZ/FBOV and PE32/i386 code."
|
|
10
10
|
readme = "README.md"
|
|
11
11
|
requires-python = ">=3.12"
|
|
@@ -305,8 +305,11 @@ def trace(image, config, continue_declared_jumps=True):
|
|
|
305
305
|
if boundary_budget < 1:
|
|
306
306
|
global_gaps.append({"site": s.at, "reason": "conditional table boundary instruction limit"})
|
|
307
307
|
return
|
|
308
|
-
seen, walk_gaps, _,
|
|
309
|
-
|
|
308
|
+
seen, walk_gaps, _, _, contested = walk(image, [root_entry], boundary_budget)
|
|
309
|
+
# walk drops rejected overlapping starts and contested instructions from seen,
|
|
310
|
+
# but it decoded them, so they are charged with the established ones.
|
|
311
|
+
overlapping = sum(g["reason"] == OVERLAP_REASON for g in walk_gaps)
|
|
312
|
+
boundary_budget -= max(1, len(seen) + len(contested) + overlapping)
|
|
310
313
|
# A truncated walk never saw the instructions that could contest a target start.
|
|
311
314
|
if any(g["reason"] == "instruction limit" for g in walk_gaps):
|
|
312
315
|
seen = {}
|
{scientific_method_engine-0.9.0 → scientific_method_engine-0.9.1}/tests/test_table_continuations.py
RENAMED
|
@@ -141,6 +141,55 @@ class TableContinuationTests(unittest.TestCase):
|
|
|
141
141
|
self.assertFalse(r["declaredContinuationPaths"])
|
|
142
142
|
self.assertTrue(any("boundary" in g["reason"] for g in r["gaps"]))
|
|
143
143
|
|
|
144
|
+
def test_boundary_budget_counts_only_decoded_instructions(self):
|
|
145
|
+
# Two functions each end in a declared table jump and branch once outside every region.
|
|
146
|
+
# Their boundary walks decode four instructions apiece and leave most region bytes uncovered.
|
|
147
|
+
data = bytearray([0x90] * 56)
|
|
148
|
+
data[0:6] = bytes.fromhex("72 06 e8 0b 00 c3")
|
|
149
|
+
data[8:12] = bytes.fromhex("e8 15 00 c3")
|
|
150
|
+
data[16:20] = bytes.fromhex("74 7f ff e3")
|
|
151
|
+
data[22:24] = bytes.fromhex("c3 c3")
|
|
152
|
+
data[32:36] = bytes.fromhex("74 7f ff e3")
|
|
153
|
+
data[38:40] = bytes.fromhex("c3 c3")
|
|
154
|
+
data[48:56] = bytes.fromhex("16 00 17 00 26 00 27 00")
|
|
155
|
+
jumps = [{"site": site, "exhaustive": True, "evidence": "constructed BX consumer",
|
|
156
|
+
"table": {"start": table, "count": 2, "stride": 2, "evidence": "constructed words"}}
|
|
157
|
+
for site, table in ((18, 48), (34, 52))]
|
|
158
|
+
config = {"entry": 0, "indirectJumps": jumps,
|
|
159
|
+
"regions": [{"name": "code", "start": 0, "end": 48, "segment": 4096, "ip": 0,
|
|
160
|
+
"entries": [0], "evidence": "constructed mappings"}]}
|
|
161
|
+
r = run_report(bytes(data), {**config, "instructionLimit": 8}, "trace")
|
|
162
|
+
self.assertEqual(len(r["declaredContinuationPaths"]), 4)
|
|
163
|
+
self.assertFalse(any("boundary" in g["reason"] for g in r["gaps"]))
|
|
164
|
+
r = run_report(bytes(data), {**config, "instructionLimit": 7}, "trace")
|
|
165
|
+
self.assertEqual(len(r["declaredContinuationPaths"]), 2)
|
|
166
|
+
self.assertTrue(any("boundary" in g["reason"] for g in r["gaps"]))
|
|
167
|
+
|
|
168
|
+
def test_boundary_budget_charges_rejected_overlapping_instructions(self):
|
|
169
|
+
# The function at 32 is walked first. Its side branch calls into its own call
|
|
170
|
+
# (40 e8 ff ff -> 42 inc bx) and returns to 43, so 40, 42 and 43 overlap and 44
|
|
171
|
+
# is reached only through them. The walk decodes eight instructions and establishes four.
|
|
172
|
+
data = bytearray([0x90] * 56)
|
|
173
|
+
data[0:6] = bytes.fromhex("72 06 e8 0b 00 c3")
|
|
174
|
+
data[8:12] = bytes.fromhex("e8 15 00 c3")
|
|
175
|
+
data[16:20] = bytes.fromhex("74 7f ff e3")
|
|
176
|
+
data[22:24] = bytes.fromhex("c3 c3")
|
|
177
|
+
data[32:36] = bytes.fromhex("74 06 ff e3")
|
|
178
|
+
data[38:40] = bytes.fromhex("c3 c3")
|
|
179
|
+
data[40:45] = bytes.fromhex("e8 ff ff c3 c3")
|
|
180
|
+
data[48:56] = bytes.fromhex("16 00 17 00 26 00 27 00")
|
|
181
|
+
jumps = [{"site": site, "exhaustive": True, "evidence": "constructed BX consumer",
|
|
182
|
+
"table": {"start": table, "count": 2, "stride": 2, "evidence": "constructed words"}}
|
|
183
|
+
for site, table in ((18, 48), (34, 52))]
|
|
184
|
+
config = {"entry": 0, "indirectJumps": jumps,
|
|
185
|
+
"regions": [{"name": "code", "start": 0, "end": 48, "segment": 4096, "ip": 0,
|
|
186
|
+
"entries": [0], "evidence": "constructed mappings"}]}
|
|
187
|
+
r = run_report(bytes(data), {**config, "instructionLimit": 12}, "trace")
|
|
188
|
+
self.assertEqual(len(r["declaredContinuationPaths"]), 4)
|
|
189
|
+
r = run_report(bytes(data), {**config, "instructionLimit": 11}, "trace")
|
|
190
|
+
self.assertEqual(len(r["declaredContinuationPaths"]), 2)
|
|
191
|
+
self.assertTrue(any("boundary" in g["reason"] for g in r["gaps"]))
|
|
192
|
+
|
|
144
193
|
def test_field_address_uses_the_table_region_mapping(self):
|
|
145
194
|
data, config = fixture()
|
|
146
195
|
data = bytearray(data)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{scientific_method_engine-0.9.0 → scientific_method_engine-0.9.1}/tests/test_effect_order.py
RENAMED
|
File without changes
|
{scientific_method_engine-0.9.0 → scientific_method_engine-0.9.1}/tests/test_nested_frame_request.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|