我会根据我的阅读进度,以章节为单位同步更新发帖。此笔记比较简略,但均保留了关键内容,并加入了我个人的理解。不过,阅读本笔记不代表阅读此书,建议搭配原书复习。
第一章 基础知识
什么是加密与解密
加密: 开发者通过一些方法保护自己的程序中的代码逻辑。目的是使代码逻辑不易被拥有黑客技术的人获取,从而保护自己的程序不被盗版或是破解。
解密: 通过逆向分析技术,还原程序的代码逻辑,目的是突破程序限制,或是开发功能相似的程序。
加密与解密的过程,外至用户层,深至内核层,涉及范围之广,知识量之庞大。经过这些年的发展,加密与解密的对抗过程,宛如战场上攻守双方的不断拼杀。
逆向工程: 根据现有程序,还原代码逻辑的过程。从软件的视角出发,“可执行程序 —-> 反编译 —-> 源码”的过程就是逆向工程。
逆向工程可实现的目的大致可分为三类:
[ol]
[/ol]
除此之外,逆向工程还可以帮助安全人员分析对抗木马病毒,帮助开发者寻找BUG或是学习他人的开发经验。
这里笔者需要指出,由于编程语言的不同,对程序的逆向也会有不同的特点。部分编程语言所写的程序可以近乎完美地还原出源代码,如:java、打包成pyc的python脚本。而部分编程语言则无法直接还原出真正的源代码,只能做到相似,如:C/C++。
逆向工程所涉及的知识往往枯燥而庞杂,因此,笔者建议各位同学:
[ol]
[/ol]
逆向分析技术
逆向分析技术总体上分为两类:静态分析技术、动态分析技术。二者各有利弊。
除开这些技术层面的分析,如果你能够厘清程序各部分的功能的作用,做到使用层面的分析,对你技术分析是有一定程度帮助的。
静态分析技术:
使用如:IDA、Ghrida等静态分析工具,对程序进行反汇编/反编译,得到程序的汇编代码/源码,通过阅读代码的方式,搞清代码逻辑的过程,称为静态分析。静态分析工具往往将程序以片段的形式呈现,能有效地将各模块分开,并显示各模块之间的关系。静态分析时,程序是没有运行的。而有些时候,程序的功能是需要运行起来才能够正确分析,这是静态分析无法做到的,也是其缺点。
动态分析技术:
虽然静态分析技术能够帮助我们了解程序各模块的功能以及它们之间的关系,但是具体的技术细节我们却无法得到。比如有这么一个程序,它每次运行都会生成一个随机数,而你必须输入这个随机数才可以进一步使用这个软件。那么很显然,静态分析是无法得到每次运行的随机数的。这时候,就需要运用动态分析技术。
以下有三点我们需要动态分析技术的原因:
[ol]
[/ol]
文本字符
计算机中存储的信息都是用二进制数表示的。屏幕上显示的文本也不例外。如果要处理文本,就必领先把文本转换为相应的二进制数。在学习过程中,我们会与各类字符打交道。这些字符在Windows里扮演着重要的⻆色。
ASCII与Unicode字符集
ASCII: 简单来说,就是使用一个字节的二进制数来表示字符。
Unicode: 使用两个字节来表示字符。
下图为常见ASCII表。
IMG_0119.jpg (374.86 KB, 下载次数: 0)
下载附件
2023-5-22 17:33 上传
字节存储顺序
计算机界使用两种字节存储顺序:大端(Big-endian)、小端(Little-endian)
大端: 高位字节存入低地址,低位字节存入高地址
小端: 高位字节存入高地址,低位字节存入低地址
一个字节拥有八个比特位。 其中,前四个比特位称为高位字节。后四个比特位称为低位字节。比如12345678,1234位于高字节, 5678位于低字节。
将12345678h写入以1000h为开头的内存中,两种存储方式的表现如下图:
IMG_0120.jpg (84.75 KB, 下载次数: 0)
下载附件
2023-5-22 17:33 上传
这两种顺序并无优劣之分。而计算机实际使用什么存储顺序,取决于CPU。Intel的CPU一般采用小端序
Windows操作系统
Win32 API函数
API: 全称”Application Programing Interface“(应用程序编程接口)。是开发者调用Windows系统服务的一个接口。
IMG_0121.jpg (65.67 KB, 下载次数: 0)
下载附件
2023-5-22 17:33 上传
Windows系统自带的Kernel.dll、User.dll、GDI.dll提供了大量重要的API
除上述三个外,还有其他的提供很多重要功能的dll。这里不列举。
由于ASCII和Unicode字符集使用的字节数不同,Windows为了兼容,在实现同一个功能时,可以根据字符集的不同而选择不同的函数。比如MessageBox函数,它拥有两个版本,一个是MessageBoxA(ANSI版),另一个是MessageBoxW(Unicode版)。一般来说,Windows都是以结尾的A/W来表明函数适用的字符集。
WOW64: 全称“Windows-on-Windows-64-bit“。是64位Windows操作系统的子系统,它的存在使得32位程序得以在64位操作系统中运行。
WOW64勾住了所有从32位代码转变至原生64位系统的代码路径,也勾住了64位原生系统需要调用至32位用户模式代码的所有路径。在进程创建的过程中,进程管理器(process manager)将原生的64位Ntdll.dll和针对WOW64进程的32位Ntdll.dll映射到进程地址空间中。当加载器的初始化过程被调用时,它调用WOW64.dll内部的WOW64初始化代码。然后WOW64建立起32位Ntdll所要求的启动环境,将CPU模式切换至32位下,并开始执行32位加载器。从这个点开始,执行过程继续执行,就如同该进程运行在原生的32位系统之上。
Ntdll.dll,User32.dll和Gdi32.dll的特殊32位版本位于\Windows\Syswow64文件夹下。它们调用到WOW64.dll中,而不是发出原生的32位系统调用指令。WOW64转变到原生的64位模式下,并捕获到与系统调用有关的参数(将32位指针转化为64位指针),并发出对应的原生64位系统调用。当原生的系统调用返回时,WOW64把任何输出参数,如果有必要的话,在返回至32位模式之前从64位转换成32位格式。
简单来说,比如:64位系统中存着的32位Ntdll.dll想和内核层沟通时,无法直接发送32位的系统调用指令,而会经过WOW64转换成64位系统调用指令后再发送,之后接收到的64位的结果会经由WOW64转回32位。
Windows消息机制
Windows系统中有两种消息队列:一种是系统消息队列;另一种是应用程序消息队列。计算机的所有输人设备由Windows监控。当一个事件发生时,Windows 先将输人的消息放人系统消息队列,
再将输人的消息复制到相应的应用程序队列中,应用程序中的消息循环在它的消息以列中检素每个 消息并发送给相应的窗口两数。 一个事件从发生到到达处理它的窗口⻄数必须经历上述过程。x
因为Windows本身是由消息驱动的,所以在调试程成中我们会得到相当底层的答案。因此我们需要了解这一机制。
值得注意的是消息的非抢先性,即不论事件的急与缓,总是按到达的先后排队(一些系统消息除外), 而这可能导致一些外部实时事件得不到及时的处理。
虚拟内存
32位操作系统最高支持4GB的物理内存。程序的数据和代码都在同一个地址空间中,不必区分代码段和数据段。但是,为了防止出错,程序员们引入了”虚拟内存“。这一机制通过映射(map)的方式实现。简单地说,虚拟内存的实现方法和过程如下:
[ol]
[/ol]
Windows是一个分时多任务操作系统。CPU时间会被分为一片片,供不同的应用程序使用。在属于程序A的时间片里,虚拟地址空间不会存在与程序A无关的内容。
看不明白上面的步骤也没关系,但需要明白以下几点:
64位操作系统也采用虚拟内存机制。只不过是寻址空间大小不止4GB,而是16TB。