Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
C
cwe_checker
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
fact-depend
cwe_checker
Commits
babf80f5
Commit
babf80f5
authored
4 years ago
by
Enkelmann
Committed by
Enkelmann
4 years ago
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Handle special cases in BAP IR to internal IR conversion.
parent
53193734
master
…
v0.7
v0.6
v0.5
v0.4
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
185 additions
and
47 deletions
+185
-47
mod.rs
cwe_checker_rs/src/bil/mod.rs
+54
-11
mod.rs
cwe_checker_rs/src/intermediate_representation/mod.rs
+6
-0
mod.rs
cwe_checker_rs/src/term/mod.rs
+125
-36
No files found.
cwe_checker_rs/src/bil/mod.rs
View file @
babf80f5
...
...
@@ -239,9 +239,15 @@ impl From<Expression> for IrExpression {
match
expr
{
Var
(
var
)
=>
IrExpression
::
Var
(
var
.into
()),
Const
(
bitvector
)
=>
IrExpression
::
Const
(
bitvector
),
Load
{
..
}
|
Store
{
..
}
|
Let
{
..
}
|
Unknown
{
..
}
|
IfThenElse
{
..
}
=>
{
panic!
()
}
Load
{
..
}
|
Store
{
..
}
|
Let
{
..
}
=>
panic!
(),
IfThenElse
{
true_exp
,
..
}
=>
IrExpression
::
Unknown
{
description
:
"BAP-IfThenElse-expression"
.into
(),
size
:
true_exp
.bitsize
()
.into
(),
},
Unknown
{
description
,
type_
}
=>
IrExpression
::
Unknown
{
description
,
size
:
type_
.bitsize
()
.unwrap
()
.into
(),
},
BinOp
{
op
,
lhs
,
rhs
}
=>
IrExpression
::
BinOp
{
op
:
op
.into
(),
lhs
:
Box
::
new
(
IrExpression
::
from
(
*
lhs
)),
...
...
@@ -254,17 +260,32 @@ impl From<Expression> for IrExpression {
Cast
{
kind
,
width
,
arg
}
=>
{
use
CastType
::
*
;
match
kind
{
UNSIGNED
=>
IrExpression
::
Cast
{
UNSIGNED
=>
{
assert
!
(
width
%
8
==
0
);
IrExpression
::
Cast
{
arg
:
Box
::
new
(
IrExpression
::
from
(
*
arg
)),
op
:
IrCastOpType
::
IntZExt
,
size
:
width
.into
(),
},
SIGNED
=>
IrExpression
::
Cast
{
}
}
SIGNED
=>
{
assert
!
(
width
%
8
==
0
);
IrExpression
::
Cast
{
arg
:
Box
::
new
(
IrExpression
::
from
(
*
arg
)),
op
:
IrCastOpType
::
IntSExt
,
size
:
width
.into
(),
},
}
}
HIGH
=>
{
if
width
==
1
{
IrExpression
::
BinOp
{
op
:
IrBinOpType
::
IntSLess
,
lhs
:
Box
::
new
(
IrExpression
::
Const
(
Bitvector
::
zero
(
(
arg
.bitsize
()
as
usize
)
.into
(),
))),
rhs
:
Box
::
new
(
IrExpression
::
from
(
*
arg
)),
}
}
else
{
assert
!
(
width
%
8
==
0
);
let
low_byte
=
(
arg
.bitsize
()
-
width
)
.into
();
IrExpression
::
Subpiece
{
...
...
@@ -273,22 +294,44 @@ impl From<Expression> for IrExpression {
size
:
width
.into
(),
}
}
LOW
=>
IrExpression
::
Subpiece
{
}
LOW
=>
{
if
width
==
1
{
IrExpression
::
Subpiece
{
low_byte
:
ByteSize
::
new
(
0
),
size
:
ByteSize
::
new
(
1
),
arg
:
Box
::
new
(
IrExpression
::
BinOp
{
op
:
IrBinOpType
::
IntAnd
,
lhs
:
Box
::
new
(
IrExpression
::
Const
(
Bitvector
::
one
(
(
arg
.bitsize
()
as
usize
)
.into
(),
))),
rhs
:
Box
::
new
(
IrExpression
::
from
(
*
arg
)),
}),
}
}
else
{
assert
!
(
width
%
8
==
0
);
IrExpression
::
Subpiece
{
arg
:
Box
::
new
(
IrExpression
::
from
(
*
arg
)),
low_byte
:
(
0
as
u64
)
.into
(),
size
:
width
.into
(),
},
}
}
}
}
}
Extract
{
low_bit
,
high_bit
,
arg
,
}
=>
IrExpression
::
Subpiece
{
}
=>
{
assert
!
(
low_bit
%
8
==
0
);
assert
!
((
high_bit
+
1
)
%
8
==
0
);
IrExpression
::
Subpiece
{
size
:
(
high_bit
-
low_bit
+
1
)
.into
(),
low_byte
:
low_bit
.into
(),
arg
:
Box
::
new
(
IrExpression
::
from
(
*
arg
)),
},
}
}
Concat
{
left
,
right
}
=>
IrExpression
::
BinOp
{
op
:
IrBinOpType
::
Piece
,
lhs
:
Box
::
new
(
IrExpression
::
from
(
*
left
)),
...
...
This diff is collapsed.
Click to expand it.
cwe_checker_rs/src/intermediate_representation/mod.rs
View file @
babf80f5
...
...
@@ -60,6 +60,12 @@ impl From<ByteSize> for apint::BitWidth {
}
}
impl
ByteSize
{
pub
fn
new
(
value
:
u64
)
->
ByteSize
{
ByteSize
(
value
)
}
}
#[cfg(test)]
mod
tests
{
use
super
::
*
;
...
...
This diff is collapsed.
Click to expand it.
cwe_checker_rs/src/term/mod.rs
View file @
babf80f5
...
...
@@ -58,10 +58,8 @@ impl Def {
match
self
.rhs
{
Expression
::
Load
{
address
,
..
}
=>
{
let
(
defs
,
cleaned_address
,
_
)
=
extract_loads_from_expression
(
*
address
,
0
);
let
mut
ir_defs
:
Vec
<
IrDef
>
=
defs
.into_iter
()
.map
(|
def
|
def
.into_ir_assignment
())
.collect
();
let
mut
ir_defs
:
Vec
<
IrDef
>
=
defs
.into_iter
()
.map
(|
def
|
def
.into_ir_load
())
.collect
();
ir_defs
.push
(
IrDef
::
Load
{
address
:
cleaned_address
.into
(),
var
:
self
.lhs
.into
(),
...
...
@@ -74,10 +72,8 @@ impl Def {
let
(
mut
more_defs
,
cleaned_value
,
_
)
=
extract_loads_from_expression
(
*
value
,
counter
);
defs
.append
(
&
mut
more_defs
);
let
mut
ir_defs
:
Vec
<
IrDef
>
=
defs
.into_iter
()
.map
(|
def
|
def
.into_ir_assignment
())
.collect
();
let
mut
ir_defs
:
Vec
<
IrDef
>
=
defs
.into_iter
()
.map
(|
def
|
def
.into_ir_load
())
.collect
();
ir_defs
.push
(
IrDef
::
Store
{
address
:
cleaned_address
.into
(),
value
:
cleaned_value
.into
(),
...
...
@@ -89,46 +85,70 @@ impl Def {
true_exp
,
false_exp
,
}
=>
{
// We only match for conditional stores.
// Other usages of the `IfThenElse`-expression will result in panics.
let
(
address
,
value
)
=
match
(
*
true_exp
,
*
false_exp
)
{
let
(
defs
,
cleaned_if_then_else
,
_
)
=
extract_loads_from_expression
(
Expression
::
IfThenElse
{
condition
,
true_exp
,
false_exp
,
},
0
,
);
let
mut
ir_defs
:
Vec
<
IrDef
>
=
defs
.into_iter
()
.map
(|
def
|
def
.into_ir_load
())
.collect
();
if
let
Expression
::
IfThenElse
{
condition
:
_
,
true_exp
,
false_exp
,
}
=
cleaned_if_then_else
{
match
(
*
true_exp
,
*
false_exp
)
{
(
Expression
::
Store
{
address
,
value
,
..
},
Expression
::
Var
(
var
))
|
(
Expression
::
Var
(
var
),
Expression
::
Store
{
address
,
value
,
..
})
if
var
==
self
.lhs
=>
{
(
address
,
value
)
}
_
=>
panic!
(),
};
let
(
mut
defs
,
_cleaned_condition
,
counter
)
=
extract_loads_from_expression
(
*
condition
,
0
);
let
(
mut
more_defs
,
cleaned_adress
,
counter
)
=
extract_loads_from_expression
(
*
address
,
counter
);
let
(
mut
even_more_defs
,
cleaned_value
,
_
)
=
extract_loads_from_expression
(
*
value
,
counter
);
defs
.append
(
&
mut
more_defs
);
defs
.append
(
&
mut
even_more_defs
);
let
mut
ir_defs
:
Vec
<
IrDef
>
=
defs
.into_iter
()
.map
(|
def
|
def
.into_ir_assignment
())
.collect
();
// The IfThenElse-expression is a conditional store to memory
ir_defs
.push
(
IrDef
::
Store
{
address
:
cleaned_adress
.into
(
),
address
:
IrExpression
::
from
(
*
address
),
value
:
IrExpression
::
Unknown
{
description
:
"BAP conditional store"
.into
(),
size
:
cleaned_value
.bitsize
()
.into
(),
size
:
value
.bitsize
()
.into
(),
},
});
}
_
=>
ir_defs
.push
(
IrDef
::
Assign
{
var
:
self
.lhs
.clone
()
.into
(),
value
:
IrExpression
::
Unknown
{
description
:
"BAP IfThenElse expression"
.into
(),
size
:
self
.lhs
.bitsize
()
.unwrap
()
.into
(),
},
}),
}
ir_defs
}
else
{
panic!
()
}
}
_
=>
{
let
(
defs
,
cleaned_rhs
,
_
)
=
extract_loads_from_expression
(
self
.rhs
,
0
);
let
mut
ir_defs
:
Vec
<
IrDef
>
=
defs
.into_iter
()
.map
(|
def
|
def
.into_ir_load
())
.collect
();
ir_defs
.push
(
IrDef
::
Assign
{
var
:
self
.lhs
.into
(),
value
:
cleaned_rhs
.into
(),
});
ir_defs
}
_
=>
vec!
[
self
.into_ir_assignment
()],
}
}
fn
into_ir_assignment
(
self
)
->
IrDef
{
IrDef
::
Assign
{
fn
into_ir_load
(
self
)
->
IrDef
{
if
let
Expression
::
Load
{
address
,
..
}
=
self
.rhs
{
IrDef
::
Load
{
address
:
IrExpression
::
from
(
*
address
),
var
:
self
.lhs
.into
(),
value
:
self
.rhs
.into
(),
}
}
else
{
panic!
()
}
}
}
...
...
@@ -223,9 +243,25 @@ impl From<Blk> for IrBlk {
let
ir_jmp_terms
=
blk
.jmps
.into_iter
()
.map
(|
jmp_term
|
Term
{
.map
(|
jmp_term
|
{
let
(
jmp
,
defs
)
=
extract_loads_from_jump
(
jmp_term
.term
);
let
mut
ir_defs
=
Vec
::
new
();
for
def
in
defs
.into_iter
()
{
ir_defs
.append
(
&
mut
def
.into_ir_defs
());
}
for
(
counter
,
ir_def
)
in
ir_defs
.into_iter
()
.enumerate
()
{
ir_def_terms
.push
(
Term
{
tid
:
Tid
{
id
:
format!
(
"{}_{}"
,
jmp_term
.tid.id
,
counter
),
address
:
jmp_term
.tid.address
.clone
(),
},
term
:
ir_def
,
});
}
Term
{
tid
:
jmp_term
.tid
,
term
:
jmp_term
.term
.into
(),
term
:
jmp
.into
(),
}
})
.collect
();
IrBlk
{
...
...
@@ -450,7 +486,30 @@ fn extract_loads_from_expression(expr: Expression, counter: u64) -> (Vec<Def>, E
(
defs
,
Var
(
temp_var
),
counter
)
}
Var
(
_
)
|
Const
(
_
)
|
Unknown
{
..
}
=>
(
Vec
::
new
(),
expr
,
counter
),
Store
{
..
}
|
Let
{
..
}
|
IfThenElse
{
..
}
=>
panic!
(),
Store
{
..
}
|
Let
{
..
}
=>
panic!
(),
IfThenElse
{
condition
,
true_exp
,
false_exp
,
}
=>
{
let
(
mut
defs
,
cleaned_cond
,
counter
)
=
extract_loads_from_expression
(
*
condition
,
counter
);
let
(
mut
defs_true
,
cleaned_true
,
counter
)
=
extract_loads_from_expression
(
*
true_exp
,
counter
);
let
(
mut
defs_false
,
cleaned_false
,
counter
)
=
extract_loads_from_expression
(
*
false_exp
,
counter
);
defs
.append
(
&
mut
defs_true
);
defs
.append
(
&
mut
defs_false
);
(
defs
,
IfThenElse
{
condition
:
Box
::
new
(
cleaned_cond
),
true_exp
:
Box
::
new
(
cleaned_true
),
false_exp
:
Box
::
new
(
cleaned_false
),
},
counter
,
)
}
BinOp
{
op
,
lhs
,
rhs
}
=>
{
let
(
mut
defs
,
cleaned_lhs
,
counter
)
=
extract_loads_from_expression
(
*
lhs
,
counter
);
let
(
mut
defs_rhs
,
cleaned_rhs
,
counter
)
=
extract_loads_from_expression
(
*
rhs
,
counter
);
...
...
@@ -521,6 +580,36 @@ fn extract_loads_from_expression(expr: Expression, counter: u64) -> (Vec<Def>, E
}
}
fn
extract_loads_from_jump
(
mut
jmp
:
Jmp
)
->
(
Jmp
,
Vec
<
Def
>
)
{
let
mut
counter
=
0
;
let
mut
defs
=
Vec
::
new
();
if
let
Some
(
condition
)
=
jmp
.condition
{
let
(
mut
new_defs
,
cleaned_condition
,
new_counter
)
=
extract_loads_from_expression
(
condition
,
counter
);
counter
=
new_counter
;
defs
.append
(
&
mut
new_defs
);
jmp
.condition
=
Some
(
cleaned_condition
);
}
match
jmp
.kind
{
JmpKind
::
Goto
(
Label
::
Indirect
(
ref
mut
target
))
=>
{
let
(
mut
new_defs
,
cleaned_target
,
_
)
=
extract_loads_from_expression
(
target
.clone
(),
counter
);
defs
.append
(
&
mut
new_defs
);
*
target
=
cleaned_target
;
}
JmpKind
::
Call
(
ref
mut
call
)
=>
{
if
let
Label
::
Indirect
(
ref
mut
target
)
=
call
.target
{
let
(
mut
new_defs
,
cleaned_target
,
_
)
=
extract_loads_from_expression
(
target
.clone
(),
counter
);
defs
.append
(
&
mut
new_defs
);
*
target
=
cleaned_target
;
}
}
_
=>
(),
}
(
jmp
,
defs
)
}
#[cfg(test)]
mod
tests
{
use
super
::
*
;
...
...
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment