• 壳的编写(1)-- 简介与搭建框架


    最近学习了壳,自己手动编写了简单的壳,功能比较简单,现在简单整理成笔记,供大家参考。个人能力有限,如有谬误,请不吝赐教,万分感谢。

    参考资料:《黑客免杀攻防》,看雪论坛等

    简介
           “壳”是一种现实比较常见的东西,比如:花生壳、瓜子壳等等。这些壳主要是用来保护其自身的果实的,要想吃到这些果实,我们就需要将其剥掉。在我们的软件行业也存在这样类似的东西,这种东西我们也称之为“壳”,我们自身的软件就类似于花生仁,而“壳”用来保护我们自身的软件,避免被其他人窥探。

    壳根据作用,一般分为两种:压缩壳、加密壳。无论哪种他们的原理大致是相同的。我们给自身软件加壳后就会产生新的软件,新的软件是由壳和原软件组成,在执行的时候,先执行壳,由壳对原程序进行解密并还原到内存中去,接着执行原来的程序。如下图:

     

    当我们将带壳的程序运行后,壳就会加载自己的API函数,然后对已知的加密区进行解密,对压缩进行解压,并按照PE结构将其释放到正确的内存位置上,并进行重定位,然后跳转到原程序的入口点(OEP),运行原程序。如图:

     

    搭建环境
    开发环境
    Win7x64 旗舰版
    vs2013
    010Edit6.03
    OD1.1(吾爱破解版)
    PEid0.94
    LordPE

    说明:
     我们想程序的界面与逻辑进行分开,这样可以使两者互不干扰。


    创建三个项目
    a、创建一个名称为PackBase的mfc项目,用于界面操作
    b、创建一个名称为Pack_Base的dll项目,编写加壳逻辑
    c、创建一个名称为Stub的dll项目,编写壳的信息

    a、创建一个名称为Pack Base的mfc项目
    界面如下:

    先给EditControl的"Read Only"属性设置为"True",并为其定义两个变量,一个是CString类型的m_pathStr,一个是CEditor类型的m_pathEdit。

             然后实现拖拽效果,将该对话框中的Accept Files属性设置为True,然后按Ctrl + Shift +X,添加 WM_DROPFILES消息。

     

    在OnDropFiles中添加如下代码:

    void CPackBaseDlg::OnDropFiles(HDROP hDropInfo)
    {
    // TODO: 在此添加消息处理程序代码和/或调用默认值
    
    CDialogEx::OnDropFiles(hDropInfo);
    CDialogEx::OnDropFiles(hDropInfo);
    //拖动单个文件的时候
    WCHAR wcStr[MAX_PATH];
    DragQueryFile(hDropInfo, 0, wcStr, MAX_PATH);//获得拖曳的文件的文件名 
    m_pathEdit.SetWindowText(wcStr); //将路基添加到文本编辑框中 
    
    DragFinish(hDropInfo); //拖放结束后,释放内存 
    UpdateData(TRUE); //将界面上的信息保存到变量中
    
    MessageBox(m_pathStr, m_pathStr, 0); //测试是否成功
    }
    

      


    再次给“浏览”按钮事件处理添加浏览文件并获取文件路径代码,如下:

    void CPackBaseDlg::OnBnClickedButton1()
    {
    UpdateData(TRUE);
    //设置要浏览文件的类型
    static TCHAR BASED_CODE szFilter[] = _T("可执行文件 (*.exe)|*.exe|")
    _T("DLL文件 (*.dll)|*.dll|")
    _T("All Files (*.*)|*.*||");
    
    CFileDialog fileDlg(TRUE, _T("exe"), _T(""),
    OFN_FILEMUSTEXIST | OFN_HIDEREADONLY, szFilter);
    
    if (fileDlg.DoModal() == IDOK)
    {	//将获取的路径信息赋给变量	m_pathStr = fileDlg.GetPathName();
    }
    //更新控件显示信息
    UpdateData(FALSE);
    }
    

      

    在“加壳”按钮的添加如下代码用于测试:

    void CPackBaseDlg::OnBnClickedButton2()
    {
    MessageBox(m_pathStr, m_pathStr, 0);
    }
    

      


    运行程序测试成功,如图:

    b、创建一个名称为Pack_Dll的加壳dll程序 

    在该工程中的Pack_Dll.h文件中定义一个导出方法Pack用于加壳操作。由于c++存在“名称粉碎机制”,所以要使用 extend "C" 不让改方法“名称粉碎”。如下:

    extern "C" PACK_DLL_API BOOL Pack(CString strPath);
    

      


    我们需要导入CString的头文件,我们为了后面的操作方便,我们将#include <afxwin.h>加入到stdafx.h文件中,由于冲突所以需要去掉文件中"#include <windows.h>"。

    在Pack_Dll.cpp文件中对Pack方法进行实现,我们只需要简单的测试下即可。

    BOOL Pack(CString strPath)
    {
    MessageBox(0, L"Pack", 0, 0);
    return TRUE;
    }
    

      


    为了项目能够正常编译,我们需要去掉用dllmain.cpp文件中的DllMain方法,同时将该项目的“运行库”设置为“多线程调试(/MTD)”,如下图:

     

    接下来实现界面工程和dll的关联,我们在MFC工程的加壳方法中调用刚刚写的Pack方法,修改代码如下:

    #include "../Pack_Dll/Pack_Dll.h"
    #pragma comment(lib,"../Debug/Pack_Dll.lib")
    
    void CPackBaseDlg::OnBnClickedButton2()
    {
    //MessageBox(m_pathStr, m_pathStr, 0);
    Pack(m_pathStr);
    }
    

      

    通过项目依赖项让两个项目关联,在Pack Base项目上点击右键的“生成依赖项”中“项目依赖项”,在“依赖项”的“依赖于”中选择“Pack_Dll”即可,如下图:

     

    编译运行Pack Base项目,效果如下:

     


    c、创建名称为Stub的dll的项目

    在Stub.h的文件中,编写两个按C语言的进行编译的函数fnGetStub和fnSetStub,代码如下:

    extern "C"
    {
    //获取和设置Stub
    STUB_API int fnGetStub(void);
    STUB_API void fnSetStub(int n);
    }
    在Stub.cpp文件中对其进行实现:
    // 这是导出函数示例。
    STUB_API int fnGetStub(void)
    {
    return nStub;
    }
    
    STUB_API void fnSetStub(int n)
    {
    nStub = n;
    }
    

      


    将项目Pack_dll项目和Stub关联起来,在Pack_dll项目上击右键的“生成依赖项”中“项目依赖项”,在“依赖项”的“依赖于”中选择“Stub”即可,此时项目就会形成了:Pack项目依赖于Pack_dll项目,而Pack_dll项目依赖于Stub项目。如下图:

     

    修改Pack_dll项目中的Pack方法,在Pack_dll项目中调用Stub项目中导出的方法,代码如下:

    typedef int(*FUNGetStub)(void);
    typedef void(*FUNSetStub)(int n);
    
    BOOL Pack(CString strPath)
    {
    HMODULE hMod = LoadLibrary(L"Stub.dll");
    FUNSetStub pfnSetStub = (FUNSetStub)GetProcAddress(hMod, "fnSetStub");
    
    pfnSetStub(1);
    
    FUNGetStub pfnGetStub = (FUNGetStub)GetProcAddress(hMod, "fnGetStub");
    
    if (pfnGetStub())
    {
    MessageBox(0,L"加壳成功",0,0);
    }
    return TRUE;
    }
    

      


    此时项目就会形成了:Pack项目依赖于Pack_dll项目,而Pack_dll项目依赖于Stub项目。

             运行项目Pack,运行成功如下图,证明我们项目的基础框架调通,我们接下来就可以去编写壳了。

     


    d、修改编译配置
    我们将生成的Debug版本的stub.dll加载到LordPE中,发现区段表中的第一个区段为.textbss,如果是这样的话就会影响我们的操作

    为了达到第一个区段为.text,我们需要将想Stub设置为Release版本。(选项配置管理器)

    然后,我们在使用LoadPE,查看Release版本Stub.dll的区段信息。


    为了后面调试方便,我们要将Stub项目的输出目录设置为Debug,这样就会让Stub.dll为Release版本,但是输出到Debug目录中。

     

    参考项目代码: 01Pack Base  http://download.csdn.net/detail/obuyiseng/9386931
    ————————————————
    版权声明:本文为CSDN博主「布衣僧」的原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/oBuYiSeng/article/details/50447540

  • 相关阅读:
    Http服务器实现文件上传与下载(二)
    Http服务器实现文件上传与下载(三)
    NHibernate VS IbatisNet
    5. Element-UI的基本使用
    4. Vue脚手架
    3. Vue单文件组件
    webpack中的加载器
    webpack
    02.模块化相关规范
    01.前端工程化的学习目标
  • 原文地址:https://www.cnblogs.com/luckywolfzyy/p/11384856.html
Copyright © 2020-2023  润新知