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 symbol(self):
# get symbol from plugin (for API calls for eg.)
if self._symbol != None:
return self._symbol
# get symbol
if self.ingroup([capstone.x86.X86_GRP_CALL]):
value = None
asm = self._asm
for o in asm.operands:
if o.type == capstone.x86.X86_OP_IMM:
value = o.imm
if o.type == capstone.x86.X86_OP_MEM:
# todo: should we consider other reg relative ??
if o.mem.base == capstone.x86.X86_REG_RIP:
value = o.mem.disp + asm.size + asm.address
# mainly 32bit
if o.mem.base == capstone.x86.X86_REG_INVALID:
value = o.mem.disp
if value:
sym = self._plugin.disasmSymbol(value)
if sym:
self._symbol = sym
repeat += 1
if list(c.bytes) != NOPCODE:
nopcode_repeat = False
break
if nopcode_repeat:
codes = codes[:1]
self.repeat = repeat
else:
self.repeat = 1
if original_opcode_len == len(opcode) and len(codes) == 1:
code = codes[0]
if (len(code.operands) == 1 and
((self.disasmblr.arch in ['x86','x64'] and code.operands[0].type == X86_OP_IMM) or
(self.disasmblr.arch == 'ARM' and code.operands[0].type == ARM_OP_IMM))):
self.view.update_list(self.view.disasmlist._w.focus_position)
self.instruction = code
self.hexcode = list(self.instruction.bytes)
self.mode_plain()
else:
def update_all(yn, arg):
if yn == "y":
self.view.update_list(self.view.disasmlist._w.focus_position)
else:
self.modify_opcode(original_opcode)
signals.set_prompt_yn.send(self,
text="This operation will break following codes, is it okey?",
callback=update_all,
def get_value_written(inst):
# Only few instructions are supported
if inst.id == X86_INS_MOV:
op = inst.operands[1]
if op.type == X86_OP_IMM:
return op.value.imm
elif inst.id == X86_INS_XOR:
return 0
return None
def is_immediate(ctx, i, index):
return i.operands[index].type == capstone.x86.X86_OP_IMM
if insn.id == X86_INS_PUSH and \
insn.operands[0].type == X86_OP_IMM:
imm = insn.operands[0].value.imm
if arg_count == 0:
new_function(imm, "main")
elif arg_count == 1:
new_function(imm, "__libc_csu_init")
elif arg_count == 2:
new_function(imm, "__libc_csu_fini")
arg_count += 1
else: # x64
if insn.id == X86_INS_MOV and \
insn.operands[0].type == X86_OP_REG and \
insn.operands[1].type == X86_OP_IMM:
reg = insn.operands[0].value.reg
imm = insn.operands[1].value.imm
if reg == X86_REG_RDI:
new_function(imm, "main")
elif reg == X86_REG_RCX:
new_function(imm, "__libc_csu_init")
elif reg == X86_REG_R8:
new_function(imm, "__libc_csu_fini")
insn_count -= 1
ad -= 1
def gather_case_arms(settings, heaps, address, min_tag, max_tag, initial_stack, initial_registers, original_stack, original_inspection, path):
mach = machine.Machine(settings, heaps, copy.deepcopy(initial_stack), copy.deepcopy(initial_registers))
first_instructions = list(disasm.disasm_from_until(settings, address, lambda insn: insn.group(capstone.x86.X86_GRP_JUMP)))
mach.simulate(first_instructions)
if first_instructions[-2].mnemonic == 'cmp' and isinstance(mach.load(first_instructions[-2].operands[0]), Tagged) and isinstance(mach.load(first_instructions[-2].operands[0]).untagged, Offset) and isinstance(mach.load(first_instructions[-2].operands[0]).untagged.base, CasePointer) and first_instructions[-2].operands[1].type == capstone.x86.X86_OP_IMM:
assert first_instructions[-1].mnemonic == 'jae'
small_address = sum(map(lambda insn: insn.size, first_instructions)) + address
large_address = first_instructions[-1].operands[0].imm
arms_small, tags_small, stacks_small, regs_small = gather_case_arms(settings, heaps, small_address, min_tag, first_instructions[-2].operands[1].imm - 1, mach.stack, mach.registers, original_stack, original_inspection, path + [address])
arms_large, tags_large, stacks_large, regs_large = gather_case_arms(settings, heaps, large_address, first_instructions[-2].operands[1].imm, max_tag, mach.stack, mach.registers, original_stack, original_inspection, path + [address])
arms = arms_small + arms_large
tags = tags_small + tags_large
stacks = stacks_small + stacks_large
registers = regs_small + regs_large
else:
arms = [address]
if min_tag == max_tag:
tag = NumericTag(value = min_tag)
else:
# if ptr is on the same memory page than rip/eip it's a func ptr
op_src = self.ctx_instr.operands[1]
if op_src.type == capstone.x86.X86_OP_MEM:
if op_src.mem.base in [capstone.x86.X86_REG_RIP,
capstone.x86.X86_REG_EIP]:
if op_src.mem.index == 0 and\
int((op_src.mem.disp + self.instr.address) / 4096)\
== int(self.instr.address / 4096):
return _dynStruct.ptr_func_str
# if not it's just a ptr because we cannot have more information
return _dynStruct.ptr_str
# when the mov is an imm value on the same page than rip => func_ptr
if self.instr.mnemonic.startswith('mov') and\
self.instr.op_find(capstone.x86.X86_OP_IMM, 1) and\
size == _dynStruct.bits / 8:
if int(self.instr.address / 4096) ==\
int(self.instr.operands[1].imm / 4096):
return _dynStruct.ptr_func_str
# detecting if signed or unsigned
if self.instr.mnemonic.startswith('mov') and len(self.ctx_instr.operands) == 2:
dest_ctx_op = self.ctx_instr.operands[0]
src_op = self.instr.operands[1]
if dest_ctx_op.type == capstone.x86.X86_OP_REG and\
src_op.type == capstone.x86.X86_OP_REG and\
src_op.reg == dest_ctx_op.reg:
if self.instr.id in unsigned_int_instr:
return _dynStruct.unsigned_str % (size)
# For read access we can only detect ptr because a use of the value read
if insn_info is None:
info = INS_INFO.get(arch_name, None)
if info is not None:
insn_info = info.get(instr.insn.insn.id, None)
if insn_info is None:
return
instr.type = insn_info
if instr.type in ('call', 'branch'):
# determine if this is a direct or indirect call/branch
if arch_name in ('X86', 'AMD64'):
last_operand = instr.insn.operands[-1]
if last_operand.type == cs.x86.X86_OP_IMM:
instr.branch_type = 'direct'
else:
instr.branch_type = 'indirect'
instr.branch_target_operand = len(instr.insn.operands) - 1
elif arch_name == 'MIPS32':
# check the last operand
last_operand = instr.insn.operands[-1]
if last_operand.type == cs.mips.MIPS_OP_REG:
instr.branch_type = 'indirect'
else:
instr.branch_type = 'direct'
instr.branch_target_operand = len(instr.insn.operands) - 1
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