CTF学习——加密与解密基础

https://www.kanxue.com/book-4-11.htm 

学习解密建议掌握:

汇编语言一定得学好;
至少掌握一门高级语言;
最好掌握Win32编程,WinSDK程序设计就是API方式的Windows程序设计,学习Windows API将使您更深入地了解Windows工作方式。此类书籍有Charles Petzold著的《Windows程序设计》(以C来讲解)。
有精力,再看看《Windows核心编程》这类书,相信会使你内力大增的。
有了这些基础,再参考《加密与解密》(第二版)这本书,你将会扣开加解密的大门。

 

高级语言编写的程序有两种形式,一种编译成机器语言在CPU上执行,如Visual C ++、PASCAL等。由于机器语言与汇编语言几乎是一一对应的,因此可将机器语言转化成汇编语言,这个过程称为反汇编(Disassembler)。另一种高级语言是一边解释一边执行的,称之为解释性语言。如Visual Basic 3.0/4.0、Visual FoxPro等,这类语言编译的程序可以被还原成高级语言的原始结构,这个过程称为反编译(Decompiler)。

由于Win32程序内存寻址使用的是相对简单的平坦寻址模式,并且Win32程序大量调用系统提供的API,而Win32平台上的调试器如SoftICE等恰好有针对API设置断点的强大功能,因而这些特点都给动态跟踪破解带来极大的方便。

因为程序的作者用的是高级语言,Windows又是提倡“透明 ”,不希望程序员知道底层的操作 , 而只提供给他们高层的接口, 而相当多的高级函数调用某个一定的底层函数,所以解密者经常在底层函数上下断点。所以在Windows中,只要Windows的函数被使用,想对任何寻找蛛丝马迹的人隐藏什么东西是比较困难的。
为什么要对软件进行动态分析呢?这主要是因为:
1、许多软件在整体上完成的功能,一般要分解成若干模块来完成,而且后一模块在执行时,往往需要使用其前一模块处理的结果,这一结果我们把它叫中间结果。如果我们只对软件本身进行静态地分析,一般是很难分析出这些中间结果的。而只有通过跟踪执行前一模块,才能看到这些结果。另外,在程序的运行过程中,往往会在某一地方出现许多分支和转移,不同的分支和转移往往需要不同的条件,而这些条件一般是由运行该分支之前的程序来产生的。如果想知道程序运行到该分支的地方时,到底走向哪一分支,不进行动态地跟踪和分析是不得而知的。
2、有许多软件在运行时,其最初执行的一段程序往往需要对该软件的后面各个模块进行一些初始始化工作,而没有依赖系统的重定位。
3、有许多加密程序为了阻止非法跟踪和阅读,对执行代码的大部分内容进行了加密变换,而只有很短的一段程序是明文。加密程序运行时,采用了逐块解密,逐块执行和方法,首先运行最初的一段明文程序,该程序在运行过程中,不仅要完成阻止跟踪的任务,而且还要负责对下一块密码进行解密。显然仅对该软件的密码部分进行反汇编,不对该软件动态跟踪分析,是根本不可能进行解密的。

逆向工程

对于(网络)黑客来说,“hack”是褒义词,“crack”则是贬义词,后者指那些寻找网络漏洞并进行恶意攻击的行为。
对于(软件)黑客来说,“crack”只是个中性词,泛指对程序修改的行为,更喜欢称自己为“逆向工程”学者。

逆向工程(Reverse Engineering)定义为:"the process of analyzing a subject system to identify the system's components and their interrelationships and create representations of the system in another form or at a higher level of abstraction." (Source: Chikofsky and Cross)
 
如果认为:
“源代码 → 编译器 → 可执行程序”的过程是“顺向工程”的话;
“可执行程序 → 反编译器或人工反编译 → 源代码”的过程就是逆向工程。

将逆向工程包括的内容可以分为3类:

 

1.软件使用限制的去除,或软件功能的添加
(1) 按照计算机类别,可以分为个人微型计算机、小型机、中型机、大型机等;
(2) 按照操作平台或处理器类型,可以分为windows、MAC、UNIX,x86,risc等
(3) 按照限制类型,可以分为软件使用时间限制,软件功能模块限制、软件运行条件限制(软件狗等)、软件注册限制等
(4) 可以是软件功能限制的去除,也可以是软件功能的添加。

 

2.软件源代码的再获得或二进制代码水平的Debug
(1) 按照计算机类别,可以分为个人微型计算机、小型机、中型机、大型机等;
(2) 按照操作平台,可以分为windows、MAC、UNIX等
(3) 按照软件层次,可以分为普通应用层软件与操作系统源等。

 

