crokus 0.0.7 → 0.0.10
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/crokus/ast.rb +8 -0
- data/lib/crokus/cfg_random_gen.rb +1 -1
- data/lib/crokus/cleaner.rb +4 -1
- data/lib/crokus/compiler.rb +24 -4
- data/lib/crokus/generic_lexer.rb +1 -1
- data/lib/crokus/ir_dumper.rb +12 -7
- data/lib/crokus/parser.rb +61 -60
- data/lib/crokus/pretty_printer.rb +11 -4
- data/lib/crokus/runner.rb +4 -0
- data/lib/crokus/tac_builder.rb +33 -5
- data/lib/crokus/token.rb +13 -7
- data/lib/crokus/transformer.rb +8 -1
- data/lib/crokus/trojan_inserter.rb +134 -0
- data/lib/crokus/version.rb +1 -1
- data/lib/crokus/visitor.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bca020ee93a39e7a8bea529c45ede29dc579f3a6536cea6999d497ffb985c1a0
|
4
|
+
data.tar.gz: 3d78efcd9e0b963791963ae7f02bd16dc51e3f22a7e13ceda0fc5552d775a7ac
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 10d5d9e59e156d4426f5cfc6145e5268188eddf73e70c455986360d6d74782ceefcaadce3154b00aa5bed6f678fa5c77317983f3d4d3ac64f4742293fcf1cf44
|
7
|
+
data.tar.gz: a7eb869b9536a8932975efd2378d283a5e5a3fd9bf337a8be64e441929a53f28fa4daa59d06a51cca507840474cf2b6c96f67147bd6281bf56c75db723b63854
|
data/lib/crokus/ast.rb
CHANGED
data/lib/crokus/cleaner.rb
CHANGED
data/lib/crokus/compiler.rb
CHANGED
@@ -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(
|
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(
|
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(
|
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
|
data/lib/crokus/generic_lexer.rb
CHANGED
data/lib/crokus/ir_dumper.rb
CHANGED
@@ -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}'"
|
7
|
-
dump
|
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
|
-
|
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
|
-
|
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
|
-
|
31
|
+
@code << "\tgoto #{bb.succs.first.label}"
|
27
32
|
end
|
28
33
|
end
|
29
34
|
if bb.succs.empty?
|
30
|
-
|
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
|
data/lib/crokus/parser.rb
CHANGED
@@ -24,7 +24,7 @@ module Crokus
|
|
24
24
|
end
|
25
25
|
|
26
26
|
def maybe kind
|
27
|
-
return acceptIt if showNext.
|
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.
|
73
|
+
warnings=@tokens.select{|tok| tok.is? :lexer_warning}
|
73
74
|
show_lexer_warnings(warnings)
|
74
|
-
@tokens=@tokens.select{|tok| !tok.
|
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.
|
165
|
+
if showNext.is? :ident
|
165
166
|
name=acceptIt
|
166
167
|
end
|
167
168
|
ret=Struct.new(name)
|
168
|
-
if showNext.
|
169
|
+
if showNext.is? :lbrace
|
169
170
|
acceptIt
|
170
|
-
while !showNext.
|
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.
|
209
|
+
while !showNext.is? :rparen
|
209
210
|
args << func_formal_arg()
|
210
|
-
if !showNext.
|
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
|
-
|
225
|
-
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
425
|
+
while showNext.is? :lbrack
|
425
426
|
acceptIt
|
426
|
-
if showNext.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
523
|
+
if showNext.is? :lbrace
|
523
524
|
lbrace=acceptIt
|
524
525
|
end
|
525
526
|
body << statement()
|
526
527
|
if lbrace
|
527
|
-
until showNext.
|
528
|
+
until showNext.is? :rbrace
|
528
529
|
body << statement
|
529
530
|
end
|
530
531
|
expect :rbrace
|
531
532
|
end
|
532
|
-
if showNext.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
810
|
-
return true if tok.
|
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.
|
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.
|
846
|
-
if showNext.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
1040
|
+
while !showNext.is? :rbrace
|
1040
1041
|
elements << (e=expression)
|
1041
|
-
if showNext.
|
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
|
-
|
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
|
data/lib/crokus/runner.rb
CHANGED
@@ -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
|
data/lib/crokus/tac_builder.rb
CHANGED
@@ -28,12 +28,12 @@ module Crokus
|
|
28
28
|
@visited << bb
|
29
29
|
@current=bb
|
30
30
|
@new_stmts=[]
|
31
|
-
|
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
|
-
|
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?
|
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?
|
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
|
data/lib/crokus/token.rb
CHANGED
@@ -4,7 +4,7 @@ class Token
|
|
4
4
|
@kind,@val,@pos=*tab
|
5
5
|
end
|
6
6
|
|
7
|
-
def
|
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
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
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']]
|
data/lib/crokus/transformer.rb
CHANGED
@@ -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
|
data/lib/crokus/version.rb
CHANGED
data/lib/crokus/visitor.rb
CHANGED
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.
|
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:
|
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
|