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

同域名网站改版需要把之前网站里的文章都拷贝过来吗?我国档案网站建设

同域名网站改版需要把之前网站里的文章都拷贝过来吗?,我国档案网站建设,物流信息平台,图跃企业网站建设本节我们将通过两个示例程序#xff0c;演示对PE文件内图标资源的置换与提取。 本节必须掌握的知识点#xff1a; 更改图标 提取图标资源 7.4.1 更改图标 让我们来做一个实验#xff0c;替换PE文件中现有的图标。如果手工替换#xff0c;一定是先找到资源表#xff0c;…本节我们将通过两个示例程序演示对PE文件内图标资源的置换与提取。 本节必须掌握的知识点 更改图标 提取图标资源 7.4.1 更改图标 让我们来做一个实验替换PE文件中现有的图标。如果手工替换一定是先找到资源表然后分别替换图标资源和图标组资源就可以了。当然这个过程稍微有点繁复可能会涉及到其他资源的重定位。还好Windows操作系统为开发者提供了一组更新PE文件中资源的API函数BeginUpdateResource、UpdateResource、EndUpdateResource。用来枚举 PE 文件中资源的函数有EnumResourceTypes、EnumResourceNames、EnumResourceLanguages。具体的使用方法可以参见MSDN下面我们将使用这些函数实现图标资源的替换。 实验五十更改图标 ●模块1resource.h略 ●模块2peinfo.rc略 ●模块3info.h #pragma once #ifndef INFO_H_ #define INFO_H_#include windows.h #include richedit.h //CHARFORMAT富文本结构定义 #include commctrl.h //通用控件 #pragma comment(lib,comctl32.lib) #include strsafe.h //StringCchCopy #include stdlib.h// 文件中的ICO头部 typedef struct {byte bWidth; //宽度byte bHeight; //高度byte bColorCount; //颜色数byte bReserved; //保留字必须为0WORD wPlanes; //调色板WORD wBitCount; //每个像素的位数DWORD dwBytesInRes; //资源长度DWORD dwImageOffset; //资源在文件偏移 }ICON_DIR_ENTRY;typedef struct {WORD idReserved; //保留字必须为0WORD idType; //资源类别如果是1表示为ICO文件WORD idCount; //图标数量//ICON_DIR_ENTRY idEntries; //图标项一个图标一项 }ICON_DIR;//PE中ICO头部 typedef struct {byte bWidth; //宽度byte bHeight; //高度byte bColorCount; //颜色数byte bReserved; //保留字必须为0WORD wPlanes; //调色板WORD wBitCount; //每个像素的位数DWORD dwBytesInRes; //资源长度WORD nID; //资源在文件序号 }PE_ICON_DIR_ENTRY; typedef struct {WORD idReserved; //保留字必须为0WORD idType; //资源类别如果是1表示为ICO文件WORD idCount; //图标数量PE_ICON_DIR_ENTRY idEntries; //图标项一个图标一项 }PE_ICON_DIR;//函数声明 BOOL CALLBACK DlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); void Exception(void); void init(); //初始化 void _OpenFile();//打开PE文件并处理 int CALLBACK _Handler(EXCEPTION_POINTERS * lpExceptionPoint); void ShowErrMsg(); void _AppendInfo(const TCHAR * _lpsz);//往文本框中追加文本 //将boy.ico图标替换指定PE程序的图标 BOOL _doUpdate(TCHAR* lpszFile, TCHAR* lpszExeFile);#endif●模块4PEUpdateIcon.c /*------------------------------------------------------------------------FileName: PEUpdateIcon.c实验50更改程序图标实例支持32位和64位PE文件(c) bcdaren, 2024 -----------------------------------------------------------------------*/ #include strsafe.h //StringCchCopy #include resource.h #include info.hHANDLE hInstance; HWND hWinMain, hWinEdit; HMODULE hRichEdit; TCHAR szFileName[MAX_PATH]; HANDLE hFileDump; HANDLE hFile;int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int nCmdShow) {TCHAR szDllEdit[] TEXT(RichEd20.dll);TCHAR szClassEdit[] TEXT(RichEdit20W);//peinfo.rc中定义hRichEdit LoadLibrary((LPCWSTR)szDllEdit);hInstance GetModuleHandle(NULL);DialogBoxParam(hInstance, MAKEINTRESOURCE(DLG_MAIN), NULL, (DLGPROC)DlgProc, (LPARAM)0);FreeLibrary(hRichEdit);return 0; }//初始化窗口函数 void init() {CHARFORMAT stCf;TCHAR szClassEdit[] TEXT(RichEdit20A);TCHAR szFont[] TEXT(宋体);HINSTANCE hInstance;hWinEdit GetDlgItem(hWinMain, IDC_INFO);//为窗口程序设置图标hInstance GetModuleHandle(NULL);HICON hIcon LoadIcon(hInstance, MAKEINTRESOURCE(ICO_MAIN));//HICON hIcon LoadIcon(hInstance, TEXT(#111));SendMessage(hWinMain, WM_SETICON, ICON_BIG, (LPARAM)hIcon);//设置编辑控件SendMessage(hWinEdit, EM_SETTEXTMODE, TM_PLAINTEXT, 0);RtlZeroMemory(stCf, sizeof(stCf));stCf.cbSize sizeof(stCf);stCf.yHeight 9 * 20;stCf.dwMask CFM_FACE | CFM_SIZE | CFM_BOLD;StringCchCopy((LPTSTR)stCf.szFaceName, lstrlen(szFont) 1, (LPCTSTR)szFont);SendMessage(hWinEdit, EM_SETCHARFORMAT, 0, (LPARAM)stCf);SendMessage(hWinEdit, EM_EXLIMITTEXT, 0, -1);//设为-1表示无限制 }//富文本窗口回调函数 BOOL CALLBACK DlgProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam) {const TCHAR szErr[] TEXT(文件格式错误);const TCHAR szErrFormat[] TEXT(这个文件不是PE格式的文件!);switch (wMsg){case WM_CLOSE:EndDialog(hWnd, 0);return TRUE;case WM_INITDIALOG:hWinMain hWnd;init(); //初始化return TRUE;case WM_COMMAND:switch (wParam){case IDM_EXIT:EndDialog(hWnd, 0);return TRUE;case IDM_OPEN:_OpenFile();return TRUE;case IDM_1:MessageBox(NULL, szErrFormat, szErr, MB_ICONWARNING);return TRUE;case IDM_2:MessageBox(NULL, szErrFormat, szErr, MB_ICONWARNING);return TRUE;case IDM_3:MessageBox(NULL, szErrFormat, szErr, MB_ICONWARNING);return TRUE;}}return FALSE; }//执行比对PE文件 void _OpenFile() {OPENFILENAME stOF;HANDLE hFile NULL;HANDLE hMapFile NULL;PBYTE lpMemory NULL; //PE文件内存映射文件地址int dwFileSize;const TCHAR szDefaultExt[] TEXT(exe);const TCHAR szFilter[] TEXT(PE Files (*.exe)\0*.exe\0)\TEXT(DLL Files(*.dll)\0*.dll\0)\TEXT(SCR Files(*.scr)\0*.scr\0)\TEXT(FON Files(*.fon)\0*.fon\0)\TEXT(DRV Files(*.drv)\0*.drv\0)\TEXT(All Files(*.*)\0*.*\0\0);const TCHAR szErr[] TEXT(文件格式错误);const TCHAR szErrFormat[] TEXT(操作文件时出现错误);const TCHAR szOut1[] TEXT(----------------------------------------------------------------\r\n)TEXT(待处理的PE文件%s\r\n);static TCHAR lpszBoyIcon[] TEXT(D:\\code\\winpe\\ch07\\PEUpdateIcon\\boy.ico);const TCHAR szFailure[] TEXT(执行图标修改失败。);const TCHAR szSuccess[] TEXT(恭喜你图标修改成功成功的。);IMAGE_DOS_HEADER *lpstDOS; //DOS块地址IMAGE_NT_HEADERS *lpstNT; //PE文件头地址//显示打开文件对话框RtlZeroMemory(stOF, sizeof(stOF));stOF.lStructSize sizeof(stOF);stOF.hwndOwner hWinMain;stOF.lpstrFilter szFilter;stOF.lpstrFile szFileName;stOF.nMaxFile MAX_PATH;stOF.Flags OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST;stOF.lpstrDefExt szDefaultExt;if (!GetOpenFileName(stOF))return;//打开PE文件hFile CreateFile(szFileName, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,OPEN_EXISTING, FILE_ATTRIBUTE_ARCHIVE, NULL);if (hFile INVALID_HANDLE_VALUE)MessageBox(NULL, TEXT(打开文件失败), NULL, MB_ICONWARNING);else{//获取文件大小dwFileSize GetFileSize(hFile, NULL);//创建内存映射文件if (dwFileSize){if (hMapFile CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL)){//获得文件在内存的映象起始位置lpMemory MapViewOfFile(hMapFile, FILE_MAP_READ, 0, 0, 0);//异常处理方法2if (!lpMemory){atexit(Exception);goto _ErrFormat;exit(EXIT_FAILURE);}//检查PE文件是否有效lpstDOS (IMAGE_DOS_HEADER *)lpMemory;if (lpstDOS-e_magic ! IMAGE_DOS_SIGNATURE){//如果非PE文件-异常处理atexit(Exception);goto _ErrFormat;exit(EXIT_FAILURE);}lpstNT (IMAGE_NT_HEADERS *)(lpMemory lpstDOS-e_lfanew);if (lpstNT-Signature ! IMAGE_NT_SIGNATURE){//如果非PE文件-异常处理atexit(Exception);goto _ErrFormat;exit(EXIT_FAILURE);}//将boy.ico的图标数据写入PE文件if (_doUpdate(lpszBoyIcon, szFileName))_AppendInfo(szSuccess);else_AppendInfo(szFailure);goto _ErrorExit;_ErrFormat:MessageBox(hWinMain, szErrFormat, NULL, MB_OK);_ErrorExit:if (lpMemory)UnmapViewOfFile(lpMemory);}if (hMapFile)CloseHandle(hMapFile);}if (hFile)CloseHandle(hFile);}return; }//RITCH控件添加文本信息--以 null 结尾的字符串 void _AppendInfo(const TCHAR * _lpsz) {CHARRANGE stCR;//检索文本控件内文本的长度stCR.cpMin GetWindowTextLength(hWinEdit);stCR.cpMax stCR.cpMin;//择并替换文本控件的选定内容SendMessage(hWinEdit, EM_EXSETSEL, 0, (LPARAM)stCR);//EM_REPLACESEL以 null 结尾的字符串的指针替换SendMessage(hWinEdit, EM_REPLACESEL, FALSE, (LPARAM)_lpsz); }//异常处理 void Exception(void) {MessageBox(hWinMain, TEXT(获得文件在内存的映象起始位置失败!), NULL, MB_OK); }/* ;----------------------------------- ;将boy.ico图标替换指定PE程序的图标 ;使用win32 api函数UpdateResource实现此功能 ;----------------------------------- */ BOOL _doUpdate(TCHAR* lpszFile, TCHAR* lpszExeFile) {ICON_DIR stID;ICON_DIR_ENTRY stIDE;PE_ICON_DIR stGID;HANDLE hFile, hUpdate;DWORD dwReserved, nSize, nGSize;BOOL flag FALSE;LPVOID pIcon, pGrpIcon;hFile CreateFile(lpszFile,GENERIC_READ,0,NULL,OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,NULL);if (hFile INVALID_HANDLE_VALUE)return 0;RtlZeroMemory(stID,sizeof(stID));ReadFile(hFile,stID,sizeof(stID),dwReserved,NULL);RtlZeroMemory(stIDE, sizeof(stIDE));ReadFile(hFile, stIDE, sizeof(stIDE), dwReserved, NULL);nSize stIDE.dwBytesInRes;pIcon GlobalAlloc(GPTR, nSize);SetFilePointer(hFile, stIDE.dwImageOffset, NULL, FILE_BEGIN);if (!ReadFile(hFile, pIcon, nSize, dwReserved, NULL))goto _ret;RtlZeroMemory(stGID,sizeof(stGID));stGID.idCount stID.idCount;stGID.idReserved 0;stGID.idType 1;RtlMoveMemory(stGID.idEntries,stIDE,12);stGID.idEntries.nID 0;nGSize sizeof(stGID);pGrpIcon GlobalAlloc(GPTR, nGSize);RtlMoveMemory(pGrpIcon,stGID,nGSize);//开始修改hUpdate BeginUpdateResource(lpszExeFile,FALSE); //检索句柄,可使用该句柄在二进制模块中添加删除或替换资源UpdateResource(hUpdate,RT_GROUP_ICON,(LPCWSTR)1,LANG_CHINESE,pGrpIcon,nGSize);flag UpdateResource(hUpdate,RT_ICON, (LPCWSTR)1,LANG_CHINESE,pIcon,nSize);EndUpdateResource(hUpdate,FALSE);if (flag FALSE)MessageBox(NULL, L替换资源失败, NULL, MB_OK);elsegoto over; _ret:GlobalFree(pIcon);CloseHandle(hFile);return flag; over:CloseHandle(hFile);return flag; } 运行 图7-7 替换图标 总结 上述示例选择打开一个PE文件然后_doUpdate函数实现图标资源的替换。具体实现步骤如下 1首先调用CreateFile函数打开boy.ico图标文件。 2然后调用ReadFile函数分别将图标文件的头部信息和图标项读取到缓冲区中。 3接着分配一个和图标资源大小一样的内存空间并将整个图标文件读取到该内存中。 4然后再将初始化后的PE_ICON_DIR结构变量stGID复制到一个新分配的内存块中。 5最后调用一组资源替换的API函数BeginUpdateResource、UpdateResource和EndUpdateResource完成替换。 7.4.2 提取图标资源 一个ICO文件由三大部分组成第一部分是图标头第二部分是图标项第三部分为图标数据。PE资源表中第一部分和第二部分组合成图标组资源第三部分的每个图标数据对应一个图标资源。接下来我们给出一个提取图标的示例程序。 实验五十一提取图标资源 ●模块1resource.h略 ●模块2peinfo.rc略 ●模块3info.h #pragma once #ifndef INFO_H_ #define INFO_H_#include windows.h #include richedit.h //CHARFORMAT富文本结构定义 #include commctrl.h //通用控件 #pragma comment(lib,comctl32.lib) #include strsafe.h //StringCchCopy #include stdlib.h//函数声明 BOOL CALLBACK DlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); //void Exception(void); void init(); //初始化 void _OpenFile();//打开PE文件并处理 DWORD RVAToOffset(IMAGE_DOS_HEADER * lpFileHead, DWORD dwRVA);// 将内存偏移量RVA转换为文件偏移 DWORD GetRVASection(IMAGE_DOS_HEADER * lpFileHead, DWORD dwRVA);//查找 RVA 所在的节区 int CALLBACK _Handler(EXCEPTION_POINTERS * lpExceptionPoint); //void ShowErrMsg(); void _AppendInfo(const TCHAR * _lpsz);//往文本框中追加文本 //PE文件处理模块 void _getResource(PBYTE, IMAGE_NT_HEADERS *, int);//获取PE文件的资源信息 void ProcessRes(PBYTE lpFile, PBYTE lpRes, IMAGE_RESOURCE_DIRECTORY * lpResDir, DWORD dwLevel); void _getIcoData(PBYTE lpFile, PBYTE lpRes, DWORD number, DWORD off, DWORD size);//处理单个ICO文件 int _getFinnalData(PBYTE lpFile, PBYTE lpRes, DWORD number);//将图标数据写入文件 #endif●模块4RvaToFileOffset.c略 ●模块5PEDumpIcon.c /*------------------------------------------------------------------------FileName:PEDumpIcon.c实验51提取程序图标实例支持32位和64位PE文件(c) bcdaren, 2024 -----------------------------------------------------------------------*/ #include strsafe.h //StringCchCopy #include resource.h #include info.hHANDLE hInstance; HWND hWinMain, hWinEdit; HMODULE hRichEdit; TCHAR szFileName[MAX_PATH]; HANDLE hFileDump; HANDLE hFile;int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int nCmdShow) {TCHAR szDllEdit[] TEXT(RichEd20.dll);TCHAR szClassEdit[] TEXT(RichEdit20W);//peinfo.rc中定义hRichEdit LoadLibrary((LPCWSTR)szDllEdit);hInstance GetModuleHandle(NULL);DialogBoxParam(hInstance, MAKEINTRESOURCE(DLG_MAIN), NULL, (DLGPROC)DlgProc, (LPARAM)0);FreeLibrary(hRichEdit);return 0; }//初始化窗口函数 void init() {CHARFORMAT stCf;TCHAR szClassEdit[] TEXT(RichEdit20A);TCHAR szFont[] TEXT(宋体);HINSTANCE hInstance;hWinEdit GetDlgItem(hWinMain, IDC_INFO);//为窗口程序设置图标hInstance GetModuleHandle(NULL);HICON hIcon LoadIcon(hInstance, MAKEINTRESOURCE(ICO_MAIN));//HICON hIcon LoadIcon(hInstance, TEXT(#111));SendMessage(hWinMain, WM_SETICON, ICON_BIG, (LPARAM)hIcon);//设置编辑控件SendMessage(hWinEdit, EM_SETTEXTMODE, TM_PLAINTEXT, 0);RtlZeroMemory(stCf, sizeof(stCf));stCf.cbSize sizeof(stCf);stCf.yHeight 9 * 20;stCf.dwMask CFM_FACE | CFM_SIZE | CFM_BOLD;StringCchCopy((LPTSTR)stCf.szFaceName, lstrlen(szFont) 1, (LPCTSTR)szFont);SendMessage(hWinEdit, EM_SETCHARFORMAT, 0, (LPARAM)stCf);SendMessage(hWinEdit, EM_EXLIMITTEXT, 0, -1);//设为-1表示无限制 }//富文本窗口回调函数 BOOL CALLBACK DlgProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam) {const TCHAR szErr[] TEXT(文件格式错误);const TCHAR szErrFormat[] TEXT(这个文件不是PE格式的文件!);switch (wMsg){case WM_CLOSE:EndDialog(hWnd, 0);return TRUE;case WM_INITDIALOG:hWinMain hWnd;init(); //初始化return TRUE;case WM_COMMAND:switch (wParam){case IDM_EXIT:EndDialog(hWnd, 0);return TRUE;case IDM_OPEN:_OpenFile();return TRUE;case IDM_1:MessageBox(NULL, szErrFormat, szErr, MB_ICONWARNING);return TRUE;case IDM_2:MessageBox(NULL, szErrFormat, szErr, MB_ICONWARNING);return TRUE;case IDM_3:MessageBox(NULL, szErrFormat, szErr, MB_ICONWARNING);return TRUE;}}return FALSE; }//执行比对PE文件 void _OpenFile() {OPENFILENAME stOF;HANDLE hFile NULL;HANDLE hMapFile NULL;PBYTE lpMemory NULL; //PE文件内存映射文件地址int dwFileSize;const TCHAR szDefaultExt[] TEXT(exe);const TCHAR szFilter[] TEXT(PE Files (*.exe)\0*.exe\0)\TEXT(DLL Files(*.dll)\0*.dll\0)\TEXT(SCR Files(*.scr)\0*.scr\0)\TEXT(FON Files(*.fon)\0*.fon\0)\TEXT(DRV Files(*.drv)\0*.drv\0)\TEXT(All Files(*.*)\0*.*\0\0);const TCHAR szErr[] TEXT(文件格式错误);const TCHAR szErrFormat[] TEXT(操作文件时出现错误);const TCHAR szOut1[] TEXT(----------------------------------------------------------------\r\n)TEXT(待处理的PE文件%s\r\n);static TCHAR szBuffer[256];IMAGE_DOS_HEADER *lpstDOS; //DOS块地址IMAGE_NT_HEADERS *lpstNT; //PE文件头地址//显示打开文件对话框RtlZeroMemory(stOF, sizeof(stOF));stOF.lStructSize sizeof(stOF);stOF.hwndOwner hWinMain;stOF.lpstrFilter szFilter;stOF.lpstrFile szFileName;stOF.nMaxFile MAX_PATH;stOF.Flags OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST;stOF.lpstrDefExt szDefaultExt;if (!GetOpenFileName(stOF))return;//打开PE文件hFile CreateFile(szFileName, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,OPEN_EXISTING, FILE_ATTRIBUTE_ARCHIVE, NULL);if (hFile INVALID_HANDLE_VALUE)MessageBox(NULL, TEXT(打开文件失败), NULL, MB_ICONWARNING);else{//获取文件大小dwFileSize GetFileSize(hFile, NULL);//创建内存映射文件if (dwFileSize){if (hMapFile CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL)){//获得文件在内存的映象起始位置lpMemory MapViewOfFile(hMapFile, FILE_MAP_READ, 0, 0, 0);//异常处理方法2if (!lpMemory){MessageBox(hWinMain, szErrFormat, NULL, MB_OK);}//检查PE文件是否有效lpstDOS (IMAGE_DOS_HEADER *)lpMemory;if (lpstDOS-e_magic ! IMAGE_DOS_SIGNATURE){//如果非PE文件-异常处理MessageBox(hWinMain, szErrFormat, NULL, MB_OK);}lpstNT (IMAGE_NT_HEADERS *)(lpMemory lpstDOS-e_lfanew);if (lpstNT-Signature ! IMAGE_NT_SIGNATURE){MessageBox(hWinMain, szErrFormat, NULL, MB_OK);}//到此为止该文件的验证已经完成。为PE结构文件wsprintf(szBuffer, szOut1, szFileName);_AppendInfo(szBuffer);//显示资源信息_getResource(lpMemory, lpstNT, dwFileSize);if (lpMemory)UnmapViewOfFile(lpMemory);}if (hMapFile)CloseHandle(hMapFile);}if (hFile)CloseHandle(hFile);}return; }//RITCH控件添加文本信息--以 null 结尾的字符串 void _AppendInfo(const TCHAR * _lpsz) {CHARRANGE stCR;//检索文本控件内文本的长度stCR.cpMin GetWindowTextLength(hWinEdit);stCR.cpMax stCR.cpMin;//择并替换文本控件的选定内容SendMessage(hWinEdit, EM_EXSETSEL, 0, (LPARAM)stCR);//EM_REPLACESEL以 null 结尾的字符串的指针替换SendMessage(hWinEdit, EM_REPLACESEL, FALSE, (LPARAM)_lpsz); }●模块6GetResource.c /* ;遍历资源表项的图标组资源 ;_lpFile文件地址 ;_lpRes资源表地址 */ #include windows.h #include info.hextern TCHAR szFileName[MAX_PATH]; //pemian.c模块中定义 extern HANDLE hWinEdit,hFileDump; extern HWND hWinMain;void _AppendInfo(const TCHAR * _lpsz); DWORD RVAToOffset(IMAGE_DOS_HEADER * lpFileHead, DWORD dwRVA); DWORD GetRVASection(IMAGE_DOS_HEADER * lpFileHead, DWORD dwRVA);//遍历资源表项的图标组资源:参数1PE文件地址参数2资源块起始地址 void ProcessRes(PBYTE lpFile, PBYTE lpRes, IMAGE_RESOURCE_DIRECTORY * lpResDir, DWORD dwLevel) {const TCHAR szOut10[] TEXT(资源表中有图标组%d个。\r\n)TEXT(----------------------------------------------------------------\r\n\r\n);const TCHAR szLevel3[] TEXT(图标组%4d所在文件位置0x%08x 资源长度%d\r\n);const TCHAR szNoIconArray[] TEXT(资源表中没有发现图标组);static TCHAR szBuffer[1024];static TCHAR szResName[256];IMAGE_RESOURCE_DIRECTORY * lpstRES_DIR;//资源目录IMAGE_RESOURCE_DIRECTORY_ENTRY * lpstRES_DIR_ENT;//目录项IMAGE_RESOURCE_DATA_ENTRY * lpstRES_DATA_ENT;int number; //资源数量DWORD dwNextLevel;DWORD lpAddr, lpAddr2;DWORD IDname, dwTemp1, dwTemp2, dwTemp3;DWORD dwICO 0 ; //ICO文件的个数dwNextLevel dwLevel 1;//检查资源目录表得到资源目录项的数量lpstRES_DIR lpResDir;number lpstRES_DIR-NumberOfIdEntries lpstRES_DIR-NumberOfNamedEntries; //IMAGE_RESOURCE_DIRECTORY结构后面紧跟着是IMAGE_RESOURCE_DIRECTORY_ENTRY结构lpstRES_DIR_ENT (IMAGE_RESOURCE_DIRECTORY_ENTRY *)((PBYTE)lpstRES_DIR sizeof(IMAGE_RESOURCE_DIRECTORY));//循环处理每个资源目录项while (number--){RtlZeroMemory(szBuffer, sizeof(szBuffer));//OffsetToData字段最高位为1后七位指向下层目录块的起始地址IMAGE_RESOURCE_DIRECTORY结构lpAddr lpstRES_DIR_ENT-OffsetToData;if (lpAddr 0x80000000){lpAddr 0x7fffffff;lpAddr (DWORD)lpRes;//第一层资源类型IDname lpstRES_DIR_ENT-Name;//目录项名称字符串或ID//最高位为1时低7位值作为指向UNICODE编码的资源名IAMGE_RESOURCE_STRING_U结构//如果是按名称定义的资源类型跳过 if (IDname 0x80000000){goto _next;}//高位为0时表示字段的值作为ID使用else{if (IDname 0x0e) //判断编号是否为图标组{//移动到第二级目录//计算目录项的个数lpstRES_DIR (IMAGE_RESOURCE_DIRECTORY*)lpAddr;dwICO lpstRES_DIR-NumberOfNamedEntries lpstRES_DIR-NumberOfIdEntries;wsprintf(szBuffer, szOut10, dwICO);_AppendInfo(szBuffer);//跳过第二级目录头定位到第二级目录项lpAddr2 lpAddr sizeof(IMAGE_RESOURCE_DIRECTORY);dwTemp1 0;while (dwICO--){lpstRES_DIR_ENT (IMAGE_RESOURCE_DIRECTORY_ENTRY*)lpAddr2;//直接访问到数据获取数据在文件的偏移及大小dwTemp1;lpAddr lpstRES_DIR_ENT-OffsetToData;if (lpAddr 0x80000000){lpAddr 0x7fffffff; //最高位为1lpAddr (DWORD)lpRes; //第三级lpstRES_DIR (IMAGE_RESOURCE_DIRECTORY*)lpAddr;//移动到第三级目录假设目录项数量都为1lpAddr sizeof(IMAGE_RESOURCE_DIRECTORY);lpstRES_DIR_ENT (IMAGE_RESOURCE_DIRECTORY_ENTRY*)lpAddr;//地址指向数据项lpAddr lpstRES_DIR_ENT-OffsetToData (DWORD)lpRes;lpstRES_DATA_ENT (IMAGE_RESOURCE_DATA_ENTRY*)lpAddr;dwTemp3 lpstRES_DATA_ENT-Size;dwTemp2 RVAToOffset((IMAGE_DOS_HEADER *)lpFile, lpstRES_DATA_ENT-OffsetToData);wsprintf(szBuffer, szLevel3, dwTemp1, dwTemp2,dwTemp3);_AppendInfo(szBuffer);//处理单个ICO文件,参数1文件开始,参数2资源表开始//参数3PE ICO头开始,参数4编号,参数5PE ICO头大小_getIcoData(lpFile, lpRes, dwTemp1, dwTemp2, dwTemp3);}lpAddr2 sizeof(IMAGE_RESOURCE_DIRECTORY_ENTRY);}goto _next;}elsegoto _next;}}_next:lpstRES_DIR_ENT;}if (dwICO 0)_AppendInfo(szNoIconArray); } //获取PE文件的资源信息 void _getResource(PBYTE lpFile, IMAGE_NT_HEADERS * _lpPeHead, int _dwSize) {const TCHAR szNoResource[] TEXT(\r\n未发现资源表!);static TCHAR szBuffer[256];static TCHAR szSectionName[16];static TCHAR szNameB[256];static TCHAR szNameW[256];IMAGE_NT_HEADERS32 * lpstNT32; //PE32文件头IMAGE_NT_HEADERS64 * lpstNT64; //PE64文件头IMAGE_RESOURCE_DIRECTORY * lpstRES_DIR;//资源目录DWORD rva, address;lpstNT32 _lpPeHead;lpstNT64 (IMAGE_NT_HEADERS64 *)_lpPeHead;//检测是否存在资源--数据目录第2项if (lpstNT64-OptionalHeader.Magic 0x020B) //64位PE文件{//数据目录项的第3项rva lpstNT64-OptionalHeader.DataDirectory[2].VirtualAddress; }elserva lpstNT32-OptionalHeader.DataDirectory[2].VirtualAddress;if (!rva){_AppendInfo(szNoResource);return;}//求资源表在文件的偏移address RVAToOffset((IMAGE_DOS_HEADER *)lpFile, rva);if (!address)return; //资源目录的实际地址lpstRES_DIR (IMAGE_RESOURCE_DIRECTORY *)(address (DWORD)lpFile); /*显示所有资源目录块的信息; 传入的两个参数分别表示; 1、文件头位置; 2、资源表位置*/ProcessRes(lpFile, (PBYTE)lpstRES_DIR, lpstRES_DIR, 1); }●模块7GetIconData.c /* ;通过PE ICO头获取ICO数据 ;参数1文件开始 ;参数2资源表开始 ;参数3PE ICO头开始 ;参数4编号由此构造磁盘文件名g12.ico ;参数5PE ICO头大小 */ #include windows.h #include info.hextern TCHAR szFileName[MAX_PATH]; //pemian.c模块中定义 extern HANDLE hFile; extern HWND hWinMain;// 文件中的ICO头部 typedef struct {byte bWidth ; //宽度byte bHeight ; //高度byte bColorCount ; //颜色数byte bReserved ; //保留字必须为0WORD wPlanes ; //调色板WORD wBitCount ; //每个像素的位数DWORD dwBytesInRes ; //资源长度DWORD dwImageOffset ; //资源在文件偏移 }ICON_DIR_ENTRY;//PE中ICO头部 typedef struct {byte bWidth; //宽度byte bHeight; //高度byte bColorCount; //颜色数byte bReserved; //保留字必须为0WORD wPlanes; //调色板WORD wBitCount; //每个像素的位数DWORD dwBytesInRes; //资源长度WORD dwImageOffset; //资源在文件偏移 }PE_ICON_DIR_ENTRY;//处理单个ICO文件 void _getIcoData(PBYTE lpFile, PBYTE lpRes, DWORD number, DWORD off, DWORD size) {const TCHAR szFile[] TEXT( 新建文件%s\r\n);const TCHAR szOut11[] TEXT(g%d.ico);const TCHAR szOut13[] TEXT( 图标组%4d中共有图标%d个。\r\n);const TCHAR szICOHeader[] TEXT( 完成ICO头部信息 \r\n);TCHAR szFileName1[MAX_PATH];static TCHAR szBuffer[256];DWORD dwTemp, dwCount, dwTemp1;DWORD dwForward,lpMemory;DWORD dwIcoDataSize; //图标数据的大小PE_ICON_DIR_ENTRY * lpPE_ICON_DIR_ENTRY;ICON_DIR_ENTRY lpIconDE;//PE_ICON_DIR_ENTRY lpPEIconDE;WORD order;DWORD lpAddr;wsprintf(szFileName1,szOut11,number);wsprintf(szBuffer,szFile,szFileName1);_AppendInfo(szBuffer);//将内存写入文件以供检查hFile CreateFile(szFileName1,GENERIC_WRITE,FILE_SHARE_READ,0,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0);//定位文件指针lpMemory (DWORD)lpFile off;//写入6个字节文件头WriteFile(hFile, (PBYTE)lpMemory, 6, dwTemp, NULL);//求出图标组包含图标的个数dwCount *(PWORD)((PBYTE)lpMemory 4);wsprintf(szBuffer,szOut13,number,dwCount);_AppendInfo(szBuffer);//求第一个图标数据在文件中的偏移dwForward dwCount * 2 size;//每一个记录多2个字节//定位到ICO图标项起始lpPE_ICON_DIR_ENTRY (PE_ICON_DIR_ENTRY *)((PBYTE)lpMemory 6);dwIcoDataSize 0;dwTemp1 dwCount;while (dwTemp1--){//将PE_ICON_DIR_ENTRY结构中的大部分字段赋值除最后一个字段外lpIconDE.bWidth lpPE_ICON_DIR_ENTRY-bWidth;lpIconDE.bHeight lpPE_ICON_DIR_ENTRY-bHeight;lpIconDE.bColorCount lpPE_ICON_DIR_ENTRY-bColorCount;lpIconDE.bReserved lpPE_ICON_DIR_ENTRY-bReserved;lpIconDE.wPlanes lpPE_ICON_DIR_ENTRY-wPlanes;lpIconDE.wBitCount lpPE_ICON_DIR_ENTRY-wBitCount;lpIconDE.dwBytesInRes lpPE_ICON_DIR_ENTRY-dwBytesInRes;//该值需要修正记录图标数据在文件偏移。//第一个图标的该值是文件ICO头大小//以后的图标的该值是上一个加上数据长度lpIconDE.dwImageOffset dwForward dwIcoDataSize;WriteFile(hFile, lpIconDE, sizeof(ICON_DIR_ENTRY),dwTemp,NULL);//为下一次计算地址做准备dwIcoDataSize lpPE_ICON_DIR_ENTRY-dwBytesInRes;lpPE_ICON_DIR_ENTRY;}//该循环结束所有的头部信息已经完毕_AppendInfo(szICOHeader);//开始下一个循环将所有图标数据写入文件lpAddr (DWORD)lpMemory 6;dwTemp1 dwCount;while (dwTemp1--){lpPE_ICON_DIR_ENTRY (PE_ICON_DIR_ENTRY *)lpAddr;//写入文件图标数据order lpPE_ICON_DIR_ENTRY-dwImageOffset;//取得图标的顺号//返回eax为图标数据大小_getFinnalData(lpFile, lpRes, order);//lpAddr sizeof(PE_ICON_DIR_ENTRY);//16个字节--错误lpAddr 14;}CloseHandle(hFile); } //将图标数据写入文件 /* ;参数lpFile 文件内存起始地址 ;参数: lpRes 资源表起始地址 ;参数nubmer为图标顺号 */ int _getFinnalData(PBYTE lpFile, PBYTE lpRes, DWORD number) {static TCHAR szBuffer[1024];static TCHAR szResName[256];DWORD lpMem, dwTemp,dwTemp1, dwTemp2, dwTemp3;DWORD dwICO 0; //ICO文件的个数int count 0; //图标数据大小int counter; //资源数量DWORD lpAddr, IDname;IMAGE_RESOURCE_DIRECTORY * lpstRES_DIR;//资源目录IMAGE_RESOURCE_DIRECTORY_ENTRY * lpstRES_DIR_ENT;//目录项IMAGE_RESOURCE_DATA_ENTRY * lpstRES_DATA_ENT;const TCHAR szLevel31[] TEXT( 图标%4d所在文件位置0x%08x 资源长度%d\r\n);const TCHAR szFinished[] TEXT( 完成写入。\r\n\r\n);const TCHAR szNoIconArray[] TEXT(资源表中没有发现图标组);//计算目录项的个数lpstRES_DIR (IMAGE_RESOURCE_DIRECTORY *)lpRes;counter lpstRES_DIR-NumberOfIdEntries lpstRES_DIR-NumberOfNamedEntries; //IMAGE_RESOURCE_DIRECTORY结构后面紧跟着是IMAGE_RESOURCE_DIRECTORY_ENTRY结构lpstRES_DIR_ENT (IMAGE_RESOURCE_DIRECTORY_ENTRY *)((PBYTE)lpstRES_DIR sizeof(IMAGE_RESOURCE_DIRECTORY));//循环处理每个资源目录项while (counter--){RtlZeroMemory(szBuffer, sizeof(szBuffer)); //OffsetToData字段最高位为1后七位指向下层目录块的起始地址IMAGE_RESOURCE_DIRECTORY结构lpAddr lpstRES_DIR_ENT-OffsetToData;if (lpAddr 0x80000000){lpAddr 0x7fffffff;lpAddr (DWORD)lpRes;//第一层资源类型IDname lpstRES_DIR_ENT-Name;//目录项名称字符串或ID //最高位为1时低7位值作为指向UNICODE编码的资源名IAMGE_RESOURCE_STRING_U结构//如果是按名称定义的资源类型跳过 if (IDname 0x80000000){goto _next;}//高位为0时表示按编号定义的资源类型else{//第一层指向了资源类别if (IDname 0x03) //判断编号是否为图标组{//移动到第二级目录//计算目录项的个数lpstRES_DIR (IMAGE_RESOURCE_DIRECTORY*)lpAddr;dwICO lpstRES_DIR-NumberOfNamedEntries lpstRES_DIR-NumberOfIdEntries;//跳过第二级目录头定位到第二级目录项lpAddr sizeof(IMAGE_RESOURCE_DIRECTORY);lpstRES_DIR_ENT (IMAGE_RESOURCE_DIRECTORY_ENTRY*)lpAddr;dwTemp1 0;while (dwICO--){//直接访问到数据获取数据在文件的偏移及大小dwTemp1;//判断序号是否和指定的一致if (dwTemp1 ! number)goto _loop;//如果一致则继续查找数据lpAddr lpstRES_DIR_ENT-OffsetToData;if (lpAddr 0x80000000){lpAddr 0x7fffffff; //最高位为1lpAddr (DWORD)lpRes; //第三级lpstRES_DIR (IMAGE_RESOURCE_DIRECTORY*)lpAddr;//移动到第三级目录假设目录项数量都为1lpAddr sizeof(IMAGE_RESOURCE_DIRECTORY);lpstRES_DIR_ENT (IMAGE_RESOURCE_DIRECTORY_ENTRY*)lpAddr;//地址指向数据项lpAddr lpstRES_DIR_ENT-OffsetToData (DWORD)lpRes;lpstRES_DATA_ENT (IMAGE_RESOURCE_DATA_ENTRY*)lpAddr;dwTemp3 lpstRES_DATA_ENT-Size;dwTemp2 RVAToOffset((IMAGE_DOS_HEADER *)lpFile,lpstRES_DATA_ENT-OffsetToData);wsprintf(szBuffer, szLevel31, dwTemp1, dwTemp2, dwTemp3);_AppendInfo(szBuffer);//将dwTemp2开始的dwTemp3个字节写入文件lpMem (DWORD)lpFile dwTemp2;WriteFile(hFile, (PBYTE)lpMem, dwTemp3, dwTemp, NULL);_AppendInfo(szFinished);count 1;return count;}_loop:lpstRES_DIR_ENT;}goto _next;}elsegoto _next;}}_next:lpstRES_DIR_ENT;}if (dwICO 0)_AppendInfo(szNoIconArray);return count; }运行 图7-8 提取图标 总结 上述程序假设图标是由多个图标数据组成即资源表中一定存在图标组。 ICO头部分ICO项描述在资源图标组里定义每一部分数据则在资源图标里定义。程序 首先检测是否存在图标组资源如果不存在则退出如果存在就定位到图标组资源数据通过将字段编号1个字修改为偏移2个字重新组合ICO头部使其符合ICO文件头部要求。最后分別读取各部分图标资源数据顺序连接到ICO头部后即可。
http://www.hyszgw.com/news/85988.html

