![]() |
Re: Inject DLL from Memory
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 |
Re: Inject DLL from Memory
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.
|
Re: Inject DLL from Memory
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 |
Re: Inject DLL from Memory
Delphi-Quellcode:
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.
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; |
Re: Inject DLL from Memory
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? |
Re: Inject DLL from Memory
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 |
Re: Inject DLL from Memory
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.
|
Re: Inject DLL from Memory
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 |
Re: Inject DLL from Memory
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? :roll: |
Re: Inject DLL from Memory
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.
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 11:37 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz