Discussion:
Extracting a resource from an exe file & adding it back in
Reinier Olislagers
2011-10-15 12:26:39 UTC
Permalink
Hi list,

I've created a zip file with some files in it, then compiled these as a
(Windows x86) resource using this .rc script:
// Configuration file for
// executable files required by checkride
//fields: resource name/resource type/resource filename

//all compressed in one zip:
ALL CR_EMB_FILE helped.zip

(Created my own resource type because that seemed the only way)

I want to give users an editor to edit a text file inside helped.zip &
save the changes back to the executable.

Therefore, I'm looking for a way to extract the compressed resource to a
zip, extract the zip, let the user edit the file, zip it back up and add
it back into the executable.

1. Can I load the exe into a stream and then copy that over to a
TResourceStream? If so, I can do the extracting/editing.
2. I suppose I'd have to call windres.exe to extract the .rc file from
the resource*) & compile the zipped resource back into the exe. Can I do
that & overwrite the exiting resources in the exe?
3. Is there a better way to do all this?

*) Of course, I have the resource .rc file in my source directory, but
perhaps the user wants to edit a different version of my program that
has other resources...

Of course, I could try out 1 & 2, but if you guys have an answer to step
3, that may be work down the drain...

Thanks a lot,
Reinier

--
Hans-Peter Diettrich
2011-10-15 14:48:56 UTC
Permalink
Post by Reinier Olislagers
Hi list,
I've created a zip file with some files in it, then compiled these as a
// Configuration file for
// executable files required by checkride
//fields: resource name/resource type/resource filename
ALL CR_EMB_FILE helped.zip
(Created my own resource type because that seemed the only way)
I want to give users an editor to edit a text file inside helped.zip &
save the changes back to the executable.
You'll run into a couple of problems:

- An executable cannot update itself (at runtime).
- A resource editor or compiler tool is needed, which may not be
available on every platform.
- The user must have write permissions for the executable file.

DoDi


--
Reinier Olislagers
2011-10-16 17:31:02 UTC
Permalink
Post by Hans-Peter Diettrich
Post by Reinier Olislagers
I want to give users an editor to edit a text file inside helped.zip &
save the changes back to the executable.
Thanks for your answer, DoDi, please see below.
Post by Hans-Peter Diettrich
- An executable cannot update itself (at runtime).
I know. CheckRideHelper is going to update CheckRide.exe
Post by Hans-Peter Diettrich
- A resource editor or compiler tool is needed, which may not be
available on every platform.
Yep, I guess I'm looking for a scriptable one ;)
As of now, my tool only works on Windows; the compressed resource
includes winvnc.exe and stunnel.exe. For Linux, I'll have a lot less
problems in this respect as I'll just specify a VNC flavour (or two) and
stunnel as dependencies.
Post by Hans-Peter Diettrich
- The user must have write permissions for the executable file.
Yep.

Regards,
Reinier

--
waldo kitty
2011-10-17 14:28:48 UTC
Permalink
Post by Hans-Peter Diettrich
Post by Reinier Olislagers
I want to give users an editor to edit a text file inside helped.zip &
save the changes back to the executable.
- An executable cannot update itself (at runtime).
why not? i have several projects that are in line to be ported to FPC/Lazarus...
they store certain config values within them which are read and altered on each
execution... why can we not do this now? what is missing??
Post by Hans-Peter Diettrich
- A resource editor or compiler tool is needed, which may not be available on
every platform.
- The user must have write permissions for the executable file.
--
Sven Barth
2011-10-17 14:58:27 UTC
Permalink
Post by waldo kitty
Post by Hans-Peter Diettrich
Post by Reinier Olislagers
I want to give users an editor to edit a text file inside helped.zip &
save the changes back to the executable.
- An executable cannot update itself (at runtime).
why not? i have several projects that are in line to be ported to
FPC/Lazarus... they store certain config values within them which are
read and altered on each execution... why can we not do this now? what
is missing??
On Linux there should be no problem (don't know about other POSIX
systems), but on Windows there is the problematic point that the binary
is opened as "share deny write" from Windows (that's why Lazarus
generates a "lazarus.new.exe" when compiling itself). It could be though
that you can open the executable within itself as writeable, I have
never tried this, so it should work.

In sum: the problem is not on FPC side, but on OS side.

Regards,
Sven


