brintos

brintos / linux-shallow public Read only

0
0
Text · 3.3 KiB · 2c70a5a Raw
108 lines · python
1#!/usr/bin/env python2# SPDX-License-Identifier: GPL-2.03# libxed.py: Python wrapper for libxed.so4# Copyright (c) 2014-2021, Intel Corporation.5 6# To use Intel XED, libxed.so must be present. To build and install7# libxed.so:8#            git clone https://github.com/intelxed/mbuild.git mbuild9#            git clone https://github.com/intelxed/xed10#            cd xed11#            ./mfile.py --share12#            sudo ./mfile.py --prefix=/usr/local install13#            sudo ldconfig14#15 16import sys17 18from ctypes import CDLL, Structure, create_string_buffer, addressof, sizeof, \19		   c_void_p, c_bool, c_byte, c_char, c_int, c_uint, c_longlong, c_ulonglong20 21# XED Disassembler22 23class xed_state_t(Structure):24 25	_fields_ = [26		("mode", c_int),27		("width", c_int)28	]29 30class XEDInstruction():31 32	def __init__(self, libxed):33		# Current xed_decoded_inst_t structure is 192 bytes. Use 512 to allow for future expansion34		xedd_t = c_byte * 51235		self.xedd = xedd_t()36		self.xedp = addressof(self.xedd)37		libxed.xed_decoded_inst_zero(self.xedp)38		self.state = xed_state_t()39		self.statep = addressof(self.state)40		# Buffer for disassembled instruction text41		self.buffer = create_string_buffer(256)42		self.bufferp = addressof(self.buffer)43 44class LibXED():45 46	def __init__(self):47		try:48			self.libxed = CDLL("libxed.so")49		except:50			self.libxed = None51		if not self.libxed:52			self.libxed = CDLL("/usr/local/lib/libxed.so")53 54		self.xed_tables_init = self.libxed.xed_tables_init55		self.xed_tables_init.restype = None56		self.xed_tables_init.argtypes = []57 58		self.xed_decoded_inst_zero = self.libxed.xed_decoded_inst_zero59		self.xed_decoded_inst_zero.restype = None60		self.xed_decoded_inst_zero.argtypes = [ c_void_p ]61 62		self.xed_operand_values_set_mode = self.libxed.xed_operand_values_set_mode63		self.xed_operand_values_set_mode.restype = None64		self.xed_operand_values_set_mode.argtypes = [ c_void_p, c_void_p ]65 66		self.xed_decoded_inst_zero_keep_mode = self.libxed.xed_decoded_inst_zero_keep_mode67		self.xed_decoded_inst_zero_keep_mode.restype = None68		self.xed_decoded_inst_zero_keep_mode.argtypes = [ c_void_p ]69 70		self.xed_decode = self.libxed.xed_decode71		self.xed_decode.restype = c_int72		self.xed_decode.argtypes = [ c_void_p, c_void_p, c_uint ]73 74		self.xed_format_context = self.libxed.xed_format_context75		self.xed_format_context.restype = c_uint76		self.xed_format_context.argtypes = [ c_int, c_void_p, c_void_p, c_int, c_ulonglong, c_void_p, c_void_p ]77 78		self.xed_tables_init()79 80	def Instruction(self):81		return XEDInstruction(self)82 83	def SetMode(self, inst, mode):84		if mode:85			inst.state.mode = 4 # 32-bit86			inst.state.width = 4 # 4 bytes87		else:88			inst.state.mode = 1 # 64-bit89			inst.state.width = 8 # 8 bytes90		self.xed_operand_values_set_mode(inst.xedp, inst.statep)91 92	def DisassembleOne(self, inst, bytes_ptr, bytes_cnt, ip):93		self.xed_decoded_inst_zero_keep_mode(inst.xedp)94		err = self.xed_decode(inst.xedp, bytes_ptr, bytes_cnt)95		if err:96			return 0, ""97		# Use AT&T mode (2), alternative is Intel (3)98		ok = self.xed_format_context(2, inst.xedp, inst.bufferp, sizeof(inst.buffer), ip, 0, 0)99		if not ok:100			return 0, ""101		if sys.version_info[0] == 2:102			result = inst.buffer.value103		else:104			result = inst.buffer.value.decode()105		# Return instruction length and the disassembled instruction text106		# For now, assume the length is in byte 166107		return inst.xedd[166], result108