新增 MariBank/SeaBank PH Root 与 SHPSSDK bypass、riskToken 净化及 Up/Suncorp/ubank 消息 Hook;整理 reverse/ 脚本与 Frida 工具链,并补充当日工作说明文档。
92 lines
2.5 KiB
Python
92 lines
2.5 KiB
Python
# -*- coding: utf-8 -*-
|
|
import os
|
|
import re
|
|
import sys
|
|
|
|
PATTERNS = [
|
|
r'FirebaseMessagingService',
|
|
r'onMessageReceived',
|
|
r'NotificationManager',
|
|
r'NotificationCompat',
|
|
r'NotificationChannel',
|
|
r'PushNotification',
|
|
r'PushMessage',
|
|
r'Transaction',
|
|
r'transaction',
|
|
r'InboxMessage',
|
|
r'AlertMessage',
|
|
r'showNotification',
|
|
r'postNotification',
|
|
r'NotificationReceiver',
|
|
r'FCM',
|
|
r'FirebaseMessaging',
|
|
r'MessagingService',
|
|
r'PaymentNotification',
|
|
r'TransferNotification',
|
|
r'BankNotification',
|
|
]
|
|
|
|
CLASS_LIKE = re.compile(r'[A-Za-z][\w$/]{3,120}')
|
|
|
|
|
|
def extract_strings(data, min_len=4):
|
|
out = set()
|
|
for m in re.finditer(rb'[\x20-\x7e]{' + str(min_len).encode() + rb',}', data):
|
|
try:
|
|
out.add(m.group().decode('ascii'))
|
|
except Exception:
|
|
pass
|
|
return out
|
|
|
|
|
|
def scan_file(path):
|
|
with open(path, 'rb') as f:
|
|
data = f.read()
|
|
strings = extract_strings(data, 5)
|
|
hits = {}
|
|
for pat in PATTERNS:
|
|
rx = re.compile(pat, re.I)
|
|
matched = sorted({s for s in strings if rx.search(s)})
|
|
if matched:
|
|
hits[pat] = matched[:40]
|
|
# interesting fully-qualified class names
|
|
fqcn = sorted({
|
|
s for s in strings
|
|
if ('/' in s or s.startswith('L')) and any(k in s.lower() for k in (
|
|
'notif', 'push', 'fcm', 'firebase', 'message', 'transaction', 'alert', 'inbox', 'payment', 'transfer'
|
|
))
|
|
})
|
|
return hits, fqcn[:80]
|
|
|
|
|
|
def main(root):
|
|
for app in sorted(os.listdir(root)):
|
|
app_dir = os.path.join(root, app)
|
|
if not os.path.isdir(app_dir):
|
|
continue
|
|
print('\n' + '=' * 70)
|
|
print('APP:', app)
|
|
print('=' * 70)
|
|
dex_files = [f for f in os.listdir(app_dir) if f.endswith('.dex')]
|
|
all_hits = {}
|
|
all_fqcn = set()
|
|
for dex in sorted(dex_files):
|
|
path = os.path.join(app_dir, dex)
|
|
hits, fqcn = scan_file(path)
|
|
for k, v in hits.items():
|
|
all_hits.setdefault(k, set()).update(v)
|
|
all_fqcn.update(fqcn)
|
|
for pat in PATTERNS:
|
|
if pat in all_hits:
|
|
print('\n[%s]' % pat)
|
|
for s in sorted(all_hits[pat])[:25]:
|
|
print(' ', s)
|
|
print('\n[interesting class-like strings]')
|
|
for s in sorted(all_fqcn)[:60]:
|
|
print(' ', s)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
root = sys.argv[1] if len(sys.argv) > 1 else 'extracted'
|
|
main(root)
|