Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def __init__(self) -> None:
import capstone.x86
Operand._x86_op_imm = capstone.x86.X86_OP_IMM
Operand._x86_op_reg = capstone.x86.X86_OP_REG
Operand._x86_op_mem = capstone.x86.X86_OP_MEM
# Index the available x86 registers.
for reg in dir(capstone.x86):
if not reg.startswith("X86_REG_"):
continue
Operand.regs[getattr(capstone.x86, reg)] = reg.split("_")[2].lower()
def getOperands(self, inst):
operands = [] # list of operands [0: type, 1: value]
if len(inst.operands) > 0:
for op in inst.operands:
opInfo = []
if op.type == capstone.x86.X86_OP_REG:
#self.dbiprintf(" - REG: %s" % (inst.reg_name(op.value.reg)))
opInfo.append("reg")
opInfo.append("%s" % inst.reg_name(op.value.reg))
elif op.type == capstone.x86.X86_OP_IMM:
#self.dbiprintf(" - IMM: 0x%x" % (op.value.imm))
opInfo.append("imm")
opInfo.append(op.value.imm)
elif op.type == capstone.x86.X86_OP_MEM: # [0: type, 1: mem addr string, 2: mem element list, 3: mem formula list, 4: mem address]
strSegReg = ""
strBaseReg = ""
strIndexReg = ""
strScale = ""
strDisp = ""
segReg = 0
baseReg = 0
indexReg = 0
scale = 0
disp = 0
baseVal = 0
indexVal = 0
memList = []
memList.append("[")
if op.value.mem.segment != 0:
segReg = op.value.mem.segment
# is called, instructions are not pushed in memory. We have only
# the set of the function.
if ad in inner_code:
n -= 1
i = inner_code[ad]
if i is None:
return None
if is_jump(i):
return None
if len(i.operands) >= 1:
op1 = i.operands[0]
if op1.type == X86_OP_REG and op1.value.reg == jump_reg:
if len(i.operands) != 2:
return None
op2 = i.operands[1]
if op2.type != X86_OP_MEM:
return None
if analyzer.dis.binary.is_address(op2.mem.disp):
return op2.mem.disp
return None
ad -= 1
return None
self._refString = ''
# PUSH
if asm.id == capstone.x86.X86_INS_PUSH:
if len(asm.operands) == 1:
o = asm.operands[0]
if o.type == capstone.x86.X86_OP_IMM:
value = o.imm
self._refString = self._plugin.stringFromVA(value)
# [RIP + ]
if len(asm.operands) > 1:
o = asm.operands[1]
if o.type == capstone.x86.X86_OP_MEM:
if o.mem.base == capstone.x86.X86_REG_RIP:
x = asm.address + asm.size + o.mem.disp
self._refString = self._plugin.stringFromVA(x)
return self._refString
def is_mem(self):
return self.type == cpu.X86_OP_MEM
return n == X86_OP_INVALID
op = i.operands[num_op]
if op.type == X86_OP_IMM:
self._imm(op.value.imm, op.size, hexa,
force_dont_print_data=force_dont_print_data,
is_from_jump=is_from_jump)
elif op.type == X86_OP_REG:
self._add(i.reg_name(op.value.reg))
# elif op.type == X86_OP_FP:
# self._add("%f" % op.value.fp)
elif op.type == X86_OP_MEM:
mm = op.mem
ret = self.get_var_offset(i, num_op)
if ret is not None:
func_addr, off = ret
if i.id == X86_INS_LEA:
self._add("&(")
self._variable(self.get_var_name(func_addr, off))
if i.id == X86_INS_LEA:
self._add(")")
return
if inv(mm.segment) and inv(mm.index) and mm.disp != 0:
if mm.base == X86_REG_RIP or mm.base == X86_REG_EIP:
ad = i.address + i.size + mm.disp
def get_operand_expression(self, ea, n):
""" return an expression representing the 'n'-th operand of the instruction at 'ea'. """
insn = self.instructions[ea]
op = insn.operands[n]
if op.type == capstone.x86.X86_OP_REG:
expr = regloc_t(self.__reg_index(op.reg), op.size*8, name=insn.reg_name(op.reg))
elif op.type == capstone.x86.X86_OP_MEM:
base, index, scale, disp = (None,)*4
if op.mem.base:
base = regloc_t(self.__reg_index(op.mem.base), op.size*8, name=insn.reg_name(op.mem.base))
if op.mem.index:
index = regloc_t(self.__reg_index(op.mem.index), op.size*8, name=insn.reg_name(op.mem.index))
if op.mem.scale > 1:
scale = value_t(op.mem.scale, op.size*8)
if op.mem.disp:
disp = value_t(op.mem.disp, op.size*8)
if base and index and disp:
# ...
# ADDRESS: jmp DWORD PTR SYMBOL
#
# we need to assign SYMBOL to ADDRESS, because in the code
# we have "call ADDRESS" and not "call SYMBOL"
#
# first_inst is the instruction at ADDRESS
#
def inv(n):
return n == X86_OP_INVALID
ARCH_UTILS = dis.load_arch_module().utils
if not ARCH_UTILS.is_uncond_jump(first_inst) or \
first_inst.operands[0].type != X86_OP_MEM:
return -1
mm = first_inst.operands[0].mem
next_ip = first_inst.address + first_inst.size
ptr = mm.disp
if mm.base == X86_REG_RIP or mm.base == X86_REG_EIP:
ptr += next_ip
if ptr not in self.imports or not inv(mm.segment) or \
not inv(mm.index):
return -1
name = "_" + self.reverse_symbols[ptr]
ty = self.db.mem.get_type(ptr)
OP_TYPE_MAP = {
OP_TYPE_REG: 'REG',
OP_TYPE_IMM: 'IMM',
OP_TYPE_MEM: 'MEM',
}
CAPSTONE_OP_TYPE_MAP = {
'X86': {
capstone.x86.X86_OP_REG: OP_TYPE_REG,
capstone.x86.X86_OP_IMM: OP_TYPE_IMM,
capstone.x86.X86_OP_MEM: OP_TYPE_MEM,
},
'AMD64': {
capstone.x86.X86_OP_REG: OP_TYPE_REG,
capstone.x86.X86_OP_IMM: OP_TYPE_IMM,
capstone.x86.X86_OP_MEM: OP_TYPE_MEM,
},
}
CAPSTONE_REG_MAP = {
# will be filled up by fill_reg_map()
'X86': {
},
'AMD64': {
}
}
# Utils
def string_escape(s):
if isinstance(s, bytes):
def store(self, operand, value):
if operand.type == capstone.x86.X86_OP_MEM:
output = self.read_memory_operand(operand.mem)
if isinstance(output, Tagged):
assert output.tag == 0
assert isinstance(output.untagged, Offset)
if isinstance(output.untagged.base, HeapPointer):
self.heap[output.untagged.index] = value
elif isinstance(output.untagged.base, StackPointer):
adjusted_index = output.untagged.index + len(self.stack)
if adjusted_index < 0:
self.stack = [None] * (-adjusted_index) + self.stack
self.stack[0] = value
else:
self.stack[adjusted_index] = value
elif operand.type == capstone.x86.X86_OP_REG:
self.registers[base_register(operand.reg)] = value