forked from facelessuser/HexViewer
-
Notifications
You must be signed in to change notification settings - Fork 0
/
hex_inspector.py
executable file
·180 lines (161 loc) · 6.71 KB
/
hex_inspector.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
'''
Hex Viewer
Licensed under MIT
Copyright (c) 2011 Isaac Muse <[email protected]>
'''
import sublime
import sublime_plugin
import math
from struct import unpack
from hex_common import *
hv_endianness = hv_settings.get("inspector_endian", "little")
class HexShowInspectorCommand(sublime_plugin.WindowCommand):
def is_enabled(self):
return is_enabled() and hv_inspector_enable
def run(self):
# Setup inspector window
view = self.window.get_output_panel('hex_viewer_inspector')
view.set_syntax_file("Packages/HexViewer/HexInspect.hidden-tmLanguage")
view.settings().set("draw_white_space", "none")
view.settings().set("draw_indent_guides", False)
view.settings().set("gutter", "none")
view.settings().set("line_numbers", False)
# Show
self.window.run_command("show_panel", {"panel": "output.hex_viewer_inspector"})
self.window.run_command("hex_inspector", {"reset": True})
class HexHideInspectorCommand(sublime_plugin.WindowCommand):
def is_enabled(self):
return is_enabled() and hv_inspector_enable
def run(self):
self.window.run_command("hide_panel", {"panel": "output.hex_viewer_inspector"})
class HexToggleInspectorEndiannessCommand(sublime_plugin.WindowCommand):
def is_enabled(self):
return is_enabled() and hv_inspector_enable
def run(self):
global hv_endianness
hv_endianness = "big" if hv_endianness == "little" else "little"
self.window.run_command('hex_highlighter')
class HexInspectorCommand(sublime_plugin.WindowCommand):
def get_bytes(self, start, bytes_wide):
bytes = self.view.substr(sublime.Region(start, start + 2))
byte64 = None
byte32 = None
byte16 = None
byte8 = None
start += 2
size = self.view.size()
count = 1
group_divide = 1
address = 12
ascii_divide = group_divide + bytes_wide + address + 1
target_bytes = 8
# Look for 64 bit worth of bytes
while start < size and count < target_bytes:
# Check if sitting on first nibble
if self.view.score_selector(start, 'raw.nibble.upper'):
bytes += self.view.substr(sublime.Region(start, start + 2))
count += 1
start += 2
else:
# Must be at byte group falling edge; try and step over divider
start += group_divide
if start < size and self.view.score_selector(start, 'raw.nibble.upper'):
bytes += self.view.substr(sublime.Region(start, start + 2))
count += 1
start += 2
# Must be at line end; try and step to next line
else:
start += ascii_divide
if start < size and self.view.score_selector(start, 'raw.nibble.upper'):
bytes += self.view.substr(sublime.Region(start, start + 2))
count += 1
start += 2
else:
# No more bytes to check
break
byte8 = bytes[0:2]
if count > 1:
byte16 = bytes[0:4]
if count > 3:
byte32 = bytes[0:8]
if count > 7:
byte64 = bytes[0:16]
return byte8, byte16, byte32, byte64
def display(self, view, byte8, bytes16, bytes32, bytes64):
item_dec = "%-12s: %-14d"
item_str = "%-12s: %-14s"
item_float = "%-12s: %-14e"
item_double = "%-12s: %-14e"
nl = "\n"
endian = ">" if self.endian == "big" else "<"
i_buffer = "%28s:%-28s" % ("Hex Inspector ", (" Big Endian" if self.endian == "big" else " Little Endian")) + nl
if byte8 != None:
i_buffer += item_dec * 2 % (
"byte", unpack(endian + "B", byte8.decode("hex"))[0],
"short", unpack(endian + "b", byte8.decode("hex"))[0]
) + nl
else:
i_buffer += item_str * 2 % (
"byte", "--",
"short", "--"
) + nl
if bytes16 != None:
i_buffer += item_dec * 2 % (
"word", unpack(endian + "H", bytes16.decode("hex"))[0],
"int", unpack(endian + "h", bytes16.decode("hex"))[0]
) + nl
else:
i_buffer += item_str * 2 % (
"word", "--",
"int", "--"
) + nl
if bytes32 != None:
i_buffer += item_dec * 2 % (
"dword", unpack(endian + "I", bytes32.decode("hex"))[0],
"longint", unpack(endian + "i", bytes32.decode("hex"))[0]
) + nl
else:
i_buffer += item_str * 2 % (
"dword", "--",
"longint", "--"
) + nl
if bytes32 != None:
s_float = unpack(endian + "f", bytes32.decode('hex'))[0]
if math.isnan(s_float):
i_buffer += item_str % ("float", "NaN")
else:
i_buffer += item_float % (
"float", s_float
)
else:
i_buffer += item_str % ("float", "--")
if bytes64 != None:
d_float = unpack(endian + "d", bytes64.decode('hex'))[0]
if math.isnan(d_float):
i_buffer += item_str % ("double", "NaN") + nl
else:
i_buffer += item_double % (
"double", d_float
) + nl
else:
i_buffer += item_str % ("double", "--") + nl
if byte8 != None:
i_buffer += item_str % ("binary", '{0:08b}'.format(unpack(endian + "B", byte8.decode("hex"))[0])) + nl
else:
i_buffer += item_str % ("binary", "--") + nl
# Update content
view.set_read_only(False)
edit = view.begin_edit()
view.replace(edit, sublime.Region(0, view.size()), i_buffer)
view.end_edit(edit)
view.set_read_only(True)
view.sel().clear()
def is_enabled(self):
return is_enabled()
def run(self, first_byte=None, bytes_wide=None, reset=False):
self.view = self.window.active_view()
self.endian = hv_endianness
byte8, bytes16, bytes32, bytes64 = None, None, None, None
if not reset and first_byte != None and bytes_wide != None:
byte8, bytes16, bytes32, bytes64 = self.get_bytes(int(first_byte), int(bytes_wide))
self.display(self.window.get_output_panel('hex_viewer_inspector'), byte8, bytes16, bytes32, bytes64)