本文整理汇总了Python中distorm3.Decompose方法的典型用法代码示例。如果您正苦于以下问题:Python distorm3.Decompose方法的具体用法?Python distorm3.Decompose怎么用?Python distorm3.Decompose使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类distorm3
的用法示例。
在下文中一共展示了distorm3.Decompose方法的9个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的Python代码示例。
示例1: __init__
# 需要导入模块: import distorm3 [as 别名]
# 或者: from distorm3 import Decompose [as 别名]
def __init__(self, offset, code, type = distorm3.Decode32Bits, feature = 0):
"""
@param offset Address of the instruction
@param code Opcode bytes of the instruction
@param type Dissassemble 32 or 64 bit code
@param feature Possible settings for distrom3
not used at the moment
"""
self.valid = False
if SV.dissassm_type == 64:
type = distorm3.Decode64Bits
else:
type = distorm3.Decode32Bits
inst = distorm3.Decompose(offset, code, type, feature)
if len(inst) == 1:
self.Instruction = inst[0]
if self.Instruction.valid:
self.valid = True
self.opcode_len = len(code)
self.opcode_bytes = []
self.addr = offset
for x in code:
self.opcode_bytes.append(ord(x))
self._len = len(self.Instruction.operands) + 1
示例2: find_rr_writes_distorm3
# 需要导入模块: import distorm3 [as 别名]
# 或者: from distorm3 import Decompose [as 别名]
def find_rr_writes_distorm3(address, data):
writes = []
for insn in distorm3.Decompose(address, data, type=distorm3.Decode64Bits):
if insn.mnemonic[:3] == 'RET':
break
if insn.mnemonic[:3] != 'MOV':
continue
# potential write
opnd = insn.operands[0]
if opnd.type != 'AbsoluteMemory' or opnd.index is None:
continue
# Absolute mov, with target that is register-based
if distorm3.Registers[opnd.index] != 'RIP':
continue
# RIP-relative write, this is what we are looking for
# distorm3 opnd.size is measured in bits, need to adjust to bytes
writes.append((insn.address + insn.size + opnd.disp, opnd.size / 8))
return writes
# Find rip-relative mov using capstone
示例3: get_distorm_info
# 需要导入模块: import distorm3 [as 别名]
# 或者: from distorm3 import Decompose [as 别名]
def get_distorm_info(inst_addr):
"""
@brief Prints whole distrom3 info of the given instruction
@param inst_addr Address of instruction
"""
size = ItemSize(inst_addr)
inst_bytes = GetManyBytes(inst_addr, size)
inst = distorm3.Decompose(inst_addr,
inst_bytes, distorm3.Decode64Bits, 0)
print inst[0]
i = inst[0]
print 'InstBytes ', i.instructionBytes
print 'Opcode ', i.opcode
for o in i.operands:
print 'operand ', o
print 'operand type', o.type
for f in i.flags:
print 'flag ', f
print 'raw_flags ', i.rawFlags
print 'inst_class ', i.instructionClass
print 'flow_control ', i.flowControl
print 'address ', i.address
print 'size ', i.size
print 'dt ', i.dt
print 'valid ', i.valid
print 'segment ', i.segment
print 'unused_Prefixes ', i.unusedPrefixesMask
print 'mnemonic ', i.mnemonic
print 'inst_class ', i.instructionClass
示例4: _get_table_info_distorm
# 需要导入模块: import distorm3 [as 别名]
# 或者: from distorm3 import Decompose [as 别名]
def _get_table_info_distorm(self):
"""
Find the size of the system call table by disassembling functions
that immediately reference it in their first isntruction
This is in the form 'cmp reg,NR_syscalls'
"""
table_size = 0
if not has_distorm:
return table_size
memory_model = self.addr_space.profile.metadata.get('memory_model', '32bit')
if memory_model == '32bit':
mode = distorm3.Decode32Bits
func = "sysenter_do_call"
else:
mode = distorm3.Decode64Bits
func = "system_call_fastpath"
func_addr = self.addr_space.profile.get_symbol(func)
if func_addr:
data = self.addr_space.read(func_addr, 6)
for op in distorm3.Decompose(func_addr, data, mode):
if not op.valid:
continue
if op.mnemonic == 'CMP':
table_size = (op.operands[1].value) & 0xffffffff
break
return table_size
示例5: isPrologInlined
# 需要导入模块: import distorm3 [as 别名]
# 或者: from distorm3 import Decompose [as 别名]
def isPrologInlined(self, model, distorm_mode, func_addr):
##check if function prologs are modified
inlined = False
content = self.addr_space.read(func_addr, 24)
op_cnt = 1
for op in distorm3.Decompose(func_addr, content, distorm_mode):
if op_cnt == 2:
if model == "32bit":
if (op.mnemonic == "MOV" and len(op.operands) == 2 and op.operands[0].type == "Register" and
op.operands[1].type == "Register" and op.operands[0].name == "EBP" and op.operands[1].name == "ESP" and
prev_op.mnemonic == "PUSH" and len(prev_op.operands) == 1 and prev_op.operands[0].type == "Register" and prev_op.operands[0].name == "EBP"):
pass
else:
inlined = True
elif model == "64bit":
if (op.mnemonic == "MOV" and len(op.operands) == 2 and op.operands[0].type == "Register" and
op.operands[1].type == "Register" and op.operands[0].name == "RBP" and op.operands[1].name == "RSP" and
prev_op.mnemonic == "PUSH" and len(prev_op.operands) == 1 and prev_op.operands[0].type == "Register" and prev_op.operands[0].name == "RBP"):
pass
elif (prev_op.mnemonic == "PUSH" and len(prev_op.operands) == 1 and prev_op.operands[0].type == "Register" and prev_op.operands[0].name == "RBP" and
op.mnemonic == "PUSH" and len(op.operands) == 1 and op.operands[0].type == "Register" and op.operands[0].name in ["RSP","RBX","R12","R13","R14","R15"]):
# Registers preserved across calls, http://people.freebsd.org/~lstewart/references/amd64.pdf
pass
else:
inlined = True
break
prev_op = op
op_cnt += 1
return inlined
# NOTES FROM ANDREW
# This function orignally checked for any call outside the kernel module
# This produces too many false positives so its modified to check if the call
# is to a known module or a kernel symbol
示例6: _get_table_info_distorm
# 需要导入模块: import distorm3 [as 别名]
# 或者: from distorm3 import Decompose [as 别名]
def _get_table_info_distorm(self):
"""
Find the size of the system call table by disassembling functions
that immediately reference it in their first isntruction
This is in the form 'cmp reg,NR_syscalls'
"""
table_size = 0
if not has_distorm:
return table_size
memory_model = self.addr_space.profile.metadata.get('memory_model', '32bit')
if memory_model == '32bit':
mode = distorm3.Decode32Bits
funcs = ["sysenter_do_call"]
else:
mode = distorm3.Decode64Bits
funcs = ["system_call_fastpath", "do_int80_syscall_32"]
for func in funcs:
func_addr = self.addr_space.profile.get_symbol(func)
if func_addr:
data = self.addr_space.read(func_addr, 64)
for op in distorm3.Decompose(func_addr, data, mode):
if not op.valid:
continue
if op.mnemonic == 'CMP':
table_size = (op.operands[1].value) & 0xffffffff
break
break
return table_size
示例7: isCallReferenceModified
# 需要导入模块: import distorm3 [as 别名]
# 或者: from distorm3 import Decompose [as 别名]
def isCallReferenceModified(self, model, distorm_mode, func_addr, kernel_syms, kmods):
# check if CALL targets are within the kernel/kext range to detect possible call reference modification
modified = False
#modified malware/apihooks.py/check_inline function
data = self.addr_space.read(func_addr, 750)
# Number of instructions disassembled so far
n = 0
# Destination address of hooks
d = None
# Save the last PUSH before a CALL
push_val = None
# Save the general purpose registers
regs = {}
ops = []
for op in distorm3.Decompose(func_addr, data, distorm_mode):
ops.append(op)
for op in distorm3.Decompose(func_addr, data, distorm_mode):
# Quit when a decomposition error is encountered
# or when reach function end
if not op.valid or op.mnemonic == "NOP":
break
if op.flowControl == 'FC_CALL':
# Clear the push value
if push_val:
push_val = None
if op.mnemonic == "CALL" and op.operands[0].type == 'AbsoluteMemoryAddress':
# Check for CALL [ADDR]
if model == '32bit':
const = op.operands[0].disp & 0xFFFFFFFF
d = obj.Object("unsigned int", offset = const, vm = self.addr_space)
else:
const = op.operands[0].disp
d = obj.Object("unsigned long long", offset = const, vm = self.addr_space)
if self.outside_module(d, kernel_syms, kmods):
break
elif op.operands[0].type == 'Immediate':
# Check for CALL ADDR
d = op.operands[0].value
if self.outside_module(d, kernel_syms, kmods):
break
elif op.operands[0].type == 'Register':
# Check for CALL REG
d = regs.get(op.operands[0].name)
if d and self.outside_module(d, kernel_syms, kmods):
break
n += 1
# filtering out false positives due to structs, you can tweak this as needed
if d and self.outside_module(d, kernel_syms, kmods) == True and str(ops[n+1].mnemonic) not in ["DB 0xff", "ADD", "XCHG", "OUTS"]:
modified = True
return (modified, d)
示例8: shadowedSyscalls
# 需要导入模块: import distorm3 [as 别名]
# 或者: from distorm3 import Decompose [as 别名]
def shadowedSyscalls(self, model, distorm_mode, sysents_addr):
#looks like these syscall functions end with a call to _thread_exception_return
thread_exc_ret_addr = self.addr_space.profile.get_symbol('_thread_exception_return')
prev_op = None
sysent_funcs = ['_unix_syscall_return', '_unix_syscall64', '_unix_syscall']
for func in sysent_funcs:
func_addr = self.addr_space.profile.get_symbol(func)
content = self.addr_space.read(func_addr, 1024)
for op in distorm3.Decompose(func_addr, content, distorm_mode):
if not op.valid:
break
if op.mnemonic == "CALL" and op.operands[0].value == thread_exc_ret_addr:
break
if model == "64bit":
#callp = &sysent[63] OR &sysent[code] OR callp == sysent
if op.mnemonic in ['ADD','CMP'] and op.operands[0].type == 'Register' and op.operands[0].name in ["RSP","RBX","R12","R13","R14","R15"] and 'FLAG_RIP_RELATIVE' in op.flags:
#compare actual sysent tbl address to the one in the instruction, calculated per distorm3 INSTRUCTION_GET_RIP_TARGET
op_sysent_ptr = obj.Object('Pointer', offset = (op.address + op.operands[1].disp + op.size), vm = self.addr_space)
if sysents_addr != op_sysent_ptr.v():
print "not same: %x | %x" % (sysents_addr, op_sysent_ptr.v())
yield (op_sysent_ptr.v(), func, op)
elif model == "32bit":
#LEA EAX, [EAX*8+0x82ef20]
if op.mnemonic == 'LEA' and op.operands[0].type == 'Register' and op.operands[0].name in ['EDI','EAX'] and distorm3.Registers[op.operands[1].index] == "EAX" and op.operands[1].scale == 8:
if op.operands[1].disp != sysents_addr:
shadowtbl_addr = op.operands[1].disp
yield (shadowtbl_addr, func, op)
break
#CMP EAX, 0x82ef20
elif op.mnemonic == 'CMP' and op.operands[0].type == 'Register' and op.operands[0].name in ['EDI','EAX'] and prev_op.mnemonic in ['LEA','MOV'] and self.addr_space.is_valid_address(op.operands[1].value) == True:
if op.operands[1].value != sysents_addr:
shadowtbl_addr = op.operands[1].value
yield (shadowtbl_addr, func, op)
#CMP DWORD [EBP-0x20], 0x82ef20
elif op.mnemonic == 'CMP' and op.operands[0].index != None and distorm3.Registers[op.operands[0].index] == "EBP" and op.operands[0].disp == -32 and op.operands[0].type == "Immediate":
if op.operands[1].value != sysents_addr:
shadowtbl_addr = op.operands[1].value
yield (shadowtbl_addr, func, op)
prev_op = op
示例9: get_registry_callbacks_legacy
# 需要导入模块: import distorm3 [as 别名]
# 或者: from distorm3 import Decompose [as 别名]
def get_registry_callbacks_legacy(nt_mod):
"""
Enumerate registry change callbacks.
This method of finding a global variable via disassembly of the
CmRegisterCallback function is only for XP systems. If it fails on
XP you can still find the callbacks using PoolScanGenericCallback.
On Vista and Windows 7, these callbacks are registered using the
CmRegisterCallbackEx function.
"""
if not has_distorm3:
return
symbol = "CmRegisterCallback"
# Get the RVA of the symbol from NT's EAT
symbol_rva = nt_mod.getprocaddress(symbol)
if symbol_rva == None:
return
# Absolute VA to the symbol code
symbol_address = symbol_rva + nt_mod.DllBase
# Read the function prologue
data = nt_mod.obj_vm.zread(symbol_address, 200)
c = 0
vector = None
# Looking for MOV EBX, CmpCallBackVector
# This may be the first or second MOV EBX instruction
for op in distorm3.Decompose(symbol_address, data, distorm3.Decode32Bits):
if (op.valid and op.mnemonic == "MOV"
and len(op.operands) == 2
and op.operands[0].name == 'EBX'):
vector = op.operands[1].value
if c == 1:
break
else:
c += 1
# Can't find the global variable
if vector == None:
return
# The vector is an array of 100 _EX_FAST_REF objects
addrs = obj.Object("Array", count = 100, offset = vector,
vm = nt_mod.obj_vm, targetType = "_EX_FAST_REF")
for addr in addrs:
callback = addr.dereference_as("_EX_CALLBACK_ROUTINE_BLOCK")
if callback:
yield symbol, callback.Function, None