吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 6841|回复: 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] 纯文本查看 复制代码
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
"""
@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, 2025-5-24 00:30

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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