首页 > 系统相关 >逆向基础知识——软断点、硬件断点和内存断点

逆向基础知识——软断点、硬件断点和内存断点

时间:2023-04-07 19:23:36浏览次数:50  
标签:函数 基础知识 指令 内存 寄存器 栈底 断点

1 寄存器

EAX : 累加器,加减和比较运算都借助 EAX 来达到指令优化的效果,乘除必须在 EAX 中进行。

EDX:数据寄存器,EAX 的延伸。

ECX:计数器

ESI:源变址寄存器,存储输入数据流位置信息,“读”

EDI:目的变址寄存器,指向相关数据操作结果存放位置,“写”

ESP:栈指针,始终指向函数栈的最顶端

EBP:基址指针,被用于指向函数栈的最顶端

EBX:通用寄存器

EIP:始终指向当前正在执行的指令

2 函数调用堆栈的过程

(引用开始:https://blog.51cto.com/u_6871414/5896878)

img

img

main 函数 :

  • 将调用 main 的栈底地址入栈。
  • 让原本指向调用方栈底的 ebp(栈底指针)指向当前函数 main 的栈底。
  • 给当前函数 main 开辟栈帧。
  • 对开辟的栈帧进行初始化。
  • 将三个局部变量放入栈中。
  • 开辟 sum 函数的形参内存,从右往左,依次把 b 的值,a 的值入栈。
  • 将 main 函数的下一行指令入栈,然后调用函数 sum

sum 函数:

  • 将 main 的栈底地址入栈。
  • 让原本指向 main 函数栈底的 ebp(栈底指针)指向当前函数 sum 的栈底。
  • 给当前函数 sum 开辟栈帧。
  • 对开辟的栈帧进行初始化。
  • 将形参变量放在 eax 寄存器中。
  • 将 eax 寄存器中的值赋值给了局部变量 tmp。
  • 局部变量的值,通过 eax 寄存器返回。
  • 出栈,并把出栈元素赋值给 ebp(栈底指针),因为调用 sum 函数刚开始时,把 main 函数的栈底地址放入栈中,出栈操作,让 ebp(栈底指针)指向了 main 函数的栈底地址。
  • 最后,函数结束 ret 指令干了两件事:先出栈;再将出栈的值放到 CPU 的 PC 寄存器中。因为 PC 寄存器中永远放的是下一次执行指令的地址,所以就顺理成章的在函数调用完之后依旧接着原来的代码继续执行。

补充:

C 语言中,每个栈帧对应着一个未运行完的函数。栈帧中保存了该函数的返回地址和局部变量。

总结:

1、函数的运行都是在栈上开辟内存。

2、栈是通过 esp(栈顶指针)、ebp(栈底指针)两个指针来标识的。

3、对于栈上的访问都是通过 ebp(栈底指针)的偏移来访问的。

4、在调用一个函数时,有两件事情要做:先将调用函数的下一行指令的地址压入栈中;再进行跳转。

5、在函数调用时检查函数是否申明、函数名是否相同、函数的参数列表是否匹配、函数的返回值多大。

  • ① 如果 【函数的返回值<=4 个字节】,则返回值通过寄存器 eax 带回。

  • ② 如果 【4<函数的返回值<=8 个字节】,则返回值通过两个寄存器 eax 和 edx 带回。

  • ③ 如果 【函数的返回值>8 个字节】,则返回值通过产生的临时量带回。

6、函数结束 ret 指令干了两件事:先出栈;再将出栈的值放到 CPU 的 PC 寄存器中。因为 PC 寄存器中永远放的是下一次执行指令的地址,所以就顺理成章的在函数调用完之后依旧接着原来的代码继续执行。

(引用结束:https://blog.51cto.com/u_6871414/5896878)

3 断点

3.1 软断点

一条常见的指令

0x44332211:    8BC3    MOV EAX, EBX
#指令地址      操作码     汇编指令

为了在此设置一个软断点,使得 CPU 执行到此能够停止,没错,需要中断指令 INT3。这里采用的方式是将双字节操作码替换为 INT3 中断指令(0xCC),设置成为断点后:

0x44332211:    CCC3    MOV EAX, EBX
#指令地址      操作码     汇编指令

注意这里操作码发生了变化

注意概念: 指令的机器码 = 操作码 + 操作数

当程序执行至此触达中断后,调试器会捕获这个事件,接着调试器会检查 EIP 时候正指向一个此前被我们设置了断点的内存地址,如果这个地址在调试器内部断点列表中,那么调试器就会将之前存储的操作码字节数据写回对应内存地址。当程序恢复后,正确的操作码将被执行。下一次再运行程序将不会有该断点的信息。
以上是一次性断点的操作,而永久性断点还会再多做一步:在 CPU 执行完正确操作码后将断点恢复,也就是保留断点状态。下一次再运行程序该断点依然存在。

但是需要注意一个问题,当你修改了可执行程序的某个字节数据后,也就改变了他的 CRC(循环冗余校验)值。CRC 用于校验一个程序是否被篡改,一些程序会在程序执行前检验程序是否被篡改,还有一些软件往往会检测自己在内存中运行代码的 CRC,一旦检测被篡改就会立即自行崩溃,这是一个有效防御软断点的技术。

3.2 硬件断点

硬件断点是通过位于 CPU 上的一组特殊寄存器来实现的,称为调试寄存器。比如 x86 架构的 CPU 上有 8 个调试寄存器(DR0-DR7),分别用于设置和管理硬件断点。

  • DR0-DR3 负责存储硬件断点的内存地址,所以最多只能同时使用 4 个硬件断点。
  • DR4 和 DR5 保留使用。
  • DR6 为调试状态寄存器,记录上一次断点触发所产生的调试事件类型信息。
  • DR7 是硬件断点的激活开关,存储着各个断点的触发信息条件。
    与软断点不同的是,硬件断点使用 1 号中断(INT1)实现,INT1 一般被用于硬件断点和单步事件。

CPU 每次试图执行一条指令时,都会首先检查当前指令所在地址是否被设置了有效的硬件断点,除此之外还会检查当前指令包含的操作数是否位于被设置了硬件断点的内存地址。

3.3 内存断点

内存断点本质上不是一个真正的断点。当调试器设置一个内存断点时,实际上是改变一个内存区域或一个内存页的权限。操作系统对内存页会设置访问权限,可执行、可读、可写、保护页,这些访问权限可以组合。

保护页的特性可以帮助我们实现断点机制。

任何对于有页保护的区域的内存访问都会导致 CPU 暂停执行当前进程并处发一个保护页调试异常,然后我们就可以对访问缓冲取得指令代码进行仔细的检查,并判断出应用程序如何处理缓冲区中的内容。

内存断点可以绕过软断点的指令篡改问题。

标签:函数,基础知识,指令,内存,寄存器,栈底,断点
From: https://www.cnblogs.com/Zyecho/p/17297141.html

相关文章

  • 基于cpu和内存进行pod扩容,创建hpa
    基于cpu和内存进行pod扩容,创建hpa创建镜像mkdirphpcdphptouchdockerfiletouchindex.phpvimdockerfileFROMphp:5-apacheADDindex.php/var/www/html/index.phpRUNchmoda+rxindex.phpvimindex.php<?php$x=0.0001;for($i=0;$i<=1000000;$i++){......
  • 免费分享前端面试题,vue面试题,TypeScript基础知识点 PDF格式
    免费分享前端资料,面试题,电子书接前端开发,带徒弟,一对一教学,远程协助,bug修改微信:......
  • 结构体基础知识
    定义struct变量后,在main函数的调用时//定义时struct不可以省略structsudents1;//这个可以省略s1.name="name";structsudents2={"学生","18"};cout<<s2.name结构体数组在main函数中structStudentstuarray[3]={{"张三",21,34},//stuarray[1]{&qu......
  • 内存淘汰策略|页面置换算法对比总结
    在学习【操作系统】【MySQL】【Redis】后,发现其都有一些缓存淘汰的策略,因此一篇小文章总结一下。目前还没着笔,初略一想MySQL和操作系统应该都是使用的年轻代和老生代的改进策略,而Redis使用的是随机抽的策略。MySQLMySQL中存在一个内存缓存池,BufferPool。里面存在着控制块和......
  • 如何获取 Android 设备的CPU核数、时钟频率以及内存大小
    DeviceYearClass的主要功能是根据CPU核数、时钟频率以及内存大小对设备进行分级。下表是Facebook公司提供的分级标准,其中Year栏表示分级结果。以下类就是从Facebook的开源项目DeviceYearClass中拿出来的packagecom.yirui.youbao.util;importandroid.annotati......
  • Java基础知识点(抽象类)
    封装:对象代表什么,就得封装对应的数据,并提供数据对应的行为。一:抽象方法和抽象类的定义将共性的行为(方法)抽取到父类之后,由于每一个子类执行的内容是不一样,所以,在父类中不能确定的具体的方法体,该方法就可以定义为抽象方法。抽象类:如果一个类中存在抽象方法,那么该类就必须声明抽象类。......
  • Java基础知识点(抽象类)
    封装:对象代表什么,就得封装对应的数据,并提供数据对应的行为。一:抽象方法和抽象类的定义将共性的行为(方法)抽取到父类之后,由于每一个子类执行的内容是不一样,所以,在父类中不能确定的具体的方法体,该方法就可以定义为抽象方法。抽象类:如果一个类中存在抽象方法,那么该类就必须声明抽象类。......
  • MYSQL基础知识之多表查询
    1、多表关系在数据表中,各个表结构之间存在着各种关系(一对一、一对多、多对多)。一对一关系:示例:学生与学生详情的关系,一个学生对应一个详细情况,一个详细情况对应一个学生。实现:在任意一方加入外键,关联另外一方的主键,并且设置外键为唯一的UNIQUE。一对多关系:示例:学生与班级的关......
  • memcachaed内存缓存优化
    ①使用场景分类展示(当然只要是短期内不频繁更换的都可以用。。。只要你内存够)②安装方法推荐网址:http://www.lai18.com/content/627794.html③操作方法$mencache=newMemcache();$host='xx.x.xxx.xx'; $port='11211';  //默认端口设置:$memcache->set('class_name','tes......
  • JavaScript超大文件上传解决方案:分片断点上传(一)
    ​ 前段时间做视频上传业务,通过网页上传视频到服务器。视频大小小则几十M,大则1G+,以一般的HTTP请求发送数据的方式的话,会遇到的问题:1,文件过大,超出服务端的请求大小限制;2,请求时间过长,请求超时;3,传输中断,必须重新上传导致前功尽弃; 解决方案:1,修改服务端上传的限制配置;Nginx以......