libs 32/64 windows only to execute exe/dll from memory not from disk

Headers, Bindings, Libraries for use with FreeBASIC, Please include example of use to help ensure they are tested and usable.
Post Reply
marpon
Posts: 342
Joined: Dec 28, 2012 13:31
Location: Paris - France

libs 32/64 windows only to execute exe/dll from memory not from disk

Post by marpon »

can execute embedded exe from memory not from disk
can use embedded dll export functions from memory not from disk

1 test .bas file can be found here :https://github.com/marpon/mem_exe_dll

the zip package also there (to simplify the compilation let all files in the same folder)
includes :
the bas file mem_exe_dll_light.bas
2 static libs libMem_Exe_Dll64.a and libMem_Exe_Dll32.a

2 exe files "inputbox_generic64.exe" for 64 and "exe_test.exe" for 32 bits (for tests only)
2 dll files "my_dll64.dll" for 64 and "Calendrier.dll" for 32 bits (for tests only)

if you want to use any else exe (what you want), change the name on the define on the bas file
same for any else dll, but you have to modify the sub dll_32() / sub dll_64() to follow the export function declaration

remember to place your selected exe or dll on the same folder as the bas file to compile correctly

you can add any exe or/and dll you want, it only increases the size of the resulting compiled exe

to verify the resulting compiled exe has effectively embedded the exe... dll
place the resulting exe in different folder
and launch it from that folder , you will see not duplication of embedded files ... only working from memory


last important point, and limitation!
if you compile in 64 bits you can only use dll 64 bits that is obvious but only exe 64 bits too
oposite when you compile in 32 bits you can only use dll 32 bits and exe 32 bits

let me know what you think about

the test code

Code: Select all

#Include Once "windows.bi"
'compile with or without console (if without the exe will add one to follow the sequence)


 /'
mem_exe_dll_light.bas          from marpon  23 jan 2019
test execute embedded exe from memory not from disk 
test use embedded dll export functions from memory not from disk

the package (to simplify the compilation let all files in the same folder)
this bas file   mem_exe_dll_light.bas
2 static libs  libMem_Exe_Dll64.a and libMem_Exe_Dll32.a are available

2 exe files  "inputbox_generic64.exe"  for 64   and   "exe_test.exe" for 32 bits
2 dll files  "my_dll64.dll" for 64 and "Calendrier.dll" for 32 bits

if you want to use any else exe  (what you want),  change the name on the define under
same for any else dll, but you have to modify the sub dll_32()  / sub dll_64() to follow the export function declaration

remember to place the new exe or dll on the same folder as the bas file to compile correctly

you can add any exe or/and dll you want, it only increases the size of the resulting compiled exe

to verify the resulting compiled exe has effectively embedded the exe... dll place the resulting exe in different folder 
	and launch it from that folder , you will see not duplication of embedded files ... only working from memory
	

last important point, and limitation!
	if you compile in 64 bits you can only use dll 64 bits that is obvious  but only exe 64 bits too
	oposite when you compile in 32 bits you can only use dll 32 bits and exe 32 bits 

'/ 


'put under the files you want to test according 64 or 32 bits
#ifdef __FB_64BIT__
	#define _ExeFullPath "inputbox_generic64.exe"
	#define _DllFullPath "my_dll64.dll"
#else
	#define _ExeFullPath "exe_test.exe"
	#define _DllFullPath "Calendrier.dll"
#endif


#ifndef __MEM_EXE_DLL_HEADER
	#define __MEM_EXE_DLL_HEADER
	#ifdef __FB_64BIT__
		#INCLIB "Mem_Exe_Dll64"   				' C  lib64  > libMem_Exe_Dll64.a
	#else
		#INCLIB "Mem_Exe_Dll32"   				' C  lib32  > libMem_Exe_Dll32.a
	#endif

	EXTERN "C"
		
		'EXE from memory functions
		'========================================================
	  #ifdef __FB_64BIT__
		'will work only with 64 bits program with 64 included
		DECLARE FUNCTION ExecMemFile alias "ExecFile64"(byval nameprog as zstring ptr, byval dataU as any ptr) as long  'return pid
	  #else
		'will work only with 32 bits program with 32 included
		DECLARE FUNCTION ExecMemFile alias "ExecFile32"(byval nameprog as zstring ptr, byval dataU as any ptr) as long  'return pid
	  #endif
	  
		'DLL from memory functions/subs
		'========================================================
		'attach the Dll in memory, return handle ptr
		DECLARE FUNCTION DllMemoryLoad alias "DllMemoryLoad"(byval dllname as any ptr) as any ptr
		 
		'declare export Function/sub from dll
		DECLARE FUNCTION DllMemoryGetProc alias "DllMemoryGetProc"(byval phandle as any ptr, byval exportname as zstring ptr) as any ptr
		
		'detach the dll from memory
		DECLARE SUB      DllMemoryFree alias "DllMemoryFree"(byval phandle as any ptr)
		
		'Helper functions/subs
		'========================================================
		'if pid0 exists returns same value as pid0  or 0 if not
		DECLARE FUNCTION pid4procpid alias "Pid4ProcPid"(byval pid0 as integer) as long 
		 
		'kill process by pid
		DECLARE FUNCTION killprocess alias "killProcess"(byval pid0 as integer) as long 

		'get running pid
		DECLARE FUNCTION actualpid alias "ActualPid"() as long
		
		'to check if exe/dll is 32 or 64  if 32 returns 32  , if 64 returns 64  , error returns 0
		DECLARE FUNCTION Check_Bits alias "Check_Bits"(byval dataU as any ptr , byval len1 as Long) as long		

	END EXTERN
	
	' to adapt to your needs, to execute exe from memory and wait until it is finished
	Function ExecWaitMem(byval str_name as zstring ptr, byval pdata as any ptr) As long
	   dim as long pid
	   pid = ExecMemFile(str_name, pdata)
	   if pid = 0 THEN return 0
	   dim  as long pid2 = pid
	   Do while pid2 = pid
		  sleep 20
		  pid2 = pid4procpid(pid)
	   LOOP
	   return pid
	End Function

#endif


'simplified version of incbin files in exe
#IfnDef INCFILE_LIGHT_
 #Define INCFILEX_LIGHT_

 #Macro __MACRO__INCLIGHT__(label, file)
  #If __FUNCTION__ = "__FB_MAINPROC__"
	#error =====> error  outside Sub/Function!
  #Else
	dim label as UByte Ptr
	dim label##_len as ULong
	#If file = ""
		#error =====> error  no given exe/dll_file!
    #Else
		#If __FB_DEBUG__
			asm jmp .LT_END_OF_FILE_##label##_DEBUG_JMP
	    #Else
		   ' Create the specified section
			asm .section .Data
	    #EndIf
		' Assign a label to the beginning of the file
		asm .LT_START_OF_FILE_##label##:
		asm __##label##__start = .
		' Include the file
		asm .incbin ##file
		' Mark the end of the the file
		asm __##label##__len = . - __##label##__start
		asm .LT_END_OF_FILE_##label##:
		' Pad it with a NULL Long (harmless, yet useful for text files)   asm .LONG 0
		#If __FB_DEBUG__
			asm .LT_END_OF_FILE_##label##_DEBUG_JMP:
		#Else
			' Switch back to the .text (code) section
			asm .section .text
			'was asm .balign 16
			asm .balign 16
		#EndIf
		asm .LT_SKIP_FILE_##label##:
		asm mov dword ptr [label], offset .LT_START_OF_FILE_##label
		asm mov dword ptr [label##_len], offset __##label##__len
   #EndIf
  #EndIf
 #EndMacro

#EndIf


function prog_bits() as long
  #ifdef __FB_64BIT__
	return 64
  #else
	return 32
  #endif
END FUNCTION


' to show usage
#ifdef __FB_64BIT__

	sub exe_64()
		__MACRO__INCLIGHT__(EXE64, _ExeFullPath)
		if check_bits(EXE64, EXE64_len) <>  prog_bits() THEN   'prog_bits()
		   messagebox 0, "Not valid " & prog_bits() & " Exe included ! " & chr(10,10) & "Closing now.", "Error", MB_OK + MB_ICONERROR
		   'messagebox 0, "Not valid " & "PE32+" & " Exe included ! " & chr(10,10) & "Closing now.", "Error", MB_OK + MB_ICONERROR
		   error 150
		end if
	   dim as long dret = ExecWaitMem( _ExeFullPath, EXE64)
	   print "included exe Pid " ; dret
	   print "end EXE64"
	END SUB

	sub dll_64()
	   __MACRO__INCLIGHT__(DLL64, _DllFullPath)
	   if check_bits(DLL64, DLL64_len) <> prog_bits() THEN
		   messagebox 0, "Not valid " & prog_bits() & " Dll included ! " & chr(10,10) & "Closing now.", "Error", MB_OK + MB_ICONERROR
		   error 150
		end if

	   dim as any ptr hhd64 = DllMemoryLoad(DLL64)
	   if hhd64 = NULL THEN
		   messagebox 0, "Wrong Dll ", "Error", MB_OK + MB_ICONERROR
		   exit sub
		end if    
	   dim jour as function(ByVal Titre1 as String, ByVal Valeur1 as String, ByVal Info1 as String) As Zstring Ptr
									jour = DllMemoryGetProc(hhd64, "FF3_Dll")
		
		if jour = 0 THEN							
			messagebox 0, "Wrong Dll or wrong function name", "Error", MB_OK + MB_ICONERROR
		else
			messagebox 0, jour("coucou", "val", "info"), "from dll34", MB_OK
	   end if
	   DllMemoryFree(hhd64)
	   print "end DLL64"
	END SUB

#else

	sub exe_32()
		__MACRO__INCLIGHT__(EXE32, _ExeFullPath)
		 if check_bits(EXE32, EXE32_len) <>  prog_bits() THEN   'prog_bits()
		   messagebox 0, "Not valid " & prog_bits() & " Exe included ! " & chr(10,10) & "Closing now.", "Error", MB_OK + MB_ICONERROR
		   error 150
		end if

	   dim as long dret = ExecWaitMem( _ExeFullPath, EXE32)
	   print "included exe Pid " ; dret
	   print "end EXE32"
	END SUB

	sub dll_32()
	   __MACRO__INCLIGHT__(DLL32, _DllFullPath)

	   if check_bits(DLL32, DLL32_len) <> prog_bits() THEN
		   messagebox 0, "Not valid " & prog_bits() & " Dll included ! " & chr(10,10) & "Closing now.", "Error", MB_OK + MB_ICONERROR
		   error 150
		end if

	   dim  as any ptr hhdll = DllMemoryLoad(DLL32)
	   if hhdll = NULL THEN
		   messagebox 0, "Wrong Dll ", "Error", MB_OK + MB_ICONERROR
		   exit sub
		end if  
	   dim jour as function (Byval  As UShort, Byval  As UShort, Byval  As UShort) As ZString Ptr _
									= DllMemoryGetProc(hhdll, "Date1")
		
		if jour = 0 THEN 
			messagebox 0, "Wrong Dll or wrong function name", "Error", MB_OK + MB_ICONERROR
		else
			messagebox 0, jour(06, 5, 1985), "Selected date", MB_OK
		end if
	   DllMemoryFree(hhdll)
	   print "end DLL32"
	END SUB

#endif



if GetConsoleWindow() < 1 then AllocConsole()

print "main prog PID", "pid = " & actualpid()

'tests to verify
#ifdef __FB_64BIT__
	dll_64()
	exe_64()
#else
	dll_32()
	exe_32()
#endif


print "main prog PID", "pid = " & actualpid()

if GetConsoleWindow() > 0 Then
	print: print: print "Press any key to close,   or program will close in 25s"
	sleep 25000
end if



marpon
Posts: 342
Joined: Dec 28, 2012 13:31
Location: Paris - France

Re: libs 32/64 windows only to execute exe/dll from memory not from disk

Post by marpon »

version 2 available on github

better execution from memory, simplified version of the libs

i noticed false virus detection with 5 tests of virus total when executing exe from memory, probably the same way some virus doing...

but seems ok with dll from memory

nobody has tested ?
srvaldez
Posts: 3373
Joined: Sep 25, 2005 21:54

Re: libs 32/64 windows only to execute exe/dll from memory not from disk

Post by srvaldez »

thank you marpon :-)
I plan on testing it soon.
marpon
Posts: 342
Joined: Dec 28, 2012 13:31
Location: Paris - France

