channel_action.py 8.4 KB
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import argparse
import os
import os.path
from xml.etree import ElementTree as ET
from xml.etree.ElementTree import SubElement
from xml.etree.ElementTree import Element
from xml.etree.ElementTree import ElementTree
import os
import os.path
import zipfile
import re
import subprocess
import platform
from xml.dom import minidom
import codecs
import sys

androidNS = 'http://schemas.android.com/apk/res/android'


def execute(channel, decompileDir, packageName):

    sdkDir = decompileDir + '/../sdk/' + channel['sdk']
    if not os.path.exists(sdkDir):
        print("The sdk temp folder is not exists. path:" + sdkDir)
        return 1

    # 1、write channel params path: assets/xggameinfo.txt
    if channel['params'] != None and len(channel['params']) > 0:
        gameid = ''
        gamename = ''
        gameappid = ''
        access_key = ''
        gameurl = ''
        for param in channel['params']:
            if param['name'] == 'gameid':
                gameid = param['value']
            elif param['name'] == 'gamename':
                gamename = param['value']
            elif param['name'] == 'gameappid':
                gameappid = param['value']
            elif param['name'] == 'access_key':
                access_key = param['value']
            elif param['name'] == 'gameurl':
                gameurl = param['value']

        xggameinfo_content = '{"gameid":"' + gameid + '","gamename":"' + gamename + '","gameappid":"' + gameappid + '","access_key":"' + access_key + '","gameurl":"' + gameurl + '"}'

        xggameinfoPath = decompileDir + '/assets/xggameinfo.txt'
        xggameinfo_file = open(xggameinfoPath, 'w', encoding='Utf-8')
        xggameinfo_file.write(xggameinfo_content)
        xggameinfo_file.close()

    sdkDir = decompileDir + '/../sdk/' + channel['sdk']
    if not os.path.exists(sdkDir):
        print("The sdk temp folder is not exists. path:"+sdkDir)
        return 1

    manifestPath = decompileDir + '/AndroidManifest.xml'
    manifest_file = open(manifestPath, 'r+', encoding='Utf-8')
    manifestContent = str(manifest_file.read())
    manifest_file.close()

    # 4、replace "${applicationId}" "${JPUSH_PKGNAME}" with packname in AndroidManifest.xml
    manifestContent = manifestContent.replace('${applicationId}', packageName)
    manifestContent = manifestContent.replace('${JPUSH_PKGNAME}', packageName)

    # 5、replace "${JPUSH_APPKEY}" "${XIAOMI_APPID}" "${XIAOMI_APPKEY}" "${VIVO_APPKEY}" "${VIVO_APPID}" "${OPPO_APPKEY}" 
    #"${OPPO_APPID}" "${OPPO_APPSECRET}" with "" in AndroidManifest.xml
    manifestContent = manifestContent.replace('${JPUSH_APPKEY}', '')
    manifestContent = manifestContent.replace('${XIAOMI_APPID}', '')
    manifestContent = manifestContent.replace('${XIAOMI_APPKEY}', '')
    manifestContent = manifestContent.replace('${VIVO_APPKEY}', '')
    manifestContent = manifestContent.replace('${VIVO_APPID}', '')
    manifestContent = manifestContent.replace('${OPPO_APPKEY}', '')
    manifestContent = manifestContent.replace('${OPPO_APPID}', '')
    manifestContent = manifestContent.replace('${OPPO_APPSECRET}', '')

    manifest_new_file = open(manifestPath, 'w', encoding='Utf-8')
    manifest_new_file.write(manifestContent)
    manifest_new_file.close()

    modify_main_activity_smali(decompileDir)


    return 0

