- initrd को कर्नेल द्वारा सीधे interpret और execute की जाने वाली program unit के रूप में परिभाषित करते हुए, Linux को एक तरह के interpreter के रूप में फिर से समझाया गया है
kexec, base64, cpio का उपयोग करके अपने-आप को reboot करने वाली recursive Linux distribution बनाई जाती है, जहाँ initrd खुद को फिर से execute करती है
- अगर
/init script को अपनी ही cpio image output करने के लिए बनाया जाए, तो Quine-शैली की self-replicating initrd बनती है
- ELF execution structure और
ld.so, binfmt_misc के जरिए interpreter layers के कर्नेल तक जारी रहने वाली संरचना समझाई गई है
kexec या QEMU का उपयोग करने पर Linux के ऊपर एक और Linux को tail-recursive तरीके से चलाना संभव है, जिससे kernel, virtualization, और interpreter की सीमाएँ प्रयोगात्मक रूप से फैलती हैं
rkx.gz का reverse engineering और self-recursive initrd संरचना
curl https://astrid.tech/rkx.gz | gunzip | sudo sh कमांड 20MB आकार की base64-encoded shell script को डाउनलोड करके चलाती है
- script root permissions की जाँच करती है और
kexec, base64, cpio की मौजूदगी की पुष्टि करती है
- base64 data को decode करके
r नाम का cpio archive बनाती है, और उसके भीतर से k नाम की kernel image निकालती है
kexec का उपयोग करके k को kernel और r को ramdisk के रूप में load करने के बाद execute करती है
r.cpio के अंदर /bin, /init, k फ़ाइलें शामिल हैं, जहाँ k Linux 6.18.18 kernel image है और /init shell script के रूप में है
/init /proc को mount करती है, /r में मौजूदा file system को cpio के रूप में पैक करती है, फिर kexec से /k और /r को दोबारा execute करती है
- नतीजतन यह अपने-आप को लगातार reboot करने वाली recursive Linux distribution बन जाती है
Linux kernel को interpreter के रूप में देखने का नज़रिया
- initrd सिर्फ़ boot के लिए ramdisk नहीं है, बल्कि इसे Linux kernel द्वारा interpret और execute किए जाने वाले program के रूप में देखा जा सकता है
curl | sh या python3 script.py की तरह, initrd भी kernel द्वारा execute किया जाने वाला input program है
- इसलिए Linux kernel initrd को interpret करने वाले interpreter की तरह काम करता है
- यह संरचना tail-call optimization जैसी है
kexec पिछले kernel को overwrite नहीं करता, बल्कि नए memory space में load करके execute करता है
- हर kernel पिछली state को बनाए नहीं रखता, बल्कि नए “stack frame” से replace हो जाता है
Quine और initrd self-replication
- Quine का मतलब ऐसा program जो खुद को output करे
- अगर
/init script आखिर में cat /r चलाए, तो वह अपने जैसा ही cpio output करती है
- इस स्थिति में Linux initrd interpreter का Quine बनता है
- चूँकि सभी फ़ाइलें RAM पर मौजूद
tmpfs में हैं, इसलिए वास्तविक disk I/O नहीं होता
ELF, ld.so, और interpreter की परतें
- ELF executable अपनी header में interpreter (
ld-linux-x86-64.so.2) का path शामिल करती है
- execution के समय kernel पहले
ld.so को चलाता है, और ld.so ELF की dynamic libraries load करने के बाद program चलाता है
- इसलिए ELF को भी एक प्रकार की interpreter language माना जा सकता है
/bin/sh को ld.so interpret करता है, और ld.so को kernel सीधे interpret करता है
ld.so statically linked ELF है, इसलिए kernel उसे सीधे execute कर सकता है
- इस तरह interpreter hierarchy का base case बनता है
binfmt_misc के जरिए CPIO execution
binfmt_misc का उपयोग करके विशिष्ट magic bytes वाले file को तय interpreter से execute कराया जा सकता है
- QEMU का उपयोग करके CPIO को initrd के रूप में चलाने वाली script को interpreter के रूप में register किया जा सकता है
- QEMU तय kernel और initrd का उपयोग करके virtual machine boot करता है
- नतीजतन CPIO file का interpreter QEMU द्वारा चलाया गया Linux kernel बन जाता है
Recursive interpreter और “सबसे अजीब loop”
- QEMU-आधारित interpreter नई Linux environment stack frame बनाता है
- Linux के ऊपर एक और Linux चलाने वाली संरचना में, memory limit तक nesting संभव है
- अगर इसे
kexec-आधारित interpreter से बदला जाए, तो tail-call optimized recursive Linux execution संभव है
- अगर
/init में binfmt_misc register करके /r को execute करने के लिए configure किया जाए,
खुद को execute करने वाली initrd पूरी हो जाती है
/r CPIO format में अगला init process है, जो execute होने पर फिर से खुद को interpret करता है
निष्कर्ष
- initrd सिर्फ़ एक boot tool नहीं, बल्कि Linux kernel द्वारा interpret की जाने वाली program unit है
kexec और binfmt_misc की मदद से Linux को ही interpreter की तरह recursive तरीके से चलाना संभव है
- यह संरचना kernel, virtualization, interpreter, और self-replicating programs की सीमाओं को तोड़ने वाली एक प्रयोगात्मक अवधारणा है
- संबंधित source code GitHub repository ifd3f/rekexec में उपलब्ध है
अभी कोई टिप्पणी नहीं है.