加密与解密 调试篇(一)
加密与解密 调试篇(一)
文章目录
- 加密与解密 调试篇(一)
- 前言
- 调试器原理笔记
- 调试技术概览
- 断点
- 单步执行
- 输出调试信息
- 日志
- 事件追踪
- 栈回溯
- 《Python灰帽子》
- 软断点
- 硬件断点
- 内存断点
前言
现在开始对《加密与解密》第二篇的内容开始学习回顾。第二部分被称为“调试篇”,从内容上看主要涵盖对常见调试器与反编译器的介绍与使用。根据自己的计划,在每部分把涉及的常见工具进行复习回顾,对使用不熟练的工具进行重点学习,对这些工具背后的技术原理进行学习剖析。原理剖析方面目前应该不会进行很深,一是自己积累达不到,二是自己也是在熟悉学习的过程中。之前编写的《CE入门笔记》也算是工具篇的一部分了。根据目前自己的安排,以及《加密与解密》的结构设计,首先对调试器的相关知识进行复习掌握,会把涉及的硬件相关知识、调试API、基础的Demo实例进行研究分析。涉及的参考资料包括软件调试、软件加密技术内幕、Python灰帽子等。关于工具的学习,目前考虑包括CE、OD(x64dbg包含其中)、WinDBG(重点)、Sysinternals等。
调试器原理笔记
调试技术概览
此部分内容参考自软件调试
断点
断点是使用调试器进行调试时最常用的调试技术之一。基本思想是在某一个位置设置一个“陷阱”,当CPU执行到这个位置时便“跌入陷阱”,即停止执行被调试的程序,中断到调试器中,让调试者进行分析和调试。
常见的断点种类有三种:代码断点、数据断点以及IO断点。
追踪点(tracepoint)是断点的一种衍生形式,基本思路是,设置追踪点之后,调试器将其认为是一个特殊的断点进行处理。当运行到该点时,系统向调试器报告断点事件,调试器收到后发现是追踪点,就按追踪点定义的方式进行处理,通常是进行日志记录。在这过程中调试器会迅速中断并迅速恢复,所以对用户来说感觉不太到这个追踪点的存在。
条件断点,其实原理和断点一致,不过它附加了其他的条件进行判断,每次中断后如果不符合条件就恢复,如果满足就中断
单步执行
分为以下几种:
- 汇编级别的单步执行。它是靠在CPU相应的单步执行标志来实现的,以x86为例,它就是靠在EFLAGS寄存器的陷阱标识(Trap Flag,TF)位,使CPU每执行一步触发一个调试异常(INT 1),中断到调试器
- 源代码(高级语言)级别的单步。也是靠汇编级别的单步实现的,不过它在每一步运行结束后会检查高级语言对应的一条语句是否完成,通常是通过符号文件中的源代码行信息来判断的
- 每次执行一个程序分支,又称为分支到分支单步跟踪。x86中,通过设置DbgCtl MSR寄存器的BTF标识后,再设置TF标识,可以使CPU执行到下一个分支指令时触发调试异常。WinDBG中使用
tb
命令 - 每次执行一个任务(线程),即当指定任务被调度时中断到调试器。x86中,每当CPU切换到一个新的任务时,它会检查任务状态段(TSS)中的T标志。如果为1,那么产生调试异常。但是目前大多数调试器未实现该功能
输出调试信息
这个是一种“古老”的调试方法,即在关键点上输出调试信息。
- Windows内核:
DbgPrint
以及DbgPrintEx
- Windows用户态:
OutputDebugString
- Linux内核:
printk
- Linux用户态:
printf
日志
一种常用方法
事件追踪
事件追踪机制使用结构化的二进制形式来记录数据,观察时将格式文件转化为文本形式,适用于监视频繁而且复杂的软件过程,如监视文件访问与网络通信等
ETW(Event trace for Windows)是Windows中的事件追踪机制
栈回溯
栈回溯是记录和探索程序执行轨迹的极佳方法
《Python灰帽子》
调试器能够跟踪一个进程运行时的状态,一般的调试器都具备以下几个功能:
- 运行, 可以启动一个进程
- 暂停执行,可以停止一个进程
- 单步执行,可以操作一个进程,使其当前运行线程按照opcode逐步运行
对于一个调试器而言,它的内部实际上是一个无限循环,并一直在等待调试事件的发生。当一个调试事件发生时,调试器将被激活,并调用相应的处理例程处理该事件。当事件处理例程被调用时,被调试的目标暂停执行并等待调试器做出如何继续的指示。一个调试器必须捕获以下几种常见的调试事件:
- 断点触发
- 非法内存操作
- 由被调试程序抛出的异常
软断点
软断点可以使目标进程运行到特定到某个位于特定位置的指令时暂停运行。它实质上一个单字节长的指令。该指令可以使被调试的目标进程暂停执行并将控制权转交给调试器的异常处理例程。在Intel系统中,这个常用的指令是int 3
,opcode是单字节值0xcc
。
- 当调试器被告知要在某一个内存地址上设置一个断点时,调试器会首先读取这个地址的第一个字节并将其存储到断点列表中,紧接着将
0xcc
写入那个内存地址 - 当CPU执行到
int 3
时,触发断点事件,调试器捕捉到该事件 - 调试器检查EIP是否指向之前设置了断点的内存地址,如果找到,将此处原始字节恢复
这里我们做了个实验,使用x32dbg下一个断点,然后使用CE查看断点处的内存信息,分为执行到断点前与执行到断点后两部分:
通过两者对比,我们可以清晰的看到,在未执行到断点处时,断点处的代码为“cc 62 f8 ff”,执行之后恢复为“e8 62 f8 ff”。
硬件断点
在x86CPU中,存在一组称为调试寄存器的特殊寄存器,它们包括DR0-DR7。其中
- DR0 - DR3被用于存储所设硬件断点的内存地址,这意味每一时刻最多使用4个硬件寄存器
- DR4 - DR5保留使用
- DR6称为调试状态寄存器,记录了上次断点触发所产生的的调试事件类型信息
- DR7是硬件断点的激活开关,并存储着各个断点的触发条件信息
通过DR7的设置,可以为断点设定多种触发条件:
- 当位于一个特定内存地址上的指令执行时触发条件
- 当数据被写入一个特定内存地址时触发条件
- 当数据被读出或者写入(不包括执行)一个特定非可执行内存时触发断点
对于DR7而言,0-7位为硬件开关位,DR0-DR3每个寄存器对应两个。低位为局部断点,高位为全局断点。8-15位不用于普通调试
16-31位用于控制对应的断点类型与长度,DR0-DR3每个寄存器占4位,前两位对应断点类型,后两位对应断点长度
数值 | 类型 | 长度 |
---|---|---|
00 | 仅当执行对应地址时中断 | 1字节长 |
01 | 仅当向对应地址写数据时中断 | 2字节长 |
10 | 当向对应地址进行IO操作时中断 | 8字节或者未定义(其他CPU) |
11 | 当向对应地址读写数据时都中断,但是非执行 | 4字节长 |
内存断点
内存断点是本质不是真正的断点,当一个调试器设置一个内存断点时,调试器本质上是改变一个内存区域或者一个内存页的访问权限。
- 页可执行,但是读写会导致非法内存操作异常
- 页可读,进程只能从这个内存页中读取数据,写入或者执行都会导致异常
- 页可写,运行写入数据
- 保护页,对保护页上任何类型的访问将导致一次性异常,之后这个内存页会恢复到之前的状态
加密与解密 调试篇(一)相关推荐
- 加密与解密 调试篇 静态分析技术 (一)文件类型/窗口/定位
目录 1.文件类型分析 2.静态反汇编 我们思索ida的分析过程 2.ida的配置 ida.cfg 反汇编选项(Disassembly) ASCII字符串和符号(ASCC strings & ...
- OD使用教程10 - 调试篇10|解密系列
OD使用教程10 - 调试篇10 让编程改变世界 Change the world by program 大家或许有所察觉了,随着我们课程的不断深入学习,我们感觉自身逆向的"内功&quo ...
- Java开发中的加密、解密、签名、验签,密钥,证书,这篇就够了,赶紧收藏起来
OpenSSL和keytool 先说一下两个重要的工具 OpenSSL:OpenSSL整个软件包大概可以分成三个主要的功能部分:SSL协议库libssl.应用程序命令工具以及密码算法库libcrypt ...
- 浅析android手游lua脚本的加密与解密(番外篇之反编译的对抗)
前言 去年在看雪论坛写了一篇<浅析android手游lua脚本的加密与解密>的精华文章,今年写一篇番外篇,将一些lua反编译对抗的内容整合一起,并以3个实例作为说明(包括2018腾讯游 ...
- [密码学基础][每个信息安全博士生应该知道的52件事][Bristol Cryptography][第15篇]RSA-OAEP和ECIES的密钥生成,加密和解密
这是一系列博客文章中最新的一篇,该文章列举了"每个博士生在做密码学时应该知道的52件事":一系列问题的汇总是为了让博士生们在第一年结束时知道些什么.通过描述RSA-OAEP和ECI ...
- OD使用教程7(上)- 调试篇07|解密系列
OD使用教程7(上)- 调试篇07 让编程改变世界 Change the world by program 小甲鱼觉得,掌握逆向的思维尤为重要. 所以在咱的OD使用教程中,不单会告诉你怎么去逆向这 ...
- OD使用教程11(困境) - 调试篇11|解密系列
OD使用教程11(困境) - 调试篇11 让编程改变世界 Change the world by program 这节课我们的主题是:困境! 可能你会觉得,跟着小甲鱼老师的视频走,程序的加密显得好像十 ...
- OD使用教程6 - 调试篇06|解密系列
OD使用教程6 - 调试篇06 让编程改变世界 Change the world by program 这一讲开始,小甲鱼带大家接触真正程序的逆向.其实也没啥大不了的,也就是对之前所学的知识进行巩 ...
- 图解SSL和加密解密-原理篇
1.SSL原理 Secure Sockets Layer(安全的套接字层)位于TCP/IP协议与各种应用层协议之间,为数据通讯提供安全支持.用于保障在Internet上数据传输之安全,利用数 ...
- OD使用教程3(中) - 调试篇03|解密系列
OD使用教程3(上) - 调试篇03 让编程改变世界 Change the world by program 关于系统API Windows应用程序运行在Ring3级别(包括我们的倚天剑:OllyDB ...
最新文章
- Codeforces 846 B Math Show DFS + 贪心
- 利用ES6进行Promise封装总结
- 基于Springboot实现旅游网站系统开发
- 字符串中 去掉字符串前后空格以、'\t'(tab) C函数实现,附sscanf正则方式
- DataSet 去除重复的行
- Jackson 框架使用说明,轻易转换JSON【转】
- Java 中初始化 List 集合的 6 种方式!
- c++ 函数模板_C/C++编程笔记:C++入门知识,深入解析C++函数和函数模板
- 销售到出仓所经历的表
- C++ pair的基本用法总结
- python开发网络小工具_Python 实现简单网络应用程序开发
- 弹性地基梁板实用计算_建筑地基基础设计规范要点
- 视频教程-Matlab小白入门必备教程-Matlab
- android 位移传感器 坐标,鼠标的工作原理及位移测量的实现方法
- springBoot+JSP搭建项目
- android平台的oa系统架构,基于Android的移动OA办公系统的设计与实现
- ES6模板字符串(循环、函数)
- 8.敏捷软件开发框架 - 规模化敏捷框架SAFe
- 9.0 OTA升级logo不更新,输入法不更新
- uniapp 实现富文本编辑器【小程序端】
热门文章
- 海思35系列型号排行_11月手机性能排行榜:小米10至尊纪念版排名第三
- K-th Number Poj - 2104 主席树
- Nodejs 使用Protobuf
- C Programming Style 总结
- 多块盘制作成一个lvm
- VS2010 调试C++项目 fatal error LNK1123 错误解决的方法
- C++test对多变参数的函数打桩处理技巧
- IOS客户端Coding项目记录导航
- PHP版本中的VC6,VC9,VC11,TS,NTS区别
- Ubuntu 12.04 LTS 键盘快捷键(转)