crokus 0.0.10 → 0.1.0

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: bca020ee93a39e7a8bea529c45ede29dc579f3a6536cea6999d497ffb985c1a0
4
- data.tar.gz: 3d78efcd9e0b963791963ae7f02bd16dc51e3f22a7e13ceda0fc5552d775a7ac
3
+ metadata.gz: be5b5ebda83413fed630ed6069d00528c985cc2a29b7d977e5a3ce31b781e267
4
+ data.tar.gz: 2f450a1c765c7aed5f4707f50b83bdf6d3ec1f9b8e4e5bc2173a41f1c21be556
5
5
  SHA512:
6
- metadata.gz: 10d5d9e59e156d4426f5cfc6145e5268188eddf73e70c455986360d6d74782ceefcaadce3154b00aa5bed6f678fa5c77317983f3d4d3ac64f4742293fcf1cf44
7
- data.tar.gz: a7eb869b9536a8932975efd2378d283a5e5a3fd9bf337a8be64e441929a53f28fa4daa59d06a51cca507840474cf2b6c96f67147bd6281bf56c75db723b63854
6
+ metadata.gz: 1b0788d72e8c057b4c2a01581a164e106b33c21c122e2de6a77751e264fdd173f11b5a43044dced72e389eceabf78c4d601912067c486b7a6fc794d94e1c17b7
7
+ data.tar.gz: 8ff0cc75ee7c2866f611e324439ac278b9c01d57e9df14bfc14cdd8d7c6047ffad0f6a1991caf03f126bce65e098946bb6ece4811e777d02a0fe4416169cdbab
data/lib/crokus/ast.rb CHANGED
@@ -1,3 +1,4 @@
1
+
1
2
  module Crokus
2
3
 
3
4
  class Ast
@@ -46,9 +47,9 @@ module Crokus
46
47
  end
47
48
 
48
49
  class Define < Ast
49
- attr_accessor :name,:expr
50
- def initialize n,e
51
- @name,@expr=n,e
50
+ attr_accessor :name,:args,:expr
51
+ def initialize n,a,e
52
+ @name,@args,@expr=n,a,e
52
53
  end
53
54
  end
54
55
 
@@ -425,7 +426,14 @@ module Crokus
425
426
  end
426
427
 
427
428
  class IntLit < Literal
429
+ def to_i
430
+ tok.val.to_i
431
+ end
428
432
  end
433
+ require_relative 'token'
434
+
435
+ ZERO_LIT=IntLit.new(ZERO)
436
+ ONE_LIT=IntLit.new(ONE)
429
437
 
430
438
  class FloatLit < Literal
431
439
  end
data/lib/crokus/cfg.rb CHANGED
@@ -35,8 +35,8 @@ module Crokus
35
35
  @bbs << bb
36
36
  end
37
37
 
38
- def print verbose=true
39
- CFGPrinter.new.print(self,verbose)
38
+ def print
39
+ CFGPrinter.new.print(self,5)
40
40
  end
41
41
 
42
42
  end
@@ -18,7 +18,7 @@ module Crokus
18
18
  end
19
19
 
20
20
  def visitFunction func,args=nil
21
- puts " |--> visitFunction '#{func.name}'" unless $options[:mute]
21
+ puts " |--[+] visitFunction '#{func.name}'" unless $options[:mute]
22
22
  @cfg=CFG.new(func.name)
23
23
  @current=@cfg.starter
24
24
  func.body.accept(self)
@@ -26,7 +26,7 @@ module Crokus
26
26
  @cfg=CFGCleaner.new.clean(@cfg)
27
27
  @cfg.name=Ident.new(Token.create "#{@cfg.name}_clean")
28
28
  func.cfg=@cfg
29
- puts "\t|--> cfg size for '#{func.name}' : #{@cfg.size}" unless $options[:mute]
29
+ puts " "*5+"|--[+] cfg size for '#{func.name}' : #{@cfg.size}" unless $options[:mute]
30
30
  @cfg.print
