- rev.ng ने decompiler backend revng-c को सार्वजनिक कर decompile engine को open source में बदल दिया है, और साथ में UI closed beta, नई website, rev.ng Hub और documentation भी जारी किए हैं
- local environment में installation script से CLI configure करने के बाद
revng artifact और revng ptml का उपयोग करके valid C code के रूप में decompile results देखे जा सकते हैं
- interactive UI VSCode-based है और browser व standalone app दोनों को target करता है; यह newsletter subscribers को FIFO तरीके से invite किए जाने वाले closed beta में उपलब्ध है
- automatic data structure recovery, collaborative reversing, विभिन्न architectures का support और extensibility इसके मुख्य लक्ष्य हैं, लेकिन अभी QA सबसे अधिक Linux x86-64 binaries पर केंद्रित है
- framework और CLI open source हैं, cloud UI public projects के लिए free दिया जाता है, जबकि private projects और offline standalone UI paid model में अलग किए गए हैं
Open source में बदलाव और closed beta
- rev.ng ने decompiler backend
revng-c को open source के रूप में सार्वजनिक किया है
- इस release से पूरा decompile engine open source हो गया है
- शुरुआती documentation भी साथ में दी गई है
- UI के लिए newsletter subscribers को closed beta invites शुरू किए जाएंगे
- नई website और rev.ng Hub भी साथ में सार्वजनिक किए गए हैं
- rev.ng Hub cloud version का entry point है
- beta users projects बना सकते हैं, browser में UI चला सकते हैं और दूसरे users के साथ collaborate कर सकते हैं
- closed beta में शामिल न होने पर भी public projects देखे जा सकते हैं
- rev.ng features को सीधे देखना चाहने वाले users के लिए private demo भी उपलब्ध है
CLI से rev.ng आज़माना
revng को root permission के बिना एक single directory में install किया जा सकता है, और उस directory को delete करने पर यह remove हो जाता है
curl -L -s https://rev.ng/downloads/revng-distributable/master/install.sh | bash
cd revng
source ./environment
- example
example.c एक simple program है जो argc * 3 return करता है
int main(int argc, char *argv[]) {
return argc * 3;
}
gcc से compile करने के बाद revng artifact चलाने पर single file के रूप में decompile result मिल सकता है
gcc example.c -o example -O2
revng artifact \
--analyze \
--progress \
decompile-to-single-file \
example \
| revng ptml --color \
| grep -A2 -B1 '[^_]main\b' \
> decompiled.c
Beta scope और test targets
- UI इस्तेमाल करने के लिए newsletter में register करना होगा, और invites छोटे batches में भेजे जाएंगे
- यह release कुछ binaries पर UI और decompile results का demo करने, और real binaries पर काम करने को लेकर feedback व bug reports लेने पर केंद्रित है
- testing में इस्तेमाल किए गए non-trivial binaries और
.text sizes ये हैं
- rev.ng कई ABI और platforms support करता है, लेकिन इस stage में शुरुआती QA Linux x86-64 binaries पर केंद्रित है
- समस्या आने पर Discourse पर मदद मिल सकती है
rev.ng जिस decompile experience को target करता है
- rev.ng का मुख्य focus automatic data structure recovery, modern UX, collaborative reversing, broad platform support और extensibility है
-
Automatic data structure recovery
- Data Layout Analysis के जरिए
struct layout को inter-procedural analysis से automatically recover किया जा सकता है
- linked list node example में
int64_t data[5] array और next node pointer वाले struct को target किया गया है
- rev.ng output array size 5 और next element pointer access को automatically detect कर struct और function code generate करता है
- decompiler output syntactically valid C code होता है
- यह feature फिलहाल उपलब्ध है
-
VSCode-based interactive UI
- UI VSCode-based है, इसलिए VSCode users इसे familiar तरीके से use कर सकते हैं
- इसे browser tab और standalone application दोनों में चलाया जा सकता है
- मुख्य shortcuts ये हैं
Ctrl + Click: cursor के नीचे मौजूद function या type definition पर जाना
N: नाम बदलना
Y: type edit करना
X: references दिखाना
- rev.ng एक interactive decompiler है, जिसमें changes होने पर केवल affected parts को ही फिर से calculate किया जाता है
- UI फिलहाल closed beta participants को दिया जा रहा है
-
Collaborative reversing
- rev.ng UI client-server architecture का उपयोग करता है
- कई users एक ही daemon instance से connect होकर एक ही project पर simultaneously काम कर सकते हैं
- cloud version में project management के लिए GitHub-like application rev.ng Hub का इस्तेमाल किया जा सकता है
- collaboration features काम करते हैं, लेकिन user experience में improvement की जरूरत है, और इसे roadmap item #797 में track किया जाता है
Architecture और platform support का तरीका
- rev.ng QEMU pipeline के front part का उपयोग करके executable code को tiny code में lift करता है, फिर उसे LLVM IR में convert कर decompilation करता है
- इस structure की वजह से QEMU-supported architectures को अपेक्षाकृत आसानी से support किया जा सकता है
- architecture support जितना ही platform, खासकर ABI support भी महत्वपूर्ण है
- rev.ng ABI properties को declaratively describe करने के लिए ABI description format का इस्तेमाल करता है
- यह format नए ABI support को आसान बनाने जितना generic design किया गया है
- मौजूदा support status यह है
- architectures: x86, x86-64, ARM, AArch64, MIPS, s390x को अलग-अलग maturity levels पर support
- binary formats: ELF, PE/COFF, Mach-O support
- imports:
.idb, DWARF debug information, PDB debug information support
- ज्यादातर QA Linux x86-64 binaries पर किया गया है, और बाकी के लिए additional QA की जरूरत है
- ज्यादा platform QA को roadmap item #58 में track किया जाता है
Extensibility और scripting
- rev.ng reverse engineering tools के लिए framework बनने का लक्ष्य रखता है, और interactive UI को छोड़कर पूरा project open source है
- project file model एक YAML document है, इसलिए अगर JSON या YAML parse कर सकते हैं तो rev.ng को script किया जा सकता है
- model में decompile target binary की architecture, default ABI, segments, function list, type list आदि शामिल होते हैं
- Python और TypeScript wrappers से model modify किया जा सकता है
- अभी model manipulation wrappers हैं, लेकिन analysis execution और artifact import को आसानी से करने का तरीका अभी नहीं है
- complete Python client को roadmap item #17 में track किया जाता है
- internal representation में LLVM IR का काफी उपयोग होता है, जिससे LLVM ecosystem tools का फायदा लिया जा सकता है
Open source CLI और paid UI का फर्क
- rev.ng framework पूरी तरह open source है, और CLI से desired targets को decompile किया जा सकता है
- UI delivery तीन तरह से विभाजित है
- public projects के लिए cloud UI free use किया जा सकता है
- private projects के लिए cloud UI के लिए subscription चाहिए
- fully standalone और fully offline UI paid रूप में उपलब्ध है
- cloud usage का तरीका यह है
- rev.ng Hub पर project बनाकर collaborators को invite करना
- UI browser में चलता है
- backend rev.ng cloud पर चलता है
- अगर project files public करना ठीक है, तो UI सहित cloud version rev.ng को free इस्तेमाल किया जा सकता है
- Kubernetes इस्तेमाल करने वाली on-premises private cloud service installation पर भी चर्चा की जा सकती है
1.0 roadmap और contact channels
- 1.0 तक का roadmap 4 tiers में बांटा गया है
- Tier 1: alpha version, acquaintances के लिए demo, completed
- Tier 2: beta version, newsletter subscribers को cloud version access देना, अब शुरू हुआ है
- Tier 3: open beta, planned
- Tier 4: 1.0 release, planned
- detailed progress roadmap page पर देखी जा सकती है
- project news और support channels ये हैं
- X/Twitter: development news और major announcements
- Discord: development team के साथ real-time chat
- Discourse: user support और bug reports
- GitHub: open source development और issue registration
- Monthly newsletter: closed beta participation और monthly updates
- E-mail: private inquiries
1 टिप्पणियां
Hacker News की राय
प्राइसिंग मॉडल यह है कि rev.ng framework पूरी तरह open source है, और CLI में आप कुछ भी decompile कर सकते हैं
UI को public projects के लिए cloud पर मुफ्त, private projects के लिए cloud subscription, और पूरी तरह standalone offline app के रूप में paid उपलब्ध कराया जाएगा
तुलना करें तो Hopper 1 साल के updates सहित $100 का है: https://www.hopperapp.com/index.html, और Ghidra व Radare2 free/open source हैं इसलिए पूरी तरह मुफ्त हैं, जबकि IDA Pro बहुत महंगा है
मेरे अनुभव में यह IDA से काफी मिलता-जुलता है, लेकिन अधिक user-friendly है और इसमें productivity बढ़ाने वाले कई अच्छे से design किए गए features हैं
मैंने Hopper नहीं इस्तेमाल किया, लेकिन Ghidra और Radare2 का developer experience खास अच्छा नहीं लगा और generated C code भी आसानी से पढ़ने लायक नहीं था। हालांकि, यह राय दोनों को कुछ साल पहले इस्तेमाल करने के आधार पर है
Binja $300 का है, commercial use के लिए $1500, और student discount भी है: https://binary.ninja/features
फिर भी अच्छे C decompiler हमेशा कम पड़ते हैं, इसलिए नई कोशिशें हमेशा स्वागत योग्य हैं
बस यह जानने की उत्सुकता है कि अगर app को internet connection अनिवार्य न बनाया जाए, तो इसे enforce कैसे किया जाएगा
टीम पेज https://rev.ng/about और code contributions https://github.com/revng/revng/graphs/contributors को देखकर, यह थोड़ा दिलचस्प लगता है कि CEO(aleclearmind) के commits, CTO(pfez) से कहीं ज्यादा हैं
दूसरे CEOs अक्सर कहते हैं कि उनके पास coding के लिए लगभग समय नहीं होता, और CTO भी आमतौर पर management में ज्यादा और actual coding में कम होते हैं
फिर भी अगर यह तरीका अच्छी तरह काम करता है, तो टीम के नज़रिए से यह काफ़ी मज़ेदार होगा। सुधार: मैंने timeline नहीं देखी थी
आखिरकार दोनों repositories को merge करने की योजना है
और मैं तो हर दिन development कर रहा हूँ, लेकिन किसी कारण GitHub मेरे user को ठीक से पहचान नहीं रहा है
सच में यह मज़ेदार है
बल्कि मुझे यह बात अच्छी लगी, और यह उन चीज़ों से अलग थी जो मैंने दूसरी जगहों पर देखी थीं, इसलिए दिलचस्प लगी
क्या downvote इसलिए हुआ कि यह न तो दिलचस्प था, न ही असामान्य?
यह एक ऐसी शानदार कंपनी लगती है जिसे मौजूदा समय की programming language theory की बेहतरीन किताबों में से एक से प्रेरणा मिली है: https://link.springer.com/book/10.1007/978-3-662-03811-6
“उसने Pietro से भी मुलाकात की, जो उसका accomplice बनने वाला था। काफ़ी romantic ढंग से कहें तो, वह उससे उस किताब की वजह से मिला जो आगे चलकर कंपनी की नींव बनी।”
https://rev.ng/about
फिर मुझे यह किताब मिली, जो घनी होने के बावजूद साफ़ लग रही थी, और मैंने अपने supervisor से पूछा कि क्या मैं इसे खरीद सकता हूँ। उन्होंने कहा, “पहले university library देख लो”
library में उसकी एक copy थी, लेकिन वह पहले से issue हो चुकी थी, और compiler research करने वाले इकलौते group में होने के नाते मेरे मन में आया, “हमारे group के बाहर भला कौन compiler कर रहा है?”
मैं library गया और पूछा कि किताब किसने ली है, लेकिन privacy के कारण वे बता नहीं सकते थे। मैंने surname का तीसरा अक्षर और first name का दूसरा अक्षर पूछा, और मुझे Z और I मिले
मैंने यहाँ से पता लगाया: https://www.deib.polimi.it/ita/personale-lista-alfabetica
समय के साथ हम दोस्त बने और साथ में कंपनी शुरू की
launch तक पहुँचने के लिए सच में बहुत काम करना पड़ा
अच्छा होगा अगर code variables और struct members को जिस तरह handle करता है, उसके आधार पर variable names और struct member names अपने-आप दिए जाएँ
उदाहरण के लिए linked list के next pointer को
nextके रूप में पहचानना आसान होना चाहिएऐसा लगता है कि पूरे GitHub को download करके code में layout और interactions के हिसाब से सबसे मिलते-जुलते variables खोजे जा सकते हैं, और अगर confidence काफी ऊँचा हो तो वही नाम इस्तेमाल किया जा सकता है
जैसे induction variable पहचानकर उसका नाम
iकर देनालेकिन अब लगता है कि इस तरह के काम का सही तरीका LLM का इस्तेमाल करना है
हालांकि इस stage पर हम ज़्यादा उन लोगों की तरह हैं जो मजबूत foundation बनाते हैं, और foundation तैयार होने के बाद existing models से rename करना या comments जोड़ना अपेक्षाकृत आसान है
मुख्य बात यह है कि 100% accuracy माँगने वाला कठिन decompilation काम हम करें, और names व comments जैसी जगहों पर, जहाँ approximation चल सकती है, वहाँ LLM लाया जा सकता है
वैसे भी rename करने वाली scripts लिखना काफ़ी आसान है, इसलिए docs देख लें: https://docs.rev.ng/user-manual/model-tutorial/
JSNice अंदर क्या करता है, यह समझाने वाला paper: https://files.sri.inf.ethz.ch/website/papers/jsnice15.pdf
मेरी ELF फ़ाइल पर यह काम नहीं करता
./revng artifact --analyze --progress decompile-to-single-file ../maytag.koचलाने परOnly ELF executables and ELF dynamic libraries are supportedआता है, और फ़ाइलELF 64-bit LSB relocatable, x86-64, version 1 (FreeBSD), not strippedके रूप में दिखती हैक्या यह FreeBSD binaries को support नहीं करता?
संपादन: मैं यह बात चूक गया कि यह kernel modules को support नहीं करता, और शायद FreeBSD की वजह से नहीं बल्कि इसलिए कि यह कोई साधारण executable नहीं है
इसे load करना इतना मुश्किल नहीं होना चाहिए
उम्मीद है collaboration workflow पर काफी ध्यान दिया जाएगा
मैंने IDA Teams जैसी चीज़ें नहीं इस्तेमाल की हैं, लेकिन अगर Google Docs जैसी frictionless reverse engineering experience मिल सके तो वह कमाल होगा
पहले हम UI के लिए QtCreator इस्तेमाल करते थे, और वह एक भयानक चुनाव था
बाद में हमने VSCode पर switch किया, और संयोग से वह browser में भी चल सकता था
इसलिए हमने थोड़ा Kubernetes मिलाकर एक cloud decompiler बनाया, जिसका user experience पूरी तरह standalone version जैसा ही है
collaboration वाला हिस्सा अभी और QA मांगता है, लेकिन बुनियादी तौर पर यह काम करता है
इसकी architecture बहुत simple है: एक daemon और कई clients
लगता है प्रेरणा उस पुराने CTF अनुभव से आई, जहाँ हम server के X session के ऊपर कई IDA windows और कई cursors के साथ “collaboration” करते थे। तरीका बहुत cursed था, लेकिन असरदार था
क्या type inference support करने की योजना है?
अभी तो लगता है कि सभी variables
generic64_tके रूप में दिखते हैं; Ghidra की तरह types अपने-आप detect हो जाएँ तो अच्छा होगा। हालांकि Ghidra भी कभी-कभी गलत होता हैroadmap item: https://rev.ng/roadmap#feature-798
design pad: https://pad.rev.ng/s/eDHi2PUoP#
दिलचस्प लग रहा है
मैं पूरी तरह standalone version आज़माना चाहूँगा
क्या pricing के बारे में कोई मोटा-मोटा संकेत है? उम्मीद है कि यह hobby users की पहुँच में होगा
बाइनरी हैकिंग tools बढ़ना हमेशा अच्छा लगता है
इसे खुद आज़माने की इच्छा हो सकती है, इसलिए चुने गए packaging format पर कुछ ज़्यादा ही बारीक सुझाव छोड़ रहा हूँ
source ./environmentअच्छा संकेत नहीं है। tar डाउनलोड करके देखा तो यह सचमुच PATH समेत कई environment variables सेट करता है, शुक्र हैLD_LIBRARY_PATHनहीं थाज़्यादातर में
HARD_prefix है, शायद यह पर्याप्त रूप से unique हो, लेकिनREVNGज़्यादा स्पष्ट लगता है, और मौजूदा environment variables से टकराव बुरा हैAWS_EC2_METADATA_DISABLED="true"भी सेट किया जाता है; मैं AWS इस्तेमाल नहीं करता इसलिए यह टूटा नहीं, लेकिन सामान्य तौर पर यह संदिग्ध लगता हैRPATH_PLACEHOLDER,HARD_FLAGS_CXX_CLANG, लंबा PATH, mingw32/gentoo/mips strings वगैरह नाज़ुक लगते हैंजब run instructions में “अब environment variables बदलें” लिखा हो, तो मैं आम तौर पर वहीं छोड़ देता हूँ; इसका non-Ubuntu systems पर ठीक से न चलने वाले programs से मज़बूत संबंध है
application control flow को execution environment से बाँधने पर पहली नज़र से ज़्यादा failure modes आते हैं, और यह global variables से बहुत मिलता-जुलता है
Clang build समय पर
-DCLANG_DEFAULT_CXX_STDLIB=libc++जैसे defaults bake कर सकता है, औरDEFAULT_SYSROOTभी उपयोगी हैrpathइस्तेमाल करने पर भी, अगर user नेLD_LIBRARY_PATHसेट किया हो तो binary काDT_RUNPATHruntime पर override हो सकता हैआजकल
-Wl,rpathवास्तव में rpath नहीं बल्कि कम उपयोगीrunpathका मतलब होता है, और शायद वांछित invocation-Wl,rpath -Wl,--disable-new-dtagsहै ताकि loader library search करते समयLD_LIBRARY_PATHको ignore करेClang build flags, static linking, binary के अंदर binary embed करना आदि मिलाकर environment variable manipulation को पूरी तरह हटाना संभव हो सकता है
clang-16binary का dynamic linking होना और runtime परlibLLVMAArch64CodeGen.so.16जैसी चीज़ें ढूँढना भी failure modes बढ़ाता हैLLVM_BUILD_STATIC=ONहोने पर HPC module toolchain सक्रिय environment में गलत libraries उठ जाने की समस्या कम हो सकती हैtools
libc++.so,libc++abi.soआदि से link हो रहे हैं; static libc++ पर विचार किया जा सकता है, और कम से कमlibc++abiऔरlibunwindको libc++ के भीतर statically link करना बेहतर होगाLinux पर dynamically linked programs distribute करने के लिए मेरा धैर्य पूरी तरह खत्म हो चुका है
अगर README का
source ourhackया module system से छोड़े गए environment variables मेरी application की runtime libraries बदल दें, तो user experience और बाद के bug reports की लागत भयानक हो जाती हैइसके मुकाबले static linking वाकई शानदार है
source environmentकरेगादरअसल हमने यह सुझाव सिर्फ इसलिए दिया था ताकि demo binaries के लिए हम जो GCC distribute करते हैं, वही इस्तेमाल हो; intended usage
./revngscript हैइस स्थिति में environment changes सिर्फ
revnginvocation को प्रभावित करते हैंdocumentation यहाँ है: https://docs.rev.ng/user-manual/working-environment/
source ./environmentके बारे में एक warning जोड़ना अच्छा रहेगाLD_LIBRARY_PATHसे बचने में हमने बहुत समय लगाया, और हर ELF अपनी dependencies को relative paths से refer करे, ऐसा पूरी तरह self-contained binaries का set बनाया।LD_LIBRARY_PATHबुरा हैHARD_variables सिर्फ compiler wrappers में इस्तेमाल होते हैं और मुझे नहीं लगता कि इनके वास्तव में टकराने की संभावना हैAWS_EC2_METADATA_DISABLED="true"पर मूल चर्चा यहाँ है: https://github.com/revng/revng/pull/309#discussion_r12805759...AWS SDK को patch करके इससे बचा जा सकता है, लेकिन वैसे भी असर सिर्फ तब होता है जब rev.ng cloud में चल रहा हो
RPATH_PLACEHOLDERऔरHARD_FLAGS_CXX_CLANGतब इस्तेमाल होते हैं जब revng अनूदित binaries को link करता है, और अगर आपको end-to-end binary translation में रुचि नहीं है, तो यह महत्वपूर्ण नहीं हैहम जानबूझकर
DT_RUNPATHचाहते हैं।DT_RPATHdeprecate होने वाला है, और ऐसे use cases हो सकते हैं जहाँ users कोLD_LIBRARY_PATHसे हमारी libraries replace करनी हों“environment manipulation” वाली आपत्ति मुझे सिर्फ तब सही लगती है जब variables private न हों
RPATH_PLACEHOLDER,HARD_*,REVNG_*private variables हैं और ये सब binary translation के लिए हैंइन्हें और छोटे दायरे वाले compiler wrapper के भीतर धकेला जा सकता है, लेकिन क्योंकि हम Python भी साथ distribute करते हैं, environment को पूरी तरह हटाया नहीं जा सकता
सिर्फ कुछ flags को Clang में bake कर देने से काम नहीं चलेगा। ये flags linker को भी प्रभावित करते हैं, और wrapper functionality के कुछ हिस्से ऐसे हैं जिन्हें बस embed नहीं किया जा सकता
हाँ, इन्हें और private जगह पर ले जाया जा सकता है
लगता है आप dynamic linking को लेकर सतर्क हैं, लेकिन हमने इस पर मेहनत की है और अब यह काफ़ी अच्छी तरह काम करता है तथा हमेशा सही location ढूँढ लेता है
हम absolute paths hardcode नहीं करते, और न ही कोई install step है जो binaries को “patch” करे। unpack की गई directory को कहीं भी ले जाया जा सकता है
हमारा समाधान
LD_LIBRARY_PATHइस्तेमाल नहीं करता; सभी binaries$ORIGINके ज़रिए मज़बूती से एक-दूसरे को refer करती हैं./root/bin/python ./root/bin/revng artifact --helpचलाकर देखें, यह काम करता हैफिर से कहूँ तो
source environmentलगभग सिर्फ demo के लिए है; असली उपयोग में बस./revngचलाना होता है और environment वैसा ही रहता हैहम Python भी साथ distribute करते हैं, लेकिन उसी का इस्तेमाल करना ज़रूरी नहीं है।
./revngइस्तेमाल करें या daemon mode में network के ज़रिए interact करेंतरीका यह है कि अपनी पसंद के scripting tool से YAML project files को parse और modify करें, फिर
./revng artifactचलाएँ या daemon से interact करें: https://docs.rev.ng/user-manual/model-tutorial/नतीजतन हम नवीनतम Python version इस्तेमाल करते हैं, और users अपनी पसंद की language इस्तेमाल कर सकते हैं
इसके बाद, विभिन्न Python versions के साथ compatible सहायक wrapper को PyPI पर उपलब्ध कराने की योजना है
सारांश में,
source ./environmentमत करें, बस./revngका उपयोग करेंअच्छा लगता है कि कोई इन बातों पर ध्यान दे रहा है
अगले बड़े iteration में nix + mount namespace लाया जा सकता है, जिससे root privileges के बिना
/nix/storeका उपयोग संभव होगा और बहुत-सी चीज़ें सरल हो सकती हैंशायद ऐसी चर्चाएँ यहाँ की बजाय Discord server पर करना बेहतर होगा
QEMU TCG को lifting सौंपने को लेकर कोई पछतावा है, या यह अच्छी तरह काम किया?
पहला, हमने कई सालों तक QEMU fork को rebase नहीं किया, जिससे स्थिति अच्छी नहीं रही
फिर भी, आज ही टीम के एक सदस्य ने नवीनतम QEMU पर lifting सफलतापूर्वक कर ली, और हम Qualcomm Hexagon code को भी lift कर पाए, जिसके लिए QEMU में support जोड़ने में हमने मदद की थी
आखिरकार हम पहले सही मायने में काम करने वाले Hexagon decompiler बनेंगे
दूसरा, QEMU पर बहुत ज़्यादा ध्यान देने की वजह से frontend, QEMU के साथ मज़बूती से coupled हो गया
अब QEMU-आधारित न होने वाले अतिरिक्त frontend को support करने के लिए कुछ मेहनत लगेगी, लेकिन यह असंभव नहीं है
योजना यह है कि जब उपयोगकर्ता किसी नए architecture के लिए support जोड़ें, तो उन्हें सिर्फ C में CPU state struct और उस पर काम करने वाले कुछ functions परिभाषित करने पड़ें
internal representation सीखने की ज़रूरत नहीं होगी
संक्षेप में, QEMU एक बेहतरीन विकल्प था, और यह इतना अच्छा चला कि हमने codebase के उस हिस्से को लंबे समय तक छुआ ही नहीं, जिससे technical debt बन गया, लेकिन अब हम उसे ठीक कर रहे हैं