import file_utils import xml_utils import os.path def changeApplication(game, sdk, subChannel, config, targetApplication): ''' 修改最顶级的application ''' decompliePath = file_utils.getDecompliePath(game, sdk, subChannel, config['cache']) manifest = os.path.join(decompliePath, 'AndroidManifest.xml') application = xml_utils.getApplicationAttr(manifest, 'name') if application is None: xml_utils.changeApplicationAttr(manifest, 'name', targetApplication) print('change add application %s' % targetApplication) else: smaliPath = os.path.join(decompliePath, 'smali') superApplication = findSuperApplication(smaliPath, application) print('super application is %s' % superApplication) if superApplication == targetApplication: return changeSuperApplication(smaliPath, superApplication, targetApplication.replace('.', '/')) print('change super application %s to %s' % (superApplication, targetApplication)) def findSuperApplication(basePath, className): ''' 获取最顶级的application ''' tagSuper = '.super Landroid/app/Application;' tag = '.super L' applicationFile = file_utils.getPackagePath(basePath, className) + '.smali' topClassName = None superClass = None with openFile(applicationFile, 'r') as f: line = f.readline() while line: if tagSuper in line: topClassName = className break elif tag in line: superClass = line[8:-2] superClass = superClass.replace('/', '.') break line = f.readline() if topClassName is not None: return topClassName elif superClass is not None: return findSuperApplication(basePath, superClass) def changeSuperApplication(basePath, className, targetApplication): ''' 更改application ''' applicationFile = file_utils.getPackagePath(basePath, className) + '.smali' # 修改application changeSuperApplicationSmali(applicationFile, targetApplication) def changeSuperApplicationSmali(file, application): ''' 修改application.smali ''' contentSpuer = '.super Landroid/app/Application;' constructor = '.method public constructor ()V' direct = 'invoke-direct' invokeSuper = 'invoke-super' applicationTag = 'Landroid/app/Application;->' newContent = '' with openFile(file, 'r+') as f: line = f.readline() isConstructor = False while line: if contentSpuer in line: newContent += '.super L%s;\n' % application elif invokeSuper in line and applicationTag in line: newContent += line.replace('android/app/Application', application) elif isConstructor and direct in line and applicationTag in line: newContent += line.replace('android/app/Application', application) isConstructor = False else: if constructor in line: isConstructor = True newContent += line line = f.readline() f.seek(0, 0) #清空内容 f.truncate() f.write(newContent) return 0 def openFile(file, mode): return file_utils.openFile(file, mode)