common_utils.py 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. import file_utils
  2. import xml_utils
  3. import os.path
  4. def changeApplication(game, sdk, subChannel, config, targetApplication):
  5. '''
  6. 修改最顶级的application
  7. '''
  8. decompliePath = file_utils.getDecompliePath(game, sdk, subChannel, config['cache'])
  9. manifest = os.path.join(decompliePath, 'AndroidManifest.xml')
  10. application = xml_utils.getApplicationAttr(manifest, 'name')
  11. if application is None:
  12. xml_utils.changeApplicationAttr(manifest, 'name', targetApplication)
  13. print('change add application %s' % targetApplication)
  14. else:
  15. smaliPath = os.path.join(decompliePath, 'smali')
  16. superApplication = findSuperApplication(smaliPath, application)
  17. print('super application is %s' % superApplication)
  18. if superApplication == targetApplication:
  19. return
  20. changeSuperApplication(smaliPath, superApplication, targetApplication.replace('.', '/'))
  21. print('change super application %s to %s' % (superApplication, targetApplication))
  22. def changeTopApplication(game, sdk, subChannel, config, targetApplication):
  23. '''
  24. 修改mainfest清单下的application入口。
  25. PS:例八门渠道,因游戏app'继承到渠道app'过程中有停住,未进入到渠道app'初始化,故改用渠道app'为入口,继承原游戏app'确保他们的功能正常运行
  26. '''
  27. decompliePath = file_utils.getDecompliePath(game, sdk, subChannel, config['cache'])
  28. manifest = os.path.join(decompliePath, 'AndroidManifest.xml')
  29. gameApplication = xml_utils.getApplicationAttr(manifest, 'name')
  30. print ("游戏application"+gameApplication)
  31. xml_utils.changeApplicationAttr(manifest, 'name', targetApplication)
  32. # if application is None:
  33. # xml_utils.changeApplicationAttr(manifest, 'name', targetApplication)
  34. #
  35. # print('change add application %s' % targetApplication)
  36. # else:
  37. smaliPath = os.path.join(decompliePath, 'smali')
  38. superApplication = findSuperApplication(smaliPath, targetApplication)
  39. print('寻找入口application。super application is %s' % superApplication)
  40. changeSuperApplication(smaliPath, superApplication, gameApplication.replace('.', '/'))
  41. print('change super application %s to %s' % (targetApplication,gameApplication))
  42. def findSuperApplication(basePath, className):
  43. '''
  44. 获取最顶级的application
  45. '''
  46. tagSuper = '.super Landroid/app/Application;'
  47. tag = '.super L'
  48. applicationFile = file_utils.getPackagePath(basePath, className) + '.smali'
  49. topClassName = None
  50. superClass = None
  51. with openFile(applicationFile, 'r') as f:
  52. line = f.readline()
  53. while line:
  54. if tagSuper in line:
  55. topClassName = className
  56. break
  57. elif tag in line:
  58. superClass = line[8:-2]
  59. superClass = superClass.replace('/', '.')
  60. break
  61. line = f.readline()
  62. if topClassName is not None:
  63. return topClassName
  64. elif superClass is not None:
  65. return findSuperApplication(basePath, superClass)
  66. def changeSuperApplication(basePath, className, targetApplication):
  67. '''
  68. 更改application
  69. '''
  70. applicationFile = file_utils.getPackagePath(basePath, className) + '.smali'
  71. # 修改application
  72. changeSuperApplicationSmali(applicationFile, targetApplication)
  73. def changeSuperApplicationSmali(file, application):
  74. '''
  75. 修改application.smali
  76. '''
  77. contentSpuer = '.super Landroid/app/Application;'
  78. constructor = '.method public constructor <init>()V'
  79. direct = 'invoke-direct'
  80. invokeSuper = 'invoke-super'
  81. applicationTag = 'Landroid/app/Application;->'
  82. newContent = ''
  83. with openFile(file, 'r+') as f:
  84. line = f.readline()
  85. isConstructor = False
  86. while line:
  87. if contentSpuer in line:
  88. newContent += '.super L%s;\n' % application
  89. elif invokeSuper in line and applicationTag in line:
  90. newContent += line.replace('android/app/Application', application)
  91. elif isConstructor and direct in line and applicationTag in line:
  92. newContent += line.replace('android/app/Application', application)
  93. isConstructor = False
  94. else:
  95. if constructor in line:
  96. isConstructor = True
  97. newContent += line
  98. line = f.readline()
  99. f.seek(0, 0)
  100. #清空内容
  101. f.truncate()
  102. f.write(newContent)
  103. return 0
  104. def openFile(file, mode):
  105. return file_utils.openFile(file, mode)