We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
IDA Pro Integration - decompile() segfault
Calling `idaapi.decompile()` causes my IDA `6.9.151221 (December 21, 2015)` to segfault (often corrupting the database) when Hex-Rays is not installed.

There needs to be some sanity checking in the [context](https://github.com/pwndbg/pwndbg/blob/master/pwndbg/commands/context.py#L209) command before calling `pwndbg.ida.decompile()`

I'm not sure if this is fixed in the latest IDA `6.95.160808 (August 08, 2016)`

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `pwndbg/ida.py`
Content:
```
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
3 """
4 Talks to an XMLRPC server running inside of an active IDA Pro instance,
5 in order to query it about the database.  Allows symbol resolution and
6 interactive debugging.
7 """
8 from __future__ import absolute_import
9 from __future__ import division
10 from __future__ import print_function
11 from __future__ import unicode_literals
12 
13 import errno
14 import functools
15 import socket
16 import traceback
17 
18 import gdb
19 
20 import pwndbg.arch
21 import pwndbg.color
22 import pwndbg.compat
23 import pwndbg.config
24 import pwndbg.elf
25 import pwndbg.events
26 import pwndbg.memoize
27 import pwndbg.memory
28 import pwndbg.regs
29 
30 try:
31     import xmlrpc.client as xmlrpclib
32 except:
33     import xmlrpclib
34 
35 
36 ida_rpc_host = pwndbg.config.Parameter('ida-rpc-host', '127.0.0.1', 'ida xmlrpc server address')
37 ida_rpc_port = pwndbg.config.Parameter('ida-rpc-port', 8888, 'ida xmlrpc server port')
38 
39 xmlrpclib.Marshaller.dispatch[int] = lambda _, v, w: w("<value><i8>%d</i8></value>" % v)
40 
41 if pwndbg.compat.python2:
42     xmlrpclib.Marshaller.dispatch[long] = lambda _, v, w: w("<value><i8>%d</i8></value>" % v)
43 
44 xmlrpclib.Marshaller.dispatch[type(0)] = lambda _, v, w: w("<value><i8>%d</i8></value>" % v)
45 
46 _ida = None
47 
48 
49 @pwndbg.config.Trigger([ida_rpc_host, ida_rpc_port])
50 def init_ida_rpc_client():
51     global _ida
52     addr = 'http://{host}:{port}'.format(host=ida_rpc_host, port=ida_rpc_port)
53 
54     _ida = xmlrpclib.ServerProxy(addr)
55 
56     try:
57         _ida.here()
58         print(pwndbg.color.green("Pwndbg successfully connected to Ida Pro xmlrpc: %s" % addr))
59     except socket.error as e:
60         if e.errno != errno.ECONNREFUSED:
61             traceback.print_exc()
62         _ida = None
63 
64 
65 class withIDA(object):
66     def __init__(self, fn):
67         self.fn = fn
68         functools.update_wrapper(self, fn)
69 
70     def __call__(self, *args, **kwargs):
71         if _ida is None:
72             init_ida_rpc_client()
73         if _ida is not None:
74             return self.fn(*args, **kwargs)
75         return None
76 
77 
78 def takes_address(function):
79     @functools.wraps(function)
80     def wrapper(address, *args, **kwargs):
81         return function(l2r(address), *args, **kwargs)
82 
83     return wrapper
84 
85 
86 def returns_address(function):
87     @functools.wraps(function)
88     def wrapper(*args, **kwargs):
89         return r2l(function(*args, **kwargs))
90 
91     return wrapper
92 
93 
94 @withIDA
95 def available():
96     return True
97 
98 
99 def l2r(addr):
100     exe = pwndbg.elf.exe()
101     if not exe:
102         raise Exception("Can't find EXE base")
103     result = (addr - int(exe.address) + base()) & pwndbg.arch.ptrmask
104     return result
105 
106 
107 def r2l(addr):
108     exe = pwndbg.elf.exe()
109     if not exe:
110         raise Exception("Can't find EXE base")
111     result = (addr - base() + int(exe.address)) & pwndbg.arch.ptrmask
112     return result
113 
114 
115 def remote(function):
116     """Runs the provided function in IDA's interpreter.
117 
118     The function must be self-contained and not reference any
119     global variables."""
120 
121 
122 @pwndbg.memoize.reset_on_objfile
123 def base():
124     segaddr = _ida.NextSeg(0)
125     base = _ida.get_fileregion_offset(segaddr)
126 
127     return segaddr - base
128 
129 
130 @withIDA
131 @takes_address
132 def Comment(addr):
133     return _ida.GetCommentEx(addr, 0) or _ida.GetCommentEx(addr)
134 
135 
136 @withIDA
137 @takes_address
138 @pwndbg.memoize.reset_on_objfile
139 def Name(addr):
140     return _ida.Name(addr)
141 
142 
143 @withIDA
144 @takes_address
145 @pwndbg.memoize.reset_on_objfile
146 def GetFuncOffset(addr):
147     rv = _ida.GetFuncOffset(addr)
148     return rv
149 
150 
151 @withIDA
152 @takes_address
153 @pwndbg.memoize.reset_on_objfile
154 def GetType(addr):
155     rv = _ida.GetType(addr)
156     return rv
157 
158 
159 @withIDA
160 @returns_address
161 def here():
162     return _ida.here()
163 
164 
165 @withIDA
166 @takes_address
167 def Jump(addr):
168     return _ida.Jump(addr)
169 
170 
171 @withIDA
172 @takes_address
173 @pwndbg.memoize.reset_on_objfile
174 def Anterior(addr):
175     hexrays_prefix = '\x01\x04; '
176     lines = []
177     for i in range(10):
178         r = _ida.LineA(addr, i)
179         if not r: break
180         if r.startswith(hexrays_prefix):
181             r = r[len(hexrays_prefix):]
182         lines.append(r)
183     return '\n'.join(lines)
184 
185 
186 @withIDA
187 def GetBreakpoints():
188     for i in range(GetBptQty()):
189         yield GetBptEA(i)
190 
191 
192 @withIDA
193 def GetBptQty():
194     return _ida.GetBptQty()
195 
196 
197 @withIDA
198 @returns_address
199 def GetBptEA(i):
200     return _ida.GetBptEA(i)
201 
202 
203 _breakpoints = []
204 
205 
206 @pwndbg.events.cont
207 @pwndbg.events.stop
208 @withIDA
209 def UpdateBreakpoints():
210     # XXX: Remove breakpoints from IDA when the user removes them.
211     current = set(eval(b.location.lstrip('*')) for b in _breakpoints)
212     want = set(GetBreakpoints())
213 
214     # print(want)
215 
216     for addr in current - want:
217         for bp in _breakpoints:
218             if int(bp.location.lstrip('*'), 0) == addr:
219                 # print("delete", addr)
220                 bp.delete()
221                 break
222         _breakpoints.remove(bp)
223 
224     for bp in want - current:
225         if not pwndbg.memory.peek(bp):
226             continue
227 
228         bp = gdb.Breakpoint('*' + hex(int(bp)))
229         _breakpoints.append(bp)
230         # print(_breakpoints)
231 
232 
233 @withIDA
234 @takes_address
235 def SetColor(pc, color):
236     return _ida.SetColor(pc, 1, color)
237 
238 
239 colored_pc = None
240 
241 
242 @pwndbg.events.stop
243 @withIDA
244 def Auto_Color_PC():
245     global colored_pc
246     colored_pc = pwndbg.regs.pc
247     SetColor(colored_pc, 0x7f7fff)
248 
249 
250 @pwndbg.events.cont
251 @withIDA
252 def Auto_UnColor_PC():
253     global colored_pc
254     if colored_pc:
255         SetColor(colored_pc, 0xffffff)
256     colored_pc = None
257 
258 
259 @withIDA
260 @returns_address
261 @pwndbg.memoize.reset_on_objfile
262 def LocByName(name):
263     return _ida.LocByName(str(name))
264 
265 
266 @withIDA
267 @takes_address
268 @returns_address
269 @pwndbg.memoize.reset_on_objfile
270 def PrevHead(addr):
271     return _ida.PrevHead(addr)
272 
273 
274 @withIDA
275 @takes_address
276 @returns_address
277 @pwndbg.memoize.reset_on_objfile
278 def NextHead(addr):
279     return _ida.NextHead(addr)
280 
281 
282 @withIDA
283 @takes_address
284 @pwndbg.memoize.reset_on_objfile
285 def GetFunctionName(addr):
286     return _ida.GetFunctionName(addr)
287 
288 
289 @withIDA
290 @takes_address
291 @pwndbg.memoize.reset_on_objfile
292 def GetFlags(addr):
293     return _ida.GetFlags(addr)
294 
295 
296 @withIDA
297 @pwndbg.memoize.reset_on_objfile
298 def isASCII(flags):
299     return _ida.isASCII(flags)
300 
301 
302 @withIDA
303 @takes_address
304 @pwndbg.memoize.reset_on_objfile
305 def ArgCount(address):
306     pass
307 
308 
309 @withIDA
310 def SaveBase(path):
311     return _ida.SaveBase(path)
312 
313 
314 @withIDA
315 def GetIdbPath():
316     return _ida.GetIdbPath()
317 
318 
319 @takes_address
320 @pwndbg.memoize.reset_on_stop
321 def has_cached_cfunc(addr):
322     return _ida.has_cached_cfunc(addr)
323 
324 
325 @withIDA
326 @takes_address
327 @pwndbg.memoize.reset_on_stop
328 def decompile(addr):
329     return _ida.decompile(addr)
330 
331 
332 @withIDA
333 @pwndbg.memoize.reset_on_stop
334 def GetStrucQty():
335     return _ida.GetStrucQty()
336 
337 
338 @withIDA
339 @pwndbg.memoize.reset_on_stop
340 def GetStrucId(idx):
341     return _ida.GetStrucId(idx)
342 
343 
344 @withIDA
345 @pwndbg.memoize.reset_on_stop
346 def GetStrucName(sid):
347     return _ida.GetStrucName(sid)
348 
349 
350 @withIDA
351 @pwndbg.memoize.reset_on_stop
352 def GetStrucSize(sid):
353     return _ida.GetStrucSize(sid)
354 
355 
356 @withIDA
357 @pwndbg.memoize.reset_on_stop
358 def GetMemberQty(sid):
359     return _ida.GetMemberQty(sid)
360 
361 
362 @withIDA
363 @pwndbg.memoize.reset_on_stop
364 def GetMemberSize(sid, offset):
365     return _ida.GetMemberSize(sid, offset)
366 
367 
368 @withIDA
369 @pwndbg.memoize.reset_on_stop
370 def GetMemberId(sid, offset):
371     return _ida.GetMemberId(sid, offset)
372 
373 
374 @withIDA
375 @pwndbg.memoize.reset_on_stop
376 def GetMemberName(sid, offset):
377     return _ida.GetMemberName(sid, offset)
378 
379 
380 @withIDA
381 @pwndbg.memoize.reset_on_stop
382 def GetMemberFlag(sid, offset):
383     return _ida.GetMemberFlag(sid, offset)
384 
385 
386 @withIDA
387 @pwndbg.memoize.reset_on_stop
388 def GetStrucNextOff(sid, offset):
389     return _ida.GetStrucNextOff(sid, offset)
390 
391 
392 class IDC(object):
393     query = "{k:v for k,v in globals()['idc'].__dict__.items() if type(v) in (int,long)}"
394 
395     def __init__(self):
396         if available():
397             data = _ida.eval(self.query)
398             self.__dict__.update(data)
399 
400 
401 idc = IDC()
402 
403 
404 def print_member(sid, offset):
405     mid = GetMemberId(sid, offset)
406     mname = GetMemberName(sid, offset) or '(no name)'
407     msize = GetMemberSize(sid, offset) or 0
408     mflag = GetMemberFlag(sid, offset) or 0
409     print("    +%#x - %s [%#x bytes]" % (offset, mname, msize))
410 
411 
412 def print_structs():
413     for i in range(GetStrucQty() or 0):
414         sid = GetStrucId(i)
415 
416         name = GetStrucName(sid)
417         size = GetStrucSize(sid)
418 
419         print("%s - %#x bytes" % (name, size))
420 
421         offset = 0
422         while offset < size:
423             print_member(sid, offset)
424             offset = GetStrucNextOff(sid, offset)
425
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/pwndbg/ida.py b/pwndbg/ida.py
--- a/pwndbg/ida.py
+++ b/pwndbg/ida.py
@@ -74,6 +74,12 @@
             return self.fn(*args, **kwargs)
         return None
 
+def withHexrays(f):
+    @withIDA
+    @functools.wraps(f)
+    def wrapper(*a, **kw):
+        if _ida.init_hexrays_plugin():
+            return f(*a, **kw)
 
 def takes_address(function):
     @functools.wraps(function)
@@ -322,7 +328,7 @@
     return _ida.has_cached_cfunc(addr)
 
 
-@withIDA
+@withHexrays
 @takes_address
 @pwndbg.memoize.reset_on_stop
 def decompile(addr):

{"golden_diff": "diff --git a/pwndbg/ida.py b/pwndbg/ida.py\n--- a/pwndbg/ida.py\n+++ b/pwndbg/ida.py\n@@ -74,6 +74,12 @@\n             return self.fn(*args, **kwargs)\n         return None\n \n+def withHexrays(f):\n+    @withIDA\n+    @functools.wraps(f)\n+    def wrapper(*a, **kw):\n+        if _ida.init_hexrays_plugin():\n+            return f(*a, **kw)\n \n def takes_address(function):\n     @functools.wraps(function)\n@@ -322,7 +328,7 @@\n     return _ida.has_cached_cfunc(addr)\n \n \n-@withIDA\n+@withHexrays\n @takes_address\n @pwndbg.memoize.reset_on_stop\n def decompile(addr):\n", "issue": "IDA Pro Integration - decompile() segfault\nCalling `idaapi.decompile()` causes my IDA `6.9.151221 (December 21, 2015)` to segfault (often corrupting the database) when Hex-Rays is not installed.\r\n\r\nThere needs to be some sanity checking in the [context](https://github.com/pwndbg/pwndbg/blob/master/pwndbg/commands/context.py#L209) command before calling `pwndbg.ida.decompile()`\r\n\r\nI'm not sure if this is fixed in the latest IDA `6.95.160808 (August 08, 2016)`\n", "before_files": [{"content": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n\"\"\"\nTalks to an XMLRPC server running inside of an active IDA Pro instance,\nin order to query it about the database.  Allows symbol resolution and\ninteractive debugging.\n\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import print_function\nfrom __future__ import unicode_literals\n\nimport errno\nimport functools\nimport socket\nimport traceback\n\nimport gdb\n\nimport pwndbg.arch\nimport pwndbg.color\nimport pwndbg.compat\nimport pwndbg.config\nimport pwndbg.elf\nimport pwndbg.events\nimport pwndbg.memoize\nimport pwndbg.memory\nimport pwndbg.regs\n\ntry:\n    import xmlrpc.client as xmlrpclib\nexcept:\n    import xmlrpclib\n\n\nida_rpc_host = pwndbg.config.Parameter('ida-rpc-host', '127.0.0.1', 'ida xmlrpc server address')\nida_rpc_port = pwndbg.config.Parameter('ida-rpc-port', 8888, 'ida xmlrpc server port')\n\nxmlrpclib.Marshaller.dispatch[int] = lambda _, v, w: w(\"<value><i8>%d</i8></value>\" % v)\n\nif pwndbg.compat.python2:\n    xmlrpclib.Marshaller.dispatch[long] = lambda _, v, w: w(\"<value><i8>%d</i8></value>\" % v)\n\nxmlrpclib.Marshaller.dispatch[type(0)] = lambda _, v, w: w(\"<value><i8>%d</i8></value>\" % v)\n\n_ida = None\n\n\n@pwndbg.config.Trigger([ida_rpc_host, ida_rpc_port])\ndef init_ida_rpc_client():\n    global _ida\n    addr = 'http://{host}:{port}'.format(host=ida_rpc_host, port=ida_rpc_port)\n\n    _ida = xmlrpclib.ServerProxy(addr)\n\n    try:\n        _ida.here()\n        print(pwndbg.color.green(\"Pwndbg successfully connected to Ida Pro xmlrpc: %s\" % addr))\n    except socket.error as e:\n        if e.errno != errno.ECONNREFUSED:\n            traceback.print_exc()\n        _ida = None\n\n\nclass withIDA(object):\n    def __init__(self, fn):\n        self.fn = fn\n        functools.update_wrapper(self, fn)\n\n    def __call__(self, *args, **kwargs):\n        if _ida is None:\n            init_ida_rpc_client()\n        if _ida is not None:\n            return self.fn(*args, **kwargs)\n        return None\n\n\ndef takes_address(function):\n    @functools.wraps(function)\n    def wrapper(address, *args, **kwargs):\n        return function(l2r(address), *args, **kwargs)\n\n    return wrapper\n\n\ndef returns_address(function):\n    @functools.wraps(function)\n    def wrapper(*args, **kwargs):\n        return r2l(function(*args, **kwargs))\n\n    return wrapper\n\n\n@withIDA\ndef available():\n    return True\n\n\ndef l2r(addr):\n    exe = pwndbg.elf.exe()\n    if not exe:\n        raise Exception(\"Can't find EXE base\")\n    result = (addr - int(exe.address) + base()) & pwndbg.arch.ptrmask\n    return result\n\n\ndef r2l(addr):\n    exe = pwndbg.elf.exe()\n    if not exe:\n        raise Exception(\"Can't find EXE base\")\n    result = (addr - base() + int(exe.address)) & pwndbg.arch.ptrmask\n    return result\n\n\ndef remote(function):\n    \"\"\"Runs the provided function in IDA's interpreter.\n\n    The function must be self-contained and not reference any\n    global variables.\"\"\"\n\n\n@pwndbg.memoize.reset_on_objfile\ndef base():\n    segaddr = _ida.NextSeg(0)\n    base = _ida.get_fileregion_offset(segaddr)\n\n    return segaddr - base\n\n\n@withIDA\n@takes_address\ndef Comment(addr):\n    return _ida.GetCommentEx(addr, 0) or _ida.GetCommentEx(addr)\n\n\n@withIDA\n@takes_address\n@pwndbg.memoize.reset_on_objfile\ndef Name(addr):\n    return _ida.Name(addr)\n\n\n@withIDA\n@takes_address\n@pwndbg.memoize.reset_on_objfile\ndef GetFuncOffset(addr):\n    rv = _ida.GetFuncOffset(addr)\n    return rv\n\n\n@withIDA\n@takes_address\n@pwndbg.memoize.reset_on_objfile\ndef GetType(addr):\n    rv = _ida.GetType(addr)\n    return rv\n\n\n@withIDA\n@returns_address\ndef here():\n    return _ida.here()\n\n\n@withIDA\n@takes_address\ndef Jump(addr):\n    return _ida.Jump(addr)\n\n\n@withIDA\n@takes_address\n@pwndbg.memoize.reset_on_objfile\ndef Anterior(addr):\n    hexrays_prefix = '\\x01\\x04; '\n    lines = []\n    for i in range(10):\n        r = _ida.LineA(addr, i)\n        if not r: break\n        if r.startswith(hexrays_prefix):\n            r = r[len(hexrays_prefix):]\n        lines.append(r)\n    return '\\n'.join(lines)\n\n\n@withIDA\ndef GetBreakpoints():\n    for i in range(GetBptQty()):\n        yield GetBptEA(i)\n\n\n@withIDA\ndef GetBptQty():\n    return _ida.GetBptQty()\n\n\n@withIDA\n@returns_address\ndef GetBptEA(i):\n    return _ida.GetBptEA(i)\n\n\n_breakpoints = []\n\n\n@pwndbg.events.cont\n@pwndbg.events.stop\n@withIDA\ndef UpdateBreakpoints():\n    # XXX: Remove breakpoints from IDA when the user removes them.\n    current = set(eval(b.location.lstrip('*')) for b in _breakpoints)\n    want = set(GetBreakpoints())\n\n    # print(want)\n\n    for addr in current - want:\n        for bp in _breakpoints:\n            if int(bp.location.lstrip('*'), 0) == addr:\n                # print(\"delete\", addr)\n                bp.delete()\n                break\n        _breakpoints.remove(bp)\n\n    for bp in want - current:\n        if not pwndbg.memory.peek(bp):\n            continue\n\n        bp = gdb.Breakpoint('*' + hex(int(bp)))\n        _breakpoints.append(bp)\n        # print(_breakpoints)\n\n\n@withIDA\n@takes_address\ndef SetColor(pc, color):\n    return _ida.SetColor(pc, 1, color)\n\n\ncolored_pc = None\n\n\n@pwndbg.events.stop\n@withIDA\ndef Auto_Color_PC():\n    global colored_pc\n    colored_pc = pwndbg.regs.pc\n    SetColor(colored_pc, 0x7f7fff)\n\n\n@pwndbg.events.cont\n@withIDA\ndef Auto_UnColor_PC():\n    global colored_pc\n    if colored_pc:\n        SetColor(colored_pc, 0xffffff)\n    colored_pc = None\n\n\n@withIDA\n@returns_address\n@pwndbg.memoize.reset_on_objfile\ndef LocByName(name):\n    return _ida.LocByName(str(name))\n\n\n@withIDA\n@takes_address\n@returns_address\n@pwndbg.memoize.reset_on_objfile\ndef PrevHead(addr):\n    return _ida.PrevHead(addr)\n\n\n@withIDA\n@takes_address\n@returns_address\n@pwndbg.memoize.reset_on_objfile\ndef NextHead(addr):\n    return _ida.NextHead(addr)\n\n\n@withIDA\n@takes_address\n@pwndbg.memoize.reset_on_objfile\ndef GetFunctionName(addr):\n    return _ida.GetFunctionName(addr)\n\n\n@withIDA\n@takes_address\n@pwndbg.memoize.reset_on_objfile\ndef GetFlags(addr):\n    return _ida.GetFlags(addr)\n\n\n@withIDA\n@pwndbg.memoize.reset_on_objfile\ndef isASCII(flags):\n    return _ida.isASCII(flags)\n\n\n@withIDA\n@takes_address\n@pwndbg.memoize.reset_on_objfile\ndef ArgCount(address):\n    pass\n\n\n@withIDA\ndef SaveBase(path):\n    return _ida.SaveBase(path)\n\n\n@withIDA\ndef GetIdbPath():\n    return _ida.GetIdbPath()\n\n\n@takes_address\n@pwndbg.memoize.reset_on_stop\ndef has_cached_cfunc(addr):\n    return _ida.has_cached_cfunc(addr)\n\n\n@withIDA\n@takes_address\n@pwndbg.memoize.reset_on_stop\ndef decompile(addr):\n    return _ida.decompile(addr)\n\n\n@withIDA\n@pwndbg.memoize.reset_on_stop\ndef GetStrucQty():\n    return _ida.GetStrucQty()\n\n\n@withIDA\n@pwndbg.memoize.reset_on_stop\ndef GetStrucId(idx):\n    return _ida.GetStrucId(idx)\n\n\n@withIDA\n@pwndbg.memoize.reset_on_stop\ndef GetStrucName(sid):\n    return _ida.GetStrucName(sid)\n\n\n@withIDA\n@pwndbg.memoize.reset_on_stop\ndef GetStrucSize(sid):\n    return _ida.GetStrucSize(sid)\n\n\n@withIDA\n@pwndbg.memoize.reset_on_stop\ndef GetMemberQty(sid):\n    return _ida.GetMemberQty(sid)\n\n\n@withIDA\n@pwndbg.memoize.reset_on_stop\ndef GetMemberSize(sid, offset):\n    return _ida.GetMemberSize(sid, offset)\n\n\n@withIDA\n@pwndbg.memoize.reset_on_stop\ndef GetMemberId(sid, offset):\n    return _ida.GetMemberId(sid, offset)\n\n\n@withIDA\n@pwndbg.memoize.reset_on_stop\ndef GetMemberName(sid, offset):\n    return _ida.GetMemberName(sid, offset)\n\n\n@withIDA\n@pwndbg.memoize.reset_on_stop\ndef GetMemberFlag(sid, offset):\n    return _ida.GetMemberFlag(sid, offset)\n\n\n@withIDA\n@pwndbg.memoize.reset_on_stop\ndef GetStrucNextOff(sid, offset):\n    return _ida.GetStrucNextOff(sid, offset)\n\n\nclass IDC(object):\n    query = \"{k:v for k,v in globals()['idc'].__dict__.items() if type(v) in (int,long)}\"\n\n    def __init__(self):\n        if available():\n            data = _ida.eval(self.query)\n            self.__dict__.update(data)\n\n\nidc = IDC()\n\n\ndef print_member(sid, offset):\n    mid = GetMemberId(sid, offset)\n    mname = GetMemberName(sid, offset) or '(no name)'\n    msize = GetMemberSize(sid, offset) or 0\n    mflag = GetMemberFlag(sid, offset) or 0\n    print(\"    +%#x - %s [%#x bytes]\" % (offset, mname, msize))\n\n\ndef print_structs():\n    for i in range(GetStrucQty() or 0):\n        sid = GetStrucId(i)\n\n        name = GetStrucName(sid)\n        size = GetStrucSize(sid)\n\n        print(\"%s - %#x bytes\" % (name, size))\n\n        offset = 0\n        while offset < size:\n            print_member(sid, offset)\n            offset = GetStrucNextOff(sid, offset)\n", "path": "pwndbg/ida.py"}], "after_files": [{"content": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n\"\"\"\nTalks to an XMLRPC server running inside of an active IDA Pro instance,\nin order to query it about the database.  Allows symbol resolution and\ninteractive debugging.\n\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import print_function\nfrom __future__ import unicode_literals\n\nimport errno\nimport functools\nimport socket\nimport traceback\n\nimport gdb\n\nimport pwndbg.arch\nimport pwndbg.color\nimport pwndbg.compat\nimport pwndbg.config\nimport pwndbg.elf\nimport pwndbg.events\nimport pwndbg.memoize\nimport pwndbg.memory\nimport pwndbg.regs\n\ntry:\n    import xmlrpc.client as xmlrpclib\nexcept:\n    import xmlrpclib\n\n\nida_rpc_host = pwndbg.config.Parameter('ida-rpc-host', '127.0.0.1', 'ida xmlrpc server address')\nida_rpc_port = pwndbg.config.Parameter('ida-rpc-port', 8888, 'ida xmlrpc server port')\n\nxmlrpclib.Marshaller.dispatch[int] = lambda _, v, w: w(\"<value><i8>%d</i8></value>\" % v)\n\nif pwndbg.compat.python2:\n    xmlrpclib.Marshaller.dispatch[long] = lambda _, v, w: w(\"<value><i8>%d</i8></value>\" % v)\n\nxmlrpclib.Marshaller.dispatch[type(0)] = lambda _, v, w: w(\"<value><i8>%d</i8></value>\" % v)\n\n_ida = None\n\n\n@pwndbg.config.Trigger([ida_rpc_host, ida_rpc_port])\ndef init_ida_rpc_client():\n    global _ida\n    addr = 'http://{host}:{port}'.format(host=ida_rpc_host, port=ida_rpc_port)\n\n    _ida = xmlrpclib.ServerProxy(addr)\n\n    try:\n        _ida.here()\n        print(pwndbg.color.green(\"Pwndbg successfully connected to Ida Pro xmlrpc: %s\" % addr))\n    except socket.error as e:\n        if e.errno != errno.ECONNREFUSED:\n            traceback.print_exc()\n        _ida = None\n\n\nclass withIDA(object):\n    def __init__(self, fn):\n        self.fn = fn\n        functools.update_wrapper(self, fn)\n\n    def __call__(self, *args, **kwargs):\n        if _ida is None:\n            init_ida_rpc_client()\n        if _ida is not None:\n            return self.fn(*args, **kwargs)\n        return None\n\ndef withHexrays(f):\n    @withIDA\n    @functools.wraps(f)\n    def wrapper(*a, **kw):\n        if _ida.init_hexrays_plugin():\n            return f(*a, **kw)\n\ndef takes_address(function):\n    @functools.wraps(function)\n    def wrapper(address, *args, **kwargs):\n        return function(l2r(address), *args, **kwargs)\n\n    return wrapper\n\n\ndef returns_address(function):\n    @functools.wraps(function)\n    def wrapper(*args, **kwargs):\n        return r2l(function(*args, **kwargs))\n\n    return wrapper\n\n\n@withIDA\ndef available():\n    return True\n\n\ndef l2r(addr):\n    exe = pwndbg.elf.exe()\n    if not exe:\n        raise Exception(\"Can't find EXE base\")\n    result = (addr - int(exe.address) + base()) & pwndbg.arch.ptrmask\n    return result\n\n\ndef r2l(addr):\n    exe = pwndbg.elf.exe()\n    if not exe:\n        raise Exception(\"Can't find EXE base\")\n    result = (addr - base() + int(exe.address)) & pwndbg.arch.ptrmask\n    return result\n\n\ndef remote(function):\n    \"\"\"Runs the provided function in IDA's interpreter.\n\n    The function must be self-contained and not reference any\n    global variables.\"\"\"\n\n\n@pwndbg.memoize.reset_on_objfile\ndef base():\n    segaddr = _ida.NextSeg(0)\n    base = _ida.get_fileregion_offset(segaddr)\n\n    return segaddr - base\n\n\n@withIDA\n@takes_address\ndef Comment(addr):\n    return _ida.GetCommentEx(addr, 0) or _ida.GetCommentEx(addr)\n\n\n@withIDA\n@takes_address\n@pwndbg.memoize.reset_on_objfile\ndef Name(addr):\n    return _ida.Name(addr)\n\n\n@withIDA\n@takes_address\n@pwndbg.memoize.reset_on_objfile\ndef GetFuncOffset(addr):\n    rv = _ida.GetFuncOffset(addr)\n    return rv\n\n\n@withIDA\n@takes_address\n@pwndbg.memoize.reset_on_objfile\ndef GetType(addr):\n    rv = _ida.GetType(addr)\n    return rv\n\n\n@withIDA\n@returns_address\ndef here():\n    return _ida.here()\n\n\n@withIDA\n@takes_address\ndef Jump(addr):\n    return _ida.Jump(addr)\n\n\n@withIDA\n@takes_address\n@pwndbg.memoize.reset_on_objfile\ndef Anterior(addr):\n    hexrays_prefix = '\\x01\\x04; '\n    lines = []\n    for i in range(10):\n        r = _ida.LineA(addr, i)\n        if not r: break\n        if r.startswith(hexrays_prefix):\n            r = r[len(hexrays_prefix):]\n        lines.append(r)\n    return '\\n'.join(lines)\n\n\n@withIDA\ndef GetBreakpoints():\n    for i in range(GetBptQty()):\n        yield GetBptEA(i)\n\n\n@withIDA\ndef GetBptQty():\n    return _ida.GetBptQty()\n\n\n@withIDA\n@returns_address\ndef GetBptEA(i):\n    return _ida.GetBptEA(i)\n\n\n_breakpoints = []\n\n\n@pwndbg.events.cont\n@pwndbg.events.stop\n@withIDA\ndef UpdateBreakpoints():\n    # XXX: Remove breakpoints from IDA when the user removes them.\n    current = set(eval(b.location.lstrip('*')) for b in _breakpoints)\n    want = set(GetBreakpoints())\n\n    # print(want)\n\n    for addr in current - want:\n        for bp in _breakpoints:\n            if int(bp.location.lstrip('*'), 0) == addr:\n                # print(\"delete\", addr)\n                bp.delete()\n                break\n        _breakpoints.remove(bp)\n\n    for bp in want - current:\n        if not pwndbg.memory.peek(bp):\n            continue\n\n        bp = gdb.Breakpoint('*' + hex(int(bp)))\n        _breakpoints.append(bp)\n        # print(_breakpoints)\n\n\n@withIDA\n@takes_address\ndef SetColor(pc, color):\n    return _ida.SetColor(pc, 1, color)\n\n\ncolored_pc = None\n\n\n@pwndbg.events.stop\n@withIDA\ndef Auto_Color_PC():\n    global colored_pc\n    colored_pc = pwndbg.regs.pc\n    SetColor(colored_pc, 0x7f7fff)\n\n\n@pwndbg.events.cont\n@withIDA\ndef Auto_UnColor_PC():\n    global colored_pc\n    if colored_pc:\n        SetColor(colored_pc, 0xffffff)\n    colored_pc = None\n\n\n@withIDA\n@returns_address\n@pwndbg.memoize.reset_on_objfile\ndef LocByName(name):\n    return _ida.LocByName(str(name))\n\n\n@withIDA\n@takes_address\n@returns_address\n@pwndbg.memoize.reset_on_objfile\ndef PrevHead(addr):\n    return _ida.PrevHead(addr)\n\n\n@withIDA\n@takes_address\n@returns_address\n@pwndbg.memoize.reset_on_objfile\ndef NextHead(addr):\n    return _ida.NextHead(addr)\n\n\n@withIDA\n@takes_address\n@pwndbg.memoize.reset_on_objfile\ndef GetFunctionName(addr):\n    return _ida.GetFunctionName(addr)\n\n\n@withIDA\n@takes_address\n@pwndbg.memoize.reset_on_objfile\ndef GetFlags(addr):\n    return _ida.GetFlags(addr)\n\n\n@withIDA\n@pwndbg.memoize.reset_on_objfile\ndef isASCII(flags):\n    return _ida.isASCII(flags)\n\n\n@withIDA\n@takes_address\n@pwndbg.memoize.reset_on_objfile\ndef ArgCount(address):\n    pass\n\n\n@withIDA\ndef SaveBase(path):\n    return _ida.SaveBase(path)\n\n\n@withIDA\ndef GetIdbPath():\n    return _ida.GetIdbPath()\n\n\n@takes_address\n@pwndbg.memoize.reset_on_stop\ndef has_cached_cfunc(addr):\n    return _ida.has_cached_cfunc(addr)\n\n\n@withHexrays\n@takes_address\n@pwndbg.memoize.reset_on_stop\ndef decompile(addr):\n    return _ida.decompile(addr)\n\n\n@withIDA\n@pwndbg.memoize.reset_on_stop\ndef GetStrucQty():\n    return _ida.GetStrucQty()\n\n\n@withIDA\n@pwndbg.memoize.reset_on_stop\ndef GetStrucId(idx):\n    return _ida.GetStrucId(idx)\n\n\n@withIDA\n@pwndbg.memoize.reset_on_stop\ndef GetStrucName(sid):\n    return _ida.GetStrucName(sid)\n\n\n@withIDA\n@pwndbg.memoize.reset_on_stop\ndef GetStrucSize(sid):\n    return _ida.GetStrucSize(sid)\n\n\n@withIDA\n@pwndbg.memoize.reset_on_stop\ndef GetMemberQty(sid):\n    return _ida.GetMemberQty(sid)\n\n\n@withIDA\n@pwndbg.memoize.reset_on_stop\ndef GetMemberSize(sid, offset):\n    return _ida.GetMemberSize(sid, offset)\n\n\n@withIDA\n@pwndbg.memoize.reset_on_stop\ndef GetMemberId(sid, offset):\n    return _ida.GetMemberId(sid, offset)\n\n\n@withIDA\n@pwndbg.memoize.reset_on_stop\ndef GetMemberName(sid, offset):\n    return _ida.GetMemberName(sid, offset)\n\n\n@withIDA\n@pwndbg.memoize.reset_on_stop\ndef GetMemberFlag(sid, offset):\n    return _ida.GetMemberFlag(sid, offset)\n\n\n@withIDA\n@pwndbg.memoize.reset_on_stop\ndef GetStrucNextOff(sid, offset):\n    return _ida.GetStrucNextOff(sid, offset)\n\n\nclass IDC(object):\n    query = \"{k:v for k,v in globals()['idc'].__dict__.items() if type(v) in (int,long)}\"\n\n    def __init__(self):\n        if available():\n            data = _ida.eval(self.query)\n            self.__dict__.update(data)\n\n\nidc = IDC()\n\n\ndef print_member(sid, offset):\n    mid = GetMemberId(sid, offset)\n    mname = GetMemberName(sid, offset) or '(no name)'\n    msize = GetMemberSize(sid, offset) or 0\n    mflag = GetMemberFlag(sid, offset) or 0\n    print(\"    +%#x - %s [%#x bytes]\" % (offset, mname, msize))\n\n\ndef print_structs():\n    for i in range(GetStrucQty() or 0):\n        sid = GetStrucId(i)\n\n        name = GetStrucName(sid)\n        size = GetStrucSize(sid)\n\n        print(\"%s - %#x bytes\" % (name, size))\n\n        offset = 0\n        while offset < size:\n            print_member(sid, offset)\n            offset = GetStrucNextOff(sid, offset)\n", "path": "pwndbg/ida.py"}]}