前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >x86_64汇编调试程序初步

x86_64汇编调试程序初步

作者头像
一见
发布2018-12-24 10:18:29
7150
发布2018-12-24 10:18:29
举报
文章被收录于专栏:蓝天蓝天

寄存器说明:

代码语言:javascript
复制
rdi 存第1个参数(值或地址)
rsi 存第2个参数
rdx 存第3个参数
rcx 存第4个参数
r8 存第5个参数
r9 存第6个参数
rax 第1个返回值
rdx 第2个返回值
rbx、rbp、r12、r13、r14、r15 用作数据存储,遵循被调用者使用规则,调用子函数之前需要先保存
r10、r11 用作数据存储,遵循调用者使用规则,使用之前需要先保存
rsp 指向栈顶

观察参数传递,被调试的源代码如下:

代码语言:javascript
复制
/* 01 */ #include
/* 02 */ #include
/* 03 */ void f(int a, const char* b) {
/* 04 */     write(1234, b, strlen(b));
/* 05 */ }
/* 06 */ int main() {
/* 07 */     f(2018, "hello\n");
/* 08 */     return 0;
/* 09 */ }

优化方式编译程序:

代码语言:javascript
复制
g++ -g -O2 -o x x.cpp

实践目标:

在gdb中让write改写到标准输出。

设置两个观察点,一是main函数,二是write函数:

代码语言:javascript
复制
(gdb) b main
(gdb) b write

运行程序:

代码语言:javascript
复制
reakpoint 1, main () at x.cpp:6
6       /* 06 */ int main() {
Missing separate debuginfos, use: debuginfo-install glibc-2.17-196.tl2.3.x86_64 libgcc-4.8.5-4.el7.x86_64 libstdc++-4.8.5-4.el7.x86_64
(gdb) n
7       /* 07 */     f(2018, "hello\n");
(gdb) disassemble
Dump of assembler code for function main():
0x0000000000400550 <+0>:     sub    $0x8,%rsp
=> 0x0000000000400554 <+4>:     mov    $0x400710,%esi // 0x400710为第二个参数的地址
0x0000000000400559 <+9>:     mov    $0x7e2,%edi // 0x7e2为第一个参数的值
0x000000000040055e <+14>:    callq  0x400660 <f(int, char const*)>
0x0000000000400563 <+19>:    xor    %eax,%eax
0x0000000000400565 <+21>:    add    $0x8,%rsp
0x0000000000400569 <+25>:    retq
End of assembler dump.
(gdb) p (char*)0x400710
$1 = 0x400710 "hello"
(gdb) p 0x7e2
$2 = 2018
(gdb) s
f (a=2018, b=0x400710 "hello") at x.cpp:3
3       /* 03 */ void f(int a, const char* b) {
(gdb) info reg
rax            0x400550 4195664
rbx            0x0      0
rcx            0x40     64
rdx            0x7fffffffe1a8   140737488347560
rsi            0x400710 4196112 // 第二个参数地址(4196112的十六进制为0x400710)
rdi            0x7e2    2018 // 第一个参数的值2018(2018的十六进制为0x7e2)
rbp            0x0      0x0
rsp            0x7fffffffe0a8   0x7fffffffe0a8
r8             0x7ffff75b5e80   140737343348352
r9             0x0      0
r10            0x7fffffffdd40   140737488346432
r11            0x7ffff7218b10   140737339558672
r12            0x40056c 4195692
r13            0x7fffffffe190   140737488347536
r14            0x0      0
r15            0x0      0
rip            0x400660 0x400660
eflags         0x202    [ IF ]
cs             0x33     51
ss             0x2b     43
ds             0x0      0
es             0x0      0
fs             0x0      0
gs             0x0      0
(gdb) c
Continuing.
Breakpoint 2, 0x00007ffff72e0840 in write () from /lib64/libc.so.6
(gdb) info reg
rax            0x5      5
rbx            0x0      0
rcx            0x10     16
rdx            0x5      5 // write的第三个参数值
rsi            0x400710 4196112 // write的第二个参数值
rdi            0x1234   4660 // write的第一个参数值
rbp            0x0      0x0
rsp            0x7fffffffe0a8   0x7fffffffe0a8
r8             0x7ffff75b5e80   140737343348352
r9             0x0      0
r10            0x7fffffffdc70   140737488346224
r11            0x7ffff72e0840   140737340377152
r12            0x40056c 4195692
r13            0x7fffffffe190   140737488347536
r14            0x0      0
r15            0x0      0
rip            0x7ffff72e0840   0x7ffff72e0840
eflags         0x202    [ IF ]
cs             0x33     51
ss             0x2b     43
ds             0x0      0
es             0x0      0
fs             0x0      0
gs             0x0      0
(gdb) p $rdi
$4 = 4660
(gdb) set $rdi=7777 // 修改寄存器rdi的值
(gdb) p $rdi
$6 = 7777
(gdb) set $rdi=1
(gdb) c
Continuing.
hello // 正常输出到了标准输出,如果不修改rdi的值,将看不到输出“hello”
[Inferior 1 (process 6722) exited normally]

掌握此基础,就可以用来修改无源代码的程序等,比如希望jstatd在指定的端口上监听,而不是一个值为0的随机端口号,请参见《防火墙内JVisualVM连接jstatd解决方案》。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018-12-05 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
数据保险箱
数据保险箱(Cloud Data Coffer Service,CDCS)为您提供更高安全系数的企业核心数据存储服务。您可以通过自定义过期天数的方法删除数据,避免误删带来的损害,还可以将数据跨地域存储,防止一些不可抗因素导致的数据丢失。数据保险箱支持通过控制台、API 等多样化方式快速简单接入,实现海量数据的存储管理。您可以使用数据保险箱对文件数据进行上传、下载,最终实现数据的安全存储和提取。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档