def modify_main_activity_smali(decompileDir):
    
    manifestFile = decompileDir + "/AndroidManifest.xml"
    # manifestFile = file_utils.getFullPath(manifestFile)
    ET.register_namespace('android', androidNS)
    key = '{' + androidNS + '}name'

    tree = ET.parse(manifestFile)
    root = tree.getroot()

    applicationNode = root.find('application')
    if applicationNode is None:
        return

    activityNodeLst = applicationNode.findall('activity')
    if activityNodeLst is None:
        return

    mainActivityName = ''
    for activityNode in activityNodeLst:
        bMain = False
        intentNodeLst = activityNode.findall('intent-filter')
        if intentNodeLst is None:
            break
        for intentNode in intentNodeLst:
            bFindAction = False
            bFindCategory = False

            actionNodeLst = intentNode.findall('action')
            if actionNodeLst is None:
                break
            for actionNode in actionNodeLst:
                if actionNode.attrib[key] == 'android.intent.action.MAIN':
                    bFindAction = True
                    break

            categoryNodeLst = intentNode.findall('category')
            if categoryNodeLst is None:
                break
            for categoryNode in categoryNodeLst:
                if categoryNode.attrib[key] == 'android.intent.category.LAUNCHER':
                    bFindCategory = True
                    break

            if bFindAction and bFindCategory:
                bMain = True
                break

        if bMain:
            mainActivityName = activityNode.attrib[key]
            break

    print("============= mainActivity name = " + mainActivityName)
    if len(mainActivityName) == 0:
        return

    mainActivityPath = mainActivityName.replace(".", "/")
    mainActivityPath = decompileDir + '/smali/' + mainActivityPath + '.smali'

    print("============= mainActivity smali path = " + mainActivityPath)

    f = open(mainActivityPath, 'r+', encoding='Utf-8')
    mainActivityContent = str(f.read())
    f.close()

    fl = open(mainActivityPath, 'r+')
    lines = fl.readlines()
    fl.close()

    """
    superClassLine = lines[1]
    superClassLine.strip()
    superClassName = 'Landroid/app/Activity;'
    if superClassLine.startswith(".super"):
        blocks = superClassLine.split()
        superClassName = blocks[len(blocks)-1]

    replaceTxt = 'invoke-super {p0, p1, p2, p3}, ' + superClassName + '->onRequestPermissionsResult(I[Ljava/lang/String;[I)V'

    idx = mainActivityContent.find(replaceTxt)
    if idx == -1:
        targetTxt = "\n.method public onRequestPermissionsResult(I[Ljava/lang/String;[I)V\n    .locals 2\n\n    invoke-super {p0, p1, p2, p3}, " + superClassName + "->onRequestPermissionsResult(I[Ljava/lang/String;[I)V\n\n    invoke-static {p1, p2, p3}, Lcom/qnAgg/sdk/QnAggGame;->onRequestPermissionsResult(I[Ljava/lang/String;[I)V\n\n    return-void\n.end method"
        mainActivityContent = mainActivityContent + targetTxt
    else:
        targetTxt = "    invoke-super {p0, p1, p2, p3}, " + superClassName + "->onRequestPermissionsResult(I[Ljava/lang/String;[I)V\n\n    invoke-static {p1, p2, p3}, Lcom/qnAgg/sdk/QnAggGame;->onRequestPermissionsResult(I[Ljava/lang/String;[I)V"
        mainActivityContent = mainActivityContent[:idx] + targetTxt + mainActivityContent[(idx + len(replaceTxt)):]

    f2 = open(mainActivityPath, 'w', encoding='Utf-8')
    f2.write(mainActivityContent)
    f2.close()
    """

    superClassLine = lines[1]
    superClassLine.strip()
    superClassName = 'Landroid/app/Activity;'
    if superClassLine.startswith(".super"):
        blocks = superClassLine.split()
        superClassName = blocks[len(blocks)-1]

    replaceTxt = '.method public getResources()Landroid/content/res/Resources;'

    idx = mainActivityContent.find(replaceTxt)
    if idx == -1:
        targetTxt = "\n.method public getResources()Landroid/content/res/Resources;\n    .locals 3\n\n    invoke-super {p0}, " + superClassName + "->getResources()Landroid/content/res/Resources;\n\n    move-result-object v0\n\n    new-instance v1, Landroid/content/res/Configuration;\n\n    invoke-direct {v1}, Landroid/content/res/Configuration;-><init>()V\n\n    invoke-virtual {v1}, Landroid/content/res/Configuration;->setToDefaults()V\n\n    invoke-virtual {v0}, Landroid/content/res/Resources;->getDisplayMetrics()Landroid/util/DisplayMetrics;\n\n    move-result-object v2\n\n    invoke-virtual {v0, v1, v2}, Landroid/content/res/Resources;->updateConfiguration(Landroid/content/res/Configuration;Landroid/util/DisplayMetrics;)V\n\n    return-object v0\n.end method"
        mainActivityContent = mainActivityContent + targetTxt
    #else:
        #targetTxt = "    invoke-super {p0, p1, p2, p3}, " + superClassName + "->onRequestPermissionsResult(I[Ljava/lang/String;[I)V\n\n    invoke-static {p1, p2, p3}, Lcom/qnAgg/sdk/QnAggGame;->onRequestPermissionsResult(I[Ljava/lang/String;[I)V"
        #mainActivityContent = mainActivityContent[:idx] + targetTxt + mainActivityContent[(idx + len(replaceTxt)):]

    f2 = open(mainActivityPath, 'w', encoding='Utf-8')
    f2.write(mainActivityContent)
    f2.close()

    return 0