Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

X86 16 bit platform support #70

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
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
1 change: 1 addition & 0 deletions angr_platforms/X86_16/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
__all__ = ["arch_86_16", "lift_86_16", "simos_86_16"]
221 changes: 221 additions & 0 deletions angr_platforms/X86_16/access.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,221 @@
from pyvex.lifting.util.vex_helper import JumpKind, Type

from .hardware import Hardware
from .regs import reg16_t, reg32_t, sgreg_t

# Constants for access modes
MODE_READ = 0
MODE_WRITE = 1
MODE_EXEC = 2


class DataAccess(Hardware):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.tlb = [] # Translation Lookaside Buffer

def set_segment(self, reg, sel):
self.set_gpreg(reg, sel)

def get_segment(self, reg):
return self.lifter_instruction.get(reg.name.lower(), Type.int_16)

#def trans_v2p(self, mode, seg, vaddr):
# laddr = self.trans_v2l(mode, seg, vaddr)
#
# paddr = laddr
# return paddr


def convert_ss_vaddr(self, vaddr):
laddr = vaddr.cast_to(Type.int_16) # Simplify ss: for decompiler
return laddr

def v2p(self, seg, off):
sg, vaddr = self.convert_segoff2vexv(seg, off)
return (sg << 4) + vaddr

def convert_segoff2vexv(self, seg, vaddr):
if isinstance(seg, sgreg_t):
sg = self.get_sgreg(seg)
elif isinstance(seg, int):
sg = self.constant(seg, Type.int_16)
else:
sg = seg
if not isinstance(vaddr, int):
vaddr = vaddr.cast_to(Type.int_32)
sg = sg.cast_to(Type.int_32)
return sg, vaddr

def search_tlb(self, vpn):
if vpn + 1 > len(self.tlb) or self.tlb[vpn] is None:
return None
return self.tlb[vpn]

def cache_tlb(self, vpn, pte):
if vpn + 1 > len(self.tlb):
self.tlb.extend([None] * (vpn + 1 - len(self.tlb)))
self.tlb[vpn] = pte

def push32(self, value):
self.update_gpreg(reg32_t.ESP, -4)
sp = self.get_gpreg(reg32_t.ESP)
self.write_mem32_seg(sgreg_t.SS, sp, value)

def pop32(self):
sp = self.get_gpreg(reg32_t.ESP)
value = self.read_mem32_seg(sgreg_t.SS, sp)
self.update_gpreg(reg32_t.ESP, 4)
return value

def push16(self, value):
self.update_gpreg(reg16_t.SP, -2)
sp = self.get_gpreg(reg16_t.SP)
self.write_mem16_seg(sgreg_t.SS, sp, value)

def pop16(self):
sp = self.get_gpreg(reg16_t.SP)
value = self.read_mem16_seg(sgreg_t.SS, sp)
self.update_gpreg(reg16_t.SP, 2)
return value

def read_mem32_seg(self, seg, addr):
#paddr = self.v2p(seg, addr)
#return self.read_mem32(paddr)
if isinstance(seg, sgreg_t) and seg == sgreg_t.SS:
paddr = self.convert_ss_vaddr(addr)
return self.read_mem32(paddr)
sg, offs = self.convert_segoff2vexv(seg, addr)
self.lifter_instruction.put(sg, "sc_class")
self.lifter_instruction.put(offs, "nraddr")
self.lifter_instruction.jump(None, 0xff032, jumpkind=JumpKind.Call)
return self.lifter_instruction.get("nraddr").cast_to(Type.int_32)

io_base = self.chk_memio(paddr)
return (
self.read_memio32(io_base, paddr - io_base)
if io_base
else self.read_mem32(paddr)
)

def read_mem16_seg(self, seg, addr):
#paddr = self.v2p(seg, addr)
#return self.read_mem16(paddr)
if isinstance(seg, sgreg_t) and seg == sgreg_t.SS:
paddr = self.convert_ss_vaddr(addr)
return self.read_mem16(paddr)
sg, offs = self.convert_segoff2vexv(seg, addr)
self.lifter_instruction.put(sg, "sc_class")
self.lifter_instruction.put(offs, "nraddr")
self.lifter_instruction.jump(None, 0xff016, jumpkind=JumpKind.Call)
return self.lifter_instruction.get("nraddr").cast_to(Type.int_16)

