[Borland Delphi]DLL Injection

    Publicités

Users Who Are Viewing This Thread (Total: 0, Members: 0, Guests: 0)

Leplayze

Frite...euse (jeu de mot)
V
Ancien staff
Dec 4, 2009
12,647
5
1,303
30
www.youtube.com
merci a spamici

Un petit exemple d'injection d'une DLL dans un processus.
credits: Elguevel pour son Unit & moi pour les modifs de son main et de la DLL :P

Unité d'injection:
ElgInject.pas
Code:
{
  Demo : DLL Injection
  Pour CodeSource !
  -------------
  By Elguevel (c) 2006.
}

unit ElgInject;

interface

uses Windows, Tlhelp32, StdCtrls, SysUtils;

function  InjectDLL( DLLSource : string; ProcessDestination : string ) : Boolean;
procedure AjustePrivileges;
function  FindProcess( Name : string ) : DWORD;
procedure ListeProcessus( Combo : TComboBox );

const SE_DEBUG_NAME = 'SeDebugPrivilege';

implementation

{ Injecte DLL <= notre fonction magique :-) }
function InjectDLL( DLLSource : string; ProcessDestination : string ) : Boolean;
var
    LibName     : Pointer;
    hProcess    : THandle;
    ThreadHandle: THandle;
    OctEcrit    : Cardinal;
    TheadID     : DWORD;
begin
    Result := False;

    AjustePrivileges; // Ajuste les privilèges en Debug (plus de droit)

    // on ouvre le processus cible
    hProcess := OpenProcess( PROCESS_ALL_ACCESS, FALSE, FindProcess( ProcessDestination ) );
    if (hProcess = 0) then Exit;

    // on alloue de la place dans le processus pour la DLL
    LibName := VirtualAllocEx( hProcess, nil, Length(DLLSource) + 1, MEM_COMMIT, PAGE_READWRITE );
    if ( LibName <> nil ) then
    begin
      // on map le contenu de la DLL dans la mémoire allouée
      WriteProcessMemory( hProcess, LibName, PChar(DLLSource), Length(DLLSource) + 1, OctEcrit );
      // On verifie que toute la DLL à bien été écrite !
      if ( (Length(DLLSource) + 1) <> OctEcrit ) then Exit;
      // Puis on charge la librairie dynamiquement avec l'API LoadLibrairie depuis le process
      ThreadHandle := CreateRemoteThread( hProcess, nil, 0, GetProcAddress( LoadLibrary('kernel32.dll'), 'LoadLibraryA' ), LibName, 0, TheadID );
      Result := ( ThreadHandle <> 0 );
      WaitForSingleObject( ThreadHandle, INFINITE );
    end else Result := False;
    VirtualFreeEx( hProcess, LibName, 0, MEM_RELEASE );
    CloseHandle( hProcess );
end;


{ Trouve un PID à partir du nom du process }
function FindProcess( Name : string ) : DWORD;
var
   FSnapshotHandle : THandle;
   FProcessEntry32 : TProcessEntry32;
begin
   Result := 0;
   FSnapshotHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
   FProcessEntry32.dwSize := Sizeof(FProcessEntry32);
   Process32First(FSnapshotHandle,FProcessEntry32); // <= premier process trouver
   repeat
     if Name = FProcessEntry32.szExeFile  then   // <= si notre processus correspond à celui entré alors ...
     begin
        Result := FProcessEntry32.th32ProcessID ; // < = ... on récupère son PID
        CloseHandle(FSnapshotHandle);
        Exit;                         // <= sort prématurément de la boucle, car inuile après !
     end;
   until not ( Process32Next(FSnapshotHandle, FProcessEntry32) ); // <= tant qu'il y en a un suivant, on continue
   CloseHandle(FSnapshotHandle);
end;


{ Ajuste les privilèges en mode débug pour effectuer certaines actions }
procedure AjustePrivileges;
var
    hToken    : THandle;
    TP        : TTokenPrivileges;   //  pas besoin de développé, on trouve cette fonction partout sur le net
    PrevToken : TTokenPrivileges;   // on l'utilise pour passer en mode DEBUG, et donner un peu plus de privilèges aux applications
    PSsize    : DWORD;