--
waldo kitty
2011-10-17 15:07:03 UTC
Permalink
Post by waldo kitty
Post by Hans-Peter Diettrich
Post by Reinier Olislagers
I want to give users an editor to edit a text file inside helped.zip &
save the changes back to the executable.
- An executable cannot update itself (at runtime).
why not? i have several projects that are in line to be ported to
FPC/Lazarus... they store certain config values within them which are
read and altered on each execution... why can we not do this now? what
is missing??
On Linux there should be no problem (don't know about other POSIX systems), but
on Windows there is the problematic point that the binary is opened as "share
deny write" from Windows (that's why Lazarus generates a "lazarus.new.exe" when
compiling itself). It could be though that you can open the executable within
itself as writeable, I have never tried this, so it should work.
i'll have to take a look at that (very) old code and see how it does it... it
may very well open the exe and hunt thru it (from back to front) looking for the
data section in question...
In sum: the problem is not on FPC side, but on OS side.
ahhh... ok... i was thinking that it was maybe something in the (new to me)
executable format... what has been being used has been able to be done
specifically due to the way and location that TP/BP stores constants in the exe ;)


--
Reinier Olislagers
2011-10-16 17:46:52 UTC
Permalink
Post by Reinier Olislagers
Hi list,
Therefore, I'm looking for a way to extract the compressed resource to a
zip, extract the zip, let the user edit the file, zip it back up and add
it back into the executable.
1. Can I load the exe into a stream and then copy that over to a
TResourceStream? If so, I can do the extracting/editing.
2. I suppose I'd have to call windres.exe to extract the .rc file from
the resource*) & compile the zipped resource back into the exe. Can I do
that & overwrite the exiting resources in the exe?
Step 2: of course I could just compress the .rc file used for generating
the resource in the first place, and use that when recompiling the
resource ;)

I've had a look see and there is some (Delphi) code that uses the Win
API calls BeginUpdateResource/EndUpdateResource. I've copied it below.
I noticed jwawinbase.pas defines this as well as unifun.inc/ascfun.inc

Other options:
- use windres.exe but it will only extract resources as hex dumps. I'd
need to convert that (or do step 1)
- use another editor such as resedit (haven't tested that yet)

I'll fiddle around with these options unless somebody has a better
solution ;)

Source:
http://www.delphi3000.com/articles/article%5F3215.asp
This little snippet works great for small files, but for some currently
unknown reason it screws up the exe file when you try to add a large
resource on 1mb. If anyone know how to bypass this, please post a little
note on how to do this! :)


Uses Classes, Windows, SysUtils, Dialogs;

Type
TBuffer = Array[0..0] of Byte;
PBuffer = ^TBuffer;

Var
FS : TFileStream;
ResourceHandle : THandle;
DataLength : DWord;
Data : PBuffer;
Ok : Boolean;

Begin
ResourceHandle := BeginUpdateResource(pChar('d:\someexefile.exe'),
False);
IF (ResourceHandle <> 0) Then
Begin
FS := TFileStream.Create('d:\somebitmap.bmp', fmOpenRead);
FS.Seek(0, soFromBeginning);
DataLength := FS.Size;
GetMem(Data, DataLength);
FS.Read(Data^, DataLength);
FS.Free;

Ok := True;
//Passing nil (I suppose 0 in Delphi) as the lpData parameter will
cause the resource to be deleted.
IF (not UpdateResource(ResourceHandle, RT_RCDATA,
pChar('MyNewResource'), LANG_SYSTEM_DEFAULT{MakeLangID(LANG_NEUTRAL,
SUBLANG_NEUTRAL)}, Data, DataLength)) Then Ok := False;


IF (not EndUpdateResource(ResourceHandle, False)) Then Ok := False;


IF (Ok) Then ShowMessage('Update of resources successful!')
Else ShowMessage('Update of resources failed!');


FreeMem(Data);
End;
End.

--
Hans-Peter Diettrich
2011-10-16 20:52:51 UTC
Permalink
Post by Reinier Olislagers
http://www.delphi3000.com/articles/article%5F3215.asp
This little snippet works great for small files, but for some currently
unknown reason it screws up the exe file when you try to add a large
resource on 1mb. If anyone know how to bypass this, please post a little
note on how to do this! :)
You may find different problems or limits on every Windows version :-(

DoDi


--
Reinier Olislagers
2011-10-24 10:57:31 UTC
Permalink
Post by Hans-Peter Diettrich
Post by Reinier Olislagers
http://www.delphi3000.com/articles/article%5F3215.asp
This little snippet works great for small files, but for some currently
unknown reason it screws up the exe file when you try to add a large
resource on 1mb. If anyone know how to bypass this, please post a little
note on how to do this! :)
You may find different problems or limits on every Windows version :-(
Well, I hit a limit on Windows Vista x64 with FPC fixes_2_6, Lazarus
SVN. Don't know if it's different on other versions...

I could extract the resources using e.g. resedit, but saving them back
in led to a corrupted exe that wouldn't run.

Don't know if it's bug
16852: Resource section comes before the relocation table in dlls
produced by FPC
or something else (PICNIC/PEBKAC ;) but I've given up for now.

People wanting to customize my program should just recompile the entire
thing...

Regards,
Reinier


--

Loading...