script.py 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. # coding:utf8
  2. import os
  3. import logging
  4. import re
  5. import glob
  6. import shutil
  7. import gw_data_center
  8. import gw_file_system
  9. import gw_apk_tool
  10. import yaml
  11. ANDROID_NS = 'http://schemas.android.com/apk/res/android'
  12. def script_init(workspace_sdk_dir, extract_dir, channel_sdk_info, new_game_channel_info, game_info):
  13. gw_data_center.pack_small = False
  14. return
  15. # sdk_id = channel_sdk_info['id']
  16. # if sdk_id == "323":
  17. # gw_data_center.pack_small = False
  18. # logging.info('script_init: ' + str(channel_sdk_info))
  19. def script_first(SDK, decompileDir, channelSdkInfo, new_game_channel_info, gameInfo):
  20. logging.info("-----debug exec first func-----")
  21. # game_apk = os.path.join(decompileDir, "game.apk")
  22. game_apk = decompileDir + "/../game.apk"
  23. if os.path.exists(game_apk):
  24. gw_file_system.delete_apk_file_by_aapt(game_apk, "assets/39285EFA.dex")
  25. logging.info("-----debug-----")
  26. def script(workspace_sdk_dir, extract_dir, channel_sdk_info, new_game_channel_info, game_info):
  27. logging.info('game_pack_info: ' + str(channel_sdk_info))
  28. # 逆向渠道id
  29. if channel_sdk_info['id'] == "323" or channel_sdk_info['id'] == "542":
  30. fixLifecycleMethod(extract_dir)
  31. hideSplash(extract_dir)
  32. decompileDir = extract_dir
  33. assets_dex = os.path.join(decompileDir, "../39285EFA.dex")
  34. assets_dir = os.path.join(decompileDir, "assets/39285EFA.dex")
  35. logging.info(assets_dex)
  36. logging.info(assets_dir)
  37. if os.path.exists(assets_dex):
  38. gw_file_system.copy_file(assets_dex, assets_dir)
  39. # gw_apk_tool.yml_remove_uncompress(extract_dir)
  40. del_do_not_compress(extract_dir)
  41. return
  42. def script_last(workspace_sdk_dir, extract_dir, channel_sdk_info, new_game_channel_info, game_info):
  43. if channel_sdk_info['id'] == "542":
  44. fix_float(extract_dir)
  45. return
  46. def script_pre(workspace_sdk_dir, extract_dir, channel_sdk_info, new_game_channel_info, game_info):
  47. logging.info('game_pack_info: ' + str(channel_sdk_info))
  48. if channel_sdk_info['id'] == "542":
  49. remove_smali(extract_dir)
  50. add_pay_field(extract_dir)
  51. return
  52. def hideSplash(preDir):
  53. tfile = preDir + "/assets/bin/Data/splash.png"
  54. picDir = os.path.dirname(tfile)
  55. if not os.path.exists(picDir):
  56. os.makedirs(picDir)
  57. shutil.copyfile(os.path.dirname(os.path.abspath(__file__)) + '/FFFFFF-0.png', tfile)
  58. else:
  59. if os.path.isfile(tfile):
  60. shutil.copyfile(os.path.dirname(os.path.abspath(__file__)) + '/FFFFFF-0.png', tfile)
  61. else:
  62. logging.info('game_pack_info: ' + tfile + 'is not exists!')
  63. tfile = preDir + "/res/values/styles.xml"
  64. if os.path.isfile(tfile):
  65. with open(tfile, 'r+') as f:
  66. cont = f.read()
  67. cont = cont.replace('<item name="android:windowBackground">@drawable/youkia_splash</item>'
  68. , '<item name="android:windowBackground">@color/transparent</item>')
  69. f.truncate(len(cont))
  70. f.seek(0)
  71. f.write(cont)
  72. f.close()
  73. else:
  74. logging.info('game_pack_info: ' + tfile + 'is not exists!')
  75. return
  76. def intoFirstLine(target, repl, cont, superclass):
  77. # srcStr = "onBackPressed"
  78. # regexp = '.method (?:public|protected) +?'+target+"\([^.]+?\.locals +[0-9]{1,2}"
  79. regexp = '.method (?:public|protected) +?' + target + "\([^.]+?\.locals +([0-9]{1,2})"
  80. # print(regexp)
  81. reObj = re.compile(regexp)
  82. matchO = reObj.search(cont)
  83. if matchO:
  84. # print(matchO.group(0))
  85. methodHead = matchO.group(0)
  86. if matchO.group(1) == "0":
  87. methodHead = re.sub("locals +0", "locals 1", methodHead)
  88. repl = methodHead + r'\n\n ' + repl + r'\n\n'
  89. cont = reObj.sub(repl, cont)
  90. else:
  91. # do call .super method
  92. isuper = "invoke-super {p0}, " + superclass + "->" + target + "()V"
  93. cont += "\n\n.method protected " + target + "()V\n .locals 0\n\n " + repl + "\n\n " + isuper + "\n\n return-void\n.end method"
  94. return cont
  95. def fixLifecycleMethod(preDir):
  96. for tfile in glob.glob(preDir + "/" + "smali*/com/youkia/gamecenter/GameCenterActivity.smali"):
  97. if os.path.isfile(tfile):
  98. with open(tfile, 'r+') as f:
  99. cont = f.read()
  100. changes = {
  101. "onPause": "invoke-static {}, Lcom/qihoo/gamecenter/sdk/matrix/Matrix;->onPause()V",
  102. "onResume": "invoke-static {}, Lcom/qihoo/gamecenter/sdk/matrix/Matrix;->onResume()V",
  103. "onDestroy": "invoke-static {p0}, Lcom/qihoo/gamecenter/sdk/matrix/Matrix;->destroy(Landroid/content/Context;)V",
  104. "onStop": "invoke-static {}, Lcom/qihoo/gamecenter/sdk/matrix/Matrix;->onStop()V"
  105. }
  106. mas = re.search('^.super L([^;]*);?', cont, re.MULTILINE)
  107. superclass = ""
  108. if mas:
  109. superclass = 'L' + mas.group(1) + ';'
  110. for k, v in changes.iteritems():
  111. cont = intoFirstLine(k, v, cont, superclass)
  112. f.seek(0)
  113. f.truncate(len(cont))
  114. f.write(cont)
  115. f.close()
  116. def add_pay_field(fooDir):
  117. for tfile in glob.glob(fooDir + "/" + "smali*/com/youkia/gamecenter/BaseMainActivity.smali"):
  118. print tfile
  119. if os.path.isfile(tfile):
  120. with open(tfile, 'r+') as f:
  121. cont = f.read()
  122. rrr = re.compile(r'const-string v13, \"app_order_id\"')
  123. endStr = rrr.findall(cont)
  124. if len(endStr) > 1:
  125. if endStr[0] == None:
  126. return
  127. logging.info('替换字符串为:' + endStr[0])
  128. inserts = '''
  129. const-string v13, "app_ext_2"\n
  130. invoke-static {}, Lcom/kf/framework/java/KFSDKUser;->getInstance()Lcom/kf/framework/java/KFSDKUser;\n
  131. move-result-object v14\n
  132. invoke-virtual {v14}, Lcom/kf/framework/java/KFSDKUser;->getOpenId()Ljava/lang/String;\n
  133. move-result-object v14\n
  134. invoke-virtual {v3, v13, v14}, Landroid/os/Bundle;->putString(Ljava/lang/String;Ljava/lang/String;)V\n
  135. const-string v13, "app_order_id"'''
  136. if len(endStr) > 1:
  137. cont = cont.replace(endStr[0], inserts)
  138. f.seek(0)
  139. f.write(cont)
  140. def remove_smali(path):
  141. for tfile in glob.glob(path + "/" + "smali*/com/youkia/gamecenter/BaseMainActivity.smali"):
  142. print tfile
  143. logging.info('删除路径:' + tfile)
  144. if os.path.isfile(tfile):
  145. with open(tfile, 'r+') as f:
  146. lines = f.readlines()
  147. start = 0
  148. end = 0
  149. line_num = 0
  150. for i in lines:
  151. print len(i.strip(" "))
  152. print len('const-string v13, "access_token"')
  153. if i.replace('\n', '').strip(" ") == 'const-string v13, "access_token"':
  154. start = lines.index(i)
  155. print start
  156. if start > 0 and i.replace('\n', '').strip(" ") == 'const-string v13, "amount"':
  157. end = line_num
  158. end -= 1
  159. print end
  160. break
  161. line_num += 1
  162. for i, v in enumerate(lines):
  163. if i >= start and i < end:
  164. lines[i] = ''
  165. if i > end:
  166. break
  167. with open(tfile, 'w') as tf:
  168. tf.write(''.join(lines))
  169. def fix_float(lastDir):
  170. for tfile in glob.glob(lastDir + "/" + "smali*/com/qihoo/sdkplugging/host/ApkPluggingManager.smali"):
  171. print tfile
  172. if os.path.isfile(tfile):
  173. with open(tfile, 'r+') as f:
  174. cont = f.read()
  175. goalStr = 'invoke-virtual {v1, p1, p2, p3, p4}, Lcom/qihoo/sdkplugging/host/pluggingitem/ApkPluggingItem;->doPluggingCommandInItem(Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/Object;)Ljava/lang/Object;'
  176. print type(goalStr)
  177. changes = '''
  178. const v2, 0xc350\n
  179. invoke-virtual {p3}, Ljava/lang/Integer;->intValue()I\n
  180. move-result v3\n
  181. if-eq v2, v3, :cond_f\n
  182. invoke-virtual {v1, p1, p2, p3, p4}, Lcom/qihoo/sdkplugging/host/pluggingitem/ApkPluggingItem;->doPluggingCommandInItem(Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/Object;)Ljava/lang/Object;'''
  183. cont = cont.replace(goalStr, changes)
  184. f.seek(0)
  185. f.write(cont)
  186. def del_do_not_compress(dir_path):
  187. yml_file = os.path.join(dir_path, 'apktool.yml')
  188. if not os.path.exists(yml_file):
  189. logging.info(yml_file + 'is not exist')
  190. return
  191. with open(yml_file, 'r') as f:
  192. d = yaml.load(f)
  193. print d
  194. del d['doNotCompress']
  195. print d
  196. with open(yml_file, 'w') as fl:
  197. fl.write(yaml.dump(d))
  198. if __name__ == '__main__':
  199. # remove_smali('D:\\xqnnn')
  200. # add_pay_field('D:\\xqnnn')
  201. # fix_float("D:\\test")
  202. # script("/tmp/ss", "/mnt/share/yanghuang/python_test/any_dir", { "id": "323" }, "", "")
  203. # hideSplash("/mnt/share/yanghuang/python_test/cr")
  204. del_do_not_compress('e:\\apk\\youhua')