
TRANSFORMERS: Forged to Fight एक 3D युद्ध खेल है जहाँ आप ट्रांसफॉर्मर्स ब्रह्मांड के सबसे करिश्माई सैनिकों में से कुछ को नियंत्रित करते हैं। हम ऑप्टिमस प्राइम, मेगाट्रॉन, बम्बलबी, रैचेट, साउंडवेव और ग्रिंडर जैसे बड़े नामों की बात कर रहे हैं। हाँ, आपने सही पढ़ा। किसी भी ट्रांसफॉर्मर्स के आपके पसंदीदा पात्र
यह पैकेज ट्रांसफॉर्मर्स: फोर्ज्ड टू फाइट का एक कार्यशील ऑफलाइन बूट प्रदान करता है, साथ ही वहाँ तक पहुँचने के लिए उपयोग किए गए सभी उपकरण, पैच और रिवर्स इंजीनियरिंग नोट्स भी शामिल हैं। इसका उद्देश्य उस व्यक्ति द्वारा उठाया जाना है जिसके पास अगला और बहुत बड़ा कदम उठाने के लिए समय और ऊर्जा है, जो खेल के सर्वर साइड कंटेंट को शुरू से फिर से बनाना है। यहाँ सब कुछ दस्तावेजीकृत है ताकि आपको उस तरह से शून्य से शुरू न करना पड़े जैसा मैंने किया।
कुछ भी छूने से पहले इस पूरी फ़ाइल को पढ़ लें। विशेष रूप से "गॉटचास" अनुभाग आपके दिन बचाएगा।
गेम पूरी तरह से ऑफलाइन बूट होता है और बिना किसी लाइव सर्वर के अपने वास्तविक इंटरैक्टिव होम स्क्रीन तक पहुँचता है। होम स्क्रीन से मेनू बिना क्रैश हुए नेविगेट करते हैं: बेस, बॉट्स रोस्टर (खाते में एक स्वामित्व वाले बॉट के साथ), फाइट मोड सेलेक्ट, क्रिस्टल्स स्क्रीन, और सामान्य पॉपअप और टिप्स। पूर्ण लॉगिन प्रवाह पूरा होता है, प्रत्येक ऑनलाइन सबसिस्टम कनेक्ट होता है, और पहली बार अनुभव और ट्यूटोरियल गेट्स साफ़ हो जाते हैं। स्क्रिप्टेड इंट्रो फाइट (ऑप्टिमस बनाम स्टार्सक्रीम) लड़ाई को लोड करना शुरू करने के लिए पर्याप्त दूर तक भी पहुँच जाती है, और 3D कैरेक्टर मॉडल रेंडर और एनिमेट होते हैं। यह कठिन हिस्सा था और यह हल हो गया है। क्लाइंट स्वयं अब ऑफलाइन फिर से जीवित है।
वास्तविक गेमप्ले काम नहीं करता। स्टोरी कोई मिशन नहीं दिखाती, और लड़ाई पूरी तरह से लोड नहीं हो सकती। यह कोई बग नहीं है और यह ऐसी चीज़ नहीं है जिसे पैच ठीक कर सके।
फोर्ज्ड टू फाइट पूरी तरह से सर्वर अथॉरिटेटिव था। फोन पर ऐप मूल रूप से नियंत्रणों वाली एक स्क्रीन है। खेल के बारे में लगभग कुछ भी ऐप में नहीं रहता था। हर मिशन, हर लड़ाई, हर दुश्मन की लाइनअप, पूरे रोस्टर के आँकड़े और क्षमताएँ, अर्थव्यवस्था, और सभी संतुलन काबम के सर्वर पर रहते थे और प्रत्येक सत्र में डिवाइस पर स्ट्रीम किए जाते थे। जब 2020 की शुरुआत में सर्वर बंद कर दिए गए, तो वह सामग्री डेटाबेस उनके साथ चला गया, और इसे कभी भी जारी या सार्वजनिक रूप से संग्रहीत नहीं किया गया जहाँ तक मैं पहुँच सकता हूँ।
तो स्थिति स्पष्ट रूप से दो भागों में विभाजित है। कला और ऑडियो बच गए, क्योंकि वे ऐप के अंदर भेजे जाते हैं (देखें re_notes/ASSET_INVENTORY.txt)। प्रत्येक पात्र मॉडल, टेक्सचर, रिग, एनिमेशन क्लिप्स, एनिमेटर कंट्रोलर, प्रभाव और ऑडियो वाला एक पूर्ण यूनिटी एसेट बंडल है। वातावरण, इमारतें, UI, पोर्ट्रेट, कटसीन और संवाद भी सब वहाँ हैं। जो नहीं बचा वह डेटा था जो गेम को बताता था कि उनमें से किन एसेट्स का उपयोग करना है, उन्हें एक लड़ाई या मिशन में कैसे इकट्ठा करना है, और प्रत्येक बॉट की संख्या वास्तव में क्या थी। सभी टुकड़े मौजूद हैं। बस कुछ भी नहीं बचा है जो जानता हो कि उन्हें एक साथ कैसे रखा जाए। उसे फिर से बनाना ही पूरा काम है जो बाकी है।
चार चलने वाले भाग हैं। एक साथ वे अपरिवर्तित गेम को यह सोचने देते हैं कि वह काबम से बात कर रहा है।
नेटिव बाइनरी पैच। गेम यूनिटी IL2CPP है, इसलिए तर्क एक संकलित ARM लाइब्रेरी, libil2cpp.so में रहता है, संपादन योग्य स्क्रिप्ट फ़ाइलों में नहीं। patches/patch_il2cpp.py उस लाइब्रेरी में छह फ़ंक्शन को फिर से लिखता है ताकि मृत सर्वर जाँचों से बचा जा सके: यह दो सर्टिफिकेट पिनिंग पथों को पराजित करता है ताकि हमारा अपना TLS प्रमाणपत्र स्वीकार किया जाए, लाइव कॉन्फ़िगरेशन शून्य होने पर भी मैनेजर रजिस्ट्रेशन ब्लॉक को चलाने के लिए मजबूर करता है, हमारे स्थानीय डिवाइस सत्र के साथ लॉगिन को सफल होने देता है, और सबसिस्टम घातक त्रुटियों को शांत करता है जो अन्यथा "लॉग इन करने में विफल" संवाद पॉप करेंगी। यह एक एकल निर्भरता प्रविष्टि (गॉटचास अनुभाग देखें) को फिर से इंजेक्ट करता है ताकि रनटाइम हुक वास्तव में लोड हो। आउटपुट libil2cpp.patched.so है।
एक नकली स्पार्क्स सर्वर। server/fakeserver.py काबम के बैकएंड का स्थान लेता है। यह TLS 443 और सादे HTTP 80 पर सुनता है और गेम के API कॉल का उत्तर देता है। कैन किए गए उत्तर server/responses/ में रहते हैं, प्रति एंडपॉइंट एक फ़ाइल, विधि और पथ द्वारा नामित, उदाहरण के लिए GET__account_data.json। कुछ एंडपॉइंट फ़ाइल के बजाय कोड में गतिशील रूप से उत्तर दिए जाते हैं, क्योंकि गेम अपेक्षा करता है कि वे अनुरोध से मानों को प्रतिध्वनित करें (ट्यूटोरियल एंडपॉइंट और हीरो विवरण एंडपॉइंट)। उत्तर लिफ़ाफ़ा {"error":null,"result": ...} है। ध्यान दें कि स्पार्क्स त्रुटि पेलोड के अंदर फ़ील्ड err लिखी जाती है, error नहीं। वह विवरण मायने रखता है और इसे याद करना आसान है।
एक नेटिव रनटाइम हुक। tools/nativehook/ libdothook.so बनाता है, एक छोटी लाइब्रेरी जो स्टार्टअप पर गेम में लोड की जाती है और गेम द्वारा पढ़ी गई प्रत्येक डेटा कुंजी को लॉग करती है, साथ ही कुछ लक्षित व्यवहार प्रोत्साहन देती है। यह फीडबैक लूप है जिसने बाकी सब कुछ संभव बनाया: यह आपको ठीक-ठीक बताता है कि गेम क्या माँग रहा है ताकि आप एक प्रतिक्रिया संश्लेषित कर सकें और इसे सत्यापित कर सकें। यह निष्पादन से पहले स्थापित एक शुद्ध बाइट ओवरराइट इनलाइन हुक है, क्योंकि इसके लिए सामान्य उपकरण (Frida) एमुलेटर की ARM अनुवाद परत के तहत क्रैश हो जाता है।
डिवाइस वायरिंग। एमुलेटर को काबम के डोमेन को PC पर भेजना होगा और नकली प्रमाणपत्र पर भरोसा करना होगा। tools/provision_ldplayer.sh यह एक बार में करता है: यह पैच की गई लाइब्रेरी और हुक को पुश करता है, काबम के होस्टनाम को होस्ट्स फ़ाइल के माध्यम से PC के LAN पते पर रीडायरेक्ट करता है, नकली CA को सिस्टम ट्रस्ट स्टोर में माउंट करता है, और SELinux को शिथिल करता है। प्रत्येक एमुलेटर रीस्टार्ट के बाद इसे चलाएँ, क्योंकि वे माउंट रीबूट से बच नहीं पाते।
रनटाइम पर डेटा प्रवाह है: गेम एक काबम डोमेन पर HTTPS कॉल करता है, होस्ट्स फ़ाइल इसे PC पर भेजती है, नकली सर्वर server/responses/ से एक प्रतिक्रिया के साथ उत्तर देता है, पैच की गई लाइब्रेरी प्रमाणपत्र और उत्तर स्वीकार करती है, और हुक लॉग करता है कि क्या पढ़ा गया। वह लूप ही है जिसके द्वारा इस बिल्ड में प्रत्येक स्क्रीन को लाया गया।
README.md this file
TECHNICAL_NOTES.md the deeper technical reference: patches, recovered data shapes, findings
patches/
patch_il2cpp.py the six native patches plus the dependency re-injection
disasm_fn.py helper: disassemble a function at an offset
find_callers.py helper: find callers of a function
find_str_ref.py helper: find references to a string
server/
fakeserver.py the fake Sparx server
gen_certs.sh regenerate the TLS cert and CA (run this, see below)
setup_device.sh device side network and trust setup reference
iterate.sh quick restart and capture loop
responses/ one JSON file per endpoint the game calls
tools/
provision_ldplayer.sh one shot re-provision of the emulator to the working state
setup_arm64.sh toolchain setup notes
decompile_targets.py drive the Ghidra headless decompiler at chosen offsets
find_xrefs.py cross reference search over the binary
apply_labels.py apply IL2CPP symbol labels
light_analyze.py lightweight static analysis helpers
frida_attach.py Frida helpers (kept for reference, see the libnb note)
frida_run.py
hook_dot.js
nativehook/
hook.c source of libdothook.so, the runtime hook
libdothook.so prebuilt hook, arm64
deploy.sh build and deploy the hook
relaunch_and_capture.sh relaunch the game and capture logs
hook/dothook.c earlier hook variant, kept for reference
re_notes/
dump.cs the full IL2CPP dump: every class, method, and field in the game
decomp_out.c decompiled bodies of key functions
decompile_targets.txt the offsets worth decompiling
ASSET_INVENTORY.txt what art and audio already ships inside the app
re_notes/dump.cs शेष कार्य के लिए सबसे मूल्यवान फ़ाइल है। यह गेम का पूर्ण प्रकार मॉडल है: प्रत्येक वर्ग, प्रत्येक विधि, और महत्वपूर्ण रूप से प्रत्येक डेटा फ़ील्ड जो क्लाइंट सर्वर से पढ़ता है। यह पूरे बैकएंड API का आपका नक्शा है। जब आपको यह जानने की आवश्यकता हो कि प्रतिक्रिया का आकार क्या होना चाहिए, तो उत्तर वहाँ है।
com.kabam.bigrobot, संस्करण 9.2.0) । यह लगभग 800 MB है। अपनी स्वयं की प्रतिलिपि प्राप्त करें। पैकेज का नाम और संस्करण TECHNICAL_NOTES.md में हैं।libil2cpp.so और गेम एसेट्स। दोनों सीधे APK से आते हैं। APK को अनज़िप करें, लाइब्रेरी lib/arm64-v8a/ के अंतर्गत है, एसेट्स assets/ के अंतर्गत हैं।server/gen_certs.sh चलाएँ, फिर डिवाइस ट्रस्ट स्टोर को नए CA की ओर इंगित करें।libil2cpp.so के विरुद्ध patches/patch_il2cpp.py चलाएँ।re_notes/dump.cs का उत्पादन किया।आपको ARM अनुवाद में सक्षम एमुलेटर (LDPlayer 9 का उपयोग किया गया, रूट और लिखने योग्य सिस्टम के साथ), PC पर Python, और उपरोक्त अनुभाग से आइटम चाहिए।
bash server/gen_certs.sh।python patches/patch_il2cpp.py path/to/original/libil2cpp.so --apply।tools/nativehook/deploy.sh।python server/fakeserver.py। इसे एमुलेटर से पोर्ट 443 और 80 पर पहुँच योग्य होना चाहिए।bash tools/provision_ldplayer.sh <आपका-PC-LAN-IP>। प्रत्येक एमुलेटर रीबूट के बाद इसे पुनः चलाएँ।यदि यह लॉगिन पर हैंग होता है, तो कुछ भी करने से पहले गॉटचास अनुभाग में पहले आइटम की जाँच करें।
ये वे हैं जिन्होंने मुझे घंटों का समय दिया। वे लिखे गए हैं ताकि वे आपको वही कीमत न दें।
libdothook.so को संदर्भित करती है। सटीक बाइट्स और ऑफ़सेट पैच स्क्रिप्ट और TECHNICAL_NOTES.md में दस्तावेजीकृत हैं।provision_ldplayer.sh को फिर से चलाना होगा अन्यथा कुछ भी कनेक्ट नहीं होगा।err है, error नहीं। गलत का उपयोग करने से ऐसे उत्तर उत्पन्न होते हैं जिन्हें क्लाइंट चुपचाप अनदेखा या गलत तरीके से संभालता है।यह वास्तविक काम है, और यह बड़ा है। यहाँ इसका आकार और कहाँ से शुरू करना है।
लक्ष्य उस सर्वर साइड सामग्री को हाथ से फिर से बनाना है जो पहले क्लाइंट को स्ट्रीम की जाती थी: क्वेस्ट और मिशन, नक्शे और उनकी दुश्मन लाइनअप, प्रत्येक बॉट के आँकड़े और क्षमताओं के साथ पूर्ण रोस्टर, युद्ध सूत्र और अर्थव्यवस्था। इनमें से कुछ भी अब मौजूद नहीं है, इसलिए यह सब क्लाइंट द्वारा अपेक्षित सटीक आकारों में नए सिरे से लिखा जाना चाहिए।
जो विधि काम करती है वह लूप है जिसके चारों ओर यह परियोजना बनाई गई है। हुक संलग्न करके गेम चलाएँ। हुक क्लाइंट द्वारा पढ़ी गई प्रत्येक कुंजी को लॉग करता है। जब क्लाइंट कुछ ऐसा माँगता है जो आपने प्रदान नहीं किया है, तो आप ठीक-ठीक देखते हैं कि वह क्या चाहता था। फिर आप सही आकार में एक प्रतिक्रिया संश्लेषित करते हैं, इसे server/responses/ में डालते हैं या fakeserver.py में गतिशील हैंडलर में जोड़ते हैं, पुनरारंभ करते हैं, और सत्यापित करते हैं कि क्लाइंट इसे स्वीकार करता है और आगे बढ़ता है। दोहराएँ। वर्तमान बिल्ड में प्रत्येक स्क्रीन इसी सटीक तरीके से लाई गई थी। re_notes/dump.cs आपको चलाने से पहले ही प्रत्येक संरचना का आकार बताता है, क्योंकि यह उन सभी फ़ील्ड को सूचीबद्ध करता है जिन्हें क्लाइंट पढ़ता है।
इसे हमला करने का एक समझदार क्रम:
एक एकल पूर्ण लड़ाई को लोड करवाएँ और शुरू से अंत तक चलाएँ। यह सबसे उच्च मूल्य का लक्ष्य है क्योंकि युद्ध खेल का मूल है और यह एक बार में सबसे अधिक सर्वर डेटा का उपयोग करता है। आपको प्रतिभागियों की परिभाषाएँ, उनके आँकड़े और क्षमताएँ, और जो कुछ भी लड़ाई init पथ माँगता है, उसकी आवश्यकता है। परिचयात्मक लड़ाई पहले से ही लोड होना शुरू हो जाती है, इसलिए पहले वहीं धक्का देना है। लड़ाई init और युद्ध डेटा पथों को डीकंपाइल करें (decompile_targets.py का उपयोग करें) और सटीक फ़ील्ड पढ़ें।
रोस्टर डेटा मॉडल को पूरी तरह से पुनर्निर्मित करें, एक बॉट एक बार, आँकड़े और क्षमताएँ शामिल। प्रत्येक बॉट की कला पहले से ही ASSET_INVENTORY.txt में सूचीबद्ध बंडलों में मौजूद है, इसलिए आप केवल संख्याएँ और क्षमता परिभाषाएँ लिख रहे हैं, एसेट नहीं।
क्वेस्ट और मानचित्र संरचनाओं का पुनर्निर्माण करें ताकि स्टोरी खाली रहना बंद कर दे। मूल संरचना आंशिक रूप से पहले ही क्रैक हो चुकी थी, कुंजियों के लिए TECHNICAL_NOTES.md देखें।
अर्थव्यवस्था और प्रगति को अंत में भरें, एक बार जब लड़ाई और मिशन मौजूद हों जिन पर इसे खर्च किया जा सके।
पैमाने के बारे में यथार्थवादी बनें। उन खेलों के लिए भी जहाँ प्रशंसकों ने बंद होने से पहले लाइव सर्वर डेटा बचा लिया था, एक निजी सर्वर खड़ा करना एक लंबी परियोजना है। यहाँ शुरू करने के लिए कोई सहेजा गया डेटा नहीं है, इसलिए प्रत्येक संख्या और प्रत्येक क्षमता पर शोध या पुनः आविष्कार किया जाना चाहिए और फिर क्लाइंट के विरुद्ध सत्यापित किया जाना चाहिए। यदि लक्ष्य वास्तविक खेल है तो यह एक बहु-व्यक्ति, बहु-वर्षीय प्रयास है। ऐसा कहा जा रहा है, रास्ता अब कोई रहस्य नहीं है। बूट हल हो गया है, फीडबैक लूप मौजूद है, प्रकार मॉडल डंप हो गया है, और एसेट्स बरकरार हैं। जो बचा है वह बहुत बड़ी मात्रा में सावधानीपूर्वक डेटा पुनर्निर्माण है, अज्ञात का और अधिक रिवर्स इंजीनियरिंग नहीं।
TECHNICAL_NOTES.md से शुरू करें। यह गहरा तकनीकी संदर्भ है, जिसमें सटीक पैच, पुनर्प्राप्त डेटा आकार और विशिष्ट निष्कर्ष हैं, इस README से अधिक विस्तार में। फिर लूप चलाएँ।
शुभकामनाएँ। यह अब एक वास्तविक मशीन है। इसे बस अपनी सामग्री के पुनर्निर्माण की आवश्यकता है।