所谓技多不压身,最近准备抽空学习一些逆向的内容,在拓宽自己的安全知识的同时也多尝试一些新的领域。

基础概念

1. 什么是逆向工程

在编写代码时,我们的目标是将源代码转换为可执行程序,而逆向工程,顾名思义,就是将编译链接好的程序反过来恢复到“代码级别”的内容。这里的“代码级别”指的是程序逻辑的表述形式,而不是完全还原到源代码。原因在于,源代码的编译过程是不可逆的,我们无法从编译后的程序中完全恢复出原始源代码。

逆向工程通常需要借助工具对程序进行反编译,将二进制文件转化为汇编代码,有时甚至可以进一步恢复成更高级的伪代码。

像日常用到的一些C\C++程序在经过编译和链接后,程序为机器码,从而可以直接被执行程序的CPU等理解与使用。这类程序我们使用IDA、OD等逆向工具,只能将其中的机器码恢复为汇编代码状态,然后通过读汇编代码来理解程序的运行过程与机制。相比这一类编译运行类的程序,依靠java虚拟机、.NET等运行的程序,由于所生成的字节码(供虚拟机解释运行)仍然具有高度抽象性,所以这类程序的逆向得到的伪代码的可读性更强,有时甚至接近于源码。但是在生成字节码的过程中,变量名函数名丢失的,所以伪代码中这些内容都是随机命名的,会给代码阅读造成一定的障碍。

2. 编译型与解释型程序

编译型程序:程序在执行前会被编译成机器语言文件,运行时不需重新翻译,可直接供机器理解与运行,一般这类程序执行效率高,依赖编译器,跨平台性差。例如:C、C++。

解释型程序:程序在使用编程语言编写后,不需要编译,以文本的方式存储原始代码,在运行时,通过对应的解释器将其解释成机器码后执行,执行时逐条读取解释每个语句再执行。执行效率较低,具有较强的跨平台性。

3. 可执行文件

常见的可执行文件有ELF格式(Linux)和PE格式(Windows):

ELF文件(Executable and Linkable Format):Linux系统中常见的可执行文件格式,包含程序段和数据段的信息。

PE文件(Portable Executable):windows系统中常见的可执行文件格式,包含了代码、资源、导入/导出表等信息。

具体的这两类文件的结构后续专门抽出一些时间来详细分析学习一下。

4. 加密与混淆

在逆向工程中,加密保护代码混淆是开发者用来对程序进行保护的两种常见的手段,这些技术的目的主要是为了增加逆向分析的难度,用来保护代码逻辑、数据安全或机密。

代码混淆(Obfuscation)

代码混淆在维基百科中的解释为“将计算机程序的源代码或机器代码,转换成功能上等价,但是难于阅读和理解的形式的行为”。混淆后的代码,会讲原本具有明确定义的类名、字段、函数名等专换成无意义的字母/符号,这些混淆后的内容对于计算机来说,执行逻辑是正常的,但是对于人来说具有很强的不可读性,进而达到对代码的保护作用。

有个看到的很好的例子:

你想去超市买水果,但又不想让人知道,于是你先去买了卫生纸回来,又去了健身房,然后又去超市买了可乐,最后才去超市买了水果。

这样一来,别人对你的行动目的就不是明确的,需要多次猜测推理才能知道你的目的。代码混淆的逻辑便是如此,代码开发者们为了隐藏目的,会在代码里加入各种多余的垃圾指令和代码,把原来的逻辑拆分成各种怪癖语法,从而达到防破解的目的。

代码加密(Encryption)

和混淆相同,加密是保护程序逻辑和数据的另一种手段,其主要目标是通过对代码内容进行加密,避免静态分析工具能够直接读取或修改。加密后的代码在运行时需要被动态解密后才能被执行,也进一步增加了逆向的难度。

当然加密的方式很多,后续遇到对应加密方法再详细学习。

5. 静态调试与动态调试

若像前面说的那样,仅仅是通过机器码梳理出来的伪代码分析程序运行过程,叫做静态调试,而动态调试则是让程序”跑”起来,从而帮助我们更直观的观察到程序的运行过程。

静态调试

静态调试指的是在程序不运行的情况下,通过对其二进制文件或反编译后的代码进行分析,以推断程序的逻辑和功能。静态调试是逆向工程的基础步骤,可以在不执行程序的情况下发现潜在的漏洞或分析其行为。

适用场景:适用于初步了解程序的结构和逻辑,特别是在程序运行可能带来风险(如恶意软件)时,静态调试是一个安全的分析方式。

动态调试

动态调试是在程序运行的过程中,通过实时观察程序的行为来分析其逻辑和功能。动态调试可以帮助我们更直观地了解程序的执行流程,尤其是在定位复杂问题或验证静态分析结论时具有重要作用。

适用场景:动态调试适合需要观察程序运行时的行为,特别是当某些逻辑仅在特定输入下触发时(如条件分支或动态加载的代码)。

参考

https://blog.csdn.net/Javachichi/article/details/140484897
https://www.dingxiang-inc.com/blog/post/691
https://www.cnblogs.com/hed10ne/p/introduction-to-reverse.html