This repository defines a small DSL used to define symex general_assembly instructions more cleanly and shortly rather than writing out struct by hand. This crate only makes sense in the context of Symex as of now.
⚠️ **All declarations are inserted before the start of the most recent block**
This means that the code
pseudo!([
let a = b + c;
])
inserts the declaration of a
right above the call to pseudo
while the code
let s = false;
pseudo!([
let a = b + c;
if (s) {
let d = a + c;
}
])
inserts the declaration of d
inside the generated if
statement.
Finally, code like
let s = false;
pseudo!([
let a = b + c;
if (s) {
let d = a + c;
}
let f = d;
])
inserts the declaration of f
right after the if
block ends.
This allows scoping of variables but not shadowing of variables.
Move
Instead of writing
ret.push(Operation::Move {
destiation: rd.clone(),
source: rn.clone()
});
We can now write
pseudo!(ret.extend[
rd = rn
]);
Conditional add or subtract
Instead of writingif add {
ret.push(Operation::Add {
destiation: rd.clone(),
operand1: rn.clone(),
operand2: rm.clone()
});
} else {
ret.push(Operation::Sub {
destination: rd.clone(),
operand1: rn.clone(),
operand2: rm.clone()
});
}
We can now write
pseudo!(ret.extend[
if (add) {
rd = rn + rm;
}
else {
rd = rn - rm;
}
]);
Add 1 to vector of registers
Assuming that the registers implement Into<Operand>
.
And that we implement some LocalInto<Operand>
for u32.
Instead of writing
for register in registers {
ret.push(
Operation::Add {
destination: rd.clone(),
operand1: register.into(),
operand2: 1.local_into()
}
)
}
We can now write
pseudo!(ret.extend[
for register in registers {
rd = register.into() + 1.local_into();
}
]);
I am not going to write these out in struct form as that would take up a lot of space.
Add together the msh and lsh of a register
let ret = pseudo!([
let result = register<31:16> + register<15:0>;
]);
Branch to XOR result between to register if Jump is true
let ret = pseudo!([
let result = rn ^ rm;
if(Jump) {
Jump(result)
}
]);
Adc but set flags if S is true
let ret = pseudo!([
let result = rn adc rm;
if(s) {
SetZFlag(result);
SetNFlag(result);
// Can be add, adc, sbc, sub
SetCFlag(rn,rm,adc);
SetVFlag(rn,rm,adc);
}
rd = result;
]);
for a more detailed look at the language features please read the language documentation
This repository is licensed under the MIT license and any contributions shall be licensed under the same license unless explicitly stated otherwise.