今天说一下写病毒木马会广泛使用的一种技术——资源释放技术。为什么我们在写木马时会使用到资源释放技术呢?这是因为它可以使我们写的程序变得简洁。如果程序需要额外加载一些DLL文件或者文本文件,我们可以把它们作为资源插入到程序里。等程序运行,再把它们释放到本地。这样好处是只有一个.exe文件,这就降低了被发现的风险。
资源插入说资源释放前,下面先说一下资源插入,资源插入不需要编写代码,只需要手动设置VS开发环境就可以。首先新建一个文件,这里命名为lxf ,然后在里面写上内容,内容为my name is lxf,如下图:
然后在VS2017中新建一个项目,在项目的解决方案里右键=》添加=》资源,如下图
点击资源后,然后再新弹出来的对话框,点击自定义,然后在资源类型框里填MYRES,最后点击导入,将刚才新建的文件导入到这里。如下图:
倒入成功后,插入资源就完成了。
释放资源接下来看一下释放资源的案例代码,如下:
// test.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。 // #undef UNICODE #include <Windows.h> #include <stdio.h> #include "resource.h" // 提取资源 BOOL FreeMyResourse(UINT uiResouceName, char *lpszResourceType, char *lpszSaveFileName) { //获取指定模块的资源 HRSRC hRsrc = FindResource(NULL, MAKEINTRESOURCE(uiResouceName), lpszResourceType); if (hRsrc == NULL) { printf("can't find the resource!\n"); return FALSE; } //获取资源的大小 DWORD dwSize = SizeofResource(NULL, hRsrc); if (dwSize <= 0) { printf("the resource's size is error!\n"); return FALSE; } //将资源加载到内存里 HGLOBAL hGlobal = LoadResource(NULL, hRsrc); if(hGlobal == NULL) { printf("load resource error!\n"); return FALSE; } //锁定资源 LPVOID lpVoid = LockResource(hGlobal); if (lpVoid == NULL) { printf("lock resource error!\n"); return FALSE; } //保存资源为文件 FILE* fp = NULL; fopen_s(&fp, lpszSaveFileName, "wb+"); if (fp == NULL) { printf("open file error!\n"); return FALSE; } fwrite(lpVoid, sizeof(char), dwSize, fp); fclose(fp); return TRUE; } int main() { char lpszResourceType[20] = "MYRES"; char szSaveFileName[20] = "lxf.txt"; BOOL flag = FreeMyResourse(IDR_MYRES4,lpszResourceType, szSaveFileName); if (flag == TRUE) { printf("释放成功\n"); } return 0; }上面写了释放资源的案例代码,这里讲解一下吧,首先是FindResource函数,这个函数的作用就是确定模块中指定类型和名称的资源所在位置。
函数原型:
HRSRC FindResource(HMODULE hModule,LPCTSTR lpName,LPCTSTR lpType)
参数:
hModule:处理包含资源的可执行文件的模块。NULL值则指定模块句柄指向操作系统通常情况下创建最近过程的相关位图文件。
lpName:指定资源名称。
lpType:指定资源类型。
返回值:
如果函数成功运行,那么返回值为指定资源信息块的句柄。可将句柄传递给LoadResource函数来获得这些资源。如果失败,返回NULL。
接下来是SizeofResource函数。这个函数的作用是获取指定资源的字节数。
函数原型:
DWORD SizeofResource(HMODULE hModule,HRSRC hReslnfo);
参数:
hModule:包合资源的可执行文件模块的句柄。
hReslnfo:资源句柄。此句柄必须由函数FindResource或FindResourceEx来创建。
返回值:
如果函数运行成功,返回值资源的字节数。如果函数运行失败,返回值为零。若想获得更多的错误信息,请调用GetLastError函数。
接着是LoadResource函数。这个函数的作用是装载指定资源到全局存储器。
函数原型:
HGLOBAL LoadResource(HMODULE hModule,HRSRC hReslnfo);
参数:
hModule:处理包合资源的可执行文件的模块句柄。若hModule为NULL,系统从当前过程中的模块中装载资源。
hReslnfo:将被装载资源的句柄。它必须由函数FindResource或FindResourceEx创建。
返回值:如果函数运行成功,返回值是相关资源的数据的句柄。如果函数运行失败,返回值为NULL。若想获得更多的错误信息,请调用GetLastError函数。
最后一个是LockResource函数,这个函数作用是锁定资源,并得到资源在内存中第一个字节的指针。
函数原型:
LPVOID LockResource(HGLOBAL hResDate);
参数:
hResDate:被装载的资源的句柄。函数LosdResource可以返回这个句柄。
返回值:
如果被装载的资源被所住了,返回值是资源第一个字节的指针;否则为NULL。
注意:通过使用函数FindResource或FindResourceEx返回句柄试图所住资源,不再工作。可以返回一个错误的数据和任意数据的指针。