I have a Linux system which is running in an embedded system. For various reasons I can't get into (or I'll get fired), I don't have direct access to this system through normal means like a keyboard, or SSH. I know, I know, it's evil to change an executing file, but please trust that if I had an alternative, I would take it.
On this system, which is built around an ARM CPU, there is an executable which is pure ARM machine code (compiled from C++). A bug has been found in this code. I found that the bug can be fixed by replacing a UXTB instruction with a UXTH instruction. Luckily for me, that requires changing an opcode byte from 0xEF to 0xFF. This patch can be performed by simply running the following command:
printf '\xff' | dd of=path/to/executable bs=1 seek=$((0x01ce22)) conv=notrunc
The byte being modified is part of a function that only gets called when this embedded system receives a particular command. I can absolutely guarantee that this command will not be sent while I am performing this patch. Therefore, there are no dangers involving differing versions of code in RAM and storage.
Unfortunately, the program that needs to be changed (which, again, initiates on system startup) is also the program I am relying on that allows me to have the little access I do to this system. So I can't kill that process, lest I lose access.
Is there any possibility I could modify this one byte of the executable, this single little bitty byte that isn't directly being used?
Maybe the best solution would be to use a shell script which kills the main process, changes the byte, then activates a reboot? Ideally I'd like for the system to stay alive, such that I can see that the change succeeded.
I have a test case script running on an identical system, which I do have direct SSH access into. The test script is a C++ script which just outputs a value to a file 1000 times, in 0.1 second increments. I disassembled it and found the byte which holds that constant value, and similarly to the above printf | dd command, I can modify that constant - but only when the program is not running. An ideal solution to me would be one where I can modify that constant on-the-fly, so that the output file holds 500ish of the as-made-in-C++ value, and 500ish of the value I have clobbered into the proper byte.
Thanks for any help or suggestions you can provide.
ssh
or something similar. – dirkt Dec 30 '20 at 13:13dd: failed to open 'executable_file': Text file busy
. That's the error I get when I run the command I listed in the original post, while the executable is running. – Murphy Dec 30 '20 at 16:29dd
, you can't do it with anything else. So it won't work this way, unless your script allows other things (like executing a debugger to attach to the running process), or you can modify other things through the script. And maybe that's a good thing, because besides "fixing" executables, you can of course also "hack" them (and this will get you fired for sure). – dirkt Dec 30 '20 at 17:18dd
withof=/proc/XXXX/mem
to update the in-memory copy of the running program where XXXX is the PID of the running process. You will need a different offset from the one you have calculated. /proc/XXXX/maps is a text file that will help you calculate the new offset. – icarus Jan 1 at 9:54