channel_action.py 9.7 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):
    replace_applicationId_to_AndroidManifest(decompileDir, packageName)

    # write_params_to_config(channel, decompileDir)

    modify_main_activity_smali(decompileDir)
    # modify_provider(decompileDir,packageName)

    # addWXEntryActivity(channel, decompileDir, packageName)

    return 0

def replace_applicationId_to_AndroidManifest(decompileDir, packageName):
    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)

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

    return 0

def write_params_to_config(channel, decompileDir):
    Pid = '104136'
    PKey = 'ISw/GOMBIDOSCzcXLy/XA5/DgXGKsA8Syzikka0V/41T2EPWCYAV0d5lcz1enF62'
    AppVersion = '1.0'
    ScreenType = '1'
    if channel['params'] != None and len(channel['params']) > 0:
        for param in channel['params']:
            if param['name'] == 'Pid':
                Pid = param['value']
            elif param['name'] == 'PKey':
                PKey = param['value']
            elif param['name'] == 'AppVersion':
                AppVersion = param['value']
            elif param['name'] == 'ScreenType':
                ScreenType = param['value']

    developer_config_path = decompileDir + '/assets/ouni_config.info'
    euConfigFile = open(developer_config_path, 'r+', encoding='Utf-8')
    configContent = str(euConfigFile.read())
    euConfigFile.close()

    configContent = configContent.replace('youlong_Pid_104136', Pid)
    configContent = configContent.replace('youlong_PKey_ISw/GOMBIDOSCzcXLy/XA5/DgXGKsA8Syzikka0V/41T2EPWCYAV0d5lcz1enF62', PKey)
    configContent = configContent.replace('youlong_AppVersion_1.0', AppVersion)
    configContent = configContent.replace('youlong_ScreenType_1', ScreenType)

    developer_config_file = open(developer_config_path, 'w', encoding='Utf-8')
    developer_config_file.write(configContent)
    developer_config_file.close()

    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

    if len(mainActivityName) == 0:
        return

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

    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/stss/sdk/STSSAggGame;->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/stss/sdk/STSSAggGame;->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

def addWXEntryActivity(channel, decompileDir, packageName):
    sdkDir = decompileDir + '/../sdk/' + channel['sdk']
    if not os.path.exists(sdkDir):
        file_utils.printF("The sdk temp folder is not exists. path:" + sdkDir)
        return 1

    """
    extraFilesPath = sdkDir + '/WXEntryActivity'
    relatedJar = os.path.join(sdkDir, 'STSSAgg_YouLong.jar')
    relatedJar = relatedJar + ";" + os.path.join(sdkDir + "/libs", 'libammsdk.jar')
    WXEntryActivity = os.path.join(extraFilesPath, 'WXEntryActivity.java')
    file_utils.modifyFileContent(WXEntryActivity, 'com.tencent.tmgp.cqm.wxapi', packageName + ".wxapi")

    splitdot = ';'
    if platform.system() == 'Darwin':
        splitdot = ':'

    toolRootPath = decompileDir + '/../../../../tool/win/'

    cmd = 'javac -source 1.8 -target 1.8 "%s" -classpath "%s"%s"%s"' % (WXEntryActivity, relatedJar, splitdot, toolRootPath + 'android.jar')

    ret = file_utils.execFormatCmd(cmd)
    if ret:
        return 1

    packageDir = packageName.replace('.', '/')
    srcDir = sdkDir + '/tempDex'
    classDir = srcDir + '/' + packageDir + '/wxapi'

    if not os.path.exists(classDir):
        os.makedirs(classDir)

    sourceClassFilePath = os.path.join(extraFilesPath, 'WXEntryActivity.class')
    targetClassFilePath = classDir + '/WXEntryActivity.class'

    file_utils.copy_file(sourceClassFilePath, targetClassFilePath)

    targetDexPath = os.path.join(sdkDir, 'WXEntryActivity.dex')


    # if platform.system() == "Windows":
    #     dxTool = file_utils.getFullToolPath('dx.bat')
    #     cmd = '"%s" --dex --output="%s" "%s"' % (dxTool, targetDexPath, srcDir)

    # else:
    #     dxTool = file_utils.getFullToolPath("/lib/dx.jar")

    #     cmd = file_utils.getJavaCMD() + ' -jar -Xmx512m -Xms512m "%s" --dex --output="%s" "%s"' % (
    #         dxTool, targetDexPath, srcDir)

    dxTool = toolRootPath + "lib/dx.jar"

    cmd = 'java -jar -Xmx512m -Xms512m "%s" --dex --output="%s" "%s"' % (dxTool, targetDexPath, srcDir)

    ret = file_utils.execFormatCmd(cmd)

    if ret:
        return 1

    ret = apk_utils.dex2smali(targetDexPath, decompileDir + '/smali', "baksmali.jar")

    if ret:
        return 1

    """
    sourcefile = sdkDir + '/WXEntryActivity/WXEntryActivity.smali'
    if not os.path.exists(sourcefile):
        return 1

    packageDir = packageName.replace('.', '/')
    destfile = decompileDir + '/smali/' + packageDir + '/wxapi/WXEntryActivity.smali'

    destdir = os.path.dirname(destfile)
    if not os.path.exists(destdir):
        os.makedirs(destdir)

    euConfigFile = open(sourcefile, 'r+', encoding='Utf-8')
    configContent = str(euConfigFile.read())
    euConfigFile.close()

    configContent = configContent.replace('Lcom/stss/sdk/WXEntryActivity', 'L' + packageDir + '/wxapi/WXEntryActivity')

    developer_config_file = open(destfile, 'w', encoding='Utf-8')
    developer_config_file.write(configContent)
    developer_config_file.close()


def modify_provider(decompileDir, packageName):
    manifestFile = decompileDir + "/AndroidManifest.xml"
    ET.register_namespace('android', androidNS)
    key = '{' + androidNS + '}name'
    schemeKey = '{'+androidNS+'}scheme'

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

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

    providerNodeLst = applicationNode.findall('provider')
    if providerNodeLst is None:
        return 1

    for providerNode in providerNodeLst:
        name = providerNode.get(key)
        if name == 'com.winunet.and.WGFileProvider':
            providerNode.set('{' + androidNS + '}authorities', packageName + '.fileprovider')

    tree.write(manifestFile, 'UTF-8')