@@ -21,7 +21,35 @@ public class ArmLePickledCanaryTest extends PickledCanaryTest {
2121 protected String getCompileInfoRaw () {
2222 return ",\" compile_info\" :[{\" compiled_using_binary\" :[{\" path\" :[\" unknown\" ],\" compiled_at_address\" :[\" 01006420\" ],\" md5\" :[\" unknown\" ]}],\" language_id\" :[\" ARM:LE:32:v8\" ]}],\" pattern_metadata\" :{}}" ;
2323 }
24-
24+
25+ private static final String simplePattern = "`=0x55`\n `&0x0f=0xab`\n `ANY_BYTES{0,4,2}`\n " ;
26+ private static final String stepsForSimplePattern = "{\" type\" :\" BYTE\" ,\" value\" :85},{\" type\" :\" MASKEDBYTE\" ,\" value\" :171,\" mask\" :15},{\" note\" :\" AnyBytesNode Start: 0 End: 4 Interval: 2 From: Token from line #3: Token type: PICKLED_CANARY_COMMAND data: `ANY_BYTES{0,4,2}`\" ,\" min\" :0,\" max\" :4,\" interval\" :2,\" type\" :\" ANYBYTESEQUENCE\" }" ;
27+
28+ private static final String simpleOrPattern = "`=0xAA`\r \n " +
29+ "`START_OR {`\r \n " +
30+ " `=0xBB`\r \n " +
31+ " `=0xCC`\r \n " +
32+ "`} OR {`\r \n " +
33+ " `=0x01`\r \n " +
34+ " `=0x02`\r \n " +
35+ "`} END_OR`" ;
36+ private static final String stepsForSimpleOrPattern = "{\" type\" :\" BYTE\" ,\" value\" :170},{\" dest2\" :5,\" type\" :\" SPLIT\" ,\" dest1\" :2},{\" type\" :\" BYTE\" ,\" value\" :187},{\" type\" :\" BYTE\" ,\" value\" :204},{\" type\" :\" JMP\" ,\" dest\" :7},{\" type\" :\" BYTE\" ,\" value\" :1},{\" type\" :\" BYTE\" ,\" value\" :2}" ;
37+
38+ private static final String simpleMetadataPattern = "`META`\r \n " +
39+ "{ 'foo': 'bar',\r \n " +
40+ " 'baz':'boop'}\r \n " +
41+ "`META_END`" ;
42+ private static final String stepsForSimpleMetadataPattern = "" ;
43+
44+ private static final String simpleNotPattern = "`NOT {`\r \n " +
45+ "`=0xaa`\r \n " +
46+ "`} END_NOT`" ;
47+ private static final String stepsForSimpleNotPattern = "{\" pattern\" :{\" tables\" :[],\" steps\" :[{\" type\" :\" BYTE\" ,\" value\" :170},{\" type\" :\" MATCH\" }],\" pattern_metadata\" :{}},\" type\" :\" NEGATIVELOOKAHEAD\" }" ;
48+
49+ private static final String simpleByteStringPattern = "`\" abc\" `" ;
50+ private static final String stepsForSimpleByteStringPattern = "{\" type\" :\" BYTE\" ,\" value\" :97},{\" type\" :\" BYTE\" ,\" value\" :98},{\" type\" :\" BYTE\" ,\" value\" :99}" ;
51+
52+
2553 private static final String simpleSuboperandInstruction = "mov `Q1/[lr].`,#0x0" ;
2654 private static final String stepsForSimpleSuboperandInstruction = "{\" data\" :[{\" type\" :\" MaskAndChoose\" ,\" choices\" :[{\" operands\" :[{\" var_id\" :\" Q1\" ,\" type\" :\" Field\" ,\" table_id\" :0,\" mask\" :[0,240,0,0]}],\" value\" :[0,0,160,227]}],\" mask\" :[255,15,255,255]}],\" type\" :\" LOOKUP\" }" ;
2755 private static final String tablesForSimpleSuboperandInstruction = "{\" r2\" :[{\" value\" :[2],\" mask\" :[15]}],\" r3\" :[{\" value\" :[3],\" mask\" :[15]}],\" r4\" :[{\" value\" :[4],\" mask\" :[15]}],\" r5\" :[{\" value\" :[5],\" mask\" :[15]}],\" r6\" :[{\" value\" :[6],\" mask\" :[15]}],\" r7\" :[{\" value\" :[7],\" mask\" :[15]}],\" r8\" :[{\" value\" :[8],\" mask\" :[15]}],\" lr\" :[{\" value\" :[14],\" mask\" :[15]}],\" r9\" :[{\" value\" :[9],\" mask\" :[15]}],\" r0\" :[{\" value\" :[0],\" mask\" :[15]}],\" r1\" :[{\" value\" :[1],\" mask\" :[15]}]}" ;
@@ -45,7 +73,9 @@ protected String getCompileInfoRaw() {
4573 // This variation works with Ghidra 10.2 (prior works with older versions)
4674 private static final String stepsForInstructionsWithWildcards_evenNewer = "{\" data\" :[{\" type\" :\" MaskAndChoose\" ,\" choices\" :[{\" operands\" :[{\" var_id\" :\" Q3\" ,\" type\" :\" Field\" ,\" table_id\" :0,\" mask\" :[0,240,0,0]}],\" value\" :[2,12,160,227]}],\" mask\" :[255,15,255,255]}],\" type\" :\" LOOKUP\" },{\" note\" :\" AnyBytesNode Start: 4 End: 16 Interval: 2 From: Token from line #2: Token type: PICKLED_CANARY_COMMAND data: `ANY_BYTES{4,16,2}`\" ,\" min\" :4,\" max\" :16,\" interval\" :2,\" type\" :\" ANYBYTESEQUENCE\" },{\" data\" :[{\" type\" :\" MaskAndChoose\" ,\" choices\" :[{\" operands\" :[{\" var_id\" :\" Q3\" ,\" type\" :\" Field\" ,\" table_id\" :0,\" mask\" :[0,240,0,0]},{\" var_id\" :\" Q3\" ,\" type\" :\" Field\" ,\" table_id\" :0,\" mask\" :[0,0,15,0]}],\" value\" :[2,12,64,226]}],\" mask\" :[255,15,240,255]}],\" type\" :\" LOOKUP\" },{\" note\" :\" AnyBytesNode Start: 0 End: 16 Interval: 3 From: Token from line #4: Token type: PICKLED_CANARY_COMMAND data: `ANY_BYTES{0,16,3}`\" ,\" min\" :0,\" max\" :16,\" interval\" :3,\" type\" :\" ANYBYTESEQUENCE\" },{\" data\" :[{\" type\" :\" MaskAndChoose\" ,\" choices\" :[{\" operands\" :[],\" value\" :[99,32,224,227]}],\" mask\" :[255,255,255,255]}],\" type\" :\" LOOKUP\" }" ;
4775 private static final String tablesForInstructionsWithWildcards = "{\" r2\" :[{\" value\" :[2],\" mask\" :[15]}],\" r3\" :[{\" value\" :[3],\" mask\" :[15]}],\" r4\" :[{\" value\" :[4],\" mask\" :[15]}],\" r5\" :[{\" value\" :[5],\" mask\" :[15]}],\" r6\" :[{\" value\" :[6],\" mask\" :[15]}],\" r7\" :[{\" value\" :[7],\" mask\" :[15]}],\" r8\" :[{\" value\" :[8],\" mask\" :[15]}],\" r9\" :[{\" value\" :[9],\" mask\" :[15]}],\" r0\" :[{\" value\" :[0],\" mask\" :[15]}],\" r1\" :[{\" value\" :[1],\" mask\" :[15]}]}" ;
48- // private static final String stepsForInstructionsWithWildcards = "{\"data\":[{\"type\":\"MaskAndChoose\",\"choices\":[{\"operands\":[{\"var_id\":\"Q3\",\"type\":\"Field\",\"table_id\":1,\"mask\":[0,240,0,0]}],\"value\":[2,12,160,227]}],\"mask\":[255,15,255,255]}],\"type\":\"LOOKUP\"},{\"note\":\"AnyBytesNode Start: 4 End: 16 Interval: 2 From: Token from line #2: Token type: PICKLED_CANARY_COMMAND data: `ANY_BYTES{4,16,2}`\",\"min\":4,\"max\":16,\"interval\":2,\"type\":\"ANYBYTESEQUENCE\"},{\"data\":[{\"type\":\"MaskAndChoose\",\"choices\":[{\"operands\":[{\"var_id\":\"Q3\",\"type\":\"Field\",\"table_id\":0,\"mask\":[0,0,15,0]},{\"var_id\":\"Q3\",\"type\":\"Field\",\"table_id\":0,\"mask\":[0,240,0,0]}],\"value\":[2,12,64,226]}],\"mask\":[255,15,240,255]}],\"type\":\"LOOKUP\"},{\"note\":\"AnyBytesNode Start: 0 End: 16 Interval: 3 From: Token from line #4: Token type: PICKLED_CANARY_COMMAND data: `ANY_BYTES{0,16,3}`\",\"min\":0,\"max\":16,\"interval\":3,\"type\":\"ANYBYTESEQUENCE\"},{\"data\":[{\"type\":\"MaskAndChoose\",\"choices\":[{\"operands\":[],\"value\":[99,32,224,227]}],\"mask\":[255,255,255,255]}],\"type\":\"LOOKUP\"}";
76+ private static final String stepsForInstructionsWithWildcards112 = "{\" data\" :[{\" type\" :\" MaskAndChoose\" ,\" choices\" :[{\" operands\" :[{\" var_id\" :\" Q3\" ,\" type\" :\" Field\" ,\" table_id\" :0,\" mask\" :[0,240,0,0]}],\" value\" :[2,12,160,227]}],\" mask\" :[255,15,255,255]}],\" type\" :\" LOOKUP\" },{\" note\" :\" AnyBytesNode Start: 4 End: 16 Interval: 2 From: Token from line #2: Token type: PICKLED_CANARY_COMMAND data: `ANY_BYTES{4,16,2}`\" ,\" min\" :4,\" max\" :16,\" interval\" :2,\" type\" :\" ANYBYTESEQUENCE\" },{\" data\" :[{\" type\" :\" MaskAndChoose\" ,\" choices\" :[{\" operands\" :[{\" var_id\" :\" Q3\" ,\" type\" :\" Field\" ,\" table_id\" :1,\" mask\" :[0,0,15,0]},{\" var_id\" :\" Q3\" ,\" type\" :\" Field\" ,\" table_id\" :1,\" mask\" :[0,240,0,0]}],\" value\" :[2,12,64,226]}],\" mask\" :[255,15,240,255]}],\" type\" :\" LOOKUP\" },{\" note\" :\" AnyBytesNode Start: 0 End: 16 Interval: 3 From: Token from line #4: Token type: PICKLED_CANARY_COMMAND data: `ANY_BYTES{0,16,3}`\" ,\" min\" :0,\" max\" :16,\" interval\" :3,\" type\" :\" ANYBYTESEQUENCE\" },{\" data\" :[{\" type\" :\" MaskAndChoose\" ,\" choices\" :[{\" operands\" :[],\" value\" :[99,32,224,227]}],\" mask\" :[255,255,255,255]}],\" type\" :\" LOOKUP\" }" ;
77+ private static final String tablesForInstructionsWithWildcards112 = "{\" r2\" :[{\" value\" :[2],\" mask\" :[15]}],\" r3\" :[{\" value\" :[3],\" mask\" :[15]}],\" r4\" :[{\" value\" :[4],\" mask\" :[15]}],\" r5\" :[{\" value\" :[5],\" mask\" :[15]}],\" r6\" :[{\" value\" :[6],\" mask\" :[15]}],\" r7\" :[{\" value\" :[7],\" mask\" :[15]}],\" r8\" :[{\" value\" :[8],\" mask\" :[15]}],\" r9\" :[{\" value\" :[9],\" mask\" :[15]}],\" r0\" :[{\" value\" :[0],\" mask\" :[15]}],\" r1\" :[{\" value\" :[1],\" mask\" :[15]}]},{\" r2\" :[{\" value\" :[2],\" mask\" :[15]}],\" r3\" :[{\" value\" :[3],\" mask\" :[15]}],\" r4\" :[{\" value\" :[4],\" mask\" :[15]}],\" r5\" :[{\" value\" :[5],\" mask\" :[15]}],\" r6\" :[{\" value\" :[6],\" mask\" :[15]}],\" r7\" :[{\" value\" :[7],\" mask\" :[15]}],\" r8\" :[{\" value\" :[8],\" mask\" :[15]}],\" lr\" :[{\" value\" :[14],\" mask\" :[15]}],\" r9\" :[{\" value\" :[9],\" mask\" :[15]}],\" r10\" :[{\" value\" :[10],\" mask\" :[15]}],\" r12\" :[{\" value\" :[12],\" mask\" :[15]}],\" r11\" :[{\" value\" :[11],\" mask\" :[15]}],\" sp\" :[{\" value\" :[13],\" mask\" :[15]}],\" r0\" :[{\" value\" :[0],\" mask\" :[15]}],\" r1\" :[{\" value\" :[1],\" mask\" :[15]}]}" ;
78+ // private static final String stepsForInstructionsWithWildcards = "{\"data\":[{\"type\":\"MaskAndChoose\",\"choices\":[{\"operands\":[{\"var_id\":\"Q3\",\"type\":\"Field\",\"table_id\":1,\"mask\":[0,240,0,0]}],\"value\":[2,12,160,227]}],\"mask\":[255,15,255,255]}],\"type\":\"LOOKUP\"},{\"note\":\"AnyBytesNode Start: 4 End: 16 Interval: 2 From: Token from line #2: Token type: PICKLED_CANARY_COMMAND data: `ANY_BYTES{4,16,2}`\",\"min\":4,\"max\":16,\"interval\":2,\"type\":\"ANYBYTESEQUENCE\"},{\"data\":[{\"type\":\"MaskAndChoose\",\"choices\":[{\"operands\":[{\"var_id\":\"Q3\",\"type\":\"Field\",\"table_id\":0,\"mask\":[0,0,15,0]},{\"var_id\":\"Q3\",\"type\":\"Field\",\"table_id\":0,\"mask\":[0,240,0,0]}],\"value\":[2,12,64,226]}],\"mask\":[255,15,240,255]}],\"type\":\"LOOKUP\"},{\"note\":\"AnyBytesNode Start: 0 End: 16 Interval: 3 From: Token from line #4: Token type: PICKLED_CANARY_COMMAND data: `ANY_BYTES{0,16,3}`\",\"min\":0,\"max\":16,\"interval\":3,\"type\":\"ANYBYTESEQUENCE\"},{\"data\":[{\"type\":\"MaskAndChoose\",\"choices\":[{\"operands\":[],\"value\":[99,32,224,227]}],\"mask\":[255,255,255,255]}],\"type\":\"LOOKUP\"}";
4979// private static final String tablesForInstructionsWithWildcards = "{\"r2\":[{\"value\":[2],\"mask\":[15]}],\"r3\":[{\"value\":[3],\"mask\":[15]}],\"r4\":[{\"value\":[4],\"mask\":[15]}],\"r5\":[{\"value\":[5],\"mask\":[15]}],\"r6\":[{\"value\":[6],\"mask\":[15]}],\"r7\":[{\"value\":[7],\"mask\":[15]}],\"r8\":[{\"value\":[8],\"mask\":[15]}],\"lr\":[{\"value\":[14],\"mask\":[15]}],\"r9\":[{\"value\":[9],\"mask\":[15]}],\"r10\":[{\"value\":[10],\"mask\":[15]}],\"r12\":[{\"value\":[12],\"mask\":[15]}],\"r11\":[{\"value\":[11],\"mask\":[15]}],\"sp\":[{\"value\":[13],\"mask\":[15]}],\"r0\":[{\"value\":[0],\"mask\":[15]}],\"r1\":[{\"value\":[1],\"mask\":[15]}]},{\"r2\":[{\"value\":[2],\"mask\":[15]}],\"r3\":[{\"value\":[3],\"mask\":[15]}],\"r4\":[{\"value\":[4],\"mask\":[15]}],\"r5\":[{\"value\":[5],\"mask\":[15]}],\"r6\":[{\"value\":[6],\"mask\":[15]}],\"r7\":[{\"value\":[7],\"mask\":[15]}],\"r8\":[{\"value\":[8],\"mask\":[15]}],\"r9\":[{\"value\":[9],\"mask\":[15]}],\"r0\":[{\"value\":[0],\"mask\":[15]}],\"r1\":[{\"value\":[1],\"mask\":[15]}]}";
5080
5181 private static final String bneInstruction = "bne `*`" ;
@@ -138,7 +168,42 @@ public void setUp() throws Exception {
138168 builder .createLabel ("0x1008420" , "TEST_LABEL" );
139169 builder .createLabel ("0x1008424" , "TEST_LABEL2" );
140170 builder .createLabel ("0x1000424" , "TEST_LABEL3" );
141- setup (builder );
171+ program = builder .getProgram ();
172+ }
173+
174+ @ Test
175+ public void testBasicCompiling () {
176+ String testQueryPatternExpected = "{\" tables\" :[" + "" + "],\" steps\" :["
177+ + stepsForSimplePattern + "]" ;
178+ generatePatternTestHelper (simplePattern , testQueryPatternExpected + this .getCompileInfo ());
179+ }
180+
181+ @ Test
182+ public void testBasicOrCompiling () {
183+ String testQueryPatternExpected = "{\" tables\" :[" + "" + "],\" steps\" :["
184+ + stepsForSimpleOrPattern + "]" ;
185+ generatePatternTestHelper (simpleOrPattern , testQueryPatternExpected + this .getCompileInfo ());
186+ }
187+
188+ @ Test
189+ public void testBasicMetadataCompiling () {
190+ String testQueryPatternExpected = "{\" tables\" :[" + "" + "],\" steps\" :["
191+ + stepsForSimpleMetadataPattern + "]" ;
192+ generatePatternTestHelper (simpleMetadataPattern , testQueryPatternExpected + (this .getCompileInfo ().replace ("\" pattern_metadata\" :{}" , "\" pattern_metadata\" :{\" foo\" :\" bar\" ,\" baz\" :\" boop\" }" )));
193+ }
194+
195+ @ Test
196+ public void testBasicNotCompiling () {
197+ String testQueryPatternExpected = "{\" tables\" :[" + "" + "],\" steps\" :["
198+ + stepsForSimpleNotPattern + "]" ;
199+ generatePatternTestHelper (simpleNotPattern , testQueryPatternExpected + (this .getCompileInfo ()));
200+ }
201+
202+ @ Test
203+ public void testBasicByteStringCompiling () {
204+ String testQueryPatternExpected = "{\" tables\" :[" + "" + "],\" steps\" :["
205+ + stepsForSimpleByteStringPattern + "]" ;
206+ generatePatternTestHelper (simpleByteStringPattern , testQueryPatternExpected + (this .getCompileInfo ()));
142207 }
143208
144209 @ Test
@@ -151,7 +216,7 @@ public void testPatternWithSuboperand() {
151216 @ Test
152217 public void testRunPatternWithSuboperand () {
153218 List <SavedDataAddresses > x = PickledCanary .parseAndRunAll (monitor , this .program ,
154- program .getMemory ().getMinAddress (), simpleSuboperandInstruction );
219+ program .getMemory ().getMinAddress (), simpleSuboperandInstruction );
155220 List <SavedDataAddresses > expected = new ArrayList <>();
156221 SavedData s = new SavedData (dataBase + 8 , dataBase + 12 );
157222 s .addOrFail (new ConcreteOperandField ("Q1" , "r1" ));
@@ -171,7 +236,7 @@ public void testRunPatternWithSuboperand() {
171236 @ Test
172237 public void testRunPatternWithConstraintEnforcement () {
173238 List <SavedDataAddresses > x = PickledCanary .parseAndRunAll (monitor , this .program ,
174- program .getMemory ().getMinAddress (), enforceConstraintsPattern );
239+ program .getMemory ().getMinAddress (), enforceConstraintsPattern );
175240
176241 List <SavedDataAddresses > expected = new ArrayList <>();
177242 SavedData s = new SavedData (dataBase + 8 , dataBase + 20 );
@@ -201,6 +266,10 @@ public void testInstructionsWithWildcards() {
201266 // For Ghidra versions in the 10.2 ballpark
202267 testQueryPatternExpected .add ("{\" tables\" :[" + tablesForInstructionsWithWildcards + "],\" steps\" :["
203268 + stepsForInstructionsWithWildcards_evenNewer + "]" + this .getCompileInfo ());
269+
270+ // For Ghidra versions in the 11.2 ballpark
271+ testQueryPatternExpected .add ("{\" tables\" :[" + tablesForInstructionsWithWildcards112 + "],\" steps\" :["
272+ + stepsForInstructionsWithWildcards112 + "]" + this .getCompileInfo ());
204273 generatePatternTestHelper (instructionsWithWildcards , testQueryPatternExpected );
205274 }
206275
@@ -252,7 +321,7 @@ public void testLabelPatternBl() {
252321 @ Test
253322 public void testLabelPatternBlExecution () {
254323 List <SavedDataAddresses > results = PickledCanary .parseAndRunAll (monitor , this .program ,
255- this .program .getMinAddress (), blPatternLabel );
324+ this .program .getMinAddress (), blPatternLabel );
256325
257326 Assert .assertEquals (1 , results .size ());
258327 SavedDataAddresses result = results .get (0 );
@@ -262,15 +331,15 @@ public void testLabelPatternBlExecution() {
262331 @ Test
263332 public void testMisalignedLabelPatternBl () {
264333 List <SavedDataAddresses > results = PickledCanary .parseAndRunAll (monitor , this .program ,
265- this .program .getMinAddress (), blPatternMisallignedLabel );
334+ this .program .getMinAddress (), blPatternMisallignedLabel );
266335
267336 Assert .assertEquals (0 , results .size ());
268337 }
269338
270339 @ Test
271340 public void testLabelPatternLdr () {
272341 List <SavedDataAddresses > results = PickledCanary .parseAndRunAll (monitor , this .program ,
273- this .program .getMinAddress (), ldrPatternLabel );
342+ this .program .getMinAddress (), ldrPatternLabel );
274343
275344 Assert .assertEquals (1 , results .size ());
276345 SavedDataAddresses result = results .get (0 );
0 commit comments