前言

SMC是一种局部代码加密技术,通过对一段代码进行加密来达到增加逆向工程难度或者免杀的目的。

编写SMC代码不是汇编语言的专利。——《加密与解密 第三版》

是的,SMC不仅能使用汇编上实现,还能很容易的使用VC实现,但是有一个比较致命缺陷:要精准的定位某个函数非常麻烦,所以我们就要以区块为加密的基础单位。

预备知识

需要一点点的PE结构基础就ok啦。

加密算法

既然是加密,就必然需要加密算法。Internet上有许多优秀的开源加密算法,在这篇文章中我将使用自己编写的加密算法。
加密原理简单,是大家耳熟能详的异或加密。

异或的运算方法是一个二进制运算:
1^1=0
0^0=0
1^0=1
0^1=1
两者相等为0,不等为1.
对于一个字符来说,都可以用二进制码来表示.如A:01000001
字符的异或就是对每一位进行二进制运算.
用于加密算法时,假设你要加密的内容为A,密钥为B,则可以用异或加密:
C=A^B
在数据中保存C就行了.
用的时候:
A=B^C
即可取得原加密的内容,所以只要知道密钥,就可以完成加密和解密.

根据原理可以推导出,加密函数也自带解密功能。

void xorPlus(char *soure,int dLen,char *Key,int Klen)
{for (int i=0;i<dLen;){for (int j=0;(j<Klen) && (i<dLen);j++,i++){soure[i]=soure[i] ^ Key[j];soure[i]=~soure[i];}}
}

参数说明
1. soure 被加数据的指针
2. dLen 被加密数据的长度
3. key 密匙数据的指针
4. key 的长度
NOTE:这个函数即时加密函数也是解密函数。

保护敏感代码

这里的敏感代码指的是Cracker和杀毒软件感兴趣的代码,也许你并不想让它们轻松地得到想要的结果。
因为定位一个具体的函数很繁琐,所以我们选择直接定位一个节表。把敏感的代码放入一个新的节表中,然后在需要的时候进行解密,这就是SMC动态加密技术的精髓。
如何把敏感代码放入一个新的节表中?

#pragma code_seg(".SMC")
void Fun1()
{MessageBoxA(NULL,"正在执行被加密算法。",NULL,MB_OK);
}
#pragma code_seg()
#pragma comment(linker, "/SECTION:.SMC,ERW")

#pragma code_seg(“.SMC”) 是一条预编译指令,作用是告诉链接器下面的代码放入 .SMC 代码段中。参数是代码段节表名,学过PE结构的人都知道,节表名<=8 个字符
#pragma code_seg() 是指示链接器,下面的代码放在原来的代码段中。
因为我们是加密敏感代码,而不是主程序代码,所以必须把它切换回去,要不然加密的时候主程序也被一起加密了,就没有负责解密的代码了。
#pragma comment(linker, “/SECTION:.SMC,ERW”) 是设置节表的属性。因为这个节表的数据是要被解密的,所以它必须具有可读写的属性;因为解密后这个节表中有代码,所以它必须具有可执行的属性。当然,这一步不是必须的,也可以在解密前调用VirtualProtect函数来修改内存属性。
一般写法

#pragma code_seg(".SMC")
#include "关键的源代码.h"
#pragma code_seg()
#pragma comment(linker, "/SECTION:.SMC,ERW")

现在,你可以尝试调用Fun1() ,它是能准确无误的执行的。

解密我们的代码

现在来说说如何解密。
要解密我们首先要定位到镜像文件的载入基址。

GetModuleHandle(0);

然后定位到节表。

void SMC(char *pBuf,char *key)
{// SMC 加密XX区段const char *szSecName = ".SMC";short nSec;PIMAGE_DOS_HEADER pDosHeader;PIMAGE_NT_HEADERS pNtHeader;PIMAGE_SECTION_HEADER pSec;pDosHeader=(PIMAGE_DOS_HEADER)pBuf;pNtHeader=(PIMAGE_NT_HEADERS)&pBuf[pDosHeader->e_lfanew];nSec=pNtHeader->FileHeader.NumberOfSections;pSec=(PIMAGE_SECTION_HEADER)&pBuf[ sizeof(IMAGE_NT_HEADERS)+pDosHeader->e_lfanew];for (int i=0;i<nSec;i++){if (strcmp((char *)&pSec->Name,szSecName)==0){int pack_size;char *packStart; pack_size=pSec->SizeOfRawData;packStart = &pBuf[pSec->VirtualAddress];//VirtualProtect(packStart,pack_size,PAGE_EXECUTE_READWRITE,&old);xorPlus(packStart,pack_size,key,strlen(key));//AfxMessageBox(_T("SMC解密成功。"));return;}pSec++;}
}

