[Lazarus] Extracting a resource from an exe file & adding it back in

Reinier Olislagers reinierolislagers at gmail.com
Sun Oct 16 19:46:52 CEST 2011


On 15-10-2011 14:26, Reinier Olislagers wrote:
> 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.




More information about the Lazarus mailing list