31
31
  end
32
32
 
@@ -38,6 +38,10 @@ module Crokus
38
38
  @current << assign
39
39
  end
40
40
 
41
+ def visitLabeledStmt assign,args=nil
42
+ @current << assign
43
+ end
44
+
41
45
  def visitPreFixAccu accu,args=nil
42
46
  @current << accu
43
47
  end
@@ -3,7 +3,7 @@ module Crokus
3
3
  class CFGCleaner
4
4
 
5
5
  def clean cfg
6
- puts "\t|--> cleaning '#{cfg.name}'" unless $options[:mute]
6
+ puts " "*5+"|--[+] cleaning '#{cfg.name}'" unless $options[:mute]
7
7
  @cfg=cfg
8
8
  @visited=[]
9
9
  @new_succs={}
@@ -6,7 +6,7 @@ module Crokus
6
6
 
7
7
  attr_accessor :code
8
8
 
9
- def print cfg,verbose=$options[:mute]!=true
9
+ def print cfg,pos=0
10
10
  @code=Code.new
11
11
  @code << header
12
12
  @visited=[]
@@ -14,7 +14,7 @@ module Crokus
14
14
  @code << footer
15
15
  dot_name="cfg_#{cfg.name}.dot"
16
16
  @code.save_as dot_name
17
- puts "\t|--> graphviz file saved as '#{dot_name}'" if verbose
17
+ puts " "*pos+"|--[+] graphviz file saved as '#{dot_name}'"
18
18
  end
19
19
 
20
20
  def header
data/lib/crokus/code.rb CHANGED
@@ -28,6 +28,10 @@ class Code
28
28
  ""
29
29
  end
30
30
 
31
+ def to_s
32
+ finalize
33
+ end
34
+
31
35
  def newline
32
36
  @lines << " "
33
37
  end
@@ -47,7 +47,7 @@ module Crokus
47
47
  def parse filename
48
48
  @base_name=File.basename(filename, ".c")
49
49
  code=IO.read(filename)
50
- puts "=> parsing #{filename}" unless options[:mute]
50
+ puts "[+] parsing #{filename}" unless options[:mute]
51
51
  @ast=Parser.new.parse(code)
52
52
  draw_ast if options[:draw_ast]
53
53
  pretty_print if options[:pp]
@@ -55,46 +55,46 @@ module Crokus
55
55
 
56
56
  def draw_ast tree=nil,filename=nil
57
57
  dotname=filename || "#{base_name}.dot"
58
- puts " |--> drawing AST '#{dotname}'" unless options[:mute]
58
+ puts " |--[+] drawing AST '#{dotname}'" unless options[:mute]
59
59
  ast_ = tree || @ast
60
60
  dot=AstPrinter.new.print(ast_)
61
61
  dot.save_as dotname
62
62
  end
63
63
 
64
64
  def transform
65
- puts "=> dummy transform" unless options[:mute]
65
+ puts "[+] dummy transform" unless options[:mute]
66
66
  ast_t= Transformer.new.transform(ast)
67
67
  dotname="#{base_name}_trans.dot"
68
68
  draw_ast ast_t,dotname
69
69
  end
70
70
 
71
71
  def visit
72
- puts "=> dummy visit" unless options[:mute]
72
+ puts "[+] dummy visit" unless options[:mute]
73
73
  Visitor.new.visit(ast)
74
74
  end
75
75
 
76
76
  def pretty_print
77
- puts "=> pretty_print" unless options[:mute]
77
+ puts "[+] pretty_print" unless options[:mute]
78
78
  code=PrettyPrinter.new.visit(ast)
79
79
  pp_c=@base_name+"_pp.c"
80
80
  File.open(pp_c,'w'){|f| f.puts code}
81
- puts " |--> saved as #{pp_c}" unless options[:mute]
81
+ puts " "*1+"|--[+] saved as #{pp_c}" unless options[:mute]
82
82
  end
83
83
 
84
84
  def build_cfg
85
- puts "=> building CFGs" unless options[:mute]
85
+ puts "[+] building CFGs" unless options[:mute]
86
86
  builder=CFGBuilder.new
87
87
  builder.build(ast)
88
88
  end
89
89
 
90
90
  def build_tac
91
- puts "=> building TAC" unless options[:mute]
91
+ puts "[+] building TAC" unless options[:mute]
92
92
  builder=TACBuilder.new
93
93
  builder.visit(ast)
94
94
  end
95
95
 
96
96
  def emit_ir
97
- puts "=> emit textual IR " unless options[:mute]
97
+ puts "[+] emit textual IR " unless options[:mute]
98
98
  IRDumper.new.visit(ast)
99
99
  end
100
100
 
@@ -103,7 +103,7 @@ module Crokus
103
103
  end
104
104
 
105
105
  def insert_trojan
106
- puts "=> inserting trojan" unless options[:mute]
106
+ puts "[+] inserting trojan" unless options[:mute]
107
107
  infected_ast=TrojanInserter.new.insert(ast)
108
108
  if infected_ast
109
109
  code=PrettyPrinter.new.visit(infected_ast)
@@ -3,11 +3,11 @@ module Crokus
3
3
  class IRDumper < Visitor
4
4
 
5
5
  def visitFunction func,args=nil
6
- puts "[+] IR for '#{func.name}'"
6
+ puts " "*1+"|--[+] IR for '#{func.name}'"
7
7
  ir_code=dump(func.cfg)
8
8
  filename=func.name.to_s+".ir"
9
9
  ir_code.save_as filename
10
- puts "\t generated #{filename}"
10
+ puts " "*5+"|--[+] generated #{filename}"
11
11
  end
12
12
 
13
13
  def dump cfg
data/lib/crokus/lexer.rb CHANGED
@@ -91,7 +91,7 @@ module Crokus
91
91
 
92
92
  token :ident => /\A[a-zA-Z]\w*/i
93
93
  token :float_lit => /\A\d*(\.\d+)(E([+-]?)\d+)?/
94
- token :integer_lit => /\A(0x[0-9a-fA-F]+)|\d+/
94
+ token :integer_lit => /\A((0x[0-9a-fA-F]+)|\d+)L?/
95
95
  token :string_lit => /\A"[^"]*"/
96
96
  token :char_lit => /\A'\\?.'/
97
97
  token :lexer_warning => /./
data/lib/crokus/parser.rb CHANGED
@@ -153,9 +153,20 @@ module Crokus
153
153
  expect :sharp
154
154
  expect :ident #define
155
155
  name=expect :ident
156
+ args=[]
157
+ if showNext.is? :lparen
158
+ acceptIt
159
+ while !showNext.is?(:rparen)
160
+ args << acceptIt
161
+ if showNext.is?(:comma)
162
+ acceptIt
163
+ end
164
+ end
165
+ expect :rparen
166
+ end
156
167
  e=expression()
157
168
  dedent
158
- return Define.new(name,e)
169
+ return Define.new(name,args,e)
159
170
  end
160
171
 
161
172
  def parse_struct
@@ -297,8 +308,9 @@ module Crokus
297
308
  end
298
309
 
299
310
  def parse_label
300
- expect :ident
301
- expect :colon
311
+ id=expect(:ident)
312
+ expect(:colon)
313
+ Ident.new(id)
302
314
  end
303
315
 
304
316
  def parse_goto
@@ -475,7 +487,7 @@ module Crokus
475
487
  when :typedef
476
488
  ret=typedef()
477
489
  else
478
- raise "Parsing ERROR in type declaration: '#{showNext}'"
490
+ raise "Parsing ERROR in type declaration: '#{showNext}' #{showNext.pos}"
479
491
  end
480
492
 
481
493
  while showNext.is? [:mul,:lparen]
@@ -541,7 +553,13 @@ module Crokus
541
553
  indent "parse else"
542
554
  expect :else
543
555
  ret=Else.new
544
- ret.body=statement()
556
+ stmt=statement()
557
+ case stmt
558
+ when Body
559
+ ret.body=stmt
560
+ else
561
+ ret.body=Body.new([stmt])
562
+ end
545
563
  dedent
546
564
  return ret
547
565
  end
@@ -550,8 +568,13 @@ module Crokus
550
568
  indent "parse_while"
551
569
  expect :while
552
570
  cond=expression()
553
- body=[]
554
- body=statement()
571
+ stmt=statement()
572
+ case stmt
573
+ when Body
574
+ body=stmt
575
+ else
576
+ body=Body.new([stmt])
577
+ end
555
578
  dedent
556
579
  return While.new(cond,body)
557
580
  end
@@ -566,7 +589,13 @@ module Crokus
566
589
  expect :semicolon
567
590
  forloop.increment=expression()
568
591
  expect :rparen
569
- forloop.body=statement()
592
+ stmt=statement()
593
+ case stmt
594
+ when Body
595
+ forloop.body=stmt
596
+ else
597
+ forloop.body=Body.new([stmt])
598
+ end
570
599
  dedent
571
600
  forloop
572
601
  end
@@ -667,7 +696,7 @@ module Crokus
667
696
  while showNext.is? :oror
668
697
  op=acceptIt
669
698
  e2=logand
670
- e1=Or2.new(e1,op,e2)
699
+ e1=Binary.new(e1,op,e2)
671
700
  end
672
701
  dedent
673
702
  return e1
@@ -786,7 +815,6 @@ module Crokus
786
815
  case showNext.kind
787
816
  when :lparen # parenth expr OR casting !
788
817
  res=is_casting?
789
- puts "casting? : #{res}" if $options[:verbose]
790
818
  if res
791
819
  e=casting
792
820
  else
@@ -799,23 +827,48 @@ module Crokus
799
827
  return e
800
828
  end
801
829
 
802
- def is_casting?
803
- i=0
804
- tok=DUMMY
805
- while tok.kind!=:rparen
806
- tok=@tokens[i]
807
- i+=1
830
+ def castexp
831
+ #puts "castexpr : #{pp @tokens[0..3]}"
832
+ case showNext.kind
833
+ when :lparen # parenth expr OR casting !
834
+ res=is_casting?
835
+ #puts "casting=#{res}"
836
+ if res
837
+ e=casting
838
+ else
839
+ e=parenthesized
840
+ end
841
+ else
842
+ e=unary
808
843
  end
809
- tok=@tokens[i]
810
- return false if tok.is? [:mul,:add,:sub]
811
- return true if tok.is? STARTERS_UNARY-STARTERS_ARRAY_OR_STRUCT_INIT
812
- return false
844
+ dedent
845
+ return e
813
846
  end
814
847
 
848
+ def is_casting?
849
+ #puts "is_casting? : #{pp @tokens[0..1]}"
850
+ cond1= @tokens[0].is?(:lparen)
851
+ cond2= @tokens[1].is?([:int,:uint,:short,:byte,:float,:long])
852
+ cond1 and cond2
853
+ end
854
+
855
+ # def is_casting?
856
+ # i=0
857
+ # tok=DUMMY
858
+ # while tok.kind!=:rparen
859
+ # tok=@tokens[i]
860
+ # i+=1
861
+ # end
862
+ # pp tok=@tokens[i]
863
+ # return false if tok.is? [:mul,:add,:sub]
864
+ # pp cond=STARTERS_UNARY-STARTERS_ARRAY_OR_STRUCT_INIT
865
+ # return true if tok.is? cond
866
+ # return false
867
+ # end
868
+
815
869
  def casting
816
870
  puts "casting : #{showNext}" if $options[:verbose]
817
871
  expect :lparen
818
- #typename
819
872
  t=parse_type
820
873
  expect :rparen
821
874
  u=unary
@@ -934,7 +987,7 @@ module Crokus
934
987
  when :sizeof
935
988
  u=sizeof()
936
989
  else
937
- raise "not an unary"
990
+ raise "not an unary. showNext : #{showNext}"
938
991
  end
939
992
  end
940
993
  return u
@@ -329,11 +329,10 @@ module Crokus
329
329
  return "continue;"
330
330
  end
331
331
 
332
- def visitLabeledStmt label,args=nil
333
- stmt=label.stmt.accept(self)
334
- code=Code.new
335
- code << stmt
336
- return code
332
+ def visitLabeledStmt lstmt,args=nil
333
+ label=lstmt.label.accept(self)
334
+ stmt =lstmt.stmt.accept(self)
335
+ ret="#{label} : #{stmt.to_s}"
337
336
  end
338
337
 
339
338
  def visitGoto goto,args=nil
data/lib/crokus/runner.rb CHANGED
@@ -69,8 +69,12 @@ 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
72
+ # parser.on('--trojan PARAMS', "generates random c files, using parameters", String) do |params_filename|
73
+ # options[:trojan] = params_filename
74
+ # end
75
+
76
+ parser.on('--trojan', "generates random c files, using parameters") do
77
+ options[:trojan] = true
74
78
  end
75
79
 
76
80
  parser.on("--vv", "verbose") do
@@ -5,7 +5,7 @@ module Crokus
5
5
  OP_ASSIGN=Token.new([:assign,"=",[0,0]])
6
6
 
7
7
  def visitFunction func,args=nil
8
- puts " |--> tac builder for '#{func.name}'"
8
+ puts " "*1+"|--[+] tac builder for '#{func.name}'"
9
9
  build func.cfg
10
10
  end
11
11
 
@@ -19,6 +19,7 @@ module Crokus
19
19
  end
20
20
 
21
21
  def new_tmp
22
+ @tmp_id||=0
22
23
  tok=Token.create "$"+@tmp_id.to_s
23
24
  @tmp_id+=1
24
25
  tok
@@ -112,6 +113,7 @@ module Crokus
112
113
  ret=Parenth.new(par.expr)
113
114
  e=par.expr.accept(self)
114
115
  tmp=new_tmp()
116
+ @new_stmts||=[]
115
117
  @new_stmts << Assign.new(tmp,OP_ASSIGN,e)
116
118
  ret.expr=tmp
117
119
  return ret
@@ -42,8 +42,9 @@ module Crokus
42
42
 
43
43
  def visitDefine define,args=nil
44
44
  name=define.name.accept(self)
45
+ args=define.args.map{|arg| arg.accept(self)}
45
46
  expr=define.expr.accept(self)
46
- Define.new(name,expr)
47
+ Define.new(name,args,expr)
47
48
  end
48
49
 
49
50
  def visitTypedef typdef,args=nil
@@ -113,6 +114,12 @@ module Crokus
113
114
  end
114
115
 
115
116
  #...........stmts...............
117
+ def visitLabeledStmt lstmt,args=nil
118
+ label=lstmt.label.accept(self)
119
+ stmt=lstmt.stmt.accept(self)
120
+ LabeledStmt.new(label,stmt)
121
+ end
122
+
116
123
  def visitCommaStmt comma,args=nil
117
124
  lhs=comma.lhs.accept(self)
118
125
  rhs=comma.rhs.accept(self)
@@ -9,10 +9,10 @@ module Crokus
9
9
  @nb_trojans=0
10
10
  new_ast=transform(ast)
11
11
  if @nb_trojans>0
12
- puts "insertion succeeded : #{@nb_trojans} trojan(s)"
12
+ puts " "*1+"|--[+] insertion succeeded : #{@nb_trojans} trojan(s)"
13
13
  return new_ast
14
14
  else
15
- puts "insertion failed"
15
+ puts " "*1+"|--[?] insertion failed"
16
16
  end
17
17
  nil
18
18
  end
@@ -25,13 +25,27 @@ module Crokus
25
25
  end
26
26
 
27
27
  def visitFunction func,args=nil