Re: libs 32/64 windows only to execute exe/dll from memory not from disk

Post by marpon »

Another exemple of use
to create static lib from dll , in fact the static lib includes the dll and use it from memory

here the explanation and links
viewtopic.php?f=6&t=27380&p=258054#p258054
oyster
Posts: 274
Joined: Oct 11, 2005 10:46

Re: libs 32/64 windows only to execute exe/dll from memory not from disk

Post by oyster »

may I make a feature request here?
cypher the embedded EXE/DLL, and the cypher/decipher function can be written by users in freeBasic

thanks
marpon
Posts: 342
Joined: Dec 28, 2012 13:31
Location: Paris - France

Re: libs 32/64 windows only to execute exe/dll from memory not from disk

Post by marpon »

Not difficult!

first, you have to prepare to pre-encrypt the exe/dll (with any crypt solution you want ) and use these encrypted files before the compilation
of the resulting executable because incbin will embeed a file without any action.

On your code you have to put the relevant code to decrypt, use the pointer of the embedded element( and size if needed),
decrypt the embedded element to a new allocated memory, get the pointer of first bit of that allocated memory
and continue the process as it was without that decrypt step.

et voila.

I will not implement that feature, because it is quite simple, anybody can do it,
it also depends a lot on encrypt/decrypt method you want to use,
and it is plenty encrypt/decrypt examples you can find just googling...
UEZ
Posts: 972
Joined: May 05, 2017 19:59
Location: Germany

Re: libs 32/64 windows only to execute exe/dll from memory not from disk

Post by UEZ »

Thanks for sharing.

This was also on my to-do list. :-)
marpon
Posts: 342
Joined: Dec 28, 2012 13:31
Location: Paris - France

Re: libs 32/64 windows only to execute exe/dll from memory not from disk

Post by marpon »

V4 version of static libs with very simple encrypt/decrypt feature ( just to validate it is easy to do it)

see files on github V4 , example of use...

i put also an encoder gui source and decoder gui source just to simplify the job

remarks will be welcome...
oyster
Posts: 274
Joined: Oct 11, 2005 10:46

Re: libs 32/64 windows only to execute exe/dll from memory not from disk

Post by oyster »

win10 reports it as Trojan: Win32/Mamson.A!rfn
Post Reply