-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy pathandroid_ucbrowser.py
275 lines (251 loc) · 10.7 KB
/
android_ucbrowser.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
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
# coding=utf-8
__author__ = 'YangLiyuan'
from PA_runtime import *
import clr
try:
clr.AddReference('model_browser')
clr.AddReference('bcp_browser')
clr.AddReference('ScriptUtils')
clr.AddReference('ResourcesExp')
except:
pass
del clr
import re
import model_browser
import bcp_browser
from ScriptUtils import tp, exc, print_run_time, CASE_NAME, BaseAndroidParser
# from ResourcesExp import AppResources
# app数据库版本
VERSION_APP_VALUE = 2
def analyze_ucbrowser(node, extract_deleted, extract_source):
''' com.UCMobile/databases/WXStorage$ '''
tp('android_ucbrowser.py is running ...')
res = []
pr = ParserResults()
try:
res = AndroidUCParser(node, db_name='UC_A').parse(bcp_browser.NETWORK_APP_UC, VERSION_APP_VALUE)
except:
TraceService.Trace(TraceLevel.Debug,
'analyze_ucbrowser 解析新案例 <{}> 出错: {}'.format(CASE_NAME, traceback.format_exc()))
if res:
pr.Models.AddRange(res)
pr.Build('UC浏览器')
tp('android_ucbrowser.py is finished !')
return pr
class AndroidUCParser(model_browser.BaseBrowserParser, BaseAndroidParser):
def __init__(self, node, db_name):
super(AndroidUCParser, self).__init__(node, db_name)
self.root = node.Parent
def parse_main(self):
''' self.root: /com.UCMobile/ '''
account_dict = self.parse_Account('databases')
if not account_dict:
account_dict = {
'default_user': ''
}
for account_id in account_dict:
self.cur_account_name = account_id
self.parse_Bookmark('databases/' + account_id + '.db', 'bookmark')
self.parse_Browserecord_SearchHistory('databases/history', 'history')
self.parse_DownloadFile('databases/RecentFile.db', 'recent_file')
self.parse_Cookie(['app_webview/Cookies', 'app_core_ucmobile/Cookies'], 'cookies')
def parse_Account(self, node_path):
''' node_path: /databases
头像位置:
com.UCMobile\UCMobile\userdata\account\1883626966
Returns:
account_dict: {
'account_id': 'account_photo',
}
'''
account_id_nodes = self.root.GetByPath(node_path)
if not account_id_nodes:
return
account_dict = {}
photo_path = ''
for account_id_node in account_id_nodes.Children:
raw_account_id = account_id_node.Name
if raw_account_id and raw_account_id.replace('.db', '').isdigit():
account_id = raw_account_id.replace('.db', '')
# account_photo
photo_node = self.root.GetByPath('UCMobile/userdata/account/'+account_id)
if photo_node:
photo_path = photo_node.AbsolutePath
#tp('photo_path', photo_path)
account_dict[account_id] = photo_path if photo_path else None
if account_dict:
for account_id, photo_path in account_dict.items():
try:
account = model_browser.Account()
account.id = account_id
# account.name
# account.logindate
# account.source
# account.deleted
self.csm.db_insert_table_accounts(account)
except:
exc()
self.csm.db_commit()
return account_dict
def parse_Bookmark(self, db_path, table_name):
''' 'databases/' + account_id + '.db', 'bookmark'
FieldName SQLType
luid INTEGER
guid TEXT
parent_id INTEGER
title TEXT
url TEXT
path TEXT
order_index INTEGER
property INTEGER
folder INTEGER
last_modify_time INTEGER
create_time INTEGER
device_type TEXT
platform TEXT
opt_state INTEGER
sync_state INTEGER
modify_flag INTEGER
fingerprint TEXT
ext_int1 INTEGER
ext_int2 INTEGER
ext_string1 TEXT
'''
if not self._read_db(db_path):
return
for rec in self._read_table(table_name):
try:
if self._is_empty(rec, 'url', 'title') or not self._is_url(rec, 'url'):
continue
bookmark = model_browser.Bookmark()
bookmark.id = rec['luid'].Value
bookmark.owneruser = self.cur_account_name
bookmark.time = rec['create_time'].Value
bookmark.title = rec['title'].Value
bookmark.url = rec['url'].Value
bookmark.source = self.cur_db_source
bookmark.deleted = 1 if rec.IsDeleted else 0
self.csm.db_insert_table_bookmarks(bookmark)
except:
exc()
self.csm.db_commit()
def parse_Browserecord_SearchHistory(self, db_path, table_name):
''' databases/history - history 浏览记录
FieldName SQLType
id INTEGER
name TEXT
url TEXT
original_url TEXT
visited_time INTEGER
host TEXT
visited_count INTEGER
state INTEGER
media_type INTEGER
url_hashcode INTEGER
from_type INTEGER
source TEXT
daoliu_type INTEGER
article_id TEXT
channel_id INTEGER
icon_url TEXT
temp_1 TEXT
temp_2 TEXT
temp_3 TEXT
'''
if not self._read_db(db_path):
return
for rec in self._read_table(table_name):
try:
if (self._is_empty(rec, 'url', 'name') or
self._is_duplicate(rec, 'id') or
not self._is_url(rec, 'url')):
continue
browser_record = model_browser.Browserecord()
browser_record.id = rec['id'].Value
browser_record.name = rec['name'].Value
browser_record.url = rec['url'].Value
browser_record.datetime = rec['visited_time'].Value
browser_record.visit_count = rec['visited_count'].Value if rec['visited_count'].Value > 0 else 1
browser_record.owneruser = self.cur_account_name
browser_record.source = self.cur_db_source
browser_record.deleted = 1 if rec.IsDeleted else 0
self.csm.db_insert_table_browserecords(browser_record)
if browser_record.name.startswith('网页搜索_'):
search_history = model_browser.SearchHistory()
search_history.id = rec['id'].Value
search_history.name = rec['name'].Value.replace('网页搜索_', '')
search_history.url = rec['url'].Value
search_history.datetime = rec['visited_time'].Value
search_history.owneruser = self.cur_account_name
search_history.source = self.cur_db_source
search_history.deleted = 1 if rec.IsDeleted else 0
self.csm.db_insert_table_searchhistory(search_history)
except:
exc()
self.csm.db_commit()
@print_run_time
def parse_DownloadFile(self, db_path, table_name):
''' 'databases/RecentFile.db' - recent_file
FieldName SQLType
id integer
full_path text
display_name text
bucket_name text
modify_time integer
data_type text
data_source text
duration integer
thumbnail text
install_state integer
size integer
origin_id integer
extra_param text
'''
if not self._read_db(db_path):
return
for rec in self._read_table(table_name):
try:
if self._is_empty(rec, 'display_name') or self._is_duplicate(rec, 'id'):
continue
downloads = model_browser.DownloadFile()
downloads.id = rec['id'].Value
# downloads.url = rec['url'].Value
downloads.filename = rec['display_name'].Value
downloads.filefolderpath = self._convert_nodepath(rec['full_path'].Value)
downloads.totalsize = rec['size'].Value
# downloads.createdate = rec['modify_time'].Value
downloads.donedate = rec['modify_time'].Value
# costtime = downloads.donedate - downloads.createdate
# downloads.costtime = costtime if costtime > 0 else None
downloads.owneruser = self.cur_account_name
downloads.source = self.cur_db_source
downloads.deleted = 1 if rec.IsDeleted else 0
self.csm.db_insert_table_downloadfiles(downloads)
except:
exc()
self.csm.db_commit()
def _convert_nodepath(self, raw_path):
''' huawei: /data/user/0/com.baidu.searchbox/files/template/profile.zip
ar.save_res_folder
ar.save_media_model
'''
try:
if not raw_path:
return
if self.rename_file_path: # '/storage/emulated', '/data/media'
raw_path = raw_path.replace(self.rename_file_path[0], self.rename_file_path[1])
fs = self.root.FileSystem
for prefix in ['', '/data', ]:
# '/storage/emulated'
file_node = fs.GetByPath(prefix + raw_path)
if file_node and file_node.Type == NodeType.File:
return file_node.AbsolutePath
invalid_path = re.search(r'[\\:*?"<>|\r\n]+', raw_path)
if invalid_path:
return
nodes = list(fs.Search(raw_path))
if nodes and nodes[0].Type == NodeType.File:
return nodes[0].AbsolutePath
except:
tp('android_ucbrowser.py _conver_2_nodeapth error, raw_path:', raw_path)
exc()