Python反编译apk,获取各类信息

python反编译apk,获取各类信息,包括activity、权限、包名、图标等等。

功能:

  1. 反编译apk,输入apk路径,使用apktool生成反编译后的文件夹。
  2. 解析AndroidManifest.xml,获取如activity、权限等关键信息。
  3. 调用dex2jar、jd-gui反编译、查看源代码

需要的工具,并将其加入环境变量:

  1. apktool,反编译apk
  2. dex2jar,dex->jar
  3. jd-gui,查看jar的源码
  4. bandizip,用于解压apk,可替换为其它解压软件,但代码中要替换命令

使用csdn客户端测试效果图:

  • 输入1,并输入apk文件路径,最终生成反编译后的文件夹
Python反编译apk,获取各类信息_第1张图片 1.反编译apk
  • 输入2,使用AndroidManifest解析功能,首先打印出名称、图标、包名、入口activity以及危险权限列表,继续输入y命令查看所有活动和权限。
Python反编译apk,获取各类信息_第2张图片 2.解析AndroidManifest文件

全部源代码,各部分的功能给出了注释:

import os

import xml.etree.ElementTree as ET

#android namespace
namespace = '{http://schemas.android.com/apk/res/android}'

#android danger-permission list
dangerPermissionArray = ['android.permission.READ_CALENDAR',
                         'android.permission.WRITE_CALENDAR',
                         'android.permission.CAMERA',
                         'android.permission.WRITE_CONTACTS',
                         'android.permission.GET_ACCOUNTS',
                         'android.permission.READ_CONTACTS',
                         'android.permission.ACCESS_FINE_LOCATION',
                         'android.permission.ACCESS_COARSE_LOCATION',
                         'android.permission.RECORD_AUDIO',
                         'android.permission.READ_CALL_LOG',
                         'android.permission.READ_PHONE_STATE',
                         'android.permission.CALL_PHONE',
                         'android.permission.WRITE_CALL_LOG',
                         'android.permission.USE_SIP',
                         'android.permission.PROCESS_OUTGOING_CALLS',
                         'com.android.voicemail.permission.ADD_VOICEMAIL',
                         'android.permission.BODY_SENSORS',
                         'android.permission.READ_SMS',
                         'android.permission.RECEIVE_WAP_PUSH',
                         'android.permission.RECEIVE_MMS',
                         'android.permission.RECEIVE_SMS',
                         'android.permission.SEND_SMS',
                         'android.permission.READ_CELL_BROADCASTS',
                         'android.permission.READ_EXTERNAL_STORAGE',
                         'android.permission.WRITE_EXTERNAL_STORAGE']

apkPath =''
apkOutPath = ''

#uses-permissions list
usesPermissionArray = []

#danger uses-permission list
dangerUsesPermissionArray = []

#activity list
activityArray = []

androidManifestPath =''
appIcon = ''
appName = ''
mainActivity = ''

def file_no_exists(str):
    if os.path.exists(str):
        return False
    else:
        return True

def apk_re():
    #apk path
    global apkPath
    apkPath = input('Please input Apk file path:')

    while file_no_exists(apkPath):
        apkPath = input('File not found,input Apk file path again:')

    #output file path
    global apkOutPath
    apkOutPath = (apkPath.split('.')[0]+'New')

    #use apktool
    cmd = 'apktool d -f '+apkPath+' -o '+apkOutPath
    os.system(cmd)
    print('-----------------------------\nwork all done,output file in:\n'
          +apkOutPath+'\n-----------------------------')
    
    #AndroidManifest.xml path
    global androidManifestPath
    androidManifestPath = apkOutPath+'\\AndroidManifest.xml'

def xmlPath_input():
    global androidManifestPath
    androidManifestPath = input('input AndroidManifext.xml file path:')
    while file_no_exists(androidManifestPath):
        
        androidManifestPath = input('File not found,input xml file path again:')

def xmlPath_confrim():
    if androidManifestPath == '':
        xmlPath_input()
    else:
        print('already get',androidManifestPath, 'change?[y/n]:')
        flag = input()
        if flag == 'y':
            xmlPath_input()
        elif flag == 'n':
            print('using',androidManifestPath, 'to work...')
        else:
            print('useless code,using',androidManifestPath, 'to work...')


