吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 6229|回复: 9
收起左侧

[Python 原创] 新手用tkinter写了一个APK提取工具

  [复制链接]
时空之外 发表于 2019-2-28 16:10
本帖最后由 时空之外 于 2019-4-1 15:56 编辑

来吾爱已经好快半年了,学习py也有一段时间了,今天把前段时间写的APK查询工具以及源码提供出来供大家参考。

程序截图:
GIF.gif
使用说明:
将apk文件拖入工作区即可,点击获取Icon将在APK文件所在目录生成Icon

安装所需以及依赖的库:
IDE:pycharm
python版本:3.7
操作系统:win7

源码:
[Python] 纯文本查看 复制代码
"""
@author:qh
@datetime:2019-3-15
@mood:<(* ̄▽ ̄*)/
"""

import os
import base64
import requests
import json
import shutil
import hashlib
from tkinter import *
from tkinter import ttk
from TkinterDnD2 import *
from TkinterDnD2 import TkinterDnD
from threading import Thread
from pyaxmlparser import APK
from pyaxmlparser.utils import NS_ANDROID
from fake_useragent import UserAgent
from conf import user_permission_info, img


class ApkR(APK):
    def __init__(self, apk):
        super().__init__(apk)

    def get_permission(self, **attribute_filter):
        tag = self.xml.findall('.//uses-permission')
        if len(tag) == 0:
            return None
        permission_list = []
        for item in tag:
            skip_this_item = False
            for attr, val in list(attribute_filter.items()):
                attr_val = item.get(NS_ANDROID + attr)
                if attr_val != val:
                    skip_this_item = True
                    break
            if skip_this_item:
                continue
            value = item.get(NS_ANDROID + 'name')
            if value is not None:
                permission_list.append(value)
        return permission_list


class ApkExtract(object):
    def __init__(self):
        self.on_off = True
        self.tostring = {
            'info': '',
            'package_name': '',
            'package_version_code': '',
            'package_version_name': '',
            'game_name': '',
            'md5_value': '',
            'empty': '',
            'apk_size': ''
        }
        with open('C:\Windows\Temp\Icon.ico', 'wb') as fp:
            fp.write(base64.b64decode(img))
        self.app = self.make_app()
        self.app.mainloop()

    @staticmethod
    def get_icon():
        save_icon_path = '{}.png'.format(file_path[:-4])
        shutil.copyfile('C:\Windows\Temp\Temp.png', save_icon_path)

    # 检查病毒
    def check_virus(self):
        def _get_response():
            sha_value = self.app.children['en'].get()
            if not sha_value:
                return '请等待MD值提取完成后再检测', '#4c4f8b'
            ua = UserAgent(verify_ssl=False).random
            headers = {
                'User-Agent': ua
            }
            try:
                res = requests.get('https://www.virustotal.com/ui/files/{}'.format(sha_value), headers=headers).json()
            except requests.exceptions.ConnectionError as e:
                return '查询失败,请检查网络', '#4c4f8b'
            else:
                if res.get('data'):
                    a = res['data']['attributes']['last_analysis_stats']['malicious']
                    # print(res)
                    with open('check_results.json', 'w', encoding='utf-8') as f2:
                        f2.write(json.dumps(res, ensure_ascii=False, indent=4))
                    return '共{}个引擎检测到恶意文件!'.format(a), 'red'
                else:
                    return '没有检测到病毒,文件安全!', 'green'

        def _main():
            lb2 = self.app.children['lb2']
            lb2.config(text='正在检测中...', fg='#4c4f8b')
            data = _get_response()
            lb2.config(text=data[0], fg=data[1])

        t = Thread(target=_main, )
        t.start()

    def show_permission(self):
        if self.on_off:
            self.app.geometry('510x640')
            self.on_off = False

        else:
            self.app.geometry('510x292')
            self.on_off = True

    @staticmethod
    def get_prm_info(item_list):
        permission_info = []
        unknown_per = []
        for item in item_list:
            if user_permission_info.get(item):
                permission_info.append(user_permission_info.get(item))
            else:
                unknown_per.append(['未知权限', item])
        permission_info_list = permission_info + unknown_per
        return permission_info_list

    def drag_and_drop(self, event):
        global file_path
        file_path = event.data.strip('{}')

        def _get_info():
            apk = ApkR(file_path)
            ic_data = apk.icon_data
            package_name = apk.package
            apk_size = '{:.1f}MB'.format(os.path.getsize(file_path) / 1024 / 1024)
            package_version_code = apk.version_code
            package_version_name = apk.version_name
            game_name = apk.application
            ele = apk.get_permission()
            a = self.get_prm_info(ele)
            lbx = self.app.children['lbx']
            lbx.delete(0, END)
            for index, item in enumerate(a):
                text = '* {}                -{}'.format(item[0], item[1])
                lbx.insert(index, text + ' ' * 16)
            show_info = '{}安装所需权限({})'.format(game_name, len(a))
            lbx.insert(0, '{:>60} '.format(show_info))
            lbx.insert(1, '')
            lbx.insert(END, '')
            lbx.insert(END, '')
            lbx.insert(END, '')
            self.tostring['info'].set(file_path)
            self.tostring['apk_size'].set(apk_size)
            self.tostring['package_name'].set(package_name)
            self.tostring['package_version_code'].set(package_version_code)
            self.tostring['package_version_name'].set(package_version_name)
            self.tostring['game_name'].set(game_name)
            _show_img(ic_data)

        def _show_img(icon_data):
            with open('C:\Windows\Temp\Temp.png', 'wb+') as f1:
                f1.write(icon_data)
            fr1 = self.app.children['lb']
            try:
                ic_path = PhotoImage(file="C:\Windows\Temp\Temp.png")
                fr1['image'] = ic_path
                fr1.image = ic_path
            except TclError:
                fr1['image'] = ''
                fr1.image = ''
                fr1['text'] = '未找到Icon图标'

        def _refresh():
            self.tostring['md5_value'].set('')
            lb2 = self.app.children['lb2']
            lb2['text'] = ''

        def _get_md5_value():
            if not os.path.isfile(file_path):
                return
            my_hash = hashlib.md5()
            total_size = os.path.getsize(file_path)
            file_size = 0
            iter_size = int(total_size / 100)
            with open(file_path, 'rb') as f:
                while True:
                    b = f.read(iter_size)
                    file_size += len(b)
                    md5_value = '{}%'.format(int(round(float(file_size / total_size) * 100)))
                    sys.stdout.flush()
                    self.tostring['md5_value'].set(md5_value)
                    if not b:
                        break
                    my_hash.update(b)
            md5_value = my_hash.hexdigest().upper()
            print('222')
            self.tostring['md5_value'].set(md5_value)

        def _main():
            _refresh()
            _get_info()
            t = Thread(target=_get_md5_value(), )
            t.start()
            # _get_md5_value()

        m = Thread(target=_main, name='aa')
        m.start()

    def make_app(self):
        window = TkinterDnD.Tk()

        sw = 510
        sh = 292
        ww = window.winfo_screenwidth()
        wh = window.winfo_screenheight()
        x = int((ww - sw) / 3)
        y = int((wh - sh) / 3)
        window.geometry('{}x{}+{}+{}'.format(sw, sh, x, y))
        window.title('APK信息提取工具')
        window.resizable(False, False)
        window.iconbitmap('C:\Windows\Temp\Icon.ico')

        self.tostring['info'] = StringVar()
        self.tostring['package_name'] = StringVar()
        self.tostring['package_version_code'] = StringVar()
        self.tostring['package_version_name'] = StringVar()
        self.tostring['game_name'] = StringVar()
        self.tostring['md5_value'] = StringVar()
        self.tostring['empty'] = StringVar()
        self.tostring['apk_size'] = StringVar()

        Label(window, name='lb', borderwidth=2, relief='ridge', background='#f3f3f3').place_configure(width=190,
                                                                                                      height=190, x=10,
                                                                                                      y=10, )

        LabelFrame(window, width=280, height=196, text='  游戏详情  ', ).place_configure(x=210, y=5)
        Label(window, text='游戏名称:', fg='#0000ff').place(x=226, y=30)
        ttk.Entry(window, state='readonly', textvariable=self.tostring['game_name'], foreground='#0000ff').place_configure(
            width=180, x=290, y=30)

        Label(window, text='游戏大小:', fg='#ff8c00').place(x=226, y=65)
        ttk.Entry(window, state='readonly', textvariable=self.tostring['apk_size'], foreground='#ff8c00').place_configure(
            width=180, x=290, y=65)

        Label(window, text='包名:', fg='#008000').place(x=226, y=100)
        ttk.Entry(window, state='readonly', textvariable=self.tostring['package_name'],
                  foreground='#008000').place_configure(width=180, x=290, y=100)

        Label(window, text='版本号:', fg='#ff00ff').place(x=226, y=135)
        ttk.Entry(window, state='readonly', textvariable=self.tostring['package_version_code'],
                  foreground='#ff00ff').place_configure(width=180, x=290, y=135)

        Label(window, text='版本名:', fg='#8b0000').place(x=226, y=170)
        ttk.Entry(window, state='readonly', textvariable=self.tostring['package_version_name'],
                  foreground='#8b0000').place_configure(width=180, x=290, y=170)

        fr2 = Frame(window, width=140, height=30)
        fr2.pack_propagate(0)
        ttk.Button(fr2, text='获取Icon', command=self.get_icon).place_configure(x=0, y=0, width=60, height=30)

        ttk.Button(fr2, text='病毒检测', command=self.check_virus).place_configure(x=70, y=0, width=60, height=30)
        fr2.place(x=10, y=218)

        Label(window, name='lb2', font=('Hack', 10, 'bold')).place_configure(x=200, y=228)

        ttk.Button(window, text='查看权限', command=self.show_permission).place_configure(width=70, height=30, x=420, y=218)

        # 提取MD5值
        Label(window, text='MD5值:', font=('Arial', 8,), fg='#4156f4').place(x=10, y=260)
        ttk.Entry(window, state='readonly', width=40, name='en', textvariable=self.tostring['md5_value'],
                  foreground='#4156f4').place(x=60, y=260)

        Label(window, text='注:将apk文件拖入工作区').place_configure(x=350, y=260)

        lbf = LabelFrame(text='  详情  ')
        lbf.place_configure(x=10, y=320, width=480, height=310)
        lb = Listbox(window, name='lbx', bg='#f9fef9', state='normal')
        sb = Scrollbar(lb)
        sb.pack(side=RIGHT, fill=Y)
        sb2 = Scrollbar(lb, orient=HORIZONTAL)
        sb2.pack(side=BOTTOM, fill=X)
        lb.config(yscrollcommand=sb.set)
        lb.config(xscrollcommand=sb2.set)
        lb.place_configure(x=20, y=340, width=460, height=280)
        sb.config(command=lb.yview)
        sb2.config(command=lb.xview)
        window.drop_target_register(DND_FILES)
        window.dnd_bind('<<Drop>>', self.drag_and_drop)
        return window

    def __del__(self):
        os.remove('C:\Windows\Temp\Icon.ico')
        os.remove('C:\Windows\Temp\Temp.png')


if __name__ == '__main__':
    new = ApkExtract()


这里使用了TkinterDnD2来实现了文件的拖拽功能,不过此库只支持Win7/Winxp/Vista/OS X,使用pyaxmlparser解析APK文件,fake_useragent随机生成headers。
还需要引入tkdnd2.8环境,下载地址:https://sourceforge.net/projects/tkdnd/,下载完成后解压放到python解释器文件下的tcl/tcl8.6文件目录下

源码:
apk_info_extract.rar (25.92 KB, 下载次数: 27)

PS:不支持win10系统

TIM图片20190316120943.png

免费评分

参与人数 6吾爱币 +6 热心值 +6 收起 理由
不到大神不改名 + 1 这个干嘛的
a18219352750 + 1 + 1 热心回复!
专门搞学习的娃 + 1 + 1 我很赞同!
MedusaSTears + 1 我苦寻了好久,真的!
wushaominkk + 3 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
一笑懸命桑 + 1 + 1 谢谢@Thanks!

查看全部评分

本帖被以下淘专辑推荐:

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

wushaominkk 发表于 2019-2-28 16:23
给个建议,病毒检测应该把https://www.virustotal.com/查出内容显示出来!
 楼主| 时空之外 发表于 2019-2-28 16:45
wushaominkk 发表于 2019-2-28 16:23
给个建议,病毒检测应该把https://www.virustotal.com/查出内容显示出来!

嗯,好的,回去试试看
MedusaSTears 发表于 2019-2-28 17:01
看帖先评论,免得日后找不到;感谢分享,楼主辛苦啦~
yc19951005 发表于 2019-2-28 18:17
这个提取有什么用??
 楼主| 时空之外 发表于 2019-2-28 23:31 来自手机
yc19951005 发表于 2019-2-28 18:17
这个提取有什么用??

查询apk文件的信息呀
yc19951005 发表于 2019-3-1 09:28
时空之外 发表于 2019-2-28 23:31
查询apk文件的信息呀

好的 谢谢
哎真是服了 发表于 2020-2-23 13:42
大佬为啥下载你的源码以后运行不了
哎真是服了 发表于 2020-2-23 13:46
能给个联系方式吗 想请教一下
哎真是服了 发表于 2020-2-23 16:17
哎真是服了 发表于 2020-2-23 13:46
能给个联系方式吗 想请教一下

大佬看见麻烦回我一下 有偿
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-16 22:03

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表