在编译的 exe 中编辑字符串变量? C++ win32

Posted

技术标签:

【中文标题】在编译的 exe 中编辑字符串变量? C++ win32【英文标题】:Edit strings vars in compiled exe? C++ win32 【发布时间】:2010-05-20 17:54:01 【问题描述】:

我想在我的 c++ 应用程序中有一些字符串,我希望以后能够在部署的应用程序(编译的 exe)中编辑它们,有没有办法让 exe 编辑自己或它的资源所以我可以更新字符串值?

应用程序在启动时检查更新,所以我正在考虑使用它来在我需要编辑字符串(例如,包含用于检查更新的 url 的字符串)时发送命令。

我不想使用 exe 外部的任何东西,我可以简单地使用注册表,但我更喜欢将所有东西都保留在 exe 中。

我正在使用 Visual Studio 2010 c++(或任何其他版本的 ms visual c++)。

【问题讨论】:

谢谢大家,我想我会使用外部文件而不是注册表,还是注册表会更好? 这取决于运行更新程序进程的用户的权限。我在回复中提到,你总是可以写入用户配置单元,但普通用户不能写入“c:\program files”。 【参考方案1】:

我知道你说过你不想使用程序外部的任何东西,但我认为在这种情况下你真正想要的是一个纯资源 DLL。可执行文件可以加载具有给定调用所需字符串的任何 DLL。

【讨论】:

【参考方案2】:

另一个想法是将字符串移动到“配置”文件中,例如 XML 或 INI 格式。

在不编译的情况下修改 EXE 是一种黑客行为,我们强烈反对。您可以使用十六进制编辑器,找到字符串并修改它。新文本的长度必须小于或等于原始 EXE。

请注意,某些病毒检查程序会对可执行文件执行 CRC 或校验和。更改可执行文件是这些病毒检查程序的危险信号。

【讨论】:

您认为外部文件会比注册表更好吗?普通用户是否能够创建/编辑文件,或者它会给权限和类似的事情带来麻烦? XML 配置文件和注册表之间的选择通常基于数据大小。如果您的字符串少于十几个,数据少于 4KB,请使用注册表。【参考方案3】:

这是不可能的,除非你的字符串的位置和长度不会改变。

因此,为了使它成为可能:在您的示例中,使用于获取更新的 URL 的“大小”相当大(想想:512 个字符,最后填充为空)。这样,您就有了一些空间来更新字符串。

为什么不能使用可变大小的字符串?好吧,我可以用一个小的 x86 汇编器 sn-p 来解释这一点:

PUSH OFFSET test.004024F0

比方说; test.004024F0 的偏移量是您的可变大小字符串。现在考虑一下变化:

我想插入一个比原始字符串更长的字符串,该字符串存储在004024F0的字符串之前:这使得004024F0成为一个新值,假设:004024F5(新字符串,在此条目之前,比原来长 5 个字符)。

您认为这很简单:搜索所有004024F0 并将其替换为004024F5错误004024F0 也可以是常规的“指令”(准确地说是:ADD BYTE PTR DS:[EAX+24],AL; LOCK ...)。如果这条指令恰好在你的代码中,它会被错误的东西代替。

好吧,你可能会想,搜索那个PUSH 指令怎么样? 错误:“推”的方式几乎是无限的。例如,MOV EAX, 004024F0; MOV ESP, EAX; ADD ESP, 4。也有可能计算字段:MOV EAX, 00402000; ADD EAX, 4F0; ...。所以这使它“几乎无限”。

但是,如果您使用静态大小的字段;您不必更改引用字符串的代码。如果你为特定字段预留了足够的空间,那么你可以很容易地写一个比原来“更长”的字符串,因为字符串的大小是通过找到第一个“空字节”来计算的;用空值填充该字段的其余部分。

如果您使用静态大小的字段,那么在编译时很难找到“文件中的位置”。考虑到花费大量时间来破解您自己的应用程序;您可以编写修改.exe 的代码,并在指定的偏移量处存储一个新的字符串值。此文件偏移量在编译时是未知的,您可以稍后使用OllyDbg 之类的工具自己修补此文件偏移量。这使可执行文件能够自行修补:-)

【讨论】:

【参考方案4】:

创建自编辑 exe 是解决此问题的一种非常不明智的方法。你最好从外部文件中存储和读取字符串。也许如果您提供一些背景信息来说明您为什么不想使用除了 exe 之外的任何东西,我们可以解决这些问题?

【讨论】:

【参考方案5】:

理论上,BeginUpdateResourceUpdateResourceEndUpdateResource 是为此目的而设计的。实际上,让这些工作完全是一件非常棘手的事情。我完全不确定它们是否可以用于更新正在运行的可执行文件中的资源。

【讨论】:

【参考方案6】:

不想责备,但这听起来不是个好主意。将用于检查更新的 URL 包含在程序中会使其不灵活。

您正试图通过重写 exe 中的字符串来缓解这种不灵活。这真是自找麻烦:

您确定运行您的程序的用户具有写入权限才能更新 exe?默认用户对程序文件夹中安装的文件没有写入权限。 如果程序由多个用户运行或由同一用户多次运行,则 exe 将被锁定且不可修改 系统管理员将很难调整 URL。 确实存在损坏 exe 的风险。重写过程可能很复杂,特别是如果您想让 URL 比当前分配的更长。 通过修改您的 exe,您消除了使用代码签名的可能性,这在网络环境中非常有用。

注册表(尽管它有很多弱点)确实是这种配置数据应该去的地方。您可以在您的 EXE 中设置一个默认值,但如果您需要进行更改,请将它们放在注册表中。这使更改变得透明,为您以后省去很多麻烦。

您想要为更新编写新 URL 的算法应该通过将其写入注册表来执行此操作。或者,有一个与您的 exe 一起提供的配置文件,然后更新它。 (但请记住用户权限 - 您可能没有对该文件的写入权限,但您始终可以写入注册表的用户配置单元。)

【讨论】:

以上是关于在编译的 exe 中编辑字符串变量? C++ win32的主要内容,如果未能解决你的问题,请参考以下文章

在已编译的 exe 中编辑字符串 [关闭]

VS2010 c++编译的时候总是出现找不到exe文件、这是个啥情况

Visual Studio 2010中的Visual C++如何编译、连接和运行?

C++ Eclipse 生成无效的exe

VS2015C++文件编译错误,始终是这种情况。DEBUGE里面没有出现exe文件,我C#是正常的,就C++有问题

把.rc文件内容(貌似C++源码)翻译成中文