一.作用对象:
对软件的结构,流程,算法,代码等进行逆向拆解和分析。
二.应用:
软件维护,软件破解,漏洞挖掘,恶意代码分析。
三.流程:
- 使用等静态分析工具收集信息,并根据这些静态信息进行搜索;
- 研究程序的保护方法,并设法破除或绕过保护;
- 反汇编目标软件,快速定位到关键代码进行分析;
- 结合动态调试,在分析的过程中理清程序功能;
- 针对程序功能,写出对应脚本,求解出 flag。
四.Tips:
(1)集中原则
程序员开发程序时,往往习惯将功能相关的代码或是数据写在同一个地方,而在反汇编代码中也能显示出这一情况,因此在分析时可以查看关键代码附近的函数和数据。
(2)代码复用
最大的源代码仓库 Github 则是最主要的来源,在分析时可以找一些特征(如字符串,代码风格等)在 Github 搜索,可能会发现类似的代码,并据此恢复出分析时缺失的符号信息等。
(3)七分逆向三分猜
进行合理的猜测,并根据猜测逐步向下分析,有助于更加接近代码的真相。
(4)区分代码
(5)耐心
给予足够的时间,不要过早的放弃分析。
五.动态分析
(1)目的:在于定位关键代码后,在程序运行的过程中,借由输出信息(寄存器,内存变化,程序输出)等来验证自己的推断或是理解程序功能。
(2)主要方法:调试,符号执行,污点分析。
(3)X64debug
- 分析步骤:分析程序功能;
- 查壳,看目标程序是否有壳;
- 分析目标程序
- 将目标程序用x64dbg(实际上是x32dbg)打开,看看x64dbg的界面
- 通过x64dbg的字符串搜索功能来查看内存中加载的字符串,具体操作步骤为:CPU(反汇编)窗口->鼠标右键->搜索->选择模块(根据个人需求选择,一般选择当前模块,前提是得先执行到主模块)->字符串
- 单步到主模块(单步调试快捷键和od一样,F7单步步入,F8单步步过),双击该字符串即可跳到反汇编窗口中相应位置
- 双击该字符串即可跳到反汇编窗口中相应位置。
- 下软件断点,运行程序,观察是何处调用了该代码(鼠标点击相应行,按下F2即可快速使用软件断点),下软件断点后,地址处会变为红色,断点窗口能看到相应信息。
- 让程序运行起来(快捷键F9),输入注册信息,点击确认,等待命中软件断点
- 程序的EIP指向了我们的软件断点
- 单步步过,一直走到返回ret,即可查看上层代码
- 找出注册成功、注册失败的判断依据,使用x64dbg的代码修改功能,将对应的注册失败验证跳过,即可完成破解
- 保存到文件(反汇编窗口右键->补丁->修补文件)
- 知识点总结:
- 相应界面的查看:CPU(反汇编)窗口、寄存器窗口、内存窗口、栈窗口
- 常用快捷键:F2下软件断点、F7单步步入、F8单步步过、F9运行程序
- 常用功能:
- 字符串搜索:CPU(反汇编)窗口->鼠标右键->搜索->选择模块(根据个人需求选择,一般选择当前模块,前提是得先执行到主模块)->字符串
- 保存修改到文件:反汇编窗口右键->补丁->修补文件
Ollydebug
- 窗口及其功能
- 反汇编窗口:显示被调试程序的反汇编代码,标题栏上的地址、HEX 数据、反汇编、注释可以通过在窗口中右击出现的菜单 界面选项->隐藏标题 或 显示标题 来进行切换是否显示。用鼠标左键点击注释标签可以切换注释显示的方式。
- 寄存器窗口:显示当前所选线程的 CPU 寄存器内容。同样点击标签 寄存器 (FPU) 可以切换显示寄存器的方式。
- 信息窗口:显示反汇编窗口中选中的第一个命令的参数及一些跳转目标地址、字串等。
- 数据窗口:显示内存或文件的内容。右键菜单可用于切换显示方式。
- 堆栈窗口:显示当前线程的堆栈。
- 要调整上面各个窗口的大小的话,只需左键按住边框拖动,等调整好了, 重新启动一下 OllyDBG 就可以生效了。
- 启动后我们要把插件及 UDD 的目录配置为绝对路径,点击菜单上的 选项->界面,将会出来一个界面选项的对话框,我们点击其中的目录标签:UDD 目录的作用是保存你调试的工作。比如你调试一个软件,设置了断点,添加了注释,一次没做完,这时 OllyDBG 就会把你所做的工作保存到这个 UDD 目录,以便你下次调试时可以继续以前的工作。如果不设置这个 UDD 目录,OllyDBG 默认是在其安装目录下保存这些后缀名为 udd 的文件,时间长了就会显的很乱,所以还是建议专门设置一个目录来保存这些文件。
- 插件的安装:把下载的插件(一般是个 DLL 文件)复制到 OllyDBG 安装目录下的 PLUGIN 目录中就可以了,OllyDBG 启动时会自动识别。要注意的是 OllyDBG 1.10 对插件的个数有限制,最多不能超过 32 个,否则会出错。建议插件不要添加的太多。
- 基本调试方法
- 点击菜单 文件->打开 (快捷键是 F3)来打开一个可执行文件进行调试。
- 点击菜单 文件->附加 来附加到一个已运行的进程上进行调试。注意这里要附加的程序必须已运行。
- 用右键菜单来载入程序。
- 调试中用到的快捷键
- F2:设置断点,只要在光标定位的位置(上图中灰色条)按F2键即可,再按一次F2键则会删除断点。(相当于 SoftICE 中的 F9)
- F8:单步步过。每按一次这个键执行一条反汇编窗口中的一条指令,遇到 CALL 等子程序不进入其代码。(相当于 SoftICE 中的 F10)
- F7:单步步入。功能同单步步过(F8)类似,区别是遇到 CALL 等子程序时会进入其中,进入后首先会停留在子程序的第一条指令上。(相当于 SoftICE 中的 F8)
- F4:运行到选定位置。作用就是直接运行到光标所在位置处暂停。(相当于 SoftICE 中的 F7)
- F9:运行。按下这个键如果没有设置相应断点的话,被调试的程序将直接开始运行。(相当于 SoftICE 中的 F5)
- CTR+F9:执行到返回。此命令在执行到一个 ret (返回指令)指令时暂停,常用于从系统领空返回到我们调试的程序领空。(相当于 SoftICE 中的 F12)
- ALT+F9:执行到用户代码。可用于从系统领空快速返回到我们调试的程序领空。(相当于 SoftICE 中的 F11)
IDA动态调试
1.性质:反编译软件
2.本地调试:
- 加载目标文件:
- 调试器界面:
“IDA-view-eip”界面是反汇编窗口,在这里点击f5,可以进入伪代码调试
下面的“hex view”顾名思义,右边从上到下分别是级寄存器/标志寄存,加载到进程内存空间中的可执行文件和共享库,双击模块名称可打开该模块输出的符号表,再向下看就是栈窗口
- 调试命令
设置断点
- 断点
设置好断点后,右键断点
例:EAX == 12
指当EAX的值为12时中断,同时,因为condition栏由IDC表达式支持,所以可以使用一些IDC的函数。
EAX 在计算机领域通常是指特定处理器(如 x86 架构处理器)中的一个通用寄存器。在 x86 架构中,EAX 等寄存器可用于存储数据、参与算术和逻辑运算、在函数调用中传递参数等多种用途。例如,在汇编语言编程中,EAX 经常被用来保存计算结果或作为临时存储单元。
例:GetRegValue(“ZF”)
指当ZF的值不为0时中断
在 IDA 调试器中,条件断点的设置可以使用 IDC 表达式。例如,可以通过 “GetRegValue (‘ZF’)” 这样的表达式来判断 ZF 的值,并根据其结果决定是否触发断点。如果 ZF 的值不为 0,就会中断程序的执行,以便进行进一步的分析和调试。
- 监视窗口
ida同样也支持对数据的监视,需要监视的数据一般在栈或者数据块中,进入栈或者数据,点击右键打开菜单,选择“Add watch”
即可在窗口“watch list”中显示,如果需要删除,则按“Delete”键
3.远程调控
ida支持远程调试Windows、linux、Android、Mac OS的二进制文件,将文件放在远程的对应系统服务器上,ida远程连接服务器,在服务器上运行、调试程序,并在本地客户端显示调试界面。界面视图上和本地调试并没有区别。
如果需要远程调试,首先需要将存储在ida目录中的dbgsrv文件中ida的服务端部署在远程服务器上
将需要调试的文件和服务端版本放入服务器中,然后运行服务端,会默认在23946端口启动ida服务端程序,以linux为例
被调试程序是64位elf文件,所以在linux端运行linux_server64,然后回到客户端
使用ida打开目标文件,然后点击菜单项中的“Debugger”
选择select debugger
选择Remote Linux debugger
先选择“Process option”进行设置
- 第一行application和input file选择被调试文件在服务端中的存储路径。
- 第三行的directory是存储路径,直接选被调试文件所在目录就行。
- 第四行的是程序启动时传入的参数,可以为空。
- 第五行则“Hostname”则填服务端的ip和端口号,我这里选的服务端是虚拟机。
- 最后一行的password是linux_server启动时设置的密码,如果没有设置,则为空即可。
- 全部设置正确之后就可以开始调试了
点击“start process”开始调试程序
可以看到在服务端程序已经成功启动
六.算法和数据结构识别
- 常用算法识别
如等加密算法,大数加减乘除、最短路等传统算法
- 常用数据结构识别
如图、树、哈希表等高级数据结构在汇编代码中的识别。【2021.12.25】ctf逆向中常见加密算法和编码识别_C4cke的博客-CSDN博客
七:代码混淆
反混淆技术,最主要的目的就是复原控制流。比如和
OLLVM
- OLLVM是一款针对LLVM的代码混淆工具,旨在加强逆向的难度,整个项目包含数个包含独立功能的LLVM Pass,每个Pass会对应实现一种特定的混淆方式,这些Pass可以改变源程序的CFG和源程序的结构。
- OLLVM有三大功能,分别是:Instructions Substitution(指令替换)、Bogus Control Flow(混淆控制流)、Control Flow Flattening(控制流平展)
(1)指令替换功能:随机选择一种功能上等效但更复杂的指令序列替换标准二元运算符;适用范围:加法操作、减法操作、布尔操作(与或非操作)且只能为整数类型。
(2)混淆控制流功能:1.在当前基本块之前添加基本块来修改函数调用图。2.原始基本块也被克隆并填充随机选择的垃圾指令。
操作指令:
-
-mllvm -bcf: activates the bogus control flow pass
-
-mllvm -bcf_loop=3: if the pass is activated, applies it 3 times on a function. Default: 1
-
-mllvm -bcf_prob=40: if the pass is activated, a basic bloc will be obfuscated with a probability of 40%. Default: 30
(3)控制流平展功能:目的是完全展平程序的控制流程图。我自己的理解是if...else变为switch..case..语句。
操作指令:
-
-mllvm -fla: activates control flow flattening
-
-mllvm -split: activates basic block splitting. Improve the flattening when applied together.
-
-mllvm -split_num=3: if the pass is activated, applies it 3 times on each basic block. Default: 1
- OLLVM环境的搭建
OLLVM版本号:OLLVM 4.0;Ubuntu环境:Ubuntu16.04;虚拟机中处理器数量为4个、运行内存3G,分配硬盘空间50g。
-
$ git clone -b llvm-4.0 https://github.com/obfuscator-llvm/obfuscator.git
-
$ mkdir build
-
$ cd build
-
$ cmake -DCMAKE_BUILD_TYPE=Release https://blog.csdn.net/2401_88456006/article/obfuscator/
-
$ make -j7
若是git clone一直失败,下不下来,尝试:
若是cmake时一直报错,则将cmake那句替换为:
若是make时时间太长,则重新cmake后,多分配一些内存和处理器。
- OLLVM源码分析
OLLVM简单入门 - huhuf6 - 博客园 (cnblogs.com)
movfuscator
花指令
- 什么是花指令
花指令实质就是一串垃圾指令,它与程序本身的功能无关,并不影响程序本身的逻辑。在软件保护中,花指令被作为一种手段来增加静态分析的难度,花指令也可以被用在病毒或木马上,通过加入花指令改变程序的特征码,躲避杀软的扫描,从而达到免杀的目的,花指令一般被分为两类,被执行的和不会被执行的。
- 不会被执行的花指令
- 这类花指令通常形式为在代码中出现了类似数据的代码,或者IDA反汇编后为jmupout(xxxxx).
- 这类花指令一般不属于CPU可以识别的操作码,那么就需要在上面用跳转跳过这些花指令才能保证程序的正常运行。
- 反汇编引擎主要有两种算法,一种是线性扫描算法,一种是递归行进算法。
- 线性扫描算法将遇到的每一条指令都解析成汇编指令,没有对反汇编的内容进行判断,因而无法正确区分代码和数据,一些数据也会被当成代码来解码,从而导致反汇编出现错误,这种错误将会影响对下一条指令的正确识别。
- 递归行进算法按照代码可能的执行顺序来反汇编程序,对每条可能的路径进行扫描,当解码出分支指令后,反汇编工具就将这么地址记录下来,并分别反汇编各个分支中的指令,这种算法比较灵活,可以避免将代码中的数据作为指令来解码。
形式一:
如果我们插入的花指令是一个操作码,那么后面程序原本的机器码就会被误认为是这个操作码的操作数,从而导致反汇编引擎的解析错误。
形式二:
插入的花指令也可以是改变堆栈平衡的汇编代码,跟形式一相同在这些花指令上面写上跳转指令,虽然花指令不会被执行,但是IDA进行解析时会认为该函数堆栈不平衡,从而使F5功能失效
- 会被执行的花指令
这类花指令本身是正常的汇编指令,它们运行完后不会改变原来程序的堆栈,寄存器,但能起到干扰静态分析的作用,一般分为两种,一种是改变堆栈操作,另一种是利用call指令或Jmp指令增加执行流程复杂度。
- 编写IDC脚本清除花指令
IDC脚本是IDA的一项功能,他的语法与C语言类似所以叫IDC,另外还有一种IDAPYTHON使用的是pyhton的语法,具体可以参考IDA权威指南,这里介绍下编写IDC脚本清除花指令需要用到的一些函数。
首先是一个编写IDC脚本的框架
在IDC脚本中,变量的声明使用的是auto关键字,例如:auto i=0;
for,if语句等语法与C语言相同,值得注意的是在IDC脚本中不支持+=;++等写法,需要老老实实的写全。
PatchByte(地址,内容)
Byte(地址)
本文地址:http://syank.xrbh.cn/quote/6890.html 迅博思语资讯 http://syank.xrbh.cn/ , 查看更多