📄 antivirusmoudle.cpp
字号:
{
postion = 2;//decode之后
}
else if( postion == 2 )//又出现了,出错
return -1;
nAddrReg = da.addrreg1;//保存使用的寄存器
}
if( postion == 3 )
{
if( !_stricmp(da.vm_name,"VJMP_REG32") && da.reg[0] == nAddrReg )//如果是跳到解密代码的语句,则结束
{
postion = 4;//结束
}
}
if( postion == 1 )//在解密code中
{
if( !_stricmp(da.vm_name,"VSUB_REG16_REG16") )
{
method = 0;//减法
decodereg = da.reg[1];
}
else if( !_stricmp(da.vm_name,"VXOR_REG16_REG16") )
{
method = 1;//异或
decodereg = da.reg[1];
}
}
if( postion == 2 )//解密code之后,循环之前
{
if( decodereg != -1 && da.reg[0] == decodereg )//又使用了解码寄存器
{
if( strstr(da.vm_name,"VINC") )
{
UseAdd = TRUE;
AddNum = 1;//加1
}
else if( strstr(da.vm_name,"VADD") )
{
UseAdd = TRUE;
AddNum = da.immconst;//加常数
}
}
if( !_stricmp(da.vm_name,"VJNZ_IMM32") || !_stricmp(da.vm_name,"VJA_IMM32") )
{
postion = 3;//循环之后
}
}
if( nAddrReg != -1 && decodereg != -1 && method != -1 && postion == 4 )//全都已经得到
{
return 0;
}
return ret;
}
//范围数据
DWORD LastFuncAddr;//最后一个FUNC地址
int dwOffset;//解密的偏移地址
DWORD CodeCout;//代码长度
//寻找常数过程
int FindConstInfo_Proc(BYTE* BaseAddr,BYTE* code,DWORD VirtualAddress,DWORD HookAddr,BOOL bLevel)
{
t_disasm da;
int ret = Disasm((char*)code,16,VirtualAddress,&da,DISASM_CODE);
if( !_stricmp(da.vm_name,"VCALL_IMM32" ) )//寻找最后一个CALL
{
LastFuncAddr = (DWORD)code;
}
//定位位置
if( !_stricmp(da.vm_name,"VXCHG_MEM08_REG08") ||
!_stricmp(da.vm_name,"VMOV_REG08_MEM08") ||
!_stricmp(da.vm_name,"VMOV_MEM08_REG08")
)
{
if( postion == 0 )
{
postion = 1;//decode之中
}
else if( postion == 1 )
{
postion = 2;//decode之后
}
else if( postion == 2 )//又出现了,出错
return -1;
nAddrReg = da.addrreg1;//保存使用的寄存器
}
if( postion == 2 )//解密code之后,循环之前
{
if( !_stricmp(da.vm_name,"VJNZ_IMM32") || !_stricmp(da.vm_name,"VJA_IMM32") )
{
postion = 3;//循环之后
}
}
if( postion == 3 )
{
if( !_stricmp(da.vm_name,"VJMP_REG32") && da.reg[0] == nAddrReg )//如果是跳到解密代码的语句,则结束
{
postion = 4;//结束
VirusEndAddr = (code+2);//设置结束地址
}
}
if( postion == 0 )
{
if( !_stricmp(da.vm_name,"VSUB_REG32_IMM32") || !_stricmp(da.vm_name,"VADD_REG32_IMM32") )
{
if( da.reg[0] == nAddrReg )//如果是解码地址寄存器
{
dwOffset = abs(da.immconst);
}
}
}
if( !_stricmp(da.vm_name,"VXOR_REG32_IMM32") ||
!_stricmp(da.vm_name,"VMOV_REG32_IMM32") ||
!_stricmp(da.vm_name,"VOR_REG32_IMM32") )
{
if( da.immconst > 0x2000 && da.immconst < 0x4000 && da.reg[0] != nAddrReg )//常数大于0xFF并且没有使用解码地址寄存器
CodeCout = da.immconst;
else if( abs(da.immconst) > 0 && abs(da.immconst) <= 0xFF && postion == 0)//如果小于FF
{
if( *(code+ret) == 0x8D && *(code+ret+3) == 0xE2 )//8D == lea xxx,[xxx+1] && E2 == loop
{//则是解码寄存器
decodekey = (BYTE)abs(da.immconst);
}
}
}
if( !_stricmp(da.vm_name,"VMOV_REG08_IMM32" ) ||
!_stricmp(da.vm_name,"VMOV_REG32_IMM32" ) ||
!_stricmp(da.vm_name,"VADD_REG08_IMM32" ) ||
!_stricmp(da.vm_name,"VADD_REG32_IMM32" ) ||
!_stricmp(da.vm_name,"VSUB_REG08_IMM32" ) ||
!_stricmp(da.vm_name,"VSUB_REG32_IMM32" ) ||
!_stricmp(da.vm_name,"VOR_REG32_IMM32" )
)
{
//常数大于0且小于FF且位置在解码之前
if( abs(da.immconst) > 0 && abs(da.immconst) <= 0xFF && postion == 0 )
{
if(da.reg[0] == decodereg )//是解码寄存器
{
decodekey = (BYTE)abs(da.immconst);
}
else if( *(code+ret) == 0x8D )//8D == lea xxx,[xxx+1]
{//则是解码寄存器
decodekey = (BYTE)abs(da.immconst);
}
}
}
if( postion == 4 && LastFuncAddr && dwOffset && CodeCout && decodekey )//全部得到了
{
ret = 0;
DWORD nextaddr = 0;
DWORD oepoffset = 0;
DWORD dwSubConst = 0;//减去的阀值
DWORD IsRestore = 0;//是否要恢复8字节CODE
DWORD RestoreHookCodeAddr = 0;//恢复5字节地址
//得到下一次地址
nextaddr = LastFuncAddr + dwOffset + 5;
decode((BYTE*)nextaddr,CodeCout);//解码OEP偏移
DWORD Count = *(DWORD*)(nextaddr + 0x6A);//恢复OEP时ESI的长度
dwSubConst = *(DWORD*)(nextaddr + 0x5B);
IsRestore = *(DWORD*)(nextaddr + 5 - dwSubConst + *(DWORD*)(nextaddr + 0xFB));
RestoreHookCodeAddr = nextaddr + 5 - dwSubConst + *(DWORD*)(nextaddr + 0x10C);//8字节的Esi地址
DWORD NextGoEsiAddr = nextaddr + 5 - dwSubConst + *(DWORD*)(nextaddr + 0x65);//Esi地址
DWORD NextEP;
if( !HookAddr )
NextEP = nextaddr + 5 - *(DWORD*)(nextaddr+0x55);//OEP地址(需要恢复的地址)
else
NextEP = HookAddr + 5 - *(DWORD*)(nextaddr+0x55);//OEP地址(需要恢复的地址)
if( Count )//需要复制
{
memcpy((BYTE*)NextEP,(BYTE*)NextGoEsiAddr,Count);
}
if( (IsRestore & 0x80000000) == 0x80000000 )//需要恢复5字节代码(内存)
{
memcpy((BYTE*)NextEP,(BYTE*)RestoreHookCodeAddr,5);
}
DWORD virtualaddress = image_nt_header->OptionalHeader.ImageBase + (DWORD)NextEP - (DWORD)pMem;
memset(VirusStartAddr,0,VirusEndAddr-VirusStartAddr);//清除内存中病毒代码
if( !CaclOEP((BYTE*)NextEP,virtualaddress,0,bLevel) )//是OEP头
{
DWORD OepOffset = NextEP - (DWORD)pMem;
if( Count )
{
BYTE* fileaddr = m_info->pvFile + RvaToOffset(OepOffset);
memcpy( fileaddr,(BYTE*)NextGoEsiAddr,Count );
}
if( (IsRestore & 0x80000000) == 0x80000000 )//需要恢复5字节代码(文件)
{
BYTE* fileaddr = m_info->pvFile + RvaToOffset(OepOffset);
memcpy((BYTE*)fileaddr,(BYTE*)RestoreHookCodeAddr,5);
}
BYTE* fileaddr = m_info->pvFile + RvaToOffset(VirusStartAddr-pMem);
memset((BYTE*)fileaddr,0,VirusEndAddr-VirusStartAddr);//在文件中的代码
if( !HookAddr )//没有搜索过
{
FindVirusEP((BYTE*)NextEP,virtualaddress,1);//搜索OEP附近是否还有病毒头
}
if( !bLevel )//顶级嵌套
{
image_nt_header->OptionalHeader.AddressOfEntryPoint = OepOffset;
image_nt_header->FileHeader.TimeDateStamp = '\0bug';
m_dlg->SetText(m_info->idx,"已清除");
}
}
}
return ret;
}
int CaclOEP(BYTE* addr,DWORD VirtualAddress,DWORD HookAddr,BOOL bLevel)
{
LastFuncAddr = 0;
dwOffset = 0;
CodeCout = 0;
decodekey = 0;
postion = 0;
method = -1;
UseAdd = FALSE;
AddNum = 0;
decodereg = -1;
nAddrReg = -1;
int codelen = 0;
int i = 0;
//first find reg
DWORD stepVirtualAddress = VirtualAddress;
while( i < 0x120 )
{
if( addr+i >= VirusStartAddr && addr+i <= VirusEndAddr )//如果在上一个病毒头中
{
i += (DWORD)(VirusEndAddr-VirusStartAddr);
stepVirtualAddress += (DWORD)(VirusEndAddr-VirusStartAddr);
}
else
{
codelen = FindBaseInfo_Proc(pMem,addr+i,stepVirtualAddress);
if( !codelen )
break;
if( codelen == -1 )//出错
codelen = 0x120;//结束
i += codelen;
stepVirtualAddress += codelen;
}
}
if( i < 0x120 )//是病毒头
{
//解码并计算EP
postion = 0;
int codelen = 0;
int i = 0;
stepVirtualAddress = VirtualAddress;
VirusStartAddr = (addr+i);//设置起始地址
while( i < 0x120 )
{
codelen = FindConstInfo_Proc(pMem,addr+i,stepVirtualAddress,HookAddr,bLevel);
if( !codelen )
break;
if( codelen == -1 )//出错
codelen = 0x120;//结束
i += codelen;
stepVirtualAddress += codelen;
}
return 1;//病毒头
}
else
{
return 0;//OEP头
}
return 0;
}
//搜索病毒头
void FindVirusEP(BYTE* addr,DWORD VirtualAddress,BOOL bLevel)
{
int i = 0;
DWORD stepVirtualAddress = VirtualAddress;
t_disasm da;
while( i < 0x200 )
{
if( *(addr+i) == 0xCC )//int3
{
return;
}
if( *(addr+i) == 0xE8 )//call
{
BYTE* calladdr = (BYTE*)(addr+i + *(DWORD*)(addr+i+1) + 5);
if( !IsBadReadPtr(calladdr,5) )//地址有效
{
DWORD NextVirtualAddress = stepVirtualAddress + *(DWORD*)(addr+i+1) + 5;
CaclOEP(calladdr,NextVirtualAddress,(DWORD)addr+i,bLevel);//是病毒头则清除
}
}
int codelen = Disasm((char*)addr+i,16,stepVirtualAddress,&da,DISASM_CODE);
i += codelen;
stepVirtualAddress += codelen;
}
}
//修复文件
void RepairFile(VirusInfo* info)
{
if( !info ) return;
m_info = info;
image_dos_header = (IMAGE_DOS_HEADER*)info->pvFile;
image_nt_header = (IMAGE_NT_HEADERS*)(info->pvFile + image_dos_header->e_lfanew);
image_section_header = (IMAGE_SECTION_HEADER *)(info->pvFile + image_dos_header->e_lfanew + sizeof(IMAGE_NT_HEADERS));
InitpMem();
EpAddr = pMem + image_nt_header->OptionalHeader.AddressOfEntryPoint;
DWORD VirtualAddress = image_nt_header->OptionalHeader.ImageBase + image_nt_header->OptionalHeader.AddressOfEntryPoint;
VirusStartAddr = NULL;
VirusEndAddr = NULL;
if( !CaclOEP(EpAddr,VirtualAddress,0,0) )//不是病毒头,则检测附近是否有stolen code
{
FindVirusEP(EpAddr,VirtualAddress,0);//搜索病毒头
}
UnmapViewOfFile((LPVOID)m_info->pvFile);m_info->pvFile = NULL;
CloseHandle(m_info->hFileMap);m_info->hFileMap = NULL;
CloseHandle(m_info->hFile);m_info->hFile = NULL;
GlobalFree(pMem);
}
void ClearList()
{
if( !m_dlg ) return;
int cout = m_dlg->m_List.GetItemCount();
for(int i = 0; i < cout; i++)
{
VirusInfo* tmpinfo = (VirusInfo*)m_dlg->m_List.GetItemData(i);
if( tmpinfo )
{
if( tmpinfo->pvFile )
{
UnmapViewOfFile((LPVOID)tmpinfo->pvFile);tmpinfo->pvFile = NULL;
}
if( tmpinfo->hFileMap )
{
CloseHandle(tmpinfo->hFileMap);tmpinfo->hFileMap = NULL;
}
if( tmpinfo->hFile )
{
CloseHandle(tmpinfo->hFile);tmpinfo->hFile = NULL;
}
delete tmpinfo; tmpinfo = NULL;
}
m_dlg->m_List.SetItemData(i,0);
}
}
//开始杀毒
BOOL StartKill(CVx_AntiVirusDlg* dlg,BOOL OnlyCheck)
{
bOnlyCheck = OnlyCheck;
InitializeCriticalSection(&cs);
m_dlg = dlg;
bStopFind = FALSE;
strdeque.clear();
m_dlg->m_List.DeleteAllItems();
if( dlg->bScanMemory )
{
if( !AntiHook() )
{
return FALSE;
}
}
DWORD dwId;
dwFindThread = CreateThread(NULL,0,FindFileThread,NULL,0,&dwId);
dwVirusThread = CreateThread(NULL,0,FindVirusThread,NULL,0,&dwId);
return TRUE;
}
//停止杀毒
void StopKill()
{
DWORD dw = 0;
bStopFind = TRUE;
dw = WaitForSingleObject(dwVirusThread,1500);
if(dw == WAIT_TIMEOUT)
{
TerminateThread(dwVirusThread,0);
}
TerminateThread(dwFindThread,0);
ClearList();
DeleteCriticalSection(&cs);
}
//解码函数
void decode(BYTE* addr,int len)
{
for(int i = 0; i < len; i++)
{
if( method == 0 )
addr[i] -= decodekey;
else
addr[i] ^= decodekey;
if( UseAdd )
decodekey += AddNum;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -