Chargement dynamic du fichier exe

J’essaie de charger dynamicment un fichier exe à partir de mon programme et d’exécuter SomeProcedure à partir de cet exe chargé dynamicment. Voici ce que je fais dans exe chargé – library.exe

interface procedure SomeProcedure; stdcall; implementation procedure SomeProcedure; begin ShowMessage('Ala has a cat'); end; 

Et voici mon exe qui charge la librairie.exe et essaye d’exécuter SomeProcedure.

 type THandle = Integer; TProc = procedure(); var AHandle: THandle; Proc: TProc; procedure TForm1.Button1Click(Sender: TObject); begin AHandle := LoadLibrary('library.exe'); if AHandle  0 then begin @Proc := GetProcAddress(AHandle, 'SomeProcedure'); if @Proc  nil then try Proc; finally FreeLibrary(AHandle); end; end; end; end; 

Malheureusement, cela ne fonctionne pas – AHandle a une adresse mais GetProcAddress renvoie toujours nil. Qu’est-ce que je fais mal?

À ma connaissance, ce que vous essayez n’est pas possible. Vous ne pouvez pas utiliser LoadLibrary pour charger un fichier .exe, puis appeler ses fonctions exscopes. Vous ne pouvez avoir qu’un seul fichier .exe chargé dans un processus. Vous devrez déplacer la fonctionnalité dans une bibliothèque, un serveur COM ou une autre solution.

Comme le souligne Sertac, la documentation couvre ceci:

LoadLibrary peut également être utilisé pour charger d’autres modules exécutables. Par exemple, la fonction peut spécifier un fichier .exe pour obtenir un handle pouvant être utilisé dans FindResource ou LoadResource. Toutefois, n’utilisez pas LoadLibrary pour exécuter un fichier .exe. Au lieu de cela, utilisez la fonction CreateProcess.

Vous pouvez utiliser GetProcAddress avec le handle de module d’un exécutable. Mais vous devez obtenir le handle de module en appelant GetModuleHandle (0), par exemple.

Comme David l’a déjà souligné, c’est presque impossible. Eh bien pas impossible je dirais. Pour simplifier, vous pouvez appeler CreateProcess, puis appeler son appel et les appels qui suivent. L’un des appels est également ZwCreateSection . J’ai joué avec des choses comme ça il y a longtemps et c’est théoriquement possible de le faire. CreateProcess crée un contexte de processus vide qui est ensuite rempli avec d’autres appels kernell Zw / Nt. Connaître les appels, vous pouvez fournir le contenu.

Mais c’était de la théorie et même cela est un piratage du système d’exploitation. Comme l’a souligné David, il est impossible de le faire d’une manière saine et documentée. Ce que vous pouvez faire, c’est extraire l’exe en tant que ressource vers un fichier temporaire et l’exécuter. Vous pouvez alors attendre la fin et ensuite supprimer le fichier. C’est la seule façon de le faire. Tout faire en RAM est un non-aller.

MODIFIER:

Voici un article sur une technique utilisable. Mais c’est un hack moche 🙂

“maintenant j’ai un appel AV à Proc” – vous oubliez de définir “stdcall” dans la définition de TProc.

Juste créé petit échantillon démontrant le chargement / exécution de la fonction exscope à partir d’un autre EXE.

Application 1:

 program Exe4Export; uses Vcl.Forms, Unit3 in 'Unit3.pas' {Form3}, ExportTypes in 'ExportTypes.pas'; {$R *.res} function Test:integer; stdcall; export; begin result := 7; end; exports Test; begin Application.Initialize; Application.MainFormOnTaskbar := True; Application.CreateForm(TForm3, Form3); Application.Run; end. 

Application 2:

 type TExtProc = function: integer; stdcall; procedure TForm3.FormCreate(Sender: TObject); var h: HMODULE; p: TExtProc; begin h := LoadLibrary('Exe4Export.exe'); p := GetProcAddress(h, 'Test'); if assigned(p) then caption := IntToStr(p); FreeLibrary(h); end; 

Ainsi, app2 charge l’app1 dans son propre espace d’adressage (oui, c’est possible pour la DLL), puis récupère l’adresse de la fonction et l’appelle de la même manière que pour les DLL.