Skip to content

A small transpiler that allows inline pseudo code -> general assembly conversion. Used in https://github.com/ivario123/symex

License

Notifications You must be signed in to change notification settings

ivajon/transpiler

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

11 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Symex General Assembly Transpiler

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.

Usage

⚠️ **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.

Examples

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 writing
if 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();
    }
]);

A bit more involved examples

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

License

This repository is licensed under the MIT license and any contributions shall be licensed under the same license unless explicitly stated otherwise.

About

A small transpiler that allows inline pseudo code -> general assembly conversion. Used in https://github.com/ivario123/symex

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages