Miasm2
 All Classes Namespaces Files Functions Variables Typedefs Properties Macros
Public Member Functions | Public Attributes | Static Public Attributes | List of all members
miasm2.analysis.gdbserver.GdbServer_x86_32 Class Reference
+ Inheritance diagram for miasm2.analysis.gdbserver.GdbServer_x86_32:
+ Collaboration diagram for miasm2.analysis.gdbserver.GdbServer_x86_32:

Public Member Functions

def read_register_by_name
 
def compute_checksum
 
def get_messages
 
def parse_messages
 
def send_string
 
def process_messages
 
def send_messages
 
def main_loop
 
def run
 
def report_general_register_values
 
def read_register
 
def set_register
 
def read_memory
 

Public Attributes

 status
 
 server
 
 dbg
 
 send_queue
 
 sock
 
 recv_queue
 
 address
 

Static Public Attributes

list general_registers_order
 
dictionary general_registers_size
 
list register_ignore
 
string status = "S05"
 

Detailed Description

Definition at line 329 of file gdbserver.py.

Member Function Documentation

def miasm2.analysis.gdbserver.GdbServer.compute_checksum (   self,
  data 
)
inherited

Definition at line 31 of file gdbserver.py.

31 
32  def compute_checksum(self, data):
33  return chr(sum(map(ord, data)) % 256).encode("hex")

+ Here is the caller graph for this function:

def miasm2.analysis.gdbserver.GdbServer.get_messages (   self)
inherited

Definition at line 34 of file gdbserver.py.

34 
35  def get_messages(self):
36  all_data = ""
37  data = self.sock.recv(4096)
38  all_data += data
39  while (len(data) == 4096 or data == ""):
40  if data == "":
41  # Avoid consuming CPU
42  time.sleep(0.001)
43  continue
44  data = self.sock.recv(4096)
45  all_data += data
46 
47  logging.debug("<- %r", all_data)
48  self.recv_queue += self.parse_messages(all_data)

+ Here is the call graph for this function:

def miasm2.analysis.gdbserver.GdbServer.main_loop (   self)
inherited

Definition at line 272 of file gdbserver.py.

273  def main_loop(self):
274  self.recv_queue = []
275  self.send_queue = []
276 
277  self.send_string("Test\n")
278 
279  while (self.sock):
280  self.get_messages()
281  self.process_messages()
282  self.send_messages()
def miasm2.analysis.gdbserver.GdbServer.parse_messages (   self,
  data 
)
inherited

Definition at line 49 of file gdbserver.py.

49 
50  def parse_messages(self, data):
51  buf = StringIO(data)
52 
53  msgs = []
54 
55  while (buf.tell() < buf.len):
56  token = buf.read(1)
57  if token == "+":
58  continue
59  if token == "-":
60  raise NotImplementedError("Resend packet")
61  if token == "$":
62  packet_data = ""
63  c = buf.read(1)
64  while c != "#":
65  packet_data += c
66  c = buf.read(1)
67  checksum = buf.read(2)
68  if checksum != self.compute_checksum(packet_data):
69  raise ValueError("Incorrect checksum")
70 
71  msgs.append(packet_data)
72 
73  return msgs

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

def miasm2.analysis.gdbserver.GdbServer.process_messages (   self)
inherited

Definition at line 77 of file gdbserver.py.

77 
78  def process_messages(self):
79 
80  while self.recv_queue:
81  msg = self.recv_queue.pop(0)
82  buf = StringIO(msg)
83  msg_type = buf.read(1)
84 
85  self.send_queue.append("+")
86 
87  if msg_type == "q":
88  if msg.startswith("qSupported"):
89  self.send_queue.append("PacketSize=3fff")
90  elif msg.startswith("qC"):
91  # Current thread
92  self.send_queue.append("")
93  elif msg.startswith("qAttached"):
94  # Not supported
95  self.send_queue.append("")
96  elif msg.startswith("qTStatus"):
97  # Not supported
98  self.send_queue.append("")
99  elif msg.startswith("qfThreadInfo"):
100  # Not supported
101  self.send_queue.append("")
102  else:
103  raise NotImplementedError()
104 
105  elif msg_type == "H":
106  # Set current thread
107  self.send_queue.append("OK")
108 
109  elif msg_type == "?":
110  # Report why the target halted
111  self.send_queue.append(self.status) # TRAP signal
112 
113  elif msg_type == "g":
114  # Report all general register values
115  self.send_queue.append(self.report_general_register_values())
116 
117  elif msg_type == "p":
118  # Read a specific register
119  reg_num = int(buf.read(), 16)
120  self.send_queue.append(self.read_register(reg_num))
121 
122  elif msg_type == "P":
123  # Set a specific register
124  reg_num, value = buf.read().split("=")
125  reg_num = int(reg_num, 16)
126  value = int(value.decode("hex")[::-1].encode("hex"), 16)
127  self.set_register(reg_num, value)
128  self.send_queue.append("OK")
129 
130  elif msg_type == "m":
131  # Read memory
132  addr, size = map(lambda x: int(x, 16), buf.read().split(","))
133  self.send_queue.append(self.read_memory(addr, size))
134 
135  elif msg_type == "k":
136  # Kill
137  self.sock.close()
138  self.send_queue = []
139  self.sock = None
140 
141  elif msg_type == "!":
142  # Extending debugging will be used
143  self.send_queue.append("OK")
144 
145  elif msg_type == "v":
146  if msg == "vCont?":
147  # Is vCont supported ?
148  self.send_queue.append("")
149 
150  elif msg_type == "s":
151  # Step
152  self.dbg.step()
153  self.send_queue.append("S05") # TRAP signal
154 
155  elif msg_type == "Z":
156  # Add breakpoint or watchpoint
157  bp_type = buf.read(1)
158  if bp_type == "0":
159  # Exec breakpoint
160  assert(buf.read(1) == ",")
161  addr, size = map(
162  lambda x: int(x, 16), buf.read().split(","))
163 
164  if size != 1:
165  raise NotImplementedError("Bigger size")
166  self.dbg.add_breakpoint(addr)
167  self.send_queue.append("OK")
168 
169  elif bp_type == "1":
170  # Hardware BP
171  assert(buf.read(1) == ",")
172  addr, size = map(
173  lambda x: int(x, 16), buf.read().split(","))
174 
175  self.dbg.add_memory_breakpoint(addr, size,
176  read=True,
177  write=True)
178  self.send_queue.append("OK")
179 
180  elif bp_type in ["2", "3", "4"]:
181  # Memory breakpoint
182  assert(buf.read(1) == ",")
183  read = bp_type in ["3", "4"]
184  write = bp_type in ["2", "4"]
185  addr, size = map(
186  lambda x: int(x, 16), buf.read().split(","))
187 
188  self.dbg.add_memory_breakpoint(addr, size,
189  read=read,
190  write=write)
191  self.send_queue.append("OK")
192 
193  else:
194  raise ValueError("Impossible value")
195 
196  elif msg_type == "z":
197  # Remove breakpoint or watchpoint
198  bp_type = buf.read(1)
199  if bp_type == "0":
200  # Exec breakpoint
201  assert(buf.read(1) == ",")
202  addr, size = map(
203  lambda x: int(x, 16), buf.read().split(","))
204 
205  if size != 1:
206  raise NotImplementedError("Bigger size")
207  dbgsoft = self.dbg.get_breakpoint_by_addr(addr)
208  assert(len(dbgsoft) == 1)
209  self.dbg.remove_breakpoint(dbgsoft[0])
210  self.send_queue.append("OK")
211 
212  elif bp_type == "1":
213  # Hardware BP
214  assert(buf.read(1) == ",")
215  addr, size = map(
216  lambda x: int(x, 16), buf.read().split(","))
217  self.dbg.remove_memory_breakpoint_by_addr_access(
218  addr, read=True, write=True)
219  self.send_queue.append("OK")
220 
221  elif bp_type in ["2", "3", "4"]:
222  # Memory breakpoint
223  assert(buf.read(1) == ",")
224  read = bp_type in ["3", "4"]
225  write = bp_type in ["2", "4"]
226  addr, size = map(
227  lambda x: int(x, 16), buf.read().split(","))
228 
229  self.dbg.remove_memory_breakpoint_by_addr_access(
230  addr, read=read, write=write)
231  self.send_queue.append("OK")
232 
233  else:
234  raise ValueError("Impossible value")
235 
236  elif msg_type == "c":
237  # Continue
238  self.status = ""
239  self.send_messages()
240  ret = self.dbg.run()
241  if isinstance(ret, debugging.DebugBreakpointSoft):
242  self.status = "S05"
243  self.send_queue.append("S05") # TRAP signal
244  elif isinstance(ret, ExceptionHandle):
245  if ret == ExceptionHandle.memoryBreakpoint():
246  self.status = "S05"
247  self.send_queue.append("S05")
248  else:
249  raise NotImplementedError("Unknown Except")
250  elif isinstance(ret, debugging.DebugBreakpointTerminate):
251  # Connexion should close, but keep it running as a TRAP
252  # The connexion will be close on instance destruction
253  print ret
254  self.status = "S05"
255  self.send_queue.append("S05")
256  else:
257  raise NotImplementedError()
258 
259  else:
260  raise NotImplementedError(
261  "Not implemented: message type '%s'" % msg_type)

