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

时间:2010-05-20 17:54:02

标签: c++ string visual-c++ winapi resources

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

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

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

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

6 个答案:

答案 0 :(得分:6)

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

答案 1 :(得分:3)

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

修改EXE而不编译是黑客攻击,非常气馁。您可以使用十六进制编辑器,找到字符串并进行修改。新文本的长度必须小于或等于原始EXE。

请注意,某些病毒检查程序会对可执行文件执行CRC或校验和。改变可执行文件是这些病毒检查员的一面红旗。

答案 2 :(得分:2)

除非你的琴弦不会改变位置,否则这是不可能的。长度。

所以为了使它成为可能:在你的例子中,使你的“大小”用于获得更新的URL非常大(想想:512个字符,最后填充空白)。这样,您就有了一些空间来更新String。

为什么不可能使用可变大小的字符串?好吧,我可以用一个小的x86汇编代码片段来解释这个:

PUSH OFFSET test.004024F0

让我们说;在test.004024F0的偏移处是您的可变大小的字符串。现在考虑一下这个改变:

  

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

您认为这很简单:搜索所有004024F5并将其替换为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; ...的代码,并将新的String值存储在指定的偏移量处。在编译时不知道此文件偏移量,您可以稍后使用OllyDbg之类的工具自行修补此文件偏移量。这使得可执行文件能够自行修补: - )

答案 3 :(得分:1)

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

答案 4 :(得分:1)

不想惩罚,但这听起来不是一个好主意。拥有用于检查程序内部更新的URL会使其不灵活。

您正试图通过重写exe​​中的字符串来减轻不灵活性。这真的是在寻找麻烦:

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

注册表(尽管存在所有缺点)实际上是这种配置数据应该去的地方。您可以在EXE中设置默认值,但如果需要进行更改,请将它们放在注册表中。这使得更改变得透明,以后会为您带来很多悲伤。

想要为更新编写新URL的Yyour算法应该通过将其写入注册表来实现。或者,有一个配置文件随您的exe一起发布,并更新它。 (但请记住用户权限 - 您可能没有该文件的写入权限,但您始终可以写入注册表的用户配置单元。)

答案 5 :(得分:1)

理论上,BeginUpdateResourceUpdateResourceEndUpdateResource就是为了这个目的。实际上,让这些工作完全是非常棘手的。我完全不确定他们是否可以在正在运行的可执行文件中更新资源。