首先通过对PE结构的解析找到第一个节表所在的地方,然后用strcmp对Name字段进行比较,如果Name字段的值=.SMC 就说明是被加密的代码块,然后取出VirtualAddress和SizeOfRawData调用xorPlus对节表.SMC进行解密。

void CTestDlg::OnBnClickedButton2()
{__try{Fun1();}__except(1){UnPack(KeyBuffer); //修正数据AfxMessageBox(_T("Key不正确,请重新输入。"));}
}

如果解密失败,Fun1() 一定会发生异常,主程序捕获这个异常并提示用户,就可以带到机器码检查的目的。

加密我们的敏感代码

读者可能已经注意到了,编译器肯定是没有加密功能的,所以只有我们自己写程序来加密。
原理:
打开PE文件->定位到节表->查找 .SMC 节表->加密.SMC节表

void SMC(HANDLE hFile,char *key)
{// SMC 加密XX区段HANDLE hMap;const char *szSecName = ".SMC";char *pBuf;int size;short nSec;PIMAGE_DOS_HEADER pDosHeader;PIMAGE_NT_HEADERS pNtHeader;PIMAGE_SECTION_HEADER pSec;size = GetFileSize(hFile,0);hMap=CreateFileMapping(hFile,NULL,PAGE_READWRITE,0,size,NULL);if (hMap==INVALID_HANDLE_VALUE){
_viewf:AfxMessageBox(_T("映射失败"));return ;}pBuf=(char *)MapViewOfFile(hMap,FILE_MAP_WRITE|FILE_MAP_READ,0,0,size);if(!pBuf) goto _viewf;pDosHeader=(PIMAGE_DOS_HEADER)pBuf;pNtHeader=(PIMAGE_NT_HEADERS)&pBuf[pDosHeader->e_lfanew];if (pNtHeader->Signature!=IMAGE_NT_SIGNATURE){AfxMessageBox(_T("不是有效的win32 可执行文件"));goto _clean;}nSec=pNtHeader->FileHeader.NumberOfSections;pSec=(PIMAGE_SECTION_HEADER)&pBuf[ sizeof(IMAGE_NT_HEADERS)+pDosHeader->e_lfanew];for (int i=0;i<nSec;i++){if (strcmp((char *)&pSec->Name,szSecName)==0){int pack_size;char *packStart; pack_size=pSec->SizeOfRawData;packStart = &pBuf[pSec->PointerToRawData];xorPlus(packStart,pack_size,key,strlen(key));AfxMessageBox(_T("SMC加密成功。"));goto _clean;}pSec++;}AfxMessageBox(_T("未找到 .SMC 段"));
_clean:UnmapViewOfFile(pBuf);CloseHandle(hMap);return ;
}

写在最后

vs2012编译的MFC工程的基址是变动,如果基址是变动的,程序每次在载入后都会进行重定位,敏感代码中的绝对地址就会被改变,因为改写的时候在解密代码之前。所以当解密后将会得到错误的结果。所以,这个技术不适用与基址会变得DLL中。
你需要这样配置:

源代码:
一个工程,两个项目,分别是:
SMC Pack SMC加密程序
Test 被加密的程序
使用VS2012编译
链接:http://pan.baidu.com/s/1kTvfWF1 密码:89wv
我的VS配色 O(∩_∩)O~

