Reverse
定义
软件代码逆向主要指对软件的结构,流程,算法,代码等进行逆向拆解和分析。
应用领域
主要应用于软件维护,软件破解,漏洞挖掘,恶意代码分析。
要求
- 熟悉如操作系统,汇编语言,加解密等相关知识
- 具有丰富的多种高级语言的编程经验
- 熟悉多种编译器的编译原理
- 较强的程序理解和逆向分析能力
流程:
- 使用
strings/file/binwalk/IDA
等静态分析工具收集信息,并根据这些静态信息进行google/github
搜索 - 研究程序的保护方法,如代码混淆,保护壳及反调试等技术,并设法破除或绕过保护
- 反汇编目标软件,快速定位到关键代码进行分析
- 结合动态调试,验证自己的初期猜想,在分析的过程中理清程序功能
- 针对程序功能,写出对应脚本,求解出 flag
逆向 tips
编码风格
每个程序员的编码风格都有所不同,熟悉开发设计模式的同学能更迅速地分析出函数模块功能
集中原则
程序员开发程序时,往往习惯将功能相关的代码或是数据写在同一个地方,而在反汇编代码中也能显示出这一情况,因此在分析时可以查看关键代码附近的函数和数据。
代码复用
代码复用情况非常普遍,而最大的源代码仓库 Github 则是最主要的来源。在分析时可以找一些特征(如字符串,代码风格等)在 Github 搜索,可能会发现类似的代码,并据此恢复出分析时缺失的符号信息等。
七分逆向三分猜
合理的猜测往往能事半功倍,遇到可疑函数却看不清里面的逻辑,不妨根据其中的蛛丝马迹猜测其功能,并依据猜测继续向下分析,在不断的猜测验证中,或许能帮助你更加接近代码的真相。
区分代码
拿到反汇编代码,必须能区分哪些代码是人为编写的,而哪些是编译器自动附加的代码。人为编写的代码中,又有哪些是库函数代码,哪些才是出题人自己写的代码,出题人的代码又经过编译器怎样的优化?我们无须花费时间在出题人以外的代码上,这很重要。如果当你分析半天还在库函数里乱转,那不仅体验极差,也没有丝毫效果。
耐心
无论如何,给予足够的时间,总是能将一个程序分析地透彻。但是也不应该过早地放弃分析。相信自己肯定能在抽茧剥丝的过程中突破问题。
动态分析
动态分析的目的在于定位关键代码后,在程序运行的过程中,借由输出信息(寄存器,内存变化,程序输出)等来验证自己的推断或是理解程序功能
主要方法有:调试,符号执行,污点分析
X64debug
使用指南:[原创]x64dbg入门之工具使用实战-软件逆向-看雪-安全社区|安全招聘|kanxue.com
Ollydebug
使用指南:OllyDBG完美教程(超强入门级) - xueyoo - 博客园 (cnblogs.com)
IDA动态调试
使用指南:ida使用技巧之动态调试_ida动态调试_parafish_0的博客-CSDN博客
算法和数据结构识别
- 常用算法识别
如Tea/XTea/XXTea/IDEA/RC4/RC5/RC6/AES/DES/IDEA/MD5/SHA256/SHA1
等加密算法,大数加减乘除、最短路等传统算法
- 常用数据结构识别
如图、树、哈希表等高级数据结构在汇编代码中的识别。
【2021.12.25】ctf逆向中常见加密算法和编码识别_C4cke的博客-CSDN博客
RC4
RC4加密算法 - shelmean - 博客园 (cnblogs.com)
TEA
TEA系列加解密算法详解_tea算法_Markus.Zhao的博客-CSDN博客
CHACHA20
ChaCha20-Poly1305 算法 - 掘金 (juejin.cn)
代码混淆
比如使用OLLVM
,movfuscator
,花指令
,虚拟化
及SMC
等工具技术对代码进行混淆,使得程序分析十分困难。
那么对应的也有反混淆技术,最主要的目的就是复原控制流。比如模拟执行
和符号执行
OLLVM
OLLVM简单入门 - huhuf6 - 博客园 (cnblogs.com)
movfuscator
注意,这种混淆的去混淆比较麻烦一般都是硬看,出题人不会出太难的逻辑
movfuscator混淆了解一下 CTF_坚强的女程序员的博客-CSDN博客
花指令
CTF逆向基础----花指令总结_逆向花指令_非著名不专业Re选手的博客-CSDN博客
smc
局部代码加密技术,常考项
探究SMC局部代码加密技术以及在CTF中的运用 - 知乎 (zhihu.com)
保护壳
保护壳类型有许多,简单的压缩壳可以归类为如下几种
unpack -> execute
直接将程序代码全部解压到内存中再继续执行程序代码
unpack -> execute -> unpack -> execute ...
解压部分代码,再边解压边执行
unpack -> [decoder | encoded code] -> decode -> execute
程序代码有过编码,在解压后再运行函数将真正的程序代码解码执行
对于脱壳也有相关的方法,比如单步调试法
,ESP定律
等等
反调试
反调试意在通过检测调试器等方法避免程序被调试分析。比如使用一些 API 函数如IsDebuggerPresent
检测调试器,使用SEH异常处理
,时间差检测等方法。也可以通过覆写调试端口、自调试等方法进行保护。TLS反调也是最近考的比较常见的技术
IsDebuggerPresent
反调试技术- IsDebuggerPresent,原理 与 反反调试_helloDesword的博客-CSDN博客
SEH异常处理
深入解析结构化异常处理(SEH) - by Matt Pietrek_dvlinker的博客-CSDN博客
非常规逆向思路
非常规逆向题设计的题目范围非常之广,可以是任意架构的任意格式文件。
- lua/python/java/lua-jit/haskell/applescript/js/solidity/webassembly/etc..
- firmware/raw bin/etc..
- chip8/avr/clemency/risc-v/etc.
但是逆向工程的方法学里不惧怕这些未知的平台格式,遇到这样的非常规题,我们也有一些基本的流程可以通用
https://ctf-wiki.org/reverse/windows/unpack/packer-introduction/)