def xml_re():
    xmlPath_confrim()
    
    tree = ET.parse(androidManifestPath)
    root = tree.getroot()

    #get packageName
    packageName = root.attrib['package']


    #get permission*****************************************
    for child in root.iter('uses-permission'):
        childName = child.get(namespace+'name')
        usesPermissionArray.append(childName)

        if (dangerPermissionArray.count(childName)) > 0 :
            dangerUsesPermissionArray.append(childName)
    #*******************************************************


    #get activity/MainActivity******************************************************************
    for application in root.iter('application'):
        appIcon = application.get(namespace+'icon')
        appName = application.get(namespace+'label').split('/')[-1]
        for activity in application.iter('activity'):
            activityName = activity.get(namespace+'name')
            #add package name
            if activityName[0] == '.':
                activityName = packageName+activityName

            activityArray.append(activityName)
            
            #find mainActivity
            for inter in activity.iter('intent-filter'):
                for action in inter.iter('action'):
                    if action.get(namespace+'name') =='android.intent.action.MAIN':
                        for cate in inter.iter('category'):
                            if cate.get(namespace+'name') == 'android.intent.category.LAUNCHER':
                               mainActivity = activityName
    #*******************************************************************************************


    # find app name in strings.xml******************************************
    homePath = androidManifestPath.split('\\')
    homePath.pop()
    stringPath = '\\'.join(homePath)+r'\res\values\strings.xml'
    if os.path.exists(stringPath):
        treeValue = ET.parse(stringPath)
        rootValue = treeValue.getroot()

        for child in rootValue.iter('resources'):
            for s in child.iter('string'):
                if s.get('name') == appName:
                    appName = s.text
    else:
        appName = "未找到,"+stringPath+"不存在"
    #********************************************************


    print('\n应用名称:', appName)
    print('应用图标:', appIcon)
    print('应用包名:', packageName)
    print('应用入口:', mainActivity)
    print('危险权限(',len(dangerUsesPermissionArray),'个):')
    for i in dangerUsesPermissionArray:
        print(i)

    flag = input('++++++++++++++++++++++++++++++++++++++\nsee all permission and activity?[y/n]:')
    if flag =='y':
        print('活动列表(',len(activityArray),'个):')
        for i in activityArray:
            print(i)
        print('权限列表(',len(usesPermissionArray),'个):')
        for i in usesPermissionArray:
            print(i)


def code_re():
    #apk path
    unzipPath = input('Please input Apk file path:')
    while file_no_exists(unzipPath):
        unzipPath = input('File not found,input Apk file path again:')

    if os.path.exists(unzipPath.split('.')[0]+'unzip'):
        pass
    else:
        bandizip = 'bandizip e -y '+unzipPath+' -o '+unzipPath.split('.')[0]+'unzip'
        print('unziping......')
        os.system(bandizip)
    
    d2j = 'd2j-dex2jar.bat '+unzipPath.split('.')[0]+'unzip\\classes.dex'

    jarPath = os.getcwd()+'\\classes-dex2jar.jar'
    if os.path.exists(jarPath):
        os.system('del '+jarPath)
    os.system(d2j)

    gui = 'jd-gui '+jarPath
    print('openning source code......')
    os.system(gui)

    
print('''
+++++++++++++++++++++++++++++++++++++++++++
          \       /    |
           +++++++     | work with:
          +++++++++    | Python3.6
       ++ +++++++++ ++ | apktool
       ++ +++++++++ ++ | dex2jar
       ++ +++++++++ ++ | jd-gui
           ++   ++     | bandizip
           ++   ++     | windows 10
          APPRETOOL    |
''')
print('Function:1.APKRE, 2.XMLRE,3.CODERE, 4.EXIT\n+++++++++++++++++++++++++++++++++++++++++++')
while 1:
    choose = input('your choose:')
    if choose == '1':
        apk_re()
    elif choose =='2':
        xml_re()
    elif choose =='3':
        code_re()
    elif choose == '4':
        break
    else:
        print('Unknown code! try again')
        continue
    print('\n+++++++++++++++++++++++++++++++++++++++++++\nFunction:1.APKRE, 2.XMLRE,3.CODERE, 4.EXIT\n+++++++++++++++++++++++++++++++++++++++++++')

os.system('pause')

 

你可能感兴趣的:(AndroidRE,Android,Java)