12 KiB
Real Racing 3 - Network Communication Analysis
Overview
Real Racing 3 uses a custom HTTP/HTTPS-based communication system built on top of EA's proprietary "CloudCell API" and "Nimble SDK" frameworks. The app communicates with EA's backend servers using JSON over HTTPS with custom authentication headers.
1. Core Network Architecture
1.1 HTTP Request System
Location: com.firemonkeys.cloudcellapi.HttpRequest and HttpThread
Key Components:
- HttpRequest: Main request manager with native JNI callbacks
- HttpThread: Worker thread that executes the actual HTTP operations
- CloudcellTrustManager: Custom SSL/TLS certificate validation
Implementation Details:
// Request initialization from native code
public void init(String userAgent, String method, String url,
byte[] data, int readCapacity, long callbackPointer,
boolean failOnError, double serverTime,
boolean sslCheck, boolean addDefaultHeaders,
int timeoutSeconds)
Key Features:
- Uses
HttpURLConnection(standard Java HTTP client) - Wrapped with Firebase Performance monitoring (
FirebasePerfUrlConnection) - Custom user agent combining app version + system HTTP agent
- SSL/TLS 1.2+ with custom certificate validation
- Native callbacks for data streaming (header, data, error, complete)
- Configurable timeouts (default: 30 seconds)
- Support for HTTP methods: GET, POST, PUT, DELETE
1.2 SSL/TLS Configuration
Location: com.firemonkeys.cloudcellapi.CloudcellTrustManager & TLSSocketFactory
Security Setup:
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, new TrustManager[]{new CloudcellTrustManager(this)}, new SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(new TLSSocketFactory(sslContext.getSocketFactory()));
HttpsURLConnection.setDefaultHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
Certificate Validation:
- Custom X509TrustManager implementation
- Validates certificate expiration against server-provided time
- Can be optionally disabled (m_bSSLCheck flag)
- NOTE: Uses
ALLOW_ALL_HOSTNAME_VERIFIER(accepts any hostname!)
2. Server Infrastructure
2.1 Primary API Servers
Synergy Director Servers (EA's service orchestration layer):
- Production (LIVE):
https://syn-dir.sn.eamobile.com - Staging:
https://director-stage.sn.eamobile.com - Integration (INT):
https://director-int.sn.eamobile.com
The "Director" server provides configuration that routes the client to specialized service endpoints.
2.2 Network Reachability Test URLs
Located in EA Nimble SDK:
- Primary:
https://ping1.tnt-ea.com - Backup:
https://www.google.com
Used to detect if the device has internet connectivity before making API calls.
2.3 API Endpoint Structure
Base Pattern: https://<director-host>/<service>/api/<platform>/<endpoint>
Example Endpoints:
| Endpoint Path | Purpose |
|---|---|
/director/api/android/getDirectionByPackage |
Get service configuration/routing |
/user/api/android/getDeviceID |
Retrieve unique device ID |
/user/api/android/validateDeviceID |
Validate existing device ID |
/user/api/android/getAnonUid |
Generate anonymous user ID |
/product/api/core/getAvailableItems |
Fetch in-game item catalog |
/product/api/core/getMTXGameCategories |
Get microtransaction categories |
/product/api/core/getDownloadItemUrl |
Get download URLs for assets |
/drm/api/core/getNonce |
Get DRM nonce for validation |
/drm/api/core/getPurchasedItems |
Retrieve purchase history |
/drm/api/android/verifyAndRecordPurchase |
Verify and record IAP purchases |
/tracking/api/core/logEvent |
Submit analytics/telemetry events |
3. Authentication & Authorization
3.1 HTTP Headers
Standard Headers:
User-Agent:<AppIdentifier> <SystemHttpAgent>Content-Type:application/jsonorapplication/x-www-form-urlencodedContent-Length: Auto-calculated for POST/PUT requests
EA Custom Headers (from Nimble SDK):
EAM-SESSION: Session ID (UUID generated per app session)EAM-USER-ID: Synergy user ID (persistent user identifier)EA-SELL-ID: Marketplace/seller ID (e.g., Google Play, App Store)SDK-VERSION: EA Nimble SDK version stringSDK-TYPE: "Nimble" (framework identifier)
3.2 Device & User Identification
Multiple ID Types Used:
-
EA Device ID (
eADeviceId)- Generated on first launch
- Persisted in shared preferences
- Used for device-level tracking
-
EA Hardware ID (
eAHardwareId)- Derived from device hardware characteristics
- More persistent than device ID
-
Synergy ID
- Primary user account identifier
- Links game progress across devices
- Required for cloud save/sync
-
Anonymous UID
- Fallback identifier for users without accounts
- Used for analytics before login
-
Google/Facebook OAuth Tokens
- For social login integration
- Google Web Client ID:
1056053393768-2irtr6olub9uil5dsp16apf9p5f0ge0k.apps.googleusercontent.com
3.3 Session Management
Session Flow:
- App launches → Generate session UUID
- Contact Director server → Get service configuration
- Retrieve/validate device ID → Get or create EA Device ID
- Initialize Synergy session → Get session token
- Attach
EAM-SESSIONheader to all subsequent requests
Session Properties:
- Session IDs are UUIDs (e.g.,
f47ac10b-58cc-4372-a567-0e02b2c3d479) - Sessions expire after inactivity period (server-controlled)
- Session data cached locally and synced to server
4. Request/Response Format
4.1 JSON Serialization
- Request bodies: JSON with entity/DTO objects
- Response bodies: JSON parsed into native objects
- Uses Jackson/Gson for JSON serialization (standard Android libraries)
4.2 Protocol Buffers (for Unity Ads SDK)
Location: gatewayprotocol.v1 package
Message Types:
UniversalRequest/UniversalResponse- Main protocol wrapperInitializationRequest/InitializationResponse- SDK init handshakeAdRequest/AdResponse- Ad servingTransactionEventRequest- Purchase trackingDiagnosticEventRequest- Telemetry/diagnosticsLimitedSessionToken- Temporary auth tokens
Uses Protocol Buffers v3 (Google protobuf library).
4.3 Example Request Structure
Typical POST Request:
POST /user/api/android/getDeviceID HTTP/1.1
Host: syn-dir.sn.eamobile.com
User-Agent: RealRacing3/12.5.0 Android/14
Content-Type: application/json
Content-Length: 128
EAM-SESSION: f47ac10b-58cc-4372-a567-0e02b2c3d479
EAM-USER-ID: 1234567890
EA-SELL-ID: GOOGLE_PLAY
SDK-VERSION: 5.2.1
SDK-TYPE: Nimble
{
"deviceId": "abc123...",
"hardwareId": "xyz789...",
"platform": "android",
"appVersion": "12.5.0"
}
5. Data Flow & Callbacks
5.1 Native Interface (JNI)
The HTTP layer bridges Java and native C++ code:
Native Callbacks (from HttpRequest.java):
public native void headerCallback(long callbackPtr, int contentLength, Map<String, List<String>> headers);
public native void dataCallback(long callbackPtr, byte[] data, int length);
public native void errorCallback(long callbackPtr, int statusCode);
public native void completeCallback(long callbackPtr, int statusCode);
Flow:
- Native C++ code calls
HttpRequest.init()with callback pointer HttpThreadexecutes HTTP request in background- As data streams in, Java calls native callbacks with data chunks
- Native code processes response in real-time
- On completion, native code receives final status
5.2 Streaming Response Handling
Read Strategy:
- Configurable read buffer size (
m_readCapacity) - Data streamed in chunks to native callback
- Supports both success and error stream reading
- Interruptible for cancellation support
byte[] buffer = new byte[readCapacity];
while (true) {
int bytesRead = inputStream.read(buffer);
if (bytesRead == -1) break;
if (isInterrupted()) return;
dataCallback(callbackPointer, buffer, bytesRead);
}
6. Network Configuration
6.1 Timeout Settings
- Default Connection Timeout: 30 seconds (30,000 ms)
- Default Read Timeout: 30 seconds
- Configurable per request via
m_TimeoutMilliseconds
6.2 Connection Properties
httpURLConnection.setConnectTimeout(timeoutMilliseconds);
httpURLConnection.setReadTimeout(timeoutMilliseconds);
httpURLConnection.setUseCaches(false); // No HTTP caching
httpURLConnection.setDoInput(true);
System.setProperty("http.keepAlive", "false"); // Disable keep-alive
Note: Keep-alive is disabled, so each request creates a new TCP connection.
6.3 Request Method Support
- GET (query parameters in URL)
- POST (JSON body)
- PUT (JSON body)
- DELETE
- Custom methods supported via
setRequestMethod()
7. Error Handling
7.1 HTTP Status Code Handling
Success Codes (200-299):
- Data read from
inputStream - Parsed and passed to native callback
Error Codes (400-599):
- Data read from
errorStream - Can still contain JSON error messages
- Optional
failOnErrorStatusflag to abort immediately
Network Errors:
- IOException →
errorCallbackwith status code 0 - Timeout →
errorCallbackwith status code 0 - SSL/Certificate errors → Custom handling in
CloudcellTrustManager
7.2 SSL Certificate Expiration Check
public void checkServerTrusted(X509Certificate[] certificates, String authType) {
if (sslCheckEnabled) {
Date serverDate = new Date(serverTime * 1000);
for (X509Certificate cert : certificates) {
if (cert.getNotAfter().before(serverDate)) {
setClosedBySSLCheck(true);
closeThread();
logError("SSL Certificate expired!");
}
}
}
}
Uses server-provided time to validate certificates (prevents time manipulation).
8. Additional Features
8.1 Network Status Monitoring
Location: com.firemonkeys.cloudcellapi.NetworkStatusMonitor
Monitors network connectivity changes (Wi-Fi ↔ Mobile Data) to handle disconnections gracefully.
8.2 In-App Purchase (IAP) Integration
Google Play Billing:
GooglePlayWorkerhandles Play Store transactions- Purchase verification via
/drm/api/android/verifyAndRecordPurchase - Receipt validation server-side
Amazon Store:
CC_AmazonStoreWorker_Classfor Amazon App Store- Similar server-side verification flow
8.3 Social Platform Integration
Google Play Games:
- OAuth 2.0 with scope
https://www.googleapis.com/auth/games - Achievement unlock API:
https://www.googleapis.com/games/v1management/achievements/reset
Facebook:
- Graph API for friends list, sharing, profile
FacebookWorkerhandles login/sharing flows
9. Security Considerations
9.1 Vulnerabilities Observed
⚠️ Certificate Hostname Verification Disabled:
HttpsURLConnection.setDefaultHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
This accepts any SSL certificate hostname, making the app vulnerable to MITM attacks.
⚠️ Optional SSL Checks:
The m_bSSLCheck flag can disable certificate validation entirely.
⚠️ Keep-Alive Disabled: Creates overhead but may be intentional to avoid connection state issues.
9.2 Security Strengths
✅ TLS Encryption: All API calls use HTTPS ✅ Custom Certificate Validation: Time-based expiration checks ✅ Session Tokens: Short-lived session identifiers ✅ Server-Side Purchase Verification: IAP receipts validated by EA servers ✅ Firebase Performance Monitoring: Instrumented connections for anomaly detection
10. Summary
Communication Pattern:
[App Native Code]
↕ (JNI)
[Java HttpRequest/HttpThread]
↕ (HTTPS)
[EA Synergy Director]
↕ (Service Routing)
[Specialized Service APIs]
Key Takeaways:
- Uses standard Java
HttpURLConnectionwith custom SSL handling - Native C++ game code interfaces via JNI callbacks for async I/O
- EA Synergy "Director" pattern routes requests to microservices
- Authentication via custom headers (session ID, user ID)
- JSON for API requests, Protocol Buffers for ad SDK
- Streaming response handling with configurable buffer sizes
- Firebase Performance wrappers for monitoring
- Weak SSL hostname verification (security concern)
Analysis Date: February 2026
APK Version: Real Racing 3 (v12.5+)
Decompiler: JADX 1.5.1