前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Windows黑客编程技术详解 --2.3 病毒木马资源释放技术(内含赠书福利)

Windows黑客编程技术详解 --2.3 病毒木马资源释放技术(内含赠书福利)

作者头像
用户1631416
发布2019-05-07 11:37:10
1.6K0
发布2019-05-07 11:37:10
举报
文章被收录于专栏:玄魂工作室

本文经原作者授权,节选自《Windows黑客编程技术详解》一书。文末有福利哦!!

-----------------------------------------------------------------

病毒木马之所以会广泛使用资源释放技术,是因为它可以使程序变得更简洁。如果程序额外需要加载一些DLL文件、文本文件、图片文件,或者其他的音/视频文件等,则可以把它们作为资源插入到程序里,等到程序运行后,再把它们释放到本地上。这样做的好处是编译出来的程序只有一个exe文件,而不需要附带其他文件,因而程序变得很简洁。只需把exe植入到用户计算机上,而不需要连同其他文件一起植入,这降低了被发现的风险。

2.3.1 资源插入的步骤

在介绍资源释放技术之前,先介绍如何向程序中插入资源。资源插入不需要编码操作,只需手动设置VS开发环境即可完成。

本节以“520”这个没有文件类型的文件作为演示实例,向大家介绍文件作为资源插入到程序中的步骤,其他类型的插入也是类似的。其中,“520”的文件内容如图2-5所示。

打开项目工程之后,在解决方案中,选择“添加”,选中“资源”。本节演示的是插入自定义资源,所以单击“自定义(C)...”按钮。资源添加对话框,如图2-6所示。

然后,在“新建自定义资源”对话框中,输入“资源类型”,如“MYRES”,然后单击“确定”。新建自定义资源对话框,如图2-7所示。

在设置好自定义资源的类型之后,接着回到“添加资源”对话框。选中刚新建的“MYRES”资源类型,然后单击右侧的“导入(M)...”按钮来选择导入文件。

经过上述步骤后便完成了插入资源的操作。

2.3.2 函数介绍

1.FindResource函数

确定模块中指定类型和名称的资源所在位置。

函数声明

HRSRC FindResource(

HMODULE hModule,

LPCWSTR lpName,

LPCWSTR lpType)

参数

hModule[in]

处理包含资源的可执行文件模块。若hModule为NULL,则系统从当前进程的模块中装载资源。

lpName[in]

指定资源名称。

lpType[in]

指定资源类型。

返回值

如果函数运行成功,那么返回值为指定资源信息块的句柄。可将这个句柄传递给LoadResource函数来获得这些资源。如果函数运行失败,则返回值为NULL。

2.SizeofResource函数

获取指定资源的字节数。

函数声明

DWORD SizeofResource(

HMODULE hModule,

HRSRC hResInfo)

参数

hModule[in]

包含资源的可执行文件模块的句柄。若hModule为NULL,则系统从当前进程的模块中装载资源。

hResInfo[in]

资源句柄。此句柄必须由函数FindResource或FindResourceEx来创建。

返回值

如果函数运行成功,则返回值为资源的字节数;如果函数运行失败,则返回值为零。

3.LoadResource函数

装载指定资源到全局存储器。

函数声明

HGLOBAL LoadResource(

HMODULE hModule,

HRSRC hResInfo)

参数

hModule[in]

处理资源可执行文件的模块句柄。若hModule为NULL,则系统从当前进程的模块中装载资源。

hResInfo[in]

资源句柄。此句柄必须由函数FindResource或FindResourceEx来创建。

返回值

如果函数运行成功,则返回值为相关资源数据的句柄。如果函数运行失败,则返回值为NULL。

4.LockResource函数

锁定资源并得到资源在内存中第一个字节的指针。

函数声明

LPVOID LockResource(

HGLOBAL hResData)

参数

hResData[in]

装载资源的句柄。函数LoadResource可以返回这个句柄。

返回值

如果装载资源被锁住了,则返回值是资源第一个字节的指针;反之则为NULL。

2.3.3 实现原理

为方便开发人员获取程序里的资源,Windows提供了一系列带有操作资源的WIN32 API函数。所以,程序实现也是基于这些WIN32 API函数进行操作的。

首先,通过FindResource定位程序里的资源,主要是根据“资源类型”和“资源名称”进行定位,从而获取资源信息块的句柄。

其次,根据上面获取的资源信息块的句柄,利用SizeofResource获取资源的大小之后,再通过LoadResource把资源加载到程序内存中。

接着,通过LockResource锁定加载到内存中的资源,防止程序中的其他操作影响这块内存。其中,返回值就是资源在进程内存中的起始地址。

最后,根据资源大小以及进程内存的起始地址,可将资源数据读取出来并保存为本地文件。

经过上述4个步骤,便可以定位出资源,并将其释放到本地磁盘。它的原理就是通过PE文件结构,确定资源在PE文件中的偏移和大小。

在资源释放过程中,要特别注意一点就是,必须明确资源所在的模块,要指明所在模块句柄并且统一。因为文件可以以资源的形式插入到DLL文件中,所以当DLL加载到其他进程时,资源所在模块仍是该DLL模块。要想成功释放资源,则需要先通过GetModuleHandle函数获取该DLL模块的句柄。否则,资源释放会因为指定了错误模块而失败。

2.3.4 编程实现

BOOL FreeMyResource(UINT uiResouceName, char *lpszResourceType, char *lpszSaveFileName)

{

// 获取指定模块里的资源

HRSRC hRsrc = ::FindResource(NULL, MAKEINTRESOURCE(uiResouceName), lpszResourceType);

if (NULL == hRsrc)

{

ShowError("FindResource");

return FALSE;

}

// 获取资源的大小

DWORD dwSize = ::SizeofResource(NULL, hRsrc);

if (0 >= dwSize)

{

ShowError("SizeofResource");

return FALSE;

}

// 将资源加载到内存里

HGLOBAL hGlobal = ::LoadResource(NULL, hRsrc);

if (NULL == hGlobal)

{

ShowError("LoadResource");

return FALSE;

}

// 锁定资源

LPVOID lpVoid = ::LockResource(hGlobal);

if (NULL == lpVoid)

{

ShowError("LockResource");

return FALSE;

}

// 保存资源为文件

FILE *fp = NULL;

fopen_s(&fp, lpszSaveFileName, "wb+");

if (NULL == fp)

{

ShowError("LockResource");

return FALSE;

}

fwrite(lpVoid, sizeof(char), dwSize, fp);

fclose(fp);

return TRUE;

}

2.3.5 测试

本节创建一个MFC工程项目,按照上述步骤插入资源,并按照上述的实现原理来编码实现,调用封装好的资源释放函数进行资源释放的测试。资源释放的时候,将其保存为txt格式文件。

单击对话框中“释放”按钮后,提示资源释放成功,如图2-8所示。然后查看目录,本地成功地生成“520.txt”文件,打开文件查看内容,它与之前插入的“520”文件中的内容相同,如图2-9所示。资源释放成功。

2.3.6 小结

资源释放技术的实现原理并不是很复杂,只需理清WIN32 API函数的调用关系以及函数作用即可。要特别注意一点,明确资源所在的模块,如果资源包含在DLL文件中,则可以在DllMain中或是通过GetModuleHandle函数获取DLL模块的句柄。

安全小贴士

可以根据PE结构中的资源表IMAGE_RESOURCE_DIRECTORY来解析PE文件中包含的所有资源,并且获取资源的偏移地址及数据大小。例如,常用的资源编辑工具eXeScope就是根据资源表来枚举PE文件中的资源的。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-04-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 玄魂工作室 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 2.3.1 资源插入的步骤
  • 2.3.2 函数介绍
    • 1.FindResource函数
      • 2.SizeofResource函数
        • 3.LoadResource函数
          • 4.LockResource函数
          • 2.3.3 实现原理
          • 2.3.4 编程实现
          • 2.3.5 测试
          • 2.3.6 小结
          • 安全小贴士
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档