MajorLogin / main.py
EvilTw's picture
Create main.py
3ef9d68 verified
Raw History Blame Contribute Delete
7.43 kB
"""
Free Fire Mock Server
Mimics Garena auth endpoints, captures and logs all requests.
Usage: python mock_server.py
"""
from flask import Flask, request, jsonify, Response
import json
import time
import hashlib
import random
app = Flask(__name__)
# ─── Fake data generators ─────────────────────────────────────────────────────
def fake_access_token():
return hashlib.sha256(str(random.random()).encode()).hexdigest()
def fake_open_id():
return hashlib.md5(str(random.random()).encode()).hexdigest()
def fake_refresh_token():
return hashlib.sha256(str(random.random() + 1).encode()).hexdigest()
def fake_uid():
return random.randint(4000000000, 5000000000)
# ─── Request logger ───────────────────────────────────────────────────────────
def log_request(endpoint):
print("\n" + "=" * 60)
print(f" [REQUEST] {endpoint}")
print(f" Method : {request.method}")
print(f" From : {request.remote_addr}")
print(f" Time : {time.strftime('%Y-%m-%d %H:%M:%S')}")
print("\n --- Headers ---")
for k, v in request.headers:
print(f" {k}: {v}")
print("\n --- Body (raw) ---")
raw = request.get_data()
print(f" {raw}")
print("\n --- Body (hex) ---")
print(f" {raw.hex()}")
if request.content_type and 'application/x-www-form-urlencoded' in request.content_type:
print("\n --- Form Fields ---")
for k, v in request.form.items():
print(f" {k}: {v}")
print("=" * 60)
# ─── Endpoint 1: Token Grant ──────────────────────────────────────────────────
@app.route('/oauth/guest/token/grant', methods=['POST'])
def token_grant():
log_request("/oauth/guest/token/grant")
now = int(time.time())
response = {
"refresh_expiry_time": now + 2592000,
"expiry_time": now + 1296000,
"uid": fake_uid(),
"open_id": fake_open_id(),
"access_token": fake_access_token(),
"main_active_platform": 4,
"expires_in": 1296000,
"token_type": "Bearer",
"platform": 4,
"create_time": now,
"scope": ["get_user_info", "get_friends", "payment", "send_request"],
"refresh_token": fake_refresh_token(),
}
print(f"\n [RESPONSE] {json.dumps(response, indent=2)}")
return jsonify(response), 200
# ─── Endpoint 2: MajorLogin ───────────────────────────────────────────────────
# Returns a minimal valid protobuf-like response (raw bytes)
# Field 4 = token (JWT-like string), field 10 = url, field 3 = account_uid
def build_fake_major_login_response():
"""
Build a minimal fake protobuf response that matches MajorLoginRes.
Fields based on what DecRypTMajoRLoGin reads:
field 4 = token (string)
field 10 = url (string)
field 3 = account_uid (varint)
"""
fake_token = (
"eyJhbGciOiJIUzI1NiIsInN2ciI6IjMiLCJ0eXAiOiJKV1QifQ"
".eyJhY2NvdW50X2lkIjoxNzU1NjA2MzU1MSwibmlja25hbWUiOiJNb2NrVXNlciIsInJlZ2lvbiI6IklORCJ9"
".FAKE_SIGNATURE"
)
fake_url = "http://127.0.0.1:5000" # point back to this mock server
fake_uid_val = 17556063551
def encode_varint(n):
result = bytearray()
while n:
b = n & 0x7F
n >>= 7
result.append(b | (0x80 if n else 0))
return bytes(result)
def encode_string_field(field_number, value):
b = value.encode()
return encode_varint((field_number << 3) | 2) + encode_varint(len(b)) + b
def encode_varint_field(field_number, value):
return encode_varint((field_number << 3) | 0) + encode_varint(value)
payload = encode_varint_field(3, fake_uid_val) # account_uid
payload += encode_string_field(4, fake_token) # token
payload += encode_string_field(10, fake_url) # url
return payload
@app.route('/MajorLogin', methods=['POST'])
def major_login():
log_request("/MajorLogin")
response_bytes = build_fake_major_login_response()
print(f"\n [RESPONSE] Raw bytes: {response_bytes}")
print(f" [RESPONSE] Hex: {response_bytes.hex()}")
return Response(response_bytes, status=200, mimetype='application/octet-stream')
# ─── Endpoint 3: GetLoginData ─────────────────────────────────────────────────
def build_fake_login_data_response():
"""
Build a minimal fake protobuf response that matches GetLoginData.
Fields:
Online_IP_Port = string
AccountIP_Port = string
AccountName = string
"""
def encode_varint(n):
result = bytearray()
while n:
b = n & 0x7F
n >>= 7
result.append(b | (0x80 if n else 0))
return bytes(result)
def encode_string_field(field_number, value):
b = value.encode()
return encode_varint((field_number << 3) | 2) + encode_varint(len(b)) + b
# Field numbers based on what DecRypTLoGinDaTa reads
payload = encode_string_field(14, "127.0.0.1:39698") # Online_IP_Port
payload += encode_string_field(16, "127.0.0.1:39800") # AccountIP_Port
payload += encode_string_field(6, "MockPlayer") # AccountName
return payload
@app.route('/GetLoginData', methods=['POST'])
def get_login_data():
log_request("/GetLoginData")
response_bytes = build_fake_login_data_response()
print(f"\n [RESPONSE] Raw bytes: {response_bytes}")
print(f" [RESPONSE] Hex: {response_bytes.hex()}")
return Response(response_bytes, status=200, mimetype='application/octet-stream')
# ─── Catch-all for any other endpoints ───────────────────────────────────────
@app.route('/', defaults={'path': ''}, methods=['GET', 'POST', 'PUT', 'DELETE'])
@app.route('/<path:path>', methods=['GET', 'POST', 'PUT', 'DELETE'])
def catch_all(path):
log_request(f"/{path} [UNHANDLED]")
return jsonify({"status": "captured", "path": path}), 200
# ─── Main ─────────────────────────────────────────────────────────────────────
if __name__ == '__main__':
print("=" * 60)
print(" Free Fire Mock Server")
print("=" * 60)
print(" Listening on http://0.0.0.0:5000")
print()
print(" Mocked endpoints:")
print(" POST /oauth/guest/token/grant -> token grant")
print(" POST /MajorLogin -> major login")
print(" POST /GetLoginData -> login data")
print()
print(" To redirect traffic, edit /etc/hosts or point")
print(" your script's URLs to http://127.0.0.1:5000")
print("=" * 60)
app.run(host='0.0.0.0', port=5000, debug=True)