在gdb中,我可以使用
call
来运行函数,但如果我想要运行一些额外的汇编代码怎么办?info registers
在执行时,会将寄存器的当前值转储出来:
set $eax = 42
将会把 eax
寄存器更改为 42
。
您也可以通过以下方式更改内存:
set *((char*)0xb7ffeca0) = 4
0xb7ffeca0
,您也可以使用同样的方法存储更宽的数据类型。
compile code
命令编译和执行任意代码,文档在这里记录。编译代码
命令
该命令在7.9左右引入,允许进行代码编译和注入,文档请参考: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;
}
编译和运行:
gcc -ggdb3 -o main.out main.c
gdb main.out
然后在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]
程序输出:
1
要让此功能在GDB 7.9.1、GCC 5.1中正常工作,我必须使用以下命令运行GDB:
LD_LIBRARY_PATH="$(dirname "$(gcc -print-libgcc-file-name)"):$LD_LIBRARY_PATH" gdb main.out
为了让libcc1.so
可见:这是最近的GCC组件,它向cc1
编译器公开了C API,但在Ubuntu 19.04上不再需要。然而,在一个最小化的环境中仍然需要它来支持C++:
main.cpp
#include <iostream>
int main() {
int i = 0;
std::cout << i << std::endl;
}
并且:
compile code int j = 1; i = j; asm("nop");
有几个结构不符合我的预期:
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?
asm volatile ("mov $abc, %eax")
这样的东西。在compile
命令返回后,$rax
仍然保持其原始值。GDB 7.10不支持源语言为汇编语言时的compile
命令,因此即使在调试使用汇编语言编写的函数时,这也无法正常工作。 - Peter Cordescompile
真的非常有限。但是它有潜力。 - Ciro Santilli OurBigBook.comstd::cout
的示例可以使用 -raw
参数重写为 compile code -raw #include <iostream> ^Mvoid _gdb_expr() { std::cout << "Hello\n"; }
(在此处将 ^M
替换为 Ctrl-V,Enter)。这对我有效。 - Ruslan-raw
的作用!不幸的是,我无法在Ubuntu 19.04上使其工作 :-( C++的hello world失败并显示“‘cout’ is not a member of ‘std’”,而一个空的main
则会在尝试时显示“warning: Could not find symbol "_ZSt4cout" for compiled module "/tmp/gdbobj-dxRNbH/out1.o".”。 - Ciro Santilli OurBigBook.com
mov
等指令,如何修改寄存器? - gdbset $eax = 42
。请参见更新。 - paxdiablo