Search code examples
cgdbreverse-engineering

Is there a way to edit argv during runtime using gdb?


Is there a way to edit argv during runtime using gdb?

I want to get the pid of a c program and pass it as an argument (argv).

For example :

gdb cProgram
(gdb) b *0x000000000040085b
(gdb) r anyway
(gdb) info inferior
  >Num  Description          Executable
  >* 1    process 2597503    /path/to/file

(gdb) #A command to pass 2597503 as argument (argv)
(gdb) c

Thanks :)


Solution

  • Yes, it appears to be possible, however, I don't know the implications of doing such a thing, someone else will need to chime in on that. If argv strings are string literals, then modifying them is undefined behavior. Furthermore, if you write past the length of the original string, that probably invokes UB as well. Nevertheless, I found this answer which details how to modify an int, and adapted it to a string. Consider the following program:

    #include <stdio.h>
    
    int main(int argc, char* argv[])
    {
      for (int i=1; i<argc; i++)
      {
        printf("%s\n", argv[i]);
      }
    
      return 0;
    }
    

    Compiling with

    gcc -Wall -Wextra -g -O0 -std=c99 test.c
    

    And then running with gdb:

    gdb a.out
    // gdb's intro
    (gdb) break main
    Breakpoint 1 at ...
    (gdb) run arg1 arg2 arg3  // pass it 3 arguments
    // breakpoint hit at main
    (gdb) print argv[1]
    $1 = <address> "arg1"
    (gdb) set {char*}(&(argv[1])) = "new4"  // change the value of argv[1]
    (gdb) print argv[1]
    $2 = <differentAddress> "new4"
    (gdb) delete 1 // deletes the break point
    (gdb) continue
    Continuing.
    new4
    arg2
    arg3
    [... exited normally]
    (gdb)
    

    So there you have it. Whether this is actually safe or not is a different story, but that changed the value of argv[1] for me. I would at least make sure the original string is the same length or longer than the string you want to replace it with.