Assembly 如何在gdb中调用程序集?
在gdb中,我可以使用Assembly 如何在gdb中调用程序集?,assembly,gdb,Assembly,Gdb,在gdb中,我可以使用call来运行函数,但是如果我想运行一些额外的程序集呢?在GCC 5(1)之前,我不知道如何运行任意机器代码,除非您将机器代码输入内存,然后运行它 如果要运行内存中已经存在的代码,只需将指令指针设置为开始,即结束时的断点,然后转到。然后,在断点之后,将指令指针更改回其原始值 但我实际上看不到这个用例。这并不意味着没有,只是通过运行代码可以完成的任何事情,也可以通过直接修改寄存器、标志、内存等来实现 例如,命令: info registers 将转储寄存器的当前值,同时:
call
来运行函数,但是如果我想运行一些额外的程序集呢?在GCC 5(1)之前,我不知道如何运行任意机器代码,除非您将机器代码输入内存,然后运行它
如果要运行内存中已经存在的代码,只需将指令指针设置为开始,即结束时的断点,然后转到。然后,在断点之后,将指令指针更改回其原始值
但我实际上看不到这个用例。这并不意味着没有,只是通过运行代码可以完成的任何事情,也可以通过直接修改寄存器、标志、内存等来实现
例如,命令:
info registers
将转储寄存器的当前值,同时:
set $eax = 42
将eax
寄存器更改为42
您还可以通过以下方式更改内存:
set *((char*)0xb7ffeca0) = 4
这会将单个字节写入内存位置0xb7ffeca0
,您还可以使用相同的方法存储更广泛的数据类型
(1) GCC 5允许您使用
编译代码
命令编译和执行任意代码,如文档所示。编译代码
命令
在7.9左右引入,它允许代码编译和注入,文档:
main.c
#include <stdio.h>
int main(void) {
int i = 0;
printf("%d\n", i);
return 0;
}
然后在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;
}
有几个构造没有像我预期的那样工作:
:返回
- 包括:
在Ubuntu 19.04中 在上面的main.c上,没有包含的compile code printf('asdf\n')
有效,因为我们已经在源代码中包含了它,但是如果我在没有包含的空printf
上尝试它,它会失败:main()
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]
gdb命令行:1:1:警告:内置函数“printf”的隐式声明不兼容 gdb命令行:1:1:注意:包括“”或提供“printf”声明 gdb命令行:1:8:警告:字符常量对于其类型太长 gdb命令行:1:8:警告:传递'printf'的参数1将从整数生成指针,而不使用强制转换[-Wint conversion] gdb命令行:1:8:注意:应为“const char*”,但参数的类型为“int” gdb命令行:1:1:警告:格式不是字符串文字,也没有格式参数[-Wformat security]
C++中UPUTU 19.04:
compile code std::cout << "Hello world\n";
编译代码std::cout如果无法直接运行mov
etc,如何修改寄存器?@gdb:例如,您可以使用设置$eax=42
。请参阅更新。您是否也可以演示如何使用set
更改内存?内存中存在执行特定汇编指令的情况。它可能是一个多媒体命令,其结果可能不容易计算。或者一些通常的命令,这些命令比手工编辑寄存器/内存更容易执行,很可能会出错。制作一个pythonapi命令来实现这一点会很有趣。找到一些空闲的可执行内存,在那里编译、编写命令,将ESP改为它,将最后一个命令设置为跳回。很可能很难:-)这似乎不适用于asm volatile(“mov$abc,%eax”)
,当语言为C时。在compile
命令返回后,$rax
仍有其原始值。当源语言为asm时,GDB 7.10不支持compile
命令,因此即使在调试用asm编写的函数时,该命令也不起作用。@PeterCordes谢谢,我没有尝试过<代码>编译
确实非常有限。但也有潜力。是的,对于C/C++来说,它看起来非常方便,但不仅仅是为了试验指令对不同输入的作用。我想你可以用一个C变量作为输出操作数,但是你需要一条指令来使用它。在这一点上,只需将指令放在文件中,组装/链接它,然后单步执行,可能会更容易。谢谢你指出这一点,尽管这不是这个问题的好答案。您的std::cout
示例可以用-raw
参数重写为compile code-raw#include^Mvoid\u gdb\u expr()-(C++的Hello World与<代码>失败,CUT”不是“STD”< /C>的成员,空<代码>主< /代码>失败,代码< >警告:当我尝试时,找不到编译模块“/tMP/gdBOBjdxrnb/Out1.o”。的符号“yZST4cOUT”。
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]
compile code std::cout << "Hello world\n";
*** 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.