📄 encrypt.cpp
字号:
// Encrypt.cpp: implementation of the Encrypt class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "Shell1.h"
#include "Encrypt.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//=====================================
//用于Loader的全局变量(传递给asm代码)
PBYTE asm_pImageBase;
DWORD asm_ImageBase;
DWORD asm_OldEntryPoint;
DWORD asm_NewEntryPoint;
DWORD asm_RVAOfEndSectionTable;
PBYTE asm_pDataSectionTable;
PBYTE asm_pDataSection;
DWORD asm_SizeOfDataSection;
bool IsInit;
//=====================================
//全局函数
//=====================================
DWORD GetFunctionRVA(void* FuncName)
{
DWORD dwRVA=DWORD(FuncName);
return(dwRVA);
}
DWORD GetFunctionSize(void* FuncName)
{
DWORD dwRVA=GetFunctionRVA(FuncName);
PBYTE pFuncBody=(PBYTE)dwRVA;
BYTE _temp;
bool notEnd=TRUE;
BYTE l=0;
do
{
CopyMemory(&_temp,pFuncBody+l,1);
if(_temp==0xC3)//0xC3为retn指令
{
notEnd=FALSE;
}
l++;
}while(notEnd);
return(l);
}
void Loader()
{
//放入被加壳文件的节表尾部,作为程序运行时候的解密部分
// PBYTE RAVOfDest=RVAOfEndSectionTable+pImageBase;
_asm
{
add esp,0c0h
mov esp,ebp
pop ebp
xor esi,esi
xor edi,edi
//xor eax,eax
//xor edx,eax
xor ebx,ebx
xor ecx,ecx
mov edi,2
////////////////
_loader:
nop//10个nop占位用的
nop
nop
nop
nop
nop
nop
nop
nop
nop
_ldr_next:
test edi,edi
jz _loader_end
xor eax,eax
xor edx,edx
mov eax,[esi+12]//eax->节区的Rva验证正确
add eax,ecx//ecx为imagebase
//eax为节的rva
mov edx,[esi+8]//edx为节的,virtualsize
and edx,000000ffh
cmp byte ptr[esi+7],0
je _ldr_not_encrypted
_ldr_decrypt: //异或解密
xor byte ptr[eax],dl
//xor byte ptr[eax],dl
inc eax //下一个字节
dec edx
jne _ldr_decrypt
dec edi
_ldr_not_encrypted:
add esi,28h //esi->下一个节区
jmp _ldr_next //开始下一个节区的解密
_loader_end:
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
}
}
//=====================================
//全局函数
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
Encrypt::Encrypt()
{
}
Encrypt::~Encrypt()
{
}
void Encrypt::InitGloablForAsm()//设置asm用的全局变量
{
asm_pImageBase=pImageBase;
asm_ImageBase=pImageOptionalHeader->ImageBase;
asm_OldEntryPoint=OldEntryPoint;
asm_RVAOfEndSectionTable=RVAOfEndSectionTable;
IsEncrypted=FALSE;
}
void Encrypt::Encrypt_sections(PIMAGE_SECTION_HEADER pSection)
{
CString Section=pSection->Name;
if( Section==".text"|| Section==".data")//判断是否是.data节或.text节
{
IsEncrypted=TRUE;
if(CheckIfEncrypted(pSection))//判断是否已经加密
{
AfxMessageBox("已加密!");
}
else
{
AfxMessageBox((LPCSTR)pSection->Name,NULL);
BYTE Name[8]=".uu";
PBYTE ptmp;
ptmp=pSection->Name;
for(int i=0;i<8;i++)
{
*(ptmp)=Name[i];
ptmp++;
}
BYTE OpCode=0x01;
CopyMemory(--ptmp,&OpCode,1);
//*(--ptmp)=0x01;//设置加密标志位
pSection->Characteristics=0x0C00000E0;//修改该节的属性(可读写)
Xor_Section(pSection);//对该节加密
//将节表的名字修改为.uu
}
}
else
{
if(Section!=".uu")
{
BYTE Name[8]=".uu";
PBYTE ptmp;
ptmp=pSection->Name;
for(int i=0;i<8;i++)
{
*(ptmp)=Name[i];
ptmp++;
}
BYTE OpCode=0x01;
CopyMemory(--ptmp,&OpCode,0);
pSection->Characteristics=0x0C00000E0;//修改该节的属性(可读写)
}
}
}
bool Encrypt::CheckIfEncrypted(PIMAGE_SECTION_HEADER pSection)
{
CString Section=pSection->Name;
if(Section=="uu.")
{
return TRUE;
}
else
{
return FALSE;//未加密
}
}
void Encrypt::Xor_Section(PIMAGE_SECTION_HEADER pSection)
{
DWORD OffSetOfSection=pSection->PointerToRawData;//
PBYTE Pointer=(PBYTE)(OffSetOfSection+pImageBase);//一个section的大小及指向它的指针
PBYTE ptmp=Pointer;
BYTE ByteSizeOfSection=pSection->Misc.VirtualSize;
if(!IsInit)
{
//初始化公共变量=======================
asm_SizeOfDataSection=ByteSizeOfSection;
asm_pDataSectionTable=(PBYTE)pSection-(PBYTE)pImageBase+(PBYTE)pImageOptionalHeader->ImageBase;
asm_pDataSection=(PBYTE)pSection->VirtualAddress+pImageOptionalHeader->ImageBase;
IsInit=TRUE;
//初始化公共变量=======================
}
BYTE tmpByteSizeOfSection=ByteSizeOfSection;
for(;ptmp<Pointer+ByteSizeOfSection;ptmp++)
{
BYTE tmpbyte=*(ptmp)^tmpByteSizeOfSection;//与该节的大小xor
CopyMemory(ptmp,&tmpbyte,1);
tmpByteSizeOfSection--;
}
}
void Encrypt::CalculateOldEntryPoint()
//计算入口地址,便于被加壳文件的载入
{
asm_OldEntryPoint=AddressOfEntryPoint+pImageOptionalHeader->ImageBase;
}
void Encrypt::CalculateRVAEndOfSectionTable()////计算节表尾部的RVA
{
DWORD SizeOfAllSectionTable=NumberOfSection*SectionTablelen;//
RVAOfEndSectionTable=(DWORD)pSection+SizeOfAllSectionTable;
}
void Encrypt::InjectLoader(DWORD InjectAddr)
{
//注入Loader
PBYTE Pointer=(PBYTE)InjectAddr;
PBYTE ptmp=Pointer;
DWORD FuncRVA=GetFunctionSize(Loader);//Loader的大小
DWORD dwRVA=GetFunctionRVA(Loader);//Loader的RVA
PBYTE pFuncBody=(PBYTE)dwRVA;
/////////////////////////////
BYTE OpNop=0x90;
///////////////////////////////
BYTE OpMovEax=0xB8;
BYTE OpMovEsi=0xBE;
BYTE OpMovEcx=0xB9;
////////////////////////////
BYTE MovEcxImageBase[4];
CopyMemory(MovEcxImageBase,&asm_ImageBase,4);
BYTE MovEsipSection[4];
CopyMemory(MovEsipSection,&asm_pDataSectionTable,4);
/////////////////////////////
BYTE OEP_Jmp[6];
CopyMemory(OEP_Jmp,&asm_OldEntryPoint,4);
OEP_Jmp[4]=0xFF;
OEP_Jmp[5]=0xE0;//jmp eax
/////////////////////////////////
bool IsInjected1=FALSE;
bool IsInjected2=TRUE;
for(;ptmp<Pointer+FuncRVA;)
{
if(*pFuncBody==OpNop && !IsInjected1)
{
/////////////////////////////
CopyMemory(ptmp,&OpMovEsi,1);
ptmp++;
pFuncBody++;
CopyMemory(ptmp,MovEsipSection,4);
ptmp=ptmp+4;
pFuncBody=pFuncBody+4;
////////////////////////
CopyMemory(ptmp,&OpMovEcx,1);
ptmp++;
pFuncBody++;
CopyMemory(ptmp,MovEcxImageBase,4);
ptmp=ptmp+4;
pFuncBody=pFuncBody+4;
////////////////////////
IsInjected1=TRUE;
IsInjected2=FALSE;
}
if(*pFuncBody==OpNop && !IsInjected2)
{
CopyMemory(ptmp,&OpMovEax,1);
ptmp++;
pFuncBody++;
CopyMemory(ptmp,OEP_Jmp,6);
ptmp=ptmp+6;
pFuncBody=pFuncBody+6;
IsInjected2=TRUE;
}
else
{
CopyMemory(ptmp,pFuncBody,1);
pFuncBody++;
ptmp++;
}
}
//修改程序的oep
DWORD NewOEP=InjectAddr-(DWORD)pImageBase;
pImageOptionalHeader->AddressOfEntryPoint=NewOEP;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -