C/C++ 动态解密释放ShellCode
今天在复习《加密与解密》时,在软件保护这一章中有一个代码与数据结合的案例,其原理是将代码段中的代码进行xor异或加密处理以后回写到原始位置,当程序运行后将此处的内容动态的进行解密,解密后回写替换回原始内存位置,这样就能实现内存加载。
由此案例我想到一个关于免杀的利用思路,首先杀软的运作方式多数为特征码查杀,当我们程序中使用了敏感的函数时,就会存在被杀的风险,而如果将代码段中的代码进行加密,需要时直接在内存中解密,那么杀软将无法捕捉硬盘文件的特征,从而可以规避杀软针对硬盘特征的查杀手法。
经过阅读该案例的源码,我首先提取出了案例中的核心代码,并加以改进后将其从软件保护改为了免杀手法,其注册码生成工具核心代码如下所示,这里我没有动使用原始的加密工具即可。
for ( i=0;i<strlen(szBuffer);i++)
{
k = k*6 + szBuffer[i];
}
Size=address2-address1;
Size=Size/0x4; //加密时,每次异或 DWORD数据,Size是为最终需要异或的次数
offset=address1;
for (i=0;i<Size;i++)
{
SetFilePointer(hFile,offset,NULL,FILE_BEGIN);
ReadFile(hFile,szBuffer, 4, &szTemp, NULL);//读取DWORD字节的文件内容
ptr=(DWORD*)szBuffer;
*ptr=(*ptr)^k;
SetFilePointer(hFile,offset,NULL,FILE_BEGIN);
if(!WriteFile(hFile,ptr,4,&nbWritten,NULL))// 写入文件
{
MessageBox(NULL,"Error while patching !","Patch aborted",MB_ICONEXCLAMATION);
CloseHandle(hFile);
return 1;
}
offset=offset+4;
}
CloseHandle(hFile);
MessageBox(NULL,"Patch successfull !","Patch",MB_ICONINFORMATION);
return 1;
}
下面则是客户端解密代码,该代码的原始部分是注册机加密,我把它抽取出来改成了这个样子,首先使用__asm mov AddressA, offset BeginOEP
定义两个段标签,分别用于表示段的开始与结束,也就是我们需要加密与解密的代码段位置,在两个标签内部的就是我们的恶意代码,将其写入到标签中,标签中的__asm inc eax dec eax
则是一串标志用于快速定位到需要加密的位置。
#include <stdio.h>
#include <Windows.h>
#include <tchar.h>
void Decrypt(DWORD*, DWORD, DWORD);
void Decrypt(DWORD* pData, DWORD Size, DWORD value)
{
//首先要做的是改变这一块虚拟内存的内存保护状态,以便可以自由存取代码
MEMORY_BASIC_INFORMATION mbi_thunk;
//查询页信息
VirtualQuery(pData, &mbi_thunk, sizeof(MEMORY_BASIC_INFORMATION));
//改变页保护属性为读写。
VirtualProtect(mbi_thunk.BaseAddress, mbi_thunk.RegionSize, PAGE_READWRITE, &mbi_thunk.Protect);
Size = Size / 0x4; //对数据共需要异或的次数
//解密begindecrypt与enddecrypt标签处的数据
while (Size--)
{
*pData = (*pData) ^ value;
pData++;
}
//恢复页的原保护属性。
DWORD dwOldProtect;
VirtualProtect(mbi_thunk.BaseAddress, mbi_thunk.RegionSize, mbi_thunk.Protect, &dwOldProtect);
}
int main(int argc, char* argv[])
{
DWORD AddressA, AddressB, Size, key;
DWORD *ptr;
TCHAR cCode[30] = { 0 };
__asm mov AddressA, offset BeginOEP
__asm mov AddressB, offset EndOEP
Size = AddressB - AddressA;
ptr = (DWORD*)AddressA;
_tcscpy(cCode, L"lyshark"); // 设置加密密钥
key = 1;
for (unsigned int i = 0; i< lstrlen(cCode); i++)
{
key = key * 6 + cCode[i];
}
Decrypt(ptr, Size, key); //执行解密函数
BeginOEP:
__asm inc eax // 在十六进制工具中对应0x40
__asm dec eax // 在十六进制工具中对应0x48
MessageBoxA(0, "hello lyshark", 0, 0);
MessageBoxA(0, "hello lyshark", 0, 0);
EndOEP:
__asm inc eax
__asm dec eax
return 0;
}
程序在运行时,首先会循环计算异或密钥,计算完成后执行Decrypt函数,对特定的段进行解密后,释放到源文件中(注意是内存中)然后在调用执行,打印出一句问候语hello lyshark
程序结束。
注意:编译时,请关闭DEP,ASLR,地址随机化等保护,否则VA不固定,无法确定位置。
首先我们需要编译上方魔改版的代码片段,然后使用winhex然后按下【ctrl+alt+X】输入4048找到开始于结束的位置。
这里我们记下,需要加密的开始位置是【526】结束位置是【54b】中间代码部分就是我们需要加密的恶意代码。
接着打开Encrypter.exe工具依次输入加密开始结束位置与密钥,这里设置如下即可。
打开程序执行,会首先经过解密函数将加密后的代码片段释放到内存中,然后才会执行弹窗,非常的安全。
反汇编看一下,解密前,代码是混乱的,根本不是代码。
而执行解密后,内存中立刻恢复到了可以执行的代码状态,然后就可以开心的执行下去了。
此方法也可以规避部分逆向分析,由于不是汇编代码,所以也就无法分析出到底是做什么的了,当然了,如果能找到加密算法的密钥,同样可以解密出来,此处我们并不是用来防范解密者的,而是用来切断程序中的病毒特征的。
C/C++ 动态解密释放ShellCode的更多相关文章
- 动态加载 ShellCode绕过杀软
反病毒解决方案用于检测恶意文件,并且通常使用静态分析技术来区分二进制文件的好坏.如果是恶意文件本身包含恶意内容(ShellCode),那么依靠静态分析技术会非常有效,但如果攻击者使用轻量级的stage ...
- 【C/C++开发】C语言 DLL(动态链接库)中申请动态内存释放的问题
参考:首先,声明一点,凡是使用malloc之类命令动态申请的内存,必须进行释放操作,否则就会发生内存泄漏问题. DLL中申请的内存释放,如果没有做过,很可能会认为是直接在调用程序中释放就可以了,其实不 ...
- C/C++ 对代码节的动态加解密
加壳的原理就是加密或者压缩程序中的已有资源,然后当程序执行后外壳将模拟PE加载器对EXE中的区块进行动态装入,下面我们来自己实现一个简单的区块加解密程序,来让大家学习了解一下壳的基本运作原理. 本次使 ...
- Android动态方式破解apk终极篇(加固apk破解方式)
一.前言 今天总算迎来了破解系列的最后一篇文章了,之前的两篇文章分别为: 第一篇:如何使用Eclipse动态调试smali源码 第二篇:如何使用IDA动态调试SO文件 现在要说的就是最后一篇了,如何应 ...
- shellcode在栈溢出中的利用与优化
0x00 前言 在<Windows Shellcode学习笔记——shellcode的提取与测试>中介绍了如何对shellcode作初步优化,动态获取Windows API地址并调用,并通 ...
- 00-DLL劫持&C语言远程加载shellcode
0x01 杀软拦截检测规则引导-DLL劫持上线 准备工具 cs vs2019 dll劫持工具:https://bbs.pediy.com/thread-224408.htm 极速PDF:https:/ ...
- android加固系列—6.仿爱加密等第三方加固平台之动态加载dex防止apk被反编译
[版权所有,转载请注明出处.出处:http://www.cnblogs.com/joey-hua/p/5402599.html ] 此方案的目的是隐藏源码防止直接性的反编译查看源码,原理是加密编译好的 ...
- C++ 动态数组实例
一维动态数组的实例: #include <iostream> using namespace std; int main() { int *arr; int n; cout<< ...
- C++动态内存分配
C++动态内存分配1.堆内存分配 :C/C++定义了4个内存区间:代码区,全局变量与静态变量区,局部变量区即栈区,动态存储区,即堆(heap)区或自由存储区(free store). 堆的概念:通常定 ...
- C++ Primer : 第十二章 : 动态内存之动态数组
动态数组的分配和释放 new和数组 C++语言和标准库提供了一次分配一个对象数组的方法,定义了另一种new表达式语法.我们需要在类型名后跟一对方括号,在其中指明要分配的对象的数目. int* arr ...
随机推荐
- 奶瓶KeyBoard | N68键盘使用说明
1.旋钮功能及操作说明 旋钮功能向下长按5秒按为音量调节/灯光亮度调节互换,顺时针方向为音量+/亮度加,逆时针方向为音量-/亮度减 2. 无线连接及操作说明 Tab按键右侧和Q按键中间为通道连接指示灯 ...
- 函数计算 FC 3.0 发布,全面降价,最高幅度达93%,阶梯计费越用越便宜
作为国内最早布局 Serverless 的云厂商之一,阿里云在 2017 年推出函数计算 FC,开发者只需编写代码并上传,函数计算就会自动准备好相应的计算资源,大幅简化开发运维过程.阿里云函数计算持续 ...
- java进阶(37)--多线程
文档目录: 一.进程与线程 二.多线程的实现 三.获取线程名与线程对象 四.线程sleep方法 五.线程调度与优先级 六.线程安全(重点) 七.死锁 ------------------------- ...
- 基于java+springboot的商城网站、电子商城管理系统
该系统是基于java+springboot+vue开发的在线商城网站.是给师弟开发的课程作业.学习过程中,遇到问题可以咨询作者. 演示地址 前台地址: http://shop.gitapp.cn 后台 ...
- 【ES系列】(一)简介与安装
首发博客地址 首发博客地址 系列文章地址 教学视频 为什么要学习 ES? 强大的全文搜索和检索功能:Elasticsearch 是一个开源的分布式搜索和分析引擎,使用倒排索引和分布式计算等技术,提供了 ...
- [转帖]两种Nginx日志切分方案,狼厂主要在用第1种
两种Nginx日志切分方案,狼厂主要在用第1种 nginx的日志切分问题一直是运维nginx时需要重点关注的.本文将简单说明下nginx支持的两种日志切分方式. 一.定时任务切分 所谓的定时任务切分, ...
- [转帖]Oracle的审计
AUDIT_TRAIL 初始化参数AUDIT_TRAIL用于控制数据库审计,默认值为none. 参数类型: String 默认值: none 允许动态修改: 否 基本参数: 否 语法: AUDIT_T ...
- [转帖]PostgreSQL中的schema和user
https://www.cnblogs.com/abclife/p/13905336.html postgresql中,用户创建的所有对象都被创建在指定的schema(或namespace)中.其他用 ...
- [转帖]使用 TiFlash
TiDB试用 来源:TiDB 浏览 490 扫码 分享 2021-04-20 20:57:48 使用 TiFlash 按表构建 TiFlash 副本 查看表同步进度 使用 TiDB 读取 TiFla ...
- [转帖]Nginx反向代理中使用proxy_redirect重定向url
https://www.cnblogs.com/kevingrace/p/8073646.html 在使用Nginx做反向代理功能时,有时会出现重定向的url不是我们想要的url,这时候就可以使用pr ...