How to call assembly in gdb?

Prior to GCC 5 (1), I don't know of a way to run arbitrary machine code unless you actually enter the machine code into memory and then run it.

If you want to run code that's already in memory, you can just set the instruction pointer to the start, a breakpoint at the end, then go. Then, after the breakpoint, change the instruction pointer back to its original value.

But I can't actually see the use case for this. That doesn't mean there isn't one, just that anything you can do by running code, you can also achieve by directly modifying the registers, flags, memory and so forth.

For example, the command:

info registers

will dump the current values of the registers while:

set $eax = 42

will change the eax register to 42.

You can also change memory in this way:

set *((char*)0xb7ffeca0) = 4

This writes a single byte to memory location 0xb7ffeca0 and you can also use that same method to store wider data types.


(1) GCC 5 allows you to compile and execute arbitrary code with the compile code command, as documented here.


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

main.c

#include <stdio.h>

int main(void) {
    int i = 0;
    printf("%d\n", i);
    return 0;
}

Compile and run:

gcc -ggdb3 -o main.out main.c
gdb main.out

Then in GDB:

(gdb) start
Temporary breakpoint 1 at 0x113d: file main.c, line 4.
Starting program: /home/ciro/test/main.out 

Temporary breakpoint 1, main () at main.c:4
4           int i = 0;
(gdb) next
5           printf("%d\n", i);
(gdb) compile code int j = 1; i = j; asm("nop");
(gdb) continue
Continuing.
1
[Inferior 1 (process 30256) exited normally]

Program output:

1

For this to work in GDB 7.9.1, GCC 5.1 I had to run GDB with:

LD_LIBRARY_PATH="$(dirname "$(gcc -print-libgcc-file-name)"):$LD_LIBRARY_PATH" gdb main.out

so that libcc1.so will be visible: that is a recent GCC component that exposes a C API to the cc1 compiler, but this was not needed anymore on Ubuntu 19.04. This was still required for C++ however on a minimal:

main.cpp

#include <iostream>

int main() {
    int i = 0;
    std::cout << i << std::endl;
}

and:

compile code int j = 1; i = j; asm("nop");

There are a few constructs that did not work as I expected:

  • return: In the GDB compile code command, what language constructs behave exactly as if they were present in the original source?

  • includes such as:

    compile code printf('asdf\n')
    

    in Ubuntu 19.04.

    On main.c above, printf without include worked because we already included it in the source, but if I try it on an empty main() without the include it fails with:

    gdb command line:1:1: warning: incompatible implicit declaration of built-in function ‘printf’
    gdb command line:1:1: note: include ‘<stdio.h>’ or provide a declaration of ‘printf’
    gdb command line:1:8: warning: character constant too long for its type
    gdb command line:1:8: warning: passing argument 1 of ‘printf’ makes pointer from integer without a cast [-Wint-conversion]
    gdb command line:1:8: note: expected ‘const char *’ but argument is of type ‘int’
    gdb command line:1:1: warning: format not a string literal and no format arguments [-Wformat-security]
    
  • In C++ Ubuntu 19.04:

    compile code std::cout << "Hello world\n";
    

    failed with:

    *** WARNING *** there are active plugins, do not report this as a bug unless you can reproduce it without enabling any plugins.
    Event                            | Plugins
    PLUGIN_PRE_GENERICIZE            | libcp1plugin
    PLUGIN_GGC_MARKING               | libcp1plugin
    PLUGIN_PRAGMAS                   | libcp1plugin
    gdb command line:1:6: internal compiler error: in plugin_build_decl, at libcc1/libcp1plugin.cc:1059
    Please submit a full bug report,
    with preprocessed source if appropriate.
    See <file:///usr/share/doc/gcc-8/README.Bugs> for instructions.
    Compilation failed.
    

    See also: How to compile C++ code in GDB?

Tags:

Assembly

Gdb