本帖最后由 舒默哦 于 2020-7-4 01:19 编辑
更新:
x64壳子的编写源码放到github上了,地址https://github.com/shumo-e/64-github。
源码兼容x32编译,支持x32加壳。实现了IAT加密,添加了一些反调试,实现了反虚拟机的功能。
0x01
感谢《加密与解密》第四版的作者。
我编写的64位壳子就是借助这本书,还不完善,只实现了对代码段的简单加密,等项目完成后,我会把源码和流程发布到github上,到时第一时间通知吾爱的兄弟们。
0x02
加密与解密上的64位壳子的源码有些问题,我会把源码传上来,下面我贴哪些地方需要更改的:
[C++] 纯文本查看 复制代码 void __declspec(naked) Start()
{
_asm {
pushfq
call Start1()
popfq
jmp rax
ret
}
}
ULONG_PTR Start1()
{
//获取kernel32基址
ULONGLONG dwBase = GetKernel32Addr();
fnGetProcAddress pfnGetProcAddress = (fnGetProcAddress)MyGetProcessAddress();
//获取API地址
fnLoadLibraryA pfnLoadLibraryA = (fnLoadLibraryA)pfnGetProcAddress((HMODULE)dwBase, "LoadLibraryW");
fnGetModuleHandleA pfnGetModuleHandle = (fnGetModuleHandleA)pfnGetProcAddress((HMODULE)dwBase, "GetModuleHandleW");
fnVirtualProtect pfnVirtualProtect = (fnVirtualProtect)pfnGetProcAddress((HMODULE)dwBase, "VirtualProtect");
HMODULE hUser32 = (HMODULE)pfnLoadLibraryA(L"user32.dll");
HMODULE hKernel32 = (HMODULE)pfnGetModuleHandle(L"kernel32.dll");
fnExitProcess pfnExitProcess = (fnExitProcess)pfnGetProcAddress(hKernel32, "ExitProcess");
fnMessageBox pfnMessageBox = (fnMessageBox)pfnGetProcAddress(hUser32, "MessageBoxW");
////弹出信息框
int nRet = pfnMessageBox(NULL, L"欢迎使用免费64位加壳程序,是否运行主程序?", L"Hello PEDIY", MB_YESNO);
if (nRet == IDYES)
{
//修改代码段属性
ULONGLONG dwCodeBase = g_stcParam.dwImageBase + (DWORD)g_stcParam.lpStartVA;
DWORD dwOldProtect = 0;
pfnVirtualProtect((LPVOID)dwCodeBase, g_stcParam.dwCodeSize, PAGE_EXECUTE_READWRITE, &dwOldProtect);
XorCode();//解密代码
pfnVirtualProtect((LPVOID)dwCodeBase, g_stcParam.dwCodeSize, dwOldProtect, &dwOldProtect);
g_oep = (FUN)(g_stcParam.dwImageBase + g_stcParam.dwOEP);
//跳回原始OEP
return (ULONG_PTR)g_oep;
}
//退出程序
pfnExitProcess(0);
}
上面这段代码在Stub的工程目录里。
我用的是intel编译器,可以支持x64内联汇编,没有intel编译器也没关系,,可以直接写shellcode,Start()函数字节不多,shellcode就那几十个字节。
0x03
项目中要多次申请内存,为了防止内存泄漏,可以使用智能指针,但我感觉用起来别扭,所有写了一个自动释放内存的类:
[C++] 纯文本查看 复制代码 #pragma once
#include <vector>
using namespace std;
class AllocMemory
{
vector<char*>p;
public:
virtual ~AllocMemory()
{
for (int i = 0; i < p.size(); i++)
{
free(p[i]);
}
p.clear();
}
public:
template<typename T>
T auto_malloc( ULONG_PTR MAXSIZE)
{
T tmp = (T)malloc(MAXSIZE);
memset((char*)tmp, 0, MAXSIZE);
p.push_back((char*)tmp);
return tmp;
}
};
修复重定位表代码没用书里作者提供的,下面贴出代码:
[C++] 纯文本查看 复制代码 /*////////////////////////////////////////////////////////////////
*※※* FullName: PerformBaseRelocation
*※※* 功能 : 修复重定位表
*※※* Returns: 无
*※※* Parameter: char* buff,PE文件首地址
*※※* Parameter: POINTER_TYPE Value,buff的基址与贴在内存中的地址的差值
*※※* Parameter:
*※※* Parameter:
*※※* Parameter:
*※※* Author: LCH
*/////////////////////////////////////////////////////////////////;
void PE::PerformBaseRelocation(ULONG_PTR buff, ULONG_PTR Value)
{
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)buff;
PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)(buff + pDosHeader->e_lfanew);
//获取目录表头指针
PIMAGE_DATA_DIRECTORY pDataDirectory = pNtHeader->OptionalHeader.DataDirectory;
if (pDataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size > 0)
{
PIMAGE_BASE_RELOCATION relocation = (PIMAGE_BASE_RELOCATION)((ULONG_PTR buff + pDataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress);
while (relocation->VirtualAddress > 0)
{
BYTE* dest = (PBYTE)((ULONG_PTR )buff + relocation->VirtualAddress);
WORD* relInfo = (PWORD)((ULONG_PTR )relocation + sizeof(IMAGE_BASE_RELOCATION));
for (DWORD i = 0; i < ((relocation->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / 2); ++i, ++relInfo)
{
DWORD *patchAddrHL;
#ifdef _WIN64
ULONGLONG *patchAddr64;//change comlete 64 bit address
#endif
ULONG_PTR type, offset;
//the upper 4 bits define the type of relocation
type = *relInfo >> 12;
//the lower 12 bits define the offset
offset = (*relInfo) & 0xFFF;
switch (type)
{
case IMAGE_REL_BASED_ABSOLUTE:
//skip relocation
break;
#ifdef _WIN64
case IMAGE_REL_BASED_DIR64://change comlete 64 bit address
patchAddr64 = (ULONGLONG*)(dest + offset);
*patchAddr64 += Value;
break;
#endif
case IMAGE_REL_BASED_HIGHLOW://change comlete 32 bit address
patchAddrHL = (DWORD*)(dest + offset);
*patchAddrHL += Value;
break;
default:
break;
}
}
//advance to next relocation block
relocation = PIMAGE_BASE_RELOCATION((char*)relocation + relocation->SizeOfBlock);
}
}
}
0x04
结语:
x64加壳框架外观,程序我会上传。
加密与解密第四版配套源码链接:
链接:https://pan.baidu.com/s/1hjAxUCsF6wiQl0TlKvCwvA 提取码:rfq6 |