{$cfg_webname}
主页 > 计算机 > C++ >

加壳程序的设计与实现

来源:wenku163.com  资料编号:WK1632131 资料等级:★★★★★ %E8%B5%84%E6%96%99%E7%BC%96%E5%8F%B7%EF%BC%9AWK1632131
资料介绍

摘  要
在自然界中,植物用壳来保护种子,动物用壳来保护身体等。同样,在计算机软件里也有一段专门负责保护软件不被非法修改的程序。他们附加在原程序上通过Windows加载器载入内存,先于原程序执行,得到控制权,执行过程中对原始程序进行解密、还原,还原完成后再把控制权交还给原始程序,执行原来的代码的部分。加上外壳后,原始程序代码在磁盘文件中一般是以加密后的形式存在的。只在执行时在内存中还原,这样可以有效的防止破解者对文件的非法的修改,同时也可防止程序被静态反编译。由于这段程序和自然界的壳在功能上有很多相同的地方,基于命名规则,就把这样的程序称为“壳”了。
加壳软件一般都有良好的操作界面,使用也比较简单。除了一些商业壳,还有一些个人开发的壳,种类较多。壳对软件提供了良好的保护同时,也带来了兼容性的问题,选择一款壳保护性软件后,要在不同的硬件和软件系统上多测试。由于壳能保护自身代码因此许多木马或病毒喜欢用壳来保护和隐藏自己。对于一些流行的壳,杀毒引擎能对目标软件脱壳,再进行病毒检查。而大多数的私人壳,杀毒软件是不会专门开发解压引擎的。
随着加壳技术的发展,很多加壳软件除具有较强的压缩性能,同时也有了较强的保护性能。本程序主要是个压缩类的壳。(所有权: 毕业设计网 )
关键词:加壳程序设计;PE格式;软件加壳

ABSTRACT
In nature, plants use the shell to protect the seeds, animal carcasses, such as to protect the body. Similarly, in the computer software also has a section dedicated to the protection of software is not illegal modification procedures. They attached to the original procedure through Windows loader loaded into memory, first in the original program execution, the control over the process of implementation of the original procedure decrypt, restore, restore later put back to original control procedures, the implementation of the original part of the code. Together with the shell, the original program code in the disk file is encrypted in the general form of existence. Only in the implementation of reduction in memory, this can effectively prevent the crack from the document illegal modifications, but also to prevent the procedure being static decompile. Procedures and because of this nature, the shell has a lot of functions the same place, based on the naming, so this process is called "shell" of the.
packed software in general have good operation interface, easy to use and more. Apart from a number of commercial shell, there are some personal development of the shell, type more. Shell of the software provided a good protection at the same time, it also brings about a compatibility problem, select a shell of protective software to different hardware and software systems on many tests. Because of the shell to protect their own code so much like to use Trojan horse or virus shell to protect and hide their own. For some popular shells, anti-virus engine can be software on the target shell, and then check for viruses. And most private shell, anti-virus software are not specifically developed decompression engine.
packed technological development,packed a lot of software in addition to a strong compression performance, but also has strong protection performance. This procedure is a major type of shell compression.
Key Words:Packed; Shell; PE

可执行程序是能被操作系统所识别的,包含机器指令码及程序数据的文件。现在用户破解分析的各类调试器、静态反汇编工具及监视工具非常多。有些静态分析工具生成的反汇编代码可读性非常接近源代码,这样程序的思路就很容易被识别了。但是有些作者想保护自己的程序思路或者一些版权信息,不想让别人随便改动。还有的作者需要把程序搞得小一点,方便使用。通常需要用到加壳程序了。现在壳程序很多,但是通用脱壳机,或者查壳工具都能很轻松的脱壳,或者查出壳。对于查出的壳,可以用OllyDbg等动态调试工具用相对应的手法很快的手工脱掉。如果自己实现一个壳,这样通用的脱壳机脱不了,查壳工具也查不出。在一定程度上可以有效的保护程序思路和作者版权信息。(所有权: 毕业设计网 )
 
加壳的概念
对程序文件加密时有一个方面是必须要考虑的,那就是防止解密者对程序文件的非法修改和反编译。要实现这种保护,最常用的方法之一就是给编译好的程序文件加上一个外壳。所谓的外壳就是附加在原程序上,通过windows装载器载入内存后,先于原程序执行,得到控制权,执行过程中对原程序进行解密、还原,还原完成后再把控制权交给原程序,执行原来的代码部分。加上外壳后,原程序代码在磁盘文件中一般是加密后的形式存在的,只在执行时在内存还原,这样就可以比较有效的防止破解者对程序文件的非法修改,同时也可以防止程序被静态反编译。
对程序的加壳一般是选用一些现成的加壳软件,如tElock,Asprotect,Aspack,UPX等。不同的外壳所侧重的方面不一样,有的侧重于压缩,有的侧重于加密。为了更好地保护软件,一般可以来用tElock,aspuroct等侧重于加密的加先软件。使用现成的加壳软件虽然很方便,却存在着一些不可避免的缺点:越是先进、优秀的加壳软件有时反而会越不安全。为什么呢?因为加壳软件越优秀、用它加密的软件越多,研究它的人也会越多,其中必定有一些高手会分析出这些外壳所用的关键技术,并将其公开,有时甚至会针对这些加壳软件而写出专门的脱壳机。一旦一个加壳软件被写出脱壳机,那么用它加密的软件的保密性就可想而知了。所以写一个自己专用的加完软件还是有一定意义的。
  本设计编写了一个简单的加壳程序。在这个加壳程序中要实现的主要功能有:对程序的压缩、对资源的处理、对输入表的处理、区块的融合和额外数据的保留等。
本设计的加壳工具有两部分组成,第一部分是主体程序,主要是将原PE文件读入内存,然后对PE文件各个部分加工,主要是各区块数据压缩,将输入表、重定位变形,最后将外壳部分与处理好的主体文件拼合。第二部分就是外壳部分,这部分主要是加壳后程序执行时候的引导段,它模拟PE加载器处理输入表、重定位表,最后跳到原程序。(所有权: 毕业设计网 )

PE格式的判断
由于处理的程序对象是PE格式,所以对文件进行处理前必须先判断文件是否符合PE格式。
检验的方法是:先看文件头部第一个字的值是否等于IMAGE_DOS_SIGNATURE,也就是字符串“MZ”,如果是,则表示DOS MZ header有效。其次根据e_lfanew字段找到PE header,检查比较PE 头部的第一个字的值是否等于IMAGE_NT_SIGNATURE,也就是“PE”。如果前后两个值都匹配,那么就认为该文件是一个有效的PE文件,最后再检查一下FileHeader结构中的characteristics字段的值,判断是EXE文件还是DLL文件。
PE格式判断的实现代码如下:
BOOL IsPEFile(TCHAR *szFilePath,HWND hDlg)
{
 DWORD     fileSize;
 HANDLE     hMapping;
 LPVOID     ImageBase;
    PIMAGE_DOS_HEADER     pDosHeader=NULL;
    PIMAGE_NT_HEADERS       pNtHeader=NULL;
    PIMAGE_FILE_HEADER      pFilHeader=NULL;
 PIMAGE_OPTIONAL_HEADER  pOptHeader=NULL;
    PIMAGE_SECTION_HEADER   pSecHeader=NULL;
 //打开文件
   HANDLE hFile = CreateFile(
  szFilePath,
  GENERIC_READ,
  FILE_SHARE_READ,
  NULL,
  OPEN_EXISTING,
  FILE_ATTRIBUTE_NORMAL,
  NULL);
 if ( hFile == INVALID_HANDLE_VALUE ) {
   AddLine(hDlg,"错误!文件打开失败!");
   return  FALSE;
 }
 //获得文件长度 :
 fileSize = GetFileSize(hFile,NULL);
 if (fileSize == 0xFFFFFFFF) {
  AddLine(hDlg,"错误!文件打开失败!");
  return FALSE;
 }
    hMapping=CreateFileMapping(hFile,NULL,PAGE_READONLY,0,0,NULL);
 if(!hMapping)
 {         
  CloseHandle(hFile);
  AddLine(hDlg,"错误!文件打开失败!");
  return FALSE;
 }
 ImageBase=MapViewOfFile(hMapping,FILE_MAP_READ,0,0,0);
    if(!ImageBase)
 {         
  CloseHandle(hMapping);
  CloseHandle(hFile);
     AddLine(hDlg,"错误!文件打开失败!");
  return FALSE;
 }
    pDosHeader=(PIMAGE_DOS_HEADER)ImageBase;
    if(pDosHeader->e_magic!=IMAGE_DOS_SIGNATURE){
  AddLine(hDlg,"错误!不是可执行文件!");
         return FALSE;
 }
pNtHeader=(PIMAGE_NT_HEADERS32)((DWORD)pDosHeader+pDosHeader->e_lfanew);
    if (pNtHeader->Signature != IMAGE_NT_SIGNATURE ){
  AddLine(hDlg,"错误!不是可执行文件!");
        return FALSE;
 }
    pFilHeader=&pNtHeader->FileHeader;
    if (pFilHeader->NumberOfSections== 1 ){
  AddLine(hDlg,"文件可能已被压缩,放弃!");
        return FALSE;
 }
  pOptHeader=&pNtHeader->OptionalHeader;//得到IMAGE_OPTIONAL_HEADER结构指针的函数
 // pOptHeader->AddressOfEntryPoint;
    //得到第一个区块的起始地址 
    pSecHeader=IMAGE_FIRST_SECTION(pNtHeader);
    pSecHeader++;//得到第二个区块的起始地址
if((pOptHeader->AddressOfEntryPoint)>(pSecHeader->VirtualAddress)){
   AddLine(hDlg,"文件可能已被压缩,放弃!");
        return FALSE;
 }
  if (((pFilHeader->Characteristics) & IMAGE_FILE_DLL )!=0){
   AddLine(hDlg,"是PE-DLL文件,可以压缩.");
  }
  else
{
   AddLine(hDlg,"是PE-EXE文件,可以压缩.");
  }
  UnmapViewOfFile(ImageBase);
  CloseHandle(hMapping);
  CloseHandle(hFile);
  return TRUE;
}



目  录 
目  录 1
摘  要 2
ABSTRACT 3
第一章 绪论 4
一.研究背景与意义 4
第二章 程序的分析与实现 5
一. 前提 5
1. PE格式简介 5
二. 加壳主程序 8
1. 加壳的概念 8
2. PE格式的判断 10
3. 文件读入内存 12
4. 读取附加数据 14
5. 处理输入表 15
6. 处理重定位表 18
7. 压缩文件 21
8. 处理资源数据 23
9. 合并节 28
三. 外壳部分的编写 29
1. 外壳工作流程概述 29
2. 外壳第一段 30
(所有权: 毕业设计网 )
3. 外壳第二段 35
四. 将外壳部分添加至原程序 40
第三章 结论 46
参考文献 47
致  谢 48

推荐资料