Ζητήστε το από τον βοηθό σας
Η εφαρμογή εμφανίζει έναν κωδικό σύνδεσης που αλλάζει. Θέλουμε να βρούμε τι τον κάνει να αλλάζει και να αναπαράγουμε αυτή τη συμπεριφορά.
Χρησιμοποιήστε το REA για να εξετάσετε το aegis-v3.4.3.apk. Βρείτε πώς δημιουργεί τον εξαψήφιο κωδικό σύνδεσης, εξηγήστε γιατί αλλάζει κάθε 30 δευτερόλεπτα και ανακατασκευάστε μια μικρή επίδειξη όπου μπορώ να αλλάζω τον χρόνο.
Παράδειγμα προτροπής για το APK που κατεβάσατε, με ρυθμισμένη την ανάλυση Android του REA. Αποκτήστε το APK και ρυθμίστε την ανάλυση ↓
Δοκιμάστε τη γεννήτρια κωδικών
Η εφαρμογή ομαδοποιεί τον χρόνο σε διαστήματα 30 δευτερολέπτων. Συνδυάζει τον αριθμό του διαστήματος με το κλειδί του λογαριασμού για να δημιουργήσει έναν κωδικό. Το ίδιο κλειδί και διάστημα παράγουν τον ίδιο κωδικό.
Μετακινήστε το ρολόι γύρω από τα 60 δευτερόλεπτα
- Χρόνος δευτερόλεπταΤο ρυθμιζόμενο ρολόι του παραδείγματός μας
-
Διάστημα 30 δευτερολέπτωνΔιάστημα
floor(59 / 30)
30–59 δευτερόλεπτα - Παραγόμενος κωδικόςΚλειδί λογαριασμού + διάστημα → έξι ψηφία
Στα 59 δευτερόλεπτα: 287082. Στα 60 δευτερόλεπτα: 359152. Η μετακίνηση μέσα στο ίδιο διάστημα αφήνει τον κωδικό αμετάβλητο.
Βρείτε τον κώδικα με το REA
-
Περιορίστε την αναζήτηση στο APK σε τρεις κλάσεις
Βοηθός → REAinspect_android_package {"path": "aegis-v3.4.3.apk"} search_android_classes {"path": "aegis-v3.4.3.apk", "query": "Totp"}REA → βοηθός · επιλεγμένα αποτελέσματαPackage: com.beemdevelopment.aegis Version: 3.4.3 Classes: 3,077 Three matches: otp.TotpInfo ui.views.TotpProgressBar importers.TotpAuthenticatorImporterΗ
TotpInfoείναι υποψήφια για τον υπολογισμό· οι άλλες δύο αφορούν τη γραμμή προόδου και τους εισαγόμενους λογαριασμούς. Το TOTP σημαίνει κωδικό μίας χρήσης βάσει χρόνου. -
Συνδέστε τη γεννήτρια με την εμφάνιση στην εφαρμογή
Βοηθός → REAinspect_android_class {"path": "aegis-v3.4.3.apk", "class_name": "com.beemdevelopment.aegis.otp.TotpInfo"} trace_android_references {"path": "aegis-v3.4.3.apk", "class_name": "com.beemdevelopment.aegis.otp.OtpInfo", "method_name": "getOtp"}REA → βοηθός · μέθοδοι και καλούντεςTotpInfo methods: getOtp() · overload 0 getOtp(long) · overload 1 OtpInfo.getOtp callers: ui.views.EntryHolder.getOtp ui.MainActivity.copyEntryCodeΤο REA εντοπίζει την υπερφόρτωση με χρονική σήμανση και βρίσκει τους καλούντες της βασικής μεθόδου. Η εξέταση της
EntryHolder.getOtpδείχνει έπειτα ότι η εμφάνιση καλεί τηTotpInfo.getOtp(timestamp).
Τα αιτήματα δείχνουν μια συντομευμένη διαδρομή εισόδου. Τα ονόματα κλάσεων στα αποτελέσματα παραλείπουν το κοινό πρόθεμα com.beemdevelopment.aegis.
Διαβάστε τον υπολογισμό
Το REA επιστρέφει τη μετατροπή του χρόνου, τις προεπιλεγμένες ρυθμίσεις και τις μεθόδους δημιουργίας. Οι κατασκευαστές ορίζουν διάστημα 30 δευτερολέπτων και έξι ψηφία· η μέθοδος χρονικής σήμανσης μετατρέπει τα δευτερόλεπτα σε αριθμό διαστήματος.
// TotpInfo defaults and clock
setPeriod(30);
getOtp(System.currentTimeMillis() / 1000);
// OtpInfo default algorithm and digits
this(bArr, "SHA1", 6);
// Block passed to the generator
(long) Math.floor(j / ((double) this._period))
// generateOTP → getHash
byte[] hash = getHash(bArr, str, j);
// getHash: account key + encoded block
Mac mac = Mac.getInstance(str);
mac.init(secretKeySpec);
return mac.doFinal(bArrArray);
// OTP.toString, case 0
this._code % ((int) Math.pow(10.0d, i))
// Keep leading zeroes
while (sb.length() < i) {
sb.insert(0, "0");
}
// Group time into 30-second blocks
seconds = current_time_ms / 1000
block = floor(seconds / 30)
// Generate a number from the key and block
hash = HMAC_SHA1(account_key,
big_endian_8_bytes(block))
number = select_31_bits(hash)
// Format the default six-digit code
code = number % 1_000_000
code = pad_with_zeroes(code, 6)
Ο χρόνος επιλέγει το διάστημα. Τα δευτερόλεπτα 30 έως 59 δίνουν όλα το διάστημα 1. Στα 60 δευτερόλεπτα, το διάστημα γίνεται 2.
Μετράει και το κλειδί. Η γεννήτρια συνδυάζει το κλειδί του λογαριασμού με το διάστημα. Ένας λογαριασμός με διαφορετικό κλειδί μπορεί να εμφανίζει διαφορετικό κωδικό την ίδια στιγμή.
Κρατήστε έξι ψηφία. Το υπόλοιπο της διαίρεσης με το 1,000,000 συμπληρώνεται με μηδενικά όπου χρειάζεται, οπότε ένας κωδικός μπορεί να αρχίζει με 0.
Αποσπάσματα από διάφορες μεθόδους που εξετάστηκαν, με αναδίπλωση γραμμών για την εμφάνιση. Το δεξί πλαίσιο είναι μια επεξηγηματική σύνοψη. Ο κώδικας του Aegis διατίθεται με άδεια GPL-3.0.
Μέσα στη γεννήτρια
Το APK της έκδοσης τοποθετεί τη generateOTP στην kotlin.ExceptionsKt. Το REA ακολουθεί την κλήση από τη TotpInfo και επιστρέφει αυτό το σώμα· ο αρχικός πηγαίος κώδικας ονομάζει τη βοηθητική συνάρτηση HOTP.
public static OTP generateOTP(byte[] bArr, String str,
int i, long j)
throws NoSuchAlgorithmException, InvalidKeyException {
byte[] hash = getHash(bArr, str, j);
int i2 = hash[hash.length - 1] & 15;
return new OTP(
(hash[i2 + 3] & 255)
| ((hash[i2] & 127) << 24)
| ((hash[i2 + 1] & 255) << 16)
| ((hash[i2 + 2] & 255) << 8), i, 0);
}
Το τελευταίο byte του κατακερματισμού επιλέγει μια θέση. Τέσσερα byte σε αυτή τη θέση δίνουν έναν θετικό αριθμό 31 bit· η μορφοποίηση τον περιορίζει στον ζητούμενο αριθμό ψηφίων. Το τελευταίο όρισμα του κατασκευαστή επιλέγει τον κλάδο μορφοποίησης κωδικού που εισήγαγε η μεταγλώττιση.
Ελέγξτε την ανακατασκευή
Συγκεντρώσαμε τις επιλεγμένες μεθόδους Java που επέστρεψε το REA σε ένα μικρό πρόγραμμα δοκιμής. Η έξοδός τους συμφώνησε με μια ανεξάρτητη ανακατασκευή σε 133 περιπτώσεις δοκιμής, που περιλάμβαναν όρια χρονικών διαστημάτων και κωδικούς που αρχίζουν με μηδέν.
| Χρόνος παραδείγματος | Διάστημα | Εξαψήφιος κωδικός |
|---|---|---|
| 30 δευτερόλεπτα | 1 | 287082 |
| 59 δευτερόλεπτα | 1 | 287082 |
| 60 δευτερόλεπτα | 2 | 359152 |
| 1,111,111,109 δευτερόλεπτα | 37,037,036 | 081804 |
Η γεννήτρια συμφωνεί επίσης με τις έξι δημοσιευμένες περιπτώσεις αναφοράς SHA-1 του RFC 6238. Ελέγξτε την υλοποίηση στον περιηγητή με αυτές:
Οι περιπτώσεις αναφοράς χρησιμοποιούν οκτώ ψηφία. Ο έλεγχος επαληθεύει επίσης τα εξαψήφια αποτελέσματά τους.
Η επαλήθευση εκτελεί τις εξαγόμενες μεθόδους Java και τη νέα επίδειξη. Το Android APK εξετάστηκε στατικά.
Εξετάστε το APK μόνοι σας
Ρυθμίστε το REA σε macOS ή Linux και έπειτα κατεβάστε αυτά τα δύο αρχεία στον ίδιο φάκελο. Στα Windows, χρησιμοποιήστε περιβάλλον Linux όπως το WSL.
Η ανάλυση Android απαιτεί πλήρες JDK 17 ή νεότερο. Επιλέξτε το με το JAVA_HOME ή το PATH. Αυτή η μελέτη χρησιμοποίησε JDK 21.
Ορίστε στο REA το αρχείο του παρόχου ανάλυσης και εξετάστε το APK:
REA_JADX_MCP_JAR="$PWD/jadx-headless-mcp-0.7.1-all.jar" \
npx rea-agents@latest inspect-android-package \
./aegis-v3.4.3.apk --format json --full-output
Ο βοηθός σας μπορεί να συνεχίσει μέσω του CLI του REA με την παραπάνω προτροπή. Για MCP, προσθέστε το REA_JADX_MCP_JAR στο περιβάλλον του διακομιστή REA και επανασυνδέστε τον.
Μια επόμενη ερώτηση: τι συμβαίνει όταν ένας λογαριασμός χρησιμοποιεί οκτώ ψηφία ή διαφορετικό χρονικό διάστημα;
Πηγές
- Επίσημη έκδοση Aegis 3.4.3 · Αντίστοιχο commit πηγαίου κώδικα · Άδεια GPL-3.0
- Περιπτώσεις αναφοράς RFC 6238 · Δεδομένα δοκιμής της επίδειξης
Εξετάστηκε με το REA 6.1.0 στις 9 Οκτωβρίου 2026. Τα απομεταγλωττισμένα αποσπάσματα αποδίδονται στο Aegis· το διάγραμμα, η ευανάγνωστη σύνοψη και η ανακατασκευή στον περιηγητή αποτελούν νέο εκπαιδευτικό υλικό.