首页
社区
课程
招聘
[原创][开源]用C++实现的壳(基础版)
发表于: 2015-12-29 19:41 80785

[原创][开源]用C++实现的壳(基础版)

2015-12-29 19:41
80785
//PE.h
public:
  HANDLE          m_hFile;      //PE文件句柄
  LPBYTE          m_pFileBuf;      //PE文件缓冲区
  DWORD          m_dwFileSize;    //文件大小
  DWORD          m_dwImageSize;    //镜像大小
  PIMAGE_DOS_HEADER    m_pDosHeader;    //Dos头
  PIMAGE_NT_HEADERS    m_pNtHeader;    //NT头
  PIMAGE_SECTION_HEADER  m_pSecHeader;    //第一个SECTION结构体指针
  DWORD          m_dwImageBase;    //镜像基址
  DWORD          m_dwCodeBase;    //代码基址
  DWORD          m_dwCodeSize;    //代码大小
  DWORD          m_dwPEOEP;      //OEP地址
  DWORD          m_dwShellOEP;    //新OEP地址
  DWORD          m_dwSizeOfHeader;  //文件头大小
  DWORD          m_dwSectionNum;    //区段数量
  DWORD          m_dwFileAlign;    //文件对齐
  DWORD          m_dwMemAlign;    //内存对齐
  DWORD          m_IATSectionBase;  //IAT所在段基址
  DWORD          m_IATSectionSize;  //IAT所在段大小
  IMAGE_DATA_DIRECTORY  m_PERelocDir;    //重定位表信息
  IMAGE_DATA_DIRECTORY  m_PEImportDir;    //导入表信息
void CPE::GetPEInfo()
{
  m_pDosHeader  = (PIMAGE_DOS_HEADER)m_pFileBuf;
  m_pNtHeader    = (PIMAGE_NT_HEADERS)(m_pFileBuf + m_pDosHeader->e_lfanew);
  m_dwFileAlign  = m_pNtHeader->OptionalHeader.FileAlignment;
  m_dwMemAlign  = m_pNtHeader->OptionalHeader.SectionAlignment;
  m_dwImageBase  = m_pNtHeader->OptionalHeader.ImageBase;
  m_dwPEOEP    = m_pNtHeader->OptionalHeader.AddressOfEntryPoint;
  m_dwCodeBase  = m_pNtHeader->OptionalHeader.BaseOfCode;
  m_dwCodeSize  = m_pNtHeader->OptionalHeader.SizeOfCode;
  m_dwSizeOfHeader= m_pNtHeader->OptionalHeader.SizeOfHeaders;
  m_dwSectionNum  = m_pNtHeader->FileHeader.NumberOfSections;
  m_pSecHeader  = IMAGE_FIRST_SECTION(m_pNtHeader);
  m_pNtHeader->OptionalHeader.SizeOfImage = m_dwImageSize;
  //保存重定位目录信息
  m_PERelocDir = 
    IMAGE_DATA_DIRECTORY(m_pNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC]);
  //保存IAT信息目录信息
  m_PEImportDir =
    IMAGE_DATA_DIRECTORY(m_pNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]);
}
DWORD CPE::XorCode(BYTE byXOR)
{
  PBYTE pCodeBase = (PBYTE)((DWORD)m_pFileBuf + m_dwCodeBase);
  for (DWORD i = 0; i < m_dwCodeSize; i++)
  {
    pCodeBase[i] ^= byXOR;
  }
  return m_dwCodeSize;
}
//导出ShellData结构体
extern"C"  typedef struct _SHELL_DATA
{
  DWORD dwStartFun;              //启动函数
  DWORD dwPEOEP;                //程序入口点
  DWORD dwXorKey;                //解密KEY
  DWORD dwCodeBase;              //代码段起始地址
  DWORD dwXorSize;              //代码段加密大小
  DWORD dwPEImageBase;            //PE文件映像基址
  IMAGE_DATA_DIRECTORY  stcPERelocDir;    //重定位表信息
  IMAGE_DATA_DIRECTORY  stcPEImportDir;    //导入表信息
  DWORD          dwIATSectionBase;  //IAT所在段基址
  DWORD          dwIATSectionSize;  //IAT所在段大小
  BOOL          bIsShowMesBox;    //是否显示MessageBox
}SHELL_DATA, *PSHELL_DATA;
  HMODULE hShell = LoadLibrary(L"Shell.dll");
  PSHELL_DATA pstcShellData = (PSHELL_DATA)GetProcAddress(hShell, "g_stcShellData");
  pstcShellData->dwXorKey = 0x15;
  pstcShellData->dwCodeBase = objPE.m_dwCodeBase;
  pstcShellData->dwXorSize = dwXorSize;
  pstcShellData->dwPEOEP = objPE.m_dwPEOEP;
  pstcShellData->dwPEImageBase = objPE.m_dwImageBase;
  pstcShellData->stcPERelocDir = objPE.m_PERelocDir;
  pstcShellData->stcPEImportDir = objPE.m_PEImportDir;
  pstcShellData->dwIATSectionBase = objPE.m_IATSectionBase;
  pstcShellData->dwIATSectionSize = objPE.m_IATSectionSize;
  pstcShellData->bIsShowMesBox = bIsShowMesBox;
BOOL CPE::SetShellReloc(LPBYTE pShellBuf, DWORD hShell)
{
  typedef struct _TYPEOFFSET
  {
    WORD offset : 12;      //偏移值
    WORD Type  : 4;      //重定位属性(方式)
  }TYPEOFFSET, *PTYPEOFFSET;
  //1.获取被加壳PE文件的重定位目录表指针信息
  PIMAGE_DATA_DIRECTORY pPERelocDir =
    &(m_pNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC]);
  
  //2.获取Shell的重定位表指针信息
  PIMAGE_DOS_HEADER    pShellDosHeader = (PIMAGE_DOS_HEADER)pShellBuf;
  PIMAGE_NT_HEADERS    pShellNtHeader = (PIMAGE_NT_HEADERS)(pShellBuf + pShellDosHeader->e_lfanew);
  PIMAGE_DATA_DIRECTORY  pShellRelocDir =
    &(pShellNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC]);
  PIMAGE_BASE_RELOCATION  pShellReloc = 
    (PIMAGE_BASE_RELOCATION)((DWORD)pShellBuf + pShellRelocDir->VirtualAddress);
  
  //3.还原修复重定位信息
  //由于Shell.dll是通过LoadLibrary加载的,所以系统会对其进行一次重定位
  //我们需要把Shell.dll的重定位信息恢复到系统没加载前的样子,然后在写入被加壳文件的末尾
  PTYPEOFFSET pTypeOffset = (PTYPEOFFSET)(pShellReloc + 1);
  DWORD dwNumber = (pShellReloc->SizeOfBlock - 8) / 2;
  for (DWORD i = 0; i < dwNumber; i++)
  {
    if (*(PWORD)(&pTypeOffset[i]) == NULL)
      break;
    //RVA
    DWORD dwRVA =pTypeOffset[i].offset + pShellReloc->VirtualAddress;
    //FAR地址(LordPE中这样标注)
    //***新的重定位地址=重定位后的地址-加载时的镜像基址+新的镜像基址+代码基址(PE文件镜像大小)
    DWORD AddrOfNeedReloc =  *(PDWORD)((DWORD)pShellBuf + dwRVA);
    *(PDWORD)((DWORD)pShellBuf + dwRVA) 
      = AddrOfNeedReloc - pShellNtHeader->OptionalHeader.ImageBase + m_dwImageBase + m_dwImageSize;
  }
  //3.1修改Shell重定位表中.text的RVA
  pShellReloc->VirtualAddress += m_dwImageSize;
  //4.修改PE重定位目录指针,指向Shell的重定位表信息
  pPERelocDir->Size = pShellRelocDir->Size;
  pPERelocDir->VirtualAddress = pShellRelocDir->VirtualAddress + m_dwImageSize;
  return TRUE;
}
void CPE::MergeBuf(LPBYTE pFileBuf, DWORD pFileBufSize,
  LPBYTE pShellBuf, DWORD pShellBufSize, 
  LPBYTE& pFinalBuf, DWORD& pFinalBufSize)
{
  //获取最后一个区段的信息
  PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pFileBuf;
  PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)(pFileBuf + pDosHeader->e_lfanew);
  PIMAGE_SECTION_HEADER pSectionHeader = IMAGE_FIRST_SECTION(pNtHeader);
  PIMAGE_SECTION_HEADER pLastSection =
    &pSectionHeader[pNtHeader->FileHeader.NumberOfSections - 1];
  //1.修改区段数量
  pNtHeader->FileHeader.NumberOfSections += 1;
  //2.编辑区段表头结构体信息
  PIMAGE_SECTION_HEADER AddSectionHeader =
    &pSectionHeader[pNtHeader->FileHeader.NumberOfSections - 1];
  memcpy_s(AddSectionHeader->Name, 8, ".cyxvc", 7);
  //VOffset(1000对齐)
  DWORD dwTemp = 0;
  dwTemp = (pLastSection->Misc.VirtualSize / m_dwMemAlign) * m_dwMemAlign;
  if (pLastSection->Misc.VirtualSize % m_dwMemAlign)
  {
    dwTemp += 0x1000;
  }
  AddSectionHeader->VirtualAddress = pLastSection->VirtualAddress + dwTemp;
  //Vsize(实际添加的大小)
  AddSectionHeader->Misc.VirtualSize = pShellBufSize;
  //ROffset(旧文件的末尾)
  AddSectionHeader->PointerToRawData = pFileBufSize;
  //RSize(200对齐)
  dwTemp = (pShellBufSize / m_dwFileAlign) * m_dwFileAlign;
  if (pShellBufSize % m_dwFileAlign)
  {
    dwTemp += m_dwFileAlign;
  }
  AddSectionHeader->SizeOfRawData = dwTemp;
  //区段属性标志(可读可写可执行)
  AddSectionHeader->Characteristics = 0XE0000040;
  //3.修改PE头文件大小属性,增加文件大小
  dwTemp = (pShellBufSize / m_dwMemAlign) * m_dwMemAlign;
  if (pShellBufSize % m_dwMemAlign)
  {
    dwTemp += m_dwMemAlign;
  }
  pNtHeader->OptionalHeader.SizeOfImage += dwTemp;
  //4.申请合并所需要的空间
  pFinalBuf = new BYTE[pFileBufSize + dwTemp];
  pFinalBufSize = pFileBufSize + dwTemp;
  memset(pFinalBuf, 0, pFileBufSize + dwTemp);
  memcpy_s(pFinalBuf, pFileBufSize, pFileBuf, pFileBufSize);
  memcpy_s(pFinalBuf + pFileBufSize, dwTemp, pShellBuf, dwTemp);
}

