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-gitdep
cwe_checker
Commits
c11a21e9
Commit
c11a21e9
authored
4 years ago
by
Enkelmann
Committed by
Enkelmann
4 years ago
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
implement conversion functions for jumps and defs.
parent
263c1498
Show whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
500 additions
and
43 deletions
+500
-43
mod.rs
cwe_checker_rs/src/bil/mod.rs
+145
-0
variable.rs
cwe_checker_rs/src/bil/variable.rs
+25
-3
expression.rs
cwe_checker_rs/src/intermediate_representation/expression.rs
+2
-1
mod.rs
cwe_checker_rs/src/intermediate_representation/mod.rs
+0
-0
term.rs
cwe_checker_rs/src/intermediate_representation/term.rs
+30
-3
variable.rs
cwe_checker_rs/src/intermediate_representation/variable.rs
+1
-1
lib.rs
cwe_checker_rs/src/lib.rs
+2
-2
expressions.rs
cwe_checker_rs/src/pcode/expressions.rs
+29
-23
mod.rs
cwe_checker_rs/src/pcode/mod.rs
+0
-1
term.rs
cwe_checker_rs/src/pcode/term.rs
+57
-9
mod.rs
cwe_checker_rs/src/term/mod.rs
+209
-0
No files found.
cwe_checker_rs/src/bil/mod.rs
View file @
c11a21e9
use
crate
::
intermediate_representation
::
BinOpType
as
IrBinOpType
;
use
crate
::
intermediate_representation
::
ByteSize
;
use
crate
::
intermediate_representation
::
CastOpType
as
IrCastOpType
;
use
crate
::
intermediate_representation
::
Expression
as
IrExpression
;
use
crate
::
intermediate_representation
::
UnOpType
as
IrUnOpType
;
use
apint
::
Width
;
use
serde
::{
Deserialize
,
Serialize
};
pub
mod
variable
;
...
...
@@ -7,6 +13,13 @@ pub type Bitvector = apint::ApInt;
pub
type
BitSize
=
u16
;
impl
From
<
BitSize
>
for
ByteSize
{
/// Convert to `ByteSize`, while always rounding up to the nearest full byte.
fn
from
(
bitsize
:
BitSize
)
->
ByteSize
{
((
bitsize
as
u64
+
7
)
/
8
)
.into
()
}
}
#[derive(Serialize,
Deserialize,
Debug,
PartialEq,
Eq,
Hash,
Clone)]
pub
enum
Expression
{
Var
(
Variable
),
...
...
@@ -189,6 +202,100 @@ impl Expression {
}
}
}
pub
fn
bitsize
(
&
self
)
->
BitSize
{
use
Expression
::
*
;
match
self
{
Var
(
var
)
=>
var
.bitsize
()
.unwrap
(),
Const
(
bitvector
)
=>
bitvector
.width
()
.to_usize
()
as
u16
,
Load
{
size
,
..
}
=>
*
size
,
Store
{
..
}
=>
0
,
BinOp
{
op
,
lhs
,
rhs
:
_
}
=>
{
use
BinOpType
::
*
;
match
op
{
EQ
|
NEQ
|
LT
|
LE
|
SLT
|
SLE
=>
1
,
_
=>
lhs
.bitsize
(),
}
}
UnOp
{
arg
,
..
}
=>
arg
.bitsize
(),
Cast
{
width
,
..
}
=>
*
width
,
Let
{
..
}
=>
panic!
(),
Unknown
{
description
:
_
,
type_
,
}
=>
type_
.bitsize
()
.unwrap
(),
IfThenElse
{
true_exp
,
..
}
=>
true_exp
.bitsize
(),
Extract
{
low_bit
,
high_bit
,
..
}
=>
high_bit
-
low_bit
,
Concat
{
left
,
right
}
=>
left
.bitsize
()
+
right
.bitsize
(),
}
}
}
impl
From
<
Expression
>
for
IrExpression
{
fn
from
(
expr
:
Expression
)
->
IrExpression
{
use
Expression
::
*
;
match
expr
{
Var
(
var
)
=>
IrExpression
::
Var
(
var
.into
()),
Const
(
bitvector
)
=>
IrExpression
::
Const
(
bitvector
),
Load
{
..
}
|
Store
{
..
}
|
Let
{
..
}
|
Unknown
{
..
}
|
IfThenElse
{
..
}
=>
{
panic!
()
}
BinOp
{
op
,
lhs
,
rhs
}
=>
IrExpression
::
BinOp
{
op
:
op
.into
(),
lhs
:
Box
::
new
(
IrExpression
::
from
(
*
lhs
)),
rhs
:
Box
::
new
(
IrExpression
::
from
(
*
rhs
)),
},
UnOp
{
op
,
arg
}
=>
IrExpression
::
UnOp
{
op
:
op
.into
(),
arg
:
Box
::
new
(
IrExpression
::
from
(
*
arg
)),
},
Cast
{
kind
,
width
,
arg
}
=>
{
use
CastType
::
*
;
match
kind
{
UNSIGNED
=>
IrExpression
::
Cast
{
arg
:
Box
::
new
(
IrExpression
::
from
(
*
arg
)),
op
:
IrCastOpType
::
IntZExt
,
size
:
width
.into
(),
},
SIGNED
=>
IrExpression
::
Cast
{
arg
:
Box
::
new
(
IrExpression
::
from
(
*
arg
)),
op
:
IrCastOpType
::
IntSExt
,
size
:
width
.into
(),
},
HIGH
=>
{
assert
!
(
width
%
8
==
0
);
let
low_byte
=
(
arg
.bitsize
()
-
BitSize
::
from
(
width
))
.into
();
IrExpression
::
Subpiece
{
arg
:
Box
::
new
(
IrExpression
::
from
(
*
arg
)),
low_byte
,
size
:
width
.into
(),
}
}
LOW
=>
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
{
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
)),
rhs
:
Box
::
new
(
IrExpression
::
from
(
*
right
)),
},
}
}
}
#[derive(Serialize,
Deserialize,
Debug,
PartialEq,
Eq,
Hash,
Clone,
Copy)]
...
...
@@ -222,12 +329,50 @@ pub enum BinOpType {
SLE
,
}
impl
From
<
BinOpType
>
for
IrBinOpType
{
fn
from
(
op
:
BinOpType
)
->
IrBinOpType
{
use
BinOpType
::
*
;
use
IrBinOpType
::
*
;
match
op
{
PLUS
=>
IntAdd
,
MINUS
=>
IntSub
,
TIMES
=>
IntMult
,
DIVIDE
=>
IntDiv
,
SDIVIDE
=>
IntSDiv
,
MOD
=>
IntRem
,
SMOD
=>
IntSRem
,
LSHIFT
=>
IntLeft
,
RSHIFT
=>
IntRight
,
ARSHIFT
=>
IntSRight
,
AND
=>
IntAnd
,
OR
=>
IntOr
,
XOR
=>
IntXOr
,
EQ
=>
IntEqual
,
NEQ
=>
IntNotEqual
,
LT
=>
IntLess
,
LE
=>
IntLessEqual
,
SLT
=>
IntSLess
,
SLE
=>
IntSLessEqual
,
}
}
}
#[derive(Serialize,
Deserialize,
Debug,
PartialEq,
Eq,
Hash,
Clone,
Copy)]
pub
enum
UnOpType
{
NEG
,
NOT
,
}
impl
From
<
UnOpType
>
for
IrUnOpType
{
fn
from
(
op
:
UnOpType
)
->
IrUnOpType
{
use
UnOpType
::
*
;
match
op
{
NEG
=>
IrUnOpType
::
Int2Comp
,
NOT
=>
IrUnOpType
::
IntNegate
,
}
}
}
#[derive(Serialize,
Deserialize,
Debug,
PartialEq,
Eq,
Hash,
Clone,
Copy)]
pub
enum
Endianness
{
LittleEndian
,
...
...
This diff is collapsed.
Click to expand it.
cwe_checker_rs/src/bil/variable.rs
View file @
c11a21e9
use
super
::
BitSize
;
use
crate
::
intermediate_representation
::
Variable
as
IrVariable
;
use
crate
::
prelude
::
*
;
use
serde
::{
Deserialize
,
Serialize
};
...
...
@@ -19,12 +20,33 @@ pub enum Type {
Unknown
,
}
impl
Type
{
pub
fn
bitsize
(
&
self
)
->
Result
<
BitSize
,
Error
>
{
if
let
Type
::
Immediate
(
bitsize
)
=
self
{
Ok
(
*
bitsize
)
}
else
{
Err
(
anyhow!
(
"Not a register type"
))
}
}
}
impl
Variable
{
pub
fn
bitsize
(
&
self
)
->
Result
<
BitSize
,
Error
>
{
if
let
Type
::
Immediate
(
bitsize
)
=
self
.type_
{
Ok
(
bitsize
)
self
.type_
.bitsize
()
}
}
impl
From
<
Variable
>
for
IrVariable
{
fn
from
(
var
:
Variable
)
->
IrVariable
{
let
size
=
if
let
Type
::
Immediate
(
bitsize
)
=
var
.type_
{
bitsize
.into
()
}
else
{
Err
(
anyhow!
(
"Not a register variable"
))
panic!
()
};
IrVariable
{
name
:
var
.name
,
size
,
is_temp
:
var
.is_temp
,
}
}
}
...
...
This diff is collapsed.
Click to expand it.
cwe_checker_rs/src/intermediate_representation/expression.rs
View file @
c11a21e9
...
...
@@ -38,6 +38,8 @@ pub enum BinOpType {
IntNotEqual
,
IntLess
,
IntSLess
,
IntLessEqual
,
IntSLessEqual
,
IntAdd
,
IntSub
,
IntCarry
,
...
...
@@ -74,7 +76,6 @@ pub enum CastOpType {
Int2Float
,
Float2Float
,
Trunc
,
}
#[derive(Serialize,
Deserialize,
Debug,
PartialEq,
Eq,
Hash,
Clone,
Copy)]
...
...
This diff is collapsed.
Click to expand it.
cwe_checker_rs/src/intermediate_representation/mod.rs
View file @
c11a21e9
This diff is collapsed.
Click to expand it.
cwe_checker_rs/src/intermediate_representation/term.rs
View file @
c11a21e9
use
super
::{
ByteSize
,
Expression
,
Variable
};
use
crate
::
prelude
::
*
;
use
crate
::
term
::{
Term
,
Tid
};
use
super
::{
Variable
,
Expression
,
ByteSize
};
#[derive(Serialize,
Deserialize,
Debug,
PartialEq,
Eq,
Hash,
Clone)]
pub
enum
Def
{
...
...
@@ -19,3 +17,32 @@ pub enum Def {
value
:
Expression
,
},
}
#[derive(Serialize,
Deserialize,
Debug,
PartialEq,
Eq,
Hash,
Clone)]
pub
enum
Jmp
{
Branch
(
Tid
),
BranchInd
(
Expression
),
CBranch
{
target
:
Tid
,
condition
:
Expression
,
},
Call
{
target
:
Tid
,
return_
:
Option
<
Tid
>
,
},
CallInd
{
target
:
Expression
,
return_
:
Option
<
Tid
>
,
},
Return
(
Expression
),
CallOther
{
description
:
String
,
return_
:
Option
<
Tid
>
,
},
}
#[derive(Serialize,
Deserialize,
Debug,
PartialEq,
Eq,
Hash,
Clone)]
pub
struct
Blk
{
pub
defs
:
Vec
<
Term
<
Def
>>
,
pub
jmps
:
Vec
<
Term
<
Jmp
>>
,
}
This diff is collapsed.
Click to expand it.
cwe_checker_rs/src/intermediate_representation/variable.rs
View file @
c11a21e9
use
crate
::
prelude
::
*
;
use
super
::
ByteSize
;
use
crate
::
prelude
::
*
;
#[derive(Serialize,
Deserialize,
Debug,
PartialEq,
Eq,
Hash,
Clone)]
pub
struct
Variable
{
...
...
This diff is collapsed.
Click to expand it.
cwe_checker_rs/src/lib.rs
View file @
c11a21e9
...
...
@@ -11,10 +11,10 @@ pub mod abstract_domain;
pub
mod
analysis
;
pub
mod
bil
;
pub
mod
ffi
;
pub
mod
intermediate_representation
;
pub
mod
pcode
;
pub
mod
term
;
pub
mod
utils
;
pub
mod
pcode
;
pub
mod
intermediate_representation
;
mod
prelude
{
pub
use
apint
::
Width
;
...
...
This diff is collapsed.
Click to expand it.
cwe_checker_rs/src/pcode/expressions.rs
View file @
c11a21e9
use
crate
::
prelude
::
*
;
use
crate
::
term
::{
Term
,
Tid
};
use
crate
::
intermediate_representation
::
BinOpType
as
IrBinOpType
;
use
crate
::
intermediate_representation
::
ByteSize
;
use
crate
::
intermediate_representation
::
Variable
as
IrVariabl
e
;
use
crate
::
intermediate_representation
::
CastOpType
as
IrCastOpTyp
e
;
use
crate
::
intermediate_representation
::
Expression
as
IrExpression
;
use
crate
::
intermediate_representation
::
BinOpType
as
IrBinOpType
;
use
crate
::
intermediate_representation
::
UnOpType
as
IrUnOpType
;
use
crate
::
intermediate_representation
::
CastOpType
as
IrCastOpType
;
use
crate
::
intermediate_representation
::
Variable
as
IrVariable
;
use
crate
::
prelude
::
*
;
use
crate
::
term
::{
Term
,
Tid
};
#[derive(Serialize,
Deserialize,
Debug,
PartialEq,
Eq,
Hash,
Clone)]
pub
struct
Variable
{
...
...
@@ -31,17 +31,19 @@ impl From<Variable> for IrExpression {
(
Some
(
_name
),
None
)
=>
IrExpression
::
Var
(
pcode_var
.into
()),
(
None
,
Some
(
hex_value
))
=>
{
// TODO: Implement parsing for large hex values.
if
pcode_var
.size
>
8
.into
()
{
panic!
(
"Parsing of immediates greater than 8 bytes not yet implemented: {}"
,
hex_value
);
if
u64
::
from
(
pcode_var
.size
)
>
8
{
panic!
(
"Parsing of immediates greater than 8 bytes not yet implemented: {}"
,
hex_value
);
}
let
val
:
u64
=
u64
::
from_str_radix
(
&
hex_value
,
16
)
.unwrap
();
let
mut
bitvector
:
Bitvector
=
Bitvector
::
from_u64
(
val
);
bitvector
.truncate
(
pcode_var
.size
)
.unwrap
();
IrExpression
::
Const
(
bitvector
)
},
}
_
=>
panic!
(),
}
}
}
...
...
@@ -50,12 +52,15 @@ impl From<Variable> for ByteSize {
match
(
&
pcode_var
.name
,
&
pcode_var
.value
)
{
(
None
,
Some
(
hex_value
))
=>
{
// TODO: Implement parsing for large hex values.
if
pcode_var
.size
>
8
.into
()
{
panic!
(
"Parsing of immediates greater than 8 bytes not yet implemented: {}"
,
hex_value
);
if
u64
::
from
(
pcode_var
.size
)
>
8
{
panic!
(
"Parsing of immediates greater than 8 bytes not yet implemented: {}"
,
hex_value
);
}
let
val
:
u64
=
u64
::
from_str_radix
(
&
hex_value
,
16
)
.unwrap
();
val
.into
()
},
}
_
=>
panic!
(),
}
}
...
...
@@ -69,14 +74,6 @@ pub struct Expression {
pub
input2
:
Option
<
Variable
>
,
}
impl
From
<
Expression
>
for
IrExpression
{
fn
from
(
expr
:
Expression
)
->
IrExpression
{
match
expr
.mnemonic
{
_
=>
todo!
(),
}
}
}
#[allow(non_camel_case_types)]
#[derive(Serialize,
Deserialize,
Debug,
PartialEq,
Eq,
Hash,
Clone,
Copy)]
pub
enum
ExpressionType
{
...
...
@@ -90,12 +87,15 @@ pub enum ExpressionType {
INT_NOTEQUAL
,
INT_LESS
,
INT_SLESS
,
INT_LESSEQUAL
,
INT_SLESSEQUAL
,
INT_ADD
,
INT_SUB
,
INT_CARRY
,
INT_SCARRY
,
INT_SBORROW
,
INT_XOR
,
INT_AND
,
INT_OR
,
...
...
@@ -103,16 +103,17 @@ pub enum ExpressionType {
INT_LEFT
,
INT_RIGHT
,
INT_SRIGHT
,
INT_MULT
,
INT_DIV
,
INT_REM
,
INT_SDIV
,
INT_SREM
,
BOOL_XOR
,
BOOL_AND
,
BOOL_OR
,
FLOAT_EQUAL
,
FLOAT_NOTEQUAL
,
FLOAT_LESS
,
...
...
@@ -126,6 +127,7 @@ pub enum ExpressionType {
INT_NEGATE
,
INT_2COMP
,
BOOL_NEGATE
,
FLOAT_NEGATE
,
FLOAT_ABS
,
FLOAT_SQRT
,
...
...
@@ -144,12 +146,16 @@ pub enum ExpressionType {
impl
From
<
ExpressionType
>
for
IrBinOpType
{
fn
from
(
expr_type
:
ExpressionType
)
->
IrBinOpType
{
use
ExpressionType
::
*
;
use
IrBinOpType
::
*
;
match
expr_type
{
PIECE
=>
IrBinOpType
::
Piece
,
INT_EQUAL
=>
IrBinOpType
::
IntEqual
,
INT_NOTEQUAL
=>
IrBinOpType
::
IntNotEqual
,
INT_LESS
=>
IrBinOpType
::
IntLess
,
INT_SLESS
=>
IrBinOpType
::
IntSLess
,
INT_LESSEQUAL
=>
IntLessEqual
,
INT_SLESSEQUAL
=>
IntSLessEqual
,
INT_ADD
=>
IrBinOpType
::
IntAdd
,
INT_SUB
=>
IrBinOpType
::
IntSub
,
...
...
This diff is collapsed.
Click to expand it.
cwe_checker_rs/src/pcode/mod.rs
View file @
c11a21e9
...
...
@@ -7,4 +7,3 @@ mod expressions;
pub
use
expressions
::
*
;
mod
term
;
pub
use
term
::
*
;
This diff is collapsed.
Click to expand it.
cwe_checker_rs/src/pcode/term.rs
View file @
c11a21e9
use
super
::{
Expression
,
Variable
};
use
crate
::
intermediate_representation
::
Def
as
IrDef
;
use
crate
::
intermediate_representation
::
Expression
as
IrExpression
;
use
crate
::
intermediate_representation
::
Jmp
as
IrJmp
;
use
crate
::
prelude
::
*
;
use
crate
::
term
::{
Term
,
Tid
};
// TODO: Handle the case where an indirect tail call is represented by CALLIND plus RETURN
#[derive(Serialize,
Deserialize,
Debug,
PartialEq,
Eq,
Hash,
Clone)]
pub
struct
Call
{
pub
target
:
Label
,
...
...
@@ -15,9 +18,10 @@ pub struct Jmp {
pub
mnemonic
:
JmpType
,
pub
goto
:
Option
<
Label
>
,
pub
call
:
Option
<
Call
>
,
pub
condition
:
Option
<
Expression
>
,
pub
condition
:
Option
<
Variable
>
,
}
// TODO: CALLOTHER is still missing!
#[derive(Serialize,
Deserialize,
Debug,
PartialEq,
Eq,
Hash,
Clone,
Copy)]
pub
enum
JmpType
{
BRANCH
,
...
...
@@ -28,6 +32,49 @@ pub enum JmpType {
RETURN
,
}
impl
From
<
Jmp
>
for
IrJmp
{
fn
from
(
jmp
:
Jmp
)
->
IrJmp
{
use
JmpType
::
*
;
let
unwrap_label_direct
=
|
label
|
{
if
let
Label
::
Direct
(
tid
)
=
label
{
tid
}
else
{
panic!
()
}
};
let
unwrap_label_indirect
=
|
label
|
{
if
let
Label
::
Indirect
(
expr
)
=
label
{
expr
}
else
{
panic!
()
}
};
match
jmp
.mnemonic
{
BRANCH
=>
IrJmp
::
Branch
(
unwrap_label_direct
(
jmp
.goto
.unwrap
())),
CBRANCH
=>
IrJmp
::
CBranch
{
target
:
unwrap_label_direct
(
jmp
.goto
.unwrap
()),
condition
:
jmp
.condition
.unwrap
()
.into
(),
},
BRANCHIND
=>
IrJmp
::
BranchInd
(
unwrap_label_indirect
(
jmp
.goto
.unwrap
())
.into
()),
CALL
=>
{
let
call
=
jmp
.call
.unwrap
();
IrJmp
::
Call
{
target
:
unwrap_label_direct
(
call
.target
),
return_
:
call
.return_
.map
(
unwrap_label_direct
),
}
}
CALLIND
=>
{
let
call
=
jmp
.call
.unwrap
();
IrJmp
::
CallInd
{
target
:
unwrap_label_indirect
(
call
.target
)
.into
(),
return_
:
call
.return_
.map
(
unwrap_label_direct
),
}
}
RETURN
=>
IrJmp
::
Return
(
unwrap_label_indirect
(
jmp
.goto
.unwrap
())
.into
()),
}
}
}
// TODO: Remove since code duplication?
#[derive(Serialize,
Deserialize,
Debug,
PartialEq,
Eq,
Hash,
Clone)]
pub
enum
Label
{
...
...
@@ -47,7 +94,7 @@ impl From<Def> for IrDef {
match
def
.rhs.mnemonic
{
COPY
=>
IrDef
::
Assign
{
var
:
def
.lhs
.into
(),
value
:
IrExpression
::
from
(
def
.rhs
),
value
:
def
.rhs.input0
.unwrap
()
.into
(
),
},
LOAD
=>
IrDef
::
Load
{
var
:
def
.lhs
.into
(),
...
...
@@ -57,10 +104,11 @@ impl From<Def> for IrDef {
address
:
def
.rhs.input1
.unwrap
()
.into
(),
value
:
def
.rhs.input2
.unwrap
()
.into
(),
},
PIECE
|
INT_EQUAL
|
INT_NOTEQUAL
|
INT_LESS
|
INT_SLESS
|
INT_ADD
|
INT_SUB
|
INT_CARRY
|
INT_SCARRY
|
INT_SBORROW
|
INT_XOR
|
INT_AND
|
INT_OR
|
INT_LEFT
|
INT_RIGHT
|
INT_SRIGHT
|
INT_MULT
|
INT_DIV
|
INT_REM
|
INT_SDIV
|
INT_SREM
|
BOOL_XOR
|
BOOL_AND
|
BOOL_OR
|
FLOAT_EQUAL
|
FLOAT_NOTEQUAL
|
FLOAT_LESS
|
FLOAT_LESSEQUAL
|
FLOAT_ADD
PIECE
|
INT_EQUAL
|
INT_NOTEQUAL
|
INT_LESS
|
INT_SLESS
|
INT_LESSEQUAL
|
INT_SLESSEQUAL
|
INT_ADD
|
INT_SUB
|
INT_CARRY
|
INT_SCARRY
|
INT_SBORROW
|
INT_XOR
|
INT_AND
|
INT_OR
|
INT_LEFT
|
INT_RIGHT
|
INT_SRIGHT
|
INT_MULT
|
INT_DIV
|
INT_REM
|
INT_SDIV
|
INT_SREM
|
BOOL_XOR
|
BOOL_AND
|
BOOL_OR
|
FLOAT_EQUAL
|
FLOAT_NOTEQUAL
|
FLOAT_LESS
|
FLOAT_LESSEQUAL
|
FLOAT_ADD
|
FLOAT_SUB
|
FLOAT_MULT
|
FLOAT_DIV
=>
IrDef
::
Assign
{
var
:
def
.lhs
.into
(),
value
:
IrExpression
::
BinOp
{
...
...
@@ -77,8 +125,8 @@ impl From<Def> for IrDef {
arg
:
Box
::
new
(
def
.rhs.input0
.unwrap
()
.into
()),
},
},
INT_NEGATE
|
INT_2COMP
|
BOOL_NEGATE
|
FLOAT_NEGATE
|
FLOAT_ABS
|
FLOAT_SQRT
|
FLOAT_CEIL
|
FLOAT_FLOOR
|
FLOAT_ROUND
|
FLOAT_NAN
=>
IrDef
::
Assign
{
INT_NEGATE
|
INT_2COMP
|
BOOL_NEGATE
|
FLOAT_NEGATE
|
FLOAT_ABS
|
FLOAT_SQRT
|
FLOAT_CEIL
|
FLOAT_FLOOR
|
FLOAT_ROUND
|
FLOAT_NAN
=>
IrDef
::
Assign
{
var
:
def
.lhs
.into
(),
value
:
IrExpression
::
UnOp
{
op
:
def
.rhs.mnemonic
.into
(),
...
...
@@ -171,7 +219,7 @@ mod tests {
"
#
,
)
.unwrap
();
let
_
:
IrDef
=
def
.into
();
let
_
:
IrDef
=
def
.into
();
}
#[test]
...
...
This diff is collapsed.
Click to expand it.
cwe_checker_rs/src/term/mod.rs
View file @
c11a21e9
use
crate
::
bil
::
*
;
use
crate
::
intermediate_representation
::
Def
as
IrDef
;
use
crate
::
intermediate_representation
::
Expression
as
IrExpression
;
use
crate
::
intermediate_representation
::
Jmp
as
IrJmp
;
use
serde
::{
Deserialize
,
Serialize
};
pub
mod
symbol
;
...
...
@@ -37,6 +40,80 @@ pub struct Def {
pub
rhs
:
Expression
,
}
impl
Def
{
fn
to_ir_defs
(
self
)
->
Vec
<
IrDef
>
{
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
.to_ir_assignment
())
.collect
();
ir_defs
.push
(
IrDef
::
Load
{
address
:
cleaned_address
.into
(),
var
:
self
.lhs
.into
(),
});
ir_defs
}
Expression
::
Store
{
address
,
value
,
..
}
=>
{
let
(
mut
defs
,
cleaned_address
,
counter
)
=
extract_loads_from_expression
(
*
address
,
0
);
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
.to_ir_assignment
())
.collect
();
ir_defs
.push
(
IrDef
::
Store
{
address
:
cleaned_address
.into
(),
value
:
cleaned_value
.into
(),
});
ir_defs
}
Expression
::
IfThenElse
{
condition
,
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
)
{
(
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
.to_ir_assignment
())
.collect
();
ir_defs
.push
(
IrDef
::
Store
{
address
:
cleaned_adress
.into
(),
value
:
IrExpression
::
Unknown
{
description
:
"BAP conditional store"
.into
(),
size
:
cleaned_value
.bitsize
()
.into
(),
},
});
ir_defs
}
_
=>
vec!
[
self
.to_ir_assignment
()],
}
}
fn
to_ir_assignment
(
self
)
->
IrDef
{
IrDef
::
Assign
{
var
:
self
.lhs
.into
(),
value
:
self
.rhs
.into
(),
}
}
}
#[derive(Serialize,
Deserialize,
Debug,
PartialEq,
Eq,
Hash,
Clone)]
pub
struct
Jmp
{
pub
condition
:
Option
<
Expression
>
,
...
...
@@ -51,6 +128,38 @@ pub enum JmpKind {
Interrupt
{
value
:
isize
,
return_addr
:
Tid
},
}
impl
From
<
Jmp
>
for
IrJmp
{
fn
from
(
jmp
:
Jmp
)
->
IrJmp
{
match
jmp
.kind
{
JmpKind
::
Goto
(
Label
::
Direct
(
tid
))
=>
IrJmp
::
Branch
(
tid
),
JmpKind
::
Goto
(
Label
::
Indirect
(
expr
))
=>
IrJmp
::
BranchInd
(
expr
.into
()),
JmpKind
::
Return
(
Label
::
Indirect
(
expr
))
=>
IrJmp
::
Return
(
expr
.into
()),
JmpKind
::
Return
(
Label
::
Direct
(
_
))
=>
panic!
(),
JmpKind
::
Call
(
call
)
=>
{
let
return_
=
match
call
.return_
{
Some
(
Label
::
Direct
(
tid
))
=>
Some
(
tid
),
None
=>
None
,
_
=>
panic!
(),
};
match
call
.target
{
Label
::
Direct
(
tid
)
=>
IrJmp
::
Call
{
target
:
tid
,
return_
,
},
Label
::
Indirect
(
expr
)
=>
IrJmp
::
CallInd
{
target
:
expr
.into
(),
return_
,
},
}
}
JmpKind
::
Interrupt
{
value
,
return_addr
}
=>
IrJmp
::
CallOther
{
description
:
format!
(
"Interrupt {}"
,
value
),
return_
:
Some
(
return_addr
),
},
}
}
}
#[derive(Serialize,
Deserialize,
Debug,
PartialEq,
Eq,
Hash,
Clone)]
pub
struct
Call
{
pub
target
:
Label
,
...
...
@@ -168,6 +277,106 @@ impl ArgIntent {
}
}
fn
extract_loads_from_expression
(
expr
:
Expression
,
counter
:
u64
)
->
(
Vec
<
Def
>
,
Expression
,
u64
)
{
use
Expression
::
*
;
match
expr
{
Load
{
memory
,
address
,
endian
,
size
,
}
=>
{
let
(
mut
defs
,
cleaned_address
,
mut
counter
)
=
extract_loads_from_expression
(
*
address
,
counter
);
counter
+=
1
;
let
temp_var
=
Variable
{
name
:
format!
(
"temp_{}"
,
counter
),
type_
:
Type
::
Immediate
(
size
),
is_temp
:
true
,
};
defs
.push
(
Def
{
lhs
:
temp_var
.clone
(),
rhs
:
Load
{
memory
,
address
:
Box
::
new
(
cleaned_address
),
endian
,
size
,
},
});
(
defs
,
Var
(
temp_var
),
counter
)
}
Var
(
_
)
|
Const
(
_
)
|
Unknown
{
..
}
=>
(
Vec
::
new
(),
expr
,
counter
),
Store
{
..
}
|
Let
{
..
}
|
IfThenElse
{
..
}
=>
panic!
(),
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
);
defs
.append
(
&
mut
defs_rhs
);
(
defs
,
BinOp
{
op
,
lhs
:
Box
::
new
(
cleaned_lhs
),
rhs
:
Box
::
new
(
cleaned_rhs
),
},
counter
,
)
}
UnOp
{
op
,
arg
}
=>
{
let
(
defs
,
cleaned_arg
,
counter
)
=
extract_loads_from_expression
(
*
arg
,
counter
);
(
defs
,
UnOp
{
op
,
arg
:
Box
::
new
(
cleaned_arg
),
},
counter
,
)
}
Cast
{
kind
,
width
,
arg
}
=>
{
let
(
defs
,
cleaned_arg
,
counter
)
=
extract_loads_from_expression
(
*
arg
,
counter
);
(
defs
,
Cast
{
kind
,
width
,
arg
:
Box
::
new
(
cleaned_arg
),
},
counter
,
)
}
Extract
{
low_bit
,
high_bit
,
arg
,
}
=>
{
let
(
defs
,
cleaned_arg
,
counter
)
=
extract_loads_from_expression
(
*
arg
,
counter
);
(
defs
,
Extract
{
low_bit
,
high_bit
,
arg
:
Box
::
new
(
cleaned_arg
),
},
counter
,
)
}
Concat
{
left
,
right
}
=>
{
let
(
mut
defs
,
cleaned_left
,
counter
)
=
extract_loads_from_expression
(
*
left
,
counter
);
let
(
mut
defs_right
,
cleaned_right
,
counter
)
=
extract_loads_from_expression
(
*
right
,
counter
);
defs
.append
(
&
mut
defs_right
);
(
defs
,
Concat
{
left
:
Box
::
new
(
cleaned_left
),
right
:
Box
::
new
(
cleaned_right
),
},
counter
,
)
}
}
}
#[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