common_utils.py 4.8 KB

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