AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

Inject DLL from Memory

Ein Thema von Megamorph · begonnen am 10. Sep 2008 · letzter Beitrag vom 23. Sep 2008
Antwort Antwort
Seite 2 von 3     12 3   
Megamorph

Registriert seit: 28. Dez 2005
25 Beiträge
 
#11

Re: Inject DLL from Memory

  Alt 17. Sep 2008, 18:04
Hallo brechi,

ich habe jetzt eine zusätzliche Funktion in die DLL implementiert, welche als EP dienen soll (mit 1 und 0 Parametern getestet), was aber leider nicht funktioniert hat.

Hast du vlt. noch eine andere Idee, wie wir das zum Laufen bekommen?

MfG, Megamorph
  Mit Zitat antworten Zitat
brechi

Registriert seit: 30. Jan 2004
823 Beiträge
 
#12

Re: Inject DLL from Memory

  Alt 17. Sep 2008, 18:09
Ich könnte dir das natürlich programmieren, aber das wäre ja nicht sinn der Sache und hab auch nicht so viel Zeit. Und ich wieß ja noch nicht einmal für welches Projekt das überhaupt ist, ist es OpenSource dann würd ich dir das vill noch machen.
  Mit Zitat antworten Zitat
Megamorph

Registriert seit: 28. Dez 2005
25 Beiträge
 
#13

Re: Inject DLL from Memory

  Alt 18. Sep 2008, 17:39
Hallo brechi,

das stimmt natürlich - ich habe dir noch garnichts von meinem eigentlichen Vorhaben erzählt:

Auf der Suche nach einem portablen TaskManger, welcher auch die einzelnen Prozesse etwas näher beleuchtet, bin ich zb. auf SystemExplorer 1.4 gekommen. Die Funde waren zwar teilweise gute Programme, jedoch war die Analyse eines bestimmten Prozesses nicht so tiefgründig, wie ich es mir gerne wünsche. Das liegt bestimmt nicht an mangelnden Möglichkeiten oder Programmierkenntnissen der Ersteller - es würde einfach den Rahmen der jeweiligen Software sprängen.

Also habe ich mir überlegt, dass ich selber so einen portablen TaskAnalyzer baue. Das Programm soll aus nur einer einzigen Executablen bestehen und aus Sicherheitsgründen auch nirgendwohin Programmteile, Libs oder DLLs temporär "entpacken" und benutzen.

Zu der tiefgründigen Analyse muss ich eine DLL injecten (durchaus üblich, siehe diverse AntiVir: Kaspersky, F-Secure und co.). Der Analyzer soll zb. Aufschluss über DateiHandles/IO-Aktivitäten, IPC's, Pipes, Netzwerk-Zugriffe, Registryzugriffe, geladene Module, verwendete verdächtige Funktionen bzw. Funktionskombinationen, ... geben und soll das Abschießen von hartnäckigen verdächtigen Prozessen erlauben (notfalls Neustart + Autostart delte + Datei delete).

Bisher habe ich mir noch keine Gedanken zur Veröffentlichung des Source Codes gemacht, jedoch finde ich die Idee sehr anreizend. Wenn man sich überlegt, dass vlt. noch ein paar andere Coder gute Ideen haben, wie man den Analyzer bereichern kann. Wenn eine gewisse Grundbasis fertig gestellt ist, werde ich ein Projekt auf SourceForge eröffnen und den Source öffentlich verfügbar machen.

MfG, Megamorph
  Mit Zitat antworten Zitat
brechi

Registriert seit: 30. Jan 2004
823 Beiträge
 
#14

Re: Inject DLL from Memory

  Alt 19. Sep 2008, 16:25