io_base = self.chk_memio(paddr)
return (
self.read_memio16(io_base, paddr - io_base)
if io_base
else self.read_mem16(paddr)
)

def read_mem8_seg(self, seg, addr):
#paddr = self.v2p(seg, addr)
#return self.read_mem8(paddr)
if isinstance(seg, sgreg_t) and seg == sgreg_t.SS:
paddr = self.convert_ss_vaddr(addr)
return self.read_mem8(paddr)
sg, offs = self.convert_segoff2vexv(seg, addr)
self.lifter_instruction.put(sg, "sc_class")
self.lifter_instruction.put(offs, "nraddr")
self.lifter_instruction.jump(None, 0xff08, jumpkind=JumpKind.Call)
return self.lifter_instruction.get("nraddr").cast_to(Type.int_8)

return self.read_mem8(paddr)
io_base = self.chk_memio(paddr)
return (
self.read_memio8(io_base, paddr - io_base)
if io_base
else self.read_mem8(paddr)
)

def write_mem32_seg(self, seg, addr, value):
if isinstance(seg, sgreg_t) and seg == sgreg_t.SS:
paddr = self.convert_ss_vaddr(addr)
return self.read_mem32(paddr)
sg, offs = self.convert_segoff2vexv(seg, addr)
self.lifter_instruction.put(sg, "sc_class")
self.lifter_instruction.put(offs, "nraddr")
self.lifter_instruction.put(value, "cmlen")
self.lifter_instruction.jump(None, 0xff132, jumpkind=JumpKind.Call)
return
io_base = self.chk_memio(paddr)
if io_base:
self.write_memio32(io_base, paddr - io_base, value)
else:
self.write_mem32(paddr, value)

def write_mem16_seg(self, seg, addr, value):
if isinstance(seg, sgreg_t) and seg == sgreg_t.SS:
paddr = self.convert_ss_vaddr(addr)
return self.read_mem32(paddr)
sg, offs = self.convert_segoff2vexv(seg, addr)
self.lifter_instruction.put(sg, "sc_class")
self.lifter_instruction.put(offs, "nraddr")
self.lifter_instruction.put(value, "cmlen")
self.lifter_instruction.jump(None, 0xff116, jumpkind=JumpKind.Call)
return
io_base = self.chk_memio(paddr)
if io_base:
self.write_memio16(io_base, paddr - io_base, value)
else:
self.write_mem16(paddr, value)

def write_mem8_seg(self, seg, addr, value):
if isinstance(seg, sgreg_t) and seg == sgreg_t.SS:
paddr = self.convert_ss_vaddr(addr)
return self.read_mem32(paddr)
sg, offs = self.convert_segoff2vexv(seg, addr)
self.lifter_instruction.put(sg, "sc_class")
self.lifter_instruction.put(offs, "nraddr")
self.lifter_instruction.put(value, "cmlen")
self.lifter_instruction.jump(None, 0xff108, jumpkind=JumpKind.Call)
return
io_base = self.chk_memio(paddr)
if io_base:
self.write_memio8(io_base, paddr - io_base, value)
else:
self.write_mem8(paddr, value)

def get_code8(self, offset):
assert offset == 0
return self.bitstream.read("uint:8")

def get_code16(self, offset):
assert offset == 0
return self.bitstream.read("uintle:16")

def get_code32(self, offset):
assert offset == 0
return self.bitstream.read("uintle:32")

def get_data16(self, seg, addr):
return self.read_mem16_seg(seg, addr)

def get_data32(self, seg, addr):
return self.read_mem32_seg(seg, addr)

def get_data8(self, seg, addr):
return self.read_mem8_seg(seg, addr)

def put_data8(self, seg, addr, value):
self.write_mem8_seg(seg, addr, value)

def put_data16(self, seg, addr, value):
self.write_mem16_seg(seg, addr, value)

def put_data32(self, seg, addr, value):
self.write_mem32_seg(seg, addr, value)

def callf(self, seg, ip):
self.push16(self.get_sgreg(sgreg_t.CS))
self.push16(self.get_gpreg(reg16_t.IP) + 5)
self.lifter_instruction.jump(None, laddr, jumpkind=JumpKind.Call)
Loading