28
- puts "[+] func #{func.name}"
28
+ puts " "*1+"|--[+] func #{func.name}"
29
29
  func_troj=super(func,args)
30
30
  success=insert_trojan(func_troj)
31
31
  @nb_trojans+=1 if success
32
32
  func_troj
33
33
  end
34
34
 
35
+ def insert_trojan func
36
+ if trojan=build_trojan(func)
37
+ bodies=bodies_collect(func)
38
+ puts "\t#bodies = #{bodies.size}"
39
+ target_body=bodies.sample
40
+ stmts=target_body.stmts
41
+ nb_decls=stmts.select{|stmt| stmt.is_a? Decl}.size
42
+ pos=rand(nb_decls-1..stmts.size-1)+1
43
+ target_body.stmts=stmts.insert(pos,trojan)
44
+ return success=true
45
+ end
46
+ success=false
47
+ end
48
+
35
49
  def bodies_collect func
36
50
  bodies=[]
37
51
  bodies << func.body
@@ -55,6 +69,8 @@ module Crokus
55
69
  bodies << stmt.body
56
70
  when Switch
57
71
  bodies << switch_.cases.collect{|case_| case_.body}
72
+ when Body
73
+ bodies << bodies_rec_collect(stmt)
58
74
  end
59
75
  end
60
76
  result = []
@@ -63,20 +79,6 @@ module Crokus
63
79
  result.flatten
64
80
  end
65
81
 
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
82
  INT_TYPE=Type.new(INT)
81
83
 
82
84
  def build_trojan func
@@ -119,16 +121,39 @@ module Crokus
119
121
 
120
122
  def build_trigger func
121
123
  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
+ arg_names=get_arg_names(args)
125
+ return unless arg_names.size>1
126
+ cond=Binary.new(Parenth.new(Binary.new(arg_names[0],AND,arg_names[1])),EQUAL,T42)
124
127
  If.new(cond,nil)
125
128
  end
126
129
 
127
130
  def find_int_arg func
128
131
  func.args.select do |arg|
129
- (tok=arg.type.name).is_a?(Token) && tok.is?(:int)
132
+ cond1=(tok=arg.type.name).is_a?(Token) && tok.is?(:int)
133
+ cond2=(atype=arg.type).is_a?(ArrayOf) && (tok=atype.name.name).is_a?(Token) && tok.is?(:int)
134
+ cond1 or cond2
130
135
  end
131
136
  end
132
137
 
138
+ def get_arg_names args
139
+ ret=[]
140
+ ret << args.map{|formal_arg|
141
+ case (type=formal_arg.type)
142
+ when ArrayOf
143
+ if type.size.is_a?(IntLit)
144
+ array_size=type.size.to_i
145
+ if array_size>1
146
+ ret << Indexed.new(formal_arg.name,ZERO_LIT)
147
+ ret << Indexed.new(formal_arg.name,ONE_LIT)
148
+ end
149
+ end
150
+ else
151
+ formal_arg.name
152
+ end
153
+ }
154
+ ret.flatten!
155
+ end
156
+
157
+
133
158
  end
134
159
  end
@@ -1,3 +1,3 @@
1
1
  module Crokus
2
- VERSION="0.0.10"
2
+ VERSION="0.1.0"
3
3
  end
@@ -266,6 +266,15 @@ module Crokus
266
266
  lit
267
267
  end
268
268
 
269
+ def visitCondExpr cexpr,args=nil
270
+ indent "condexpr"
271
+ cexpr.cond.accept(self)
272
+ cexpr.lhs.accept(self,args)
273
+ cexpr.rhs.accept(self,args)
274
+ dedent
275
+ cexpr
276
+ end
277
+
269
278
  def visitBinary expr,args=nil
270
279
  indent "Binary"
271
280
  expr.lhs.accept(self,args)
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.10
4
+ version: 0.1.0
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: 2020-02-04 00:00:00.000000000 Z
11
+ date: 2020-02-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: distribution