2011-03-30 126 views

回答

5

之前GCC 5 (1),我不知道一种方式来运行任意机器码,除非你真的输入机器码到内存,然后运行它。

如果你想在内存中运行的代码是已经,你可以将指令指针设置为开始,结束时断点,然后去。然后,在断点之后,将指令指针更改回其原始值。

但我实际上看不到这个用例。这并不意味着不是之一,只要你可以通过运行代码来做任何事情,你也可以通过直接修改寄存器,标志,内存等来实现。

例如,命令:

info registers 

将转储寄存器的当前值,同时:

set $eax = 42 

eax寄存器更改为42

您也可以通过这种方式改变内存:

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

此写入内存位置0xb7ffeca0一个字节,你也可以使用同样的方法来存储更广泛的数据类型。


(1) GCC 5允许编译和与compile code命令执行任意代码,如记录here

+0

如何修改寄存器,如果'mov'等不能直接运行? – gdb 2011-03-30 01:59:02

+0

@gdb:例如,您可以使用'set $ eax = 42'。查看更新。 – paxdiablo 2011-03-30 02:13:11

+0

你也可以演示如何用'set'来改变内存吗? – gdb 2011-03-30 02:22:53

0

编译代码命令,近GDB引入,允许代码编译和注射,文档:https://sourceware.org/gdb/onlinedocs/gdb/Compiling-and-Injecting-Code.html

实施例:

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

然后在GDB:

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

程序输出:

1 

为此,您需要最近的GDB和GCC 5.x.测试上GDB 7.9.1,GCC 5.1,具有:

export LD_LIBRARY_PATH="/path/to/gcc/install/lib64:$LD_LIBRARY_PATH" 

使得libcc1.so将是可见的:这是一个最近GCC组分暴露一个C API到cc1编译器。

还有如我所料一样return,没有工作的几个结构,所以我问为什么在:In the GDB compile code command, what language constructs behave exactly as if they were present in the original source?

+0

这似乎并没有像'asm volatile (“mov $ abc,%eax”)',当语言是C.在'compile'命令返回后,'$ rax'仍然有它的原始值。当源语言为asm时,GDB 7.10不支持'compile'命令,所以即使在调试用asm编写的函数时也不起作用。 – 2016-02-17 04:42:09

+0

@PeterCordes谢谢,我没有尝试过。 'compile'确实非常有限。但有潜力。 – 2016-02-17 10:22:30

+0

对于C/C++来说,它看起来非常方便,但不适合仅仅试验不同输入的指令。我想你可以使用一个C变量作为输出操作数,但是你需要一条指令来使用它。在这一点上,将指令放在文件中,汇编/链接它,以及单步操作可能会更容易。感谢您指出,尽管这不是* this *问题的好答案。 >< – 2016-02-17 10:28:20