crokus 0.0.10 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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