[注意]APP应用上架合规检测服务,协助应用顺利上架!

上传的附件:
收藏
免费 16
支持
分享
最新回复 (67)
雪    币: 1176
活跃值: (1269)
能力值: ( LV12,RANK:380 )
在线值:
发帖
回帖
粉丝
2
感谢分享 前排来赞~
2015-12-29 20:01
0
雪    币: 81
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
赞 111111
2015-12-29 20:08
0
雪    币: 878
活跃值: (496)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
4
扔到github上
2015-12-29 20:42
0
雪    币: 76
活跃值: (1050)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
5
还真没去那里看过,多谢提醒,以后常去逛逛
2015-12-29 20:47
0
雪    币: 191
活跃值: (848)
能力值: ( LV12,RANK:530 )
在线值:
发帖
回帖
粉丝
6
感谢分享
2015-12-29 21:04
0
雪    币: 6
活跃值: (1509)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
唉  我只能说 15PB  广告打的真多  一开始真有期待 最后你发现 都是基础 的基础   发些内部视频出来啊
2015-12-29 22:03
0
雪    币: 199
活跃值: (53)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
感谢分享!
2015-12-29 22:45
0
雪    币: 5483
活跃值: (3874)
能力值: ( LV13,RANK:283 )
在线值:
发帖
回帖
粉丝
9
可以结合bambam,就不用loadlibrary了
2015-12-29 23:38
0
雪    币: 76
活跃值: (1050)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
10
请教一下,什么是bambam 啊
2015-12-29 23:52
0
雪    币: 107
活跃值: (419)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
感谢楼主分享.........................
2015-12-30 11:27
0
雪    币: 204
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
学到的知识分享,非常感谢。我为15PB匠人精神点赞
2015-12-30 12:04
0
雪    币: 294
活跃值: (119)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
13
NICE~
2015-12-30 12:54
0
雪    币: 76
活跃值: (1050)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
14
小疯疯
2015-12-30 13:35
0
雪    币: 14
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
感谢分享,学习下
2015-12-30 14:42
0
雪    币: 148
活跃值: (140)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
nice work
2015-12-30 15:04
0
雪    币: 2359
活跃值: (288)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
感谢分享
2015-12-30 15:38
0
雪    币: 5483
活跃值: (3874)
能力值: ( LV13,RANK:283 )
在线值:
发帖
回帖
粉丝
18
一个开源壳
2015-12-30 15:51
0
雪    币: 35
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
感谢分享
2015-12-30 19:25
0
雪    币: 49
活跃值: (118)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
20
马上毕业了,加油吧,小伙子
2015-12-31 21:08
0
雪    币: 260
活跃值: (29)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
21
测试了下在win7 x64可以正常运行,但是在xp win32系统运行不成功
2016-1-1 01:30
0
雪    币: 76
活跃值: (1050)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
22
对,我编程的环境就是Win7 64的。我觉得运行不了是因为Shell.dll没有静态编译,如果加壳系统缺少VS2013的环境的话就无法正常加载Shell.dll

如果在xp 或者 Win32 下用源代码重新编译一下应该可以...

暂时没考虑太多兼容性问题啊
2016-1-1 09:40
1
雪    币: 165
活跃值: (1521)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
23
条理清晰,学得很扎实,继续努力吧
2016-1-3 15:38
0
雪    币: 201
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
24
这个不错  很详细  很细致
2016-1-4 09:33
0
雪    币: 43
活跃值: (40)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
25
感谢分享
2016-1-18 17:41
0
游客
登录 | 注册 方可回帖
返回
//