精华内容
下载资源
问答
  • 1.如果您在使用 Enigma Protector 加壳保护工具。 2.支持制作一机一码。 3.暂时不支持NET程序。 4.enigma protector安全性高。
  • 吾爱软件加壳脱壳工具箱.exe
  • C#实现软件加壳

    2017-07-07 08:42:12
    C#实现软件加壳
  • 原创软件加壳方案,可C/C++实现,无需写汇编代码。 软件加壳方案 1 1. 方案概况 2 1.1. 方案概况图 2 1.2. 执行过程 2 2. 预备知识 3 2.1. 从EntryPoint到main() 3 2.2. 镜像基地址 3 2.3. 地址重定位 3 2.3.1. 全局...
  • Linux系统下改进的软件加壳保护技术.pdf。
  • Vmprotect使用虚拟一个不同于x86的CPU来执行转化后的程序,这个CPU只... VMProtect是一个软件保护软件。通过这个软件保护的代码部分在虚拟机上执行,这使得被保护的程序很难被分析与破解。反汇编程序与MAP文件的运用使
  • 针对Linux系统下加壳软件易被发现、易改变原有程序入口地址等一系列问题,提出了一种改进的软件加壳方法——加壳并重构可执行文件,即:SRELF(Shelling and Re-constructed Executable and LinkingFormat)。...
  • SE软件加壳免费版

    2019-01-22 22:21:45
    Shielden有2种工作模式: 完整模式提供完整的Safengine产品体验(如反调试、授权功能等)。 虚拟机模式则以体积和速度优先,提供代码虚拟化等关键保护功能。 您可以运行Shielden.exe启动完整模式,或运行Shielden...
  • 软件加壳工具

    2015-06-07 16:32:40
    给自己写的软件进行加壳,轻轻松松维护自己的软件版权!
  • 各种加壳软件全部版本,应有尽有:virboxprotector_trial_windows、vprotectpjb_61772、vprotect_pro
  • 软件加壳的作用

    千次阅读 2019-07-25 10:34:28
    一、加壳含义 百度释义:   加壳的特征是可执行程序资源压缩,压缩后的程序可直接运行。   加壳的另一种常用方式是在二进制的程序中植入一段代码,在运行的时候优先取得控制权,之后再把控制权交给原始代码...

    一、加壳含义

    百度释义:
      加壳的特征是可执行程序资源压缩,压缩后的程序可直接运行。
      加壳的另一种常用方式是在二进制的程序中植入一段代码,在运行的时候优先取得控制权,之后再把控制权交给原始代码(目的:隐藏程序真正的OEP[入口点,防止被破解],大多数病毒就是此原理)

    二、加壳作用

    • 防止软件被破解,保护软件版权;
    • 增加程序运行速度;
    • 病毒制作,绕过一些杀毒软件的扫描,从而实现作为病毒的一些入侵或破坏一些特征;
    展开全文
  • 软件加壳源代码

    2013-09-09 11:09:22
    PE文件检测,输入表内容获取和转储,以及重建shellcode写入新区段,获得LoadLibrary,GetProcAddress地址
  • 软件加壳加密

    2018-08-03 10:31:22
    针对所有桌面应用程序进行加壳加密,使软件更加安全,基本无法破解。
  • 软件加壳工具windows

    2009-06-27 15:21:03
    个人收藏,可以定做软件。直接将程序打成exe格式的程序包
  • 软件加壳与脱壳

    千次阅读 2018-03-05 20:21:23
    加壳一般是指保护程序资源的方法;脱壳一般是指除掉程序的保护,用来修改程序资源。从技术的角度出发,壳是一... 软件的壳分为加密壳、压缩壳、伪装壳、多层壳等类,目的都是为了隐藏程序真正的OEP(入口点,防止被破...

    加壳一般是指保护程序资源的方法;
    脱壳一般是指除掉程序的保护,用来修改程序资源。

    从技术的角度出发,壳是一段执行于原始程序前的代码。原始程序的代码在加壳的过程中可能被压缩、加密……当加壳后的文件执行时,壳-这段代码先于原始程序运行,其把压缩、加密后的代码还原成原始程序代码,然后再把执行权交还给原始代码。 软件的壳分为加密壳、压缩壳、伪装壳、多层壳等类,目的都是为了隐藏程序真正的OEP(入口点,防止被破解)。

    1)壳的概念

    作者编好软件后,编译成*.exe可执行文件。

    1.有一些版权信息需要保护起来,不想让别人随便改动,如作者的姓名,即为了保护软件不被破解,通常都是采用加壳来进行保护;

    2.需要把程序搞的小一点,从而方便使用。于是,需要用到一些软件,它们能将exe可执行文件压缩;

    3.在黑客界给木马等软件加壳脱壳以躲避杀毒软件。实现上述功能,这些软件称为加壳软件。

    2)加壳软件最常见的加壳软件

    ASPACK ,UPX,PEcompact 不常用的加壳软件WWPACK32;PE-PACK ;PETITE NEOLITE

    3)侦测壳和软件所用编写语言的软件 

    因为脱壳之前要查他的壳的类型。 

    1.侦测壳的软件fileinfo.exe 简称fi.exe(侦测壳的能力极强);

    2.侦测壳和软件所用编写语言的软件language.exe(两个功能合为一体,很棒),推荐language2000中文版(专门检测加壳类型);
    3.软件常用编写语言Delphi,Visual Basic(VB)---最难破,Visual C(VC)。 

    4)脱壳软件 
    软件加壳是作者写完软件后,为了保护自己的代码或维护软件产权等利益所常用到的手段。目前有很多加壳工具,当然有盾,自然就有矛,只要我们收集全常用脱壳工具,那就不怕他加壳了。软件脱壳有手动脱和自动脱壳之分,下面我们先介绍自动脱壳,因为手动脱壳需要运用汇编语言,要跟踪断点等,不适合初学者,但我们在后边将稍作介绍。 

    加壳一般属于软件加密,现在越来越多的软件经过压缩处理,给汉化带来许多不便,软件汉化爱好者也不得不学习掌握这种技能。现在脱壳一般分手动和自动两种,手动就是用TRW2000、TR、SOFTICE等调试工具对付,对脱壳者有一定水平要求,涉及到很多汇编语言和软件调试方面的知识。而自动就是用专门的脱壳工具来脱,最常用某种压缩软件都有他人写的反压缩工具对应,有些压缩工具自身能解压,如UPX;有些不提供这功能,如:ASPACK,就需要UNASPACK对付,好处是简单,缺点是版本更新了就没用了。另外脱壳就是用专门的脱壳工具来对付,最流行的是PROCDUMP v1.62 ,可对付目前各种压缩软件的压缩档。在这里介绍的是一些通用的方法和工具,希望对大家有帮助。我们知道文件的加密方式,就可以使用不同的工具、不同的方法进行脱壳。下面是我们常常会碰到的加壳方式及简单的脱壳措施,供大家参考:

    脱壳的基本原则就是单步跟踪,只能往前,不能往后

    脱壳的一般流程是:查壳->寻找OEP->Dump->修复

    找OEP的一般思路如下:先看壳是加密壳还是压缩壳,压缩壳相对来说容易些,一般是没有异常,找到对应的popad后就能到入口, 我们知道文件被一些压缩加壳软件加密,下一步我们就要分析加密软件的名称、版本。因为不同软件甚至不同版本加的壳,脱壳处理的方法都不相同。 


    常用脱壳工具: 


    1、文件分析工具(侦测壳的类型):Fi,GetTyp,peid,pe-scan, 
    2、OEP入口查找工具:SoftICE,TRW,ollydbg,loader,peid 
    3、dump工具:IceDump,TRW,PEditor,ProcDump32,LordPE 
    4、PE文件编辑工具PEditor,ProcDump32,LordPE 
    5、重建Import Table工具:ImportREC,ReVirgin 
    6、ASProtect脱壳专用工具:Caspr(ASPr V1.1-V1.2有效),Rad(只对ASPr V1.1有效),loader,peid 

    (1)Aspack: 用的最多,但只要用UNASPACK或PEDUMP32脱壳就行了 
    (2)ASProtect+aspack:次之,国外的软件多用它加壳,脱壳时需要用到SOFTICE+ICEDUMP,需要一定的专业知识,但最新版现在暂时没有办法。 
    (3)Upx: 可以用UPX本身来脱壳,但要注意版本是否一致,用-D 参数 
    (4)Armadill: 可以用SOFTICE+ICEDUMP脱壳,比较烦 
    (5)Dbpe: 国内比较好的加密软件,新版本暂时不能脱,但可以破解 
    (6)NeoLite: 可以用自己来脱壳 
    (7)Pcguard: 可以用SOFTICE+ICEDUMP+FROGICE来脱壳 
    (8)Pecompat: 用SOFTICE配合PEDUMP32来脱壳,但不要专业知识 
    (9)Petite: 有一部分的老版本可以用PEDUMP32直接脱壳,新版本脱壳时需要用到SOFTICE+ICEDUMP,需要一定的专业知识 
    (10)WWpack32: 和PECOMPACT一样其实有一部分的老版本可以用PEDUMP32直接脱壳,不过有时候资源无法修改,也就无法汉化,所以最好还是用SOFTICE配合 PEDUMP32脱壳 

    我们通常都会使用Procdump32这个通用脱壳软件,它是一个强大的脱壳软件,他可以解开绝大部分的加密外壳,还有脚本功能可以使用脚本轻松解开特定外壳的加密文件。另外很多时候我们要用到exe可执行文件编辑软件ultraedit。我们可以下载它的汉化注册版本,它的注册机可从网上搜到。ultraedit打开一个中文软件,若加壳,许多汉字不能被认出 ultraedit打开一个中文软件,若未加壳或已经脱壳,许多汉字能被认出 ultraedit可用来检验壳是否脱掉,以后它的用处还很多,请熟练掌握例如,可用它的替换功能替换作者的姓名为你的姓名注意字节必须相等,两个汉字替两个,三个替三个,不足处在ultraedit编辑器左边用00补。 

    常见的壳脱法: 
    (一)aspack壳 脱壳可用unaspack或caspr

    1.unaspack ,使用方法类似lanuage,傻瓜式软件,运行后选取待脱壳的软件即可. 缺点:只能脱aspack早些时候版本的壳,不能脱高版本的壳

    2.caspr第一种:待脱壳的软件(如aa.exe)和caspr.exe位于同一目录下,执行windows起始菜单的运行,键入 caspr aa.exe脱壳后的文件为aa.ex_,删掉原来的aa.exe,将aa.ex_改名为aa.exe即可。使用方法类似fi 优点:可以脱aspack任何版本的壳,脱壳能力极强缺点:Dos界面。第二种:将aa.exe的图标拖到caspr.exe的图标上***若已侦测出是aspack壳,用unaspack脱壳出错,说明是aspack高版本的壳,用caspr脱即可。 

    (二)upx壳 脱壳可用upx待脱壳的软件(如aa.exe)和upx.exe位于同一目录下,执行windows起始菜单的运行,键入upx -d aa.exe。 

    三)PEcompact壳 脱壳用unpecompact 使用方法类似lanuage傻瓜式软件,运行后选取待脱壳的软件即可。 

    四)procdump 万能脱壳但不精,一般不要用 使用方法:运行后,先指定壳的名称,再选定欲脱壳软件,确定即可脱壳后的文件大于原文件由于脱壳软件很成熟,手动脱壳一般用不到。

    展开全文
  • 软件加壳的原理及实现

    万次阅读 多人点赞 2017-03-30 16:48:11
    加壳的实现我是个初学者,所知有限,难免会有错误,如果有人发现了错误,还请指正 先大致说一下加壳的原理,即在原PE文件(后面称之为宿主文件)上加一个新的区段(也就是壳),然后从这个新的区段上开始运行;也就...

    加壳的实现

    我是个初学者,所知有限,难免会有错误,如果有人发现了错误,还请指正。
    先大致说一下加壳的原理,即在原PE文件(后面称之为宿主文件)上加一个新的区段(也就是壳),然后从这个新的区段上开始运行;也就算是成功的加上了壳;下面我们就说一下具体的实现。
    这个工程有两个项目,一个用来生成壳的Win32项目(dll类型),另一个是实现加壳的MFC项目;
    加壳的项目界面是用MFC实现的,除了原有的类外,添加了两个新类,一个用于PE操作,
    一个用于加壳。

    下面说下加壳过程的实现:
    先将原PE文件读取到内存;获取头文件信息,获得.text区段信息,然后对代码段进行加密(简单的异或加密);随后再用LoadLibrary将生成的壳(是一个dll)加载到内存;我们需要在壳的程序里对宿主PE进行解密,并且还要修复重定位,所以要把一些必要的数据存储到加载的壳里面;
    申请空间将dll(壳)拷贝一份(此处大家可能会疑惑为什么要拷贝一份,因为我在以LoadLibrary加载进来的壳里直接修改需要重定位的地址信息时,程序运行会出错);
    然后申请内存,大小是原宿主PE文件和壳的大小的和;先将宿主程序拷贝进去;
    然后修复重定位信息,这个地方应该重点说明一下,我是直接把展开的整个dll拷贝到新PE文件里,并且打算壳的部分利用系统的重定位(每次加载PE文件的时候,如果重定位没有关掉,系统会进行一次重定位),所以在拷贝之前,要把需要重定位的地址修改成在新PE中的虚拟地址,并且我们的壳是通过LoadLibrary的方式加载的,已经被重定位过,我又是直接拷贝过来的,所以修改地址的时候要注意,后面会说到如何修改。
    然后,合并PE文件和壳;设置新的OEP,既然加壳,当然要从壳的我们规定的开始位置开始执行,需要将其改成相对新PE开始位置的偏移,原理和修复重定位差不多,不过一个是相对虚拟地址,一个是虚拟地址。
    如图:
    这里写图片描述
    相对虚拟地址=1+2;
    如果修复重定位的话就某一地址的相对虚拟地址再加个默认基址;
    下面是代码实现部分:

    bool CPack::Pack(WCHAR * szPath)
    {
        CPe objPe;
    
        //读取要被加壳的PE文件
        DWORD dwReadFilSize = 0;
        HANDLE hFile = CreateFile(szPath,GENERIC_READ | GENERIC_WRITE, 0, NULL,
                       OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    
        DWORD dwFileSize = GetFileSize(hFile, NULL);
        char * pFileBuf = new char[dwFileSize];
        memset(pFileBuf, 0, dwFileSize);
        ReadFile(hFile, pFileBuf, dwFileSize, &dwReadFilSize, NULL);
    
        //获取PE头文件信息
        PEHEADERINFO pPeHead = { 0 };
        objPe.GetPeHeaderinfo(pFileBuf, &pPeHead);
    
        //加密
        IMAGE_SECTION_HEADER pTxtSection;
        objPe.GetSectionInfo(pFileBuf, &pTxtSection, ".text");
        objPe.XorCode((LPBYTE)(pTxtSection.PointerToRawData + pFileBuf), pTxtSection.SizeOfRawData);
    
        //用loadLibrary加载壳文件
        HMODULE pLoadStubBuf = LoadLibrary(L"..\\Release\\Stub.dll");
    
        //存储必要的信息
        PPACKINFO PackInfoAdd = (PPACKINFO)GetProcAddress((HMODULE)pLoadStubBuf, "g_PackInfo");
    
        PackInfoAdd->dwOriStartPoint = pPeHead.pOptionHeader->AddressOfEntryPoint;                                          //需要跳转的OEP
        PackInfoAdd->dwImageBase = pPeHead.pOptionHeader->ImageBase;                                                        //默认加载基址
        PackInfoAdd->dwXorCode = pTxtSection.VirtualAddress;                                                                //加密代码段地址
        PackInfoAdd->dwXorKey = 0xE;                                                                                        //加密密钥
        PackInfoAdd->dwXorSize = pTxtSection.SizeOfRawData;                                                                 //加密大小
        PackInfoAdd->stcPeRelocDir = pPeHead.pOptionHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC];                 //重定位表信息
        PackInfoAdd->dwSizeOfImage = pPeHead.pOptionHeader->SizeOfImage;                                                    //原PE的大小
    
        //拷贝一份
        MODULEINFO stcModInfo = { 0 };
        GetModuleInformation(GetCurrentProcess(), pLoadStubBuf, &stcModInfo, sizeof(MODULEINFO));
        char * pStubBuf = new char[stcModInfo.SizeOfImage];
        memset(pStubBuf, 0, stcModInfo.SizeOfImage);
        memcpy(pStubBuf, pLoadStubBuf, stcModInfo.SizeOfImage);
    
        //申请新空间存储新PE
        int NewPeSize = objPe.GetAddSectionSize(pFileBuf, (char*)pLoadStubBuf, stcModInfo.SizeOfImage);
        char * pNewPeBuf = new char[NewPeSize];
        memset(pNewPeBuf, 0, NewPeSize);
        memcpy(pNewPeBuf, pFileBuf, dwFileSize);
    
        //修改重定位表
        objPe.FixReloc(pStubBuf, pNewPeBuf);
    
        // 添加一个区段
        objPe.AddSection(pNewPeBuf, pStubBuf, stcModInfo.SizeOfImage);
    
        //设置入口点
        //自己定义的壳的开始位置的原始偏移
        DWORD Offset = PackInfoAdd->dwStartPoint - (DWORD)pLoadStubBuf;
        //相对于新PE的起始位置的偏移
        unsigned int NewOep = Offset + pPeHead.pOptionHeader->SizeOfImage;
        objPe.SetOep(pNewPeBuf, NewOep);
    
        //保存成文件
        SavePackFile(szPath, pNewPeBuf, NewPeSize);
    
        //释放内存
        delete[]pFileBuf;
        delete[]pStubBuf;
        delete[]pNewPeBuf;
    
        return true;
    }

    下面我们就重点说一下修复重定位,通过重定位表找到能存储着需要重定位地址的地址,然后我们把这个地址存储的数据给改了就行了;其实修改重定位信息,简而言之就是把需要重定位的地址改成基于新基址的虚拟地址,这样程序在运行时才能根据真正的加载基址进行重定位;像我们这种情况,需要算出目标地址相对于壳的起始位置的偏移,加上宿主PE的默认加载基址,再加上这个壳加到PE之后的作为新区段的相对虚拟地址,也就是基于新PE的虚拟地址了。
    并且由于相对虚拟地址是从0开始,所以头文件里的sizeofimage就是这个新区段的RVA。
    比如说一个在内存中展开后大小(sizeofimage)为5000的宿主文件,相对虚拟地址为5000的地方就是新区段的起始位置(vitualaddress)。
    如图:
    这里写图片描述

    还有几点应该注意,壳的部分我们要用系统进行重定位,在循环中要修改壳需要重定位的页的起始位置相对虚拟地址(重定位表的每一个PIMAGE_BASE_RELOCATION结构体变量描述的都是某个区段一个页的重定位信息),最后还要将重定位表的指针指向壳的重定位表,并且将重定位表的大小改成壳的重定位表的大小。
    代码实现如下:

    bool CPe::FixReloc(char* StubBuf, char*PeBuf)
    {
        //获取被加壳PE文件的重定位表指针
        PIMAGE_DOS_HEADER pPeDos = (PIMAGE_DOS_HEADER)PeBuf;
        PIMAGE_NT_HEADERS pPeNt = (PIMAGE_NT_HEADERS)(pPeDos->e_lfanew + PeBuf);
        PIMAGE_DATA_DIRECTORY pPeRelocDir = &(pPeNt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC]);
    
    
        //获取壳文件的重定位表指针
        PIMAGE_DOS_HEADER pStuDos = (PIMAGE_DOS_HEADER)StubBuf;
        PIMAGE_NT_HEADERS pStuNt = (PIMAGE_NT_HEADERS)(pStuDos->e_lfanew + StubBuf);
        PIMAGE_DATA_DIRECTORY pStuRelocDir = pStuNt->OptionalHeader.DataDirectory;
        pStuRelocDir = &(pStuRelocDir[IMAGE_DIRECTORY_ENTRY_BASERELOC]);
    
        //获取重定位目录
        PIMAGE_BASE_RELOCATION pStuReloc = (PIMAGE_BASE_RELOCATION)((DWORD)StubBuf + pStuRelocDir->VirtualAddress);
    
        //定义一个存储TypeOffset的结构体
        typedef struct {
            WORD Offset : 12;
            WORD Type : 4;
        }TypeOffset, *PTypeOffset;
    
        //修复重定位信息
        PTypeOffset pTypeOffset = (PTypeOffset)(pStuReloc + 1);
    
        DWORD dwCount = (pStuReloc->SizeOfBlock - 8) / 2;
    
        while (pStuReloc->VirtualAddress)
        {
            for (DWORD i = 0; i < dwCount; i++)
            {
                if (*(PDWORD)(&pTypeOffset[i]) == NULL)
                {
                    break;
                }
    
                //存储重定位地址的相对虚拟地址
                DWORD dwRVA = pStuReloc->VirtualAddress + pTypeOffset[i].Offset; //RVA
    
                //重定位的地址
                DWORD pRelocAddr = *(PDWORD)((DWORD)StubBuf + dwRVA);            
    
                //改掉(PDWORD)((DWORD)StubBuf + dwRVA)存储的值,也就是已经重定位的将来需要重定位的地址
                *(PDWORD)((DWORD)StubBuf + dwRVA) = pRelocAddr - pStuNt->OptionalHeader.ImageBase
                    + pPeNt->OptionalHeader.ImageBase + pPeNt->OptionalHeader.SizeOfImage;
            }
    
            //修改壳重定表中需要重定位的页的起始位置的相对虚拟地址
            pStuReloc->VirtualAddress += pPeNt->OptionalHeader.SizeOfImage;
    
            pStuReloc = (PIMAGE_BASE_RELOCATION)((DWORD)pStuReloc + pStuReloc->SizeOfBlock);
        }
    
        //修改PE文件的重定位表指针
        pPeRelocDir->Size = pStuRelocDir->Size;
        pPeRelocDir->VirtualAddress = pStuRelocDir->VirtualAddress + pPeNt->OptionalHeader.SizeOfImage;
    
        return true;
    }

    接下来讲一下添加区段,这个主要要注意更改PE头文件的信息,文件才能正常运行,不用对齐,我是把整个展开的dll拷贝过来的,按0x1000进行对齐展开的代码,按0x200对齐肯定没问题。要注意将新区段的属性得是可读可写可执行(我踩的一个坑),至于为什么后面再说;
    下面是实现代码:

    void CPe::AddSection(char* pBuf, char*pNewSection, int nSize)
    {
        PEHEADERINFO HeaderInfo = { 0 };
        DWORD NumOfSection = 0;
        if (IsPeFile(pBuf) == false)
        {
            return;
        }
    
        //获得PE的头文件信息
        GetPeHeaderinfo(pBuf,&HeaderInfo);
        //修改区段数量
        NumOfSection = HeaderInfo.pFileHeader->NumberOfSections;
        HeaderInfo.pFileHeader->NumberOfSections += 1;
        //新增区段信息
        PIMAGE_SECTION_HEADER pLastHeader = HeaderInfo.pSectionHeader + NumOfSection - 1;
        PIMAGE_SECTION_HEADER pNewSecHeader = HeaderInfo.pSectionHeader + NumOfSection;
        memcpy(pNewSecHeader->Name, "aStub", 6);
        pNewSecHeader->Misc.VirtualSize = nSize;
        pNewSecHeader->VirtualAddress = HeaderInfo.pOptionHeader->SizeOfImage;
        int a = sizeof(*pBuf);
        pNewSecHeader->PointerToRawData = pLastHeader->PointerToRawData + pLastHeader->SizeOfRawData;
        pNewSecHeader->SizeOfRawData = nSize;
        pNewSecHeader->Characteristics = 0xE0000020;
        //修改镜像大小
        HeaderInfo.pOptionHeader->SizeOfImage += nSize;
        //把区段添加到PE文件中
        memcpy(pBuf + pNewSecHeader->PointerToRawData, pNewSection, nSize);
    }

    大家应该已经注意到我获取头文件信息 很多地方都是直接用的一个函数GetPeHeaderinfo,我是把获取头文件信息的操作封装成了函数;信息保存在一个自定义结构体类型的变量里;

    typedef struct PEHEADERINFO
    {
        PIMAGE_FILE_HEADER pFileHeader;
        PIMAGE_OPTIONAL_HEADER pOptionHeader;
        PIMAGE_SECTION_HEADER pSectionHeader;
    }PEHEADERINFO, *PPEHEADERINFO;

    下面就说一下壳的实现:
    既然前面对宿主PE的代码段进行加密,自然要在壳的代码里进行解密;在执行之前我们还要人工对原PE文件进行一次重定位;要让程序执行原PE文件;自然要跳转到原始的入口点,前面已经将原始入口点的相对虚拟地址保存到了壳里面。只要根据加载基址算出这个入口点的地址,到这个地址去执行就可以了。那么问题来了,我们的壳利用利用入口点直接开始执行了我们的代码,既没加载模块,也没加载资源什么的,无论是人工的进行重定位,还是获得当前的加载基址,都需要函数。所所以我们要人工的获取以下这些函数的地址。
    首先,要先将可能要用到的函数定义好:

    //Stub部分用到的函数的类型定义
    typedef DWORD(WINAPI *fnGetProcAddress)(_In_ HMODULE hModule, _In_ LPCSTR lpProcName);
    typedef HMODULE(WINAPI *fnLoadLibraryA)(_In_ LPCSTR lpLibFileName);
    typedef HMODULE(WINAPI *fnGetModuleHandleA)(_In_opt_ LPCSTR lpModuleName);
    typedef BOOL(WINAPI *fnVirtualProtect)(_In_ LPVOID lpAddress, _In_ SIZE_T dwSize, _In_ DWORD flNewProtect, _Out_ PDWORD lpflOldProtect);
    typedef LPVOID(WINAPI *fnVirtualAlloc)(_In_opt_ LPVOID lpAddress, _In_ SIZE_T dwSize, _In_ DWORD flAllocationType, _In_ DWORD flProtect);
    typedef void(WINAPI *fnExitProcess)(_In_ UINT uExitCode);
    typedef int(WINAPI *fnMessageBox)(HWND hWnd, LPSTR lpText, LPSTR lpCaption, UINT uType);

    定义函数指针,保存函数地址

    //需要获取的函数
    fnGetProcAddress     pfnGetProcAddress = NULL;
    fnLoadLibraryA       pfnLoadLibraryA = NULL;
    fnVirtualProtect     pfnVirtualProtect = NULL;
    fnVirtualAlloc       pfnVirtualAlloc = NULL;
    fnGetModuleHandleA   pfnGetModuleHandleA = NULL;
    fnMessageBox         pfnMessageBox = NULL;
    fnExitProcess        pfnExitProcess = NULL;

    好了该说一下,我上面提到的那个坑了,我开始没有把壳的这个区段保存成可读可写可执行的属性,导致获得的下面这些变量的值都无法保存;后来意识到这个问题,改了属性后果然正常。

    下面是获取Kernel32.dll的代码

    DWORD GetKernel32Addr()
    {
        DWORD dwKernel32Addr = 0;
        _asm
        {
            push eax
                mov eax, dword ptr fs : [0x30]  //eax=PEB的地址
                mov eax, [eax + 0x0C]           //eax=PEB_LDR_DATA的指针
                mov eax, [eax + 0x1C]           //eax=模块初始化链表的指针,InInitializationOrderModuleList
                mov eax, [eax]                  //eax=列表中的第二个条目
                mov eax, [eax]                  //eax=列表中的第二个条目
                mov eax, [eax + 0x08]           //eax=获取到的Kernel32.dll基址(win7下获取的是KernelBase.dll
                mov dwKernel32Addr, eax                           
                pop eax
        }
        return dwKernel32Addr;
    }

    然后用名称遍历导出表得到函数GetProcAddress的地址;
    然后我们就可以利用GetProcAddress获得所需函数的地址:

    void Init()
    {
        HMODULE hKernel32 = (HMODULE)GetKernel32Addr();
        pfnGetProcAddress = (fnGetProcAddress)MyGetProcessAddress();
        pfnLoadLibraryA = (fnLoadLibraryA)pfnGetProcAddress(hKernel32, "LoadLibraryA");
        pfnVirtualProtect = (fnVirtualProtect)pfnGetProcAddress(hKernel32, "VirtualProtect");
        pfnVirtualAlloc = (fnVirtualAlloc)pfnGetProcAddress(hKernel32, "VirtualAlloc");
        pfnGetModuleHandleA = (fnGetModuleHandleA)pfnGetProcAddress(hKernel32, "GetModuleHandleA");
        pfnExitProcess = (fnExitProcess)pfnGetProcAddress(hKernel32, "ExitProcess");
    
        //获取messagebox
        HMODULE hUser32 = pfnLoadLibraryA("user32.dll");
        pfnMessageBox = (fnMessageBox)pfnGetProcAddress(hUser32, "MessageBoxA");
    
        //加载基址
        LoadBase = (DWORD)pfnGetModuleHandleA(NULL);
    }

    下面就要利用得到的函数,对原宿主PE进行人工的重定位了,就是把需要重定位的虚拟地址改成真正的地址;用保存的地址-默认加载基址(加壳的过程中已保存)+实际的加载基址;在重定位的过程中要修改保护属性。

    bool SelfReloc()
    {
    
        //获取重定位目录
        PIMAGE_BASE_RELOCATION pStuReloc = (PIMAGE_BASE_RELOCATION)(LoadBase + g_PackInfo.stcPeRelocDir.VirtualAddress);
    
        //定义一个存储TypeOffset的结构体
        typedef struct {
            WORD Offset : 12;
            WORD Type : 4;
        }TypeOffset, *PTypeOffset;
    
        DWORD dwOldProtect = 0;               
    
        //修复重定位信息
        while (pStuReloc->VirtualAddress)
        {
            //修改保护属性
            //按道理来修改属性大小设置为0x1000就可以了,调试能力有限,暂时不知道为什么设置成0x2000才可以
            pfnVirtualProtect((LPVOID)(LoadBase + pStuReloc->VirtualAddress), 0X2000, PAGE_EXECUTE_READWRITE, &dwOldProtect);
            PTypeOffset pTypeOffset = (PTypeOffset)(pStuReloc + 1);
    
            DWORD dwCount = (pStuReloc->SizeOfBlock - 8) / 2;
    
            for (DWORD i = 0; i < dwCount; i++)
            {
                if (*(PDWORD)(&pTypeOffset[i]) == NULL)
                {
                    break;
                }
    
                DWORD dwRVA = pStuReloc->VirtualAddress + pTypeOffset[i].Offset;        
    
                DWORD pRelocAddr = *(PDWORD)(LoadBase + dwRVA);                         
                *(PDWORD)(LoadBase + dwRVA) = pRelocAddr - g_PackInfo.dwImageBase
                    + LoadBase;
            }
    
            //恢复保护属性
            pfnVirtualProtect((LPVOID)(LoadBase + pStuReloc->VirtualAddress), 0X2000, dwOldProtect, &dwOldProtect);
    
            //获取描述下一个页重定位信息的结构体变量
            pStuReloc = (PIMAGE_BASE_RELOCATION)((DWORD)pStuReloc + pStuReloc->SizeOfBlock);
        }
    
        return true;
    }

    加壳的时候已经把原PE文件OEP相对虚拟地址保存下来,加上加载基址就是原PE入口点现在的地址,然后从那个地址执行就可以了:

    void _declspec(naked) start()
    {
        Init();
        DeXorCode();
        SelfReloc();
        _asm
        {
            push eax;
            mov eax, LoadBase;
            add eax, g_PackInfo.dwOriStartPoint;
            mov dword ptr[esp], eax;
            ret;
        }
    }
    展开全文
  • 过360免杀加壳软件

    2020-05-09 21:55:41
    免杀加壳软件 代码混淆过360 亲测免杀 除了代码混淆还有乱序等可以选择 还有虚拟执行,还可以判断程序运行环境
  • 软件加壳

    2015-11-17 20:49:00
    2019独角兽企业重金招聘Python...加壳神器——WinLicense界面功能汉化 那些年我们一起脱过的衣裳-脱壳 http://drops.wooyun.org/ 转载于:https://my.oschina.net/ITELITE/blog/531733

    .NET Reactor is a powerful .NET code protection & licensing system which assists developers in protecting their .NET software. Developers are able to protect their software in a safe and simple way now. This way developers can focus more on development than on worrying how to protect their intellectual property.

    加壳神器——WinLicense界面功能汉化

    那些年我们一起脱过的衣裳-脱壳
    http://drops.wooyun.org/

    转载于:https://my.oschina.net/ITELITE/blog/531733

    展开全文
  • 加壳软件加壳软件加壳软件加壳软件加壳软件加壳软件加壳软件加壳软件加壳软件加壳软件加壳软件加壳软件
  • 给winfrom做的项目 进行加壳 项目加壳,保证了软件的代码的安全,有漏洞无风险
  • 集整理一些常用软件加壳脱壳工具制作成工具箱,希望大家喜欢。 下载地址 本文转自haiyang45751CTO博客,原文链接:http://blog.51cto.com/haiyang457/1928835 ,如需转载请自行联系原作者 ...
  • 这是我在网上整理的一个软件加壳脱壳教程,非本人所做,供学习者参考。 首先大家应该先明白“壳”的概念。在自然界中,大家对壳这东西应该都不会陌生了,植物用它来保护种子,动物用它来保护身体等等。同样,在一些...
  • 使用VMProtect给软件加壳

    万次阅读 2016-09-19 16:12:48
    查阅资料后,得知软件加壳后破解难度会大增,经过研究确定使用VMProtect给自己的软件加壳,并将过程记录下来。VMProtect安装首先下载VMProtect V2.13.8,直接安装,将VMProtect.key放在安装目录下即可正常使用该软件...
  • upx394w 软件加壳

    2017-11-29 16:03:51
    UPX (the Ultimate Packer for eXecutables)是一款先进的可执行程序文件压缩器,压缩过的可执行文件体积缩小50%-70% ,这样减少了磁盘占用空间、网络上传下载的时间和其它分布以及存储费用。 通过 UPX 压缩过的程序...
  • 计算机网络安全相关
  • 易语言软件加壳程序

    2012-10-31 17:44:58
    用易语言写的软件添加外壳程序,单文件绿色免费版 1.自定义添加网站/动画/图片/FLASH等 2.可添加统计代码 3.自定义限制运行时间,限制操作等 4.自定义公告内容

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 8,056
精华内容 3,222
关键字:

软件加壳

友情链接: TCPServer.rar