Delphi-Quellcode:
function LoadLibraryEx(const fsLibrary: TStream; dwProcessID: DWord): Boolean; stdcall;
type
  TRelocBlock = packed record
    dwAddress: DWord;
    dwSize: DWord;
  end;
  PRelocBlock = ^TRelocBlock;

  TImportBlock = packed record
    dwCharacteristics: DWord;
    dwTimeDateStamp: DWord;
    dwForwarderChain: DWord;
    dwName: DWord;
    pFirstThunk: Pointer;
  end;
  PImportBlock = ^TImportBlock;

  TImportNameBlock = packed record
    wHint: Word;
    pName: PChar;
  end;
  PImportNameBlock = ^TImportNameBlock;

  procedure ChangeReloc(POrigBase, PBaseTemp, PReloc, PBaseTarget: Pointer; dwRelocSize: DWord); stdcall;
  var
    pCurrentRelocBlock: PRelocBlock;
    RelocCount: DWord;
    PCurrentStart: PWord;
    i: Integer;
    pRelocAddress: PInteger;
    iDif: Integer;
  begin
    pCurrentRelocBlock := PReloc;
    iDif := Integer(PBaseTarget) - Integer(POrigBase);
    PCurrentStart := Pointer(Integer(PReloc) + 8);
    while (not isBadReadPtr(pCurrentRelocBlock, SizeOf(TRelocBlock))) and
      (not isBadReadPtr(pCurrentStart, SizeOf(Pointer))) and
      (DWord(pCurrentRelocBlock) < DWord(pReloc) + dwRelocSize) do begin
      RelocCount := (pCurrentRelocBlock^.dwSize - 8) div SizeOf(Word);
      for i := 0 to RelocCount - 1 do begin
        if (not isBadReadPtr(pCurrentStart, SizeOf(Pointer))) and
          (PCurrentStart^ xor $3000 < $1000) then begin
          pRelocAddress := Pointer(pCurrentRelocBlock^.dwAddress + PCurrentStart^ mod $3000 + DWord(PBaseTemp));
          if (not isBadWritePtr(pRelocAddress, SizeOf(Integer))) then
            pRelocAddress^ := pRelocAddress^ + iDif;
        end;
        PCurrentStart := Pointer(DWord(PCurrentStart) + SizeOf(Word));
      end;
      pCurrentRelocBlock := Pointer(PCurrentStart);
      pCurrentStart := Pointer(DWord(PCurrentStart) + 8);
    end;
  end;

  procedure CreateImportTable(pLibraryHandle, pImportTable: pointer); stdcall;
  var
    pIBlock: PImportBlock;
    pThunksRead: PDWord;
    pThunksWrite: PDWord;
    pDllName: PChar;
    dwLibraryHandle: DWord;
    dwOldProtect: DWord;
  begin
    pIBlock := pImportTable;
    while (not isBadReadPtr(pIBlock, SizeOf(TImportBlock))) and
      (pIBlock^.pFirstThunk <> nil) and (pIBlock^.dwName <> 0) do begin
      pDllName := Pointer(DWord(pLibraryHandle) + DWord(pIBlock^.dwName));
      if (not isBadReadPtr(pDllName, 4)) then begin
        dwLibraryHandle := LoadLibrary(pDllName);
        pThunksRead := Pointer(DWord(pIBlock^.pFirstThunk) + DWord(pLibraryHandle));
        pThunksWrite := pThunksRead;
        if (DWord(pIBlock^.dwTimeDateStamp) = $FFFFFFFF) then
          pThunksRead := Pointer(DWord(pIBlock^.dwCharacteristics) + DWord(pLibraryHandle));
        while (not isBadReadPtr(pThunksRead, SizeOf(DWord))) and
          (not isBadReadPtr(pThunksWrite, SizeOf(Word))) and
          (pThunksRead^ <> 0) do begin
          if VirtualProtect(pThunksWrite, SizeOf(DWord), PAGE_EXECUTE_READWRITE, dwOldProtect) then begin
            if (DWord(pThunksRead^) and $80000000 <> 0) then
              pThunksWrite^ := DWord(GetProcAddress(dwLibraryHandle, PChar(pThunksRead^ and $FFFF)))
            else
              pThunksWrite^ := DWord(GetProcAddress(dwLibraryHandle, PChar(DWord(pLibraryHandle) + pThunksRead^ + SizeOf(Word))));
            VirtualProtect(pThunksWrite, SizeOf(DWord), dwOldProtect, dwOldProtect);
          end;
          Inc(pThunksRead);
          Inc(pThunksWrite);
        end;
      end;
      pIBlock := Pointer(DWord(pIBlock) + SizeOf(TImportBlock));
    end;
  end;

  procedure StartDll(dwDllHandle: DWord); stdcall;
  asm
    MOV EBX, DWORD PTR [dwDllHandle]
    CALL @@J
    @@J:
    POP EAX
    AND EAX, $FFFFF000
    MOV EAX, DWORD PTR [EAX]
    PUSH 0
    PUSH DLL_PROCESS_ATTACH
    PUSH EBX
    CALL EAX
  end;
  procedure EndDll; asm end;


var
  DllMain: function(dwHandle, dwReason, dwReserved: DWord): DWord; stdcall;
  IDH: PImageDosHeader;
  INH: PImageNtHeaders;
  SEC: PImageSectionHeader;
  dwSecCount: DWord;
  dwmemsize: DWord;
  i: Integer;
  pFileMem: Pointer;
  pMemLocal: Pointer;
  pMemProcess: Pointer;
  hProcessHandle: THandle;
  dwWritten: DWord;
  hThread: THandle;
  dwThreadID: DWord;
  ThreadStart: function(_Param: Pointer): Integer; stdcall;
