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

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

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

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

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

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

 

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

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

 

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

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


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

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

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

 

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

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

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

 

在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);
}

  


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

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

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)”,如下图:

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

 

接下来实现界面工程和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”即可,如下图:

 

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

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

 

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

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

 


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项目。如下图:

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

 

修改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,运行成功如下图,证明我们项目的基础框架调通,我们接下来就可以去编写壳了。

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

 


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

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

 

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

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

 

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

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

 


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

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

 

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

上一篇:[UVM]在對收到的Transaction做$cast(tr, temp.clone())操作后,member全變為0的問題


下一篇:web pack备忘