Skip to content

Instantly share code, notes, and snippets.

@zmike

zmike/WineReload.py

Last active Feb 11, 2021
Embed
What would you like to do?
WineReload.py
from __future__ import print_function
import gdb
import subprocess
import sys
import re
import os.path
class WineReload (gdb.Command):
"Command to pipe gdb internal command output to external commands."
def __init__(self):
super(WineReload, self).__init__("wine-reload", gdb.COMMAND_FILES, gdb.COMPLETE_NONE, False)
self.libraries = {}
gdb.execute("alias -a wr = wine-reload", True)
def invoke(self, arg, from_tty):
libraries = {}
gdb.execute('set confirm off')
gdb.execute('set pagination off')
gdb.execute('handle SIGUSR1 nostop')
pid = gdb.selected_inferior().pid
if not pid in self.libraries:
self.libraries[pid] = {}
with open('/proc/{}/maps'.format(pid), 'r') as maps:
for line in maps:
print('MAP "{}"', line)
if not '/usr/local/lib64' in line and \
not '.so' in line:
continue
if '.dll' in line:
continue
address, _, _, _, _, soname = re.split(r' +', line.strip(), maxsplit=5)
soname = soname.replace(' (deleted)', '')
if soname in libraries:
continue
print('ADDED')
libraries[soname] = int(address.split('-')[0], 16)
for k,l in libraries.items():
if arg is not None and len(arg) > 0 and not k.endswith(arg):
continue
if k in self.libraries[pid]:
if not k.endswith('.exe') or '/wine/' in k:
gdb.execute('remove-symbol-file "{}"'.format(k), True)
self.libraries[pid][k] = l
file = k.replace('/run/host', '').replace('/usr/lib/x86_64-linux-gnu', '/usr/lib64').replace('/usr/lib/i686-linux-gnu', '/usr/lib')
print('LIBRARY "{}"'.format(file))
if not os.path.isfile(file):
print('...not found')
continue
if not k.endswith('.dll') and not k.endswith('.exe'):
out = subprocess.check_output(['readelf', '-l', file]).decode('utf-8')
for line in out.split('\n'):
if 'LOAD' in line:
b = int(line.split()[2], 16)
break
out = subprocess.check_output(['objdump', '-h', file]).decode('utf-8')
for line in out.split('\n'):
if '.text' in line:
o = int(line.split()[3], 16)
break
o -= b
else:
out = subprocess.check_output(['objdump', '-h', file]).decode('utf-8')
for line in out.split('\n'):
if '.text' in line:
o = int(line.split()[5], 16)
break
if not k.endswith('.exe') or '/wine/' in k:
gdb.execute('add-symbol-file "{}" 0x{:x}'.format(file, l + o), True)
WineReload()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment