In this exercise, we will replace these two binaries with assembly language versions that do not have such an interpreter dependency.
Optionally, you might want to first edit your grub defaults, /etc/default/grub, so that you have a bit more time to react; I suggest increasing your grub dialogue timeout:
If you do change your grub defaults, you will need to run update-grub to update the actual configuration file. However, if you have reasonably fast reflexes, the current Debian defaults are not bad.
When you boot, hit "e" to edit your Linux kernel's start-up parameters. Add "break=premount" after the "ro" bit on the boot command line, to force the kernel to stop before it mounts any file systems, and thus you leaving in the initial RAM filesystem rather than your ordinary root filesystem. Then do a CTRL-X or hit F10 to continue the boot process.
Once you have booted to the "(initramfs)" prompt, do a "cd" into /bin.
Do an "ls -li" of "true" and "false" and then a "file" of each:
Note that these are currently some 600 bytes each, and they use an interpreter listed by the "file" — *if* your initrd contains "/bin/file"; my test version this time around did not. If you don't have one, try "od -a /bin/true" and look at byte 440 for the path to the interpreter.
Now do an "exit", and let your system boot up normally.
Become root. Create a subdirectory something like "initrd-new"; I used "/root/initrd-new", but you can use "/tmp" if you like (but if you use /tmp and then have to redo anything, then you will have to redo everything since the contents of "/tmp" disappears on each reboot.)
Now you can do "cd initrd-new && zcat < /boot/initrd-SOMEVERS | cpio -i -d" to extract your current initrd to your subdirectory.
Now it's time to work with the substitute true and false code.
Change directory to somewhere that you can assemble your new code (i.e., do not do the assembly in your initrd-new/ directory), and then pull the source code for "true" and "false" in with wget:
(Or feel free to write your own assembly, if you don't like mine. ;-)
Now you will need "yasm", "build-essential", and possibly "file":
Now assemble, link, and strip your binaries:
Once you have new "true" and "false" binaries (they should each be around 360 bytes in size), copy them over the versions in "initrd-new/bin". (This is critical, by the way — if you don't put the new copies into the initrd-new/bin subdirectory, then they won't be there when you reboot using your initrd-new.)
Now create a new gzipped initrd with your new binaries, using "cpio" with both "-o" and "--format='newc'" (the man page for cpio's various format is here) and piping to gzip:
Copy the old version of initrd in the /boot subdirectory to an "ORIG" file (if you don't do this, and you subsequently have any sort of problem with your new initrd, it's *much* harder to recover!), and then install your new version over the previous one in /boot:
And now reboot, again specifying "break=premount". Change directory into "/bin", and, voila, you should see your shiny new "true" and "false" programs, each at 360 bytes and statically linked with no pesky interpreter interposed: