文件加密:软件保护技术:加壳与脱壳

2023-11-06 16:36

本文主要是介绍文件加密:软件保护技术:加壳与脱壳,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文件加密
https://blog.csdn.net/weixin_46175201/article/details/132565792
加壳原理浅析:
1.什么是壳:
专门负责对程序体积进行压缩,或者是保护一个程序不被非法修改、逆向分析的一类软件。

壳通过附加自身代码在保护对象(原始程序)上,在操作系统对原始程序代码进行执行只求按获得程序控制权,进而对原始程序进行解压或解密等还原操作,完成操作后控制权将还给原始程序,程序的元时代吗才开始被执行。

2.壳的分类:
侧重于缩小程序体积,称为压缩壳,经典压缩壳软件:UPX、ASPack;
侧重于程序代码及数据加密,称为加密壳,经典加密壳软件有VMProtect、ASProrect、Themida、EXECrypror、Safengine等、其中VMP、Themida的特色是指令虚拟化,保护强度极高
3.壳的加载过程:
入口现场保存

可执行文件被操作系统载入后开始执行前,寄存器内会存放一些操作系统预先填充好的值,栈的数据也会被设置,壳程序要保存这些数据(状态),以免其被壳段代码不经意间地破坏,在转交控制权前壳需要恢复这些数据,才能让原来的程序正常运行。

一般情况下,由于已有栈的内容是不应更改的,简单的壳会选择将这样的信息压入栈(在栈上开辟新的空间),x86的汇编指令 pushad 可以轻松地将所有寄存器一次性压入栈,UPX使用了这样的方式,被形象地称为“保护现场”。

获取壳自身解密程序所需API的地址

外壳的输入表中往往只有GetProcAddress / LoadLibrary / GetModuleHandle等最基本的函数,有的可能只包含-个GelProcAddress,完全不够满足解密程序过程涉及到的许多操作,因此需要事先用以上几个函数获得其他函数地址以便壳段代码使用。

解密原程序的各个区块(Section)的数据

壳出于保护原程序代码和数据的目的,-般都会加密原程序文件的各个区块。在程序执行时外壳将会对这些区块数据解密,以让程序能正常运行。壳般是按区块加密的,那么在解密时也按区块解密,并且把解密的区块数据按照原区块的定义放在合适的内存位置,或者放置到由加壳程序调整后的位置。

初始化IAT,导入原程序所需系统API地址

调整重定位项

Hook API,实现一些保护功能(可选)

恢复入口现场,跳转至OEP(Original Entry Point,原入口点),转交控制权

4.如何寻找原入口点(OEP)
根据跨段指令寻找OEP:

绝大多数加壳程序会在被加密的程序中加上一个或多个段(section),在最后跳转值OEP时一般都是通过跨段跳转指令进行转移,所以依据跨度的转移指令(远jmp等),就可找到真正的入口点,在该跳转指令前一般会有POPAD/POPFD指令出现(用于恢复入口现场),可以用作定位参考。(PUSHAD是保存通用寄存器,POPFD是保存状态寄存器,jmp的机械代码是19开头)

UPX用了一次跨段的转移指令,(远JMP,指令以E9开头),在跳至OEP的指令处可以看到虚拟地址的值有一个明显突变,

据此可以确定OEP的位置0x555544

根据堆栈平衡原理寻找OEP:

该方法是用“ESP定律”,对绝大部分的压缩壳都很有效,原理便是基于栈平衡。

壳段代码在保护现场后,我们对ESP指向的内存单元下硬件访问断点,那么在壳段代码恢复现场时一定会访问到这个单元,此时我们EIP所处的位置处于壳段代码末尾,距离跳转至OEP也就不远了

调试壳:(以UPX壳为例)
示例程序

将后缀改回exe

notepad.txt

notepad_upx.txt

tips:程序来自《逆向工程核心原理》一书

加壳前后对比:
首先查看在未加壳是notepad的EP代码,以及PE结构:

在未加壳时程序的PE结构为正常的代码段、数据段以及资源段

然后对比以下加壳后的程序:

原来的加壳后程序的PE结构被改变了,段名变为了UPX0、UPX1。

调试程序notepad_upx.exe
用OD打开notepad_upx程序:

在程序的开始,可以看到和之前介绍的一样,壳加载的第一步就是对入口现场的保存,然后分别把UPX1的起始地址设置到esi寄存器,将UPX0的起始地址设置到edi寄存器。

tips:UPX文件的第一个节区仅存在于内存,该处及是解压缩后保存源文件代码的地方。也就是说,解压缩过程就是对节区UPX1进行解密,并将解密后的内容保存到EDI所指向的UPX0节区。

01015330 > $ 60 pushad
01015331 . BE 00100101 mov esi,notepad_.01011000
01015336 . 8DBE 0000FFFF lea edi,dword ptr ds:[esi-0x10000]
1
2
3
循环一:
CTRL+F8开始跟踪代码,观察程序运行,当程序运行到第一个循环时按F7停下来,观察该循环的作用:

这段代码的作用就是将EDX指向的内存数据一个字节一个字节的拷贝到EDI指向的内存地址处,查看寄存器,EDX所指向的地址为UPX0节区的起始地址,查看对应地址的内存数据:

全是NULL,这个循环的作用是确保写入的目标地址为空,在010153E6地址处设置断点,F9跳过该循环。

循环二:
继续CTRL+F8,会遇到一个较大的循环,这个循环为正式的解压缩循环

AL存放ESI中的数据,经过解压缩运算后存入EDI指向的内存地址中,解压缩过程没看懂。

循环三:
继续跟踪代码

