Patrick O'Callaghan wrote: > Running sed on an executable is unlikely to work: > > $ file /usr/bin/kwrite > > /usr/bin/kwrite: ELF 64-bit LSB shared object, x86-64, version 1 > (GNU/Linux), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, > for GNU/Linux 2.6.32, BuildID[sha1]=3c378cb60be1e2a76f98 > 1ba5c15c1096f1b6a5b5, stripped > > Also, are you sure you mean 'getpid'? OK, so let me explain how this hack works (*) (I wanted to let you try and be amazed first :-p): * The first thing to observe is that the replacement string has the same length as the string being replaced. (In fact, I only replace one character with another, but this does not even matter, as long as the length does not change.) sed actually has no issues at all with operating on binary files. The only problem is, if you change the length of the string, you break all the offsets in the executable and it will stop working. So it is extremely important that the replacement string also has 6 characters like "getuid". * Now compare the prototypes of "getuid" and "getpid": uid_t getuid(void); pid_t getpid(void); Notice that they are almost the same, only the return type looks different at first glance. But both uid_t and pid_t are actually 32-bit integers (technically, uid_t is unsigned and pid_t is signed, but that does not matter at all at assembly level), so that does not matter. Therefore, it is safe to call one function instead of the other. * Symbol versioning might get in your way. But if you check, you will find that the current symbol version of both "getuid" and "getpid" on x86_64 is GLIBC_2.2.5, so that will not get in your way either. * Now look at how the check for root actually works: it does something like: if (getuid() == 0) fail; My hack changes this to: if (getpid() == 0) fail; The interesting thing is, getpid() == 0 is always false! The PID is never zero, PID 0 is reserved by the Linux kernel. So the whole check becomes a no-op and kwrite will always run. So, all in all, I just had to look for a libc function that has a 6-letter name, a compatible prototype with getuid, and will never return 0. getpid was the perfect match. (By the way, if upstream decides to change the check to check for geteuid instead, which has 7 characters, then you can replace that with getppid, which is also never 0.) So next time you should at least try my command before claiming that it will not work. :-) You should trust an experienced developer with assembly knowledge like me more than you do. ;-) Note: (*) To be sure, I have now just tested it on the kwrite binary from kwrite-17.04.1-1.fc26.x86_64.rpm, and yes, it does work – but I was almost sure it would work even before testing it. :-) "I have only proved it correct, not tried it." as Donald Knuth once wrote. ;-) But now I did try it and it works indeed. Kevin Kofler _______________________________________________ kde mailing list -- kde@xxxxxxxxxxxxxxxxxxxxxxx To unsubscribe send an email to kde-leave@xxxxxxxxxxxxxxxxxxxxxxx