我想要做的是使用版本签名(例如“1.2.0”)对编译后的可执行文件的前 32 个字节进行签名,并且我需要在运行时中修改此签名,请记住
- :将由可执行文件本身完成
- 可执行文件驻留在客户端,这意味着无法
- 使用外部文件来跟踪版本而不是在二进制文件本身中进行重新编译,也不是解决方案
- 必须独立于平台的选项;我知道 Windows/VC 允许您使用 .rc 资源对可执行文件进行版本控制,但我不知道 Mac(也许是 Info.plist?)和 Linux 的等效版本
我脑海中的解决方案是编写版本签名在二进制文件的前 32 个字节或最后 32 个字节中(我还没弄清楚如何做),然后我将在需要时修改这些字节。遗憾的是,事情并不那么简单,因为我正在尝试修改正在执行的相同二进制文件。
如果您知道我如何做到这一点,或者知道这个问题的更清洁/主流的解决方案,我将非常感激。 FWIW,该应用程序是游戏的补丁程序/启动器;我选择在修补程序本身而不是游戏可执行文件中对版本进行编码,因为我希望它是独立的且独立于目标。
更新:从您有用的答案和评论中,我发现弄乱二进制文件的页眉/页脚并不是正确的方法。但是对于运行用户的写入权限,游戏必须以某种方式打补丁并且需要修改游戏文件,没有办法规避这一点:要更新游戏,您需要管理员权限。
我会选择使用外部文件来保存签名,并在每次更新时对其进行修改,但我不知道如何防止用户使用该文件进行欺骗:如果他们弄乱了版本号,我如何检测我正在运行哪个版本?
更新2:感谢您的所有回答和评论,实际上有两种方法可以做到这一点:要么使用外部资源来跟踪版本,要么将其嵌入到主应用程序的二进制文件本身中。我只能选择 1 个答案,所以我做了我要选择的答案,尽管它不是唯一的答案。 :-)
What I'm trying to do is to sign my compiled executable's first 32 bytes with a version signature, say "1.2.0" and I need to modify this signature in runtime, keeping in mind that:
- this will be done by the executable itself
- the executable resides on the client side, meaning no recompilation is possible
- using an external file to track the version instead of encoding it in the binary itself is also not an option
- the solution has to be platform-independent; I'm aware that Windows/VC allows you to version an executable using a .rc resource, but I'm unaware of an equivalent for Mac (maybe Info.plist?) and Linux
The solution in my head was to write the version signature in the first or last 32 bytes of the binary (which I didn't figure out how to do yet) and then I'll modify those bytes when I need to. Sadly it's not that simple as I'm trying to modify the same binary that I'm executing.
If you know of how I can do this, or of a cleaner/mainstream solution for this problem, I'd be very grateful. FWIW, the application is a patcher/launcher for a game; I chose to encode the version in the patcher itself instead of the game executable as I'd like it to be self-contained and target-independent.
Update: from your helpful answers and comments, I see that messing with the header/footer of the binary is not the way to go. But regarding the write permission for the running users, the game has to be patched one way or another and the game files need to be modified, there's no way to circumvent that: to update the game, you'll need admin privileges.
I would opt for using an external file to hold the signature, and modify that with every update, but I can't see how I can guard against the user spoofing with that file: if they mess up the version numbers, how can I detect which version I'm running?
Update2: Thanks for all your answers and comments, in truth there are 2 ways to do this: either use an external resource to track the version or embed it in the main application's binary itself. I could choose only 1 answer on SO so I did the one I'm going with, although it's not the only one. :-)
发布评论
评论(4)
现代 Windows 版本不允许您更新已安装的程序文件,除非您以管理员权限运行。我相信所有版本的 Windows 都会完全阻止对正在运行的文件进行修改;这就是为什么您在更新后被迫重新启动的原因。我认为你在要求不可能的事情。
Modern Windows versions will not allow you to update an installed program file unless you're running with administrator privileges. I believe all versions of Windows block modifications to a running file altogether; this is why you're forced to reboot after an update. I think you're asking for the impossible.
由于多种原因,这将是一个挑战。首先,写入二进制文件的前 N 个字节很可能会涉及到二进制文件的头信息,程序加载器使用这些信息来确定代码和文件的位置。数据段等位于文件内。这在不同平台上会有所不同(请参阅 ELF 格式 和 可执行格式比较)——有很多不同的二进制格式标准。
假设您可以克服这一问题,那么如果您开始在运行时修改程序的代码,则可能会与安全/防病毒系统发生冲突。我不相信大多数当前的操作系统将允许您覆盖当前正在运行的可执行文件。至少,他们可能允许您以更高的权限执行此操作,而您不太可能在玩游戏时在场。
This is going to be a bit of a challenge, for a number of reasons. First, writing to the first N bytes of the binary is likely to step on the binary file's header information, which is used by the program loader to determine where the code & data segments, etc. are located within the file. This will be different on different platforms (see the ELF format and executable format comparison)--there are a lot of different binary format standards.
Assuming you can overcome that one, you're likely to run afoul of security/antivirus systems if you start modifying a program's code at runtime. I don't believe most current operating systems will allow you to overwrite a currently-running executable. At the very least, they might allow you to do so with elevated permissions--not likely to be present while gaming.
如果您的应用程序旨在修补游戏,为什么不在其中嵌入该版本呢?您可以使用 @Juliano 显示的字符串,并在游戏未运行时从修补程序中修改该字符串 - 如果您当前正在修补,则应该是这种情况。 :P
编辑:如果您使用 Visual Studio,根据 #pragma comment 在可执行文件中嵌入这样的字符串确实很容易“http://msdn.microsoft.com/en-us/library/7f0aews7%28v=VS.90%29.aspx”rel="nofollow">此 MSDN 页面:
由于第二个参数是一个简单的字符串文字,它可以连接,我将在一个简单的
#define
中获得版本:If your application is meant to patch a game, why not embed the version in there while you're at it? You can use a string like @Juliano shows and modify that from the patcher while the game is not running - which should be the case if you're currently patching anyways. :P
Edit: If you're working with Visual Studio, it's really easy to embed such a string in the executable with a
#pragma comment
, according to this MSDN page:Since the second argument is a simple string literal, it can be concatenated, and I'd have the version in a simple
#define
:我将给出一些关于如何做到这一点的想法。
我认为不可能在没有副作用的情况下更改可执行文件中的某些任意字节。为了克服这个问题,我会在源代码中创建一些字符串,例如:
我不知道这是否是规则,但您可以在二进制代码中查找该字符串(在文本编辑器中打开它,您会看到) 。因此,您可以在二进制文件中搜索并更改此字节以获取版本号。每次编译应用程序时,它们的位置可能都会有所不同,因此只有当该位置对您来说不是问题时才可能实现。
由于该文件正在被使用(它正在运行),因此您必须启动一个外部程序来执行此操作。修改文件后,该外部程序可以重新启动原始应用程序。
该版本将存储在您的二进制代码的某些部分。那有用吗?您将如何检索版本号?
I'll give just some ideas on how to do this.
I think it's not possible to change some arbitrary bytes in the executable without side effects. To overcome this, I would create some string in your source code, like:
I don't know if this is a rule, but you can look for this string in your binary code (open it in a text editor and you will see). So, you search and change this bytes for your version number in the binary file. Probably, their position will vary each time you compile the application, so this it is possible only if that location is not a problem for you.
Because the file is being used (it's running), you have to launch an external program that would do this. After modifying the file, this external program could relaunch the original application.
The version will be stored in your binary code in some part. Is that useful? How will you retrieve the version number?