今天有人让我解释一下断点调试的原理,我就想先解释一下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


浙江温州皮鞋湿,下雨进水不会胖。

int3断点指令的原理和示例相关推荐

  1. CPU Cache原理与示例

    CPU Cache原理与示例 基础知识 现在的 CPU 多核技术,都会有几级缓存,老的 CPU 会有两级内存(L1 和 L2),新的CPU会有三级内存(L1,L2,L3 ),如下图所示: 其中:  ...

  2. Swift与LLVM-Clang原理与示例

    Swift与LLVM-Clang原理与示例 LLVM 学习 从 简单汇编基础 到 Swift 不简单的 a + 1 作为iOS开发,程序崩溃犹如家常便饭,秉着没有崩溃也要制造崩溃的原则 每天都吃的很饱 ...

  3. Oracle 并行原理与示例总结

    <Oracle 并行原理与示例总结> 并行:把一个工作分成几份,分给不同进程同时进行处理. 进程层面 并发:多个会话同时进行访问,就是通常所说并发数.会话层面 数据库版本 LEO1@LEO ...

  4. 《Arduino开发实战指南:机器人卷》一3.6 编程原理与示例程序

    本节书摘来华章计算机<Arduino开发实战指南:机器人卷>一书中的第3章 ,第3.6节,黄文恺 伍冯洁 陈 虹 编著更多章节内容可以访问云栖社区"华章计算机"公众号查 ...

  5. TensorFlow XLA优化原理与示例

    TensorFlow XLA优化原理与示例 XLA概述 XLA(加速线性代数)是用于优化TensorFlow计算的线性代数的域特定编译器.结果是在服务器和移动平台上的速度,内存使用率和可移植性得到了改 ...

  6. 逆向工程核心原理图书-示例样本(无病毒)

    逆向工程核心原理图书-示例样本(无病毒) https://github.com/snappyJack/reverse-core

  7. 计算机体系结构 第1-2章 量化设计与分析基础/指令系统原理与示例

    第1章 量化设计与分析基础 计算机的分类类别 计算机系统结构定义和计算机的设计任务:指令集结构概念及要素 实现技术的趋势:技术发展的趋势 集成电路功耗的趋势:功耗的概念 可靠性:提高可靠性的方法 6. ...

  8. php怎么实现打印预览,JavaScript_js实现局部页面打印预览原理及示例代码,最近有朋友问js 如何打印预览 - phpStudy...

    js实现局部页面打印预览原理及示例代码 最近有朋友问js 如何打印预览,今天就来讲解一下,首先了解一下打印原理,其实局部打印页面很简单.就是把你需要打印的部分做一个起始标记,至于标记如何写,随便你写什 ...

  9. 华为 静态NAT---动态NAT---NAPT---Easy IP---NAT服务器工作原理和示例配置

    目    录 一.NAT简介 二.NAT好处: 三.静态NAT工作原理和示例配置 1. 静态NAT工作原理 2. 静态NAT配置示例 四.动态NAT工作原理和示例配置 1. 动态NAT工作原理 2.动 ...

最新文章

  1. 【OpenCV 4开发详解】图像仿射变换
  2. ASP.NET 中HttpRuntime.Cache缓存数据
  3. spring集成mongodb通过aop记录业务日志
  4. 把之前写的几个项目放到了github上
  5. python json模块
  6. Oracle dblink报错:ORA-01017、ORA-02063解决
  7. python 数学基础_Python3数学基础 - 随笔分类 - 既生喻何生亮 - 博客园
  8. Java 中单引号和双引号的区别
  9. FFmpeg开发(1)从mp4中提取aac音频
  10. 初级计算机英语,初级英语口语怎么学?
  11. oracle 物化视图 on demand,oracle物化视图的两个典型应用场景
  12. cv2.imread不能正常读取gif格式图片
  13. Xshell访问连接路由器的服务器
  14. ElasticSearch(待改)
  15. IOB寄存器的使用:IOB= TRUE 属性
  16. 美团酒店:如何收割新一代90后住宿需求? | 一点财经
  17. 描写火车站场景_求几段描写火车站的段落,而且是描写的极好的段落
  18. jzoj4879. 少女觉
  19. iOS底层原理探究 第一探. 事件传递和响应者链
  20. c语言编程培训网站,最新C语言编程培训

热门文章

  1. 操作系统底层工作的整体认识
  2. arduino与语音模块LDV7(LD3320)的串口通信实现简单语音控制
  3. 60个前端常用的实现方法(邮箱,手机号,url地址)
  4. 微信隐藏功能:微信提现怎么免手续费?勤俭持家的福音,2步做到
  5. postgresql查询锁表以及解除锁表
  6. PyCharm自动格式化代码
  7. 计算机视觉 马尔_计算机视觉概述
  8. Facebook要“变脸”,网友乐了:你这不就是抄微信嘛
  9. MySql练习---[SQL查询语句练习]
  10. 两少年玩防狼喷雾剂 致广州地铁发生踩踏