+#!/usr/bin/python
+
+## This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published
+## by the Free Software Foundation; version 2 and higer.
+##
+## Dani Church 2010
+
+import hashlib
+
+patch_config = {
+ 'known_md5sums': [
+ '5a51e4fbb38dac338e4444e6b713e9b3',
+ '44d6b8258fb4fb9c849162704120ba53',
+ ],
+ 'check_ranges': [
+ (194380, 'f04f2de920b08de2'),
+ (195340, 'f04f2de920b08de2'),
+ ],
+ 'patch_ranges': [
+ (194380, '0010a0e3001097e5'),
+ (195340, '0010a0e3001097e5'),
+ ],
+}
+
+class Patcher:
+ known_md5sums = []
+ check_ranges = []
+ patch_ranges = []
+
+ def __init__(self, config):
+ self.known_md5sums = config['known_md5sums']
+ self.check_ranges = config['check_ranges']
+ self.patch_ranges = config['patch_ranges']
+
+ def check_md5sum(self, filename):
+ md5 = hashlib.md5()
+ f = open(filename, 'rb')
+ while True:
+ d = f.read(8096)
+ if not d: break
+ md5.update(d)
+ f.close()
+
+ md5sum = md5.hexdigest()
+ for known_sum in self.known_md5sums:
+ if md5sum == known_sum: return True
+
+ return False
+
+ def check_data(self, filename):
+ f = open(filename, 'rb')
+
+ for seek, hexbytes in self.check_ranges:
+ bytes = hexbytes.decode('hex')
+ f.seek(seek)
+ actual = f.read(len(bytes))
+ if actual != bytes:
+ f.close()
+ return False
+
+ f.close()
+ return True
+
+ def patch_file(self, filename):
+ f = open(filename, 'r+b')
+
+ for seek, hexbytes in self.patch_ranges:
+ bytes = hexbytes.decode('hex')
+ f.seek(seek)
+ f.write(bytes)
+
+ f.close()
+
+if __name__ == '__main__':
+ import sys, os, shutil
+
+ library = '/usr/lib/librtcom-call-ui.so.0.0.0'
+
+ if os.access(library+'.orig', os.F_OK):
+ print "It looks like %s has already been patched. Aborting." % (library,)
+ sys.exit(1)
+
+ patcher = Patcher(patch_config)
+
+ if not patcher.check_md5sum(library):
+ if not patcher.check_data(library):
+ print "Your %s is not recognized. So I won't patch it." % (library,)
+ sys.exit(1)
+ if len(sys.argv) > 1 and sys.argv[1] == '--force':
+ print "Patching an unrecognized %s. Please test your system before rebooting." % (library,)
+ else:
+ message = "Your %s is not recognized, but it seems to match the patterns.\nRun '%s --force' to try patching anyway, but understand that\nTHIS MAY BREAK YOUR SYSTEM. If you do, test your system thoroughly before rebooting." % (library,library,sys.argv[0])
+ subprocess.call(["dbus-send --type=method_call --dest=org.freedesktop.Notifications /org/freedesktop/Notifications org.freedesktop.Notifications.SystemNoteDialog string:\""+message+"\" uint32:0 string:\"OK\""],shell=True)
+ sys.exit(1)
+
+ shutil.copy2(library, library+'.orig')
+ patcher.patch_file(library)