无忧启动论坛

 找回密码
 注册
搜索
系统gho:最纯净好用系统下载站投放广告、加入VIP会员,请联系 微信:wuyouceo
楼主: mdyblog
打印 上一主题 下一主题

[更新376#2825]PECMD2012.1.80.13_Win32_64.多窗口多线程.裸机系统2.3.3.1+18M酷M...

    [复制链接]
19501#
发表于 前天 11:05 | 只看该作者
  1. #include <windows.h>
  2. #include <vector>
  3. #include <string>
  4. #include <fstream>
  5. #include <cstdlib>
  6. #include <iostream>
  7. #include <iomanip>
  8. #include <sstream>
  9. #include <algorithm>

  10. // 全局向量存储资源名称(替代 AutoIt 的 $aEN 数组)
  11. std::vector<std::wstring> g_resourceNames;

  12. // 资源枚举回调函数(替代 AutoIt 的 ___EnumResNameProc)
  13. BOOL CALLBACK EnumResNameProc(HMODULE hModule, LPCWSTR lpszType, LPWSTR lpszName, LONG_PTR lParam) {
  14.     if (IS_INTRESOURCE(lpszName)) {
  15.         // ★ 处理整数型资源 ID(如 #123)
  16.         WORD id = static_cast<WORD>(reinterpret_cast<ULONG_PTR>(lpszName));
  17.         std::wstringstream wss;
  18.         wss << L"#" << id;
  19.         g_resourceNames.push_back(wss.str());
  20.     } else {
  21.         // ★ 处理字符串型资源名称
  22.         g_resourceNames.push_back(lpszName);
  23.     }
  24.     return TRUE; // 继续枚举
  25. }

  26. int wmain(int argc, wchar_t* argv[]) {
  27.     // ===== 1. 命令行参数处理 =====
  28.     if (argc != 4) {
  29.         std::wcerr << L"用法: " << argv[0] << L" <文件> <索引> <输出文件>\n";
  30.         return -1;
  31.     }

  32.     std::wstring file = argv[1];
  33.     int index = _wtoi(argv[2]);       // 转换索引参数
  34.     std::wstring outputFile = argv[3];

  35.     // ===== 2. 文件存在性检查 =====
  36.     if (!PathFileExistsW(file.c_str())) {
  37.         wchar_t sysDir[MAX_PATH];
  38.         // 获取系统目录路径
  39.         UINT sysDirLen = GetSystemDirectoryW(sysDir, MAX_PATH);
  40.         if (sysDirLen == 0 || sysDirLen > MAX_PATH) {
  41.             std::wcerr << L"错误: 无法获取系统目录\n";
  42.             return -2;
  43.         }
  44.         // 尝试在系统目录中查找
  45.         std::wstring sysFile = std::wstring(sysDir) + L"\" + file;
  46.         if (!PathFileExistsW(sysFile.c_str())) {
  47.             std::wcerr << argv[1] << L" 未找到\n";
  48.             return -2;
  49.         }
  50.         file = sysFile; // 使用系统目录中的文件
  51.     }

  52.     // ===== 3. 加载目标文件为数据文件 =====
  53.     HMODULE hModule = LoadLibraryExW(
  54.         file.c_str(),
  55.         NULL,
  56.         LOAD_LIBRARY_AS_DATAFILE // 重要:仅作为资源加载
  57.     );
  58.     if (!hModule) {
  59.         std::wcerr << L"错误: 无法加载文件资源\n";
  60.         return -3;
  61.     }

  62.     // ===== 4. 枚举图标组资源 =====
  63.     g_resourceNames.clear();
  64.     if (!EnumResourceNamesW(
  65.         hModule,
  66.         RT_GROUP_ICON,       // 图标组资源类型
  67.         EnumResNameProc,     // 回调函数
  68.         0                    // 回调参数
  69.     )) {
  70.         FreeLibrary(hModule);
  71.         std::wcerr << L"错误: 枚举资源失败\n";
  72.         return -3;
  73.     }

  74.     // ===== 5. 验证并选择图标索引 =====
  75.     int absIndex = abs(index); // 处理负索引
  76.     if (absIndex < 1 || absIndex > static_cast<int>(g_resourceNames.size())) {
  77.         FreeLibrary(hModule);
  78.         std::wcerr << L"错误: 无效的图标索引\n";
  79.         return -3;
  80.     }
  81.     std::wstring resName = g_resourceNames[absIndex - 1]; // 转换为0-based索引

  82.     // ===== 6. 准备资源标识符 =====
  83.     LPCWSTR lpResName;
  84.     if (resName[0] == L'#') {
  85.         // ★ 转换 "#数字" 格式为资源ID
  86.         int id = std::wcstol(resName.substr(1).c_str(), nullptr, 10);
  87.         lpResName = MAKEINTRESOURCEW(id);
  88.     } else {
  89.         // ★ 直接使用字符串资源名
  90.         lpResName = resName.c_str();
  91.     }

  92.     // ===== 7. 加载图标组资源 =====
  93.     HRSRC hGroupRes = FindResourceW(hModule, lpResName, RT_GROUP_ICON);
  94.     if (!hGroupRes) {
  95.         FreeLibrary(hModule);
  96.         std::wcerr << L"错误: 未找到图标组资源\n";
  97.         return -3;
  98.     }

  99.     // 获取资源大小
  100.     DWORD groupSize = SizeofResource(hModule, hGroupRes);
  101.     if (groupSize < 6) { // 最小头尺寸检查
  102.         FreeLibrary(hModule);
  103.         return -3;
  104.     }

  105.     // 加载并锁定资源
  106.     HGLOBAL hGroupData = LoadResource(hModule, hGroupRes);
  107.     if (!hGroupData) {
  108.         FreeLibrary(hModule);
  109.         return -3;
  110.     }
  111.     BYTE* pGroupData = static_cast<BYTE*>(LockResource(hGroupData));
  112.     if (!pGroupData) {
  113.         FreeLibrary(hModule);
  114.         return -3;
  115.     }

  116.     // ===== 8. 解析图标组头信息 =====
  117.     WORD reserved = *reinterpret_cast<WORD*>(pGroupData);      // 保留字段 (应为0)
  118.     WORD type = *reinterpret_cast<WORD*>(pGroupData + 2);      // 资源类型 (应为1)
  119.     WORD count = *reinterpret_cast<WORD*>(pGroupData + 4);     // 图标数量

  120.     // 验证图标组头
  121.     if (reserved != 0 || type != 1 || groupSize < 6 + 14 * count) {
  122.         FreeLibrary(hModule);
  123.         std::wcerr << L"错误: 无效的图标组格式\n";
  124.         return -3;
  125.     }

  126.     // ===== 9. 创建输出ICO文件 =====
  127.     std::ofstream outFile(outputFile, std::ios::binary);
  128.     if (!outFile.is_open()) {
  129.         FreeLibrary(hModule);
  130.         std::wcerr << L"错误: 无法创建输出文件\n";
  131.         return -3;
  132.     }

  133.     // ===== 10. 写入ICO文件头 =====
  134.     DWORD offset = 6 + 16 * count; // 计算首个图标数据偏移量
  135.     outFile.write(reinterpret_cast<char*>(pGroupData), 6); // 写入ICO头
  136.     if (!outFile) {
  137.         outFile.close();
  138.         FreeLibrary(hModule);
  139.         return -3;
  140.     }

  141.     // ===== 11. 处理每个图标条目 =====
  142.     for (WORD i = 0; i < count; ++i) {
  143.         BYTE* pEntry = pGroupData + 6 + 14 * i; // 当前图标条目指针
  144.         
  145.         // 修改条目中的偏移量字段
  146.         outFile.write(reinterpret_cast<char*>(pEntry), 12); // 写入前12字节
  147.         outFile.write(reinterpret_cast<char*>(&offset), 4); // 写入新计算的偏移量
  148.         
  149.         if (!outFile) {
  150.             outFile.close();
  151.             FreeLibrary(hModule);
  152.             return -3;
  153.         }
  154.         
  155.         // 更新下一个图标的偏移量
  156.         DWORD iconSize = *reinterpret_cast<DWORD*>(pEntry + 8);
  157.         offset += iconSize;
  158.     }

  159.     // ===== 12. 写入图标数据 =====
  160.     for (WORD i = 0; i < count; ++i) {
  161.         BYTE* pEntry = pGroupData + 6 + 14 * i;
  162.         WORD iconId = *reinterpret_cast<WORD*>(pEntry + 12); // 获取图标ID
  163.         
  164.         // 加载单个图标资源
  165.         HRSRC hIconRes = FindResourceW(hModule, MAKEINTRESOURCEW(iconId), RT_ICON);
  166.         if (!hIconRes) {
  167.             outFile.close();
  168.             FreeLibrary(hModule);
  169.             std::wcerr << L"错误: 未找到图标资源\n";
  170.             return -3;
  171.         }

  172.         // 获取图标数据
  173.         DWORD iconSize = SizeofResource(hModule, hIconRes);
  174.         HGLOBAL hIconData = LoadResource(hModule, hIconRes);
  175.         if (!hIconData || iconSize == 0) {
  176.             outFile.close();
  177.             FreeLibrary(hModule);
  178.             return -3;
  179.         }
  180.         
  181.         BYTE* pIconData = static_cast<BYTE*>(LockResource(hIconData));
  182.         if (!pIconData) {
  183.             outFile.close();
  184.             FreeLibrary(hModule);
  185.             return -3;
  186.         }

  187.         // 写入图标数据到文件
  188.         outFile.write(reinterpret_cast<char*>(pIconData), iconSize);
  189.         if (!outFile) {
  190.             outFile.close();
  191.             FreeLibrary(hModule);
  192.             return -3;
  193.         }
  194.     }

  195.     // ===== 13. 清理资源 =====
  196.     outFile.close();
  197.     FreeLibrary(hModule);
  198.     std::wcout << L"图标成功导出至: " << outputFile << std::endl;
  199.     return 0; // 成功退出
  200. }
复制代码

点评

太费劲了,帖代码咋不一次帖完。 不想看不想研究,你自己改吧  详情 回复 发表于 前天 11:07
回复

使用道具 举报

19502#
发表于 前天 11:07 | 只看该作者

太费劲了,帖代码咋不一次帖完。   不想看不想研究,你自己改吧

点评

Zap
你咋不一次改成 我这今天才研究出来,大前天还不会  详情 回复 发表于 前天 12:13
回复

使用道具 举报

19503#
发表于 前天 12:13 | 只看该作者
红毛樱木 发表于 2025-11-6 11:07
太费劲了,帖代码咋不一次帖完。   不想看不想研究,你自己改吧

你咋不一次改成  我这今天才研究出来,大前天还不会

点评

你第一次给的C++源码,我都帮你翻译完了。而且你代码里的逻辑不对,我也帮你改了。 还要咋样呀。。。我都不知道你代码的原理  详情 回复 发表于 前天 12:45
你没发现你把一个括号改丢了吗? [attachimg]567152[/attachimg]  详情 回复 发表于 前天 12:29
回复

使用道具 举报

19504#
发表于 前天 12:29 | 只看该作者
Zap 发表于 2025-11-6 12:13
你咋不一次改成  我这今天才研究出来,大前天还不会


你没发现你把一个括号改丢了吗?



点评

Zap
丢不丢都一样了 因为错不在这 前面都截胡了 快去请掌管代码的神@mdyblog  详情 回复 发表于 前天 12:34
回复

使用道具 举报

19505#
发表于 前天 12:34 | 只看该作者
527104427 发表于 2025-11-6 12:29
你没发现你把一个括号改丢了吗?

丢不丢都一样了 因为错不在这 前面都截胡了
快去请掌管代码的神@mdyblog

点评

你牛逼,你来请  发表于 前天 12:40
回复

使用道具 举报

19506#
发表于 前天 12:45 | 只看该作者
Zap 发表于 2025-11-6 12:13
你咋不一次改成  我这今天才研究出来,大前天还不会

你第一次给的C++源码,我都帮你翻译完了。而且你代码里的逻辑不对,我也帮你改了。  还要咋样呀。。。我都不知道你代码的原理

点评

Zap
PECMD太难了  详情 回复 发表于 前天 18:02
回复

使用道具 举报

19507#
发表于 前天 18:02 | 只看该作者
红毛樱木 发表于 2025-11-6 12:45
你第一次给的C++源码,我都帮你翻译完了。而且你代码里的逻辑不对,我也帮你改了。  还要咋样呀。。。我 ...

PECMD太难了

点评

想翻译成PECMD,自己研究的代码要用C语言,不能用C++,不然不好翻译的。 PECMD我感觉是类似C风格的  详情 回复 发表于 前天 19:59
回复

使用道具 举报

19508#
发表于 前天 19:59 | 只看该作者

想翻译成PECMD,自己研究的代码要用C语言,不能用C++,不然不好翻译的。 PECMD我感觉是类似C风格的

点评

Zap
呼叫古希腊掌管代码的神  详情 回复 发表于 昨天 13:03
回复

使用道具 举报

19509#
发表于 前天 20:11 | 只看该作者
感谢分享。
回复

使用道具 举报

19510#
发表于 昨天 13:03 | 只看该作者
本帖最后由 Zap 于 2025-11-7 13:04 编辑
红毛樱木 发表于 2025-11-6 19:59
想翻译成PECMD,自己研究的代码要用C语言,不能用C++,不然不好翻译的。 PECMD我感觉是类似C风格的

呼叫古希腊掌管代码的神
  1. //返回程序第一个图标名
  2. #include <windows.h>
  3. #include <shlwapi.h>
  4. #include <wchar.h>
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <io.h>      // 用于_setmode
  8. #include <fcntl.h>   // 用于_O_U16TEXT

  9. #pragma comment(lib, "shlwapi.lib")

  10. // 全局资源名称数组及计数
  11. wchar_t** g_resourceNames = NULL;
  12. int g_resourceCount = 0;

  13. // 资源枚举回调函数:正确处理整数ID和字符串名称
  14. BOOL CALLBACK EnumResNameProc(HMODULE hModule, LPCWSTR lpszType, LPWSTR lpszName, LONG_PTR lParam) {
  15.     wchar_t* resName = NULL;
  16.     if (IS_INTRESOURCE(lpszName)) {
  17.         // 处理整数ID(资源ID是16位无符号整数)
  18.         WORD id = (WORD)(UINT_PTR)lpszName;  // 正确转换资源ID
  19.         resName = (wchar_t*)malloc(64 * sizeof(wchar_t));  // 扩大缓冲区避免溢出
  20.         if (!resName) return FALSE;  // 检查内存分配失败
  21.         // 格式化整数ID为 "#数字"(例如#1000)
  22.         if (swprintf_s(resName, 64, L"#%u", id) < 0) {  // 使用%u匹配WORD(无符号)
  23.             free(resName);
  24.             return FALSE;
  25.         }
  26.     } else {
  27.         // 处理字符串名称(例如ICO_MYCOMPUTER)
  28.         size_t nameLen = wcslen(lpszName);
  29.         resName = (wchar_t*)malloc((nameLen + 1) * sizeof(wchar_t));
  30.         if (!resName) return FALSE;  // 检查内存分配失败
  31.         wcscpy_s(resName, nameLen + 1, lpszName);
  32.     }

  33.     // 扩展资源名称数组
  34.     wchar_t** newArray = (wchar_t**)realloc(g_resourceNames, (g_resourceCount + 1) * sizeof(wchar_t*));
  35.     if (!newArray) {
  36.         free(resName);
  37.         return FALSE;
  38.     }
  39.     g_resourceNames = newArray;
  40.     g_resourceNames[g_resourceCount++] = resName;
  41.     return TRUE;
  42. }

  43. // 释放资源名称数组内存
  44. void FreeResourceNames() {
  45.     for (int i = 0; i < g_resourceCount; i++) {
  46.         if (g_resourceNames[i]) free(g_resourceNames[i]);
  47.     }
  48.     free(g_resourceNames);
  49.     g_resourceNames = NULL;
  50.     g_resourceCount = 0;
  51. }

  52. // 显示帮助信息
  53. void ShowHelp(const wchar_t* programName) {
  54.     wprintf(L"用法: %ls <目标程序路径>\n", programName);
  55.     wprintf(L"示例: %ls C:\\Windows\\explorer.exe\n", programName);
  56. }

  57. int wmain(int argc, wchar_t* argv[]) {
  58.     // 设置控制台宽字符模式(确保中文和宽字符正常显示)
  59.     _setmode(_fileno(stdout), _O_U16TEXT);
  60.     _setmode(_fileno(stderr), _O_U16TEXT);

  61.     // 参数检查
  62.     if (argc != 2) {
  63.         ShowHelp(argv[0]);
  64.         return -1;
  65.     }

  66.     wchar_t targetPath[MAX_PATH];
  67.     wcscpy_s(targetPath, MAX_PATH, argv[1]);

  68.     // 检查目标文件是否存在
  69.     if (!PathFileExistsW(targetPath)) {
  70.         fwprintf(stderr, L"错误: 文件不存在 - %ls\n", argv[1]);
  71.         return -2;
  72.     }

  73.     // 加载目标程序作为资源文件(仅读取资源,不执行代码)
  74.     HMODULE hModule = LoadLibraryExW(targetPath, NULL, LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_IMAGE_RESOURCE);
  75.     if (!hModule) {
  76.         fwprintf(stderr, L"错误: 无法加载文件资源 (错误码: %d)\n", GetLastError());
  77.         return -3;
  78.     }

  79.     // 枚举所有图标组资源(RT_GROUP_ICON是图标组的资源类型)
  80.     FreeResourceNames();
  81.     if (!EnumResourceNamesW(hModule, RT_GROUP_ICON, EnumResNameProc, 0)) {
  82.         fwprintf(stderr, L"错误: 枚举图标资源失败 (错误码: %d)\n", GetLastError());
  83.         FreeLibrary(hModule);
  84.         FreeResourceNames();
  85.         return -3;
  86.     }

  87.     // 输出第一个图标组名称(修复格式符错误)
  88.     if (g_resourceCount > 0 && g_resourceNames[0]) {
  89.         // 修复:用%ls打印宽字符字符串(wchar_t*),而非%s
  90.         wprintf(L"%ls\n", g_resourceNames[0]);
  91.     } else {
  92.         fwprintf(stderr, L"错误: 未找到图标组资源\n");
  93.         FreeLibrary(hModule);
  94.         FreeResourceNames();
  95.         return -3;
  96.     }

  97.     // 清理资源
  98.     FreeLibrary(hModule);
  99.     FreeResourceNames();
  100.     return 0;
  101. }
复制代码

点评

牛逼,你要双休吗  详情 回复 发表于 昨天 13:37
回复

使用道具 举报

19511#
发表于 昨天 13:37 来自手机 | 只看该作者
Zap 发表于 2025-11-7 13:03
呼叫古希腊掌管代码的神

牛逼,你要双休吗
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|Archiver|捐助支持|无忧启动 ( 闽ICP备05002490号-1 )

闽公网安备 35020302032614号

GMT+8, 2025-11-8 10:12

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表