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 +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
|