Patching Binaries: Live Modification

Patching Binaries is a series of articles about how to extract information and modify program behavior. It focuses on the Mac Mach-O executable format for the x86-64 architecture, but the techniques are similar for other formats.

Before proceeding it is recommended reading the second part about jumping and bypassing instructions.

We can also read and write registers of a program while it is running!

So let’s try changing the score right after it is set to 1 but before being used. As we saw before the value is saved into -0x8(%rbp) which we first have to understand what it means. The RBP (base pointer) register holds the pointer to the beginning of a stack frame while executing a function. Allocating on the stack is done by using a proper offset from the RBP, and since addresses grow upwards we use a negative addressing of -0x8 in this case.

Another approach is to start LLDB in a wait-for-process state where it will attach once a program with the given process name has been started. Something to note, though, is that the address 0x100001164 of before won’t work in this example due to how it attaches to the process. Instead we use the fact that main() is the first function so we can name it in LLDB as ___lldb_unnamed_function1$$score. Also, since it attaches to a running program we don’t have to start the process so we just continue after setting the break point. Finally, because we know that the original 0x100001164 is 36 instructions after the start of main() we set a break point using the RIP (instruction pointer) register with $rip+36.