Link to home
Start Free TrialLog in
Avatar of ALoneBoy
ALoneBoy

asked on

How can i embed an executable file in my Application and run it in runtime WITHOUT extracting it?

Hi there
I'm a delphi, C#, JBuilder programmer.
I need to embed an exe file into my application. I did it and i can extract it into Hard disk and run it.
But I need to run this exe file WITHOUT extracting it to harddisk.
I want to run it axactly from Main file [An application that i embed my exe file into it].
This file is so important and it must be under protection by my Application.
Please guide me how can I execute this file WITHOUT extracting or saving it?
Special Thanks to you dear Expert
AloneBoy
Avatar of CodedK
CodedK
Flag of Greece image

Hi

The only way (and i dont know if this can be done) is to deploy the exe code into memory but... its too easy to dump the memory even with freeware tools !

Maybe you find this useful :
https://www.experts-exchange.com/questions/11625698/execute-program-direct-from-memory.html

I think you should try some exe protector / encryption.
You can compress/encrypt your file with some application like Asprotect...
Embed your file to your application... Run it (it will load in memory and also it will protect this memory space using anti-dump tech) and then delete it.

Hope this helps.
1. how big is the embedded program?
2. how complicated is the embedded program?
3. how long will the code run?
4. is the code reused or run once?
5. Jay Cole wrote a Delphi Informant article back in the 90s about creating object (assembly) code in a memory stream and then transferring control to it.

Here is a recently closed discussion of executable protection options:
https://www.experts-exchange.com/questions/22394594/What-is-the-best-protector-for-exe-against-cracker.html
=======================
CodeK is correct to point out that once the executable has been placed into memory, any hacker/cracker can dump it and start the reverse engineering process with a variety of tools.
See: http://www.maxcomponents.net/components.html#RESOURCESTORE

TmxResourceStore
Features:

It can store files on your forms
Compression support
Can extract files from executable file at run-time
You can access to stored files directly from memory
Full source code available
 
@Eddie,

I don't think the challenge is packaging and distributing the embedded executable as much as it is:
* mimic the actions of the Windows PE loader
* protect the memory stream bytes from crackers and hackers
Avatar of ALoneBoy
ALoneBoy

ASKER

Any Exe protector (that encrypt exe files) saves that exe on temp dir or ... and then run it. I know it.
I dont want to use them.
1.Embeded file size: Its free for every size (But not so big)
2.Comlicated? I dont think so. It can be every simple program
3. Run time length?  Unknown (a minute or a day and no longer)
4. It run once and there is no change for it or its used other files
Not all commercial PE wrappers/packers use a temp file.  If that is your concern, do a little more shopping.

I'm not sure about your answers.  It reads as if you are trying to create a commercial product to do this wrapping/packing for any executable.

Maybe its time to step back and have you explain the 'big picture' of your PE processing needs.  In this case, include the purpose/functions performed by the embedded executable.
>> Any Exe protector (that encrypt exe files) saves that exe on temp dir or ... and then run it

If that was the case then there would be no need to encrypt it...
Asprotect for example decrypts parts of the application in memory and protects this memory space from any tampering...
CodedK  -> I check you link at first answer.
that Question looking like me...
but the accepted answer is not so clearly !!!???

It says that
""""""
1) Uncompress the file into position, just as LoadLibrary would, that is expand the data according to section boundary.

2) Use VirtualProtect to set the attributes for each section according to what's in the PE header: readable/writeable/executable, etc.

3) Relocate the EXE according to the new base address. This may fail normally becasue EXE normally does not have relocation table attached in release mode. You may want to make sure your original program has a strange base address such that it will not conflict with normal EXE base address.

4) Load all imported DLL into memory, resolve all import reference, recursively.

5) Shut-down your original program as much as possible.

6) Jump to the entry point of the 'loaded' program.
""""""""""
OK. I load my exe to a Stream.
Now what I must do?
I must use CreateFileMapping ????
Its not so clear for me, can you guide me more?
Big Picture of my problem:

1. Embed an exe file (every simple exe file)  into my own application [Its Done !!!]
2. Load embede exe into Stream [Its Done !!!]
3. Run this exe exactly from this stream [The problem is here]
I found something ... different.
Save the file in the end of your file and call it dynamically ...
I didn't check it and i don't know if it is of any help...

Here is the link :
http://www.swissdelphicenter.ch/en/showcode.php?id=2427

About running the file from memory... i cant help you. I wish i new.
codedk
i saw it before
but it can also laod it to memory, but it cant run it from memory
Anymore, I'll check it more again
@ALoneBoy

<<Big Picture of my problem:>>

Those items are NOT a big picture.  You are asking us how-to questions.  I'm asking you to tell us why you need to do this.  Please review my prior comment.  You haven't told us anything about the purpose of this embedded executable nor the relationship with the (containing) executable.
ASKER CERTIFIED SOLUTION
Avatar of 2266180
2266180
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
:D i have the same problems too with this new interface ...
-> ciuly
Hi there
OK. Sounds good
but there are 2 question!
1. Where is this damn CreateprocessEx unit or dll ?
2. This function can the stream on HD and then run it. isn't it?
@ALoneBoy

You should ask all your questions and be satisfied that you have a solution *BEFORE* you accept one of these comments.
aikimark is correct. personally, I was out of town for almost 2 days. you should take that into consideration when somebody doesn't reply for more than 24 hours, especially if it's the weekend. we do have a personal life and not sitting 24/7 on EE.

anyway,
1) deltaziz says in that paq: "don't forget to include CreateProcessEX from the link above". so if you look at the link I provided in that paq, you will find the createprocessex procedure.
2) that function uses a stream. a stream can be anything, from a memory stream, filestream, blobstream, serial stream, etc. so yes, it can use a file stream.
ciuly

What's a "personal life"?  I've heard several folks mention that, but I'm not sure what it is.  

Is it an extension to Half Life? (Full-Cup Productions)

Is it that monogram service where you send them something and they personalize it for you?

It's so dark and dank down here in the coding dungeon.
you usually get that after you get married ;) though I heard some people have it before too. it's sometimes kind of boring if you ask me, but as my wife says "we need to ..." (notice the "we" part and then the "need" part. of course sometimes it's fun and interesting too) I wouldn't be able to decide though if I have to choose between keeping it or getting lost in the "coding dungeon"...
"Is it an extension to Half Life? (Full-Cup Productions)" <- this would be nice :D
in case you haven't realized it already, your wife is using the royal "we".
"Dear aikimark" I thank you for helping me,
But I get my answers from that link before "ciuly" reply to me.
So, I did that and then I accept that Solution.

The Solution is here from DeltaAziz (His or Her name is looking like a Moslem's name !!!)

************************************************************************************
type
  TSections = array [0..0] of TImageSectionHeader;

{$IMAGEBASE $10000000}

function GetAlignedSize(Size: dword; Alignment: dword): dword;
begin
  if ((Size mod Alignment) = 0) then
    Result := Size;
  else
    Result := ((Size div Alignment) + 1) * Alignment;
end;

function ImageSize(Image: pointer): dword;
var
  Alignment: dword;
  ImageNtHeaders: PImageNtHeaders;
  PSections: ^TSections;
  SectionLoop: dword;
begin
  ImageNtHeaders := pointer(dword(dword(Image)) + dword(PImageDosHeader(Image)._lfanew));
  Alignment := ImageNtHeaders.OptionalHeader.SectionAlignment;
  if ((ImageNtHeaders.OptionalHeader.SizeOfHeaders mod Alignment) = 0) then
  begin
    Result := ImageNtHeaders.OptionalHeader.SizeOfHeaders;
  end
  else
  begin
    Result := ((ImageNtHeaders.OptionalHeader.SizeOfHeaders div Alignment) + 1) * Alignment;
  end;
  PSections := pointer(pchar(@(ImageNtHeaders.OptionalHeader)) + ImageNtHeaders.FileHeader.SizeOfOptionalHeader);
  for SectionLoop := 0 to ImageNtHeaders.FileHeader.NumberOfSections - 1 do
  begin
    if PSections[SectionLoop].Misc.VirtualSize <> 0 then
    begin
      if ((PSections[SectionLoop].Misc.VirtualSize mod Alignment) = 0) then
      begin
        Result := Result + PSections[SectionLoop].Misc.VirtualSize;
      end
      else
      begin
        Result := Result + (((PSections[SectionLoop].Misc.VirtualSize div Alignment) + 1) * Alignment);
      end;
    end;
  end;
end;

procedure CreateProcessEx(FileMemory: pointer);
var
  BaseAddress, Bytes, HeaderSize, InjectSize,  SectionLoop, SectionSize: dword;
  Context: TContext;
  FileData: pointer;
  ImageNtHeaders: PImageNtHeaders;
  InjectMemory: pointer;
  ProcInfo: TProcessInformation;
  PSections: ^TSections;
  StartInfo: TStartupInfo;
begin
  ImageNtHeaders := pointer(dword(dword(FileMemory)) + dword(PImageDosHeader(FileMemory)._lfanew));
  InjectSize := ImageSize(FileMemory);
  GetMem(InjectMemory, InjectSize);
  try
    FileData := InjectMemory;
    HeaderSize := ImageNtHeaders.OptionalHeader.SizeOfHeaders;
    PSections := pointer(pchar(@(ImageNtHeaders.OptionalHeader)) + ImageNtHeaders.FileHeader.SizeOfOptionalHeader);
    for SectionLoop := 0 to ImageNtHeaders.FileHeader.NumberOfSections - 1 do
    begin
      if PSections[SectionLoop].PointerToRawData < HeaderSize then HeaderSize := PSections[SectionLoop].PointerToRawData;
    end;
    CopyMemory(FileData, FileMemory, HeaderSize);
    FileData := pointer(dword(FileData) + GetAlignedSize(ImageNtHeaders.OptionalHeader.SizeOfHeaders, ImageNtHeaders.OptionalHeader.SectionAlignment));
    for SectionLoop := 0 to ImageNtHeaders.FileHeader.NumberOfSections - 1 do
    begin
      if PSections[SectionLoop].SizeOfRawData > 0 then
      begin
        SectionSize := PSections[SectionLoop].SizeOfRawData;
        if SectionSize > PSections[SectionLoop].Misc.VirtualSize then SectionSize := PSections[SectionLoop].Misc.VirtualSize;
        CopyMemory(FileData, pointer(dword(FileMemory) + PSections[SectionLoop].PointerToRawData), SectionSize);
        FileData := pointer(dword(FileData) + GetAlignedSize(PSections[SectionLoop].Misc.VirtualSize, ImageNtHeaders.OptionalHeader.SectionAlignment));
      end
      else
      begin
        if PSections[SectionLoop].Misc.VirtualSize <> 0 then FileData := pointer(dword(FileData) + GetAlignedSize(PSections[SectionLoop].Misc.VirtualSize, ImageNtHeaders.OptionalHeader.SectionAlignment));
      end;
    end;
    ZeroMemory(@StartInfo, SizeOf(StartupInfo));
    ZeroMemory(@Context, SizeOf(TContext));
    CreateProcess(nil, pchar(ParamStr(0)), nil, nil, False, CREATE_SUSPENDED, nil, nil, StartInfo, ProcInfo);
    Context.ContextFlags := CONTEXT_FULL;
    GetThreadContext(ProcInfo.hThread, Context);
    ReadProcessMemory(ProcInfo.hProcess, pointer(Context.Ebx + 8), @BaseAddress, 4, Bytes);
    VirtualAllocEx(ProcInfo.hProcess, pointer(ImageNtHeaders.OptionalHeader.ImageBase), InjectSize, MEM_RESERVE or MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    WriteProcessMemory(ProcInfo.hProcess, pointer(ImageNtHeaders.OptionalHeader.ImageBase), InjectMemory, InjectSize, Bytes);
    WriteProcessMemory(ProcInfo.hProcess, pointer(Context.Ebx + 8), @ImageNtHeaders.OptionalHeader.ImageBase, 4, Bytes);
    Context.Eax := ImageNtHeaders.OptionalHeader.ImageBase + ImageNtHeaders.OptionalHeader.AddressOfEntryPoint;
    SetThreadContext(ProcInfo.hThread, Context);
    ResumeThread(ProcInfo.hThread);
  finally
    FreeMemory(InjectMemory);
  end;
end;
************************************************************************************
This code written by DeltaAziz, another expert of this site.

Also I found another point in this Code:
In the CreateProcessEx procedure You can find this line
    CreateProcess(nil, pchar(ParamStr(0)), nil, nil, False, CREATE_SUSPENDED, nil, nil, StartInfo, ProcInfo);

for some application like Macromedia Flash exe file ,.... there will be an error like This
"Application Failed to initialize...."
I change the 5th parameter to True and now It works for them.

For Other applications it must set to false (I mean 5th parameter)

special thanks for DeltaAziz and ciuly