标签:示例 ++ unsigned value inst RIP int3 断点
今天有人让我解释一下断点调试的原理,我就想先解释一下int3指令,就写了一篇短文。
单字节指令int3的二进制码是0xcc,它的效果是:
- 处理器执行到0xcc时,会陷入内核,执行int3的异常处理代码,比如给当前进程发送一个SIGTRAP信号。
就这么简单。剩下的就看信号处理程序如何发挥了。
我给出一个简单的代码,演示一下一个程序的 自我单步跟踪 如何实现:
#include <stdio.h>
#include <sys/mman.h>
#include <signal.h>
unsigned char old;
unsigned char *inst;
// RIP距离stack的当前位置正好192字节,详情参见rt_sigframe结构
#define PC_OFFSET 192
// value ++指令从main函数的第106字节开始,这个是从objdump -D看出来的。
static int i = 106;
// 这是我们单步跟踪的变量。
int value = 0;
// 打断点需要两步:
// 1. 保存原始单字节指令。
// 2. 替换为int3指令。
void breakpoint(char *inst)
{
old = *inst;
*inst = 0xcc;
}
void trap(int unused)
{
unsigned long *p;
// 恢复断点需要两步:
// 1. 恢复单字节为保存的指令。
// 2. PC寄存器回退一个字节。
p = (unsigned long*)((unsigned char *)&p + PC_OFFSET);
// 可以在这里来一个命令行查询更详细的程序当前状态,我这里仅仅一行打印,说明问题够了。
printf("current RIP: :%lx value:%d\n", *p, value);
inst[i] = old;
*p = *p - 1;
// 单步跟踪value的值:
// value ++正好需要15个字节的指令。
i += 15;
// 设置新的断点为下一个value ++
breakpoint(&inst[i]);
}
int main(int argc, char **argv)
{
unsigned char *page;
unsigned long rip;
signal(SIGTRAP, trap);
inst = (unsigned char *)main;
// addr按照4096对齐
page = (unsigned char *)((unsigned long)inst & 0xfffffffffffff100);
// 让main函数可写。
mprotect((void *)page, 4096, PROT_WRITE|PROT_READ|PROT_EXEC);
// 设置第一个断点为第一个value ++。
breakpoint(&inst[i]);
value ++;
value ++;
value ++;
value ++;
value ++;
value ++;
printf("value is %d\n", value);
}
来吧,看看效果:
[root@localhost test]# ./int3test
current RIP: :4006c6 value:0
current RIP: :4006d5 value:1
current RIP: :4006e4 value:2
current RIP: :4006f3 value:3
current RIP: :400702 value:4
current RIP: :400711 value:5
current RIP: :400720 value:6
value is 6
文章很短,可以仔细体会一下。
关于int3指令,下面这个链接解释了为什么int3是单字节指令:
http://www.cs.columbia.edu/~junfeng/09sp-w4118/lectures/int3/int3.txt
浙江温州皮鞋湿,下雨进水不会胖。
标签:示例,++,unsigned,value,inst,RIP,int3,断点 来源: https://blog.csdn.net/dog250/article/details/106267041
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。