当前位置: 首页 > wzjs >正文

靓号注册网站免费购买网址

靓号注册网站免费,购买网址,上传网站内容,重庆石桥铺网站建设所谓的资源也就是我们之前学的MFC中的对话框,按钮,编辑框之类的东西。不仅MFC有资源,我们平时熟悉的控制台程序也有资源 当我们平时写一些程序或者木马时,我们通常对其定义一个随机的名称或者路径,然后再向外界进行释…

所谓的资源也就是我们之前学的MFC中的对话框,按钮,编辑框之类的东西。不仅MFC有资源,我们平时熟悉的控制台程序也有资源

当我们平时写一些程序或者木马时,我们通常对其定义一个随机的名称或者路径,然后再向外界进行释放(资源的 二进制数据写入文件)。而这些随机的名称或路径被写入PE文件的资源中

资源释放

我们以一个控制台程序为例,添加一个exe文件资源然后再进行资源释放:

首先我们先添加一个资源:资源文件->添加资源->导入->某exe文件->自定义资源类型,此时便会加载该exe文件的二进制数据

代码演示

#include <iostream>
#include <stdlib.h>
#include <time.h>
#include <Windows.h>
#include "resource.h"//随机资源名称
LPCSTR RandomString() 
{srand((int)time(NULL));//设置随机数起始值char szStr[] = { 'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z' };//设置随机名称的字符char Temp[9] = { 0 };for (size_t i = 0; i < 7; i++){int nIndex = rand();//设置随机数nIndex = nIndex % 26;//获取对应名称字符的随机数Temp[i] = szStr[nIndex];//获取随机数对应字符}return Temp;
}
//释放
void ReleaseFile(LPCSTR lpFilePath)
{HRSRC hRsrc = FindResource(NULL, MAKEINTRESOURCE(IDR_INJECTEXE1), "injectexe");//获取添加的资源DWORD dwSize = SizeofResource(NULL, hRsrc);//获取资源大小HGLOBAL hGlobal = LoadResource(NULL, hRsrc);//加载资源LPVOID lpRes = LockResource(hGlobal);//获取资源内存二进制数据HANDLE hFile = CreateFile(lpFilePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);//创建文件DWORD dwWriteLen = 0;WriteFile(hFile, lpRes, dwSize, &dwWriteLen, NULL);//将资源的二进制数据写入文件CloseHandle(hFile);//关闭文件句柄
}int main()
{char szFilePath[50] = "D:\\";char szFileEnd[5] = ".exe";LPCSTR szFileName = new char[50];strcpy((char *)szFileName, RandomString());strcat(szFilePath, szFileName);strcat(szFilePath, szFileEnd);//拼接资源名称ReleaseFile(szFilePath);system("pause");return 0;
}

此时我们生成的文件可以正常运行

资源表

资源表是一张描述资源数据在PE中的分布情况的表,其包含了PE文件中所使用到的资源。通过资源表,操作系统和应用程序可以轻松地访问和加载可执行文件中的资源。开发人员可以使用资源编辑器或编程工具来创建、编辑和管理资源表中的资源。

资源表定位

通过数据目录的第3个目录项,我们可以得知资源表所在地址RVA及其数据大小,从而定位到资源表所在地址

从资源表的起始开始为一级子目录的资源目录头,紧接着是各个一级子目录的资源目录项。每个一级子目录都可以指向一个二级子目录,起始为二级子目录的资源目录头,紧接着是各个二级子目录的资源目录项。每个而级子目录都可以指向一个三级子目录,起始为三级子目录的资源目录头,紧接着是各个三级子目录的资源目录项。每个三级子目录都可以指向一个资源或者代码页

三级目录结构

PE文件组织资源的方式类似于操作系统的文件管理方式。从根目录开始向下分为三级管理:一级子目录、二级子目录和三级子目录,三级子目录下为具体资源。如图所示:

1.一级子目录按照资源类型分类,如光标一级子目录,位图一级子目录等多个资源类型。

2.二级子目录按照资源的ID分类。例如:在菜单一级子目录下可以有: IDM_OPEN的ID为2001,IDM_EXIT的ID为2002,IDM1的ID为4000等多个菜单项。

