common_utils.py 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. import os.path
  2. import random
  3. import file_utils
  4. import xml_utils
  5. def change_application(game, sdk, sub_channel, config, target_application):
  6. """
  7. 修改最顶级的application
  8. """
  9. decompile_path = file_utils.get_decompile_path(game, sdk, sub_channel, config['cache'])
  10. manifest = os.path.join(decompile_path, 'AndroidManifest.xml')
  11. application = xml_utils.get_application_attr(manifest, 'name')
  12. if application is None:
  13. xml_utils.change_application_attr(manifest, 'name', target_application)
  14. print('change add application %s' % target_application)
  15. else:
  16. smaliPath = os.path.join(decompile_path, 'smali')
  17. super_application = find_super_application(smaliPath, application)
  18. print('super application is %s' % super_application)
  19. if super_application == target_application:
  20. return
  21. change_super_application(smaliPath, super_application, target_application.replace('.', '/'))
  22. print('change super application %s to %s' % (super_application, target_application))
  23. def change_top_application(game, sdk, sub_channel, config, target_application):
  24. """
  25. 修改manifest清单下的application入口。
  26. PS:例八门渠道,因游戏app继承到渠道app过程中有停住,未进入到渠道app初始化,故改用渠道app为入口,继承原游戏app确保他们的功能正常运行
  27. """
  28. decompliePath = file_utils.get_decompile_path(game, sdk, sub_channel, config['cache'])
  29. manifest = os.path.join(decompliePath, 'AndroidManifest.xml')
  30. gameApplication = xml_utils.get_application_attr(manifest, 'name')
  31. print("游戏application" + gameApplication)
  32. xml_utils.change_application_attr(manifest, 'name', target_application)
  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 = find_super_application(smaliPath, target_application)
  40. print('寻找入口application。super application is %s' % superApplication)
  41. change_super_application(smaliPath, superApplication, gameApplication.replace('.', '/'))
  42. print('change super application %s to %s' % (target_application, gameApplication))
  43. def find_super_application(base_path, class_name):
  44. """
  45. 获取最顶级的application
  46. """
  47. tagSuper = '.super Landroid/app/Application;'
  48. tag = '.super L'
  49. applicationFile = file_utils.get_package_path(base_path, class_name) + '.smali'
  50. topClassName = None
  51. superClass = None
  52. with open_file(applicationFile, 'r') as f:
  53. line = f.readline()
  54. while line:
  55. if tagSuper in line:
  56. topClassName = class_name
  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 find_super_application(base_path, superClass)
  67. def change_super_application(base_path, class_name, target_application):
  68. """
  69. 更改application
  70. """
  71. applicationFile = file_utils.get_package_path(base_path, class_name) + '.smali'
  72. # 修改application
  73. change_supper_application_smali(applicationFile, target_application)
  74. def change_supper_application_smali(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 open_file(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 get_random_number(size):
  106. content = ""
  107. for i in range(6):
  108. ch = chr(random.randrange(ord('0'), ord('9') + 1))
  109. content += ch
  110. return content
  111. def open_file(file, mode):
  112. return file_utils.open_file(file, mode)