Recent

Author Topic: Add executable to my resource file then shell execute it [Solved]  (Read 5501 times)

jw

  • Full Member
  • ***
  • Posts: 126
How would I add an executable to my resource file and then shell execute it when the user hits the right button?  Say for example, I have the executable for a cool little stand alone freeware game that I'd like to use as an easter egg in my program.  How would I make that executable a resource that my code could then shell execute?


Regards
JW
« Last Edit: January 29, 2019, 08:10:41 pm by jw »

flowCRANE

  • Hero Member
  • *****
  • Posts: 937
For convenient resource management you can use the project options window. In this windows, select the Project Options/Resources branch and add the required files with a few clicks.

In your source code, load this program from resources via TResourceStream, save it to a disk file and open it normally. Problems? Read this — Using resources in your program.
« Last Edit: January 29, 2019, 02:35:17 am by furious programming »
Lazarus 4.2 with FPC 3.2.2, Windows 11 — all 64-bit

Working solo on a top-down retro-style action/adventure game (pixel art), programming the engine from scratch, using Free Pascal and SDL3.

jamie

  • Hero Member
  • *****
  • Posts: 7603
Please keep your Easter eggs to yourself.

I know exactly how to do that, but I'll reframe from broadcasting it..
The only true wisdom is knowing you know nothing

mercurhyo

  • Sr. Member
  • ****
  • Posts: 255
I know 3 WAYS to do that but it opens hackers' pandora box
by difficulty order :
1) copy resource to a temp exe file
2) use special linker that hacks GDT/LDT (global mem permissions table)
3) shhhhh héhéhéhéhhéhêhèhê !!!! :D :D :D
« Last Edit: January 29, 2019, 05:44:14 am by mercurhyo »
DEO MERCHVRIO - Fedora PlasmaKDE, Win11pro - Ryzen9XT+Geforce Rtx 3080SUPRIM
god of financial gain, commerce, eloquence (and thus poetry), messages, communication (including divination), travelers, boundaries, luck, trickery and thieves; he also serves as the guide of souls to the underworld

mercurhyo

  • Sr. Member
  • ****
  • Posts: 255
DEO MERCHVRIO - Fedora PlasmaKDE, Win11pro - Ryzen9XT+Geforce Rtx 3080SUPRIM
god of financial gain, commerce, eloquence (and thus poetry), messages, communication (including divination), travelers, boundaries, luck, trickery and thieves; he also serves as the guide of souls to the underworld

jw

  • Full Member
  • ***
  • Posts: 126
Hmm, how unfortunate.  Labeled a villain for no good reason.. 

They ways I know how to do it are...

1) Put some magic bytes at the end of my compiled program then copy the easter executable to the end of my program and then, from within my executable, look for my magic bytes and copy the easter exe to a temp file and execute it. 

2) convert the easter egg file to an array, write the array to file, execute..

3) Create my program as a dll and inject it into the exe with some easily found tools..

4) write my own loader like a virus does, but that's a bit beyond me, as I've never fully understood the PE format, and I've never really understood the loaders written in assembly. 

The reason I thought about including the exe as a resource file is because I've never used a resource file before, and I figured I could execute an exe from it without having to copy it out..  If that makes me evil then so be it.
« Last Edit: January 29, 2019, 08:12:04 pm by jw »

balazsszekely

  • Guest
@jw
Quote
Hmm, how unfortunate.  Labeled a villain for no good reason..
This kind of request are always suspicius, but don't worry I was a "villain" once too, so maybe this helps:
http://forum.lazarus.freepascal.org/index.php/topic,28456.msg178004.html#msg178004
Please note you cannot inject a 32 bit dll into a 64 bit process and vice versa. Make sure both the dll and the taget process are the same bitness.
« Last Edit: January 29, 2019, 07:09:38 am by GetMem »

mercurhyo

  • Sr. Member
  • ****
  • Posts: 255
@jw add bytes to an exe file = 99.99% antivirus are going to dance the jerk >:D with "magic" bugs
« Last Edit: January 29, 2019, 09:02:40 am by mercurhyo »
DEO MERCHVRIO - Fedora PlasmaKDE, Win11pro - Ryzen9XT+Geforce Rtx 3080SUPRIM
god of financial gain, commerce, eloquence (and thus poetry), messages, communication (including divination), travelers, boundaries, luck, trickery and thieves; he also serves as the guide of souls to the underworld

balazsszekely

  • Guest
I agree with @mercurhyo, the detection rate is high on windows. As a proof of concept, download the following attachment(with little modification works on linux too):
1. Build the main application(Shift + F9). Don't run it yet.
2. Build the easter egg(Shift + F9). Don't run it.
3. Build the third executable(WriteToExe)
4. Close Lazarus
5. Run WriteToExe, write the easter egg to the main application
6. Run the main application, press the "Show easter egg button"

PE: Please note: the project does not manipulate PE headers or anything, it's not a malware. The extracting method is very similar to TResourceStream.
« Last Edit: January 29, 2019, 09:52:14 am by GetMem »

sash

  • Sr. Member
  • ****
  • Posts: 366
If you want to run your code from your code, and everything is contained in a single file, why don't you use a regular procedure call?

If you're trying to "embed" 3rd party application (even if it is "freeware") in your one, probably you're violating rights of that application author.
Lazarus 2.0.10 FPC 3.2.0 x86_64-linux-gtk2 @ Ubuntu 20.04 XFCE

Mr.Madguy

  • Hero Member
  • *****
  • Posts: 881
Re: How would I add an executable to my resource file then shell execute it
« Reply #10 on: January 29, 2019, 02:30:25 pm »
I saw such behavior in old versions of ProcessExplorer back in old days, so I wanted to reproduce it. Here is my solution:
Code: Pascal  [Select][+][-]
  1. program Launcher;
  2.  
  3. {$R 'Program.res' 'Program.rc'}
  4.  
  5. uses
  6.   Windows,
  7.   SysUtils,
  8.   ShellAPI,
  9.   Classes;
  10.  
  11. {$R *.res}
  12.  
  13. type
  14.   TIsWOW64Process = function(hProcess:THandle;var IsWOW64:Boolean):Boolean;stdcall;
  15.  
  16. const
  17.   FileName = 'Program.exe';
  18.   Res32 = 'Program32';
  19.   Res64 = 'Program64';
  20.  
  21. function GetTempFolder: String;
  22. var
  23.   Buffer: array [0..MAX_PATH+1] of WideChar;
  24. begin
  25.   GetTempPath(MAX_PATH, Buffer);
  26.   Result := IncludeTrailingPathDelimiter(String(Buffer));
  27. end;
  28.  
  29. function Is64Process:Boolean;
  30.   var Kernel:HMODULE;IsWOW64Process:TIsWOW64Process;Temp:Boolean;
  31. begin
  32.   Result := false;
  33.   Kernel := LoadLibrary('kernel32');
  34.   if Kernel = 0 then Exit;
  35.   IsWOW64Process := GetProcAddress(Kernel, 'IsWow64Process');
  36.   if not Assigned(IsWow64Process) then Exit;
  37.   IsWOW64Process(GetCurrentProcess, Temp);
  38.   Result := Temp;
  39.   FreeLibrary(Kernel);
  40. end;
  41.  
  42. var ResName, FilePath, Params:String;
  43.   Source:TResourceStream;Dest:TStream;
  44.   I:Integer;StartupInfo:TStartupInfo;
  45.   ProcessInfo:TProcessInformation;
  46.  
  47. begin
  48.   if Is64Process then begin
  49.     ResName := Res64;
  50.   end
  51.   else begin
  52.     ResName := Res32;
  53.   end;
  54.   FilePath := GetTempFolder + FileName;
  55.   Source := TResourceStream.Create(hInstance, ResName, RT_RCDATA);
  56.   Dest := TFileStream.Create(FilePath, fmCreate);
  57.   Dest.CopyFrom(Source, 0);
  58.   Dest.Write(Source.Memory, Source.Size);
  59.   Dest.Free;
  60.   Source.Free;
  61.   Params := '"'+FilePath+'"';
  62.   for I := 1 to ParamCount do begin
  63.     Params := Params + ' ' + ParamStr(I);
  64.   end;
  65.   GetStartupInfo(StartupInfo);
  66.   if CreateProcess(PWideChar(FilePath),
  67.     PWideChar(Params),
  68.     nil,
  69.     nil,
  70.     false,
  71.     CREATE_UNICODE_ENVIRONMENT,
  72.     nil,
  73.     PWideChar(GetCurrentDir),
  74.     StartupInfo,
  75.     ProcessInfo) then begin
  76.       if ProcessInfo.hProcess <> 0 then begin
  77.         WaitForSingleObject(ProcessInfo.hProcess, INFINITE);
  78.       end;
  79.   end;
  80.   DeleteFile(FilePath);
  81. end.
  82.  
And Program.rc:
Code: [Select]
Program32 RCDATA ..\Program\Win32\Release\Program.exe
Program64 RCDATA ..\Program\Win64\Release\Program.exe
You need to manually delete Program.res to update it, if Program.exe is modified.
Is it healthy for project not to have regular stable releases?
Just for fun: Code::Blocks, GCC 13 and DOS - is it possible?

flowCRANE

  • Hero Member
  • *****
  • Posts: 937
Re: How would I add an executable to my resource file then shell execute it
« Reply #11 on: January 29, 2019, 06:35:22 pm »
@jw: simple example below (not tested on 64-bit Windows).

Add your application to resources via project options window (see attachment), then write few lines of code. Create output file stream, create resource stream and load file from resources, then copy the content of resource stream to the file stream and free both. After that, create process, fill the properties and run extracted executable.

Example code:

Code: Pascal  [Select][+][-]
  1. uses
  2.   LCLType, Classes, Process;
  3.  
  4. procedure TMainForm.CRunButtonClick(Sender: TObject);
  5. var
  6.   Output: TFileStream;
  7.   Resource: TResourceStream;
  8. var
  9.   Colorization: TProcess;
  10. begin
  11.   Output := TFileStream.Create('colorization.exe', fmCreate);
  12.   Resource := TResourceStream.Create(HINSTANCE, 'COLORIZATION', RT_RCDATA);
  13.   try
  14.     Output.CopyFrom(Resource, Resource.Size);
  15.   finally
  16.     Output.Free();
  17.     Resource.Free();
  18.   end;
  19.  
  20.   Colorization := TProcess.Create(nil);
  21.   try
  22.     Colorization.Executable := 'colorization.exe';
  23.     Colorization.Execute();
  24.   finally
  25.     Colorization.Free();
  26.   end;
  27. end;

If necessary, delete the executable file after closing the program (this unpacked from resources).
« Last Edit: January 29, 2019, 06:42:23 pm by furious programming »
Lazarus 4.2 with FPC 3.2.2, Windows 11 — all 64-bit

Working solo on a top-down retro-style action/adventure game (pixel art), programming the engine from scratch, using Free Pascal and SDL3.

jw

  • Full Member
  • ***
  • Posts: 126
Re: How would I add an executable to my resource file then shell execute it
« Reply #12 on: January 29, 2019, 08:09:34 pm »
Thanks for all the help folks, lots of good tricks.
As far as magic bytes, and even an array, yes that would trip virus scanners, especially the ones using heuristics to determine exe infection.  Which, though I didn't mention it, is why I'd implement a simple xor encryption/decryption scheme on the appended file, or array.

I do wonder though, if adding the exe file to my resource file will result in a compiled program that angers virus scanners anyway.  I could imagine them labeling it as some sort of evil dropper.   

Furthermore, though my question used the word shellexececute, that was only used because I ran out of room in the title.  I was actually wondering if there was a way to get tprocess(http://wiki.freepascal.org/Executing_External_Programs#TProcess) to execute a tfilestream via the conversion of TResourceStream.  I figured, Since tprocess is a cross platform component, perhaps it bypasses the native OS's pe / elf loader, doing everything itself...  Similar to the loader most graciously posted by Mr.Madguy.

lucamar

  • Hero Member
  • *****
  • Posts: 4217
Re: How would I add an executable to my resource file then shell execute it
« Reply #13 on: January 29, 2019, 08:28:42 pm »
I figured, Since tprocess is a cross platform component, perhaps it bypasses the native OS's pe / elf loader, doing everything itself...  Similar to the loader most graciously posted by Mr.Madguy.

Being cross-platform means that TProcess uses each system's preferred way of executing binaries: In Unix it uses fork/execv, in Windows CreateProcess, and so on. Quite the contrary of "bypassing" :)

ETA Regarding this:
Quote
Furthermore, though my question used the word shellexececute, that was only used because I ran out of room in the title.  I was actually wondering if there was a way to get tprocess(http://wiki.freepascal.org/Executing_External_Programs#TProcess) to execute a tfilestream via the conversion of TResourceStream.

No, there is no way; TProcess is meant to deal only with executable files stored in disk.
« Last Edit: January 29, 2019, 08:36:22 pm by lucamar »
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus/FPC 2.0.8/3.0.4 & 2.0.12/3.2.0 - 32/64 bits on:
(K|L|X)Ubuntu 12..18, Windows XP, 7, 10 and various DOSes.

 

TinyPortal © 2005-2018