Static-analysis disclosure · ru.oneme.app “MAX”
If You Wanted to Watch a Country
We pulled MAX apart and read the code: the surveillance machine you could build on top of it, and how little of it we had to make up.
MAX (ru.oneme.app) is Russia’s state-mandated national messenger, built by VK and preinstalled by law. It was never meant to be just a chat app. One login is being wired to your messages, your whole contact book, your government ID, and your bank: your whole civic life in one place. And none of it is private. There is no end-to-end encryption on anything, not your texts, not your voice notes, not the videos you send, so the operator holds it all in the clear.
We decompiled the shipping build. That same server can do more than read. It can move your connection to one it chooses with the encryption switched off, flip any of 455 settings for a single account, pull a live location fix from your phone, report your device, IP and VPN status to an unlisted server, and replace the whole app on your phone, all aimed at one user. Every piece ships today. And since nothing is encrypted, in theory it could even put words in your mouth: a message injected so it reads as a contact’s, though we found no sign this is used.
So MAX isn’t the spy. It’s the infrastructure a spy would plug into. One app ties a single, named citizen, physical and digital life alike (identity, location, money, messages), to the rest of the state’s databases, where all of it can be cross-referenced against one person. Every wire is real and present in the shipping build, and it is already the operator’s to hand over by law. The only thing we invented is the “Service” that pulls it together into a command-and-control operation.
| Capability | In the code | Needs the Service | Proof | Verdict |
|---|---|---|---|---|
| Read your messages (plaintext) | ● | ○ | §7 | Confirmed |
| Reroute your connection, turn off encryption | ● | ○ | §1 | Confirmed |
| Rewrite one account’s rules (455 flags) | ● | ○ | §3 | Confirmed |
| Locate you on demand | ● | ○ | §5 | Confirmed |
| Report device, IP, VPN to an unlisted server | ● | ○ | §4 | Confirmed |
| Swap the app on your phone (targeted) | ● | ○ | §2 | Confirmed |
| Inject a message as anyone | ◑ | ● | §7 | Narrowed |
| Cross-reference you across state databases | ○ | ● | none | Imagined |
If you wanted to watch a whole country, you wouldn’t break in. Breaking in is work. You find a flaw in every phone, exploit it, and cling on as the patches land, and that window keeps closing faster now that AI is putting the defenders ahead. The smarter move is to never break in at all: own the supply chain. Build a super-app that holds a whole life (messages, money, ID, dealings with the state), ship it through the official store as a legitimate app, and make everyone install it. Russia did exactly that. Since 1 September 2025, federal law puts its national messenger, MAX, on every new phone sold in the country, and the state is routing essential services through it. We pulled it apart and read the code.
You don’t have to force an install when the alternatives disappear. Adoption figures are VK’s own and count registered accounts, not unique people; independent outlets flag likely inflation. Competitor restrictions are Roskomnadzor’s, reported by The Moscow Times and Russian wires.
The hard way: an exploit operation
- Find a flaw in the phone
- Build and deliver an exploit
- Escalate & gain persistence
- Exfiltrate, then keep re-winning as patches land
The pivot: own the super-app
- Mandate the app onto every phone
- Capabilities already granted; it’s a legit app
- Push new code through the official store, any time
- Aim it at anyone, at population scale
Read this first. The whole usage story (the Service, pointing MAX at a person, deciding to pull the levers) is imaginary and speculative. We built it by piecing together the infrastructure we observed and the features and bugs sitting in MAX’s own code, to show what such an app could be worth to a government that chose to use it. Everything on the MAX client side, Acts I and II, is pinned to a line in the build we pulled and decompiled: each claim carries its citation, and the Appendix walks the evidence. We leave it to you to weigh exactly which claims are proven, and how well. Where a detail comes from public reporting rather than our own read of the code, we mark it.
Not a Backdoor. The Architecture.
It isn’t hidden, and it isn’t a hack. It’s the architecture: six everyday features that, stacked into one app, hand a single operator a whole life. Each one is confirmed in the build we pulled.
Start with what the one app already holds. Your messages sit on the server in the clear. There’s no end-to-end encryption anywhere, and the web client at web.max.ru proves it: a browser that never held a key still shows your history (§7). Your whole contact book, including people who never installed MAX, uploads at login. And the moment you link Digital ID, your real name and state identity bind to the same account as your chats, through ESIA / Gosuslugi (Russia’s national login for state services) and a tap-to-verify NFC service (§6).
The rest of a life follows. Your money runs through in-chat payments and bank mini-apps, tagged to you (SBP, VTB, Alfa, per public reporting). Your dealings with the state go through the same app: Gosuslugi login, the 2FA codes that replaced SMS, the e-signature. And the updater can replace MAX itself with a build of the operator’s choosing, from its own server, outside any store (§2). Six ordinary features. Stacked in one app, behind one operator, they are a filing cabinet of a whole life, before a single “surveillance feature” is switched on.
What MAX is actually made of
MAX wasn’t written from scratch. Under the new name it’s TamTam, VK and Odnoklassniki’s old messenger, reskinned. Our own copy of the app carries roughly 200 classes under ru.ok.tamtam.* (the whole messaging core: chats, contacts, folders, uploads) and still sends messages in TamTam’s own nano.Protos format, over a proprietary binary protocol to api2.oneme.ru. That matters because the parts this whole story turns on, namely no end-to-end encryption, the cloud-mailbox model, and the server opcodes that carry the RECONNECT redirect, aren’t new experiments bolted on for a national rollout. They are a mature, years-old codebase, lightly repainted and handed a country.
From our decompile: the ru/ok/tamtam/** class tree, the ru.ok.tamtam.nano.Protos$* wire types, the plaintext body field Tasks$MsgEdit.text, and the opcode-plus-map session protocol (the Appendix walks the chain). Reported only, not in our build: a separate Russian-channel build is said to swap standard TLS for Russian GOST cryptography (host api-gost.oneme.ru); the build we pulled ships GOST switched off (Gost:false, no such host), so we make no GOST claim here.
Now the Service Wants Hands
A filing cabinet is nice, but our Service wants reach. The uncomfortable part is that it doesn’t need to break in, smuggle a payload, or even push an update. Every way of reaching further is already in the app: switches the operator throws from its own servers, pointed at a single account when that is all it wants. We found the switches in the code. What a security service would do with them is the only part we’re imagining.
Walk the seven. Every one is throwable from the server, aimed at one account if that’s all it wants. Several aren’t even separate systems: the reroute (§1), the per-account config flip (§3), an on-demand re-upload of your whole address book, and the location request (§5) are all opcodes on the one command channel the mailbox already runs: the server reaches each by sending your phone a single numbered message on the same wire. On command, the app hands over a GPS fix (gated on a location permission granted once, not fresh consent; §5), and it flags you the moment you switch on a VPN: detect-and-report, not a block (ledger). One message, RECONNECT, can move your whole connection to any server it names with the encryption switched off, with no allow-list, and it survives logout (§1). A dormant reporter can beacon (silently phone home) your IP, carrier, VPN state and device to an unlisted domain whose address is scrambled in the code to hide it (§4).
The last three reach further still. A config message flips any of 455 settings for your account alone (§3). Every app updates through a store, which vets the download for you; MAX keeps a second path of its own. The self-updater can replace MAX with a build of the operator’s choosing, from its own server; the only backstops left are the system “install this app?” prompt and MAX’s own signing key (§2). And a whitelisted mini-app can run a carrier-grade SIM check and read the raw answer, with no consent prompt (§6). Seven ordinary features, and the only imagined part is a hand deciding to throw one at you.
Why “for one account” is the whole game
A switch flipped for everyone is a boring product setting. The same switch flipped for one named person, when every request the app sends already identifies you, becomes a dial pointed at a single citizen. That shift, from everyone to you, is the whole difference between a messaging app and a weapon. (The app makes it possible; whether a server actually targets you that way is what we can’t see from the outside, and it is where the Service steps in.) It also dissolves the split in the public reporting: one team watched a clean install and called MAX boring, another found it probing and reporting, the same app in two server states. An independent study (InterSecLab) observed exactly that, the behaviour varying from one account to the next.
One Company Builds the App, and Owns the Store It Skips
We’ve been saying “the operator” like it’s a neutral box. It isn’t. It’s VK, Russia’s largest internet company, and who controls VK is the whole point. VK builds and runs MAX; it also runs RuStore, the national app store that Act II’s self-updater steps around, and the same ministry ordered both onto every phone. But VK is not independent. Since late 2021 its voting control has sat with a holding company, MF Technologies, owned by Kremlin-adjacent state money, and its chief executive is Vladimir Kiriyenko, the son of Sergei Kiriyenko, the official who runs the Kremlin’s domestic politics. The chart below names each link. The short of it: the state that forces MAX onto your phone also owns the company that operates it.
None of this is in the code. It’s public reporting, and we flag it as such. One detail is too good to leave out: in July 2026, days after the EU sanctioned VK and MAX’s operator for building the messenger as a surveillance tool, VK sold RuStore, not to an outside buyer but to the CEO of the firm it had hired to build the store (Dmitry Pankrushev of Many Applications). A sale to a close associate, a tidy way to put daylight between the store and a sanctioned parent.
The app and the store are one company
The “out-of-store” updater and the official store both lead back to VK. MAX is built by VK’s «Коммуникационная платформа» (“Communication Platform”); RuStore, Russia’s mandated app store, is VK’s «Много приложений». The escape hatch and the front door belong to the same firm.
Shared wiring, one owner
The two halves don’t just share an owner; they share plumbing. RuStore’s push notifications run through a VK service literally called VKPNS (“VK Push”), and VK’s own apps now let you sign in with MAX. The app, the store, the login, and the company behind them are one system.
Sources (public reporting, not our code): Meduza, The Bell, IntelliNews, The Moscow Times, TASS, and the Council of the EU sanctions listing, 2021–2026. Ownership percentages are from 2021–22 reporting and may have shifted since; the July 2026 EU sanctions and the RuStore sale were reported at the time.
So Who’s Behind the Operator?
We’ve seen who owns the operator and what its servers can do. The last step is the one we can’t photograph: a command-and-control console wired to drive those real levers at a single, named person. Every lever it pulls ships in the code. The console, the hand on those levers, is the part we imagine. One hard fact holds it up: Russian law already forces an operator to hand its data to the state on demand (SORM for the live tap, Yarovaya for the stored archive). The compulsion is real; only the console is drawn.
Make it one person. Say she joins an opposition channel on MAX one morning, having done nothing the law forbids. The operator already holds her messages in the clear, voice notes included (§7), and her real name and verified identity, because her Digital ID is bound to the account (§6). Ask the phone where she is and it answers (§5). The instant she opens a VPN to hide, the app notes it (§1). Want more reach? Flip a handful of her 455 account settings (§3), or send her a fresh build of MAX straight from the server, outside any store (§2). None of that is hypothetical code; it all sits in the build we pulled. The only invented part is someone deciding she is worth the trouble.
None of the links are exotic: the operator already holds your messages in the clear and, through Digital ID, can know who you are; the console’s switches are Act II’s seven doors; the wire up to the ID database is just what “one messenger, one identity, one company, one country’s law” already means. We invented only the room that draws it together, and the law that would hand it the keys isn’t invented at all.
What’s Real, What’s Imagined, What We Won’t Say
This story only works if the fact half is trustworthy, so here is where the ground ends and the thought experiment begins.
Real, and this is the point
Every capability in Acts I and II is pinned to a line in the build we pulled and hashed. The foundation and the seven doors are facts about MAX 26.31.0, not predictions. (Where payment rails, bank names, or specific government services are named, those come from public reporting and are marked as such.)
Imagined, built from the real
The Service, the console, and the server-side stack are a thought experiment. We are not claiming MAX does this. We’re showing it would need no new client code, only an operational server to receive the reroute and the decision to use what ships today, inside a legal system that can already compel the operator.
What we deliberately won’t say
We did no live interception, so we don’t claim the mailbox runs plaintext on the wire today, only that the code accepts a tls:false redirect. We can’t see the server’s targeting logic. We never pulled the Google Play build. “Refuted” means absent in this build, not impossible forever.
The rumors that don’t survive the code
No always-on microphone, no server-triggered stealth call recording, no silent upload of your installed-app list, no hidden screenshot-and-send, no neural keyword listener (that engine existed in older builds and was pulled). Ruling these out is what makes the rest credible, and honestly, a Service built on MAX wouldn’t need any of them. An independent nine-week dynamic study of the earlier 26.12.0 build (InterSecLab) reached the same conservative conclusions on the big rumors: installed-app upload present but inactive, no silent call recording, contacts not hashed. Where the builds differ, we say so: InterSecLab observed a VPN send-block and an on-device call-audio detector in 26.12.0 that we find unarmed or removed by 26.31.0, a version change, not a disagreement.
The Proof
The story spends no time on smali class names; this is where they live. Each confirmed capability below traces to a specific chain in the decompiled code, drawn as a diagram and walked in prose, and closes with the raw citation into the decompiled client itself. A claim earns a place only if a specific file:line in the app backs it.
Move the connection: RECONNECT (opcode 3)
MAX’s main connection, the one carrying your login, messages and contacts, can be redirected by its own server to any address, with encryption switched off, without asking you. There’s no fallback address and no allow-list, and the change survives logging out.
The mailbox protocol has an opcode named RECONNECT (opcode 3). When one arrives, the handler runs a single check (is the host field empty?) and then overwrites its own connection target:
# k1k.smali onReconnect (payload parsed by z4f.smali) onReconnect(msg): if msg.redirectHost == "": return # the ONLY check - no allow-list mailbox.host = msg.redirectHost mailbox.port = msg.port mailbox.useTls = msg.tls # server may send false → TLS off # is9.b() saves host/port/useTls, clears state, then writes them back # → the redirect outlives logout
So: the server can move your whole connection to any host and turn encryption off, and it sticks across logout. We don’t claim the live mailbox speaks plaintext today, only that the client accepts and keeps a tls:false redirect to an unrestricted host. Read as charitably as possible, the redirect itself is ordinary plumbing: every messenger lets its server steer clients between gateways for load-balancing and failover. But a real failover names a fixed set of its own hosts and never switches the encryption off. This one does neither, and the setting outlives logout. Even at its most innocent, those three properties are the part no routine feature needs. And the redirect doesn’t stand alone: RECONNECT is one opcode on the same server command channel that also carries the per-account config flip (§3), an on-demand re-upload of your address book, and the location request (§5). Read it not as a lone feature but as the most dangerous entry on a bus of commands the operator can send a single phone. And RECONNECT isn’t even the only way in: a second, quieter lever lets the server move the client’s API connection through a hidden DNS–TXT record (appendix), with the same no-allow-list blind trust (milder, since it can relocate the connection but can’t strip encryption or survive a restart), yet the same defect a second time.
ru.oneme.app 26.31.0 (decompiled) · §1Replace the code: self-update, no app-side signature check
MAX can replace itself with any build the operator signs, from its own server, and MAX itself never checks that what arrived is genuinely its own code. (Android still enforces the signing key, so a build signed with a different key is refused; what’s missing is any app-side integrity check of MAX’s own.)
MAX’s own updater builds its download URL from a server-controlled template and installs whatever comes back, with no integrity check of its own on the way:
url = "https://download.max.ru/android/release/%vendor%/%abi%/MAX.apk" # server also sets the version: release-url, release-version (remote config) download(url) then PackageInstaller.install(apk) # system "install?" dialog # install path (kuf, n37, w17, adg, vu6) searched for: # MessageDigest · SHA-256 · GET_SIGNATURES · checkSignature · CertificatePinner # → none found
So: the only thing between a swapped APK and your phone is Android refusing a package signed with a different key. The store-signed forced-update path (Google Play, RuStore) is separate and keeps that protection; it’s this self-hosted path that skips it. (Ironically, MAX fingerprints itself at login: an anti-tamper check inside the oddly-named libqrcode.so hashes the app’s own signature and native libraries for the server, so a modified client can be spotted (appendix), yet no such check is applied to what its own updater installs.)
ru.oneme.app 26.31.0 (decompiled) · §2Rewrite the rules per account: PMS remote config
What the app does, and does to you specifically, can change the moment the operator chooses, with nothing on your phone standing in the way.
The remote-config channel (opcode 0x16, NOTIF_CONFIG) applies whatever the server sends, key by key, with no validation:
onConfig(payload): # opcode 0x16 → pxg.smali:1689 for key, value in payload: store[key] = value # no validation, no allow-list (455 flags) # every request already carries: deviceId · uid · GAID · locale # → the server CAN return a different map to one chosen phone
So: per-account targeting is possible from the client’s side: a feature can be switched on for one phone. What we can’t see is the server’s targeting logic; that isn’t in anything we pulled.
ru.oneme.app 26.31.0 (decompiled) · §3Watch without telling: the trace-flow.ru reporter
The app can fingerprint your connection and device and send it to a destination you’re never told about, and it can start doing this with no new version installed.
A reporter class ships disabled in the manifest, but Java builds and runs it the moment a remote flag flips:
# manifest: ru.trace_flow.dps.DpsInitProvider android:enabled="false" if config["dps"] == true: # AccountInitializer.smali:104 report = { ip, carrier, isVpn, deviceId, uid, reachableHosts, appVersion, ts } host = decodeXor(...) # nof.smali:179 → https://trace-flow.ru POST host + "/api/v1/report" (gzip json) # key hardcoded in the APK
So: the destination is XOR-hidden in the binary and never surfaced to the user, and two config keys (selfIpDetectionDomains, reachabilityHosts) let the server swap the host list without an update. And the destination’s certificate names VK: the TLS certificate trace-flow.ru presented in 2026 was issued to “VK LLC”, an organization-validated certificate, so the issuing authority checked that legal identity, which anyone can confirm in public certificate-transparency logs. (An OV certificate attests the named owner, not that VK runs every server behind the domain.) An independent nine-week study (InterSecLab) separately observed the reporter contacting home 19 times in 26 days.
ru.oneme.app 26.31.0 (decompiled) · §4Ask exactly where you are, on demand
The server can ask your phone for a GPS fix, live or one-shot, any moment it chooses, with no new consent screen at the time of the ask.
An inbound server message asks for a fix; the only gate is a permission that was granted at some point in the past:
onNotifLocationRequest(): # NOTIF_LOCATION_REQUEST (server opcode) if locationPermissionAlreadyGranted: reply(getGpsFix()) # live or one-shot # no fresh consent shown at the moment of the ask
So: this is separate from the “share live location” button you press yourself. We don’t claim it bypasses the Android permission, only that once that’s granted, the operator can pull a fix on its own schedule.
ru.oneme.app 26.31.0 (decompiled) · §5Bridge into government identity: the Mobile-ID handler
A web page running inside MAX can be allowed to make your phone perform a carrier-grade identity lookup and read the full, raw result, the same trick used for silent SIM authentication, with nothing on screen asking if that’s okay.
A mini-app only gets the privileged bridge if the server puts its bot-id on an allow-list that ships empty. Once it does, the page can run a carrier identity check and read the raw answer:
if config["webapp-pr"].contains(botId): # pqk.smali:608 - empty by default attach(PrivateWebViewHandler) # exposes the private bridge WebAppVerifyMobileId({requestId, url}): resp = rnk.get(url) # cellular-only (fails on Wi-Fi) = silent SIM auth page.eval(resp.status, resp.headers, base64(resp.body)) # no consent prompt
So: the cleartext allow-list for this bridge is carrier and government identity gateways: mobileid.megafon.ru, idgw.mobileid.mts.ru, nuc-cdp.digital.gov.ru, and more. The mini-app JS that drives it arrives from the server at runtime; we didn’t capture it.
ru.oneme.app 26.31.0 (decompiled) · §6No E2E, anywhere: text, voice and video held in the clear
Every message, voice note and video you send sits somewhere the operator can read, store, search and hand over; none of it is encrypted beyond the operator’s own reach.
There’s no secret-chat or Olm/Signal protocol anywhere in the tree, and the message body on the wire (MsgEdit.text) is a plain String, not a ciphertext blob. The clean proof needs no protobuf:
MAX ships a web client (web.max.ru) that logs into the same account, and a browser that just authenticated never held an end-to-end key, so for it to show your history the server has to hold the plaintext. Voice and video ride the same mailbox: the transcribe button (opcode 0xca) only works because the server already holds the raw media, and the transcription setting defaults on (though each note is transcribed only when you tap, not automatically).
The same gap cuts both ways. Because nothing cryptographically binds a message to its sender, the client has only the server’s word for who said what. A server that can read your inbox can therefore also write to it: inject a message that arrives attributed to any contact, rendered as genuine, with nothing on your phone able to tell the difference. This is not a “send-as” feature we found; it is the unavoidable consequence of no end-to-end encryption plus a server that relays every message. (We did no live interception; we claim the architecture permits it, not that it is happening.)
And the server isn’t a passive store. Every message you send carries a flag (detectShare, on by default) telling the server to inspect it for links and shared content, and the client does no link-parsing of its own, so it ships your plaintext plus an explicit “inspect this” instruction and lets the server find the links. (Signal does the opposite: it builds link previews on your device, so its server never sees the URL.) We can show the request to inspect and the missing client-side handling; what the server does with it downstream we can’t see from the binary.
ru.oneme.app 26.31.0 (decompiled) · §7Live calls: relayed, not provably intercepted
A group or relayed call is, to the operator, closer to a conference call it’s already routing, and two shipped features could turn that audio into text or render your face on its servers. We can’t prove either runs on any particular call.
For a group or relayed call the media runs through the operator’s server, not a direct phone-to-phone link. The call is encrypted with DTLS-SRTP, but MAX never turns on WebRTC’s end-to-end option (the SFrame/FrameEncryptor API ships yet is never wired), so on a relayed leg the encryption terminates at the server, which holds the keys and can decode the audio and video. (A one-to-one call may stay peer-to-peer.) Two shipped features could lean on that:
request-asr {start:true} → AsrOnlineChunk(participantId, text) # live captions, server-side
animojiBackendRender : set by the call's server config # face model runs server-side
# enableAsrOnline has ZERO callers in MAX's own code - it fires only
# from the bundled VK/OK call SDK (no user toggle). BUT an on-device
# engine (libEnhancementLibShared.so) can do the SAME job locally -
# we did NOT prove which path a real call takes.
So: MAX group calls relay through the operator’s servers, and because no end-to-end layer is wired, those servers terminate the encryption and can read the media. Which calls take the relay path rather than staying peer-to-peer, and whether server-side captions or animoji run on any given one, we could not settle from the binary, and no live call was captured this pass. The operator can read a relayed call; we have not proven it does on a specific one.
ru.oneme.app 26.31.0 (decompiled) · §8Every Other Claim, in Brief
The eight proofs above are the headline capabilities. The remaining claims cleared the same bar: a row exists only if a specific line backs it. Confirmed safe to publish as fact; Narrowed there’s a true core, but the popular version exaggerates it; Refuted not true in this build.
| Claim | What the code shows | Cite | Verdict |
|---|---|---|---|
| Second reroute lever (hidden DNS record) | Besides RECONNECT, the client will take a hidden Google-DNS TXT record and make whatever address it names its API server, with no allow-list on where that points. Weaker than RECONNECT: API host only, can’t switch encryption off, forgotten on restart, and only while the app is still on its built-in default address. The server flag it was reported to need is declared in the code but never read. Lead: zarazaex69/m, re-derived by us. | decompiled client · §1 | Confirmed |
| Login-time self-integrity check | At each login the app fingerprints its own signing certificate and native libraries and sends the result with the login, so the server can detect a modified or repackaged client. An anti-tamper mechanism, not surveillance; the accept-or-reject decision sits on the server, which we can’t see. Lead: owenewans, Habr (item 16), re-derived by us. | decompiled client | Confirmed |
| Every message flagged for server-side inspection | Each message you send carries a detectShare flag (on by default) telling the server to scan it for links and shared content; the client does no link-parsing itself, so it sends plaintext plus the inspect instruction, the opposite of on-device preview. We show the request-to-inspect, not what the server does with it. Lead: InterSecLab, re-derived by us. | decompiled client · §7 | Confirmed |
| Whole contact book uploaded | Address book incl. non-users uploaded at login; server can re-trigger a sync. Not a covert always-on loop; the UI admits it. | decompiled client | Confirmed |
| Public IP echoed home | Queries five “what’s my IP” services on open and uploads the answer on the telemetry pipe. | decompiled client · §4 | Confirmed |
| Google Advertising ID at login | Login fetches and sends your GAID unless Limit Ad Tracking is on or the id is empty. | decompiled client | Confirmed |
| deviceId = ANDROID_ID | Every login round-trip carries a user-agent string and the device’s ANDROID_ID. | decompiled client | Confirmed |
| Root / Magisk fingerprinting | Detects root/Magisk/emulator and uploads the flag with crash and ad telemetry; does not block login. | decompiled client | Confirmed |
| VPN detection & reporting | Detects a VPN transport, reports vpn=1, can nag the UI, but does not hard-lock chats. | decompiled client · §4 | Narrowed |
| Transcription on by default | Server-side transcription of voice/video notes: the setting ships default-enabled, but each note is transcribed on a user tap, not automatically (needs the server to hold the raw media). | decompiled client · §7 | Confirmed |
| Daily permission census | Background worker reports the live state of every sensitive permission, whether in use or idle. | decompiled client | Confirmed |
| Immediate permission-flip logging | Toggling a permission in Android settings is logged the moment it changes. | decompiled client | Confirmed |
| Search queries logged | What you type into in-app search rides the telemetry pipe, not just the result you tap. | decompiled client | Confirmed |
| Contact-vs-stranger counters | Server-side presence counters already distinguish whether a sender is in your contacts. | decompiled client | Confirmed |
| Battery / CPU / thermal census | Device-performance telemetry collected alongside the rest of analytics. | decompiled client | Confirmed |
| Digital-ID NFC service | A genuine exported NFC host-card-emulation service, not a mock. | decompiled client · §6 | Confirmed |
| Mini-app bridge platform | Real opcode launch, a public JS bridge we pulled, phone-number share to a bot, and every bridge call telemetered. | decompiled client · §6 | Confirmed |
| ML model push (ZipSlip) | Server can push a new noise-suppression model; the unzip step has a path-traversal bug and the server supplies both file and checksum. | decompiled client | Confirmed |
| Full installed-app list uploaded | Reported by an earlier code analysis; in the build we decompiled (26.31.0) the MyTracker enumeration hook is present but unwired: no class implements it, nothing calls it, and there is no QUERY_ALL_PACKAGES permission, so this build uploads no app list. The bundled SDK could do it; a different build could wire it. | decompiled client | Refuted (this build) |
| Silent server-triggered call recording | Inbound dispatcher (~49 commands) has no “collect the mic” case; every mic-dump function has zero callers. Real feature is a user-started, notified recorder. | decompiled client | Refuted |
| Stealth chat screenshots | FLAG_SECURE blocks your screenshots on protected chats; it does not take and upload one. | decompiled client | Refuted |
| Hidden keyword listener (KWS) | Native engine present but zero Java arms it and the library can’t reach the network; the model was removed two versions back. | decompiled client | Refuted |
| Dynamic remote code loading | Zero DexClassLoader-family calls; short of the full app-swap, no new executable code loads from the network. | decompiled client | Refuted |
Across the full review: 32 confirmed, 6 narrowed, 5 refuted: 43 claims, each checked against the decompiled client.