feat: MariBank 风控 bypass、澳洲银行 Hook 与 reverse 逆向工作区
新增 MariBank/SeaBank PH Root 与 SHPSSDK bypass、riskToken 净化及 Up/Suncorp/ubank 消息 Hook;整理 reverse/ 脚本与 Frida 工具链,并补充当日工作说明文档。
This commit is contained in:
91
reverse/scripts/scan_dex.py
Normal file
91
reverse/scripts/scan_dex.py
Normal file
@@ -0,0 +1,91 @@
|
||||
# -*- 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)
|
||||
Reference in New Issue
Block a user