VC实现SMC加密技术相关推荐

  1. 2020-10-23(SMC加密技术)

    第一篇博客,写得不好还请多多谅解. 今日收获: 今天接触了SMC加密技术,代码一般般,也就自我解密代码这块我这个初学者难以想到. 代码奉上,静态没法查看 judge里面的东西,需要jdb或者ida动态 ...

  2. 数据保密-第三代透明加密技术

    透明加密技术是近年来针对企业数据保密需求应运而生的一种数据加密技术.所谓透明,是指对使用者来说是透明的,感觉不到加密存在,当使用者在打开或编辑指定文件时,系统将自动对加密的数据进行解密,让使用者看到的 ...

  3. 软件加密技术及实现(转载)

    标题   软件加密技术及实现     选择自 whinah 的 Blog 关键字   encrypt 软件加密 保护 散列 数字签名 出处   软件加密技术及实现 雷 鹏 ( 桂林电子工业学院  计算 ...

  4. 加密软件的加密技术发展分析

    透明加密技术是近年来针对企业数据保密需求应运而生的一种数据加密技术.所谓透明,是指对使用者来说是透明的,感觉不到加密存在,当使用者在打开或编辑指定文件时,系统将自动对加密的数据进行解密,让使用者看到的 ...

  5. 【安全加密技术】 对称加密

    转载请注明出处:http://blog.csdn.net/sk719887916/article/details/46822663 上篇了解了<非对称加密>后 今天我来继续了解下加密技术中 ...

  6. 苹果大战FBI将加速科技圈的加密技术发展?

    苹果和 FBI 最终还是没有因为一部手机而走上法庭,但在此之前双方已经经历了多种形式的明争暗斗.回顾本次事件,我们可以概括为:FBI 想要让苹果解锁一部恐怖分子的 iPhone,但是遭到了拒绝.然后 ...

  7. 快速配置Windows 2003平台下实现 IIS(WEB)站点的安全(SSL加密技术!)

    [实验名称] 快速配置Windows 2003平台下实现 IIS(WEB)站点的安全(SSL加密技术!) [实验基本概念] A. 对于公用信息--------------------www.Sohu. ...

  8. Microsoft CryptoAPI加密技术(一)

    http://www.vckbase.com/index.php/wv/716.html 在这个信息爆炸的时代,我们不得不对信息的安全提高警惕.加密作为保障数据信息安全的一种方式,越来越受到人们的关注 ...

  9. Microsoft CryptoAPI加密技术(二)

    原文:http://www.vckbase.com/index.php/wv/717.html 上次我们讲了Microsoft CryptoAPI的构成以及会话密钥的使用.接下来我们将看一下公私密钥对 ...

最新文章

  1. 教你如何看手相掌握命运!
  2. ROS机器人程序设计(原书第2版)3.4 设置动态参数
  3. 快速排序算法-php实现
  4. nginx $mail-send()发送邮件报错_基于SMTP协议的E-MAIL电子邮件发送客户端软件C#实现...
  5. python爬虫反爬机制_Python Scrapy突破反爬虫机制(项目实践)
  6. 人工智能在线特征系统中的生产调度
  7. 学习了c#和ad的操作
  8. linux 卷文件满,LVM逻辑卷容量的增减
  9. Epub,Mobi,Azw3电子书格式的区别
  10. cdr软件百度百科_cdr是什么软件?
  11. 教师计算机基础培训心得,教师集中培训心得体会
  12. 2022年全国职业院校技能大赛:网络系统管理项目 A模块-网络构建(10套样题)
  13. lumen 项目根目录_Lumen 初体验(二)
  14. Pet Peeve 是什么?
  15. 【九度OJ】查找第K小数
  16. mono android单选按钮,CLEngine
  17. 华为OD机试 - 卡片组成的最大数字(Python) | 机试题算法思路
  18. py3 BeautifulSoup 利器 html 解析器使用
  19. 红旗Linux网卡Bind,红旗linux(sp3)怎么安装网卡驱动啊
  20. 一个完整的产品专题页面策划思路是什么样子?

热门文章

  1. 低电压版cpu java编程_cpu低电压版跟标准电压版区别哪个好
  2. Notification点击跳转及消失
  3. 鼠标(HID)设备描述符含义
  4. 1.3「Motoko——Actors and async data」
  5. JAVA增删改查代码
  6. mysql 数据类型 ppt_第4章__MySQL数据类型.ppt
  7. python selenium安装教程 谷歌驱动_selenium 安装与chromedriver安装的方法步骤
  8. Manifest merger failed : android:exported needs to be explicitly specified for element
  9. windows- 怎么查看本地网卡速度
  10. bootstrap公共样式(学习笔记)