白袍的小行星

Windows Hack之资源释放技术

字数统计: 823阅读时长: 3 min
2020/04/04 Share

资源释放是一种经常被木马或病毒使用的技术,目的在于使攻击文件更简洁,只需一个exe文件就能完成攻击,本文将使用简单的例子来演示这种技术。

实现方式

一整套的动作可分解为4个步骤:

  1. 定位程序里的资源,使用FindResource完成,最后得到一个句柄:

    HRSRC FindResourceA(
    HMODULE hModule, //用于处理包含资源的可执行模块,如果为NULL,则从当前进程的模块装载
    LPCSTR lpName, //指定资源名称
    LPCSTR lpType //指定资源类型
    );
  2. 根据句柄,获取资源大小并加载到内存,分别使用SizeofResourceLoadResource实现:

    DWORD SizeofResource(
    HMODULE hModule, //包含资源的可执行文件的句柄,若为NULL,则从当前进程的模块装载
    HRSRC hResInfo //资源句柄,必须由 FindResource 或 FindResourceEx 来创建
    );

    HGLOBAL LoadResource(
    HMODULE hModule, //包含资源的可执行文件的句柄,若为NULL,则从当前进程的模块装载
    HRSRC hResInfo //资源句柄,必须由 FindResource 或 FindResourceEx 来创建
    );
  3. 锁定此块内存,避免被其他程序影响,通过LockResource实现,返回值为资源在内存中的起始地址:

    LPVOID LockResource(
    HGLOBAL hResData //装载资源的句柄,可以由LoadResource返回
    );
  4. 根据资源大小和起始地址,读取并保存资源到本地。

实现示例

本次实验环境

Windows 10 专业版

Visual Studio 2013

新建一个Win32控制台程序,然后添加一个txt文件为资源,文件内容如图:

资源类型选择自定义:

添加好之后就可以开始编写代码尝试了。

代码编写

这里使用C++来实现,需要读者对Win32编程有最基础的了解即可。

主体函数:

BOOL FreeMyResource(UINT uResourceName, char *ResourceType, char *SaveFileName){
//获取资源
HRSRC hSrc = ::FindResourceA(NULL, MAKEINTRESOURCEA(uResourceName), ResourceType);
if (hSrc == NULL){
cout << "Can't find resource" << endl;
return FALSE;
}

//获取资源大小
DWORD sizeResource = ::SizeofResource(NULL, hSrc);
if (sizeResource <= 0){
cout << "Can't get the size of resource" << endl;
return FALSE;
}

//加载资源
HGLOBAL lResource = ::LoadResource(NULL, hSrc);
if (lResource == NULL){
cout << "Can't load resource" << endl;
return FALSE;
}

//锁定内存
LPVOID lock = ::LockResource(lResource);
if (lock == NULL){
cout << "Can't lock resource" << endl;
return FALSE;
}

//释放资源到本地
FILE *fp = NULL;
fopen_s(&fp, SaveFileName, "wb+");
if (fp == NULL){
cout << "Can't write file" << endl;
return FALSE;
}
fwrite(lock, sizeof(char), sizeResource, fp);
fclose(fp);
return TRUE;
}

其中有个坑点,就是FindResourceA的传参,需要使用MAKEINTRESOURCEA来转换一下。原因在于我们常常使用资源ID来标识资源,ID号一般为无符号的整型,FindResourceA的对象参数为LPCSTR类型,这就需要一个类型转换相关的函数来处理了。

这里放出主函数和资源相关的头文件resource.h,供参考使用。

//主函数
int _tmain(int argc, _TCHAR* argv[])
{
if (FreeMyResource(IDR_MYTXT2, "MYTXT", "hacker.txt")){
cout << "You win!" << endl;
}
else{
cout << "You lose!" << endl;
}
system("pause");
return 0;
}
//resource.h

//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ 生成的包含文件。
// 供 win32test.rc 使用
//
#define IDR_MYTXT1 101
#define IDR_MYTXT2 102

// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 103
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1001
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

运行结果如图:

总结

编程能力确实很重要,加油吧。

CATALOG
  1. 1. 实现方式
  2. 2. 实现示例
    1. 2.1. 代码编写
  3. 3. 总结