script.py 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  1. # coding:utf8
  2. import os
  3. import logging
  4. import re
  5. import glob
  6. import shutil
  7. import distutils.dir_util
  8. import gw_file_system
  9. import xml.etree.ElementTree as ET
  10. ANDROID_NS = 'http://schemas.android.com/apk/res/android'
  11. def script(workspace_sdk_dir, extract_dir, channel_sdk_info, new_game_channel_info, game_info):
  12. logging.info('game_pack_info: ' + str(channel_sdk_info))
  13. # 逆向渠道id
  14. if channel_sdk_info['id'] == "323":
  15. fixLifecycleMethod(extract_dir)
  16. return
  17. def script_pre(workspace_sdk_dir, extract_dir, channel_sdk_info, new_game_channel_info, game_info):
  18. if channel_sdk_info['SDKName'] == 'x7sy':
  19. logging.info('workspace_sdk_dir: ' + str(workspace_sdk_dir))
  20. s1 = os.path.join(workspace_sdk_dir, 'x7sy/ForRes/drawable')
  21. x7_bg_female_pink_7_xml = os.path.join(s1, "x7_bg_female_pink_7.xml")
  22. x7_bg_female_pink_right_7 = os.path.join(s1, "x7_bg_female_pink_right_7.xml")
  23. if os.path.exists(x7_bg_female_pink_7_xml):
  24. os.remove(x7_bg_female_pink_7_xml)
  25. if os.path.exists(x7_bg_female_pink_right_7):
  26. os.remove(x7_bg_female_pink_right_7)
  27. s1 = os.path.join(workspace_sdk_dir, 'x7sy/ForRes/values/public.xml')
  28. handle_public_xml(s1)
  29. return
  30. def script_last(workspace_sdk_dir, extract_dir, channel_sdk_info, new_game_channel_info, game_info):
  31. logging.info('game_pack_info: ' + str(channel_sdk_info))
  32. fix_android_manifest(extract_dir)
  33. if channel_sdk_info['id'] == "512":
  34. s1 = os.path.join(extract_dir, "smali_classes4", "com/netease")
  35. smali_dir = create_mutil_smali(extract_dir)
  36. s3 = os.path.join(smali_dir, "com/netease")
  37. list_package = ["androidcrashhandler","autotext","environment","godlikeshare","htprotect","neox","ngpush","ntunisdk"]
  38. if not os.path.exists(s3):
  39. distutils.dir_util.mkpath(s3)
  40. move_package(s1, s3, list_package)
  41. replace_kf_application(extract_dir)
  42. if channel_sdk_info['id'] == "323":
  43. change_smali(extract_dir)
  44. s1 = os.path.join(extract_dir, "smali", "androidx")
  45. s3 = os.path.join(extract_dir, "smali_classes3", "androidx")
  46. if not os.path.exists(s3):
  47. distutils.dir_util.mkpath(s3)
  48. move_package_one(s1, s3)
  49. s1 = os.path.join(extract_dir, "smali_classes3", "androidx")
  50. s3 = os.path.join(extract_dir, "smali_classes4", "androidx")
  51. list_package = ["a", "appcompat", "b", "c", "coordinatorlayout", "customview", "activity",
  52. "asynclayoutinflater", "browser", "cardview", "cor"]
  53. if not os.path.exists(s3):
  54. distutils.dir_util.mkpath(s3)
  55. move_package(s1, s3, list_package)
  56. if channel_sdk_info['SDKName'] == 'smallsheep':
  57. move_package_for_small_sheep(extract_dir)
  58. if channel_sdk_info['SDKName'] == 'x7sy':
  59. s1 = os.path.join(extract_dir, "smali_classes2", "com")
  60. smali_classes2_dir = create_mutil_smali(extract_dir)
  61. s3 = os.path.join(smali_classes2_dir, "com")
  62. list_package = ["a", "adjust", "alipayx", "cloudplay", "google", "heepay", "helpshift", "iapppay", "ipaynow"]
  63. if not os.path.exists(s3):
  64. distutils.dir_util.mkpath(s3)
  65. move_package(s1, s3, list_package)
  66. s1 = os.path.join(extract_dir, "smali_classes3", "androidx")
  67. smali_classes2_dir = create_mutil_smali(extract_dir)
  68. s3 = os.path.join(smali_classes2_dir, "androidx")
  69. list_package = ["core", "d", "drawerlayout", "e", "f", "fragment", "legacy", "lifecycle", "loader", "media",
  70. "multidex"]
  71. if not os.path.exists(s3):
  72. distutils.dir_util.mkpath(s3)
  73. move_package(s1, s3, list_package)
  74. if channel_sdk_info['SDKName'] == 'jolo':
  75. s1 = os.path.join(extract_dir, "smali_classes3", "androidx")
  76. s3 = os.path.join(extract_dir, "smali_classes5", "androidx")
  77. list_package = ["core", "d", "drawerlayout", "e", "f", "fragment", "legacy", "lifecycle", "loader"]
  78. if not os.path.exists(s3):
  79. distutils.dir_util.mkpath(s3)
  80. move_package(s1, s3, list_package)
  81. if channel_sdk_info['SDKName'] == 'sogou':
  82. rm_wechatpay(extract_dir)
  83. if channel_sdk_info['SDKName'] == 'xxzhushou':
  84. rm_alipay(extract_dir)
  85. if channel_sdk_info['id'] == "389":
  86. s1 = os.path.join(extract_dir, "smali", "com")
  87. smali_classes2_dir = create_mutil_smali(extract_dir)
  88. s3 = os.path.join(smali_classes2_dir, "com")
  89. list_package = ["smwl", "netease"]
  90. if not os.path.exists(s3):
  91. distutils.dir_util.mkpath(s3)
  92. move_package(s1, s3, list_package)
  93. if channel_sdk_info['id'] == "549" or channel_sdk_info['id'] == "591":
  94. s1 = os.path.join(extract_dir, "smali_classes5", "com")
  95. smali_classes2_dir = create_mutil_smali(extract_dir)
  96. s3 = os.path.join(smali_classes2_dir, "com")
  97. list_package = ["netease"]
  98. if not os.path.exists(s3):
  99. distutils.dir_util.mkpath(s3)
  100. move_package(s1, s3, list_package)
  101. return
  102. def fix_android_manifest(decompile_dir):
  103. manifest_file = decompile_dir + '/AndroidManifest.xml'
  104. ET.register_namespace('android', ANDROID_NS)
  105. key_android_name = '{' + ANDROID_NS + '}authorities'
  106. target_tree = ET.parse(manifest_file)
  107. target_root = target_tree.getroot()
  108. manifest_node = target_root.get("package")
  109. application_node = target_root.find('application')
  110. if application_node is None:
  111. return
  112. if application_node is not None:
  113. activity_list_node = application_node.findall('provider')
  114. if activity_list_node is None:
  115. return
  116. for activityNode in activity_list_node:
  117. node_name_str = activityNode.attrib[key_android_name]
  118. if node_name_str == 'com.netease.onmyoji.coolpad111':
  119. activityNode.set(key_android_name, manifest_node + '111')
  120. target_tree.write(manifest_file)
  121. def create_mutil_smali(decompileDir):
  122. f_idx = 5
  123. while True:
  124. tmp = gw_file_system.get_full_path(os.path.join(decompileDir, 'smali_classes%d' % f_idx))
  125. tmp = tmp.replace('\\', '/')
  126. tmp = re.sub('/+', '/', tmp)
  127. if os.path.exists(tmp):
  128. f_idx += 1
  129. else:
  130. smali_classes2_dir = tmp
  131. break
  132. # endwhile
  133. os.mkdir(smali_classes2_dir)
  134. return smali_classes2_dir
  135. def move_package(s1, s3, list_package):
  136. for d in list_package:
  137. src = os.path.join(s1, d)
  138. if os.path.exists(src):
  139. dst = os.path.join(s3, d)
  140. distutils.dir_util.copy_tree(src, dst)
  141. distutils.dir_util.remove_tree(src)
  142. def move_package_one(src, dst):
  143. if os.path.exists(src):
  144. distutils.dir_util.copy_tree(src, dst)
  145. distutils.dir_util.remove_tree(src)
  146. def rm_alipay(extract_dir):
  147. delet_file = os.path.join(extract_dir, 'smali/org/json')
  148. print delet_file
  149. logging.info('delet_file: ' + delet_file)
  150. shutil.rmtree(delet_file)
  151. def rm_wechatpay(extract_dir):
  152. delet = os.path.join(extract_dir, 'smali_classes2/com/ipaynow')
  153. print delet
  154. logging.info(delet)
  155. shutil.rmtree(delet)
  156. def change_smali(fooDir):
  157. for smali_flie in glob.glob(fooDir + "/" + "smali*/com/kunlun/platform/android/KunlunApplication.smali"):
  158. print smali_flie
  159. if os.path.isfile(smali_flie):
  160. with open(smali_flie, 'r+') as f:
  161. cont = f.read()
  162. change_str = 'invoke-virtual {p0}, Lcom/kf/framework/KFApplication;->onCreate()V'
  163. str = 'invoke-virtual {p0}, Landroid/app/Application;->onCreate()V'
  164. print len(change_str)
  165. print len(str)
  166. change_str2 = 'invoke-virtual {v0, p1}, Lcom/kf/framework/KFApplication;->onConfigurationChanged(Landroid/content/res/Configuration;)V'
  167. str2 = 'invoke-virtual {v0, p1}, Landroid/app/Application;->onConfigurationChanged(Landroid/content/res/Configuration;)V'
  168. cont = cont.replace(change_str, str)
  169. cont = cont.replace(change_str2, str2)
  170. with open(smali_flie, 'w') as tf:
  171. tf.write(cont)
  172. def intoFirstLine(target, repl, cont):
  173. # srcStr = "onBackPressed"
  174. # regexp = '.method (?:public|protected) +?'+target+"\([^.]+?\.locals +[0-9]{1,2}"
  175. regexp = '.method (?:public|protected) +?' + target + "\([^.]+?\.locals +([0-9]{1,2})"
  176. # print(regexp)
  177. reObj = re.compile(regexp)
  178. matchO = reObj.search(cont)
  179. if matchO:
  180. # print(matchO.group(0))
  181. methodHead = matchO.group(0)
  182. if matchO.group(1) == "0":
  183. methodHead = re.sub("locals +0", "locals 1", methodHead)
  184. repl = methodHead + r'\n\n ' + repl + r'\n\n'
  185. cont = reObj.sub(repl, cont)
  186. else:
  187. # todo call .super method
  188. cont += r'.method protected ' + target + r'()V\n\n .locals 0\n\n ' + repl + r'\n\n .end method\n'
  189. return cont
  190. def fixLifecycleMethod(preDir):
  191. for tfile in glob.glob(preDir + "/" + "smali*/com/supercell/titan/kunlun/GameAppKunlun.smali"):
  192. if os.path.isfile(tfile):
  193. with open(tfile, 'r+') as f:
  194. cont = f.read()
  195. changes = {
  196. "onPause": "invoke-static {}, Lcom/qihoo/gamecenter/sdk/matrix/Matrix;->onPause()V",
  197. "onResume": "invoke-static {}, Lcom/qihoo/gamecenter/sdk/matrix/Matrix;->onResume()V",
  198. "onDestroy": "invoke-static {p0}, Lcom/qihoo/gamecenter/sdk/matrix/Matrix;->destroy(Landroid/content/Context;)V",
  199. "onStop": "invoke-static {}, Lcom/qihoo/gamecenter/sdk/matrix/Matrix;->onStop()V"
  200. }
  201. for k, v in changes.iteritems():
  202. cont = intoFirstLine(k, v, cont)
  203. f.seek(0)
  204. f.write(cont)
  205. f.close()
  206. def handle_public_xml(public_xml_path):
  207. if not os.path.exists(public_xml_path):
  208. logging.info('public_xml is null: ' + public_xml_path)
  209. return
  210. new_lines = []
  211. with open(public_xml_path, 'r+') as f:
  212. for line in f.readlines():
  213. # l = line.strip()
  214. if line.find("x7_bg_female_pink_7") > -1:
  215. continue
  216. if line.find("x7_icon_female_pink") > -1:
  217. continue
  218. if line.find("x7_bg_female_pink_right_7") > -1:
  219. continue
  220. new_lines.append(line)
  221. f.seek(0)
  222. f.truncate()
  223. f.writelines(new_lines)
  224. return
  225. def move_package_for_small_sheep(extract_dir):
  226. s1 = os.path.join(extract_dir, "smali_classes4", "com/netease")
  227. smali_classes2_dir = create_mutil_smali(extract_dir)
  228. s3 = os.path.join(smali_classes2_dir, "com/netease")
  229. list_package = ["mpay", "neox", "ngpush", "ntunisdk", "onmyoji", "pharos", "tryautotext2", "unisdk", "xyqa"]
  230. if not os.path.exists(s3):
  231. distutils.dir_util.mkpath(s3)
  232. move_package(s1, s3, list_package)
  233. lines = ['invoke-virtual {p3}, Lcom/kf/framework/KFApplication;->getApplicationInfo()Landroid/content/pm/ApplicationInfo;',
  234. 'invoke-virtual {v0}, Lcom/kf/framework/KFApplication;->onCreate()V']
  235. def replace_kf_application(extract_dir):
  236. goal_file = glob.glob(os.path.join(extract_dir, 'smali*/com/netease/ntunisdk/unifix_hotfix_library/proxyApplication/UFProxyApplication.smali'))[0]
  237. print(os.path.isfile(goal_file))
  238. if os.path.isfile(goal_file):
  239. logging.info('method_proceed: ' + 'goal_file')
  240. print(goal_file)
  241. with open(goal_file, 'r+') as f:
  242. cont = f.read()
  243. for line in lines:
  244. change_line = line.replace('Lcom/kf/framework/KFApplication',
  245. 'Landroid/app/Application')
  246. cont = cont.replace(line, change_line)
  247. logging.info('replace_str: ' + cont)
  248. with open(goal_file, 'w+') as tf:
  249. tf.write(cont)
  250. if __name__ == '__main__':
  251. replace_kf_application("D:\\work\\yys")