这段循环代码用于恢复源代码的CALL/JMP指令的地址

循环四:

这个循环用于恢复IAT表,在01015436地址处设置EDI=01014000,它指向第二个节区(UPX1)区域,该区域中保存着原notepad.exe调用的API函数名称的字符串。

UPX压缩原notepad.exe文件时,它会分析其IAT,提取出程序中调用的API名称列表,形成API名称字符串。
用这些API名称字符串调用01015467地址处的GetProcAddress(0函数,获取API的起始地址,然后把API地址输入EBX寄存器所指的原notepad.exe的IAT区域。该过程会反复进行至API名称字符串结束,最终恢复原notepad.exe的IAT。

跳转至OEP:

notepad.exe全部解压缩完成后,应该将程序的控制返回到OEP处。

010154AD地址处的POPAD命令与UPX代码的第一条PUSHAD命令对应,用来把当前寄存器恢复原状最终,使用010154BB地址处的JMP命令跳转到OEP处,要跳转到的目标地址为0100739D,它就是原notepad.exe的EP地址。

将解压缩后的代码DUMP下来:
OD提供了一个叫OllyDump的插件:

这个插件可以自动将当前EIP作为OEP输入,直接选择脱壳即可,IAT表也会自动修复。

将脱壳后的程序放到EXEinfo里面查一下壳:

可以看到已经脱壳成功了。
————————————————
版权声明:本文为CSDN博主「Reveone」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_46175201/article/details/132565792

这篇关于文件加密:软件保护技术:加壳与脱壳的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/357786

相关文章

Java中使用Hutool进行AES加密解密的方法举例

《Java中使用Hutool进行AES加密解密的方法举例》AES是一种对称加密,所谓对称加密就是加密与解密使用的秘钥是一个,下面:本文主要介绍Java中使用Hutool进行AES加密解密的相关资料... 目录前言一、Hutool简介与引入1.1 Hutool简介1.2 引入Hutool二、AES加密解密基础

SpringBoot3实现Gzip压缩优化的技术指南

《SpringBoot3实现Gzip压缩优化的技术指南》随着Web应用的用户量和数据量增加,网络带宽和页面加载速度逐渐成为瓶颈,为了减少数据传输量,提高用户体验,我们可以使用Gzip压缩HTTP响应,... 目录1、简述2、配置2.1 添加依赖2.2 配置 Gzip 压缩3、服务端应用4、前端应用4.1 N

Java利用JSONPath操作JSON数据的技术指南

《Java利用JSONPath操作JSON数据的技术指南》JSONPath是一种强大的工具,用于查询和操作JSON数据,类似于SQL的语法,它为处理复杂的JSON数据结构提供了简单且高效... 目录1、简述2、什么是 jsONPath?3、Java 示例3.1 基本查询3.2 过滤查询3.3 递归搜索3.4

Python中随机休眠技术原理与应用详解

《Python中随机休眠技术原理与应用详解》在编程中,让程序暂停执行特定时间是常见需求,当需要引入不确定性时,随机休眠就成为关键技巧,下面我们就来看看Python中随机休眠技术的具体实现与应用吧... 目录引言一、实现原理与基础方法1.1 核心函数解析1.2 基础实现模板1.3 整数版实现二、典型应用场景2

SpringBoot3使用Jasypt实现加密配置文件

《SpringBoot3使用Jasypt实现加密配置文件》这篇文章主要为大家详细介绍了SpringBoot3如何使用Jasypt实现加密配置文件功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编... 目录一. 使用步骤1. 添加依赖2.配置加密密码3. 加密敏感信息4. 将加密信息存储到配置文件中5

SpringBoot整合jasypt实现重要数据加密

《SpringBoot整合jasypt实现重要数据加密》Jasypt是一个专注于简化Java加密操作的开源工具,:本文主要介绍详细介绍了如何使用jasypt实现重要数据加密,感兴趣的小伙伴可... 目录jasypt简介 jasypt的优点SpringBoot使用jasypt创建mapper接口配置文件加密

Java实现MD5加密的四种方式

《Java实现MD5加密的四种方式》MD5是一种广泛使用的哈希算法,其输出结果是一个128位的二进制数,通常以32位十六进制数的形式表示,MD5的底层实现涉及多个复杂的步骤和算法,本文给大家介绍了Ja... 目录MD5介绍Java 中实现 MD5 加密方式方法一:使用 MessageDigest方法二:使用

SpringBoot使用Jasypt对YML文件配置内容加密的方法(数据库密码加密)

《SpringBoot使用Jasypt对YML文件配置内容加密的方法(数据库密码加密)》本文介绍了如何在SpringBoot项目中使用Jasypt对application.yml文件中的敏感信息(如数... 目录SpringBoot使用Jasypt对YML文件配置内容进行加密(例:数据库密码加密)前言一、J

Java中的密码加密方式

《Java中的密码加密方式》文章介绍了Java中使用MD5算法对密码进行加密的方法,以及如何通过加盐和多重加密来提高密码的安全性,MD5是一种不可逆的哈希算法,适合用于存储密码,因为其输出的摘要长度固... 目录Java的密码加密方式密码加密一般的应用方式是总结Java的密码加密方式密码加密【这里采用的

使用Python制作一个PDF批量加密工具

《使用Python制作一个PDF批量加密工具》PDF批量加密‌是一种保护PDF文件安全性的方法,通过为多个PDF文件设置相同的密码,防止未经授权的用户访问这些文件,下面我们来看看如何使用Python制... 目录1.简介2.运行效果3.相关源码1.简介一个python写的PDF批量加密工具。PDF批量加密