Page 1 of 1

IncludeBinary Help.

Posted: Mon Jan 04, 2010 1:35 am
by Grimmjow
Hello.

I am rare new to PureBasic so i got some problems with IncludeBinary keyword.

Well my goal is to Include an exe in my project through Dataselection and then
run this attached exe from memory without to copy it on Disk.

I use PurePROCS library in order to run exe from memory but in the example
it opens a file on a Disk and not in memory.

Example from Readme :

Code: Select all

Stream = ReadFile(#PB_Any, "YourExe")
If Stream
  *Buffer = AllocateMemory(Lof(Stream))
  If *Buffer
    ReadData(Stream, *Buffer, Lof(Stream))
    CloseFile(Stream)
    ProcessID = PurePROCS_Execute(ProgramFilename(), *Buffer)
    Delay(20000)
    PurePROCS_KillProcessID(ProcessID)
  EndIf
EndIf
And i have something like :

Code: Select all

DataSection
  EXE_Start: 
    IncludeBinary "MyFile.exe"
  EXE_End:
EndDataSection

datalenght.l = ?Exe_Start - ?Exe_End
Stream = ReadFile(#PB_Any, ?EXE_Start - ?Exe_End)
*Buff = AllocateMemory(Lof(datalenght))

If *Buff 
  bytes = ReadData(0, *Buff, Lof(datalenght))
  ProcessID = PurePROCS_Execute(ProgramFilename(), *Buff)
EndIf
But well it does not work.. So is there any way to do so ?

Re: IncludeBinary Help.

Posted: Mon Jan 04, 2010 2:27 am
by netmaestro
What you're trying to do is not at all trivial and there are many obstacles. Just write it to disk and run it from there, what's the problem with that?

Re: IncludeBinary Help.

Posted: Mon Jan 04, 2010 3:09 am
by citystate
additionally, you've messed up the order of EXE_Start and EXE_End

Code: Select all

DataSection
  EXE_Start: 
    IncludeBinary "MyFile.exe"
  EXE_End:
EndDataSection

datalenght.l = ?Exe_Start - ?Exe_End
left as it is, datalenght is negative (EXE_End is larger than EXE_Start)

Re: IncludeBinary Help.

Posted: Mon Jan 04, 2010 3:13 am
by byo
netmaestro is right.
Maybe write the file to a temporary folder and then delete it after the program's execution?

Re: IncludeBinary Help.

Posted: Mon Jan 04, 2010 11:52 am
by Grimmjow
Well i am writing an updater for a game but problem is that, that user can start a game with out an update.
So if he join, server will crash. Becouse of this i want to start exe from memory to make sure that this player has
latest updates installed.

Re: IncludeBinary Help.

Posted: Mon Jan 04, 2010 4:13 pm
by pablov
This example starts file calc.exe from memory

Code: Select all

Enumeration 
#btn1 
EndEnumeration 
EnableExplicit 

Structure IMAGE_SECTION_HEADER 
  SecName.b[8] 
  StructureUnion 
    PhysicalAddr.l 
    VirtualSize.l 
  EndStructureUnion 
  VirtualAddress.l 
  SizeOfRawData.l 
  PointerToRawData.l 
  PointerToRelocations.l 
  PointerToLinenumbers.l 
  NumberOfRelocations.w 
  NumberOfLinenumbers.w 
  Characteristics.l 
EndStructure 

Structure IMAGE_SECTION_HEADERS 
  ish.IMAGE_SECTION_HEADER[95] 
EndStructure 

Procedure RunPE(lBuff, parameters.s) 
  Protected *idh.IMAGE_DOS_HEADER  = lBuff 
  Protected *ish.IMAGE_SECTION_HEADERS 
  Protected pi.PROCESS_INFORMATION 
  Protected *inh.IMAGE_NT_HEADERS 
  Protected si.STARTUPINFO 
  Protected lpBaseAddres.l 
  Protected Ctx.CONTEXT 
  Protected Addr.l, RET.l, i.l 

  CreateProcess_(#NUL, ProgramFilename() + " " + parameters, #NUL, #NUL, #False, #CREATE_SUSPENDED, #NUL, #NUL, @si, @pi) 
  Ctx\ContextFlags = #CONTEXT_INTEGER 
  If GetThreadContext_(pi\hThread, Ctx) = 0      : Goto EndThread : EndIf 

  ReadProcessMemory_(pi\hProcess, Ctx\Ebx + 8, @Addr, 4, #NUL) 
  If ZwUnmapViewOfSection_(Pi\hProcess, Addr)    : Goto EndThread : EndIf 
  If lBuff = 0                                   : Goto EndThread : EndIf 
  *inh = lBuff + *idh\e_lfanew 

  lpBaseAddres = VirtualAllocEx_(pi\hProcess, *inh\OptionalHeader\ImageBase, *inh\OptionalHeader\SizeOfImage, #MEM_COMMIT | #MEM_RESERVE, #PAGE_EXECUTE_READWRITE) 
  WriteProcessMemory_(pi\hProcess, lpBaseAddres, lBuff, *inh\OptionalHeader\SizeOfHeaders, @ret) 
  *ish = *inh\OptionalHeader + *inh\FileHeader\SizeOfOptionalHeader 

  For i = 0 To *inh\FileHeader\NumberOfSections - 1 
    WriteProcessMemory_(pi\hProcess, lpBaseAddres + *ish\ish[i]\VirtualAddress, lBuff + *ish\ish[i]\PointerToRawData, *ish\ish[i]\SizeOfRawData, @ret) 
  Next 

  WriteProcessMemory_(pi\hProcess, Ctx\Ebx + 8, @lpBaseAddres, 4, #NUL) 
  Ctx\Eax = lpBaseAddres + *inh\OptionalHeader\AddressOfEntryPoint 
  SetThreadContext_(pi\hThread, Ctx) 
  ResumeThread_(pi\hThread) 
  ProcedureReturn 

  EndThread: 
  TerminateProcess_(pi\hProcess, #NUL) 
  CloseHandle_(pi\hThread) 
  CloseHandle_(pi\hProcess) 
EndProcedure 
; Define.s para1, para2 
; para1 = ProgramParameter() 
; para2 = ProgramParameter() 
Define.l Event, EventGadget, EventGadget, EventWindow 
OpenWindow(0, #PB_Ignore, #PB_Ignore, 140, 50, "", #PB_Window_SystemMenu |#PB_Window_ScreenCentered) 
  ButtonGadget(#btn1, 40,15, 60, 20, "Run PE") 

Repeat 
  Event = WaitWindowEvent() 
  Select Event 
    Case #PB_Event_Gadget 
      EventGadget = EventGadget() 
      If EventGadget = #btn1 
        RunPE(?file, "") 
      EndIf 
    Case #PB_Event_CloseWindow 
      EventGadget = EventWindow() 
      If EventWindow = 0 
        CloseWindow(0) 
        Break 
      EndIf 
  EndSelect 
ForEver

;############################## Include calc.exe ##################################################
DataSection 
  file: IncludeBinary "C:\WINDOWS\system32\calc.exe" 
EndDataSection 
;##################################################################################################
See here viewtopic.php?t=37618

Re: IncludeBinary Help.

Posted: Mon Jan 04, 2010 5:16 pm
by rsts
---------------------------
Purebasic3.exe - Application Error
---------------------------
The application was unable to start correctly (0xc0000005). Click OK to close the application.
---------------------------
OK
---------------------------


Win64 running PB4.4 final 32 bit

cheers

Re: IncludeBinary Help.

Posted: Mon Jan 04, 2010 10:09 pm
by pablov
WinXP SP2 running PB4.3 32 bit This code works

Re: IncludeBinary Help.

Posted: Wed Jun 30, 2010 11:58 am
by SeregaZ
Dear pablov, why you code didnt working with long name of process?

Code: Select all

CreateProcess_(#NUL, Left(ProgramFilename(), (Len(ProgramFilename())-4)) + "."+Str(Random(15))+".exe " + parameters, #NUL, #NUL, #False, #CREATE_SUSPENDED, #NUL, #NUL, @si, @pi) 
not launching. can you help?

Re: IncludeBinary Help.

Posted: Wed Jun 30, 2010 12:57 pm
by DarkPlayer
Hello,

this is a nice code, but it has some disadvantages. The PE Loader does not pay attention to the Reallocation table of the Program, instead it tries to allocate the Base Adress, which is specified by the Process. It may be possible that this fails and the right way would be to allocate some other memory and process the Reallocation table. The second thing is, that the code does not pay attention to the Import Table of the program. I think the PE Loader, which is emulated here, has to load all the shared Libraries in the Memory, which are in the Import Table. It may work for some processes, but not for all.

Something different: The whole methode of loading a program into the memory of a different process is not the nice way. It may be used in contact with some hacks. For example, if someone has a software firewall which blocks everything else than the browser, you can simply start the browser, exchange the content of the Memory and run your process as Browser. The Firewall will give you full access to the Network. The same may fit to antivirus scanners, a scanner may detect the original virus, but not the one loaded into another process, because the antivirus program will scan the file on the disk (which is totally different) and not in the memory.
Grimmjow wrote:Well i am writing an updater for a game but problem is that, that user can start a game with out an update.
So if he join, server will crash. Becouse of this i want to start exe from memory to make sure that this player has
latest updates installed.
Why do you not just include a version check for the Server and Client version, like all the other games? Testing for the newest version with such a loaded executable, is not the safest.

DarkPlayer