crokus 0.0.7 → 0.0.10

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '061769523e1b3d35501dd09d51cb609a75da50fb86a55f55f31fd47b12299eec'
4
- data.tar.gz: e85164ce03f41a61627f8d1b84c92504f077e7757932ee17095c0eb2cc297fb7
3
+ metadata.gz: bca020ee93a39e7a8bea529c45ede29dc579f3a6536cea6999d497ffb985c1a0
4
+ data.tar.gz: 3d78efcd9e0b963791963ae7f02bd16dc51e3f22a7e13ceda0fc5552d775a7ac
5
5
  SHA512:
6
- metadata.gz: a685f4bae55f560e066e3f28f4e1f5acafc347edcdbccabe0eaf5d4cba7664f4fdaa60009c1dc10b9ba26a3a72100411f9d19bca4e62ff4eb95ad2a1d596bc4f
7
- data.tar.gz: a3b16a1ab6a5be70febb9417579f0ac9cd1eaf1a5fb3874e13e076915d5116a03e94b49eb1589b41f016608fe211e9f262e72914b7721683edcce07d2418020c
6
+ metadata.gz: 10d5d9e59e156d4426f5cfc6145e5268188eddf73e70c455986360d6d74782ceefcaadce3154b00aa5bed6f678fa5c77317983f3d4d3ac64f4742293fcf1cf44
7
+ data.tar.gz: a7eb869b9536a8932975efd2378d283a5e5a3fd9bf337a8be64e441929a53f28fa4daa59d06a51cca507840474cf2b6c96f67147bd6281bf56c75db723b63854
@@ -178,6 +178,14 @@ module Crokus
178
178
  def collect(&block)
179
179
  @stmts.collect(&block)
180
180
  end
181
+
182
+ def select(&block)
183
+ @stmts.select(&block)
184
+ end
185
+
186
+ def size
187
+ @stmts
188
+ end
181
189
  end
182
190
 
183
191
  class Stmt < Ast
@@ -16,7 +16,7 @@ module Crokus
16
16
  attr_accessor :cfg
17
17
 
18
18
  def run params
19
- puts "[+] running random C generation"
19
+ puts "[+] running random Newage code generation"
20
20
  puts " |-->[+] reading parameters file '#{params}'"
21
21
  @params=YAML.load(File.read(params))
22
22
  init_cfg
@@ -1,10 +1,13 @@
1
1
  module Crokus
2
2
  class Cleaner
3
3
  def clean str_c
4
+
4
5
  str_c.gsub!(";;",";")
5
6
  str_c.gsub!(";)",")")
6
- str_c.gsub!(/\n\s*\;/,";")
7
+ str_c.gsub!(/\n+\s*\;/,";")
8
+ str_c.gsub!(/\;\s*\:/,":")
7
9
  #str_c.gsub!(/\n\s+\{/,"{")
10
+ str_c
8
11
  end
9
12
  end
10
13
  end
@@ -2,8 +2,9 @@ require_relative 'ast'
2
2
  require_relative 'ast_printer'
3
3
  require_relative 'parser'
4
4
  require_relative 'visitor'
5
- require_relative 'transformer'
6
5
  require_relative 'pretty_printer'
6
+ require_relative 'trojan_inserter'
7
+
7
8
  require_relative 'cfg_builder'
8
9
  require_relative 'tac_builder'
9
10
  require_relative 'ir_dumper'
@@ -30,6 +31,12 @@ module Crokus
30
31
  build_cfg
31
32
  return true if options[:cfg]
32
33
 
34
+ pretty_print
35
+
36
+ if options[:trojan]
37
+ insert_trojan
38
+ end
39
+
33
40
  build_tac
34
41
  return true if options[:tac]
35
42
 
@@ -77,22 +84,35 @@ module Crokus
77
84
  def build_cfg
78
85
  puts "=> building CFGs" unless options[:mute]
79
86
  builder=CFGBuilder.new
80
- builder.build(@ast)
87
+ builder.build(ast)
81
88
  end
82
89
 
83
90
  def build_tac
84
91
  puts "=> building TAC" unless options[:mute]
85
92
  builder=TACBuilder.new
86
- builder.visit(@ast)
93
+ builder.visit(ast)
87
94
  end
88
95
 
89
96
  def emit_ir
90
97
  puts "=> emit textual IR " unless options[:mute]
91
- IRDumper.new.visit(@ast)
98
+ IRDumper.new.visit(ast)
92
99
  end
93
100
 
94
101
  def execute params
95
102
  RandomGen.new.run(params)
96
103
  end
104
+
105
+ def insert_trojan
106
+ puts "=> inserting trojan" unless options[:mute]
107
+ infected_ast=TrojanInserter.new.insert(ast)
108
+ if infected_ast
109
+ code=PrettyPrinter.new.visit(infected_ast)
110
+ pp_c=@base_name+"_troj.c"
111
+ puts code
112
+ File.open(pp_c,'w'){|f| f.puts code}
113
+ puts " |--> saved as #{pp_c}" unless options[:mute]
114
+ end
115
+ end
116
+
97
117
  end
98
118
  end
@@ -30,7 +30,7 @@ class GenericLexer
30
30
  def next_token
31
31
  return [nil,nil,nil] if @ssc.empty?
32
32
  tok = get_token
33
- return (tok.is_a? :skip) ? next_token : tok
33
+ return (tok.is? :skip) ? next_token : tok
34
34
  end
35
35
 
36
36
  def get_token
@@ -3,31 +3,36 @@ module Crokus
3
3
  class IRDumper < Visitor
4
4
 
5
5
  def visitFunction func,args=nil
6
- puts "IR for '#{func.name}'".center(40,'=')
7
- dump func.cfg
6
+ puts "[+] IR for '#{func.name}'"
7
+ ir_code=dump(func.cfg)
8
+ filename=func.name.to_s+".ir"
9
+ ir_code.save_as filename
10
+ puts "\t generated #{filename}"
8
11
  end
9
12
 
10
13
  def dump cfg
11
14
  @visited=[]
15
+ @code=Code.new
12
16
  visit_rec cfg.starter
17
+ return @code
13
18
  end
14
19
 
15
20
  def visit_rec bb
16
- print bb.label+":"
21
+ @code << bb.label+":"
17
22
  @visited << bb
18
23
  @current=bb
19
24
  bb.stmts.each do |stmt|
20
25
  unless stmt.is_a? Break or stmt.is_a? Continue
21
- puts "\t"+stmt.str.gsub(/;/,'')
26
+ @code << "\t"+stmt.str.gsub(/;/,'')
22
27
  end
23
28
  end
24
29
  unless bb.stmts.last.is_a? Crokus::ITE
25
30
  if bb.succs.any?
26
- puts "\tgoto #{bb.succs.first.label}"
31
+ @code << "\tgoto #{bb.succs.first.label}"
27
32
  end
28
33
  end
29
34
  if bb.succs.empty?
30
- puts "\tstop"
35
+ @code << "\tstop"
31
36
  else
32
37
  bb.succs.each do |bb|
33
38
  unless @visited.include? bb
@@ -41,7 +46,7 @@ module Crokus
41
46
  cond=ite.cond.accept(self)
42
47
  label1=ite.trueBranch.label
43
48
  label2=ite.falseBranch.label
44
- "\t"+"ite #{cond},#{label1},#{label2}"
49
+ @code << "\t"+"ite #{cond},#{label1},#{label2}"
45
50
  end
46
51
 
47
52
  end
@@ -24,7 +24,7 @@ module Crokus
24
24
  end
25
25
 
26
26
  def maybe kind
27
- return acceptIt if showNext.is_a? kind
27
+ return acceptIt if showNext.is? kind
28
28
  end
29
29
 
30
30
  def expect kind
@@ -68,10 +68,11 @@ module Crokus
68
68
  begin
69
69
  @str=str
70
70
  @tokens=Lexer.new.tokenize(str)
71
+ @tokens=@tokens.reject{|tok| tok==[nil,nil,nil]}
71
72
  @tokens=remove_comments()
72
- warnings=@tokens.select{|tok| tok.is_a? :lexer_warning}
73
+ warnings=@tokens.select{|tok| tok.is? :lexer_warning}
73
74
  show_lexer_warnings(warnings)
74
- @tokens=@tokens.select{|tok| !tok.is_a? [:newline]}
75
+ @tokens=@tokens.select{|tok| !tok.is? [:newline]}
75
76
  ast=design_unit()
76
77
  rescue Exception => e
77
78
  puts "PARSING ERROR : #{e}"
@@ -161,13 +162,13 @@ module Crokus
161
162
  indent "struct"
162
163
  expect :struct
163
164
  name=nil
164
- if showNext.is_a? :ident
165
+ if showNext.is? :ident
165
166
  name=acceptIt
166
167
  end
167
168
  ret=Struct.new(name)
168
- if showNext.is_a? :lbrace
169
+ if showNext.is? :lbrace
169
170
  acceptIt
170
- while !showNext.is_a? :rbrace
171
+ while !showNext.is? :rbrace
171
172
  ret.decls << declaration()
172
173
  end
173
174
  ret.decls.flatten!
@@ -205,9 +206,9 @@ module Crokus
205
206
  indent "function_formal_args"
206
207
  args=[]
207
208
  expect :lparen
208
- while !showNext.is_a? :rparen
209
+ while !showNext.is? :rparen
209
210
  args << func_formal_arg()
210
- if !showNext.is_a? :rparen
211
+ if !showNext.is? :rparen
211
212
  expect :comma
212
213
  end
213
214
  end
@@ -217,12 +218,12 @@ module Crokus
217
218
  end
218
219
 
219
220
  def func_formal_arg
220
- indent "function_arg"
221
221
  @current_type=type=parse_type()
222
222
  d=declarator
223
223
  a=arrayed?(type)
224
- #parenthesized?
225
- dedent
224
+ if a
225
+ type=a
226
+ end
226
227
  return FormalArg.new(type,d)
227
228
  end
228
229
 
@@ -280,7 +281,7 @@ module Crokus
280
281
  ret=expression_statement
281
282
  end
282
283
  when :const,:volatile
283
- declaration
284
+ ret=declaration()
284
285
  when :semicolon
285
286
  acceptIt
286
287
  #ret=expression_statement
@@ -326,7 +327,7 @@ module Crokus
326
327
  ret=Switch.new(e,cases=[],default=nil)
327
328
  expect :rparen
328
329
  expect :lbrace
329
- while showNext.is_a? :case
330
+ while showNext.is? :case
330
331
  expect :case
331
332
  case_e=expression
332
333
  case_body=Body.new
@@ -336,7 +337,7 @@ module Crokus
336
337
  end
337
338
  cases << Case.new(case_e,case_body)
338
339
  end
339
- if showNext.is_a? :default
340
+ if showNext.is? :default
340
341
  acceptIt
341
342
  expect :colon
342
343
  default_body=Body.new
@@ -353,7 +354,7 @@ module Crokus
353
354
  def parse_return
354
355
  indent "parse_return"
355
356
  expect :return
356
- unless showNext.is_a? :semicolon
357
+ unless showNext.is? :semicolon
357
358
  e=expression
358
359
  end
359
360
  dedent
@@ -388,7 +389,7 @@ module Crokus
388
389
  end
389
390
  init=initialization?
390
391
  ret << Decl.new(type,d,init)
391
- while tokens.any? and showNext.is_a?(:comma)
392
+ while tokens.any? and showNext.is?(:comma)
392
393
  acceptIt
393
394
  ptr=pointed?
394
395
  if ptr
@@ -406,7 +407,7 @@ module Crokus
406
407
  end
407
408
 
408
409
  def declarator
409
- if showNext.is_a? :ident
410
+ if showNext.is? :ident
410
411
  ret=@current_ident=Ident.new(acceptIt)
411
412
  end
412
413
  return ret
@@ -414,16 +415,16 @@ module Crokus
414
415
 
415
416
  def pointed?
416
417
  return if tokens.empty?
417
- while showNext.is_a? :mul
418
+ while showNext.is? :mul
418
419
  acceptIt
419
420
  end
420
421
  end
421
422
 
422
423
  def arrayed?(type)
423
424
  return if tokens.empty?
424
- while showNext.is_a? :lbrack
425
+ while showNext.is? :lbrack
425
426
  acceptIt
426
- if showNext.is_a? :rbrack
427
+ if showNext.is? :rbrack
427
428
  acceptIt
428
429
  type=ArrayOf.new(type,IntLit.new(ZERO))
429
430
  else
@@ -437,7 +438,7 @@ module Crokus
437
438
 
438
439
  def initialization?
439
440
  return if tokens.empty?
440
- if showNext.is_a? :assign
441
+ if showNext.is? :assign
441
442
  expect :assign
442
443
  e=expression
443
444
  return e
@@ -446,7 +447,7 @@ module Crokus
446
447
 
447
448
  def parenthesized?
448
449
  return if tokens.empty?
449
- if showNext.is_a? :lparen
450
+ if showNext.is? :lparen
450
451
  f=function_decl(@current_ident,@current_type)
451
452
  return f
452
453
  end
@@ -457,14 +458,14 @@ module Crokus
457
458
  ret=Type.new(nil)
458
459
 
459
460
  ret.precisions << spec_qualifier?() # const, volatile
460
- if showNext.is_a? [:signed,:unsigned]
461
+ if showNext.is? [:signed,:unsigned]
461
462
  ret.precisions << acceptIt
462
463
  end
463
464
 
464
465
  case showNext.kind
465
466
  when :ident,:char,:int,:short,:long,:float,:double,:void
466
467
  ret.name=acceptIt
467
- while showNext.is_a? [:char,:int,:short,:long,:float,:double,:void]
468
+ while showNext.is? [:char,:int,:short,:long,:float,:double,:void]
468
469
  ret.precisions << ret.name
469
470
  ret.name=acceptIt
470
471
  end
@@ -477,14 +478,14 @@ module Crokus
477
478
  raise "Parsing ERROR in type declaration: '#{showNext}'"
478
479
  end
479
480
 
480
- while showNext.is_a? [:mul,:lparen]
481
+ while showNext.is? [:mul,:lparen]
481
482
  case showNext.kind
482
483
  when :mul
483
484
  acceptIt
484
485
  ret=PointerTo.new(ret)
485
486
  when :lparen
486
487
  acceptIt
487
- if showNext.is_a? :rparen
488
+ if showNext.is? :rparen
488
489
  acceptIt
489
490
  else
490
491
  expression
@@ -498,7 +499,7 @@ module Crokus
498
499
 
499
500
  def spec_qualifier?
500
501
  list=[]
501
- while showNext.is_a? STARTERS_TYPE_QUALIFIER
502
+ while showNext.is? STARTERS_TYPE_QUALIFIER
502
503
  case showNext.kind
503
504
  when :volatile
504
505
  list << acceptIt
@@ -512,24 +513,24 @@ module Crokus
512
513
  def parse_if
513
514
  indent "parse_if"
514
515
  expect :if
515
- if showNext.is_a? :lparen # helps wrt casting.
516
+ if showNext.is? :lparen # helps wrt casting.
516
517
  acceptIt
517
518
  lparen=true
518
519
  end
519
520
  cond=expression()
520
521
  expect :rparen if lparen
521
522
  body=Body.new
522
- if showNext.is_a? :lbrace
523
+ if showNext.is? :lbrace
523
524
  lbrace=acceptIt
524
525
  end
525
526
  body << statement()
526
527
  if lbrace
527
- until showNext.is_a? :rbrace
528
+ until showNext.is? :rbrace
528
529
  body << statement
529
530
  end
530
531
  expect :rbrace
531
532
  end
532
- if showNext.is_a? :else
533
+ if showNext.is? :else
533
534
  else_=parse_else()
534
535
  end
535
536
  dedent
@@ -595,7 +596,7 @@ module Crokus
595
596
  def parse_body
596
597
  body=Body.new
597
598
  expect :lbrace
598
- while !showNext.is_a? :rbrace
599
+ while !showNext.is? :rbrace
599
600
  body << statement()
600
601
  end
601
602
  expect :rbrace
@@ -603,7 +604,7 @@ module Crokus
603
604
  end
604
605
 
605
606
  def expression_statement
606
- if showNext.is_a? :semicolon
607
+ if showNext.is? :semicolon
607
608
  acceptIt
608
609
  else
609
610
  e=expression
@@ -619,7 +620,7 @@ module Crokus
619
620
  def expression
620
621
  indent "expression : #{showNext}"
621
622
  e1=assign()
622
- while showNext.is_a? :comma
623
+ while showNext.is? :comma
623
624
  acceptIt
624
625
  e2=assign()
625
626
  e1=CommaStmt.new(e1,e2)
@@ -637,7 +638,7 @@ module Crokus
637
638
  def assign
638
639
  indent "assign : #{showNext}"
639
640
  e1=cond_expr
640
- while showNext.is_a? ASSIGN_OP
641
+ while showNext.is? ASSIGN_OP
641
642
  op=acceptIt
642
643
  e2=assign
643
644
  e1=Assign.new(e1,op,e2)
@@ -649,7 +650,7 @@ module Crokus
649
650
  def cond_expr
650
651
  indent "cond_expr : #{showNext}"
651
652
  e1=logor
652
- while showNext.is_a? :qmark
653
+ while showNext.is? :qmark
653
654
  acceptIt
654
655
  e2=expression
655
656
  expect :colon
@@ -663,7 +664,7 @@ module Crokus
663
664
  def logor
664
665
  indent "logor : #{showNext}"
665
666
  e1=logand
666
- while showNext.is_a? :oror
667
+ while showNext.is? :oror
667
668
  op=acceptIt
668
669
  e2=logand
669
670
  e1=Or2.new(e1,op,e2)
@@ -675,7 +676,7 @@ module Crokus
675
676
  def logand
676
677
  indent "logand : #{showNext}"
677
678
  e1=inclor
678
- while showNext.is_a? :andand
679
+ while showNext.is? :andand
679
680
  op=acceptIt
680
681
  e2=inclor
681
682
  e1=Binary.new(e1,op,e2)
@@ -687,7 +688,7 @@ module Crokus
687
688
  def inclor
688
689
  indent "inclor : #{showNext}"
689
690
  e1=exclor
690
- while showNext.is_a? :or
691
+ while showNext.is? :or
691
692
  op=acceptIt
692
693
  e2=exclor
693
694
  e1=Binary.new(e1,op,e2)
@@ -699,7 +700,7 @@ module Crokus
699
700
  def exclor
700
701
  indent "exclor : #{showNext}"
701
702
  e1=andexp
702
- while showNext.is_a? :xor
703
+ while showNext.is? :xor
703
704
  op=acceptIt
704
705
  e2=andexp
705
706
  e1=Binary.new(e1,op,e2)
@@ -711,7 +712,7 @@ module Crokus
711
712
  def andexp
712
713
  indent "andexp : #{showNext}"
713
714
  e1=eqexp
714
- while showNext.is_a? :and
715
+ while showNext.is? :and
715
716
  op=acceptIt
716
717
  e2=eqexp
717
718
  e1=Binary.new(e1,op,e2)
@@ -723,7 +724,7 @@ module Crokus
723
724
  def eqexp
724
725
  indent "eqexp : #{showNext}"
725
726
  e1=relexp
726
- while showNext.is_a? [:eq,:neq]
727
+ while showNext.is? [:eq,:neq]
727
728
  op=acceptIt
728
729
  e2=relexp
729
730
  e1=Binary.new(e1,op,e2)
@@ -735,7 +736,7 @@ module Crokus
735
736
  def relexp
736
737
  indent "relexp : #{showNext}"
737
738
  e1=shiftexp
738
- while showNext.is_a? [:lte,:lt,:gte,:gt ]
739
+ while showNext.is? [:lte,:lt,:gte,:gt ]
739
740
  op=acceptIt
740
741
  e2=shiftexp
741
742
  e1=Binary.new(e1,op,e2)
@@ -747,7 +748,7 @@ module Crokus
747
748
  def shiftexp
748
749
  indent "shiftexp : #{showNext}"
749
750
  e1=additive
750
- while showNext.is_a? [:shift_l,:shift_r]
751
+ while showNext.is? [:shift_l,:shift_r]
751
752
  op=acceptIt
752
753
  e2=additive
753
754
  e1=Binary.new(e1,op,e2)
@@ -759,7 +760,7 @@ module Crokus
759
760
  def additive
760
761
  indent "addititve : #{showNext}"
761
762
  e1=multitive
762
- while showNext.is_a? [:add,:sub]
763
+ while showNext.is? [:add,:sub]
763
764
  op=acceptIt
764
765
  e2=multitive
765
766
  e1=Binary.new(e1,op,e2)
@@ -771,7 +772,7 @@ module Crokus
771
772
  def multitive
772
773
  indent "multitive : #{showNext}"
773
774
  e1=castexp
774
- while showNext.is_a? [:mul,:div,:mod]
775
+ while showNext.is? [:mul,:div,:mod]
775
776
  op=acceptIt
776
777
  e2=castexp
777
778
  e1=Binary.new(e1,op,e2)
@@ -806,8 +807,8 @@ module Crokus
806
807
  i+=1
807
808
  end
808
809
  tok=@tokens[i]
809
- return false if tok.is_a? [:mul,:add,:sub]
810
- return true if tok.is_a? STARTERS_UNARY-STARTERS_ARRAY_OR_STRUCT_INIT
810
+ return false if tok.is? [:mul,:add,:sub]
811
+ return true if tok.is? STARTERS_UNARY-STARTERS_ARRAY_OR_STRUCT_INIT
811
812
  return false
812
813
  end
813
814
 
@@ -833,7 +834,7 @@ module Crokus
833
834
  def typename
834
835
  indent "typename"
835
836
  type=specifier_qualifier
836
- while showNext.is_a? STARTERS_ABSTRACT_DECLARATOR
837
+ while showNext.is? STARTERS_ABSTRACT_DECLARATOR
837
838
  list << abstract_decl
838
839
  end
839
840
  dedent
@@ -842,8 +843,8 @@ module Crokus
842
843
 
843
844
  def spec_qualifier_list
844
845
  indent "spec_qualifier_list #{showNext.inspect}"
845
- while showNext.is_a? STARTERS_TYPE_SPECIFIER+STARTERS_TYPE_QUALIFIER
846
- if showNext.is_a? STARTERS_TYPE_SPECIFIER
846
+ while showNext.is? STARTERS_TYPE_SPECIFIER+STARTERS_TYPE_QUALIFIER
847
+ if showNext.is? STARTERS_TYPE_SPECIFIER
847
848
  list << type_specifier
848
849
  else
849
850
  list << type_qualifier
@@ -857,7 +858,7 @@ module Crokus
857
858
  def type_specifier
858
859
  type=Type.new(nil,[])
859
860
  indent "type_specifier #{showNext}"
860
- if showNext.is_a? STARTERS_TYPE_SPECIFIER
861
+ if showNext.is? STARTERS_TYPE_SPECIFIER
861
862
  ret=acceptIt
862
863
  type.name=ret
863
864
  else
@@ -875,7 +876,7 @@ module Crokus
875
876
  STARTERS_ABSTRACT_DECLARATOR=[:mul,:lparen,:lbrack]
876
877
  def abstract_decl
877
878
  indent "abstract_decl"
878
- if showNext.is_a? STARTERS_ABSTRACT_DECLARATOR
879
+ if showNext.is? STARTERS_ABSTRACT_DECLARATOR
879
880
  case showNext.kind
880
881
  when :mul
881
882
  pointer
@@ -897,7 +898,7 @@ module Crokus
897
898
  STARTERS_TYPE_QUALIFIER=[:const,:volatile]
898
899
  def pointer
899
900
  expect :mul
900
- while showNext.is_a? STARTERS_TYPE_QUALIFIER+[:mul]
901
+ while showNext.is? STARTERS_TYPE_QUALIFIER+[:mul]
901
902
  case showNext.kind
902
903
  when :volatile
903
904
  acceptIt
@@ -916,7 +917,7 @@ module Crokus
916
917
  def unary
917
918
  if STARTERS_PRIMARY.include? showNext.kind
918
919
  u=postfix
919
- elsif showNext.is_a? [:and,:mul,:add,:sub,:tilde,:not]
920
+ elsif showNext.is? [:and,:mul,:add,:sub,:tilde,:not]
920
921
  op=acceptIt
921
922
  e=castexp
922
923
  u=Unary.new(op,e)
@@ -957,7 +958,7 @@ module Crokus
957
958
  def postfix
958
959
  indent "postfix : #{showNext}"
959
960
  e1=primary
960
- while showNext.is_a? [:lbrack,:lparen,:dot,:inc_op,:dec_op,:ptr_op]
961
+ while showNext.is? [:lbrack,:lparen,:dot,:inc_op,:dec_op,:ptr_op]
961
962
  case showNext.kind
962
963
  when :lbrack
963
964
  acceptIt
@@ -967,7 +968,7 @@ module Crokus
967
968
  when :lparen
968
969
  acceptIt
969
970
  args=[]
970
- if !showNext.is_a? :rparen
971
+ if !showNext.is? :rparen
971
972
  args=argument_expr_list
972
973
  end
973
974
  expect :rparen
@@ -1025,7 +1026,7 @@ module Crokus
1025
1026
  def argument_expr_list
1026
1027
  list=[]
1027
1028
  list << expression
1028
- while showNext.is_a? :comma
1029
+ while showNext.is? :comma
1029
1030
  acceptIt
1030
1031
  list << expression
1031
1032
  end
@@ -1036,9 +1037,9 @@ module Crokus
1036
1037
  indent "array_or_struct_init"
1037
1038
  expect :lbrace
1038
1039
  elements=[]
1039
- while !showNext.is_a? :rbrace
1040
+ while !showNext.is? :rbrace
1040
1041
  elements << (e=expression)
1041
- if showNext.is_a? :comma
1042
+ if showNext.is? :comma
1042
1043
  acceptIt
1043
1044
  end
1044
1045
  end
@@ -33,6 +33,7 @@ module Crokus
33
33
  dedent
34
34
  end
35
35
 
36
+ # WTF !?#
36
37
  def visitDecl decl,args=nil
37
38
  code=Code.new
38
39
  type=decl.type.accept(self)
@@ -67,9 +68,8 @@ module Crokus
67
68
 
68
69
  code << last_str
69
70
  else
70
- ret = "#{type} #{vname}#{array_size}#{init}"
71
+ code << "#{type} #{vname}#{array_size}#{init}"
71
72
  end
72
- code << ret
73
73
  code << ";"
74
74
  return code
75
75
  end
@@ -376,6 +376,13 @@ module Crokus
376
376
  return unary.postfix ? "#{e}#{op}" : "#{op}#{e}"
377
377
  end
378
378
 
379
+ def visitCondExpr ternary,args=nil
380
+ cond=ternary.cond.accept(self)
381
+ lhs=ternary.lhs.accept(self)
382
+ rhs=ternary.rhs.accept(self)
383
+ "#{cond} ? #{lhs} : #{rhs}"
384
+ end
385
+
379
386
  def visitParenth par,args=nil
380
387
  e=par.expr.accept(self)
381
388
  return "(#{e})"
@@ -396,10 +403,10 @@ module Crokus
396
403
  def visitArrayOrStructInit init,args=nil
397
404
  inits=init.elements.collect{|e| e.accept(self)}
398
405
  #handle imbrications
399
- inits=inits.collect{|init| (init.is_a? Code) ? init.finalize : init}
406
+ #inits=inits.collect{|init| (init.is_a? Code) ? init.finalize : init}
400
407
  code=Code.new
401
408
  code << "{"+inits.join(",")+"}"
402
- return code
409
+ return code.finalize
403
410
  end
404
411
 
405
412
  def visitAddressOf ao,args=nil
@@ -69,6 +69,10 @@ module Crokus
69
69
  options[:random] = params_filename
70
70
  end
71
71
 
72
+ parser.on('--trojan PARAMS', "generates random c files, using parameters", String) do |params_filename|
73
+ options[:trojan] = params_filename
74
+ end
75
+
72
76
  parser.on("--vv", "verbose") do
73
77
  options[:verbose] = true
74
78
  end
@@ -28,12 +28,12 @@ module Crokus
28
28
  @visited << bb
29
29
  @current=bb
30
30
  @new_stmts=[]
31
- @post_stmts=[]
31
+ #@post_stmts=[]
32
32
  bb.stmts.each do |stmt|
33
33
  @new_stmts << stmt.accept(self)
34
34
  end
35
35
  bb.stmts=@new_stmts
36
- bb.stmts << @post_stmts
36
+ #bb.stmts << @post_stmts
37
37
  bb.stmts.flatten!
38
38
  bb.succs.each do |bb|
39
39
  unless @visited.include? bb
@@ -64,11 +64,15 @@ module Crokus
64
64
 
65
65
  def visitITE ite,args=nil
66
66
  ret=ITE.new(ite.cond,ite.trueBranch,ite.falseBranch)
67
- if ite.cond.is_a?(Binary)
67
+ case ite.cond
68
+ when Binary
68
69
  cond=ite.cond.accept(self)
69
70
  tmp=new_tmp()
70
71
  @new_stmts << Assign.new(tmp,OP_ASSIGN,cond)
71
72
  ret.cond=tmp
73
+ when Parenth
74
+ cond=ite.cond.accept(self)
75
+ ret.cond=cond.expr
72
76
  end
73
77
  ret
74
78
  end
@@ -76,14 +80,14 @@ module Crokus
76
80
  def visitBinary bin,args=nil
77
81
  ret=Binary.new(bin.lhs,bin.op,bin.rhs)
78
82
  ret.lhs=bin.lhs.accept(self)
79
- if bin.lhs.respond_to? :lhs #Binary,Indexed,etc
83
+ if bin.lhs.respond_to?(:lhs) or bin.lhs.is_a?(FunCall)#Binary,Indexed,etc
80
84
  #lhs=bin.lhs.accept(self)
81
85
  tmp=new_tmp()
82
86
  @new_stmts << Assign.new(tmp,OP_ASSIGN,ret.lhs)
83
87
  ret.lhs=tmp
84
88
  end
