PE文件格式中数据目录项中的资源表

资源表

资源表地址在数据目录的数组下标为2的地方,定位到资源表后就可以遍历资源
资源是树形结构,一般有3层 根目录 子目录 文件
  1. 根目录结构结构体如下定义
typedef struct _IMAGE_RESOURCE_DIRECTORY {
    DWORD   Characteristics;          资源属性
    DWORD   TimeDateStamp;           时间戳
    WORD    MajorVersion;            资源大版本号
    WORD    MinorVersion;            资源小版本号
    WORD    NumberOfNamedEntries;       按照名称命名的数量
    WORD    NumberOfIdEntries;         按照ID命名的数量//  IMAGE_RESOURCE_DIRECTORY_ENTRY DirectoryEntries[];
} IMAGE_RESOURCE_DIRECTORY, *PIMAGE_RESOURCE_DIRECTORY;	//只有后面两个字段是重要的
  1. 资源目录项(子目录)结构体定义如下
ypedef struct _IMAGE_RESOURCE_DIRECTORY_ENTRY 
{
    union 
    {
        struct 
        {
            DWORD NameOffset:31;          位段:31位位是偏移 定义了目录项的名称或者ID
            DWORD NameIsString:1;          位段: 高位, 如果这位为1,则表示31位的偏移指向的是一个Unicode字符串的指针偏移
        };                      这里列出结构体,自己去看,IMAGE_RESOURCE_DIR_STRING_U 里面是字符串长度还有字符串,不是\0结尾         
        DWORD   Name;                 
        WORD    Id;
    };
    union 
    {
        DWORD   OffsetToData;            偏移RVA因为是联合体,所以有不同的解释
        struct 
        {
            DWORD   OffsetToDirectory:31;    看高位,如果高位是1,那么RVA偏移指向的是新的(根目录)
            DWORD   DataIsDirectory:1;      
        };
    };
} IMAGE_RESOURCE_DIRECTORY_ENTRY, *PIMAGE_RESOURCE_DIRECTORY_ENTRY;

注意点:如果第一4字节高位为0 表示是ID 但是ID有3种表示,如果在第一层目录,也就是根目录下则表示是资源类型,第二层目录(子目录)表示的是资源ID 第3层目录(文件)ID表示的是代码页

3.资源文件定义如下

typedef struct _IMAGE_RESOURCE_DATA_ENTRY {
    DWORD   OffsetToData;          资源数据的偏移RVA
    DWORD   Size;               大小
    DWORD   CodePage;             代码页缓冲(CMD设置窗口的时候就是这个,没用)
    DWORD   Reserved;             保留
} IMAGE_RESOURCE_DATA_ENTRY, *PIMAGE_RESOURCE_DATA_ENTRY;

注意点:只有文件的时候OffsetToData才是RVA ,其他都是节内偏移

宿主病毒
  • 将整个PE文件当资源加载到宿主文件
  • 当宿主文件启动后,释放PE文件的资源
  • 通过资源表或者API获取PE文件所在内存位置
  • 创建新文件,将PE文件拷贝的新的文件中
  • 使用CreateProcess打开新文件,运行PE文件进程
使用API获取资源在内存的位置代码如下
// LoadResourse.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include<windows.h>
#include <string>
#include <WinUser.h>
#include "resource.h"
using namespace std;


void ReportError(std::string strError)
{
    LPVOID lpMsgBuf;
    FormatMessage(
        FORMAT_MESSAGE_ALLOCATE_BUFFER |
        FORMAT_MESSAGE_FROM_SYSTEM |
        FORMAT_MESSAGE_IGNORE_INSERTS,
        NULL,
        GetLastError(),
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
        (LPTSTR)&lpMsgBuf,
        0,
        NULL
        );
    printf("%s==>%s", strError.c_str(), (char*)lpMsgBuf);

    LocalFree(lpMsgBuf);

}

int _tmain(int argc, _TCHAR* argv[])
{
    //加载资源
    HMODULE hMoudule = GetModuleHandle(NULL);
    if (hMoudule == NULL)
    {
        ReportError("GetModuleHandle");
    }

    HRSRC hRes = FindResource(hMoudule, MAKEINTRESOURCE(IDR_MYEXE1), "myexe");
    if (hRes == NULL)
    {
        ReportError("FindResource");
    }

    HGLOBAL hResData = LoadResource(hMoudule, hRes);
    if (hResData == NULL)
    {
        ReportError("LoadResource");
    }

    LPVOID lpFileData = LockResource(hResData);
    if (lpFileData == NULL)
    {
        ReportError("LockResource");
    }

    DWORD dwResSize = SizeofResource(hMoudule, hRes);
    if (dwResSize == 0)
    {
        ReportError("SizeofResource");
    }
    //创建文件
    HANDLE hFile = CreateFile(
       "MyExeCopy.exe",
        GENERIC_READ | GENERIC_WRITE,
        NULL,
        NULL,
        OPEN_ALWAYS,
        FILE_ATTRIBUTE_NORMAL,
        NULL);
    if (hFile == INVALID_HANDLE_VALUE)
    {
        ReportError("CreateFile");
    }

    DWORD dwRealWriteSize = 0;
    DWORD dwTotalWriteSize = 0;
    while (dwTotalWriteSize < dwResSize)
    {
        if (!WriteFile(hFile, lpFileData, dwResSize, &dwRealWriteSize, NULL))
        {
            ReportError("WriteFile");
        }
        dwTotalWriteSize += dwRealWriteSize;
    }
    if (!CloseHandle(hFile))
    {
        ReportError("CloseHandle");
    }
   
    TCHAR szExe[] = { "MyExeCopy"};
    PROCESS_INFORMATION stProcessInformation = { 0 };
    STARTUPINFO stStartupInfo = { 0 };
    stStartupInfo.cb = sizeof(stStartupInfo);
    BOOL bRet = CreateProcess(
        NULL,
        szExe,
        NULL,
        NULL,
        TRUE,
        0,
        NULL,
        NULL,
        &stStartupInfo,             //设置窗口的一些基本信息
        &stProcessInformation);            //传出参数
    if (!bRet)
    {
        ReportError("CreateProcess");
    }

    system("pause");
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值