相关文章:

  • 网站建设流程总结湖州网站开发
  • wordpress插件文档重庆seo技术博客
  • 山东菏泽网站建设上海建设部网站首页
  • 外贸网站建设官网wordpress js弹窗
  • 网站开发设计比较好的公司做网站带阿里云服务器多少钱
  • wordpress 移动建站镇江网络营销外包
  • 国家企业信用信息公示系统官方seo排名的职位
  • 亚马逊站外推广网站怎么做诸葛建站官网
  • 钓鱼网站源码中企动力淄博分公司
  • 成都网站公司网站建设h5页面制作效果图
  • 做个网站需要多少钱.诸城网站价格
  • 网站怎么推广怎么做wordpress的使用方法
  • 淮安哪里有做网站的人wordpress 后台开发
  • 滨州网站建设招聘t和p在一起怎么做网页
  • 如何用python做网站哪里做网站好
  • 58网站开发要多少钱wordpress auto
  • 陕西交通建设集团网站体检陕煤化建设集团网站矿建二公司
  • 韩国学校网站模板wordpress支付宝alipay
  • 网站建设. 龙兵科技网站建设业务员论坛
  • 余姚做网站设计的珠海企业网站建设服务
  • 安庆市住房和建设厅网站wordpress超级排版
  • 网站建设的流程电子商务深圳网站空间租用价格
  • 什么企业时候做网站阿里巴巴网站服务内容
  • 网站建设是专业迁安市住房和城乡建设局网站
  • iis 浏览网站wordpress头像存储
  • 如何模板建站华星建设集团网站
  • 苏州网站建设有限公司西湖app开发公司
  • 国外毕业设计网站在线留电话的广告
  • 网站建设与管理的专业群做网站首页代码
  • 平面设计类网站有哪些建筑设计理念万能模板