用GDB修改可执行文件的代码和变量(gdb)

修改可执行文件中的代码和变量好像也没有什么比较好的工具,今天leviathan问我用“set write on”相关的问题,我才发现GDB就是可以很方便完成这个工作的工具,下面我向大家介绍一下使用方法。
另,在GDB文档中介绍这个方法也 能修改CORE文件的内容,但即使我读了这块的代码,还是对修改CORE文件毫无思路也没成功过,所以本文就不介绍对CORE文件的修改了。

一般情况下GDB是以只读方式打开可执行文件的,如果需要改变可执行文件,需要在读入文件以前,用GDB启动参数“--write”或者命令“set write on”用可读写方式打开可执行文件。如果文件已经打开了可执行文件,就需要使用exec-file重新以读写方式打开可执行文件,注意如果你还没打开可执行文件,就一定要使用file命令读入,因为exec-file不会重新读入符号信息。

还有要注意的是,因为修改只能修改section的内容,所以能修改的变量只能是非0的全局变量,内容是O的变量会被放入bss。

下面举例修改变量内容:
cat 1.c
#include <stdio.h>
int a = 1;
int
main(int argc,char *argv[],char *envp[])
{
       printf ("%d\n", a);
       return 0;
}
gcc -g 1.c
./a.out
            #注意这个输出
gdb
GNU gdb 6.8-debian
Copyright (C) 2008 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.   Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
(gdb) set write on       #打开功能
(gdb) file ./a.out        #打开文件
Reading symbols from /home/teawater/gdb/a.out...done.
(gdb) p a = 100       #修改变量的文件中的值
$1 = 100
./a.out
100              #注意修改后的输出

下面举例修改代码内容:
cat 1.c
#include <stdio.h>
void
cool (void)
{
       printf ("Call function cool.\n");
}
int
main(int argc,char *argv[],char *envp[])
{
       cool ();
       return 0;
}
gcc -g 1.c
./a.out
Call function cool.       #注意现在有输出
gdb --write ./a.out        #使用--write直接打开可写功能
GNU gdb 6.8-debian
Copyright (C) 2008 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.   Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu"...
(gdb) disas cool
Dump of assembler code for function cool:
0x000000000040050c <cool+0>:       push     %rbp              #注意改之前这条指令
0x000000000040050d <cool+1>:       mov       %rsp,%rbp
0x0000000000400510 <cool+4>:       mov       $0x40062c,%edi
0x0000000000400515 <cool+9>:       callq   0x4003f8 <puts@plt>
0x000000000040051a <cool+14>:       leaveq
0x000000000040051b <cool+15>:       retq    
End of assembler dump.
(gdb) set *(unsigned char *)(0x000000000040050c) = 0xc3       #修改指令
(gdb) disas cool
Dump of assembler code for function cool:
0x000000000040050c <cool+0>:       retq                          #改之后这指令发生了变化
0x000000000040050d <cool+1>:       mov       %rsp,%rbp
0x0000000000400510 <cool+4>:       mov       $0x40062c,%edi
0x0000000000400515 <cool+9>:       callq   0x4003f8 <puts@plt>
0x000000000040051a <cool+14>:       leaveq
0x000000000040051b <cool+15>:       retq    
End of assembler dump.
. /a.out                     #现在没有输出了 因为cool函数直接返回了

 

常用的gdb命令 
backtrace 显示程序中的当前位置和表示如何到达当前位置的栈跟踪(同义词:where) 
breakpoint 在程序中设置一个断点 
cd 改变当前工作目录 
clear 删除刚才停止处的断点 
commands 命中断点时,列出将要执行的命令 
continue 从断点开始继续执行 
delete 删除一个断点或监测点;也可与其他命令一起使用 
display 程序停止时显示变量和表达时 
down 下移栈帧,使得另一个函数成为当前函数 
frame 选择下一条continue命令的帧 
info 显示与该程序有关的各种信息 
jump 在源程序中的另一点开始运行 
kill 异常终止在gdb 控制下运行的程序 
list 列出相应于正在执行的程序的原文件内容 
next 执行下一个源程序行,从而执行其整体中的一个函数 
print 显示变量或表达式的值 
pwd 显示当前工作目录 
pype 显示一个数据结构(如一个结构或C++类)的内容 
quit 退出gdb 
reverse-search 在源文件中反向搜索正规表达式 
run 执行该程序 
search 在源文件中搜索正规表达式 
set variable 给变量赋值 
signal 将一个信号发送到正在运行的进程 
step 执行下一个源程序行,必要时进入下一个函数 
undisplay display命令的反命令,不要显示表达式 
until 结束当前循环 
up 上移栈帧,使另一函数成为当前函数 
watch 在程序中设置一个监测点(即数据断点) 
whatis 显示变量或函数类型 

你可能感兴趣的:(用GDB修改可执行文件的代码和变量(gdb))