Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/striga/semantics.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ class GPR(NamedTuple):
"af": 4,
"zf": 6,
"sf": 7,
"df": 10,
"of": 11,
}

Expand Down Expand Up @@ -123,6 +124,7 @@ def __init__(self, module: Module, *, verbose=False):
"of": 8,
"pf": 8,
"af": 8,
"df": 8,
}
self.reg_types = {
name: types.int_n(size) for name, size in self.reg_sizes.items()
Expand Down
10 changes: 10 additions & 0 deletions src/striga/x86/control.py
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,16 @@ def clc(sem: Semantics):
sem.flag_write("cf", sem.i1.constant(0))


@semantic
def std(sem: Semantics):
sem.flag_write("df", sem.i1.constant(1))


@semantic
def cld(sem: Semantics):
sem.flag_write("df", sem.i1.constant(0))


@semantic
def int_(sem: Semantics):
sem.ir.ret_void()
Expand Down
71 changes: 68 additions & 3 deletions src/striga/x86/data.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from capstone import CS_OP_REG
from llvm import lookup_intrinsic_id
from ..semantics import FLAGS, Semantics, semantic
from capstone import CS_OP_REG, CS_OP_MEM
from llvm import lookup_intrinsic_id, IntPredicate
from ..semantics import FLAGS, Semantics, Successor, semantic, _semantics


@semantic
Expand Down Expand Up @@ -168,3 +168,68 @@ def xchg(sem: Semantics):
dst = sem.op_read(0)
sem.op_write(0, src)
sem.op_write(1, dst)


def _movs_step(sem: Semantics):
size = sem.insn.operands[0].size
sem.op_write(0, sem.op_read(1))
df = sem.flag_read("df")
delta = sem.ir.select(
df, sem.const64(-size, sign_extend=True), sem.const64(size)
)
sem.reg_write("rsi", sem.ir.add(sem.reg_read("rsi"), delta))
sem.reg_write("rdi", sem.ir.add(sem.reg_read("rdi"), delta))


@semantic
def movsb(sem: Semantics):
_movs_step(sem)


@semantic
def movsw(sem: Semantics):
_movs_step(sem)


@semantic
def movsq(sem: Semantics):
_movs_step(sem)


@semantic
def movsd(sem: Semantics):
if all(op.type == CS_OP_MEM for op in sem.insn.operands):
_movs_step(sem)
else:
mov(sem)


def _rep(sem: Semantics, step_fn):
addr = sem.insn.address
fallthrough = addr + sem.insn.size
check = sem.function.append_basic_block(f"rep_check_{addr:#x}")
body = sem.function.append_basic_block(f"rep_body_{addr:#x}")
exit_block = sem.get_or_create_block(fallthrough)

sem.ir.br(check)

with check.create_builder() as ir:
sem.ir = ir
cond = sem.ir.icmp(IntPredicate.NE, sem.reg_read("rcx"), sem.const64(0))
sem.ir.cond_br(cond, body, exit_block)

with body.create_builder() as ir:
sem.ir = ir
step_fn(sem)
sem.reg_write("rcx", sem.ir.sub(sem.reg_read("rcx"), sem.const64(1)))
sem.ir.br(check)

return [Successor(addr, sem.const64(fallthrough))]


def _rep_movs(sem: Semantics):
return _rep(sem, _movs_step)


for _m in ("rep movsb", "rep movsw", "rep movsd", "rep movsq"):
_semantics[_m] = _rep_movs