Open DLL from memory
Open DLL from memory
Hi, I have been delving in to the world of DLL's and was wondering if it was possible to for example, stream a DLL file from a server directly in to client memory and open it from there so the DLL is never created as a file on the client machine but is still usable by my application in the normal way?
Thanks
Andy
Thanks
Andy
Re: Open DLL from memory
you can do this, with this: http://www.joachim-bauch.de/tutorials/l ... om-memory/
c-source (32-bit only). create a static lib with PellesC for example and import the 3 functions.
Or i upload a example for you?
greetings
Thomas
c-source (32-bit only). create a static lib with PellesC for example and import the 3 functions.
Or i upload a example for you?
greetings
Thomas
Re: Open DLL from memory
A PB example would be great! 

Re: Open DLL from memory
you can download the static lib and pb import here: http://www.realsource.de/tmp/memorymodule.zip
I think the import is selfexplaining
The result of MemoryLoadLibrary is hModule!
I think the import is selfexplaining
Code: Select all
ImportC "memorymodule.lib"
MemoryLoadLibrary(MemoryPointer)
MemoryGetProcAddress(hModule, FunctionName.p-ascii)
MemoryFreeLibrary(hModule)
EndImport
Re: Open DLL from memory
Thanks i will try this out now. I also just stumbled across this and it seems to work but it runs EXE's from memory. I am using Windows 7 x64 and the latest Avast AntiVirus.. no negative effects and it the application runs fine.
http://www.purebasic.fr/english/viewtop ... dll+in+exe
http://www.purebasic.fr/english/viewtop ... dll+in+exe
Re: Open DLL from memory
you can use callfunctionfast, but better use prototypes.
Re: Open DLL from memory
you can use the pb osl functions to load a dll into memory, loadLibraryM(), GetProcAddressM(), FreeLibraryM()
the RunPe code from hipy001 seems to work fine though the process created is orphaned and runs under Unknown.
Code: Select all
*OutBuffer = PureLZMA_UnCompress(*dat, @BufferLen,key$)
If *OutBuffer > 0
My_DLL=LoadLibraryM(*OutBuffer)
MyDll=GetProcAddressM(My_dll,"MyDll")
res = CallFunctionFast(SomeFunction,Param1,Param2)
FreeLibraryM(My_dll)
FreeMemory(*outbuffer)
FreeMemory(*dat)
EndIf
Re: Open DLL from memory
The PBOSL Lib uses the same c-source but you can't use it in Unicode-Mode.
Re: Open DLL from memory
I hadn't made the connection, too early in the morning.
Re: Open DLL from memory
What are the implications of this?the RunPe code from hipy001 seems to work fine though the process created is orphaned and runs under Unknown.
Re: Open DLL from memory
You don't want orpahaned processes. Orphans waste resources and can potentially leave the system in trouble and possibly vunlerable in some cases.AndyMK wrote:What are the implications of this?the RunPe code from hipy001 seems to work fine though the process created is orphaned and runs under Unknown.
How about the streaming part, any ideas on that? I'd be interested in seeing what you come up with.
The advantage of a 64 bit operating system over a 32 bit operating system comes down to only being twice the headache.
Re: Open DLL from memory
Offer You my variant
Example:
Code: Select all
; Author: Pablov
; Date: 19. 08.2011
; OS: Windows (for PB4.30 - 4.51)
;DllFM.pbi
#IMAGE_REL_BASED_ABSOLUTE = 0
#IMAGE_ORDINAL_FLAG32 = $80000000
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[64]
EndStructure
Structure ImageBaseRelocation
VirtualAddress.l
SizeOfBlock.l
EndStructure
Structure _IMAGE_IMPORT_DESCRIPTOR
OriginalFirstThunk.l
TimeDateStamp.l
ForwarderChain.l
Name.l
FirstThunk.l
EndStructure
Structure DLL_INFO
BaseVirtDll.l
EntryPoint.l
loadDLL.l
EndStructure
Global Dim LibraryLoad(0)
Global DllInfo.DLL_INFO
ProcedureDLL FreeLibraryEx()
CallFunctionFast(DllInfo\BaseVirtDll + DllInfo\EntryPoint, DllInfo\BaseVirtDll, #DLL_PROCESS_DETACH, 0)
For i.w = 0 To DllInfo\loadDLL - 1
FreeLibrary_(LibraryLoad(i))
Next i
If DllInfo\BaseVirtDll : VirtualFree_(DllInfo\BaseVirtDll, 0, #MEM_RELEASE) :EndIf
EndProcedure
ProcedureDLL GetProcAddressEx(BaseAddress.l, ProcName.s)
PExports.IMAGE_EXPORT_DIRECTORY
_step = 0
*DOS_HEADER.IMAGE_DOS_HEADER
*NT_HEADERS.IMAGE_NT_HEADERS
*DOS_HEADER = BaseAddress
*NT_HEADERS = BaseAddress + *DOS_HEADER\e_lfanew
RtlMoveMemory_(PExports, *NT_HEADERS\OptionalHeader\DataDirectory[0]\VirtualAddress + BaseAddress , SizeOf(IMAGE_EXPORT_DIRECTORY))
NameAddr.l = PExports\AddressOfNames + BaseAddress
OrdinalAddres.l = PExports\AddressOfNameOrdinals + BaseAddress
FuncAddr.l = PExports\AddressOfFunctions + BaseAddress
For index.l = 0 To PExports\NumberOfNames - 1
NameAddr + _step
OrdinalAddres + _step/2
If ProcName = PeekS(PeekL(NameAddr) + BaseAddress)
ProcAddress.l = PeekL(FuncAddr + PeekW(OrdinalAddres)*4 ) + BaseAddress
Break
EndIf
_step = 4
Next index
ProcedureReturn ProcAddress
EndProcedure
ProcedureDLL ImportProc(BaseAddress.l, *NT_HEADERS.IMAGE_NT_HEADERS)
Protected PImport._IMAGE_IMPORT_DESCRIPTOR
If *NT_HEADERS\OptionalHeader\DataDirectory[1]\VirtualAddress
SizeImportStruct.b = SizeOf(_IMAGE_IMPORT_DESCRIPTOR)
RtlMoveMemory_(PImport, *NT_HEADERS\OptionalHeader\DataDirectory[1]\VirtualAddress + BaseAddress , SizeImportStruct)
While PImport\FirstThunk <> 0
LibsUsed.s = PeekS(PImport\Name + BaseAddress)
hModule = GetModuleHandle_(LibsUsed)
If hModule = 0
hModule = LoadLibrary_(LibsUsed)
ReDim LibraryLoad(DllInfo\loadDLL)
LibraryLoad(DllInfo\loadDLL) = hModule
DllInfo\loadDLL + 1
EndIf
While PeekL(PImport\FirstThunk + BaseAddress) <> 0
If PeekL(PImport\FirstThunk + BaseAddress) & #IMAGE_ORDINAL_FLAG32 <> 0
PokeL(PImport\FirstThunk + BaseAddress, GetProcAddress_(hModule, PeekL(PImport\FirstThunk + BaseAddress) & $FFFF))
Else
PokeL(PImport\FirstThunk + BaseAddress, GetProcAddress_(hModule, PeekS(PeekL(PImport\FirstThunk + BaseAddress) + 2 + BaseAddress)))
EndIf
PImport\FirstThunk + 4
Wend
RtlMoveMemory_(PImport, *NT_HEADERS\OptionalHeader\DataDirectory[1]\VirtualAddress + BaseAddress + _step.w + SizeImportStruct, SizeImportStruct)
_step + SizeImportStruct
Wend
EndIf
EndProcedure
ProcedureDLL RelocProc(BaseAddress.l, *NT_HEADERS.IMAGE_NT_HEADERS)
Protected *PReloc.ImageBaseRelocation
ImageBaseDelta = BaseAddress - *NT_HEADERS\OptionalHeader\ImageBase ; calculate delta
If ImageBaseDelta
RelocsSize.l = *NT_HEADERS\OptionalHeader\DataDirectory[5]\Size
*PReloc = *NT_HEADERS\OptionalHeader\DataDirectory[5]\VirtualAddress + BaseAddress
P.w
j.l
ModCount.l
tempSize.l = 0
startAdrReloc = *NT_HEADERS\OptionalHeader\DataDirectory[5]\VirtualAddress + BaseAddress + 8
While tempSize < RelocsSize
ModCount = (*PReloc\SizeOfBlock - 8) / 2
For j = 0 To ModCount-1
P = PeekW(startAdrReloc)
If P & $f000 <> #IMAGE_REL_BASED_ABSOLUTE
RelocValue = PeekL(BaseAddress + *PReloc\VirtualAddress + (P & $0fff)) + ImageBaseDelta
PokeL(BaseAddress + *PReloc\VirtualAddress + (P & $0fff), RelocValue) ; Correct reference
startAdrReloc + 2
Else
startAdrReloc + 2
EndIf
Next j
tempSize + *PReloc\SizeOfBlock
*PReloc + *PReloc\SizeOfBlock
startAdrReloc + 8
Wend
EndIf
EndProcedure
ProcedureDLL LoadLibraryEx(StartFile.l, EndFile.l)
Protected *DOS_HEADER.IMAGE_DOS_HEADER
Protected*SECTION_HEADERS.IMAGE_SECTION_HEADERS
Protected BaseVirtDll.l
Protected *NT_HEADERS.IMAGE_NT_HEADERS
SizeDll = EndFile - StartFile
If PeekW(StartFile) = $434A ; If file pack > PureBasic (signature "JC")
*Source = AllocateMemory(SizeDll)
*VirtMemOffset = AllocateMemory(SizeDll * 3)
EnableASM
mov ecx, SizeDll
mov edi, *Source
mov esi, StartFile
rep movsb ; unpack and write in memory
UnpackMemory(*Source, *VirtMemOffset)
If *Source : FreeMemory(*Source) : EndIf
ElseIf PeekW(StartFile) = $5A4D ; else (signature "MZ")
*VirtMemOffset = AllocateMemory(SizeDll)
mov ecx, SizeDll
mov edi, *VirtMemOffset
mov esi, StartFile
rep movsb ; write in memory
DisableASM
Else
MessageRequester("Error", " No valid PE File ", #MB_OK|#MB_ICONERROR)
End
EndIf
; *****************************************************************************************
*DOS_HEADER = *VirtMemOffset
*NT_HEADERS = *VirtMemOffset + *DOS_HEADER\e_lfanew
*SECTION_HEADERS = *NT_HEADERS\OptionalHeader + *NT_HEADERS\FileHeader\SizeOfOptionalHeader
;******************************************************************************************
BaseVirtDll = VirtualAlloc_(#Null, *NT_HEADERS\OptionalHeader\SizeOfImage, #MEM_COMMIT, #PAGE_EXECUTE_READWRITE)
If BaseVirtDll
DllInfo\EntryPoint = *NT_HEADERS\OptionalHeader\AddressOfEntryPoint
RtlMoveMemory_(BaseVirtDll, *VirtMemOffset, *NT_HEADERS\OptionalHeader\SizeOfHeaders)
For i = 0 To *NT_HEADERS\FileHeader\NumberOfSections - 1
RtlMoveMemory_(BaseVirtDll + *SECTION_HEADERS\ish[i]\VirtualAddress, *VirtMemOffset + *SECTION_HEADERS\ish[i]\PointerToRawData, *SECTION_HEADERS\ish[i]\SizeOfRawData)
Next i
RelocProc(BaseVirtDll, *NT_HEADERS) ; Relocation
ImportProc(BaseVirtDll, *NT_HEADERS) ; Import
; @@@@@@@@@@@@@@@@@@@@@@@@@@ Flags @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
For i = 0 To *NT_HEADERS\FileHeader\NumberOfSections - 1
SC.l = *SECTION_HEADERS\ish[i]\Characteristics
protect.l = #PAGE_READONLY
If SC & $80000000 : protect = #PAGE_READWRITE : EndIf
If SC & $20000000 : protect = #PAGE_EXECUTE_READ : EndIf
If SC & $20000000 And SC & $80000000 : protect = #PAGE_EXECUTE_READWRITE : EndIf
VirtualProtect_(*SECTION_HEADERS\ish[i]\VirtualAddress + BaseVirtDll, *SECTION_HEADERS\ish[i]\VirtualSize, protect, @TempAddr.l)
Next i
; @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ Init DLL @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
If DllInfo\EntryPoint <> 0
If CallFunctionFast(BaseVirtDll + *NT_HEADERS\OptionalHeader\AddressOfEntryPoint, BaseVirtDll, #DLL_PROCESS_ATTACH, 0)
Else
FreeLibraryEx()
ProcedureReturn 0
EndIf
EndIf
; @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
If *VirtMemOffset : FreeMemory(*VirtMemOffset) : EndIf
DllInfo\BaseVirtDll = BaseVirtDll
ProcedureReturn BaseVirtDll
EndIf
If *VirtMemOffset : FreeMemory(*VirtMemOffset) : EndIf
ProcedureReturn 0
EndProcedure
Code: Select all
; Example for BASS.dll !!!!!!!!!!!!!!
XIncludeFile "DllFM.pbi"
DataSection
StartFile:
IncludeBinary "BASS.dll"
EndFile:
EndDataSection
BaseDll.l = LoadLibraryEx(?StartFile, ?EndFile)
If BaseDll
MessageRequester("Congratulation", "Library loaded to: " + RSet(Hex(BaseDll), 8, "0"), #MB_OK|#MB_ICONINFORMATION)
Else
MessageRequester("Error", "Can Not load library", #MB_OK|#MB_ICONERROR)
End
EndIf
BASS_GetVersion.l = GetProcAddressEx(BaseDll, "BASS_GetVersion")
If BASS_GetVersion
ver.s = Hex(CallFunctionFast(BASS_GetVersion))
If ver
While Right(ver, 1) = "0"
ver = Mid(ver, 1, Len(ver)-1)
Wend
ver = ReplaceString(ver, "0", ".")
MessageRequester("Version of BASS", "Version BASS.dll: " + ver, #MB_OK|#MB_OK|#MB_ICONINFORMATION)
EndIf
EndIf
FreeLibraryEx()
Re: Open DLL from memory
Its possible to, instead of loading the dll when compile, downloading from the web on run time?
Code: Select all
XIncludeFile "DllFM.pbi"
DataSection
StartFile:
IncludeBinary "BASS.dll"
EndFile:
EndDataSection
ARGENTINA WORLD CHAMPION