I Pack You:实现基本的软件壳框架
记录一下自己开发简易软件壳的过程,参考的开源软件和书籍贴在文末。
这只是一个简易的加壳工具,实现了加壳的基本框架,后面会增加更多的功能填充这个框架。
实现思路
这个壳全部使用c/c++进行编写,没有使用汇编。因为在x64下,visual c++不支持内联汇编的语法了。如果要使用汇编,需要将汇编代码作为一个模块供c/c++使用。
软件壳分为两个部分:加壳程序和stub。其中stub以dll的形式存在,使用链接器指令将一些节区融合在一起(参考《加密与解密》)。加壳程序对目标PE文件进行加密和变换后,会提取Stub.dll的.text节区,写入目标文件的特定节区中。通过在dll中导出一些变量,实现加壳程序和stub之间的通信。
另外对于Stub.dll,我们需要修改vs默认的编译选项使得.text的代码移植到目标PE文件后可以正常运行,这点后面会说。
异常处理
为了优化程序结构,我自定义了一些异常类供程序使用:
#pragma once
#include <Windows.h>
#include <string>
#include <stdexcept>
class MyException : public std::runtime_error
public:
class not_pe_format : public MyException
public:
class winapi_failed : public MyException
public:
explicit winapi_failed(const std::string &msg)
winapi_failed类的构造函数中会自动将自定义的错误消息和win32错误码合并,在throw的时候就可以直接知道错误码了。
本来还实现了一个通用的win32错误码格式化工具类的,感觉没什么用,砍掉了。也贴出来给大家参考一下:
#include "ErrorPrinter.h"
// ANSI版本
void ErrorPrinter::PrintErrorA(const std::string& context, DWORD errorCode)
// 获取Windows系统错误描述
LPSTR lpMsgBuf = nullptr;
DWORD bufLen = FormatMessageA(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
nullptr,
errorCode,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPSTR)&lpMsgBuf,
nullptr);
std::cerr << "错误: " << context << std::endl;
std::cerr << "错误代码: " << errorCode
<< " (0x" << std::hex << errorCode << std::dec << ")" << std::endl;
if (bufLen > 0 && lpMsgBuf != nullptr)
// 移除结尾的换行符
std::string message(lpMsgBuf, bufLen);
while (!message.empty() &&
(message.back() == '\n' || message.back() == '\r' || message.back() == ' '))
message.pop_back();
std::cerr << "错误描述: " << message << std::endl;
LocalFree(lpMsgBuf);
else
std::cerr << "无法获取错误描述" << std::endl;
// Unicode/Wide版本
void ErrorPrinter::PrintErrorW(const std::wstring& context, DWORD errorCode)
// 获取Windows系统错误描述
LPWSTR lpMsgBuf = nullptr;
DWORD bufLen = FormatMessageW(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
nullptr,
errorCode,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPWSTR)&lpMsgBuf,
nullptr);
std::wcerr << L"错误: " << context << std::endl;
std::wcerr << L"错误代码: " << errorCode
<< L" (0x" << std::hex << errorCode << std::dec << L")" << std::endl;
if (bufLen > 0 && lpMsgBuf != nullptr)
// 移除结尾的换行符
std::wstring message(lpMsgBuf, bufLen);
while (!message.empty() &&
(message.back() == L'\n' || message.back() == L'\r' || message.back() == L' '))
message.pop_back();
std::wcerr << L"错误描述: " << message << std::endl;
LocalFree(lpMsgBuf);
else
std::wcerr << L"无法获取错误描述" << std::endl;
PEFile模块
主要用于获取目标PE文件的各种信息以及对其进行修改。
#pragma once
#include <Windows.h>
#include <string>
// 直接分配SizeOfImage大小的内存,模仿加载器对PE文件进行读取
class PEFile
public:
...(已截断)
---
来源: 看雪论坛
原文链接: https://bbs.kanxue.com/thread-291331.htm
[原创]I Pack You:实现基本的软件壳框架
188 浏览
0 回复
暂无回复,快来抢沙发吧!