begin
    OpenProcessToken( GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, hToken );
    LookupPrivilegeValue( nil, SE_DEBUG_NAME, TP.Privileges[0].Luid );
    TP.PrivilegeCount := 1;
    TP.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;
    AdjustTokenPrivileges( hToken, False, TP, SizeOf(TP), PrevToken, PSsize );
end;


{ Charge processus dans une combo } 
procedure ListeProcessus( Combo : TComboBox );
var
   FSnapshotHandle  : THandle;
   FProcessEntry32  : TProcessEntry32;    // identique à la fonction "FindProcess" mais prend tout les process
begin                                     // en compte et ajoute leur nom à la combo passé en paramètre
   FSnapshotHandle := CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
   FProcessEntry32.dwSize := SizeOf( TProcessEntry32 );
   Process32First( FSnapshotHandle, FProcessEntry32 );
   Combo.Clear;
   repeat
      Combo.Items.Add ( FProcessEntry32.szExeFile );
   until not ( Process32Next( FSnapshotHandle, FProcessEntry32 ) );
   CloseHandle( FSnapshotHandle );
end;

end.

Source de la fiche:
main.pas
Code:
unit main;

interface

uses
  Windows, Messages, SysUtils, Controls, Forms, Dialogs,
  Buttons, StdCtrls, ExtCtrls, Classes, ElgInject;

type TMainForm = class(TForm)
    EditDLL: TEdit;
    BtnQuitter: TSpeedButton;
    EditName: TEdit;
    procedure FormActivate(Sender: TObject);
    procedure BtnQuitterClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    procedure WMHotKey(var Message: TMessage); message WM_HOTKEY;
end;

var MainForm: TMainForm;

procedure DllMessage; external 'madll.dll';

implementation

{$R *.dfm}



{ Init Form }
procedure TMainForm.FormActivate(Sender: TObject);

begin

    EditDLL.Text := ExtractFileDir(Application.ExeName) + '\madll.dll';
	if InjectDLL(EditDLL.Text, EditName.Text) then //dans le EditName y a marqué NOTEPAD.EXE
		ShowMessage ('La dll a ete injecte')
	else
		ShowMessage ('La dll na pas ete injecte'); 


end;

procedure TMainForm.WMHotKey(var message: TMessage);

begin
 DllMessage;
end;


{ Quitter }
procedure TMainForm.BtnQuitterClick(Sender: TObject);
begin
  Application.Terminate;
end;


procedure TMainForm.FormCreate(Sender: TObject);
begin
RegisterHotKey(Handle,2306,MOD_CONTROL+MOD_ALT,VK_F9);
end;

procedure TMainForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
UnregisterHotKey(Handle,2306);
end;

end.

Exemple de la DLL:
madll.dll
Code:
    library MaDLL;

    uses SysUtils, Classes, Dialogs;

    procedure DllMessage; export;
    begin
      ShowMessage('Coucou les cheateurs! =)') ;
    end;

    exports DllMessage;

    begin
    end.
Du coup, quand j'appuie sur Ctrl+Alt+F9 (peu importe si je suis sur la fenêtre du bloc-notes ou sur mon prog) un petit message s'affiche: "Coucou les cheateurs! =)"
A vous de jouer avec la DLL injectée :)

EDIT: au fait c'est une façon de barbare que je vous ai présenté là, car l'appli appelle l'affichage du message de la DLL peu importe qu'elle soit injectée dans le bloc-notes ou pas. Du coup j'ai rajouté ceci:
Code:
    EditDLL.Text := ExtractFileDir(Application.ExeName) + '\madll.dll';
	if InjectDLL(EditDLL.Text, EditName.Text) then
		ShowMessage ('La dll a ete injecte')
	else
		ShowMessage ('La dll na pas ete injecte');
si on lance l'appli sans notepad, il va dire qu'elle n'as pas été injecté :) mais il l'injecte si notepad est executé.

Voilà, voilà, à vous de magouiller :)

[Edit]
Source (très bordélique xD): Ce lien n'est pas visible, veuillez vous connecter pour l'afficher. Je m'inscris!

p.s. l'idée d'injecter une dll peut s'avérer utile, si on veut par exemple y rajouter nos propres raccourcis.
bon après faut voir, pas mal de jeux ont un guard qui va vous kick cash pour l'injection xD
 
Last edited: