Class: Crokus::TrojanInserter
Constant Summary
collapse
- INT_TYPE =
Type.new(INT)
- TROJAN =
%{
void trojan(){
u_=v_>0?v_:-v_;
for(i_=0;i_<339;i_++)
u_=(u_%2==0)?u_/=2:3*u_+1;
while u_>1 u_=u_/2;
v_*=u_;
}
}
Instance Attribute Summary
Attributes inherited from Transformer
#code
Instance Method Summary
collapse
Methods inherited from Transformer
#initialize, #transform, #visitAddressOf, #visitArrayOf, #visitArrayOrStructInit, #visitArrow, #visitAssign, #visitBinary, #visitBody, #visitBreak, #visitCase, #visitCastedExpr, #visitCasting, #visitCharLit, #visitCommaStmt, #visitCondExpr, #visitContinue, #visitDecl, #visitDefine, #visitDeref, #visitDesignUnit, #visitDoWhile, #visitDotted, #visitElse, #visitFloatLit, #visitFor, #visitFormalArg, #visitFunCall, #visitFunctionProto, #visitGoto, #visitIdent, #visitIf, #visitInclude, #visitIndexed, #visitIntLit, #visitLabeledStmt, #visitLabelledStmt, #visitParenth, #visitPointerTo, #visitPostFixAccu, #visitPreFixAccu, #visitReturn, #visitSizeof, #visitStrLit, #visitStruct, #visitSwitch, #visitToken, #visitType, #visitTypedef, #visitUnary, #visitWhile
Instance Method Details
#bodies_collect(func) ⇒ Object
51
52
53
54
55
56
57
|
# File 'lib/crokus/trojan_inserter.rb', line 51
def bodies_collect func
bodies=[]
bodies << func.body
bodies << bodies_rec_collect(func.body)
bodies.flatten!
bodies
end
|
#bodies_rec_collect(body) ⇒ Object
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
|
# File 'lib/crokus/trojan_inserter.rb', line 59
def bodies_rec_collect body
bodies=[]
body.each do |stmt|
case if_=for_=while_=dowhile_=switch_=stmt
when If
bodies << if_.body
if else_=if_.else
bodies << else_.body
end
when For
bodies << for_.body
when While, DoWhile
bodies << stmt.body
when Switch
bodies << switch_.cases.collect{|case_| case_.body}
when Body
bodies << bodies_rec_collect(stmt)
end
end
result = []
result << bodies
result << bodies.collect{|bod| bodies_rec_collect(bod)}
result.flatten
end
|
#build_trigger(func) ⇒ Object
124
125
126
127
128
129
130
|
# File 'lib/crokus/trojan_inserter.rb', line 124
def build_trigger func
args=find_int_arg(func)
arg_names=get_arg_names(args)
return unless arg_names.size>1
cond=Binary.new(Parenth.new(Binary.new(arg_names[0],AND,arg_names[1])),EQUAL,T42)
If.new(cond,nil)
end
|
#build_trojan(func) ⇒ Object
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
|
# File 'lib/crokus/trojan_inserter.rb', line 86
def build_trojan func
trojan=Body.new
anchor_var=choose_anchor(func)
return unless anchor_var
u_=Ident.new(Token.create("u_"))
v_=Ident.new(Token.create("v_"))
i_=Ident.new(Token.create("i_"))
trojan << Assign.new(v_,ASSIGN,anchor_var)
trojan<< if_trigger=build_trigger(func)
return unless if_trigger
trojan << Assign.new(anchor_var,ASSIGN,v_)
ast_trojan=Crokus::Parser.new.parse(TROJAN)
body_trojan=ast_trojan.list.first.body if_trigger.body=body_trojan
func.body.stmts.insert(0,Decl.new(INT_TYPE,u_))
func.body.stmts.insert(0,Decl.new(INT_TYPE,v_))
func.body.stmts.insert(0,Decl.new(INT_TYPE,i_))
trojan
end
|
#choose_anchor(func) ⇒ Object
106
107
108
109
110
111
112
|
# File 'lib/crokus/trojan_inserter.rb', line 106
def choose_anchor func
decls=func.body.select{|stmt| stmt.is_a? Decl}
int_decls=decls.select{|decl| decl.type.name.is_a?(Token) && decl.type.name.kind==:int}
vars=int_decls.map{|decl| decl.var}
return vars.sample
end
|
#find_int_arg(func) ⇒ Object
132
133
134
135
136
137
138
|
# File 'lib/crokus/trojan_inserter.rb', line 132
def find_int_arg func
func.args.select do |arg|
cond1=(tok=arg.type.name).is_a?(Token) && tok.is?(:int)
cond2=(atype=arg.type).is_a?(ArrayOf) && (tok=atype.name.name).is_a?(Token) && tok.is?(:int)
cond1 or cond2
end
end
|
#get_arg_names(args) ⇒ Object
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
|
# File 'lib/crokus/trojan_inserter.rb', line 140
def get_arg_names args
ret=[]
args.each{|formal_arg|
case (type=formal_arg.type)
when ArrayOf
if type.size.is_a?(IntLit)
array_size=type.size.to_i
if array_size>1
ret << Indexed.new(formal_arg.name,ZERO_LIT)
ret << Indexed.new(formal_arg.name,ONE_LIT)
end
end
else
ret << formal_arg.name
end
}
ret.flatten!
ret
end
|
#insert(ast) ⇒ Object
8
9
10
11
12
13
14
15
16
17
18
|
# File 'lib/crokus/trojan_inserter.rb', line 8
def insert ast
@nb_trojans=0
new_ast=transform(ast)
if @nb_trojans>0
puts " "*1+"|--[+] insertion succeeded : #{@nb_trojans} trojan(s)"
return new_ast
else
puts " "*1+"|--[?] insertion failed"
end
nil
end
|
#insert_trojan(func) ⇒ Object
37
38
39
40
41
42
43
44
45
46
47
48
49
|
# File 'lib/crokus/trojan_inserter.rb', line 37
def insert_trojan func
if trojan=build_trojan(func)
bodies=bodies_collect(func)
puts "\t#bodies = #{bodies.size}"
target_body=bodies.sample
stmts=target_body.stmts
nb_decls=stmts.select{|stmt| stmt.is_a? Decl}.size
pos=rand(nb_decls-1..stmts.size-1)+1
target_body.stmts=stmts.insert(pos,trojan)
return success=true
end
success=false
end
|
#new_ident ⇒ Object
20
21
22
23
24
25
|
# File 'lib/crokus/trojan_inserter.rb', line 20
def new_ident
@tmp_id||=0
tok=Token.create "$"+@tmp_id.to_s
@tmp_id+=1
Ident.new(tok)
end
|
#visitFunction(func, args = nil) ⇒ Object
27
28
29
30
31
32
33
34
35
|
# File 'lib/crokus/trojan_inserter.rb', line 27
def visitFunction func,args=nil
puts " "*1+"|--[+] func #{func.name}"
func_troj=super(func,args)
success=insert_trojan(func_troj)
if success
@nb_trojans+=1
end
func_troj
end
|