+ Here is the call graph for this function:

def miasm2.analysis.gdbserver.GdbServer.read_memory (   self,
  addr,
  size 
)
inherited

Definition at line 320 of file gdbserver.py.

321  def read_memory(self, addr, size):
322  except_flag_vm = self.dbg.myjit.vm.get_exception()
323  try:
324  return self.dbg.get_mem_raw(addr, size).encode("hex")
325  except RuntimeError:
326  self.dbg.myjit.vm.set_exception(except_flag_vm)
327  return "00" * size
328 

+ Here is the caller graph for this function:

def miasm2.analysis.gdbserver.GdbServer.read_register (   self,
  reg_num 
)
inherited

Definition at line 294 of file gdbserver.py.

295  def read_register(self, reg_num):
296  reg_name = self.general_registers_order[reg_num]
297  reg_value = self.read_register_by_name(reg_name)
298  size = self.general_registers_size[reg_name]
299 
300  pack_token = ""
301  if size == 1:
302  pack_token = "<B"
303  elif size == 2:
304  pack_token = "<H"
305  elif size == 4:
306  pack_token = "<I"
307  elif size == 8:
308  pack_token = "<Q"
309  else:
310  raise NotImplementedError("Unknown size")
311 
312  return struct.pack(pack_token, reg_value).encode("hex")

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

def miasm2.analysis.gdbserver.GdbServer_x86_32.read_register_by_name (   self,
  reg_name 
)

Definition at line 357 of file gdbserver.py.

358  def read_register_by_name(self, reg_name):
359  sup_func = super(GdbServer_x86_32, self).read_register_by_name
360 
361  # Assert EIP on pc jitter
362  if reg_name == "EIP":
363  return self.dbg.myjit.pc
364 
365  # EFLAGS case
366  if reg_name == "EFLAGS":
367  val = 0
368  eflags_args = [
369  "cf", 1, "pf", 0, "af", 0, "zf", "nf", "tf", "i_f", "df", "of"]
370  eflags_args += ["nt", 0, "rf", "vm", "ac", "vif", "vip", "i_d"]
371  eflags_args += [0] * 10
372 
373  for i, arg in enumerate(eflags_args):
374  if isinstance(arg, str):
375  if arg not in self.register_ignore:
376  to_add = sup_func(arg)
377  else:
378  to_add = 0
379  else:
380  to_add = arg
381 
382  val |= (to_add << i)
383  return val
384  else:
385  return sup_func(reg_name)
386 
def miasm2.analysis.gdbserver.GdbServer.report_general_register_values (   self)
inherited

Definition at line 288 of file gdbserver.py.

290  s = ""
291  for i in xrange(len(self.general_registers_order)):
292  s += self.read_register(i)
293  return s

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

def miasm2.analysis.gdbserver.GdbServer.run (   self)
inherited

Definition at line 283 of file gdbserver.py.

284  def run(self):
285  self.sock, self.address = self.server.accept()
286  self.main_loop()
def miasm2.analysis.gdbserver.GdbServer.send_messages (   self)
inherited

Definition at line 262 of file gdbserver.py.

263  def send_messages(self):
264  for msg in self.send_queue:
265  if msg == "+":
266  data = "+"
267  else:
268  data = "$%s#%s" % (msg, self.compute_checksum(msg))
269  logging.debug("-> %r", data)
270  self.sock.send(data)
271  self.send_queue = []

+ Here is the call graph for this function:

def miasm2.analysis.gdbserver.GdbServer.send_string (   self,
  s 
)
inherited

Definition at line 74 of file gdbserver.py.

74 
75  def send_string(self, s):
76  self.send_queue.append("O" + s.encode("hex"))
def miasm2.analysis.gdbserver.GdbServer.set_register (   self,
  reg_num,
  value 
)
inherited

Definition at line 313 of file gdbserver.py.

314  def set_register(self, reg_num, value):
315  reg_name = self.general_registers_order[reg_num]
316  self.dbg.set_reg_value(reg_name, value)

+ Here is the caller graph for this function:

Member Data Documentation

miasm2.analysis.gdbserver.GdbServer.address
inherited

Definition at line 284 of file gdbserver.py.

miasm2.analysis.gdbserver.GdbServer.dbg
inherited

Definition at line 27 of file gdbserver.py.

list miasm2.analysis.gdbserver.GdbServer_x86_32.general_registers_order
static
Initial value:
1 = ["EAX", "ECX", "EDX", "EBX", "ESP", "EBP", "ESI",
2  "EDI", "EIP", "EFLAGS", "CS", "SS", "DS", "ES",
3  "FS", "GS"]

Definition at line 333 of file gdbserver.py.

dictionary miasm2.analysis.gdbserver.GdbServer_x86_32.general_registers_size
static
Initial value:
1 = {"EAX": 4,
2  "ECX": 4,
3  "EDX": 4,
4  "EBX": 4,
5  "ESP": 4,
6  "EBP": 4,
7  "ESI": 4,
8  "EDI": 4,
9  "EIP": 4,
10  "EFLAGS": 2,
11  "CS": 2,
12  "SS": 2,
13  "DS": 2,
14  "ES": 2,
15  "FS": 2,
16  "GS": 2}

Definition at line 337 of file gdbserver.py.

miasm2.analysis.gdbserver.GdbServer.recv_queue
inherited

Definition at line 273 of file gdbserver.py.

list miasm2.analysis.gdbserver.GdbServer_x86_32.register_ignore
static
Initial value:
1 = [
2  "tf", "i_f", "nt", "rf", "vm", "ac", "vif", "vip", "i_d"]

Definition at line 354 of file gdbserver.py.

miasm2.analysis.gdbserver.GdbServer.send_queue
inherited

Definition at line 137 of file gdbserver.py.

miasm2.analysis.gdbserver.GdbServer.server
inherited

Definition at line 26 of file gdbserver.py.

miasm2.analysis.gdbserver.GdbServer.sock
inherited

Definition at line 138 of file gdbserver.py.

string miasm2.analysis.gdbserver.GdbServer.status = "S05"
staticinherited

Definition at line 19 of file gdbserver.py.

miasm2.analysis.gdbserver.GdbServer.status
inherited

Definition at line 237 of file gdbserver.py.


The documentation for this class was generated from the following file: