Edit strings vars in compiled exe? C++ win32
I want to have a few strings in my c++ app and I want to be able to edit them later in the deployed applications (the compiled exe), Is there a way to make the exe edit itself or it resources开发者_StackOverflow社区 so I can update the strings value?
The app checks for updates on start, so I'm thinking about using that to algo send the command when I need to edit the strings (for example the string that contains the url used to check for updates).
I don't want to use anything external to the exe, I could simply use the registry but I prefer to keep everything inside the exe.
I am using visual studio 2010 c++ (or any other version of ms visual c++).
I know you said you don't want to use anything external to the program, but I think what you really want in this case is a resource-only DLL. The executable can load whichever DLL has the strings that you need in a given invocation.
Another idea is to move the strings into a "configuration" file, such as in XML or INI format.
Modifying the EXE without compilation is hacking and highly discouraged. You could use a hex editor, find the string and modify it. The new text must be have a length less than or equal to the original EXE.
Note, some virus checkers perform CRCs or checksums on the executables. Altering the executables is a red flag to these virus checkers.
It is impossible, unless your strings won't change in position & length.
So to make it possible: make your "size" of the, in your example, URL that is used to get updates pretty big (think of: 512 characters, null-filled at the end). This way, you have got some space to update the String.
Why is it impossible to use variable-sized strings? Well I can explain this with a small x86 Assembler snippet:
PUSH OFFSET test.004024F0
Let's say; at the offset of test.004024F0
is your variable-sized string. Now consider the change:
I want to insert a string, which is longer than the original string, which is stored before the string at
004024F0
: This makes004024F0
to a new value, let's say:004024F5
(the new string, before this entry, is 5 characters longer than it's original).
You think it's simple: search for all 004024F0
and replace it with 004024F5
? Wrong. 004024F0
can also be a regular "instruction" (to be precise: ADD BYTE PTR DS:[EAX+24],AL; LOCK ...
). If this instruction happens to be in your code, it'll be replaced by something wrong.
Well, you might think, what about searching for that PUSH
instruction? Wrong: there are virtually unlimited ways to "PUSH". For instance, MOV EAX, 004024F0; MOV ESP, EAX; ADD ESP, 4
. There is also the possibility that the field is calculated: MOV EAX, 00402000; ADD EAX, 4F0; ...
. So this makes it "virtually unlimited".
However, if you use statically sized fields; you don't have to change the code refering to Strings. If you reserve enough space of a specific field, then you can easily write a "longer" string than original, because the size of a string is calculated by finding the first "null-byte"; pad the rest of the field with nulls.
If you use statically sized fields, it's, however, very hard to find the "position in the file", at compile-time. Considering a lot of time spending hacking your own app; you can write code that modifies the .exe
, and stores a new String value at a specified offset. This file-offset isn't known at compile time, and you can patch this file-offset yourself later, using a tool like OllyDbg. This enables the executable to patch itsself :-)
Creating a self-editing exe is a very ill-advised approach to solving this problem. You are much better off storing and reading the strings from an external file. Maybe if you provide some background as to why you don't want to use anything but an exe, we can address those issues?
In theory, BeginUpdateResource
, UpdateResource
and EndUpdateResource
are intended for this purpose. In reality, getting these to work at all is pretty tricky. I'm not at all sure they'll work for updating resources in a running executable.
Not wanting to chastise, but this doesn't sound like a great idea. Having the URL for checking for updates baked inside the program makes it inflexible.
You're trying to mitigate the inflexibility by rewriting the strings in your exe. This is really asking for trouble:
- are you sure users that run your program have write permission to be able to update the exe? Default users have no write access to files installed in the program folder.
- If the program is run by multiple users or simply multiple times by the same user, the exe will be locked and unmodifiable
- Systems administrators will have a hard time tweaking the URL.
- There is a real risk you will corrupt your exe. The rewrite process is likely to be complex, especially if you want to make the URL longer than is presently allocated.
- By modifying your exe, you remove the possiblity of using code signing, which can be useful in a networked environment.
The registry (despite all it's weaknesses) is really where this kind of configuration data should go. You can put a default value in your EXE, but if you need to make changes, put them in the registry. This makes the changes transparent, saving you a lot of grief later.
Yyour algorithm that wants to write a new URL for updates should do this by writing it to the registry. Alternatively, have a config file that ships alongsite with your exe, and update that. (But bear in mind user permissions - you may not have write access to that file, but you can always write to the user hive of the registry.)
精彩评论