crokus 0.1.1 → 0.1.7
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 +4 -0
- data/lib/crokus/cfg.rb +1 -1
- data/lib/crokus/cfg_builder.rb +10 -0
- data/lib/crokus/cfg_cleaner.rb +1 -1
- data/lib/crokus/cfg_optim.rb +31 -0
- data/lib/crokus/cfg_printer.rb +1 -0
- data/lib/crokus/cfg_printer_c.rb +7 -5
- data/lib/crokus/cfg_random_gen.rb +8 -3
- data/lib/crokus/cleaner.rb +8 -3
- data/lib/crokus/compiler.rb +5 -3
- data/lib/crokus/parser.rb +2 -1
- data/lib/crokus/pretty_printer.rb +1 -1
- data/lib/crokus/runner.rb +7 -5
- data/lib/crokus/trojan_inserter.rb +47 -9
- data/lib/crokus/version.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: b690523ea19dfb9b7eaa5f0569ab5b4d9cba857ca8e4a451907af3b28c7749c7
|
4
|
+
data.tar.gz: 2313aac03fc005f09dbee2925a64738e0c85fe0a343f1de0a426ce73a9307eab
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3b8be391422d91f28ffc75c0d86f00098f9ba17f2d64a277a28dee774348bb725b558a1a469d11831d07ac58f9dbab3a08a37779f3c4a3672aa06f6f94374041
|
7
|
+
data.tar.gz: 89aeab45274244cadd1758cd17a2ca2364db45ec3b3f1ed748caf2c6a6840cf9c9a9a99cf0e4f6a90844a2c623f0315bb26c7195650dd55c2675367f805b164e
|
data/lib/crokus/ast.rb
CHANGED
data/lib/crokus/cfg.rb
CHANGED
data/lib/crokus/cfg_builder.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require_relative 'cfg'
|
2
2
|
require_relative 'cfg_cleaner'
|
3
|
+
require_relative 'cfg_optim'
|
3
4
|
|
4
5
|
require_relative 'visitor'
|
5
6
|
require_relative 'cleaner'
|
@@ -24,6 +25,7 @@ module Crokus
|
|
24
25
|
func.body.accept(self)
|
25
26
|
@cfg.print
|
26
27
|
@cfg=CFGCleaner.new.clean(@cfg)
|
28
|
+
@cfg=CFGOptimizer.new.clean(@cfg)
|
27
29
|
@cfg.name=Ident.new(Token.create "#{@cfg.name}_clean")
|
28
30
|
func.cfg=@cfg
|
29
31
|
puts " "*5+"|--[+] cfg size for '#{func.name}' : #{@cfg.size}" unless $options[:mute]
|
@@ -126,6 +128,10 @@ module Crokus
|
|
126
128
|
@current=falseBranch
|
127
129
|
end
|
128
130
|
|
131
|
+
def visitFunCall fcall,args=nil
|
132
|
+
@current << fcall
|
133
|
+
end
|
134
|
+
|
129
135
|
def visitFor for_,args=nil
|
130
136
|
for_.init.each{|stmt| stmt.accept(self)}
|
131
137
|
cond=for_.cond.accept(self)
|
@@ -148,6 +154,10 @@ module Crokus
|
|
148
154
|
@current=falseBranch
|
149
155
|
end
|
150
156
|
|
157
|
+
def visitReturn ret,args=nil
|
158
|
+
@current << ret
|
159
|
+
end
|
160
|
+
|
151
161
|
def visitDoWhile dowhile,args=nil
|
152
162
|
@cfg << cond_bb = BasicBlock.new
|
153
163
|
@current_continue_dest = cond_bb # for continue stmt !
|
data/lib/crokus/cfg_cleaner.rb
CHANGED
@@ -0,0 +1,31 @@
|
|
1
|
+
module Crokus
|
2
|
+
|
3
|
+
class CFGOptimizer
|
4
|
+
|
5
|
+
def clean cfg
|
6
|
+
puts " "*5+"|--[+] optimizing cfg '#{cfg.name}'" unless $options[:mute]
|
7
|
+
@cfg=cfg
|
8
|
+
@visited=[]
|
9
|
+
@new_succs={}
|
10
|
+
optim_rec cfg.starter
|
11
|
+
cfg
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def optim_rec bb
|
17
|
+
@visited << bb
|
18
|
+
@new_succs[bb]=[]
|
19
|
+
bb.succs.each_with_index do |succ,idx|
|
20
|
+
if bb.succs.size==1 and succ.succs.size==1
|
21
|
+
bb.stmts << succ.stmts
|
22
|
+
bb.stmts.flatten!
|
23
|
+
@cfg.bbs.delete(succ)
|
24
|
+
bb.succs[0]=succ.succs.first
|
25
|
+
end
|
26
|
+
optim_rec succ unless @visited.include?(succ)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
data/lib/crokus/cfg_printer.rb
CHANGED
data/lib/crokus/cfg_printer_c.rb
CHANGED
@@ -2,15 +2,17 @@ module Crokus
|
|
2
2
|
|
3
3
|
class PrinterC
|
4
4
|
|
5
|
-
attr_accessor :cfg
|
5
|
+
attr_accessor :cfg, :options
|
6
6
|
|
7
|
-
def initialize
|
7
|
+
def initialize options={}
|
8
|
+
@options=options
|
8
9
|
@visited=[]
|
9
10
|
@prp=PrettyPrinter.new
|
10
11
|
end
|
11
12
|
|
12
13
|
def print cfg
|
13
|
-
|
14
|
+
filename= "#{cfg.name}.c"
|
15
|
+
puts " |-->[+] generating C code from cfg '#{cfg.name}' in '#{filename}'"
|
14
16
|
@cfg=cfg
|
15
17
|
code=Code.new
|
16
18
|
code << "//"+"-"*60
|
@@ -34,8 +36,8 @@ module Crokus
|
|
34
36
|
code << "}"
|
35
37
|
code.newline
|
36
38
|
code << main(cfg)
|
37
|
-
puts code.finalize
|
38
|
-
code.save_as
|
39
|
+
puts code.finalize if options[:verbose]
|
40
|
+
code.save_as filename
|
39
41
|
end
|
40
42
|
|
41
43
|
def main cfg
|
@@ -13,10 +13,15 @@ end
|
|
13
13
|
module Crokus
|
14
14
|
|
15
15
|
class RandomGen
|
16
|
+
attr_accessor :options
|
16
17
|
attr_accessor :cfg
|
17
18
|
|
19
|
+
def initialize options={}
|
20
|
+
@options=options
|
21
|
+
end
|
22
|
+
|
18
23
|
def run params
|
19
|
-
puts "[+] running random
|
24
|
+
puts "[+] running random C code generation"
|
20
25
|
puts " |-->[+] reading parameters file '#{params}'"
|
21
26
|
@params=YAML.load(File.read(params))
|
22
27
|
init_cfg
|
@@ -30,7 +35,7 @@ module Crokus
|
|
30
35
|
gen_dot # to see the structure, before hacking the content
|
31
36
|
populate_all
|
32
37
|
generate_c
|
33
|
-
|
38
|
+
print_infos
|
34
39
|
end
|
35
40
|
|
36
41
|
|
@@ -306,7 +311,7 @@ module Crokus
|
|
306
311
|
end
|
307
312
|
|
308
313
|
def generate_c
|
309
|
-
PrinterC.new.print(cfg)
|
314
|
+
PrinterC.new(options).print(cfg)
|
310
315
|
end
|
311
316
|
end
|
312
317
|
end
|
data/lib/crokus/cleaner.rb
CHANGED
@@ -1,13 +1,18 @@
|
|
1
1
|
module Crokus
|
2
2
|
class Cleaner
|
3
3
|
def clean str_c
|
4
|
-
|
5
|
-
str_c.gsub!(";;",";")
|
6
4
|
str_c.gsub!(";)",")")
|
7
5
|
str_c.gsub!(/\n+\s*\;/,";")
|
8
6
|
str_c.gsub!(/\;\s*\:/,":")
|
9
|
-
|
7
|
+
str_c.gsub!(/\n\s+\{/,"{")
|
8
|
+
str_c.gsub!(/\;+/,";")
|
10
9
|
str_c
|
11
10
|
end
|
11
|
+
|
12
|
+
def debug str_c
|
13
|
+
puts "hit a key"
|
14
|
+
$stdin.gets.chomp
|
15
|
+
puts str_c
|
16
|
+
end
|
12
17
|
end
|
13
18
|
end
|
data/lib/crokus/compiler.rb
CHANGED
@@ -28,13 +28,15 @@ module Crokus
|
|
28
28
|
parse(filename)
|
29
29
|
return true if options[:parse_only]
|
30
30
|
|
31
|
+
draw_ast(@ast) if options[:ast]
|
32
|
+
|
31
33
|
build_cfg
|
32
34
|
return true if options[:cfg]
|
33
35
|
|
34
36
|
pretty_print
|
35
37
|
|
36
38
|
if options[:trojan]
|
37
|
-
return_code=insert_trojan
|
39
|
+
return_code=insert_trojan()
|
38
40
|
return return_code
|
39
41
|
end
|
40
42
|
|
@@ -55,7 +57,7 @@ module Crokus
|
|
55
57
|
end
|
56
58
|
|
57
59
|
def draw_ast tree=nil,filename=nil
|
58
|
-
dotname=filename || "#{base_name}.dot"
|
60
|
+
dotname=filename || "#{base_name}_ast.dot"
|
59
61
|
puts " |--[+] drawing AST '#{dotname}'" unless options[:mute]
|
60
62
|
ast_ = tree || @ast
|
61
63
|
dot=AstPrinter.new.print(ast_)
|
@@ -105,7 +107,7 @@ module Crokus
|
|
105
107
|
|
106
108
|
def insert_trojan
|
107
109
|
puts "[+] inserting trojan" unless options[:mute]
|
108
|
-
infected_ast=TrojanInserter.new.insert(ast)
|
110
|
+
infected_ast=TrojanInserter.new(@options).insert(ast)
|
109
111
|
if infected_ast
|
110
112
|
code=PrettyPrinter.new.visit(infected_ast)
|
111
113
|
pp_c=@base_name+"_troj.c"
|
data/lib/crokus/parser.rb
CHANGED
@@ -68,6 +68,7 @@ module Crokus
|
|
68
68
|
begin
|
69
69
|
@str=str
|
70
70
|
@tokens=Lexer.new.tokenize(str)
|
71
|
+
#pp @tokens
|
71
72
|
@tokens=@tokens.reject{|tok| tok==[nil,nil,nil]}
|
72
73
|
@tokens=remove_comments()
|
73
74
|
warnings=@tokens.select{|tok| tok.is? :lexer_warning}
|
@@ -848,7 +849,7 @@ module Crokus
|
|
848
849
|
def is_casting?
|
849
850
|
#puts "is_casting? : #{pp @tokens[0..1]}"
|
850
851
|
cond1= @tokens[0].is?(:lparen)
|
851
|
-
cond2= @tokens[1].is?([:int,:uint,:short,:byte,:float,:long])
|
852
|
+
cond2= @tokens[1].is?([:int,:uint,:short,:byte,:float,:long,:double])
|
852
853
|
cond1 and cond2
|
853
854
|
end
|
854
855
|
|
data/lib/crokus/runner.rb
CHANGED
@@ -69,12 +69,14 @@ module Crokus
|
|
69
69
|
options[:random] = params_filename
|
70
70
|
end
|
71
71
|
|
72
|
-
#
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
72
|
+
# optional argument for --trojan
|
73
|
+
parser.on('--trojan FUNC', "insert Syracuse Trojan in function FUNC") do |target_func|
|
74
|
+
if target_func.end_with?(".c")
|
75
|
+
puts "wrong argument for --trojan . It requires a function name as argument."
|
76
|
+
abort
|
77
|
+
end
|
77
78
|
options[:trojan] = true
|
79
|
+
options[:trojan_target_func]=target_func
|
78
80
|
end
|
79
81
|
|
80
82
|
parser.on("--vv", "verbose") do
|
@@ -5,6 +5,10 @@ module Crokus
|
|
5
5
|
|
6
6
|
class TrojanInserter < Transformer
|
7
7
|
|
8
|
+
def initialize options={}
|
9
|
+
@options=options
|
10
|
+
end
|
11
|
+
|
8
12
|
def insert ast
|
9
13
|
@nb_trojans=0
|
10
14
|
new_ast=transform(ast)
|
@@ -13,6 +17,12 @@ module Crokus
|
|
13
17
|
return new_ast
|
14
18
|
else
|
15
19
|
puts " "*1+"|--[?] insertion failed"
|
20
|
+
if func=@options[:trojan_target_func] and @target_reached.nil?
|
21
|
+
puts " "*5+"|-- no function named '#{func}' found"
|
22
|
+
end
|
23
|
+
if @failure_reason
|
24
|
+
puts " "*5+"|-- #{@failure_reason}"
|
25
|
+
end
|
16
26
|
end
|
17
27
|
nil
|
18
28
|
end
|
@@ -25,12 +35,20 @@ module Crokus
|
|
25
35
|
end
|
26
36
|
|
27
37
|
def visitFunction func,args=nil
|
28
|
-
puts " "*1+"|--[+] func #{func.name}"
|
29
38
|
func_troj=super(func,args)
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
39
|
+
if @options[:trojan_target_func].nil? or (name=@options[:trojan_target_func] and target_reached=(func.name.to_s==name))
|
40
|
+
puts " "*1+"|--[+] func #{func.name}"
|
41
|
+
if target_reached
|
42
|
+
@target_reached=true
|
43
|
+
end
|
44
|
+
success=insert_trojan(func_troj)
|
45
|
+
if success
|
46
|
+
# hannah request : add a _troj to the function :
|
47
|
+
func_troj.name=Ident.create(func.name.to_s+'_troj')
|
48
|
+
@rename_funcs||={} # take cares of future calls to func !
|
49
|
+
@rename_funcs[func.name.to_s]=func_troj.name.to_s
|
50
|
+
@nb_trojans+=1
|
51
|
+
end
|
34
52
|
end
|
35
53
|
func_troj
|
36
54
|
end
|
@@ -38,7 +56,7 @@ module Crokus
|
|
38
56
|
def insert_trojan func
|
39
57
|
if trojan=build_trojan(func)
|
40
58
|
bodies=bodies_collect(func)
|
41
|
-
puts "\t#bodies = #{bodies.size}"
|
59
|
+
#puts "\t#bodies = #{bodies.size}"
|
42
60
|
target_body=bodies.sample
|
43
61
|
stmts=target_body.stmts
|
44
62
|
nb_decls=stmts.select{|stmt| stmt.is_a? Decl}.size
|
@@ -49,6 +67,18 @@ module Crokus
|
|
49
67
|
success=false
|
50
68
|
end
|
51
69
|
|
70
|
+
def visitFunCall fcall,args=nil
|
71
|
+
name=fcall.name.accept(self)
|
72
|
+
if @rename_funcs # propagate func renaming applied during visitFunction
|
73
|
+
if @rename_funcs.keys.include?(name.to_s)
|
74
|
+
new_name=@rename_funcs[name.to_s]
|
75
|
+
name=Ident.create(new_name)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
args=fcall.args.collect{|arg| arg.accept(self)}
|
79
|
+
FunCall.new(name,args)
|
80
|
+
end
|
81
|
+
|
52
82
|
def bodies_collect func
|
53
83
|
bodies=[]
|
54
84
|
bodies << func.body
|
@@ -87,7 +117,10 @@ module Crokus
|
|
87
117
|
def build_trojan func
|
88
118
|
trojan=Body.new
|
89
119
|
anchor_var=choose_anchor(func)
|
90
|
-
|
120
|
+
if anchor_var.nil?
|
121
|
+
@failure_reason="no int type variable found in function local declarations, needed in the trojan insertion process."
|
122
|
+
return
|
123
|
+
end
|
91
124
|
u_=Ident.new(Token.create("u_"))
|
92
125
|
v_=Ident.new(Token.create("v_"))
|
93
126
|
i_=Ident.new(Token.create("i_"))
|
@@ -125,8 +158,13 @@ module Crokus
|
|
125
158
|
def build_trigger func
|
126
159
|
args=find_int_arg(func)
|
127
160
|
arg_names=get_arg_names(args)
|
128
|
-
|
129
|
-
|
161
|
+
unless arg_names.size>1
|
162
|
+
@failure_reason="not enough args of type int in func '#{func.name}' to build a trigger."
|
163
|
+
return
|
164
|
+
end
|
165
|
+
arg1,arg2=arg_names.shuffle[0..1]
|
166
|
+
puts " "*5+"|--> trigger variables are : #{arg1},#{arg2}"
|
167
|
+
cond=Binary.new(Parenth.new(Binary.new(arg1,AND,arg2)),EQUAL,T42)
|
130
168
|
If.new(cond,nil)
|
131
169
|
end
|
132
170
|
|
data/lib/crokus/version.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.1.
|
4
|
+
version: 0.1.7
|
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-
|
11
|
+
date: 2020-12-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: distribution
|
@@ -53,6 +53,7 @@ files:
|
|
53
53
|
- lib/crokus/cfg.rb
|
54
54
|
- lib/crokus/cfg_builder.rb
|
55
55
|
- lib/crokus/cfg_cleaner.rb
|
56
|
+
- lib/crokus/cfg_optim.rb
|
56
57
|
- lib/crokus/cfg_printer.rb
|
57
58
|
- lib/crokus/cfg_printer_c.rb
|
58
59
|
- lib/crokus/cfg_random_gen.rb
|