3.三级子目录是按照资源的代码页分类,即不同的语言代码页对应不同的数据。其中,根据语言可以分为简体中文、英文、繁体中文等多个代码页。一般来说这个目录没啥用,这样用该目录下的文件

4.三级子目录后即为文件(资源),三级子目录和文件一一对应。文件是包含了资源数据的指针和大小等信息的一个数据结构。对所有资源数据块的访问均可从这里开始。

资源表结构

资源表的结构分为如下四个部分:

资源目录表(根目录):资源目录表是资源表的顶层结构,它包含了指向各个资源类型的目录项的指针。

资源类型目录表(一级子目录):资源类型目录表包含了每个资源类型的目录项,例如位图、图标、对话框等。

资源名称/标识符目录表(二级子目录):资源名称/标识符目录表包含了每个资源类型下的资源名称或标识符的目录项。

资源数据目录表(资源):资源数据目录表包含了每个资源的实际数据的位置和大小。

资源目录头

资源目录头,它标识了当前级别目录整体信息,如:属性,创建日期,版本目录项的数量等等描述信息。

资源目录头结构如下:

typedef struct _IMAGE_RESOURCE_DIRECTORY {DWORD   Characteristics;				//资源特性DWORD   TimeDateStamp;					//时间戳WORD    MajorVersion;					//资源的大版本号WORD    MinorVersion;					//资源的小版本号WORD    NumberOfNamedEntries;			//以字符串命名的入口数量WORD    NumberOfIdEntries;				//以ID命名的入口数量
} IMAGE_RESOURCE_DIRECTORY, *PIMAGE_RESOURCE_DIRECTORY;

资源目录项

紧接着资源目录头的是资源目录项。一个资源目录可以有多个资源目录项(以名称定义的资源目录项或以ID定义的资源目录项,或者两者组合)。目录项和目录项之间按照线性排列:首先按照字母升序(不分大小写)排列名称资源目录项, 然后再按ID升序排列ID资源目录项。

资源目录项分为两种表示类型,分别为名称和ID。名称为以字符串形式命名的资源,一般为用户自定义的。ID条目为以整数形式命名的资源,一般为操作系统为我们预定义

 如下的操作系统为我们预定义的一级子目录的ID类型的类型数据,ID = 0到ID = 0x11

const char * g_ResType[0x11] = 
{"NULL","鼠标指针","位图","图标","菜单","对话框","字符串列表","字体目录","字体","快捷键","非格式化资源","消息列表","鼠标指针组","NULL","图标组","NULL","版本信息",
};

资源目录项结构如下:

typedef struct _IMAGE_RESOURCE_DIRECTORY_ENTRY {union {struct {DWORD NameOffset:31;//低位:当高位为1时,该值为一个包含名称的结构体相对于一级子目录的资源目录头的偏移。当高位为0时,该值为一个编号DWORD NameIsString:1;//高位:当为1时,资源类型为名称。当为0时,资源类型为ID} DUMMYSTRUCTNAME;DWORD   Name;    //当NameIsString为1时,该值为ID,当NameIsString为0时,该值为一个包含名称的结构体相对于一级子目录的资源目录头的偏移。一般不用该成员WORD    Id;      //资源ID} DUMMYUNIONNAME;union {DWORD   OffsetToData;struct {DWORD   OffsetToDirectory:31;//低位:高位为1时,该值为下一级目录或资源相对于一级子目录的资源目录头的偏移。DWORD   DataIsDirectory:1;//高位:当为1时,该值表示下一级目录或资源} DUMMYSTRUCTNAME2;} DUMMYUNIONNAME2;
} IMAGE_RESOURCE_DIRECTORY_ENTRY, *PIMAGE_RESOURCE_DIRECTORY_ENTRY;

由于一级子目录下的DataIsDirectory为1指向二级子目录。而二级子目录下的DataIsDirectory为1指向资源

包含union字符串的结构体如下:

typedef struct _IMAGE_RESOURCE_DIR_STRING_U {WORD    Length;WCHAR   NameString[ 1 ];
} IMAGE_RESOURCE_DIR_STRING_U, *PIMAGE_RESOURCE_DIR_STRING_U;

注意:NameString并不是以0结尾的字符串数组,因此我们在使用时,需要把它复制到一个新的数组中,以添加结尾的0

资源数据项

资源数据项即三级目录结构中的文件,它是通过三次目录定位后找到的一个数据结构,其结构如下:

typedef struct _IMAGE_RESOURCE_DATA_ENTRY {DWORD   OffsetToData; //文件偏移DWORD   Size;         //资源大小DWORD   CodePage;     //代码页DWORD   Reserved;     //保留字段
} IMAGE_RESOURCE_DATA_ENTRY, *PIMAGE_RESOURCE_DATA_ENTRY;

通过资源目录项的OffsetToData,我们可以找到具体的资源。

资源表图示

 我们通过LoadPE观察一个PE文件的资源表:

如上图所示:

AFX_DIALOG_LAYOUT为一级子目录的资源目录项的类型信息

102为二级子目录的资源目录项的类型信息

图中并没有显示三级子目录,一般来说三级子目录的作用就是指向资源,因此常常把它忽略

Root Rirectory为根目录的资源目录头的相关信息

Selected Rirectory为一级子目录的资源目录头的相关信息

Selected Item为三级子目录下资源的相关信息

遍历资源表

代码实现:

static const char* szResName[0x11]
{0,"Corsor","Bitmap","Icon","Menu","Dialog","StringTable","FontDir","Font","Accelerator","RCDATA","MessageTable","GroupCursor","zz","GroupIcon","xx","Version"
};void PrintResourceTable()
{PIMAGE_DOS_HEADER pDosHeader = nullptr;PIMAGE_NT_HEADERS pNTHeader = nullptr;PIMAGE_FILE_HEADER pFileHeader = nullptr;PIMAGE_OPTIONAL_HEADER pOptionalHeader = nullptr;PIMAGE_DATA_DIRECTORY pDataDirectory = nullptr;PIMAGE_RESOURCE_DIRECTORY pResourceTable = nullptr;PIMAGE_RESOURCE_DIRECTORY_ENTRY pResourceEntry = nullptr;LPVOID pFileBuffer = nullptr;DWORD dwSize = 0;dwSize = ReadFile(&pFileBuffer, FILE_PATH_IN);if (dwSize == 0 || pFileBuffer == nullptr){printf("读取文件失败");}pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pFileBuffer + pDosHeader->e_lfanew);pFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + sizeof(pNTHeader->Signature));pOptionalHeader = (PIMAGE_OPTIONAL_HEADER)((DWORD)pFileHeader + IMAGE_SIZEOF_FILE_HEADER);//定位资源表pDataDirectory = (PIMAGE_DATA_DIRECTORY)(&pOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE]);pResourceTable = (PIMAGE_RESOURCE_DIRECTORY)((DWORD)pFileBuffer + RVA2FOA(pDataDirectory->VirtualAddress, pFileBuffer));pResourceEntry = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(pResourceTable + 1);//解析第一层DWORD dwTypeCount = pResourceTable->NumberOfIdEntries + pResourceTable->NumberOfNamedEntries;for (DWORD i = 0; i < dwTypeCount; i++){//最高位为0if (pResourceEntry[i].NameIsString == 0){if (pResourceEntry[i].Id < 0x11){printf("资源类型ID:%d %s\n", pResourceEntry[i].Id, szResName[pResourceEntry[i].Id]);}else{printf("资源类型ID:%d\n", pResourceEntry[i].Id);}}//最高位为1else if (pResourceEntry[i].NameIsString == 1){PIMAGE_RESOURCE_DIR_STRING_U pStr = (PIMAGE_RESOURCE_DIR_STRING_U)((DWORD)pResourceTable + pResourceEntry[i].NameOffset);WCHAR szStr[MAX_PATH] = { 0 };memcpy(szStr, pStr->NameString, pStr->Length * sizeof(WCHAR));printf("资源类型名称:%ls\n", szStr);}//解析第二层if (pResourceEntry[i].DataIsDirectory == 1){printf("第二层目录偏移:%x\n", pResourceEntry[i].OffsetToDirectory);PIMAGE_RESOURCE_DIRECTORY pRes2 = (PIMAGE_RESOURCE_DIRECTORY)((DWORD)pResourceTable + pResourceEntry[i].OffsetToDirectory);PIMAGE_RESOURCE_DIRECTORY_ENTRY pResEntry2 = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(pRes2 + 1);DWORD dwCount = pRes2->NumberOfIdEntries + pRes2->NumberOfNamedEntries;for (DWORD i = 0; i < dwCount; i++){//最高位为0if (pResEntry2[i].NameIsString == 0){printf("  ->资源标识ID:%d\n", pResEntry2[i].Id);}else{PIMAGE_RESOURCE_DIR_STRING_U pStr = (PIMAGE_RESOURCE_DIR_STRING_U)((DWORD)pResourceTable + pResEntry2[i].NameOffset);WCHAR szStr[MAX_PATH] = { 0 };memcpy(szStr, pStr->NameString, pStr->Length * sizeof(WCHAR));printf("  ->资源名称:%ls\n", szStr);}//解析第三层if (pResEntry2[i].DataIsDirectory == 1){PIMAGE_RESOURCE_DIRECTORY pRes3 = (PIMAGE_RESOURCE_DIRECTORY)((DWORD)pResourceTable + pResEntry2[i].OffsetToDirectory);PIMAGE_RESOURCE_DIRECTORY_ENTRY pResEntry3 = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(pRes3 + 1);printf("    -->代码页标号为:%x\n", pResEntry3->Id);if (pResEntry3->DataIsDirectory == 0){PIMAGE_RESOURCE_DATA_ENTRY pResDataEntry = (PIMAGE_RESOURCE_DATA_ENTRY)((DWORD)pResourceTable+pResEntry3->OffsetToData);printf("    --数据RVA:%x\n", pResDataEntry->OffsetToData);printf("    --数据大小:%x\n", pResDataEntry->Size);}}}}}
}

作业

利用MFC遍历资源表,用树进行显示记录

// ResTreeDlg.h: 头文件
//#pragma once
#include<iostream>
#include<Windows.h>// CResTreeDlg 对话框
class CResTreeDlg : public CDialogEx
{
// 构造
public:CResTreeDlg(CWnd* pParent = nullptr);	// 标准构造函数// 对话框数据
#ifdef AFX_DESIGN_TIMEenum { IDD = IDD_RESTREE_DIALOG };
#endifprotected:virtual void DoDataExchange(CDataExchange* pDX);	// DDX/DDV 支持// 实现
protected:HICON m_hIcon;// 生成的消息映射函数virtual BOOL OnInitDialog();afx_msg void OnSysCommand(UINT nID, LPARAM lParam);afx_msg void OnPaint();afx_msg HCURSOR OnQueryDragIcon();DECLARE_MESSAGE_MAP()
public:CTreeCtrl m_ResTree;CString RootNameEntries;CString FirstNameEntries;CString RootIDEntries;CString FirstIDEntries;CString ResRVA;CString ResFOA;CString ResSize;afx_msg void OnOpenFile();char* LoadFile(const WCHAR* szFilePath);char* szFileBuffer;DWORD RvaToFoa(DWORD dwRva, char* szBuffer);void OnInitResTree();DWORD dwFirstNameEntrys = 0;DWORD dwFirstIDEntrys = 0;
};// ResTreeDlg.cpp: 实现文件
//#include "pch.h"
#include "framework.h"
#include "ResTree.h"
#include "ResTreeDlg.h"
#include "afxdialogex.h"#ifdef _DEBUG
#define new DEBUG_NEW
#endif// 用于应用程序“关于”菜单项的 CAboutDlg 对话框class CAboutDlg : public CDialogEx
{
public:CAboutDlg();// 对话框数据
#ifdef AFX_DESIGN_TIMEenum { IDD = IDD_ABOUTBOX };
#endifprotected:virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持// 实现
protected:DECLARE_MESSAGE_MAP()
public:afx_msg void OnTvnSelchangedTree1(NMHDR* pNMHDR, LRESULT* pResult);
};CAboutDlg::CAboutDlg() : CDialogEx(IDD_ABOUTBOX)
{
}void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{CDialogEx::DoDataExchange(pDX);
}BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)ON_NOTIFY(TVN_SELCHANGED, IDC_TREE1, &CAboutDlg::OnTvnSelchangedTree1)
END_MESSAGE_MAP()// CResTreeDlg 对话框CResTreeDlg::CResTreeDlg(CWnd* pParent /*=nullptr*/): CDialogEx(IDD_RESTREE_DIALOG, pParent), RootNameEntries(_T("")), FirstNameEntries(_T("")), RootIDEntries(_T("")), FirstIDEntries(_T("")), ResRVA(_T("")), ResFOA(_T("")), ResSize(_T(""))
{m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}void CResTreeDlg::DoDataExchange(CDataExchange* pDX)
{CDialogEx::DoDataExchange(pDX);DDX_Control(pDX, IDC_TREE1, m_ResTree);DDX_Text(pDX, IDC_EDIT1, RootNameEntries);DDX_Text(pDX, IDC_EDIT3, FirstNameEntries);DDX_Text(pDX, IDC_EDIT2, RootIDEntries);DDX_Text(pDX, IDC_EDIT4, FirstIDEntries);DDX_Text(pDX, IDC_EDIT5, ResRVA);DDX_Text(pDX, IDC_EDIT6, ResFOA);DDX_Text(pDX, IDC_EDIT7, ResSize);
}BEGIN_MESSAGE_MAP(CResTreeDlg, CDialogEx)ON_WM_SYSCOMMAND()ON_WM_PAINT()ON_WM_QUERYDRAGICON()ON_COMMAND(ID_32771, &CResTreeDlg::OnOpenFile)
END_MESSAGE_MAP()// CResTreeDlg 消息处理程序BOOL CResTreeDlg::OnInitDialog()
{CDialogEx::OnInitDialog();// 将“关于...”菜单项添加到系统菜单中。// IDM_ABOUTBOX 必须在系统命令范围内。ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);ASSERT(IDM_ABOUTBOX < 0xF000);CMenu* pSysMenu = GetSystemMenu(FALSE);if (pSysMenu != nullptr){BOOL bNameValid;CString strAboutMenu;bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);ASSERT(bNameValid);if (!strAboutMenu.IsEmpty()){pSysMenu->AppendMenu(MF_SEPARATOR);pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);}}// 设置此对话框的图标。  当应用程序主窗口不是对话框时,框架将自动//  执行此操作SetIcon(m_hIcon, TRUE);			// 设置大图标SetIcon(m_hIcon, FALSE);		// 设置小图标// TODO: 在此添加额外的初始化代码return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
}void CResTreeDlg::OnSysCommand(UINT nID, LPARAM lParam)
{if ((nID & 0xFFF0) == IDM_ABOUTBOX){CAboutDlg dlgAbout;dlgAbout.DoModal();}else{CDialogEx::OnSysCommand(nID, lParam);}
}// 如果向对话框添加最小化按钮,则需要下面的代码
//  来绘制该图标。  对于使用文档/视图模型的 MFC 应用程序,
//  这将由框架自动完成。void CResTreeDlg::OnPaint()
{if (IsIconic()){CPaintDC dc(this); // 用于绘制的设备上下文SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);// 使图标在工作区矩形中居中int cxIcon = GetSystemMetrics(SM_CXICON);int cyIcon = GetSystemMetrics(SM_CYICON);CRect rect;GetClientRect(&rect);int x = (rect.Width() - cxIcon + 1) / 2;int y = (rect.Height() - cyIcon + 1) / 2;// 绘制图标dc.DrawIcon(x, y, m_hIcon);}else{CDialogEx::OnPaint();}
}//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CResTreeDlg::OnQueryDragIcon()
{return static_cast<HCURSOR>(m_hIcon);
}void CResTreeDlg::OnOpenFile()
{// TODO: 在此添加命令处理程序代码CFileDialog file(TRUE, L"exe", L"*.exe", OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY, L"可执行文件|.exe|所有文件|.*", NULL);if (file.DoModal() == IDOK){CString FilePath = file.GetPathName();szFileBuffer = LoadFile(FilePath.GetBuffer());AfxMessageBox(L"打开文件成功");OnInitResTree();}else{AfxMessageBox(L"打开文件失败");}}char* CResTreeDlg::LoadFile(const WCHAR* szFilePath)
{HANDLE hFile = CreateFileW(szFilePath, GENERIC_READ | GENERIC_WRITE, NULL, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);if (hFile == INVALID_HANDLE_VALUE){return FALSE;}DWORD dwFileSize = GetFileSize(hFile, NULL);char* szBuffer = new char[dwFileSize];memset(szBuffer, 0, dwFileSize);if (ReadFile(hFile, szBuffer, dwFileSize, &dwFileSize, NULL)){return szBuffer;}else{return FALSE;}
}DWORD CResTreeDlg::RvaToFoa(DWORD dwRva, char* szBuffer)
{PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)szBuffer;PIMAGE_NT_HEADERS pNt = (PIMAGE_NT_HEADERS)(szBuffer + pDos->e_lfanew);PIMAGE_SECTION_HEADER pSectionHeader = IMAGE_FIRST_SECTION(pNt);if (dwRva < pSectionHeader[0].VirtualAddress){return dwRva;}else{for (int i = 0; i < pNt->FileHeader.NumberOfSections; i++){if (dwRva >= pSectionHeader[i].VirtualAddress && dwRva < pSectionHeader[i].VirtualAddress + pSectionHeader[i].Misc.VirtualSize){return dwRva - pSectionHeader[i].VirtualAddress + pSectionHeader[i].PointerToRawData;}}}return 0;
}void CResTreeDlg::OnInitResTree()
{ const WCHAR* g_ResType[0x11] = {L"NULL",L"鼠标指针",L"位图",L"图标",L"菜单",L"对话框",L"字符串列表",L"字体目录",L"字体",L"快捷键",L"非格式化资源",L"消息列表",L"鼠标指针组",L"NULL",L"图标组",L"NULL",L"版本信息",};PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)szFileBuffer;PIMAGE_NT_HEADERS pNt = (PIMAGE_NT_HEADERS)(szFileBuffer + pDos->e_lfanew);PIMAGE_OPTIONAL_HEADER pOptionHeader = &pNt->OptionalHeader;PIMAGE_DATA_DIRECTORY pResDir = pOptionHeader->DataDirectory + IMAGE_DIRECTORY_ENTRY_RESOURCE;PIMAGE_RESOURCE_DIRECTORY pFirst = (PIMAGE_RESOURCE_DIRECTORY)(RvaToFoa(pResDir->VirtualAddress, szFileBuffer) + szFileBuffer);DWORD dwFirstNum = pFirst->NumberOfIdEntries + pFirst->NumberOfNamedEntries;CHAR cRootNameEntries[MAX_PATH];sprintf(cRootNameEntries, "%04x", pFirst->NumberOfNamedEntries);RootNameEntries = cRootNameEntries;CHAR cRootIDEntries[MAX_PATH];sprintf(cRootIDEntries, "%04x", pFirst->NumberOfIdEntries);RootIDEntries = cRootIDEntries;UpdateData(FALSE);PIMAGE_RESOURCE_DIRECTORY_ENTRY pFirstEntry = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(pFirst + 1);HTREEITEM tFirstEntry;HTREEITEM tSecondEntry;HTREEITEM tResEntry;for (DWORD i = 0; i < dwFirstNum; i++){if (pFirstEntry[i].NameIsString != 1){if (pFirstEntry[i].Id < 0x11){tFirstEntry = m_ResTree.InsertItem(g_ResType[pFirstEntry[i].Id], TVI_ROOT, TVI_LAST);}else{				WCHAR wcFirstEntryID[MAX_PATH];wsprintf(wcFirstEntryID, L"%d", pFirstEntry[i].Id);tFirstEntry = m_ResTree.InsertItem(wcFirstEntryID, TVI_ROOT, TVI_LAST);}			}else{PIMAGE_RESOURCE_DIR_STRING_U pFirstEntryName = (PIMAGE_RESOURCE_DIR_STRING_U)(pFirstEntry[i].NameOffset + (DWORD)pFirst);WCHAR wcFirstEntryName[MAX_PATH];memset(wcFirstEntryName, 0, MAX_PATH);memcpy(wcFirstEntryName, pFirstEntryName->NameString, pFirstEntryName->Length * 2);tFirstEntry = m_ResTree.InsertItem(wcFirstEntryName, TVI_ROOT, TVI_LAST);}if (pFirstEntry[i].DataIsDirectory == 1){PIMAGE_RESOURCE_DIRECTORY pSecond = (PIMAGE_RESOURCE_DIRECTORY)(pFirstEntry[i].OffsetToDirectory + (DWORD)pFirst);DWORD dwSecondNum = pSecond->NumberOfIdEntries + pSecond->NumberOfNamedEntries;for (DWORD i = 0; i < dwSecondNum; i++){PIMAGE_RESOURCE_DIRECTORY_ENTRY pSecondEntry = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(pSecond + 1);if (pSecondEntry[i].NameIsString != 1){WCHAR wcSecondEntryID[MAX_PATH];wsprintf(wcSecondEntryID, L"%d", pSecondEntry[i].Id);tSecondEntry = m_ResTree.InsertItem(wcSecondEntryID, tFirstEntry, TVI_LAST);}else{PIMAGE_RESOURCE_DIR_STRING_U pSecondEntryName = (PIMAGE_RESOURCE_DIR_STRING_U)(pSecondEntry[i].NameOffset + (DWORD)pFirst);WCHAR wcFirstEntryName[MAX_PATH];memset(wcFirstEntryName, 0, MAX_PATH);memcpy(wcFirstEntryName, pSecondEntryName->NameString, pSecondEntryName->Length * 2);tSecondEntry = m_ResTree.InsertItem(wcFirstEntryName, tFirstEntry, TVI_LAST);}if (pSecondEntry[i].DataIsDirectory == 1){PIMAGE_RESOURCE_DIRECTORY pThird = (PIMAGE_RESOURCE_DIRECTORY)(pSecondEntry[i].OffsetToDirectory + (DWORD)pFirst);PIMAGE_RESOURCE_DIRECTORY_ENTRY pThirdEntry = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(pThird + 1);if (pThirdEntry->DataIsDirectory == 1){PIMAGE_RESOURCE_DATA_ENTRY pResDateEntry = (PIMAGE_RESOURCE_DATA_ENTRY)((DWORD)pFirst + pThirdEntry->OffsetToDirectory);}}}}}
}

由于本人能力有限,并不能全部实现功能,望诸位基于本人相关意见
 

http://www.dtcms.com/wzjs/791157.html

相关文章:

  • 做网上竞猜网站合法吗网页设计制作网站代码html
  • 网站优化成功案例wordpress插件 速度
  • 网站集约化建设情况的汇报做网站需要什么步骤
  • 网站教育机构排行前十名海口seo外包
  • 安徽合肥建设厅网站做网站的商标是哪类
  • 枣庄手机网站建设电话上海财务公司
  • 彩票网站开发亿云wordpress主题授权方式
  • 培训学校网站做网站流量是什么
  • 2021能打开的网站免费wordpress做一个网站404引导
  • 有帮忙做儿童房设计的网站吗南通南通网站优化
  • 有前景的网站建设辽宁建设信息网站
  • 怎样通过手机建网站叶县建设局网站
  • 如何看到网站的建设时间国外服务器需要备案吗
  • 做网站需要融资机械设计制造及其自动化圳建设网站
  • 西安汇友网站建设淘宝官方网
  • 站优云网络公司网络服务器配置与管理
  • 网站后台域名解析怎么做宁波seo网络推广选哪家
  • 网站建设摊销年限最新规定北京微信公众号定制开发
  • 凯里网站设计哪家好湖北黄石域名注册网站建设
  • 桥头镇做网站科技网站哪个好
  • 网站没收录可以做推广吗百度商桥怎么和网站
  • 通信建设网站档案网站的建设方案
  • wordpress 商业网站附近电商培训班
  • 广东东莞网站建设邯郸公司起名
  • 免费建站系统有哪些wordpress编辑插件
  • 淘宝网站建设单子好接吗广州手机网站案例
  • 2022年没封网站直接进入wordpress年会员
  • 网站开发哪家公司好建立网站用英语
  • 惠州网站建设英语文山微网站建设
  • 深圳官网建站服务商郑州手机网站推广公司