首页
社区
课程
招聘
[原创]动手写加密壳
发表于: 2015-7-15 18:46 27481

[原创]动手写加密壳

2015-7-15 18:46
27481

这个是继上一篇加密壳帖子   masm32写加密壳 的另一篇新帖。不同的是,这次将采用vc++来编译壳

工程文件已经打包。 解决方案内有2个项目:EasyProtect 和 Shell。
EasyProtect 是用来加壳的。
Shell就是壳的核心,编译后是Shell.dll。

EasyProtect 流程:
  打开被加壳文件 -> 打开Shell.dll -> 提取shell.dll代码段(.MyCode) 数据 ->在被加壳文件中创建新的区段->重定位Shell.dll的代码数据->把重定位好的代码数据写到被加壳程序的新区段中->加密被加壳程序代码段->修正OEP

但是还有一些细节没有提及。
packPE 加壳函数。

bool packPE(char * szFileName)
{
        CPeFile MyPe;
        CPeFile MyShell;  // 壳也是一个编译的pe文件
        PIMAGE_SECTION_HEADER pNewSec,pShellSec;
        PMyDosHeader pDosHead;
        char *shellcode;
        if(!MyPe.LoadPe(szFileName))
                return false;
        if(!MyShell.LoadPe(SHELL_FILE))
                return false;
        
        pDosHead = (PMyDosHeader)MyPe.GetBuffer();
        if (pDosHead->info.flag==0x1447) // 已经加密过了
                return false;
        /* 获取壳的代码段 */
        pShellSec = MyShell.FindSectionByName(".MyCode");
        pNewSec = MyPe.AddSection(".fishc",pShellSec->SizeOfRawData);
        if(!pNewSec) return false;
        // 重定位数据 0.0 
        FixRelocBase2(MyShell,MyPe.GetImageBase(),pNewSec->VirtualAddress);
        // 复制代码数据
        shellcode = new char[pShellSec->SizeOfRawData];
        bool bRet =
        MyShell.ReadDataByRaw(pShellSec->PointerToRawData,shellcode,pShellSec->SizeOfRawData);
        if(!bRet)return false;
        bRet = 
        MyPe.WriteDataByRaw(pNewSec->PointerToRawData,shellcode,pShellSec->SizeOfRawData);
        if(!bRet) return false;
        delete shellcode;
        // 加密代码段
        char *buf;
        char *key = "mooncakeisverylovelygirl";
        PIMAGE_SECTION_HEADER cs;
        pDosHead->info.CodeSec=MyPe.GetCodeSection();
        cs = MyPe.GetSectionById(pDosHead->info.CodeSec);
        buf = (char *)MyPe.GetBuffer();
        xorPlus(&buf[cs->PointerToRawData],cs->SizeOfRawData,key,strlen(key));
        // 修正OEP
        DWORD t;
         // 获得壳的入口函数在.MyCode中的偏移
        t = MyShell.GetEntry() - pShellSec->VirtualAddress;
        // 把这个偏移加上新区段的基址就是最终的入口偏移
        t+=pNewSec->VirtualAddress;
        //保存源程序OEP
        DWORD orgOEP;
        orgOEP = MyPe.GetEntry()+MyPe.GetImageBase();
        pDosHead->info.oep = orgOEP;
        pDosHead->info.flag = 0x1447;
        MyPe.SetNewEntry(t);
        MyPe.FlushBuffer(); //把缓冲区的数据保存到硬盘
        return true;
}
void FixRelocBase2(CPeFile &cPe,DWORD ImageBase,DWORD SecBase)
{
        PIMAGE_BASE_RELOCATION rel;
        DWORD relNum;
        rel=(PIMAGE_BASE_RELOCATION)(
                cPe.rva_to_buffer(cPe.GetDataDirInfo(IMAGE_DIRECTORY_ENTRY_BASERELOC)->VirtualAddress)
                );
        while (rel->SizeOfBlock)
        {
                relNum=(rel->SizeOfBlock-8)/2;
                for (DWORD i=0;i<relNum;i++)
                {
                        char Type;
                        Type = rel->TypeOffset[i]>>12;
                        if (Type==3)
                        {
                                DWORD *relAdr;
                                relAdr   = (DWORD *)rel->VirtualAddress;
                                relAdr   = (DWORD *)cPe.rva_to_buffer((DWORD)relAdr + (rel->TypeOffset[i]&0x0fff));
                                *relAdr -= cPe.GetImageBase();  //算出RVA
                                *relAdr -=cPe.FindSectionByName(".MyCode")->VirtualAddress;
                                *relAdr +=SecBase;
                                *relAdr +=ImageBase;
                        }
                }
                rel=(PIMAGE_BASE_RELOCATION)((DWORD)rel + rel->SizeOfBlock);
        }
}

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

