@@ -52,24 +52,41 @@ A simple usage looks like the following:
5252
5353``` python
5454import logging
55+
56+ from crackers.crackers import DecisionResult
57+ from crackers.jingle import ModeledBlock, State
58+
5559logging.basicConfig(level = logging.INFO )
5660
57- from z3 import BoolRef, BoolVal
61+ from z3 import BoolRef, BoolVal, simplify
5862
59- from crackers import State, ModeledBlock
60- from crackers.config import MetaConfig, LibraryConfig, SleighConfig,
61- ReferenceProgramConfig, SynthesisConfig, ConstraintConfig, CrackersConfig
62- from crackers.config.constraint import RegisterValuation,
63- RegisterStringValuation, MemoryValuation, PointerRange,
64- CustomStateConstraint, CustomTransitionConstraint, PointerRangeRole
63+ from crackers.config import (
64+ MetaConfig,
65+ LibraryConfig,
66+ SleighConfig,
67+ ReferenceProgramConfig,
68+ SynthesisConfig,
69+ ConstraintConfig,
70+ CrackersConfig,
71+ )
72+ from crackers.config.constraint import (
73+ RegisterValuation,
74+ RegisterStringValuation,
75+ MemoryValuation,
76+ PointerRange,
77+ CustomStateConstraint,
78+ CustomTransitionConstraint,
79+ PointerRangeRole,
80+ )
6581from crackers.config.log_level import LogLevel
6682from crackers.config.synthesis import SynthesisStrategy
6783
84+
6885# Custom state constraint example
6986def my_constraint (s : State, _addr : int ) -> BoolRef:
7087 rdi = s.read_register(" RDI" )
7188 rcx = s.read_register(" RCX" )
72- return rdi == (rcx ^ 0x 5a5a5a5a5a5a5a5a )
89+ return rdi == (rcx ^ 0x 5A5A5A5A5A5A5A5A )
7390
7491
7592# Custom transition constraint example
@@ -79,29 +96,53 @@ def my_transition_constraint(block: ModeledBlock) -> BoolRef:
7996
8097
8198meta = MetaConfig(log_level = LogLevel.INFO , seed = 42 )
82- library = LibraryConfig(max_gadget_length = 8 , path = " libz.so.1" , sample_size = None ,
83- base_address = None )
99+ library = LibraryConfig(
100+ max_gadget_length = 8 , path = " libz.so.1" , sample_size = None , base_address = None
101+ )
84102sleigh = SleighConfig(ghidra_path = " /Applications/ghidra" )
85- reference_program = ReferenceProgramConfig(path = " sample.o" , max_instructions = 8 , base_address = library.base_address)
86- synthesis = SynthesisConfig(strategy = SynthesisStrategy.SAT , max_candidates_per_slot = 200 , parallel = 8 , combine_instructions = True )
103+ reference_program = ReferenceProgramConfig(
104+ path = " sample.o" , max_instructions = 8 , base_address = library.base_address
105+ )
106+ synthesis = SynthesisConfig(
107+ strategy = SynthesisStrategy.SAT ,
108+ max_candidates_per_slot = 200 ,
109+ parallel = 8 ,
110+ combine_instructions = True ,
111+ )
112+
87113constraint = ConstraintConfig(
88114 precondition = [
89- RegisterValuation(name = " rdi " , value = 0x deadbeef ),
115+ RegisterValuation(name = " RDI " , value = 0x DEADBEEF ),
90116 MemoryValuation(space = " ram" , address = 0x 1000 , size = 4 , value = 0x 41 ),
91- RegisterStringValuation(reg = " rsi " , value = " /bin/sh" ),
92- CustomStateConstraint( code = my_constraint)
117+ RegisterStringValuation(reg = " RSI " , value = " /bin/sh" ),
118+ CustomStateConstraint.from_callable( my_constraint),
93119 ],
94120 postcondition = [
95- RegisterValuation(name = " rax" , value = 0x 1337 ),
96- CustomStateConstraint(code = my_constraint)
121+ RegisterValuation(name = " RBX" , value = 0x 1337 ),
97122 ],
98- transition = [
99- PointerRange(role = PointerRangeRole.READ , min = 0x 2000 , max = 0x 3000 ),
100- CustomTransitionConstraint(code = my_transition_constraint)
101- ]
123+ pointer = [
124+ PointerRange(role = PointerRangeRole.READ , min = 0x 80_0000 , max = 0x 80_8000 ),
125+ CustomTransitionConstraint.from_callable(my_transition_constraint),
126+ ],
127+ )
128+ config = CrackersConfig(
129+ meta = meta,
130+ library = library,
131+ sleigh = sleigh,
132+ specification = reference_program,
133+ synthesis = synthesis,
134+ constraint = constraint,
102135)
103- config = CrackersConfig(meta = meta, library = library, sleigh = sleigh, specification = reference_program, synthesis = synthesis, constraint = constraint)
104- config.run()
136+ r = config.run()
137+ match r:
138+ case DecisionResult.AssignmentFound(a):
139+ for g in a.gadgets():
140+ for i in g.instructions:
141+ print (i.disassembly)
142+ print ()
143+ for name, bv in a.input_summary(True ):
144+ print (f " { name} = { simplify(bv)} " )
145+
105146```
106147
107148### Rust CLI
0 commit comments