85
89
  ret.rhs=bin.rhs.accept(self)
86
- if bin.rhs.respond_to? :lhs #Binary,Indexed,etc
90
+ if bin.rhs.respond_to?(:lhs) or bin.rhs.is_a?(FunCall) #Binary,Indexed,etc
87
91
  # rhs=bin.rhs.accept()
88
92
  tmp=new_tmp()
89
93
  @new_stmts << Assign.new(tmp,OP_ASSIGN,ret.rhs)
@@ -104,6 +108,30 @@ module Crokus
104
108
  return ret
105
109
  end
106
110
 
111
+ def visitParenth par,args=nil
112
+ ret=Parenth.new(par.expr)
113
+ e=par.expr.accept(self)
114
+ tmp=new_tmp()
115
+ @new_stmts << Assign.new(tmp,OP_ASSIGN,e)
116
+ ret.expr=tmp
117
+ return ret
118
+ end
119
+
120
+ # TBC
121
+ def visitCondExpr ternary,args=nil
122
+ cond=ternary.cond.accept(self)
123
+ lhs=ternary.lhs.accept(self)
124
+ rhs=ternary.rhs.accept(self)
125
+ CondExpr.new(cond,lhs,rhs)
126
+ end
127
+
128
+ # def visitFunCall fcall,args=nil
129
+ # fcall_n=super(fcall)
130
+ # fcall_n.args=fcall.args.collect{|arg| arg.accept(self)}
131
+ # tmp=new_tmp()
132
+ # @new_stmts << Assign.new(tmp,OP_ASSIGN,fcall_n)
133
+ # return tmp
134
+ # end
107
135
 
108
136
  end
109
137
  end
@@ -4,7 +4,7 @@ class Token
4
4
  @kind,@val,@pos=*tab
5
5
  end
6
6
 
7
- def is_a? kind
7
+ def is? kind
8
8
  case kind
9
9
  when Symbol
10
10
  return @kind==kind
@@ -37,9 +37,15 @@ class Token
37
37
  alias :str :val
38
38
  end
39
39
 
40
- ONE = Token.new [:int_lit,'1' ,['na','na']]
41
- ZERO = Token.new [:int_lit,'0' ,['na','na']]
42
- DUMMY= Token.new [:id ,'' ,['na','na']]
43
- EQUAL= Token.new [:eq ,'==' ,['na','na']]
44
- ASSIGN= Token.new [:assign ,'=' ,['na','na']]
45
- MOD = Token.new [:mod ,'%' ,['na','na']]
40
+ INT = Token.new [:int ,'int' ,['na','na']]
41
+ ONE = Token.new [:int_lit,'1' ,['na','na']]
42
+ ZERO = Token.new [:int_lit,'0' ,['na','na']]
43
+ T42 = Token.new [:int_lit,'42' ,['na','na']]
44
+ DUMMY= Token.new [:id ,'' ,['na','na']]
45
+ EQUAL= Token.new [:eq ,'==' ,['na','na']]
46
+ ASSIGN= Token.new [:assign ,'=' ,['na','na']]
47
+ XOR = Token.new [:xor ,'^' ,['na','na']]
48
+ AND = Token.new [:and ,'&' ,['na','na']]
49
+ MOD = Token.new [:mod ,'%' ,['na','na']]
50
+ SUB = Token.new [:sub ,'%' ,['na','na']]
51
+ GT = Token.new [:gt ,'>' ,['na','na']]
@@ -17,7 +17,7 @@ module Crokus
17
17
  end
18
18
 
19
19
  def transform ast
20
- ast.accept(self)
20
+ new_ast=ast.accept(self)
21
21
  end
22
22
 
23
23
  alias :visit :transform
@@ -249,6 +249,13 @@ module Crokus
249
249
  Unary.new(op,rhs,unary.postfix)
250
250
  end
251
251
 
252
+ def visitCondExpr ternary,args=nil
253
+ cond=ternary.cond.accept(self)
254
+ lhs=ternary.lhs.accept(self)
255
+ rhs=ternary.rhs.accept(self)
256
+ CondExpr.new(cond,lhs,rhs)
257
+ end
258
+
252
259
  def visitParenth par,args=nil
253
260
  e=par.expr.accept(self)
254
261
  Parenth.new(e)
@@ -0,0 +1,134 @@
1
+ require_relative 'code'
2
+ require_relative 'transformer'
3
+
4
+ module Crokus
5
+
6
+ class TrojanInserter < Transformer
7
+
8
+ def insert ast
9
+ @nb_trojans=0
10
+ new_ast=transform(ast)
11
+ if @nb_trojans>0
12
+ puts "insertion succeeded : #{@nb_trojans} trojan(s)"
13
+ return new_ast
14
+ else
15
+ puts "insertion failed"
16
+ end
17
+ nil
18
+ end
19
+
20
+ def new_ident
21
+ @tmp_id||=0
22
+ tok=Token.create "$"+@tmp_id.to_s
23
+ @tmp_id+=1
24
+ Ident.new(tok)
25
+ end
26
+
27
+ def visitFunction func,args=nil
28
+ puts "[+] func #{func.name}"
29
+ func_troj=super(func,args)
30
+ success=insert_trojan(func_troj)
31
+ @nb_trojans+=1 if success
32
+ func_troj
33
+ end
34
+
35
+ def bodies_collect func
36
+ bodies=[]
37
+ bodies << func.body
38
+ bodies << bodies_rec_collect(func.body)
39
+ bodies.flatten!
40
+ bodies
41
+ end
42
+
43
+ def bodies_rec_collect body
44
+ bodies=[]
45
+ body.each do |stmt|
46
+ case if_=for_=while_=dowhile_=switch_=stmt
47
+ when If
48
+ bodies << if_.body
49
+ if else_=if_.else
50
+ bodies << else_.body
51
+ end
52
+ when For
53
+ bodies << for_.body
54
+ when While, DoWhile
55
+ bodies << stmt.body
56
+ when Switch
57
+ bodies << switch_.cases.collect{|case_| case_.body}
58
+ end
59
+ end
60
+ result = []
61
+ result << bodies
62
+ result << bodies.collect{|bod| bodies_rec_collect(bod)}
63
+ result.flatten
64
+ end
65
+
66
+ def insert_trojan func
67
+ bodies=bodies_collect(func)
68
+ puts "#bodies = #{bodies.size}"
69
+ target_body=bodies.sample
70
+ stmts=target_body.stmts
71
+ nb_decls=stmts.select{|stmt| stmt.is_a? Decl}.size
72
+ pos=rand(nb_decls..stmts.size-1)
73
+ if trojan=build_trojan(func)
74
+ target_body.stmts=stmts.insert(pos,trojan)
75
+ return success=true
76
+ end
77
+ success=false
78
+ end
79
+
80
+ INT_TYPE=Type.new(INT)
81
+
82
+ def build_trojan func
83
+ trojan=Body.new
84
+ anchor_var=choose_anchor(func)
85
+ return unless anchor_var
86
+ u_=Ident.new(Token.create("u_"))
87
+ v_=Ident.new(Token.create("v_"))
88
+ i_=Ident.new(Token.create("i_"))
89
+ trojan << Assign.new(v_,ASSIGN,anchor_var)
90
+ trojan<< if_trigger=build_trigger(func)
91
+ return unless if_trigger
92
+ trojan << Assign.new(anchor_var,ASSIGN,v_)
93
+ ast_trojan=Crokus::Parser.new.parse(TROJAN)
94
+ body_trojan=ast_trojan.list.first.body # root/func/body
95
+ if_trigger.body=body_trojan
96
+ func.body.stmts.insert(0,Decl.new(INT_TYPE,u_))
97
+ func.body.stmts.insert(0,Decl.new(INT_TYPE,v_))
98
+ func.body.stmts.insert(0,Decl.new(INT_TYPE,i_))
99
+ trojan
100
+ end
101
+
102
+ def choose_anchor func
103
+ # find a var of type int in func local declaration
104
+ decls=func.body.select{|stmt| stmt.is_a? Decl}
105
+ int_decls=decls.select{|decl| decl.type.name.is_a?(Token) && decl.type.name.kind==:int}
106
+ vars=int_decls.map{|decl| decl.var}
107
+ return vars.sample
108
+ end
109
+
110
+ TROJAN=%{
111
+ void trojan(){
112
+ u_=v_>0?v_:-v_;
113
+ for(i_=0;i_<339;i_++)
114
+ u_=(u_%2==0)?u_/=2:3*u_+1;
115
+ while u_>1 u_=u_/2;
116
+ v_*=u_;
117
+ }
118
+ }
119
+
120
+ def build_trigger func
121
+ args=find_int_arg(func)
122
+ return unless args.size>1
123
+ cond=Binary.new(Parenth.new(Binary.new(args[0],AND,args[1])),EQUAL,T42)
124
+ If.new(cond,nil)
125
+ end
126
+
127
+ def find_int_arg func
128
+ func.args.select do |arg|
129
+ (tok=arg.type.name).is_a?(Token) && tok.is?(:int)
130
+ end
131
+ end
132
+
133
+ end
134
+ end
@@ -1,3 +1,3 @@
1
1
  module Crokus
2
- VERSION="0.0.7"
2
+ VERSION="0.0.10"
3
3
  end
@@ -59,7 +59,7 @@ module Crokus
59
59
 
60
60
  def visitType type,args=nil
61
61
  indent "Type"
62
- type.specifiers.each{|spec| spec.accept(self)}
62
+ type.precisions.each{|precision| precision.accept(self)}
63
63
  type.name.accept(self)
64
64
  dedent
65
65
  type
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: crokus
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.7
4
+ version: 0.0.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jean-Christophe Le Lann
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-11-20 00:00:00.000000000 Z
11
+ date: 2020-02-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: distribution
@@ -70,6 +70,7 @@ files:
70
70
  - lib/crokus/tac_builder.rb
71
71
  - lib/crokus/token.rb
72
72
  - lib/crokus/transformer.rb
73
+ - lib/crokus/trojan_inserter.rb
73
74
  - lib/crokus/version.rb
74
75
  - lib/crokus/visitor.rb
75
76
  homepage: https://github.com/JC-LL/crokus