Can GDB change the assembly code of a running program?

21,564

Solution 1

You can write binary to memory directly but GDB doesn't have an assembler build in by default you can however do something like set *(unsigned char*)0x80FFDDEE = 0x90 to change the mnemonic at that address to a NOP for example. You could however use NASM to write a shellcode and use perl or python to inject it into the program :)

You might also like this little .gdbinit file to make debugging allot easier: https://gist.github.com/985474

Solution 2

I would recommend a different approach: Download the coreutils package and modify the source code for ls. If possible, you should get the package from your distro's source repositories and apply any patches.

Solution 3

compile code command

Introduced around 7.9, it allows code compilation and injection. Documentation: https://sourceware.org/gdb/onlinedocs/gdb/Compiling-and-Injecting-Code.html

I have given a minimal example in this answer.

While it is not actual code modification, it does allow you to compile some code on the fly and run it once immediately, which might be enough.

And the GNU cauldron presentation suggests that actual code modification may be added later on as an extension to this feature, see slide 30 "Fix and continue".

There are a few constructs that did not work as I expected like return, so I've asked why at: In the GDB compile code command, what language constructs behave exactly as if they were present in the original source?

Solution 4

Here is a blog post that explains how to change the code at runtime both for gdb and Visual Studio.

Share:
21,564
jyz
Author by

jyz

Updated on May 07, 2020

Comments

  • jyz
    jyz about 4 years

    I want to add some extra funcionality to /bin/ls.
    So I started it on gdb and added a breakpoint at the beginning.

    Now question is: how can I change the code of a running program in memory? I can see the assembly code, but I'm not able to modify. How can I do it?

    On Windows I can easily do this with olldbg for example. How about on Linux?

    (I know that doing this I will only change the code of the process in memory. So then I can dump memory to a file, and then I'll have my changes saved in a binary file).

    Thank you.

  • jyz
    jyz almost 13 years
    I really like your suggestion, but to inject a shellcode I would need a vulnerable buffer right? I'm not sure if /bin/ls would have a bug to exploit...
  • jyz
    jyz almost 13 years
    BTW this command *(unsigned char*) did not work. Are you sure about that?
  • DipSwitch
    DipSwitch almost 13 years
    No I mean with OllyDbg you can reassemble complete operations, if you want do do something like this with GDB you would need to assemble it with your assembler of choice and write it byte for byte into the memory with the trick I showed above.
  • DipSwitch
    DipSwitch almost 13 years
    Sorry forgot to place set in front, you would need to enter set *(unsigned char*)0x80FFDDEE = 0x90 at the GDB prompt.
  • mohit
    mohit over 12 years
    I had put together a blogpost a few years back that explains how one can alter code in memory both for Windows and Unix (gdb) similar to the answer above. technochakra.com/debugging-modifying-code-at-runtime
  • jyz
    jyz over 12 years
    +1 for the link. Do you know if gdb can dump and assembly again the program in memory with the changes I did?
  • Wakan Tanka
    Wakan Tanka over 9 years
    Dude your .gdbinit is amazing. I am just starting with gdb and this helped a lot. Thank you very very much.
  • A. Nilsson
    A. Nilsson over 6 years
    It did that for me automatically the next time I listed the disassembled code
  • phil294
    phil294 almost 6 years
    Please include the actual answer in your answer. Answers shouldn't contain of a mere url
  • arainchi
    arainchi about 2 years
    This link is dead. Here is a copy from webarchive