begin
  Result := False;
  // ProcessHandle holen um Speicher für DLL zu allozieren und RemoteThread zu starten
  hProcessHandle := OpenProcess(PROCESS_ALL_ACCESS, false, dwProcessID);
  if hProcessHandle <> 0 then begin
    // für den Stream speicher holen um leichter auf die Daten zuzugreifen
    pFileMem := VirtualAlloc(nil, fsLibrary.Size, MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE);
    if (pFileMem <> nil) then begin
      fsLibrary.Position := 0;
      fsLibrary.Read(pFileMem^, fsLibrary.Size);
      IDH := pFileMem;
      // ImageDosHeader gültig?
      if (not isBadReadPtr(IDH, SizeOf(TImageDosHeader))) and
        (IDH^.e_magic = IMAGE_DOS_SIGNATURE) then begin
        // ImageNtHeader gültig?
        INH := pointer(cardinal(pFileMem) + cardinal(IDH^._lfanew));
        if (not isBadReadPtr(INH, SizeOf(TImageNtHeaders))) and
          (INH^.Signature = IMAGE_NT_SIGNATURE) then begin
          SEC := Pointer(Integer(INH) + SizeOf(TImageNtHeaders));

          // Virtuelle größe der Dll/Exe ermitteln
          dwMemSize := INH^.OptionalHeader.SizeOfImage;
          if (dwMemSize <> 0) then begin
            // Lokalen speicher für die DLL holen (wir bereiten die in userem Prozess vor)
            pMemLocal := VirtualAlloc(nil, dwMemSize, MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE);
            if (pMemLocal <> nil) then begin
              // Speicher aus dem Fremdprozess holen (indem wir die dll nachher kopieren und ausführen)
              pMemProcess := VirtualAllocEx(hProcessHandle, nil, dwMemSize+$1000, MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE);
              if pMemProcess <> nil then begin

                // jede Sektion and die richtige Adresse kopieren
                dwSecCount := INH^.FileHeader.NumberOfSections;
                CopyMemory(pMemLocal, IDH, DWord(SEC) - DWord(IDH) + dwSecCount * SizeOf(TImageSectionHeader));
                for i := 0 to dwSecCount - 1 do begin
                  CopyMemory(Pointer(DWord(pMemLocal) + SEC^.VirtualAddress),
                    Pointer(DWord(pFileMem) + DWord(SEC^.PointerToRawData)),
                    SEC^.SizeOfRawData);
                  SEC := Pointer(Integer(SEC) + SizeOf(TImageSectionHeader));
                end;

                // Adressen der Dll für den Zielprozess anpassen
                if (INH^.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress <> 0) then begin
                  ChangeReloc(Pointer(INH^.OptionalHeader.ImageBase),
                    pMemLocal,
                    Pointer(DWord(pMemLocal) + INH^.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress),
                    Pointer(pMemProcess),
                    INH^.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size);
                end;

                // die Importtabelle anpassen, die Adressen holen wir lokal aus unserem Prozess
                // sollte die Dll nicht im Zielprozess geladen sein -> crash
                // theoretisch kann man diese auch aus dem Zielprozess ermitteln
                // und fehlende Dlls dort ebenfalls nachladen
                // aber jetzt nicht hier behandelt, da dll die in einen Fremdprozess injeziert werden
                // IMMER nur ntdll/kernel32/(user32 falls Prozess mit Fenster) Funktionen benutzen sollen
                CreateImportTable(pMemLocal, Pointer(DWord(pMemLocal) + INH^.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress));

                // bei DLL-Main einen Thread starten
                @DllMain := Pointer(INH^.OptionalHeader.AddressOfEntryPoint + DWord(pMemProcess));
                if WriteProcessMemory(hProcessHandle, pMemProcess, pMemLocal, dwMemSize, dwWritten) and (dwWritten = dwMemSize) and
                   WriteProcessMemory(hProcessHandle, Pointer(DWord(pMemProcess)+dwMemSize), @@DllMain, 4, dwWritten) and (dwWritten = 4) and
                   WriteProcessMemory(hProcessHandle, Pointer(DWord(pMemProcess)+dwMemSize+4), @StartDll, Integer(@EndDll)-Integer(@StartDll), dwWritten) then begin
                  @ThreadStart := Pointer(DWord(pMemProcess)+dwMemSize+4);
                  //ThreadStart(nil);
                  hThread := CreateRemoteThread(hProcessHandle, nil, 0, @ThreadStart, nil, 0, dwThreadID);
                  if hThread <> 0 then begin
                    Result := True;
                    CloseHandle(hThread);
                  end;
                end else begin
                  VirtualFreeEx(hProcessHandle, pMemProcess, dwMemSize+$1000, MEM_DECOMMIT);
                end;
              end;
            end;
            VirtualFree(pMemLocal, dwMemSize, MEM_DECOMMIT);
          end;
        end;
        VirtualFree(pFileMem, fsLibrary.Size, MEM_DECOMMIT);
      end;
    end;
    CloseHandle(hProcessHandle);
  end;
end;
Davon ab verstehe ich aber nicht warum du nicht InjectMe verwendest. Diese ist genua dafür gedacht dll&exe in einem Programm zu haben und die Exe dann zu injecten wobei dort dann andere Funktionen (die z.b. von der Dll) ausgeführt werden können. Gerade jetzt mach ich mir wieder Gedanken ob ich den Code oben umsonst programmiert habe. Jedenfalls hätte ich dir direkt zu InjectMe geraten wenn du mir dein Anliegen erklärt hättest.
  Mit Zitat antworten Zitat
Metal_Snake2

Registriert seit: 19. Nov 2004
134 Beiträge
 
Delphi 7 Personal
 
#15

Re: Inject DLL from Memory

  Alt 19. Sep 2008, 17:32
Wollte fragen funktioniert das jetzt?

Also wenn ja dan ab damit in die Code- Library würde ich sagen.
So eine funktion kann man immer (so wie ich jetzt) wieder gebrauchen.

Edit: Wie könnte man die Injezierte Dll aus dem Prozess entfernen?
  Mit Zitat antworten Zitat
Megamorph

Registriert seit: 28. Dez 2005
25 Beiträge
 
#16

Re: Inject DLL from Memory

  Alt 20. Sep 2008, 09:39
Hallo,

ich bin noch etwas am probieren, deswegen habe ich mich noch nicht gemeldet. Mit einer ganz einfachen DLL (Application.MessageBox...) klappt es auf jeden Fall schon. Jedoch kann man kaum andere Funktionen benutzen, dann stürzt der Prozess beim injecten immer gleich ab. Man muss seine DLL's auf jeden Fall darauf zuschneiden. Aber wie gesagt - ich bin noch am Testen.

@brechi: Vielleicht wäre die Funktion ja auch eine sinnvolle Erweiterung für deine uall Collection?

edit:
@brechi: Die Funktion war auf jeden fall nicht unnütz, da ich auch dll's benutze, deren Code ich nicht kenne --> InjectMe schaltet aus

MfG Megamorph
  Mit Zitat antworten Zitat
brechi

Registriert seit: 30. Jan 2004
823 Beiträge
 
#17

Re: Inject DLL from Memory

  Alt 20. Sep 2008, 11:01
Es sollten nur Funktionen aus der kernel32.dll verwendet werden, dann sollte es funktionieren. Wenn du eine Dll hast, die nicht wirklich viel macht und nicht funktioniiert dann her damit ich würds mir dann mal anschauen.
  Mit Zitat antworten Zitat
Megamorph

Registriert seit: 28. Dez 2005
25 Beiträge
 
#18

Re: Inject DLL from Memory

  Alt 20. Sep 2008, 13:25
Hallo,

zb. ein einfaches ShowMessage funktioniert nicht, Application.MessageBox geht allerdings.

Ansonsten "mache ich sehr viel" in der DLL: haufenweise Informationen aus dem Prozess holen, Prozessspeicher komplett rauskopieren (die Analyse code ich später), etc..

MfG Megamorph
  Mit Zitat antworten Zitat
Win32.API

Registriert seit: 23. Mai 2005
312 Beiträge
 
#19

Re: Inject DLL from Memory

  Alt 20. Sep 2008, 13:49
Wenn du so wenig Wissen in diesem Bereich hast, solltest du dir das Wissen aneignen, oder das Projekt vergessen.

Oder soll brechi das gesamte Projekt fuer dich vollenden?
  Mit Zitat antworten Zitat
brechi

Registriert seit: 30. Jan 2004
823 Beiträge
 
#20

Re: Inject DLL from Memory

  Alt 20. Sep 2008, 14:09
Du verstößt gegen die Hook Regeln. Keine VCL benutzen. Nur Funktionen aus der Kernel32.dll. D.h. fü den Fall MessageBoxA. (Ist gernell so ob du nu ne dll injezierst odre nicht). *Eigentlich* sollte es funktionieren aber kA was Delphi da alles macht in der VCL.
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 03:24 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz