注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

Tsecer的回音岛

Tsecer的博客

 
 
 

日志

 
 

gdb之jump指令及修改函数返回值  

2012-09-06 23:43:12|  分类: gdb源代码分析 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
一、进程调试
主要发生在一些调试环境中,文件的编译我们可以认为比较麻烦,或者说我们并不像真正的修改源代码,因为测试的代码修改之后还要改回来;麻烦不说,如果修改之后测试代码没有改回来,那么问题就更加严重了,所以我们尽量希望通过gdb工具来环保的修改程序的行为,这样我们就可能使用到下面的一些方法和指令。
二、修改变量值
这个其实是比较简单的,就是大家比较常见的通过gdb的内置命令set来完成,例如,一个函数的返回值保存在一个变量iRet变量中,如果我们想修改这个变量的值,可以通过
set iRet=10
来动态设置变量iRet的值为10,这样其实可以改变运行的流程。
三、跳过一些代码
由于一些代码可能会对系统做持久性操作,例如删除文件,写数据库等操作,我们希望跳过一些函数或者代码段的执行,此时就可以使用jump指令来完成该功能。
gdb的jump指令是对汇编语言中的jump指令的模拟,或者说是对C语言中goto语言的模拟。在被调试任务刚开始运行的时候,就可以通过jump指令来动态的修改被调试任务的PC指针,这个做法简单粗暴,但是比较有效。
gdb中代码
jump_command
  resolve_sal_pc (&sal);    /* May error out */
……
  addr = sal.pc;
……
  proceed (addr, TARGET_SIGNAL_0, 0);

关键的proceed函数中对于这个解析出来的地址的处理为
void
proceed (CORE_ADDR addr, enum target_signal siggnal, int step)
  if (addr == (CORE_ADDR) -1)
    {
……
    }
  else
    {
      write_pc (addr);直接修改了被调试任务的PC指针,所以被调试任务开始运行之后直接从pc地址直接继续运行。
    }
四、修改函数返回值。
有些调用者并没有保存调用函数的返回值,而是直接把函数调用作为一个判断语句,例如
if (func())
{}
else
{}
此时我们如何修改这个函数func的返回,从而让程序执行和返回值相反的操作。
此时其实是通过体系结构相关的一些指令来完成,但是对于特定的处理器,这个指令却是可以确定的。因为386下函数的返回值都是通过eax保存的,所以我们可以直接修改这个寄存器的值即可,而修改的指令同样还是set,即
set $eax=10
五、一个测试的例子
[root@Harry changereturn]# cat func.cpp
#include <stdio.h>
int test()
{
    printf("In test function\n");
    return true;
}
int main()
{
    if (test())
    {
    printf("return is true\n");
}
else
{
    printf("Return is false\n");
}
}
[root@Harry changereturn]# g++ func.cpp -g -o func.c.exe
[root@Harry changereturn]# gdb func.c.exe
GNU gdb (GDB) Fedora (7.0-3.fc12)
Copyright (C) 2009 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 "i686-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/tsecer/CodeTest/changereturn/func.c.exe...done.
(gdb) b main
Breakpoint 1 at 0x8048496: file func.cpp, line 9.
(gdb) r
Starting program: /home/tsecer/CodeTest/changereturn/func.c.exe

Breakpoint 1, main () at func.cpp:9
9        if (test())
Missing separate debuginfos, use: debuginfo-install glibc-2.11.2-3.i686 libgcc-4.4.2-7.fc12.i686 libstdc++-4.4.2-7.fc12.i686
(gdb) s
test () at func.cpp:4
4        printf("In test function\n");
(gdb) jump 5  通过jump5直接设置地址到源代码第5行,可以看到接下来的输出中没有打印"In test function\n"
Continuing at 0x8048486.
return is true

Program exited normally.
(gdb) r
Starting program: /home/tsecer/CodeTest/changereturn/func.c.exe

Breakpoint 1, main () at func.cpp:9
9        if (test())
(gdb) s
test () at func.cpp:4
4        printf("In test function\n");
(gdb) finish
Run till exit from #0  test () at func.cpp:4
In test function
0x0804849b in main () at func.cpp:9
9        if (test())
Value returned is $1 = 1
(gdb) set $eax=0 修改test函数返回值,此时主函数执行流程被修改
(gdb) c
Continuing.
Return is false

Program exited normally.
(gdb)
  评论这张
 
阅读(2688)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017