📄 cryptstuff.cpp
字号:
//_GetModuleHandle DD 0
dwRO = dwRO - 4;
dwRO_GetModuleHandle=dwRO;
CopyMemory(Base+dwRO,&_GetModuleHandle,4);
//szGetModuleHandle DB "GetModuleHandleA",0
l=DWORD(strlen(szGetModuleHandle))+1;
dwRO = dwRO - l;
dwRO_szGetModuleHandle=dwRO;
CopyMemory(Base+dwRO,szGetModuleHandle,l);
//dwKernelBase DD 0
dwRO = dwRO - 4;
dwRO_dwKernelBase=dwRO;
CopyMemory(Base+dwRO,&dwKernelBase ,4);
//szKernel32 DB "Kernel32.dll",0
l=DWORD(strlen(szKernel32))+1;
dwRO = dwRO - l;
dwRO_szKernel32=dwRO;
CopyMemory(Base+dwRO,szKernel32,l);
//_GetProcAddress DD 0
dwRO = dwRO - 4;
dwRO_GetProcAddress = dwRO;
CopyMemory(Base+dwRO,&_GetProcAddress,4);
//_LoadLibrary DD 0
dwRO = dwRO - 4;
dwRO_LoadLibrary = dwRO;
CopyMemory(Base+dwRO,&_LoadLibrary,4);
//SEH sSEH <0>
dwRO = dwRO - sizeof(sSEH);
dwRO_SEH = dwRO;
CopyMemory(Base+dwRO,&SEH,sizeof(sSEH));
//IIDInfo db (SIZEOF sItInfo * MAX_IID_NUM) dup (0)
l=sizeof(IIDInfo);
dwRO = dwRO - sizeof(IIDInfo);
dwRO_IIDInfo = dwRO;
CopyMemory(Base+dwRO,&IIDInfo,sizeof(IIDInfo));
//bNT DD 0
dwRO = dwRO - 4;
dwRO_bNT = dwRO;
CopyMemory(Base+dwRO,&bNT,4);
//dwLoaderCRC DD 0
dwRO = dwRO - 4;
dwRO_dwLoaderCRC = dwRO;
CopyMemory(Base+dwRO,&dwLoaderCRC,4);
//dwCalcedCRC DD 0
dwRO = dwRO - 4;
dwRO_dwCalcedCRC = dwRO;
CopyMemory(Base+dwRO,&dwCalcedCRC,4);
//PROTECTION_FLAGS DD 0
dwRO = dwRO - 4;
dwRO_PROTECTION_FLAGS = dwRO;
CopyMemory(Base+dwRO,&PROTECTION_FLAGS,4);
//dwOrgEntryPoint DD 0
dwRO = dwRO - 4;
dwRO_dwOrgEntryPoint = dwRO;
CopyMemory(Base+dwRO,&dwOrgEntryPoint,4);
//dwImageBase DD 0
dwRO = dwRO - 4;
dwRO_dwImageBase = dwRO;
CopyMemory(Base+dwRO,&dwImageBase,4);
}
//----------------------------------------------------------------
//return Raw Data address of Loader Crypter Codes
void GetLoaderCryptRO(char* pFuncBody)
{
DWORD l=0;
DWORD tmp;
unsigned char _temp;
#ifdef _DEBUG
do
{
CopyMemory(&tmp,pFuncBody+l,4);
l++;
}while(tmp!=0xCCCCCCCC);
l=l+3;
#endif
do
{
CopyMemory(&tmp,pFuncBody+l,4);
l++;
}while(tmp!=0xCCCCCCCC);
tmp=0xC201EB90;
CopyMemory(pFuncBody+l-1,&tmp,4);
l=l+3;
do
{
CopyMemory(&_temp,pFuncBody+l,1);
l++;
}while((_temp!=0xAC));
dwRO_VAR_DECRYPTION=l;
l=l+3;
do
{
CopyMemory(&tmp,pFuncBody+l,4);
l++;
}while(tmp!=0xCCCCCCCC);
tmp=0xE901EB90;
CopyMemory(pFuncBody+l-1,&tmp,4);
l=l+3;
do
{
CopyMemory(&_temp,pFuncBody+l,1);
l++;
}while((_temp!=0xAC));
dwRO_SEC_DECRYPT=l;
}
//----------------------------------------------------------------
//return Raw Data address of OEP JUMP Codes
void GetOepJumpCodeRO(char* pFuncBody)
{
DWORD l=DEPACKER_CODE_SIZE-2;
DWORD tmp;
do
{
l--;
}while(UCHAR(pFuncBody[l])==0xCC);
l=l-4;
do
{
CopyMemory(&tmp,pFuncBody+l,4);
l--;
}while(tmp!=0xCCCCCCCC);
tmp=0xC201EB90;
CopyMemory(pFuncBody+l+1,&tmp,4);
dwRO_OEP_JUMP_CODE_END=l;
l=l-4;
do
{
l--;
CopyMemory(&tmp,pFuncBody+l,4);
}while(tmp!=0xCCCCCCCC);
tmp=0xE901EB90;
CopyMemory(pFuncBody+l,&tmp,4);
l=l+4;
dwRO_OEP_JUMP_CODE_START=l;
OEP_JUMP_CODE_SIZE=dwRO_OEP_JUMP_CODE_END-dwRO_OEP_JUMP_CODE_START;
}
//----------------------------------------------------------------
// This functin encryptes the OEP JUMP Codes
void OepJumpEncrypt(char* Base)
{
DWORD i;
UCHAR _temp=0;
UCHAR _tempC=UCHAR(OEP_JUMP_CODE_SIZE);
for(i=dwRO_OEP_JUMP_CODE_START;i<=dwRO_OEP_JUMP_CODE_END;i++)
{
CopyMemory(&_temp,Base+i,1);
_asm
{
MOV AL,_temp
ROR AL, 2
ADD AL, _tempC
XOR AL, OEP_JUMP_ENCRYPT_NUM
MOV _temp,AL
DEC _tempC
}
CopyMemory(Base+i,&_temp,1);
}
}
//----------------------------------------------------------------
// returns aligned value
DWORD PEAlign(DWORD dwTarNum,DWORD dwAlignTo)
{
DWORD dwtemp;
dwtemp=dwTarNum/dwAlignTo;
if((dwTarNum%dwAlignTo)!=0)
{
dwtemp++;
}
dwtemp=dwtemp*dwAlignTo;
return(dwtemp);
}
//----------------------------------------------------------------
// return Check Sum of buffer
//CYCLIC REDUNDANCY CHECKS (CRC)
DWORD GetChecksum(char* Base,DWORD FileSize)
{
DWORD checksum,dwhold,dwdata;
DWORD64 dwtemp64;
UCHAR _temp;
checksum=dwhold=0;
for(DWORD i=0;i<FileSize;i++)
{
CopyMemory(&_temp,Base+i,1);
dwtemp64=_temp*dwhold;
dwdata=DWORD(dwtemp64);
dwtemp64=dwtemp64>>32;
dwhold=DWORD(dwtemp64);
checksum=checksum+dwdata;
dwhold++;
}
return(checksum);
}
//----------------------------------------------------------------
// This function reads the dll name strings, turn it back.
// and destroys them.
// return values:
// char* - the dll name strings
char* ReadStringFrom(char* Base,DWORD dwRVA)
{
int l=0;
for(int i=0;i<255;i++)
{
if(Base[dwRVA+i]==0x00) break;
l++;
}
char *filename=new TCHAR[l+1];
strncpy(filename,Base+dwRVA,l+1);
return(filename);
}
//----------------------------------------------------------------
// This function encrypts the dll name strings, saves the ImageImportDescriptors to the loader data
// and destroys them.
// return values:
// 1 - success
// 0 - too much IID's !
DWORD EnDeCryptString(char* Base,DWORD dwRO)
{
UCHAR _temp;
for(int i=0;i<255;i++)//DllCryptLoop
{
CopyMemory(&_temp,Base+dwRO+i,1);
__asm ROR _temp,4;
CopyMemory(Base+dwRO+i,&_temp,1);
if(_temp==0x00) break;
}
if(i>223) return(0);
return(1);
}
//----------------------------------------------------------------
// This function encrypts the dll name strings, saves the ImageImportDescriptors to the loader data
// and destroys them.
// return values:
// 1 - success
// 0 - too much IID's !
DWORD ProcessOrgIT(char* pFileImage,DWORD pITBaseRO)
{
DWORD stupid_num;
DWORD dwIIDNum;
char *dllname,*dllfunc;
for(int i=0;i<MAX_IID_NUM;i++)// clear the IIDInfo array
{
IIDInfo[i].DllNameRVA=0;
IIDInfo[i].FirstThunk=0;
IIDInfo[i].OrgFirstThunk=0;
}
stupid_num=GetTickCount();// get a random number
stupid_num=stupid_num ^ 'yoda';// EDX -> stupid number :)
// start
IMAGE_IMPORT_DESCRIPTOR import_descriptor;// -> IID
dwIIDNum=0;
CopyMemory(&import_descriptor,
pFileImage+pITBaseRO+dwIIDNum*sizeof(IMAGE_IMPORT_DESCRIPTOR),
sizeof(IMAGE_IMPORT_DESCRIPTOR));
while(import_descriptor.Name)
{
dwIIDNum++;
if(dwIIDNum == (MAX_IID_NUM))// too much IID's ?
{
return 0;
}
// save IID Infos -> Loader IT data array
IIDInfo[dwIIDNum-1].DllNameRVA=import_descriptor.Name;
IIDInfo[dwIIDNum-1].OrgFirstThunk=import_descriptor.OriginalFirstThunk;
IIDInfo[dwIIDNum-1].FirstThunk=import_descriptor.FirstThunk;
//-> get dll pointer
DWORD dllpoint=RVA2Offset(pFileImage,import_descriptor.Name);
dllname=ReadStringFrom(pFileImage,dllpoint);
EnDeCryptString(pFileImage,dllpoint);//-> crypt string
dllname=ReadStringFrom(pFileImage,dllpoint);
//--- CRYPT API name strings ---
DWORD dllfileRef=import_descriptor.OriginalFirstThunk;
if(!dllfileRef)
{
dllfileRef=import_descriptor.FirstThunk;
}
dllfileRef=RVA2Offset(pFileImage,dllfileRef);
DWORD _dllfileRef=dllfileRef;
DWORD dllfilePoint;
CopyMemory(&dllfilePoint,pFileImage+_dllfileRef,4);
while( dllfilePoint!=0)// ESI -> Thunk pointer
{
if((_dllfileRef&IMAGE_ORDINAL_FLAG32)==0)// is it an Ordinal Import ?
{
dllfilePoint=RVA2Offset(pFileImage,dllfilePoint);
if(dllfilePoint!=0)
{
dllfunc=ReadStringFrom(pFileImage,dllfilePoint+2);
EnDeCryptString(pFileImage,dllfilePoint+2);//-> crypt string; skip the HINT
dllfunc=ReadStringFrom(pFileImage,dllfilePoint+2);
}
}
_dllfileRef=_dllfileRef+4;
CopyMemory(&dllfilePoint,pFileImage+_dllfileRef,4);
}
// destroy Original IID*/
import_descriptor.Name=stupid_num;
import_descriptor.OriginalFirstThunk=stupid_num;
import_descriptor.FirstThunk=stupid_num;
import_descriptor.TimeDateStamp=stupid_num;
import_descriptor.ForwarderChain=stupid_num;
CopyMemory(pFileImage+pITBaseRO+(dwIIDNum-1)*sizeof(IMAGE_IMPORT_DESCRIPTOR),
&import_descriptor,
sizeof(IMAGE_IMPORT_DESCRIPTOR));
CopyMemory(&import_descriptor,
pFileImage+pITBaseRO+dwIIDNum*sizeof(IMAGE_IMPORT_DESCRIPTOR),
sizeof(IMAGE_IMPORT_DESCRIPTOR));//-> point to next IID
}
return 1;
}
//----------------------------------------------------------------
// This function assembles Import Table for new section
void AssembleIT(char* Base,DWORD dwNewSectionRO,DWORD dwNewSectionRVA)
{
char* pAddress4IT=Base+dwNewSectionRO;//-> base of the new IT
// Zero the memory for the new IT
FillMemory(Base+dwNewSectionRO,IT_SIZE,0x00);
// build a new,nice ImportTable :)
IMAGE_IMPORT_DESCRIPTOR import_descriptor;//assume esi:ptr IMAGE_IMPORT_DESCRIPTOR
CopyMemory(&import_descriptor,
pAddress4IT,
sizeof(IMAGE_IMPORT_DESCRIPTOR));
// make ebx point after the terminating IID
DWORD dwRO=dwNewSectionRO+2*sizeof(IMAGE_IMPORT_DESCRIPTOR);
import_descriptor.Name=dwNewSectionRVA+2*sizeof(IMAGE_IMPORT_DESCRIPTOR);// process the IID Name
CopyMemory(Base+dwRO
,szKernel,strlen(szKernel));
dwRO=dwRO+strlen(szKernel)+1;
// process the FirstThunk pointers
import_descriptor.FirstThunk=dwRO-dwNewSectionRO+dwNewSectionRVA;
DWORD dwRO_,dwRO1;
dwRO1=dwRO+10;
dwRO_=dwRO1-dwNewSectionRO+dwNewSectionRVA;
CopyMemory(Base+dwRO,&dwRO_,4);
dwRO1=dwRO1+2;
CopyMemory(Base+dwRO1
,szLoadLibrary,strlen(szLoadLibrary));
dwRO1=dwRO1+strlen(szLoadLibrary);
dwRO=dwRO+4;
dwRO_=dwRO1-dwNewSectionRO+dwNewSectionRVA;
CopyMemory(Base+dwRO,&dwRO_,4);
dwRO1=dwRO1+2;
CopyMemory(Base+dwRO1
,szGetProcAddress,strlen(szGetProcAddress));
CopyMemory(Base+dwNewSectionRO,
&import_descriptor,
sizeof(IMAGE_IMPORT_DESCRIPTOR));
}
//----------------------------------------------------------------
// This function relocates the Thread Local Storage (TLS) Table
// in different place
void ProcessTlsTable(char* Base,DWORD dwCryptSectionRVA)
{
DWORD TlsDirAddr;
// check whether there's a tls table
IMAGE_NT_HEADERS nt_headers;
DWORD dwPE_Offset;
CopyMemory(&dwPE_Offset,Base+0x3c,4);//-> pointer to PE header
CopyMemory(&nt_headers,Base+dwPE_Offset,sizeof(IMAGE_NT_HEADERS));
TlsDirAddr=nt_headers.OptionalHeader.DataDirectory[9].VirtualAddress;
DWORD dwRO;
if(TlsDirAddr!=0)// check if no tls section
{
// get a RAW pointer to the tls table
dwRO=RVA2Offset(Base,TlsDirAddr);//-> pointer to tls tables
if(dwRO!=0)
{
dwRO_TlsBackup =DEPACKER_CODE_SIZE-(9+sizeof(IMAGE_TLS_DIRECTORY32));;
// copy the whole TLS table into the loader data part
CopyMemory(&TlsBackup,Base+dwRO,sizeof(IMAGE_TLS_DIRECTORY32));
// fix the TLS DIRECTORY VA
DWORD dwTLS_D_VA=dwCryptSectionRVA+IT_SIZE+dwRO_TlsBackup;
nt_headers.OptionalHeader.DataDirectory[9].VirtualAddress=dwTLS_D_VA;
CopyMemory(Base+dwPE_Offset,&nt_headers,sizeof(IMAGE_NT_HEADERS));
FillMemory(Base+dwRO,sizeof(IMAGE_TLS_DIRECTORY32),0x00);
}
}
}
//----------------------------------------------------------------
// return values:
// 0 - no room for a new section
// 1 - file already encrypted
// else: returns a pointer to the IMAGE_SECTION_HEADER struct of the new section
PIMAGE_SECTION_HEADER AddSection(char* Base)
{
IMAGE_NT_HEADERS nt_headers;
DWORD dwSecNum,dwPE_Offset;
DWORD SectionOffset,newSectionOffset;
CopyMemory(&dwPE_Offset,Base+0x3c,4);
CopyMemory(&nt_headers,Base+dwPE_Offset,sizeof(IMAGE_NT_HEADERS));// edi -> pointer to PE header
dwSecNum=nt_headers.FileHeader.NumberOfSections;
// contains the size of the whole section header except the size being needed for our new section
SectionOffset=dwPE_Offset+sizeof(IMAGE_NT_HEADERS);
newSectionOffset=SectionOffset+dwSecNum*sizeof(IMAGE_SECTION_HEADER);
// check whether there's room for a new section
if(nt_headers.OptionalHeader.SizeOfHeaders<(newSectionOffset+sizeof(IMAGE_SECTION_HEADER)))
{
return NULL;
}
// create a new section
IMAGE_SECTION_HEADER section;//-> pointer to section headers
// go to the last section
for(DWORD i=0;i<(dwSecNum-1);i++)
{
CopyMemory(§ion,Base+SectionOffset+i*0x28,sizeof(IMAGE_SECTION_HEADER));
section.Characteristics=section.Characteristics | 0x80000000;
CopyMemory(Base+SectionOffset+i*0x28,§ion,sizeof(IMAGE_SECTION_HEADER));
}
// start to build the new section
IMAGE_SECTION_HEADER newsection=section;//-> pointer to the new section
CopyMemory(§ion,Base+SectionOffset+(dwSecNum-1)*0x28,sizeof(IMAGE_SECTION_HEADER));
// VirtualAddress...
newsection.VirtualAddress=PEAlign(section.VirtualAddress
+section.Misc.VirtualSize,0x1000);
// VirtualSize..
newsection.Misc.VirtualSize=0x2000;
// RawSize..
newsection.SizeOfRawData=IT_SIZE+DEPACKER_CODE_SIZE;
// Section name
int l=(int)strlen(DEPACKER_SECTION_NAME);
for(int i=0;i<=7;i++)
{
if(i<l)newsection.Name[i]=DEPACKER_SECTION_NAME[i];
else newsection.Name[i]=0x00;
}
// Characteristics
newsection.Characteristics=0xE00000E0;
// RawOffset
newsection.PointerToRawData=PEAlign(section.PointerToRawData
+section.SizeOfRawData,0x200);
CopyMemory(Base+newSectionOffset,&newsection,sizeof(IMAGE_SECTION_HEADER));
// update the PE header
nt_headers.FileHeader.NumberOfSections++;
CopyMemory(Base+dwPE_Offset,&nt_headers,sizeof(IMAGE_NT_HEADERS));
// newsection -> will be returned
return ((PIMAGE_SECTION_HEADER)&newsection);
}
//----------------------------------------------------------------
// Base = pointer to file memory
// dwMode: 0 - RawCrypt mode
// 1 - VirtualCrypt mode
void CryptPE(char* Base,DWORD dwMode)
{
DWORD SectionName;
DWORD CryptStart;
DWORD CryptSize;
IMAGE_SECTION_HEADER section;
IMAGE_NT_HEADERS nt_headers;
DWORD dwPE_Offset;
DWORD SectionOffset;
CopyMemory(&dwPE_Offset,Base+0x3c,4);
CopyMemory(&nt_headers,Base+dwPE_Offset,sizeof(IMAGE_NT_HEADERS));// edi -> pointer to PE header
SectionOffset=dwPE_Offset+sizeof(IMAGE_NT_HEADERS);
for(int i=0;i<nt_headers.FileHeader.NumberOfSections;i++)
{
CopyMemory(§ion,Base+SectionOffset+i*0x28,sizeof(IMAGE_SECTION_HEADER));
// -> skip some special sections !
CopyMemory(&SectionName,section.Name,4);
if((SectionName!='crsr')&& //rsrc
(SectionName!='rsr.')&& //.rsrc
(SectionName!='oler')&& //reloc
(SectionName!='ler.')&& //.reloc
(SectionName!='Cy')&& //yC
(SectionName!='ade.')&& //.edata
(SectionName!='adr.')&& //.rdata
(SectionName!='adi.')&& //.idata
(SectionName!='slt.')&& //.tls
(section.PointerToRawData!=0)&&
(section.SizeOfRawData!=0))//-> skip also some other sections
{
//-> en-/decrypt it
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -