parent
9fd4ae328b
commit
4fb18e31b4
38
mode/hex.py
38
mode/hex.py
|
@ -1,4 +1,5 @@
|
|||
import string, struct
|
||||
import re, string, struct
|
||||
from subprocess import Popen, PIPE, STDOUT
|
||||
import color, mode
|
||||
from lex import Grammar, PatternRule, RegionRule
|
||||
from method import Method, Argument
|
||||
|
@ -6,6 +7,9 @@ from point import Point
|
|||
|
||||
class Hex(mode.Fundamental):
|
||||
modename = 'Hex'
|
||||
config = {
|
||||
'hex.disinst': 'disinst',
|
||||
}
|
||||
lmargin = 12
|
||||
rmargin = 18
|
||||
_ctrans = ['.'] * 256
|
||||
|
@ -88,6 +92,7 @@ class Hex(mode.Fundamental):
|
|||
self.add_action_and_bindings(HexReadAligned('double', 'd'), ('C-c d',))
|
||||
|
||||
self.add_action_and_bindings(ShowAddress(), ('C-c a',))
|
||||
self.add_action_and_bindings(ShowX86Instruction(), ('C-c x',))
|
||||
self.add_action_and_bindings(GotoAddress(), ('C-c M-g',))
|
||||
|
||||
# create all the insert actions for the basic text input
|
||||
|
@ -129,15 +134,16 @@ class Hex(mode.Fundamental):
|
|||
else:
|
||||
return ((0, s, self.cgreen),)
|
||||
|
||||
def read_data(self, cy, ix, fmt, size):
|
||||
def read_data(self, cy, ix, size):
|
||||
b = self.window.buffer
|
||||
s = b.rawdata[cy][ix:]
|
||||
if len(s) < size:
|
||||
if cy < len(b.rawdata) - 1:
|
||||
s += b.rawdata[cy + 1]
|
||||
else:
|
||||
return None
|
||||
s = s[:size]
|
||||
return s
|
||||
def read_struct(self, cy, ix, fmt, size):
|
||||
s = self.read_data(cy, ix, size)
|
||||
return struct.unpack(fmt, s)[0]
|
||||
|
||||
class HexForward(Method):
|
||||
|
@ -194,7 +200,7 @@ class HexRead(Method):
|
|||
ix = self._get_ix(b, cy, cx)
|
||||
addr = b.get_address(cy, 0) + ix
|
||||
try:
|
||||
v = w.mode.read_data(cy, ix, self.fmt, self.size)
|
||||
v = w.mode.read_struct(cy, ix, self.fmt, self.size)
|
||||
if v is None:
|
||||
w.set_error("not enough data to read %s" % self.type_)
|
||||
else:
|
||||
|
@ -228,6 +234,27 @@ class HexOverwriteChar(Method):
|
|||
while w.cursor_char().isspace() and w.cursor < end:
|
||||
w.forward()
|
||||
|
||||
class ShowX86Instruction(Method):
|
||||
''''''
|
||||
size_re = re.compile(r'X86 insn \((\d+) bytes\):')
|
||||
def _execute(self, w, **vargs):
|
||||
disinst = w.application.config.get('hex.disinst')
|
||||
(cx, cy) = w.cursor.xy()
|
||||
ix = w.buffer.cursorx_to_datax(cy, cx)
|
||||
data = w.mode.read_data(cy, ix, 13)
|
||||
data = ''.join(['%02x' % ord(c) for c in data])
|
||||
try:
|
||||
p = Popen((disinst, data), stdout=PIPE, stderr=STDOUT)
|
||||
lines = [l.strip() for l in p.stdout.readlines()]
|
||||
result = p.wait()
|
||||
m = self.size_re.match(lines[0])
|
||||
assert m
|
||||
size = int(m.group(1))
|
||||
data = data[:size]
|
||||
w.set_error("%s %s" % (data, lines[1]))
|
||||
except Exception, e:
|
||||
w.set_error("there was an error")
|
||||
|
||||
class GotoAddress(Method):
|
||||
'''Jump to the specified line number'''
|
||||
args = [Argument("address", type=type(0), prompt="Goto address: ")]
|
||||
|
@ -241,6 +268,7 @@ class GotoAddress(Method):
|
|||
cy = addr // (b.groupsize * b.numgroups)
|
||||
w.goto(Point(cx, cy))
|
||||
w.set_error("Goto 0x%08x (%r, %r)" % (addr, cx, cy))
|
||||
|
||||
class ShowAddress(Method):
|
||||
'''Show the cursor's address in the current buffer'''
|
||||
def _execute(self, w, **vargs):
|
||||
|
|
Loading…
Reference in New Issue