Files
notiMessage/reverse/scripts/scan_dex.py
Mars 59970a84a8 feat: MariBank 风控 bypass、澳洲银行 Hook 与 reverse 逆向工作区
新增 MariBank/SeaBank PH Root 与 SHPSSDK bypass、riskToken 净化及 Up/Suncorp/ubank 消息 Hook;整理 reverse/ 脚本与 Frida 工具链,并补充当日工作说明文档。
2026-07-03 17:15:16 +08:00

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)