上传的附件:
收藏
免费 4
支持
分享
最新回复 (37)
雪    币: 205
活跃值: (40)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
谢谢分享!
2015-7-15 19:28
0
雪    币: 4560
活跃值: (1002)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
3
好东西收藏一份
2015-7-15 19:47
0
雪    币: 47147
活跃值: (20450)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
4
感谢分享!
帖子我移到脱壳版块上来了。

有时间,再研究一下VM
2015-7-15 21:09
0
雪    币: 135
活跃值: (106)
能力值: ( LV2,RANK:140 )
在线值:
发帖
回帖
粉丝
5
有一个问题:
Shell.dll 只用里面的代码段的话, 那在编写的时候, 能使用全局变量吗
2015-7-15 21:19
0
雪    币: 8
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
学习学习了学习学习了
2015-7-15 21:43
0
雪    币: 6911
活跃值: (9069)
能力值: ( LV17,RANK:797 )
在线值:
发帖
回帖
粉丝
7
可以的,代码段和数据段都合并在一起的。
#pragma code_seg(".MyCode")  // 设置代码段为.MyCode
#pragma comment(linker, "/MERGE:.data=.MyCode") // 设置数据段为 .MyCode
#pragma comment(linker, "/MERGE:.rdata=.MyCode")
2015-7-15 21:54
0
雪    币: 6911
活跃值: (9069)
能力值: ( LV17,RANK:797 )
在线值:
发帖
回帖
粉丝
8
谢谢大大的鼓励~
2015-7-15 21:56
0
雪    币: 322
活跃值: (113)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
谢谢分享!
2015-7-15 23:42
0
雪    币: 56
活跃值: (34)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
10
多谢分享~
2015-7-16 08:37
0
雪    币: 135
活跃值: (106)
能力值: ( LV2,RANK:140 )
在线值:
发帖
回帖
粉丝
11
懂了, 不错的。 还有一个问题: 这个壳能给dll加壳吗?
2015-7-16 09:40
0
雪    币: 602
活跃值: (45)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
加壳 学习了
2015-7-16 12:04
0
雪    币: 6911
活跃值: (9069)
能力值: ( LV17,RANK:797 )
在线值:
发帖
回帖
粉丝
13
还没实现。
要实现的话要需要重新修正重定位表。
2015-7-16 12:07
0
雪    币: 341
活跃值: (143)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
14
mooncakeisverylovelygirl
2015-7-16 16:46
0
雪    币: 110
活跃值: (527)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
15
能给任意DLL和EXE加壳吗。
2015-7-16 17:06
0
雪    币: 144
活跃值: (335)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
哪里是加密壳了 - -
2015-7-16 17:09
0
雪    币: 6911
活跃值: (9069)
能力值: ( LV17,RANK:797 )
在线值:
发帖
回帖
粉丝
17
好眼力!
2015-7-16 19:53
0
雪    币: 1
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
Sry
18
支持技术分享,受教了。
2015-7-18 01:33
0
雪    币: 35739
活跃值: (7155)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
19
14楼看你眼熟
2015-7-18 07:00
0
雪    币: 112
活跃值: (14)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
20
不错,学习下..
2015-7-18 10:25
0
雪    币: 13082
活跃值: (4082)
能力值: ( LV15,RANK:1673 )
在线值:
发帖
回帖
粉丝
21
下载学习中.3Q.
2015-7-18 22:59
0
雪    币: 5327
活跃值: (3719)
能力值: ( LV13,RANK:283 )
在线值:
发帖
回帖
粉丝
22
写的挺好,支持一下
2015-7-19 14:39
0
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
23
比较高深,先收藏再慢慢消化。
2015-7-19 20:46
0
雪    币: 454
活跃值: (16)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
24
谢谢分析,文章对我很有用。
2015-7-20 10:00
0
雪    币: 74
活跃值: (748)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
25
谢谢分享
2015-7-21 09:27
0
游客
登录 | 注册 方可回帖
返回
//