2.13 PE结构:实现PE代码段加密
代码加密功能的实现原理,首先通过创建一个新的.hack
区段,并对该区段进行初始化,接着我们向此区段内写入一段具有动态解密功能的ShellCode
汇编指令集,并将程序入口地址修正为ShellCode
地址位置处,当解密功能被运行后则可释放加密的.text
节,此时再通过一个JMP
指令跳转到原始OEP
位置,则可继续执行解密后的区段。
如下是一段异或解密功能实现,用于实现循环0x88
异或解密代码功能;
00408001 MOV EAX, main.00401000 (代码段首地址)
00408006 XOR BYTE PTR DS : [EAX], 88 (与0x88异或)
00408009 INC EAX
0040800A CMP EAX, main.00404B46 (代码段结束位置)
0040800F JNZ SHORT main.00408006 (写入原始OEP)
00408011 POPAD
00408012 MOV EAX, main.00401041 (写入新OEP)
00408017 JMP EAX
有了上述加密流程,则下一步就是对内部的变量进行填充,我们可以提取出这些汇编指令的机器码并存储到Code[]
数组内,通过对数组中的特定位置进行替换来完善跳转功能,此处我们需要提取如下几个位置的特征字段;
- 00408001 数组下标第
2
位替换为ImageBase + pSection->VirtualAddress
- 0040800A 数组下标第
11
位替换为ImageBase + pSection->VirtualAddress + pSection->Misc.VirtualSize
- 0040800F 数组下标第
19
位替换为ImageBase + BaseRVA
- 00408012 原始
OEP
位置替换为pSection->VirtualAddress
根据上述流程我们可以编写一个AddPacking
函数,该函数通过传入一个待加密程序路径,则可将一段解密代码Code[]
写入到程序节表中的最后一个节.hack
所在内存空间,并动态修正当前入口地址为.hack
节的首地址,最终执行解密后自动跳转回原始OEP位置执行功能,如下代码所示;
// 对文件执行加壳操作
void AddPacking(LPSTR szFileName)
{// 打开文件HANDLE hFile = CreateFileA(szFileName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ,NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);// 创建文件映射HANDLE hMap = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, 0, 0);HANDLE lpBase = MapViewOfFile(hMap, FILE_MAP_READ | FILE_SHARE_WRITE, 0, 0, 0);// 找到PE文件头PIMAGE_DOS_HEADER DosHdr = (PIMAGE_DOS_HEADER)lpBase;PIMAGE_NT_HEADERS NtHdr = (PIMAGE_NT_HEADERS)((DWORD)lpBase + DosHdr->e_lfanew);DWORD ImageBase = NtHdr->OptionalHeader.ImageBase;DWORD BaseRVA = NtHdr->OptionalHeader.AddressOfEntryPoint;PIMAGE_FILE_HEADER FileHdr = &NtHdr->FileHeader;PIMAGE_SECTION_HEADER pSection = IMAGE_FIRST_SECTION(NtHdr);// 首先得到最后一个节的指针,然后找到里面的虚拟偏移值,填入到程序OEP位置即可。DWORD SectionNum = FileHdr->NumberOfSections;char Code[] ={"\x60""\xb8\x00\x00\x00\x00""\x80\x30\x88""\x40""\x3d\xff\x4f\x40\x00""\x75\xf5""\x61""\xb8\x00\x00\x00\x00""\xff\xe0"};DWORD dwWrite = 0;// 写入代码节开始位置*(DWORD *)&Code[2] = ImageBase + pSection->VirtualAddress;printf("[+] 写入代码节开始位置: 0x%08X \n", ImageBase + pSection->VirtualAddress);// 写入代码节终止位置*(DWORD *)&Code[11] = ImageBase + pSection->VirtualAddress + pSection->Misc.VirtualSize;printf("[+] 写入代码节结束位置:0x%08X \n", ImageBase + pSection->VirtualAddress + pSection->Misc.VirtualSize);// 写入原来的的OEP位置*(DWORD *)&Code[19] = ImageBase + BaseRVA;printf("[+] 写入原始OEP 0x%08X \n", ImageBase + BaseRVA);// 拿到最后一个节的文件偏移pSection = pSection + (SectionNum - 1);printf("[+] 得到最后一个节的实际地址: 0x%08X \n", pSection->PointerToRawData);// 设置指针到最后一个节文件偏移位置SetFilePointer(hFile, pSection->PointerToRawData, 0, FILE_BEGIN);WriteFile(hFile, (LPVOID)Code, sizeof(Code), &dwWrite, NULL);FlushViewOfFile(lpBase, 0);// 修正当前入口点地址printf("[+] 修正入口点地址为: 0x%08X \n", pSection->VirtualAddress);*(DWORD *)&NtHdr->OptionalHeader.AddressOfEntryPoint = pSection->VirtualAddress;UnmapViewOfFile(lpBase);
}
读者可自行运行上述代码片段,传入d://lyshark.exe
对该程序中的.text
节进行解密,运行后读者可打开x64dbg
调试器,观察入口地址处的变化,此时入口地址已经跳转到.hack
节内,此节中的汇编指令则用于对.text
代码节进行解密操作,当解密结束后则会跳转到原始地址0x45C865
位置处,如下图所示;
当加密功能写入后,则接下来就可以对.text
代码节进行加密了,加密的实现也非常容易,如下函数,通过定位到第一个节,并通过ReadFile
函数将这个节读入内存,通过循环对这个区域进行加密,最后调用WriteFile
函数再将加密后的数据回写到代码节,此时加密功能就实现了,如下所示;
// 将特定的节进行加密,此处只加密Text节
void EncrySection(LPSTR szFileName, DWORD Key)
{// 打开文件HANDLE hFile = CreateFileA(szFileName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ,NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);// 创建文件映射HANDLE hMap = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, 0, 0);HANDLE lpBase = MapViewOfFile(hMap, FILE_MAP_READ | FILE_SHARE_WRITE, 0, 0, 0);// 定位PE文件节PIMAGE_DOS_HEADER DosHdr = (PIMAGE_DOS_HEADER)lpBase;PIMAGE_NT_HEADERS NtHdr = (PIMAGE_NT_HEADERS)((DWORD)lpBase + DosHdr->e_lfanew);PIMAGE_FILE_HEADER FileHdr = &NtHdr->FileHeader;PIMAGE_SECTION_HEADER pSection = IMAGE_FIRST_SECTION(NtHdr);printf("[-] 节虚拟地址: 0x%08X 虚拟大小: 0x%08X\n", pSection->VirtualAddress, pSection->Misc.VirtualSize);printf("[-] 读入FOA基地址: 0x%08X 节表长度: 0x%08X \n", pSection->PointerToRawData, pSection->SizeOfRawData);printf("[-] 已对 %s 节 --> XOR加密/解密 --> XOR密钥: %d \n\n", pSection->Name, Key);// 分配内存空间DWORD dwRead = 0;PBYTE pByte = (PBYTE)malloc(pSection->SizeOfRawData);SetFilePointer(hFile, pSection->PointerToRawData, 0, FILE_BEGIN);memset(pByte, 0, pSection->SizeOfRawData);ReadFile(hFile, pByte, pSection->SizeOfRawData, &dwRead, NULL);// 对代码节加密for (int x = 0; x < pSection->SizeOfRawData; x++){pByte[x] ^= Key;}// 写出加密后的数据SetFilePointer(hFile, pSection->PointerToRawData, 0, FILE_BEGIN);WriteFile(hFile, pByte, pSection->SizeOfRawData, 0, FILE_BEGIN);pSection->Characteristics = 0xE0000020;free(pByte);FlushViewOfFile(lpBase, 0);UnmapViewOfFile(lpBase);
}
读者通过AddPacking
函数对文件加壳后,接着就可以调用EncrySection
函数对目标程序进行异或处理,此处分别传入d://lyshark.exe
路径,以及一个加密密钥0x88
,等待加密结束即可,此时运行程序即可实现对代码段的解密运行,这样也就起到了保护了代码段的作用,如下是解密之前的代码段;
当解密后,代码段将会被展开,并输出如下图所示的样子,此时程序即可被正确执行;
本文作者: 王瑞
本文链接: https://www.lyshark.com/post/5912e71.html
版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
相关文章:
2.13 PE结构:实现PE代码段加密
代码加密功能的实现原理,首先通过创建一个新的.hack区段,并对该区段进行初始化,接着我们向此区段内写入一段具有动态解密功能的ShellCode汇编指令集,并将程序入口地址修正为ShellCode地址位置处,当解密功能被运行后则可…...
Rust更换Cargo国内源,镜像了寂寞
换皮不换身 换了国内源,构建时该卡还会卡。因为它所谓的换源,只是更换crates.io“索引”的源,而不是package“内容”的源。换了国内源后,在国内编译时访问 crates.io-index 自然会快很多,可是crates.io-index里面的信…...
【网络安全带你练爬虫-100练】第23练:文件内容的删除+写入
目录 0x00 前言: 0x02 解决: 0x00 前言: 本篇博文可能会有一点点的超级呆 0x02 解决: 你是不是也会想: 使用pyrhon将指定文件夹位置里面的1.txt中数据全部删除以后---->然后再将参数req_text的值写入到1.txt …...
ESP32蓝牙实例-BLE服务器与客户端通信
BLE服务器与客户端通信 文章目录 BLE服务器与客户端通信1、软件准备2、硬件准备3、代码实现3.1 BLE服务器实现3.2 Android手机测试BLE服务器3.3 ESP32 BLE客户端在本文中,我们将介绍如何使用低功耗蓝牙在两个 ESP32 开发板之间执行 BLE 服务器客户端通信。 换句话说,将介绍如…...
第11章_瑞萨MCU零基础入门系列教程之SysTick
本教程基于韦东山百问网出的 DShanMCU-RA6M5开发板 进行编写,需要的同学可以在这里获取: https://item.taobao.com/item.htm?id728461040949 配套资料获取:https://renesas-docs.100ask.net 瑞萨MCU零基础入门系列教程汇总: ht…...
【面试题精讲】如何使用Stream的聚合功能
有的时候博客内容会有变动,首发博客是最新的,其他博客地址可能会未同步,认准https://blog.zysicyj.top 首发博客地址 系列文章地址 求和(Sum): List<Integer> numbers Arrays.asList(1, 2, 3, 4, 5);int sum n…...
Linux 中的 chmod 命令及示例
在 Unix 操作系统中,chmod命令用于更改文件的访问模式。该名称是change mode的缩写。其中规定每个文件和目录都有一组权限来控制权限,例如谁可以读取、写入或执行该文件。其中权限分为三类:同时读、写和执行,用“r”、“w”和“x”表示。这些字母组合在一起形成一组用户的特…...
sannaing i14 pro max使用体验
体验了一把山寨机,不明真相的人会以为这是三星的英文标志,又是pro又是max的,价格600,进系统去看了配置,cpu写的是snapdragon 888,运存12g,内存500g。下了个安兔兔也是被忽悠了,它也以…...
Shazam音乐检索算法原理及实现
算法基本流程如下: 1. 采集音乐库 2. 音乐指纹采集 3. 采用局部最大值作为特征点 4. 将临近的特征点进行组合形成特征点对 5. 对每个特征点对进行hash编码 编码过程:将f1和f2进行10bit量化,其余bit用来存储时间偏移合集形成32bit的hash码 …...
vue递归组件
父组件: <template><div><treeVue :treeData"treeData"></treeVue></div> </template><script setup lang"ts"> import { reactive } from "vue"; import treeVue from "./tree.vue…...
软件测试/测试开发丨测试用例自动录入 学习笔记
点此获取更多相关资料 本文为霍格沃兹测试开发学社学员学习笔记分享 原文链接:https://ceshiren.com/t/topic/27139 测试用例自动录入 测试用例自动录入的价值 省略人工同步的步骤,节省时间 兼容代码版本的自动化测试用例 用例的执行与调度统一化管理…...
来学Python啦,大话字符串
To be a happy man, reading, travel, hard work, care for the body and mind。做一个幸福的人,读书,旅行,努力工作,关心身体和心境。 前面我们讲解过关于用Python写温度转换器&…...
pyqt5设置背景图片
PyQt5设置背景图片 1、打开QTDesigner 创建一个UI,camera.ui。 2、创建一个pictures.qrc文件 在ui文件同级目录下先创建一个pictures.txt,填写内容: <RCC><qresource prefix"media"><file>1.jpg</file>…...
C# WPF 自己写的一个模拟病毒传播的程序,有可视化
源代码: https://github.com/t39q/VirusSpread 主要代码 using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks;namespace VirusSpread.Bu…...
stable diffusion实践操作-大模型介绍-SDXL1大模型
系列文章目录 大家移步下面链接中,里面详细介绍了stable diffusion的原理,操作等(本文只是下面系列文章的一个写作模板)。 stable diffusion实践操作 提示:写完文章后,目录可以自动生成,如何生…...
软考高级系统架构设计师系列案例考点专题四:嵌入式系统
软考高级系统架构设计师系列案例考点专题四:嵌入式系统 一、相关概念二、软件可靠性和硬件可靠性的区别三、可靠性指标四、可靠性设计五、冗余技术六、软件容错七、双机容错技术八、集群技术九、负载均衡十、可维护性的评价指标十一、软件维护的分类嵌入式每年必考一题,但是属…...
Django Form实现表单使用及应用场景
首先需要定义一个使用场景: 音乐网站的前端部分可以添加上传歌手的单曲, 这个添加页面就使用django form表单来实现。 目录 数据表内容 歌手表及表模型 单曲表及表模型 演示表单使用 设置路由 创建form.py 视图实例化表单类 模板使用表单对象 表…...
golang面试题:json包变量不加tag会怎么样?
问题 json包里使用的时候,结构体里的变量不加tag能不能正常转成json里的字段? 怎么答 如果变量首字母小写,则为private。无论如何不能转,因为取不到反射信息。如果变量首字母大写,则为public。 不加tag,…...
国内项目管理中级证书CSPM-3正在报名!
CSPM-3中级项目管理专业人员认证,是中国标准化协会(全国项目管理标准化技术委员会秘书处),面向社会开展项目管理专业人员能力的等级证书。旨在构建多层次从业人员培养培训体系,建立健全人才职业能力评价和激励机制的要…...
vue表格不显示列号123456
我在网上找了半天,都是如何添加列号123456的,没有找到不显示列号的参考,现在把这个解决了,特此记录一下。 没有加右边的就会显示,加上右边的就隐藏了...
【大数据】Kafka 入门指南
Kafka 入门指南 1.Kafka 简介2.Kafka 架构3.分区与副本4.偏移量5.消费者组6.总结 1.Kafka 简介 Apache Kafka 是一种高吞吐、分布式的流处理平台,由 LinkedIn 开发并于 2011 年开源。它具有 高伸缩性、高可靠性 和 低延迟 等特点,因此在大型数据处理场景…...
Qt 5.15集成Crypto++ 8.8.0(MSVC 2019)笔记
一、背景 笔者已介绍过在Qt 5.15.x中使用MinGW(8.10版本)编译并集成Crypto 8.8.0。 但是该编译出来的库(.a和.dll)不适用MSVC(2019版本)构建环境,需要重新编译(.lib或和.dll…...
前端面试的话术集锦第 9 篇:高频考点(webpack性能优化)
这是记录前端面试的话术集锦第九篇博文——高频考点(webpack性能优化),我会不断更新该博文。❗❗❗ 在此章节中,我不会浪费篇幅给大家讲如何写配置文件。如果你想学习这方面的内容,那么完全可以去官网学习。在这部分的内容中,我们会聚焦于以下两个知识点,并且每一个知识…...
程序员,你真热爱编程吗?
程序员的热爱与演变 我发现,程序员这个行业不像其他行业那样,很多人是因为热爱编程才去做程序员,不会被逼无奈去做程序员(要是真有就太惨了)。 热爱编程的漫长过程 热爱过、⼜不爱了、⼜爱了,这是个过程…...
算法通关村-----海量数据的处理方法
从40亿中产生一个不存在的数 问题描述 给定一个文件,包含40亿个非负整数,请你设计一个算法,产生一个不在该文件中的数字。假设你只有1GB内存。 问题分析 40亿整数,在java中,用int存储的话,大概需要40亿✖️4B,大约…...
Pytorch 多卡并行(1)—— 原理简介和 DDP 并行实践
近年来,深度学习模型的规模越来越大,需要处理的数据也越来越多,单卡训练的显存空间和计算效率都越来越难以满足需求。因此,多卡并行训练成为了一个必要的解决方案本文主要介绍使用 Pytorch 的 DistributedDataParallel(…...
快速排序(重点)
前言 快排是一种比较重要的排序算法,他的思想有时候会作用到个别算法提上,公司招聘的笔试上有时候也有他的过程推导题,所以搞懂快排势在必行!!! 快速排序 基本思想: 根据基准,将数…...
python高级内置函数介绍及应用举例
目录 1. 概述2. 举例 1. 概述 Python中有许多高级内置函数,它们提供了丰富的功能和便利性,可以大大简化代码并提高效率。以下是一些常用的高级内置函数: map(): 用于将一个函数应用于一个可迭代对象的所有项,返回一…...
人体呼吸存在传感器成品,毫米波雷达探测感知技术,引领智能家居新潮流
随着科技的不断进步和人们生活质量的提高,智能化家居逐渐成为一种时尚和生活方式。 人体存在传感器作为智能家居中的重要组成部分,能够实时监测环境中人体是否存在,为智能家居系统提供更加精准的控制和联动。 在这个充满创新的时代…...
软件设计模式(三):责任链模式
前言 前面荔枝梳理了有关单例模式、策略模式的相关知识,这篇文章荔枝将沿用之前的写法根据示例demo来体会这种责任链设计模式,希望对有需要的小伙伴有帮助吧哈哈哈哈哈哈~~~ 文章目录 前言 责任链模式 1 简单场景 2 责任链模式理解 3 Java下servl…...
wordpress怎么制作订单号管理/seo描述是什么意思
转:/********************** * 课题:将窗体中鼠标所在控件名显示在窗体标题上 * 作者:ZAXX * QQ : 94027486 * 本课题可简单扩展:获取屏幕上鼠标所在位置的窗口句柄与类名 **********************/using System;using System.Draw…...
能源门户网站建设/排名函数rank怎么用
文章目录一、LVS负载均衡概念二、LVS负载均衡之NAT方式1、工作过程图解:2、通过上述其工作过程,总结一下NAT方式的特点三、LVS负载均衡之NAT方式配置流程详解3、实验步骤:(1)查看ip_vs模块是否加载(2&#…...
主题网站设计模板/百度模拟搜索点击软件
准备好滚滚的JOE – Java on Everything吗? Java on Everything掌握了如何在几乎所有内容上运行Java的关键。 没有操作系统? 没问题。 JOE无需操作系统即可工作。 放弃操作系统的好处是什么? Java on Everything是由约瑟夫库里格(…...
网站推广托管/福州seo结算
请创建一个一维整型数组用来存储待排序关键码,关键码从数组下标为1的位置开始存储,下标为0的位置不存储关键码。输入关键码的个数,以及各个关键码,采用起泡排序的方法对关键码数组进行排序,输出每轮比较的过程。 输入描…...
在线做qq空间的网站吗/营业推广策划
memcached 与 redis 的区别? 1、Redis 不仅仅支持简单的 k/v 类型的数据,同时还提供 list,set,zset,hash 等数据结构的存储。而 memcache 只支持简单数据类型( php类型 基本类型:int string bo…...
WordPress网站转HTPPS/在线识图
1.树的定义: (1)有且只有一个称为根的节点。 (2)有若干个互不相交的子树,这些子树本身也是一棵树。 eg: 2.通俗的定义: (1)树由节点和边组成。 (2…...