关于exe或dll文件中的字符串资源

AI权益加码!Claude Code、Cursor等20+工具免费用! 购周边限时加赠Coding Plan Lite,畅享主流AI工具!学习进阶更高效! 阅读详情

资源在WindowsGUI的程序中随处可见,这也是微软为了方便把界面和逻辑分开的优秀策略。所谓的资源就是一些用于描述界面或其他特征的说明性字符,它们有固定的格式。这点与HTML有相似之处。而微软提供了处理这些资源描述字符的函数,并上升到Win32API的高度。资源有两种存在形式,一是编译之前,此时的资源被存放到.rc文件(此文件为纯文本文件)中,在程序编译的时候,资源编译器rc.exe.rc文件编译为.res二进制文件,然后链接器把.res文件和.obj文件链接在一起,并作为资源节存在于生成的.exe文件中。

 

对于.rc文件,相信很多程序员都很熟悉了,可以直接用文本编辑器编辑。为了可视化设计,微软和其他第三方软件厂商还提供了可视化编辑工具,称之为资源编辑器。VS带的资源编辑器,相信大家都不会陌生。

 

对于.res文件或者是.exe文件中的资源节的格式,大多数程序员就望而却步了。详细介绍.exe文件结构的资料也不多,能够说清楚资源节格式的资料就更少了。微软提供了FindResource(), LoadResource(), LockResource(), UpdateResource()等函数供用户查看修改二进制资源节里的资源。但是具体的用法解释的并不清楚,网上的例子也很少。但是这方便有做的功能很晚上的软件,如eXeScope,不仅可以查看二进制资源,还可以修改之,可惜没有公开源代码。由于项目需要,这几天一直找相关的例子,发现象Dialog,ICON等资源的处理有很多成功的例子,但是对于看似简单的字符串资源的处理却几乎无一成功的!!!就连老外也一样!!!于是乎,疯狂找资料,终于找到一位明白人写的文章,还有源代码,只是有两点可惜:一是作者是老外,国内程序员不一定都喜欢英语;二是程序源码采用VB编写,这让C/C++的程序源很不舒服。于是乎,对这篇文章关于字符串资源的处理的部分进行研究并重新用C/C++实现的想法涌上心头。由于我对于VB也不是很熟悉,转换语言的过程也不太顺利,不过总算是成功转成了C/C++。技术不敢独享,愿为大家献上,不当之处还请见谅!

 

1 字符串资源的存放格式与处理单位

不想其他资源,字符串是不能单独处理的,像UpdateResource()等函数要求的最小处理单位是“串组”,这是由字符串资源的存放方式决定的。每16个字符串为一个串组,字符串的排序以字符串的资源ID号为依据,0-15为第一串组,16-31位第二串组,32-47位第三串组,...。串组ID号从1开始,字符串ID号从0开始。由此可以得到如下公式:

串组ID = (取整)(字符串ID/16) + 1

同一串组的字符串是相邻存放的,我们以7号串组为例说明。如下图所示:

 

2      你好

5      你好abc

0  

1     

中间省略

 

 

 


上图列出了几个代表的串,其中最开头的串的ID96,一个串有两部分组成,前一部分占2个字节,用于描述本串的长度,以UNICODE字符为单位(也就是2个字节),注意字符串资源里的字符都是采用UNICODE16位编码的。后一部分是串的具体内容,注意没有结尾标志。从上图可以看出,ID号为96的串的长度为2个字符,内容为“你好”。下一个串也就是ID97的串的长度为0,所以没有内容;接着98号串长度为5,内容为“你好abc"(请注意,在UNICODE编码方式下,所有字符都占据2个字节,英文字母也一样)。最后一个字符串,也就是111号,长度为1,内容为“你”。

2 处理方法

理解了字符串资源的存放方式与处理单位,对于其处理方法也就不难了。基本思路是,首先根据字符串的ID号,找到所处的串组号,然后找到整个串组的内容,随后定位到需要处理的串,修改其长度标示和内容。修改不会影响到前面的串,但却会影响到后面的串,所以首先要把后面的所有串先备份,然后添加到修改后的串的尾部。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


如上图所示,需要修改的串显示为红色,串组以此串为分割点分成前后两部分,这两部分原样复制,把需要修改的串修改后重新将其与前后两部分衔接起来。

顺着这个思路问题迎刃而解,具体代码如下:

BOOL StringResourceModify(CString strResExePath, int ID, CString strNew, long LangID)

{

         long ret;

         long x;

         HANDLE hResource;

         int iGroup;

         HRSRC hObject;

         HGLOBAL hResourceData;

         HGLOBAL lpResourceData;

         DWORD cbResource;

         HMODULE hModule;

         byte *lpData;

         byte *lpReadData;

         int lenOfData;

         int cbText;

        

         if(ID<1)                                 //不能修改第0个字符串

                   return FALSE;

         iGroup = ID/16 + 1;           //计算字符串所在的串组

         hModule = ::LoadLibrary(strResExePath);

          //找到这个串组

         hObject = ::FindResourceEx(hModule,RT_STRING,MAKEINTRESOURCE(iGroup),LangID );

         hResourceData = ::LoadResource(hModule, hObject);   //加载串组

         lpResourceData = ::LockResource(hResourceData);       //返回串组数据的地址

         cbResource = ::SizeofResource(hModule, hObject);        //获取串组数据长度(字节)

 

         if(cbResource <= 32 || hObject == 0)                                   //串组不存在,则增加一个串组

         {

                   cbResource = 32 + strNew.GetLength()*2;//串组至少2*16=32字节长度(全空)

                   lpData = new byte[cbResource];

                  

                   lenOfData = cbResource;

                   cbText = strNew.GetLength();                                      //串的字符数

 

                   //写入串长度,此时前面的串都是空串,各占据2个字节

                   ::CopyMemory((lpData + 2*(ID-(iGroup-1)*16)), &cbText, 2);

                   if(strNew.GetLength())

                   {

                            ::CopyMemory(lpData+2*(ID-(iGroup-1)*16)+2,

                                     strNew.GetBuffer(), strNew.GetLength()*2); //写入串内容

                   }

         }

         else //串组中有串非空,则修改

         {

                   lpReadData = new byte[cbResource];

                   lenOfData = cbResource;

                   ::CopyMemory(lpReadData, lpResourceData, cbResource);//复制串组原来的内容

                   long countX = 0;

                   int CHECKLNG = 0;

                   //遍历本串组第一个串到本串前一个串

                   for(x=0; x<(ID-(iGroup-1)*16); x++)

                   {

                            ::CopyMemory(&CHECKLNG, lpReadData+countX, 2); //读出每个串的长度

                            countX = countX + 2 + CHECKLNG*2;                //指向下一个字符串

                   }

                   //至此,countX代表了本串之前的所有串所占据的空间大小(字节)

 

                   //读出要修改串修改前的长度

                   ::CopyMemory(&CHECKLNG, lpReadData+countX, 2);

                   //至此,CHECKLNG代表修改前本串的长度

 

                   lpData = new byte[countX+2+strNew.GetLength()*2 + //从开头到本串(修改后)结束的长度

                            ( cbResource-(countX+2 + CHECKLNG*2)) ]; //从本串后一个串开始到结束的总长度

                   ::CopyMemory(lpData, lpReadData, countX); //读入开头到本串前一个串结束

                   cbText = strNew.GetLength();

                   ::CopyMemory(lpData+countX, &cbText, 2);  //写入修改后串长度

                  if(cbText)

                   {

                            //写入修改后串的内容

                            ::CopyMemory(lpData+countX+2, strNew.GetBuffer(), cbText*2);

                   }

                   if( (cbResource - (countX+2+CHECKLNG*2)) >0 )     //修改前,本串后面还有串

                   {

                            ::CopyMemory(lpData+countX+2+cbText*2,

                                                lpReadData+countX+2+CHECKLNG*2,                                                                                                                cbResource-(countX+2+CHECKLNG*2));//原来的内容保留

 

                   }

         }

 

         ::FreeLibrary(hModule);

         hResource = BeginUpdateResource(strResExePath, FALSE);

         ret = UpdateResource(hResource, RT_STRING, MAKEINTRESOURCE(iGroup),

                                                        LangID, lpData, lenOfData);

         ret = ::EndUpdateResource(hResource, FALSE);

 

         return ret;

}

Dllexe的区别及使用详解 DLL(Dynamic Link Library,动态链接库)和EXEExecutable, 可执行文件)是两种同类型的文件格式,主要用于同的目的。DLL中虽然包含了可执行代码却能单独执行,而应由Windows应用程序直接间接调用。由于DLL能被应用程序动态载入内存。所以,应用程序可以在需要时才将DLL载入到内存中,这让程序的可维护性变得很高。比如QQ的视频功能需要升级,那么负责编写QQ的程序必将QQ所有代码都重写,只需将视频功能相关的DLL文件重写即可。 阅读详情

相关推荐

批处理调用Rcedit 修改exedll详细信息(版本、版权)

官方文档示例显示帮助:rcedit-h设置版本字符串:rcedit"Comments"设置文件版本:rcedit"10.7"设置产品版本:rcedit"10.7"设置图标:rcedit--set-icon设置资源字符串:rceditid_number设置rcedit设置rcedit您可以在一个命令中更改多个内容:rcedit--set-icon"10.7"获取版本字符串:rcedit"property"

枫蓝驿的博客 2139

exe软件改标题 改软件内文字 永久改 免脱壳 适用于大部分程序 改按钮文字

exe软件改标题 改软件内文字 永久改 免脱壳 适用于大部分程序 改按钮文字 改标签文字 改跳转网站

DLL嵌入EXE资源文件调用方法

动态链接库(Dynamic Link Library,简称DLL)是包含可由多个程序同时使用的代码和数据的库。它们是Windows操作系统的核心组件之一,能够使得程序共享相同的代码和资源,从而节省内存空间并提高运行效率。DLL的概念起源于1980年代,随着Windows操作系统的普及,DLL成为程序模块化和复用的主要方式。

weixin_42361478的博客 965

LordPE PE文件编辑工具(LordPE)下载 1.4 汉化增强版_PE脱壳软件修复

LordPE Deluxe 增强版,这个工具大家应该也比较熟悉吧?这是另一款PE编辑工具,号称是“最好的PE文件修改工具”。正好我以前汉化过这个软件(自己用的,没发布过),顺便套用一下以前的资源,把它给汉化了(里面所附带的工具基本上都汉化了)。可能有许多兄弟都比较喜欢用这个软件,这次发出来希望能给大家带来一点方便。 LordPE 使用说明 这个增强版的主要更新(根据看雪兄的readme文件): (1) 为LordPE查看输入表部分加上搜索功能 (2) 为LordPE查看输入表部分加右键菜单(仅复制ThunkRVA/FirstThunk列). (3) 当点击LordPE查看输入表部分中"View always FirstThunk",保持光条在原来位置.(LordPE默认会将光条置到0行) (4) 修改FLC(File Location Calulator)窗口中各个文本框(VA,RVA,Offset)为只读属性,此时可以用鼠标复制里面的文本.(LordPE原来是将文本框禁止变灰,此时可复制) 过上面的第二条查看输入表部分的右键菜单我没看到。难道是我的系统(XP_SP2)有问题? 其它内容请看附带在内的readme.txt文件。LordPE的原版和增强版的原版我都放在英文原版文件夹中,大家可以进行比较。 文件列表: LordPE.EXE .............原版 LordPE_fix.EXE .............增强版

计算机EXE文件改参数,exe文件修改器(eXeScope)

eXeScope是款功能强大的exe程序修改器,能修改exe程序中的字体、菜单位置、对话框排序、字符串、图片资源等,支持exedll和ocx文件,常常用作软件工具,可直接修改vc++及delphi编写的程序eXeScope功能介绍1、exescope 6.50能在没有资源文件的情况下分析,显示同的信息,重写可执行文件资源,包括(EXEDLL、OCX等)。2、exescope 6.50可以...

weixin_42223667的博客 8002

查询与修改exedllPE文件的版本信息【界面版】

软件功能: 查询与修改exedll文件的版本信息,支持数字签名查询。 界面图: 下载地址:https://download.csdn.net/download/lhyhr/15120562

技术皮皮虾 1066

破解figugegl.1.exe和figugegl.2.exe

2.使用OD搜索字符串功能,搜到有用的字符串字符串应该是被加密了,浏览代码,发现有两个地方调用了GetDlgItemTextA和GetDlgItemInt,在这两个地方下断。eax中保存了用户输入的Serial,esi中保存了程序根据Name计算出的Serial,两者相等即通过验证。这段代码中,两次调用GetDlgItemTextA,在调用处下断,第一次调用获取输入的Name,第二次调用获取输入的Serial。在此处下断点调试,发现401335处判断name的长度,应该小于5。6.保存文件,并运行。

tianjiayun的博客 308

跟我一起学“网络安全”通识-Windows

本篇文章是《跟我一起学“网络安全”通识》的第二章,介绍了Windows操作系统里的一系列基础知识,包括:Windows常用dos命令、WindowsServer搭建AD域、Windows之震网三代漏洞实验等。

Cool_foolisher的博客 3372

3.3 用户界面资源的应用资源是Windows应用程序的一种特殊数据,包括菜单、快捷键、光标、位图、图标、对话框、字符串工具栏、状态栏等,资源一般放在EXEDLL文件中。当Windows将程

资源定义在资源脚本(resource script)文件中,以,rc为文件扩展名,文件名与工程名相同。Visual C++6.0中提供了资源编辑器,对资源进行可视化编辑,并自动生成资源脚本文件,资源是Windows应用程序的一种特殊数据,包括菜单、快捷键、光标、位图、图标、对话框、字。资源脚本文件中定义了各种资源的相关数据,但对于光标、位图、图标等与图形相关的资源,在脚。本节介绍最基本的用户界面元素,包括菜单、工具栏和状态栏,3.4节介绍对话框资源的应。窗口,而弹出式菜单是选择某个菜单项后弹出的子菜单。

Popcorn_zyh的博客 438

windows从内存加载dll

在git找到了个可以用的 项目git地址 摘录主要文件内容: MemoryModule.h /* * Memory DLL loading code * Version 0.0.4 * * Copyright (c) 2004-2015 by Joachim Bauch / mail@joachim-bauch.de * http://www.joachim-bauch.de * * The contents of this file are subject to the Mozilla Pu

l1040515635的博客 1411

微软提供的Message Compiler(MC.EXE)使用总结

在看windows核心编程时,第一章《错误处理》里提到“我们也可以向自己的模块添加错误代码,具体做法是使用Message Compiler(MC.EXE)来创建一个消息资源并将其添加到DLLEXE)模块中。”顿时对这句话产生了兴趣,感觉这是一个一劳永逸的事情,然后就查找了一番资料,对目前的掌握程度做一个总结,若有对之处还望大虾们纠正。   下面是翻译的一篇博客中的一段话,对于MC的评价:

seastars_sh的专栏 5543

EXE/DLL文件字符串替换工具showstring汉化版.rar

软件介绍: showstring能够打开可执行文件EXE/DLL,从中搜索并替换指定的字符串支持ASCII/UNICODE类型的字符串。能逐个字符地扫描文件,根据选项要求来设定如何搜索。

0022__exe文件图标修改工具

https://jingyan.baidu.com/article/b907e6278c668c46e6891c4e.html http://www.angusj.com/resourcehacker/#download

行潇 234

dllexe的区别

DLL中虽然包含了可执行代码却能单独执行,而应由Windows应用程序直接间接调用。   所谓静态链接是指把要调用的函数者过程链接到可执行文件中,成为可执行文件的一部分。换句话说,函数和过程的代码就在程序exe文件中,该文件包含了运行时所需的全部代码。当多个程序都调用相同函数时,内存中就会存在这个函数的多个拷贝,这样就浪费了宝贵的内存资源。   动态链接所调用的函数代码并没有被拷贝到应用程...

ChasingdreamLY的博客 9168

如何查看exedll调用了什么dll

[转载]如何查看exedll调用了什么dll呢 已有 19410 次阅读 2014-4-17 21:08|系统分类:科研笔记|文章来源:转载 Dependency Walker使用说明 在Windows世界中,有无数块活动的大陆,它们都有一个共同的名字——动态链接库。现在就让我们走进这些神奇的活动大陆,找出它们隐藏已久的秘密吧!   初窥门径:Windows

arthurkang的专栏 1万+

Windows系统中的DLL文件详解

随便打开一个系统目录,一眼望去就能看到很多扩展名DLL文件,这些就是经常说的“动态链接库”,DLL是Dynamic Link Library(即“动态链接库”)的缩写。从Microsoft公司推出首个版本的Windows以来,动态链接库就一直是这个操作系统的基础。.dll文件是Dynamic Link Library(动态链接库)文件的缩写,它是一种共享库文件,包含了程序所需的代码和数据。与静态链接库同,动态链接库可以在程序运行时动态加载,使得程序的内存占用更小,同时也方便了程序的更新和维护

计算机毕业论文源码,学生个人网页制作html源码。贴近用户做网络推广和互联网优化。 3825

dll文件exe文件的段分区,使用resource hacker替换dll文件string

文章摘要 DLLEXE文件在底层结构上几乎完全相同,均采用Windows的PE文件格式。它们由多个段(Section)组成,包括.text(代码区)、.rdata(字符串区)、.data(二进制区)和.rsrc(资源区)等。两者的主要区别仅在于PE中的一个标志位(DLL带有IMAGE_FILE_DLL标志)。DLL本质上是一个可被其他程序加载的PE文件,而EXE则是直接执行的程序。通过Resource Hacker工具可以修改DLL中的STRINGTABLE资源,命令格式为指定目标文件、操作类型、资源

jimy1的博客 457
上一篇: WinInet, WinHttp, Winsock, ws2_32的基本解释
下一篇: MySql基本命令
smstong
博客等级 码龄19年 1716粉丝 343原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值