3.硬件的复制、模拟
由此观之,一般所谓的“软件破解”只是逆向工程中非常初级的一小部分。
坦白地讲,现在的逆向工程,真实目的就是为了再利用。据此,个人可以学习别人的编程技术及技巧,公司可以窥探别人的商业软件秘密,或开发与之兼容的软件;(二进制代码层面的)Debug自然也是其中重要的目的之一。
据说,著名的杀毒软件AVP代码写的实在太有条理,因此很容易被分析后“再利用”。有心人不仅可以将其病毒特征库改头换面后再推出,也可以利用逆向工程得到AVP某些模块的源代码,加入自己开发的产品中。

成为一个“逆向工程”大师,应该具有如下特征:
1.永远保存好奇心,崇尚自由。这能促使探索;也能抵抗商业利欲的侵袭;有了它,枯燥的代码世界才有了生气。
2.勤奋与毅力:“让我们搞清楚作为一名Cracker最需要具备的基本条件,其实那并不是扎实的汇编功底和编程基础。你可以完全不懂这些,CRACKING的秘诀就是勤奋+执着!记住并能做到这两点,你一样可以变得优秀。”
3.精通至少一门编程语言,不仅仅是Coding,更重要的是编程思想。RAD工具也许是容易学的,但你要明白隐藏在它背后的机制。
4.扎实的汇编功底和系统编程的知识。
5.能发现“美丽”。是的,你能在枯燥的二进制代码中见到美,那是数学和对称的美丽。卓越的编译器优化能力,简洁而又高效的代码,都能使你领略到她的存在。

 

逆向工程的终极网站woodmann上列出那些大师的名字:Matt Pietrek,Jeffrey Richter,John Robbins ......他们的专著是每个程序员都应该阅读的:《Windows95系统程式设计打奥秘》、《Windows核心编程》、《应用程序调试技术》......

 

ASCII字符集

美国信息交换标准码(ASCII)是一个7位的编码标准,包括26个小写字母、26个大写字母、10个数字、32个符号、33个控制代码及空格,总共128个代码。

CTF学习——加密与解密基础_第1张图片

Unicode是ASCII字符编码的一个扩展,只不过在Windows中用2个字节对其进行编码,也称为“宽字符集”(Widechars)。Unicode是一种双字节编码机制的字符集,使用0~65535之间的双字节无符号整数对每个字符进行编码。在Unicode中,所有的字符都是16位,包括所有的7位ASCII码都被扩充为16位(注意,高位扩充的是零)。例如,字符串“pediy”的ASCII码是:
70h 65h 64h 69h 79h
其Unicode码的十六进制是:
0070h 0065h 0064h 0069h 0079h
Intel处理器在内存中,一个字存入存储器要占有相继的2个字节,这个字存放时就按Little-Endian方式存入,即低位字节存入低地址,高位字节存入高地址,如图所示。 

CTF学习——加密与解密基础_第2张图片

两种编码区别:
 Big-Endian 高位字节存入低地址,低位字节存入高地址,依次排列;
 Little-Endian 低位字节存入低地址,高位字节存入高地址,反序排列。

CTF学习——加密与解密基础_第3张图片 

Win32 API函数

CTF学习——加密与解密基础_第4张图片

在NT架构下,Win32 API能接受Unicode和ASCII两种字符集,而其内核则只能使用Unicode。所有这些操作对用户来说都是透明的,但这些字符串的转换需要占用系统资源。

 WOW64(Windows-on-Windows 64-bit)是64位Windows操作系统的子系统,可以使大多数32位应用程序在不作修改的情况下运行在64位版本上。

简单地说,虚拟内存的实现方法和过程如下。

 

① 当一个应用程序被启动时,操作系统就创建一个新进程,并给每个进程分配2GB的虚拟地址(不是内存,只是地址)。
② 虚拟内存管理器将应用程序的代码映射到那个应用程序的虚拟地址中的某个位置,并把当前所需要的代码读取到物理地址中(注意:虚拟地址与应用程序代码在物理内存中的位置是没有关系的)。
③ 如果使用动态链接库DLL,DLL也会被映射到进程的虚拟地址空间中,在需要的时候才被读入物理内存中。
④ 其他项目(例如数据、堆栈等)的空间是从物理内存中分配的,并被映射到虚拟地址空间中。
⑤ 应用程序通过使用它的虚拟地址空间中的地址开始执行,然后虚拟内存管理器把每次的内存访问映射到物理位置。
看不明白上面的步骤也不要紧,但要明白以下几点。

  • 应用程序是不会直接访问物理地址的。
  • 虚拟内存管理器通过虚拟地址的访问请求来控制所有的物理地址访问。
  • 每个应用程序都有相互独立的4GB寻址空间,不同应用程序的地址空间是隔离的。
  • DLL程序没有自己的“私有”空间,它们总是被映射到其他应用程序的地址空间中,作为其他应用程序的一部分运行。因为如果它不和其他程序处于同一个地址空间,应用程序就无法调用它。

使用虚拟内存的好处是:简化了内存的管理,并可弥补物理内存的不足;可以防止多任务环境下各个应用程序之间的冲突。

你可能感兴趣的:(ctf)