吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 6579|回复: 21
收起左侧

[Packers] [VC] 64位壳子编写

  [复制链接]
舒默哦 发表于 2020-6-27 01:12
本帖最后由 舒默哦 于 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
clipboard1.png
clipboard.png

64位壳子.7z

135.29 KB, 下载次数: 132, 下载积分: 吾爱币 -1 CB

免费评分

参与人数 3吾爱币 +3 热心值 +2 收起 理由
cpj1203 + 1 + 1 谢谢@Thanks!
oepoep + 1 我很赞同!
Rodriguezs + 1 + 1 谢谢@Thanks!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

风之暇想 发表于 2020-6-30 20:05
舒默哦 发表于 2020-6-30 10:49
我写的兼容32位和64位的哦,版主大人

兼容性有待提高
cpj1203 发表于 2020-6-28 11:12
netspirit 发表于 2020-6-27 01:36
王兰花秀丽 发表于 2020-6-27 01:40
虽然没怎么看懂,但是不妨碍我夸你厉害
拉玛西亚 发表于 2020-6-27 04:02
书我存了,谢谢分享了
Rodriguezs 发表于 2020-6-27 07:34
厉害了我的哥
yiting8 发表于 2020-6-27 11:37
大佬,书可以共享一下吗?
gh0st_ 发表于 2020-6-27 15:47
感谢分享
htpidk 发表于 2020-6-27 15:52
可以的,我也在准备写壳
 楼主| 舒默哦 发表于 2020-6-28 14:16
yiting8 发表于 2020-6-27 11:37
大佬,书可以共享一下吗?

链接:https://pan.baidu.com/s/1BG8Foq5ComqNbkFbAJ2DCQ
提取码:khqa
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-24 11:27

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表