Comment puis-je exécuter du code directement depuis la mémoire dans delphi?

Est-il possible d’imiter la fonction loadlibrary ? Je veux charger une bibliothèque à partir d’un champ BLOB sans l’écrire au préalable dans un fichier temporaire, et j’ai besoin d’une solution qui ne dépend pas de la version spécifique du compilateur ou des fenêtres delphi et ne déclenche pas de logiciel antivirus.

dzlib contient un object prêt à l’emploi pour lire une DLL d’une ressource en mémoire et l’utiliser sans jamais l’enregistrer sur le disque:

C’est le fichier principal …

http://sourceforge.net/p/dzlib/code/147/tree/dzlib/trunk/src/u_dzResourceDllLoader.pas

.. mais il a besoin d’autres fichiers du même référentiel.

Oui vous pouvez, et vous n’avez pas besoin de loadlibrary pour exécuter un code à partir de la mémoire – vous devez allouer une mémoire à l’aide de la fonction VirtualAlloc avec l’indicateur PAGE_EXECUTE


Update: voici une démo rapide et sale du code exécuté depuis la mémoire pour Delphi 32 bits – j’ai seulement testé que cela fonctionnait:

 type TIncMe = procedure(var I: Integer); var IncMeProc: TIncMe; procedure IncMe(var I: Integer); begin Inc(I); end; procedure CopyIncMe; var Size: LongWord; Tmp: Pointer; begin Size:= LongWord(@CopyIncMe) - LongWord(@IncMe); Tmp:= VirtualAlloc(nil, Size, MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE); Move(Pointer(@IncMe)^, Tmp^, Size); IncMeProc:= Tmp; end; procedure TForm1.Button1Click(Sender: TObject); var J: Integer; begin J:= 0; CopyIncMe; while J < 10 do begin IncMeProc(J); ShowMessage(IntToStr(J)); end; VirtualFree(@IncMeProc, 0, MEM_RELEASE); end; 

Il y a un article sur delphi.about.com , qui montre comment charger une DLL à partir d’une ressource.

Il charge d’abord la ressource en mémoire, puis charge la DLL à partir de la ressource à l’aide du module de mémoire.

Au lieu d’une ressource, vous pouvez utiliser une firebase database ou n’importe quelle source à partir de laquelle vous souhaitez charger la DLL. Une fois qu’il est dans un stream de mémoire, vous pouvez utiliser le code suivant pour charger et exécuter les fonctions dll, qui ressemble beaucoup au code “normal” pour appeler une DLL:

 var btMM: PBTMemoryModule; begin btMM := BTMemoryLoadLibary(mp_DllData, m_DllDataSize); try if btMM = nil then Abort; @m_TestCallstd := BTMemoryGetProcAddress(btMM, 'TestCallstd'); if @m_TestCallstd = nil then Abort; m_TestCallstd('This is a Dll Memory call!'); except Showmessage('An error occoured while loading the dll: ' + BTMemoryGetLastError); end; if Assigned(btMM) then BTMemoryFreeLibrary(btMM); end;