bool PEProtecter::LoadFile(wchar_t* _file)
{
auto hFile = CreateFile(_file, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE)return false;
DWORD dRead;
DWORD dSize = GetFileSize(hFile, &dRead);//获取大小
if (dSize < 1)return false;
_data = new char[dSize];
if (ReadFile(hFile, _data, dSize, &dRead, NULL))
{
PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)_data;//读DOS头
PIMAGE_NT_HEADERS32 ntHeader32 = (PIMAGE_NT_HEADERS32)(_data + dosHeader->e_lfanew);//读NT头
SecCount = ntHeader32->FileHeader.NumberOfSections;//节数量
SecArrys = (PIMAGE_SECTION_HEADER)(sizeof(IMAGE_NT_HEADERS32) + (unsigned)ntHeader32);//节的地址
Base = ntHeader32->OptionalHeader.ImageBase;//基址
return true;
CloseHandle(hFile);
}
return false;
}
unsigned PEProtecter::VAtofoa(unsigned va, unsigned _base)
{
DWORD uBase;
(_base == 0) ? uBase = Base : uBase = _base;
DWORD rva = va - uBase;
for (int i = 0; i < SecCount; i++)
{
if ((rva > SecArrys[i].VirtualAddress) && (rva < SecArrys[i].VirtualAddress + SecArrys[i].SizeOfRawData))
{
DWORD offset = rva - SecArrys[i].VirtualAddress;
return offset + SecArrys[i].PointerToRawData;
}
}
return 0;
}
?集成库写反汇编信息
CString PEProtecter::DAsm(unsigned va, unsigned len, unsigned _base)
{
CStringA _output;
CStringA _tmp;
char* buffer = ReadDataByVA(va, _base);
DISASM disasm;
memset(&disasm, 0, sizeof(DISASM));//初始化
disasm.EIP = (UIntPtr)buffer;
disasm.VirtualAddr = (UIntPtr)va;//虚拟地址
disasm.Archi = IA32;//AMD64
disasm.Options = MasmSyntax;//汇编的形式 NASM MASM
int _len;
while (!disasm.Error)
{
disasm.SecurityBlock = (UIntPtr)va + len - disasm.EIP;
if(disasm.SecurityBlock<=0)break;//没有任何代码可以解读
_len = Disasm(&disasm); //反汇编
switch (disasm.Error)
{
case OUT_OF_BLOCK:break;
case UNKNOWN_OPCODE:
_tmp.Format("0x%.08X => ????????\r\n", (unsigned)disasm.VirtualAddr);
_output += _tmp;
disasm.EIP += 1;
disasm.VirtualAddr += 1;
break;
default:
_tmp.Format("0x%.08X => [%s]\r\n", (unsigned)disasm.VirtualAddr, &disasm.CompleteInstr);
_output += _tmp;
disasm.EIP += _len;
disasm.VirtualAddr += _len;
break;
}
}
CString result;
result = _output;
return result;
}
效果:?
?接下来就是实现对源程序修改,生成自己的加壳程序
//生成加壳程序 ?? ?/* ?? ?[1] 对原客户端的修改 ?? ?*/ ?? ?/* ?? ?* START LEN ?写入CC? ?开始到结束写入CC ?? ?60 6A B8 FC EF 02 01 FF 20 修改客户端 从START开始
按之前的设计 其他都是不会变得,只有6A00 这个00参数会变? 按我们的设计,最多有256个保护节点 ?? ?*/ ?? ?/*
可以自己设计一个结构体: ?? ?[int count]
?? ?[start] ?? ?[len] short ?? ?[r_count] short ?//处理重定位 ?? ?short [r_count] offset //远近跳重定位问题 ?? ?data[len]
?? ?[start] ?? ?[len] short ?? ?[r_count] short ?//处理重定位 ?? ?short [r_count] offset //远近跳重定位问题 ?? ?data[len]
?? ?[start] ?? ?[len] short ?? ?[r_count] short ?//处理重定位 ?? ?short [r_count] offset //远近跳重定位问题 ?? ?data[len]
为了速度更快可以? ?处理内存对齐问题
思路:
- 告诉PEProtect 一共几个点
- 传入PushData ?start ?base ? len 这几个数据
- Create
定义:
class PEProtecter
{
public:
unsigned Base;
unsigned SecCount;//节数量
PIMAGE_SECTION_HEADER SecArrys;
private:
unsigned _pushcount{};
unsigned filelen{};//数据长度
char* _data{}; //存放数据
char* _dataEntry{};//存放加密数据
char* _dataHead{}; //头部数据
unsigned CodeCount{};//代码的数量
public:
bool LoadFile(wchar_t* _file);
unsigned VAtofoa(unsigned va, unsigned _base=0);
char* ReadDataByVA(unsigned va, unsigned _base =0);
~PEProtecter();
CString DAsm(unsigned va, unsigned len, unsigned _base);
public:
//生成功能
void Init(unsigned count);
void PushCode(unsigned va, unsigned len, unsigned _base);
void Save(wchar_t* file);
};
方案2:
?? ?[file] //文件数据
?? ?[int count]
?? ?[start] ?? ?[len] short ?? ?[r_count] short ?//处理重定位
?? ?[start] ?? ?[len] short ?? ?[r_count] short ?//处理重定位
?? ?[start] ?? ?[len] short ?? ?[r_count] short ?//处理重定位 ?? ?//?? ?记录数据 ?? ?
?? ?//code 代码数据 ?? ?short [r_count] offset //远近跳重定位问题 ?? ?data[len]
?? ? ?? ?short [r_count] offset //远近跳重定位问题 ?? ?data[len]
?? ? ?? ?short [r_count] offset //远近跳重定位问题 ?? ?data[len] ?? ? ?? ?[filelen]
typedef struct CODEContext
{
unsigned start;
unsigned short r_couent; //重定位信息
unsigned short len; //代码长度
}*PCODEContext;
|