108

I know that we can use several commands to access and read memory: for example, print, p, x...

But how can I change the contents of memory at any specific location (while debugging in GDB)?

Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985
bits
  • 8,110
  • 8
  • 46
  • 55

5 Answers5

143

The easiest is setting a program variable (see GDB: assignment):

(gdb) l
6       {
7           int i;
8           struct file *f, *ftmp;
9
(gdb) set variable i = 10
(gdb) p i
$1 = 10

Or you can just update arbitrary (writable) location by address:

(gdb) set {int}0x83040 = 4

There's more. Read the manual.

Nikolai Fetissov
  • 82,306
  • 11
  • 110
  • 171
  • 4
    I do need to set a program variable BEFORE accessing arbitrary memory locations? Can't I just run the second set command right away? – Spidey Sep 26 '12 at 12:44
  • 2
    also, `set (str[6]) = 'c'` works, in case you have an array, like `char str[]` – xealits Sep 24 '20 at 13:38
  • 1
    I'm debugging assembly code(arm64). To write 0x1234 at address 0x6000000, do `set *((unsigned int)0x6000000) = 0x1234` – Chan Kim Dec 07 '21 at 04:24
36

As Nikolai has said you can use the gdb 'set' command to change the value of a variable.

You can also use the 'set' command to change memory locations. eg. Expanding on Nikolai's example:

(gdb) l
6       {
7           int i;
8           struct file *f, *ftmp;
9
(gdb) set variable i = 10
(gdb) p i
$1 = 10

(gdb) p &i
$2 = (int *) 0xbfbb0000
(gdb) set *((int *) 0xbfbb0000) = 20
(gdb) p i
$3 = 20

This should work for any valid pointer, and can be cast to any appropriate data type.

Andrew Edgecombe
  • 39,594
  • 3
  • 35
  • 61
17

Expanding on the answers provided here.

You can just do set idx = 1 to set a variable, but that syntax is not recommended because the variable name may clash with a set sub-command. As an example set w=1 would not be valid.

This means that you should prefer the syntax: set variable idx = 1 or set var idx = 1.

Last but not least, you can just use your trusty old print command, since it evaluates an expression. The only difference being that he also prints the result of the expression.

(gdb) p idx = 1
$1 = 1

You can read more about gdb here.

João Portela
  • 6,338
  • 7
  • 38
  • 51
4

Writing memory:

(gdb) set *0x20001234 = 0xABABABAB

Reading memory:

(gdb) x 0x20001234
0x20001234:     0xabababab
Jaakko
  • 4,674
  • 2
  • 26
  • 20
3

One of the most useful things is to change the value of Registers directly.

 0x000000000800088e <+67>:    lea    rdi,[rip+0x118]        # 0x80009ad

To change the value of rdi register:

 set $rdi = 0x8201010
BoRRis
  • 983
  • 8
  • 23