This document provides an institutional-grade, corner-to-corner technical breakdown of MaybeScanner's architecture, subsystems, memory management, and network security profiles.
MaybeScanner is designed as a hybrid Android application that leverages a highly responsive programmatic Java UI and a high-performance, concurrent Go scanning engine (go-sidecar).
graph TD
A[Android Main UI Thread] -->|Launches Scan| B[Scan Orchestrator Thread]
B -->|Instantiates| C[Thread Pool Executor]
C -->|Concurrent Workers| D[Socket Probe Engine]
D -->|Nested try-with-resources| E[Raw TCP Connect]
E -->|Upgrade| F[uTLS SSL Handshake]
B -->|Diagnostic Commands| G[Shizuku Service Connection]
G -->|Type-safe Binder| H[ITelephony AIDL Proxy]
G -->|Thread Pool Execution| I[settings global put]
MaybeScanner shares low-level contracts and diagnostic boundaries with its sibling project, MaybeEdgeScanner, but the products intentionally differ at the default workflow:
- MaybeScanner is an IP-first target scanner. It audits explicit user targets. Literal IP scans are no-SNI unless the user enables an advanced override.
- MaybeEdgeScanner owns explicit IP/SNI/HTTP Host/route pairing and provider-route comparison workflows.
To prevent socket and file descriptor leaks under heavy parallel scanning loads (processing thousands of subnets with up to 128 threads), the scanning client uses a nested, secure try-with-resources architecture:
// Outer try block guarantees raw TCP socket cleanup on any exception
try (Socket raw = new Socket()) {
long connectStart = System.currentTimeMillis();
raw.connect(new InetSocketAddress(ip, port), timeout);
tcpPass = true;
tcpLatencyMs = System.currentTimeMillis() - connectStart;
raw.setSoTimeout(timeout);
// Inner try block upgrades the raw TCP socket and guarantees SSL socket cleanup
try (SSLSocket ssl = (SSLSocket) ((SSLSocketFactory) SSLSocketFactory.getDefault())
.createSocket(raw, host, port, true)) {
ssl.setSoTimeout(timeout);
configureTlsSocket(ssl, activeMode, false);
ssl.startHandshake();
// Extract metrics and certificates safely
tlsPass = true;
tlsLatencyMs = System.currentTimeMillis() - t;
tlsVersion = ssl.getSession().getProtocol();
tlsCipher = ssl.getSession().getCipherSuite();
alpn = selectedAlpn(ssl);
Certificate[] certs = ssl.getSession().getPeerCertificates();
if (certs.length > 0 && certs[0] instanceof X509Certificate) {
X509Certificate c = (X509Certificate) certs[0];
tlsCert = c.getSubjectX500Principal().getName();
certFingerprint = sha256(c.getEncoded());
}
}
} catch (Exception e) {
reason = classify(e);
}- Guaranteed Cleanup: If the raw TCP connection succeeds (
raw.connect()completes) but the subsequent SSL handshake, certificate parsing, or ALPN selection throws an exception, the outertryblock ensuresraw.close()is called implicitly, returning the file descriptor to the OS immediately. - Auto-Close Upgrades: Decorating the raw socket inside
createSocket(..., true)flagsautoClose = true. Consequently, closing the upgradedSSLSocketautomatically triggers the teardown of the underlying TCP socket.
MaybeScanner incorporates a type-safe privileged subsystem using Shizuku to communicate with the Android OS baseband services.
[Android ServiceManager] ---> Maps IBinder for "phone"
│
▼
[ITelephony$Stub.asInterface] ---> Maps type-safe ITelephony Binder Proxy
│
▼
[PrivilegedTelephonyBasebandManager] ---> Asynchronously mutates network types on Worker Thread
Rather than executing raw shell scripts (which introduces parsing errors, string manipulation bottlenecks, and potential command injections), the app accesses the internal phone service directly using compile-time checked AIDL interfaces:
package com.android.internal.telephony;
interface ITelephony {
boolean setPreferredNetworkType(int subId, int networkType);
int getPreferredNetworkType(int subId);
}All privileged radio mutations and Shizuku process forks are offloaded from the main UI thread to prevent Application Not Responding (ANR) flags:
- Spawns settings and shell modifications inside Android's global
AsyncTask.THREAD_POOL_EXECUTOR. - Bundles multiple setting alterations into a single shell execution script (
settings put global key value ; settings put ...), reducing kernel context switches to a single invocation.
The user interface of MaybeScanner is programmatically generated in pure Java to maintain extreme responsiveness and high layout densities.
- Dynamic Tab Transitions: Uses three independent, isolated
ScrollViewcontainers (targetScroll,liveScroll,diagnosticsScroll) in a centralFrameLayoutcontentContainerbetween the pinned top header and bottom navigation bar. Tab selection toggles visibility (VISIBLE/GONE) directly with smooth alpha fade animations, preserving scroll position. - Resilience to Resizing: Standardizes programmatic height metrics to use
wrap_contentor layout weight rather than absolute pixel bounds. This guarantees flawless rendering under:- Multi-window split-screen resizes.
- Folding phone screen expansions.
- System font size overrides and accessibility scaling.
- Single-Physical-Pixel Borders: On high-DPI screens, cards are bordered with exactly
1physical pixel (1.0f / resources.getDisplayMetrics().density) with a low-opacity white stroke to construct an ultra-premium glassmorphic outline. - Micro-Animations: Toggle events utilize
TransitionManager.beginDelayedTransitionto animate arrow rotations (0f->180f) and card height expansions smoothly. - Haptic Click Profiles: Taps on card titles and operation buttons trigger context haptics (
HapticFeedbackConstants.CONTEXT_CLICK) and touch-scale scaling (0.98f) for physical feedback.
The companion Go sidecar includes a robust suite of defenses:
- Provider Classification Index: The current implementation uses a pointer-linked prefix helper protected by ordinary synchronization. It is a best-effort result annotation, not a lock-free arena-backed routing primitive.
- Compact dedup maps: Evaluates IP targets as compact
map[[16]byte]boolsets rather than repeated string operations (.String()), reducing heap churn during expansion. This is not a lock-free routing or prefix-index claim. - Rolling Read/Write Deadlines: Prevents slow-rate socket exhaustion by enforcing dynamic socket deadlines:
_ = conn.SetReadDeadline(time.Now().Add(750 * time.Millisecond))
- Adaptive Backoff Scoping: Binds the error ring-buffer outside of individual scanning batch loops. This preserves accurate, long-term latency contexts and protects upstream services from load spikes.
When the user exits the scanning utility, background work must terminate instantly. We enforce this inside onDestroy():
@Override
protected void onDestroy() {
super.onDestroy();
stop.set(true);
if (executor != null) {
executor.shutdownNow(); // Interrupts active scan workers
}
if (previewExecutor != null) {
previewExecutor.shutdownNow(); // Cleans up target resolution pools
}
}By defining android:launchMode="singleTop" on MainActivity and overriding onNewIntent(Intent), we route all widget click actions and tile activations into the existing activity instance. This avoids launching redundant application instances and maintains scanning telemetry session state.
To preserve UI smoothness while displaying and filtering massive logs generated by high-speed concurrent scans:
- Thread-Safe Filter Lock: Log appending operates concurrently with the search text input. In
refreshLogViewDirect(), we capture the filter query, and then synchronize on the shared list:This prevents concurrent modification exceptions while the background scan threads append tosynchronized (logLines) { for (String x : logLines) { if (x.toLowerCase(Locale.US).contains(filter)) { sb.append(x).append('\n'); } } }
logLines. - Dedicated Diagnostic Thread: Triggering the Network Diagnostic Suite spawns a custom named thread
network-diagnostic-threadwhich performs blocking latency queries (DNS lookups, socket connects, HTTPS requests) without pausing Android's Main Looper (UI thread), thus preventing Application Not Responding (ANR) dialogs. Results are safely updated on the UI viaui.post(...)handlers.