LexManos

SRG Python utils

Mar 22nd, 2018
227
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 6.32 KB | None | 0 0
  1. # Reads and sorts a SRG file by Obf name
  2.  
  3. import json, sys, os, sets, re
  4. from pprint import pprint
  5.  
  6. def load_srg_file(input):
  7.     f = open(input, 'r')
  8.     data = f.readlines()
  9.     f.close()
  10.  
  11.     srg = {'PK:' : {}, 'CL:': {}, 'FD:': {}, 'MD:':{}}
  12.    
  13.     data = [x.rstrip() for x in data if not x[0] == '#' and len(x.strip()) > 0]
  14.     if 'PK:' in data[0] or 'CL:' in data[0] or 'FD:' in data[0] or 'MD:' in data[0]: #Normal SRG
  15.         for line in data:
  16.             pts = line.split()
  17.             #print line
  18.             if pts[0] == 'PK:' or pts[0] == 'CL:' or pts[0] == 'FD:':
  19.                 srg[pts[0]][pts[1]] = pts[2]
  20.             elif pts[0] == 'MD:':
  21.                 srg[pts[0]]['%s %s' % (pts[1], pts[2])] = '%s %s' % (pts[3], pts[4])
  22.     else:
  23.         srg['CL:'] = {k:v for k,v in (l.split(' ') for l in data if len(l.split(' ')) == 2 and not l[0] == '\t')}
  24.        
  25.         def remap(cls):
  26.             return cls if not cls in srg['CL:'] else srg['CL:'][cls]
  27.                    
  28.         def remap_desc(desc):
  29.             reg = re.compile('L([^;]+);')
  30.             return reg.sub(lambda m: 'L%s;' % remap(m.group(1)), desc)
  31.            
  32.         current_cls = None
  33.         for line in data:
  34.             if line[0] == '\t':
  35.                 if current_cls == None:
  36.                     raise Exception('Invalid TSRG Line, Missing Current class: ' + line)
  37.                 pts = line.strip().split(' ')
  38.                 if len(pts) == 2:
  39.                     srg['FD:']['%s/%s' % (current_cls, pts[0])] = '%s/%s' % (remap(current_cls), pts[1])
  40.                 elif len(pts) == 3:
  41.                     srg['MD:']['%s/%s %s' % (current_cls, pts[0], pts[1])] = '%s/%s %s' % (remap(current_cls), pts[2], remap_desc(pts[1]))
  42.                 else:
  43.                     raise Exception('Invalid TSRG Line, To many peices: ' + line)
  44.             else:
  45.                 pts = line.strip().split(' ')
  46.                 if len(pts) == 2:
  47.                     current_cls = pts[0] # Save class for TSRG, we already built CL mapping above.
  48.                 elif len(pts) == 3:
  49.                     srg['FD:']['%s/%s' % (pts[0], pts[1])] = '%s/%s' % (remap(pts[0]), pts[2])
  50.                 elif len(pts) == 4:
  51.                     srg['MD:']['%s/%s %s' % (pts[0], pts[1], pts[2])] = '%s/%s %s' % (remap(pts[0]), pts[3], remap_desc(pts[2]))
  52.                 else:
  53.                     raise Exception('Invalid CSRG Line, To many peices: ' + line)
  54.        
  55.     return srg
  56.    
  57. def sort_srg_file(input, output):
  58.     srg = load_srg_file(input)
  59.     sort_srg_dict(srg, output)
  60.  
  61. def sort_srg_dict(srg, output):
  62.     f = open(output, 'w')
  63.     if len(srg['PK:']) > 0:
  64.         f.write('\n'.join(['PK: %s %s' % (v, srg['PK:'][v]) for v in sorted(srg['PK:'].keys())]))
  65.         f.write('\n')
  66.     if len(srg['CL:']) > 0:
  67.         f.write('\n'.join(['CL: %s %s' % (v, srg['CL:'][v]) for v in sorted(srg['CL:'].keys(), key=format_class)]))
  68.         f.write('\n')
  69.     if len(srg['FD:']) > 0:
  70.         f.write('\n'.join(['FD: %s %s' % (v, srg['FD:'][v]) for v in sorted(srg['FD:'].keys(), key=format_field)]))
  71.         f.write('\n')
  72.     if len(srg['MD:']) > 0:
  73.         f.write('\n'.join(['MD: %s %s' % (v, srg['MD:'][v]) for v in sorted(srg['MD:'].keys(), key=format_method)]))
  74.         f.write('\n')
  75.     f.close()
  76.    
  77. def srg_to_tsrg(srg):
  78.     tsrg = {}
  79.    
  80.     for k,v in srg['CL:'].items():
  81.         tsrg[k] = {'name':v}
  82.        
  83.     for k,v in srg['FD:'].items():
  84.         ocls, ofd = k.rsplit('/', 1)
  85.         mcls, mfd = v.rsplit('/', 1)
  86.         if not ocls in tsrg:
  87.             tsrg[ocls] = {'name': mcls}
  88.         if not 'fd' in tsrg[ocls]:
  89.             tsrg[ocls]['fd'] = {}
  90.         tsrg[ocls]['fd'][ofd] = mfd
  91.        
  92.     def split_md(md):
  93.         parts = md.split(' ')
  94.         return {'cls': parts[0].rsplit('/', 1)[0],
  95.                 'name': parts[0].rsplit('/', 1)[1],
  96.                 'desc': parts[1]}
  97.     for k,v in srg['MD:'].items():
  98.         o = split_md(k)
  99.         m = split_md(v)
  100.        
  101.         if not o['cls'] in tsrg:
  102.             tsrg[o['cls']] = {'name': m['cls']}
  103.         if not 'md' in tsrg[o['cls']]:
  104.             tsrg[o['cls']]['md'] = {}
  105.         tsrg[o['cls']]['md']['%s %s' % (o['name'], o['desc'])] = m['name']
  106.     return tsrg
  107.  
  108. def dump_tsrg(srg, output):    
  109.     f = open(output, 'w')
  110.     tsrg = srg_to_tsrg(srg)
  111.    
  112.     for cls in sorted(tsrg.keys(), key=format_class):
  113.         if not 'name' in tsrg[cls]:
  114.             print('Error: Missing class name for %s' % cls)
  115.             continue
  116.         f.write('%s %s\n' % (cls, tsrg[cls]['name']))
  117.        
  118.         if 'fd' in tsrg[cls]:
  119.             for fn in sorted(tsrg[cls]['fd'].keys(), key=format_field_csrg):
  120.                 f.write('\t%s %s\n' % (fn, tsrg[cls]['fd'][fn]))
  121.        
  122.         if 'md' in tsrg[cls]:
  123.             for mn in sorted(tsrg[cls]['md'].keys(), key=format_method_csrg):
  124.                 f.write('\t%s %s\n' % (mn, tsrg[cls]['md'][mn]))
  125.     f.close()
  126.  
  127. def dump_csrg(srg, output):    
  128.     f = open(output, 'w')
  129.     tsrg = srg_to_tsrg(srg)
  130.    
  131.     for cls in sorted(tsrg.keys(), key=format_class):
  132.         if not 'name' in tsrg[cls]:
  133.             print('Error: Missing class name for %s' % cls)
  134.             continue
  135.         f.write('%s %s\n' % (cls, tsrg[cls]['name']))
  136.        
  137.         if 'fd' in tsrg[cls]:
  138.             for fn in sorted(tsrg[cls]['fd'].keys(), key=format_field_csrg):
  139.                 f.write('%s %s %s\n' % (cls, fn, tsrg[cls]['fd'][fn]))
  140.        
  141.         if 'md' in tsrg[cls]:
  142.             for mn in sorted(tsrg[cls]['md'].keys(), key=format_method_csrg):
  143.                 f.write('%s %s %s\n' % (cls, mn, tsrg[cls]['md'][mn]))
  144.     f.close()
  145.    
  146. def format_class(cls):
  147.     if '/' in cls:
  148.         return cls #Unobfed names should be formatted fine
  149.     ret = ''
  150.     for pt in cls.split('$'):
  151.         ret = ret + '$' + pt.rjust(1000, ' ')
  152.     return ret[1:]
  153.  
  154. def format_field(fld):
  155.     return format_class(fld.rsplit('/', 1)[0]) + '/' + fld.rsplit('/', 1)[1].rjust(1000, ' ')
  156.    
  157. def format_method(mtd):
  158.     return format_field(mtd.split(' ')[0]) + ' ' + mtd.split(' ')[1]
  159.    
  160. def format_field_csrg(fld):
  161.     return fld.swapcase().rjust(1000, ' ')
  162.    
  163. def format_method_csrg(mtd):
  164.     return format_field_csrg(mtd.split(' ')[0]) + ' ' + mtd.split(' ')[1]
  165.    
  166. if __name__ == '__main__':
  167.     sort_srg_file(sys.argv[1], sys.argv[2])
Advertisement
Add Comment
Please, Sign In to add comment