Skip to content

Instantly share code, notes, and snippets.

@Mm7
Created December 20, 2018 08:31
Show Gist options
  • Save Mm7/5c1327a1dff7a3ead2bbc46326533579 to your computer and use it in GitHub Desktop.
Save Mm7/5c1327a1dff7a3ead2bbc46326533579 to your computer and use it in GitHub Desktop.
diff --git a/Cargo.toml b/Cargo.toml
index cda6f34..399e559 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -2,3 +2,12 @@
name = "esil"
version = "0.1.0"
authors = ["Sushant <sushant.dinesh94@gmail.com>"]
+
+[features]
+trace_log = ["log", "env_logger"]
+
+[dependencies]
+log = {version="0.4.0", optional=true}
+env_logger = {version="0.5.0", optional=true}
+
+
diff --git a/src/parser.rs b/src/parser.rs
index 5be7fc6..7a94175 100644
--- a/src/parser.rs
+++ b/src/parser.rs
@@ -68,12 +68,15 @@ impl Parse for Parser {
if self.skip_esil_set == 0 {
if let Some(ref token) = self.last_op {
if token.should_set_vars() && token.updates_result() {
+ println!("token: {:?}, cur: {:?}", token,self.stack.last().clone());
self.ecur = self.stack.last().cloned();
}
}
}
while let Some(token) = self.tokens.as_mut().unwrap().pop_front() {
+ println!("token: {:?}, skip: {}",token, self.skip_esil_set);
+
match token {
// Esil Internal Vars
Token::IZero(_) |
@@ -86,7 +89,8 @@ impl Parse for Parser {
Token::IConstant(_) |
Token::IAddress(_) => {
let mut internal_q = self.evaluate_internal(&token);
- //self.skip_esil_set += internal_q.len() + 1;
+ self.skip_esil_set += internal_q.len() + 2;
+
while let Some(i) = internal_q.pop_back() {
// count the number of operations to skip for.
self.tokens.as_mut().map(|v| v.push_front(i));
@@ -138,12 +142,17 @@ impl Parse for Parser {
_ => {
if self.skip_esil_set == 0 {
self.last_op = Some(token.clone());
- } else {
+ } else if token.is_unary() || (token.is_unary() && !token.should_set_vars()) { // arghhh
+
self.skip_esil_set -= 1;
}
return Some(token);
}
}
+
+ if self.skip_esil_set > 0 {
+ self.skip_esil_set -= 1;
+ }
}
// This means that the parser is empty and there are no more tokens
// to be processed. So we set tokens to None and return None.
@@ -176,6 +185,7 @@ impl Parse for Parser {
}
self.eold = self.last_pop.0.clone();
self.eold_ = self.last_pop.1.clone();
+ println!("token: {:?}, res: {:?}", t, result);
if !t.updates_result() {
self.ecur = result.1.clone();
}
@@ -197,6 +207,10 @@ impl Parse for Parser {
}
}
+ if self.skip_esil_set == 1 && t.should_set_vars() {
+ self.skip_esil_set -= 1;
+ }
+
result
}
}
@@ -237,15 +251,14 @@ impl Parser {
let genmask = |bit: u64| {
// ( 1 << bit ) - 1
if bit == 64 {
- [Token::EConstant(u64::max_value())]
+ u64::max_value()
} else {
- [Token::EConstant((1 << bit) - 1)]
+ (1 << bit) - 1
}
};
// Initialize esil vars.
let esil_old = self.get_meta(Token::EOld);
- let esil_old_ = self.get_meta(Token::EOld_);
let esil_cur = self.get_meta(Token::ECur);
let lastsz = match self.get_meta(Token::ELastsz) {
Token::ELastsz => panic!("lastsz unset!"),
@@ -258,15 +271,23 @@ impl Parser {
// tokens that will be returned from the parser to the consumer.
match *t {
Token::IZero(_) => {
- result.extend(genmask(lastsz).iter().cloned());
- result.extend([esil_cur, Token::EAnd, Token::EConstant(1), Token::EXor]
- .iter()
- .cloned());
- self.skip_esil_set = 4;
+ result.extend([Token::EConstant(genmask(lastsz)),
+ esil_cur,
+ Token::EAnd,
+ Token::EConstant(0),
+ Token::ECmp].iter().cloned());
+// self.skip_esil_set = 4;
}
Token::ICarry(_bit) => {
- result.extend([esil_cur, esil_old, Token::EGt].iter().cloned());
- self.skip_esil_set = 3;
+ let bit: u64 = u64::from(_bit)+1;
+ result.extend([Token::EConstant(genmask(bit)),
+ esil_old,
+ Token::EAnd,
+ Token::EConstant(genmask(bit)),
+ esil_cur,
+ Token::EAnd,
+ Token::ELt].iter().cloned());
+// self.skip_esil_set = 3;
}
Token::IParity(_) => {
// Parity flag computation as described in:
@@ -287,27 +308,33 @@ impl Parser {
Token::EAnd]
.iter()
.cloned());
- self.skip_esil_set = 7;
+// self.skip_esil_set = 7;
}
- Token::IOverflow(_bit) => {
- // of = ((((~eold ^ eold_) & (enew ^ eold)) >> (lastsz - 1)) & 1) == 1
- result.extend([Token::EConstant(1),
- Token::EConstant(1),
- Token::EConstant(lastsz - 1),
+ Token::IOverflow(_) => {
+ // cur = x+y
+ // old = x
+ // carry-out = (cur & mask(bit)) < (old & mask(bit))
+ // carry-in = (cur & mask(bit-1)) < (old & mask(bit-1))
+ // of = carry-in ^ carry-out
+ // For more infos: http://teaching.idallen.com/dat2343/10f/notes/040_overflow.txt
+ result.extend([Token::EConstant(genmask(lastsz)),
esil_old.clone(),
- esil_cur,
- Token::EXor,
- esil_old_,
- esil_old.clone(),
- Token::ENeg,
- Token::EXor,
Token::EAnd,
- Token::ELsr,
+ Token::EConstant(genmask(lastsz)),
+ esil_cur.clone(),
+ Token::EAnd,
+ Token::ELt,
+ Token::EConstant(genmask(lastsz-1)),
+ esil_old,
+ Token::EAnd,
+ Token::EConstant(genmask(lastsz-1)),
+ esil_cur,
Token::EAnd,
- Token::ECmp]
+ Token::ELt,
+ Token::EXor]
.iter()
.cloned());
- self.skip_esil_set = 9;
+// self.skip_esil_set = 9;
}
Token::ISign(_) => {
result.extend([Token::EConstant(1),
@@ -317,23 +344,30 @@ impl Parser {
Token::ELsr]
.iter()
.cloned());
- self.skip_esil_set = 4;
+// self.skip_esil_set = 4;
}
Token::IBorrow(_bit) => {
- result.extend([esil_cur, esil_old, Token::ELt].iter().cloned());
- self.skip_esil_set = 3;
+ let bit: u64 = _bit.into();
+ result.extend([Token::EConstant(genmask(bit)),
+ esil_cur,
+ Token::EAnd,
+ Token::EConstant(genmask(bit)),
+ esil_old,
+ Token::EAnd,
+ Token::ELt].iter().cloned());
+// self.skip_esil_set = 3;
}
Token::ISize(_) => {
result.push_front(Token::EConstant(self.default_size));
- self.skip_esil_set = 2;
+// self.skip_esil_set = 2;
}
Token::IAddress(_) => {
result.push_front(Token::EAddress);
- self.skip_esil_set = 2;
+// self.skip_esil_set = 2;
}
Token::IConstant(n) => {
result.push_front(Token::EConstant(n));
- self.skip_esil_set = 2;
+// self.skip_esil_set = 2;
}
_ => unreachable!(),
}
@@ -427,7 +461,7 @@ mod test {
#[test]
fn parser_zf() {
let expression = construct!("$z,zf,=");
- assert_eq!("(EEq zf, (EXor 0x1, (EAnd rax_cur, 0xFFFFFFFFFFFFFFFF)))",
+ assert_eq!("(EEq zf, (ECmp 0x0, (EAnd rax_cur, 0xFFFFFFFFFFFFFFFF)))",
expression);
}
@@ -439,23 +473,43 @@ mod test {
#[test]
fn parser_cf() {
- let expression = construct!("$c64,cf,=");
- let expected = "(EEq cf, (EGt rax_old, rax_cur))";
+ let expression = construct!("$c63,cf,=");
+ let expected = "(EEq cf, (ELt (EAnd rax_cur, 0xFFFFFFFFFFFFFFFF), (EAnd rax_old, 0xFFFFFFFFFFFFFFFF)))";
+ assert_eq!(expected, expression);
+ }
+
+ #[test]
+ fn parser_cf2() {
+ let expression = construct!("$c31,cf,=");
+ let expected = "(EEq cf, (ELt (EAnd rax_cur, 0xFFFFFFFF), (EAnd rax_old, 0xFFFFFFFF)))";
assert_eq!(expected, expression);
}
#[test]
fn parser_of() {
- // of = ((((~eold ^ eold_) & (enew ^ eold)) >> (lastsz - 1)) & 1) == 1
+ // cur = x+y
+ // old = x
+ // carry-out = (cur & mask(bit)) < (old & mask(bit))
+ // carry-in = (cur & mask(bit-1)) < (old & mask(bit-1))
+ // of = carry-in ^ carry-out
+ // For more infos: http://teaching.idallen.com/dat2343/10f/notes/040_overflow.txt
let expression = construct!("$o,of,=");
- let expected = "(EEq of, (ECmp (EAnd (ELsr (EAnd (EXor (ENeg rax_old, -), rbx_old), (EXor rax_cur, rax_old)), 0x3F), 0x1), 0x1))";
+ let expected = "(EEq of, (EXor (ELt (EAnd rax_cur, 0x7FFFFFFFFFFFFFFF), (EAnd rax_old, 0x7FFFFFFFFFFFFFFF)), (ELt (EAnd rax_cur, 0xFFFFFFFFFFFFFFFF), (EAnd rax_old, 0xFFFFFFFFFFFFFFFF))))";
+// let expected = "(EEq of, (ECmp (EAnd (ELsr (EAnd (EXor (ENeg (EAnd rax_old, 0xFFFFFFFFFFFFFFFF), -), (EAnd rbx_old, 0xFFFFFFFFFFFFFFFF)), (EXor (EAnd rax_cur, 0xFFFFFFFFFFFFFFFF), (EAnd rax_old, 0xFFFFFFFFFFFFFFFF))), 0x3F), 0x1), 0x1))";
assert_eq!(expected, expression);
}
#[test]
fn parser_bf() {
let expression = construct!("$b64,cf,=");
- let expected = "(EEq cf, (ELt rax_old, rax_cur))";
+ let expected = "(EEq cf, (ELt (EAnd rax_old, 0xFFFFFFFFFFFFFFFF), (EAnd rax_cur, 0xFFFFFFFFFFFFFFFF)))";
+ assert_eq!(expected, expression);
+ }
+
+ #[test]
+ fn parser_bf2() {
+ let expression = construct!("$b32,cf,=");
+ let expected = "(EEq cf, (ELt (EAnd rax_old, 0xFFFFFFFF), (EAnd rax_cur, 0xFFFFFFFF)))";
assert_eq!(expected, expression);
}
@@ -517,12 +571,11 @@ mod test {
let mut parser = Parser::init(Some(regset), Some(64));
let expr = ExpressionConstructor::run("ebx,eax,+=,$o,of,=,$s,sf,=,$z,zf,=,$c31,cf,=,$p,pf,=",
Some(&mut parser));
-
let expected = "(EEq eax, (EAdd eax, ebx))\
- (EEq of, (ECmp (EAnd (ELsr (EAnd (EXor (ENeg eax, -), ebx), (EXor (EAdd eax, ebx), eax)), 0x1F), 0x1), 0x1))\
+ (EEq of, (ECmp (EAnd (ELsr (EAnd (EXor (ENeg (EAnd eax, 0xFFFFFFFFFFFFFFFF), -), (EAnd ebx, 0xFFFFFFFFFFFFFFFF)), (EXor (EAnd (EAdd eax, ebx), 0xFFFFFFFFFFFFFFFF), (EAnd eax, 0xFFFFFFFFFFFFFFFF))), 0x1F), 0x1), 0x1))\
(EEq sf, (ELsr (EAdd eax, ebx), (ESub 0x20, 0x1)))\
(EEq zf, (EXor 0x1, (EAnd (EAdd eax, ebx), 0xFFFFFFFF)))\
- (EEq cf, (EGt eax, (EAdd eax, ebx)))\
+ (EEq cf, (ELt (EAnd (EAdd eax, ebx), 0xFFFFFFFFFFFFFFFF), (EAnd eax, 0xFFFFFFFFFFFFFFFF)))\
(EEq pf, (EAnd (EMod (EAnd (EMul (EAnd (EAdd eax, ebx), 0xFF), 0x101010101010101), 0x8040201008040201), 0x1FF), 0x1))";
assert_eq!(expected, &expr);
@@ -593,11 +646,19 @@ mod test {
Some(&mut parser));
let expected = "(EEq eax, (EAdd eax, (EAdd eax, cf)))\
+ (EEq of, (EXor (ELt (EAnd (EAdd eax, (EAdd eax, cf)), 0x7FFFFFFF), (EAnd eax, 0x7FFFFFFF)), (ELt (EAnd (EAdd eax, (EAdd eax, cf)), 0xFFFFFFFF), (EAnd eax, 0xFFFFFFFF))))\
+ (EEq sf, (ELsr (EAdd eax, (EAdd eax, cf)), (ESub 0x20, 0x1)))\
+ (EEq zf, (ECmp 0x0, (EAnd (EAdd eax, (EAdd eax, cf)), 0xFFFFFFFF)))\
+ (EEq cf, (ELt (EAnd (EAdd eax, (EAdd eax, cf)), 0xFFFFFFFF), (EAnd eax, 0xFFFFFFFF)))\
+ (EEq pf, (EAnd (EMod (EAnd (EMul (EAnd (EAdd eax, (EAdd eax, cf)), 0xFF), 0x101010101010101), 0x8040201008040201), 0x1FF), 0x1))";
+
+
+/* let expected = "(EEq eax, (EAdd eax, (EAdd eax, cf)))\
(EEq of, (ECmp (EAnd (ELsr (EAnd (EXor (ENeg eax, -), (EAdd eax, cf)), (EXor (EAdd eax, (EAdd eax, cf)), eax)), 0x1F), 0x1), 0x1))\
(EEq sf, (ELsr (EAdd eax, (EAdd eax, cf)), (ESub 0x20, 0x1)))\
(EEq zf, (EXor 0x1, (EAnd (EAdd eax, (EAdd eax, cf)), 0xFFFFFFFF)))\
(EEq cf, (EGt eax, (EAdd eax, (EAdd eax, cf))))\
- (EEq pf, (EAnd (EMod (EAnd (EMul (EAnd (EAdd eax, (EAdd eax, cf)), 0xFF), 0x101010101010101), 0x8040201008040201), 0x1FF), 0x1))";
+ (EEq pf, (EAnd (EMod (EAnd (EMul (EAnd (EAdd eax, (EAdd eax, cf)), 0xFF), 0x101010101010101), 0x8040201008040201), 0x1FF), 0x1))";*/
assert_eq!(expected, &expr);
assert_eq!(parser.skip_esil_set, 1);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment