![]() |
Delphi-Version: XE8
DLL Injection von Memory in anderen Prozess
Mit Hilfe von BTMemoryModule (
![]()
Delphi-Quellcode:
Jedoch möchte ich die DLL nicht in meinen Speicher laden und verwenden, sondern in einen anderen Prozesss (Notepad).
unit Main;
{ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Memory DLL loading code Demo Application * *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -* * Copyright (c) 2005-2010 by Martin Offenwanger / coder@dsplayer.de * * http://www.dsplayer.de * *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -* * Mozilla Public License Version 1.1: * *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -* * The contents of this file are used with permission, subject to the * * Mozilla Public License Version 1.1 (the "License"); you may * * not use this file except in compliance with the License. You may * * obtain a copy of the License at * * http://www.mozilla.org/MPL/MPL-1.1.html * * + * Software distributed under the License is distributed on an * * "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * * implied. See the License for the specific language governing * * rights and limitations under the License. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * } { @author(Martin Offenwanger: coder@dsplayer.de) @created(Mar 20, 2005) @lastmod(Jul 16, 2010) @supported operationg systems(Windows 98 up to Windows 7) @tested Delphi compilers(Delphi 7, Delphi 2007 , Delphi 2010) } interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, BTMemoryModule, StdCtrls, xpman; type TTestCallstdA = procedure(f_Text: PAnsiChar); stdcall; TTestCallstdW = procedure(f_Text: PWideChar); stdcall; TTestCallcdelA = procedure(f_Text: PAnsiChar); cdecl; TTestCallcdelW = procedure(f_Text: PWideChar); cdecl; TForm1 = class(TForm) BtnMemCall: TButton; procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure BtnMemCallClick(Sender: TObject); private m_TestCallstdA: TTestCallstdA; m_TestCallstdW: TTestCallstdW; m_TestCallcdelA: TTestCallcdelA; m_TestCallcdelW: TTestCallcdelW; mp_DllData: Pointer; m_DllDataSize: Integer; mp_MemoryModule: PBTMemoryModule; public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} {$R DemoDLL.RES} procedure TForm1.FormCreate(Sender: TObject); var ResStream: TResourceStream; begin Position := poScreenCenter; ResStream := TResourceStream.Create(HInstance, 'DemoDLL', RT_RCDATA); ResStream.Position := 0; m_DllDataSize := ResStream.Size; mp_DllData := GetMemory(m_DllDataSize); ResStream.Read(mp_DllData^, m_DllDataSize); ResStream.Free; end; procedure TForm1.FormDestroy(Sender: TObject); begin FreeMemory(mp_DllData); end; procedure TForm1.BtnMemCallClick(Sender: TObject); begin mp_MemoryModule := BTMemoryLoadLibary(mp_DllData, m_DllDataSize); try if mp_MemoryModule = nil then Abort; @m_TestCallstdA := BTMemoryGetProcAddress(mp_MemoryModule, 'TestCallstdA'); if @m_TestCallstdA = nil then Abort; @m_TestCallstdW := BTMemoryGetProcAddress(mp_MemoryModule, 'TestCallstdW'); if @m_TestCallstdW = nil then Abort; @m_TestCallcdelA := BTMemoryGetProcAddress(mp_MemoryModule, 'TestCallcdelA'); if @m_TestCallcdelA = nil then Abort; @m_TestCallcdelW := BTMemoryGetProcAddress(mp_MemoryModule, 'TestCallcdelW'); if @m_TestCallcdelW = nil then Abort; m_TestCallstdA('This is a Dll Memory call loaded from resource!'); m_TestCallstdW('This is a Dll Memory call loaded from resource!'); m_TestCallcdelA('This is a Dll Memory call loaded from resource!'); m_TestCallcdelW('This is a Dll Memory call loaded from resource!'); except Showmessage('An error occoured while loading the dll: ' + BTMemoryGetLastError); end; if mp_MemoryModule <> nil then BTMemoryFreeLibrary(mp_MemoryModule); end; end. Leider fehlt mir die Erfahrung bzw. das Know-How, wie dies zu bewerkstelligen ist. Über jegliche Hilfe wäre ich sehr dankbar. |
AW: DLL Injection von Memory in anderen Prozess
Es ist vllt etwas umständlich (bin mir grad im ersten Moment nicht sicher obs auch einfacher geht):
Du kannst eine DLL erstellen die deine Memory-DLL als Ressource enthält. Diese DLL injizierst du dann "ganz normal" über DLL Injection in Notepad. Deine ZwischenDLL lädt nun ganz normal wie in deinem Beispielcode unten die Memory-DLL. Weiß aber nicht ob das für dich so in Ordnung ist. Du könntest die DLL aus der Resource auch stattdessen als normale Datei abspeichern und diese injizieren. Wofür soll der ganze Ressourcen-Kram denn gut sein? |
AW: DLL Injection von Memory in anderen Prozess
Hallo Michael,
so ähnlich habe ich es momentan auch realisiert. Erst wird eine Dll in den Zielprozess injectet, die dann wiederrum eine weitere Dll läd ohne sie auf der Festplatte zu speichern. Optimalerweise wäre es jedoch folgendermaßen: Programm (exe) läd eine Dll direkt in einen Zielprozess ohne Zwischen-DLL und ohne Zwischen-Speichern auf Festplatte. |
AW: DLL Injection von Memory in anderen Prozess
Zitat:
Du kannst die Dll auch direkt aus deiner Resource in den Zielprozess mappen, aber das ist nicht wirklich trivial und erfordert viel Wissen über das PE Format und die Funktionsweise des Windows Loaders. Hatte vor Ewigkeiten mal eine "Manual Mapping" Library geschrieben, die Dlls direkt aus einer Resource laden konnte (nur im eigenen Prozess). Es ist aber auch möglich direkt in einen Zielprozess zu mappen. Mapping der Sections mit NtCreateSection, NtMapViewOfSection, (evtl. VirtualProtect, wenn du die Section Protections korrekt setzen willst), danach musst du Relocations parsen und anwenden, die IAT auflösen (indem du einen kleinen Loader im Zielprozess ausführst z.b. mit CreateRemoteThread), TLS ausführen, DllMain ausführen, ggfls. noch Exception Tables laden (64 Bit) und noch viele weitere kleine Dinge. Alles in allem den Aufwand nicht wert denke ich :wink: |
AW: DLL Injection von Memory in anderen Prozess
Genau das macht doch BTMemoryModule,
d.h. man kann das dort doch erweitern (VirtualAllocEx anstatt VirtualAlloc etc.) uallHook von mir hat eine Funktion InjectMe, da kann die eigene Exe-Datei direkt in einen Zielprozess geladen werden ![]() Naja schön ist das zwar nicht, würde das mittlerweilse anders machen aber vill hilfts dir. |
AW: DLL Injection von Memory in anderen Prozess
Hallo Zacherl und brechi!
Vielen Dank für euren Input. Leider bin ich nun etwas verwirrt, da sich eure Antworten dermaßen unterscheiden in Sachen Aufwand und Angehensweise. Die Vorgehensweise von dir Zacherl ist, wie du ja selbst schreibst "den Aufwand nicht wert", da ich mich wahrscheinlich einige Wochen mit dem Thema beschäftigen müsste um einen Einblick in die Thematik zu bekommen. Sollte ich jedoch wirklich nur ![]() ![]() Danke auch nochmal an brechi für den Link zur ![]() Edit: Wäre diese Vorgehensweise bei VirtualAllocEx korrekt:
? |
AW: DLL Injection von Memory in anderen Prozess
Zitat:
IAT auflösen und DllMain ausführen dann per CreateRemoteThread. |
AW: DLL Injection von Memory in anderen Prozess
Du kannst auch die InjectMe Funktion anpassen:
bei ReadFile(iFileHandle, pFileMem^, dwFileSize, dwRead, nil); wird in pFileMem die Datei eingelesen, das kann dein Pointer auf den Speicherbereich der dll sein. Innerhalb der Funktion die du bei "pDllMain" angibst, solltest du aber auch nur Funktionen verwenden die bereits im Prozess geladen wurden (und da wohl nur von der kernel32.dll) uallKernel.CreateImportTable müsste sonst noch angepasst werden, da dort die lokalen Adressen verwendet werden und nicht die vom Zielprozess. Achja: eine dll ist ja nichts anderes als ne exe, d.h. du kannst deine Funktionen in die eigene Exe einbauen und dann di eigene exe in den Zielprozess laden, aber mit einem anderen EntryPoint. |
AW: DLL Injection von Memory in anderen Prozess
Liste der Anhänge anzeigen (Anzahl: 1)
Habe leider vergeblich den gestrigen Abend damit verbracht BTMemoryModule umzuschreiben mit
Delphi-Quellcode:
und den von Zacherl genannten Änderungen (wpm, createremotethread,... ).
VirtualAllocEx
Die Herangehensweise die Exe zu injecten finde ich sehr interessant. Habe mir daszu mal den passenden Text aus der msdn Hilfe kopiert: Zitat:
Das hat auch soweit geklappt: http://www.delphipraxis.net/attachme...1&d=1437975655 Nur weiß ich jetzt noch nicht so recht, wie ich beispielsweise direkt Code beim injecten der Exe im Zielprozess ausführen kann. Sofern man eine Dll injected wird automatisch DllMain ausgeführt. Bei der Injection gehe ich folgendermaßen vor:
Delphi-Quellcode:
Gibt es eine Möglichkeit Code direkt beim Injecten der Exe auf diese Weise auszuführen?
function InjectExe(const pid: DWORD; exedir: PWideChar): Boolean;
var dwThreadID: Cardinal; hProc, hKernel: THandle; BytesToWrite, BytesWritten: SIZE_T; pRemoteBuffer, pLoadLibrary: Pointer; hThread: THandle; begin Result := True; hProc := OpenProcess(PROCESS_CREATE_THREAD or PROCESS_QUERY_INFORMATION or PROCESS_VM_OPERATION or PROCESS_VM_WRITE or PROCESS_VM_READ, False, pid); if hProc = 0 then Exit(False); try BytesToWrite := SizeOf(WideChar) * (Length(exedir) + 1); pRemoteBuffer := VirtualAllocEx(hProc, nil, BytesToWrite, MEM_COMMIT, PAGE_READWRITE); if pRemoteBuffer = nil then Exit(False); try if not WriteProcessMemory(hProc, pRemoteBuffer, exedir, BytesToWrite, BytesWritten) then Exit(False); hKernel := GetModuleHandleW('kernel32.dll'); pLoadLibrary := GetProcAddress(hKernel, 'LoadLibraryW'); hThread := CreateRemoteThread(hProc, nil, 0, pLoadLibrary, pRemoteBuffer, 0, dwThreadID); try WaitForSingleObject(hThread, INFINITE); finally CloseHandle(hThread); end; finally VirtualFreeEx(hProc, pRemoteBuffer, 0, MEM_RELEASE); end; finally CloseHandle(hProc); end; end; |
AW: DLL Injection von Memory in anderen Prozess
Ja, du musst per CreateRemoteThread die DllMain ausführen. Das Offset dazu findest du in den ImageNtHeaders unter dem Namen EntryPoint. Prototyp ist folgender:
![]() Beim Laden nimmst du DLL_PROCESS_ATTACH als fdwReason und beim Entladen DLL_PROCESS_DETACH. Korrekterweise müsste man auch noch DLL_THREAD_ATTACH und DLL_THREAD_DETACH implementieren (ist zumindest bei manchen DLLs erforderlich, die manuell TLS benutzen), aber dazu benötigt man entweder Hooks in der DLL selbst oder eine zweite "normal" geladene DLL, mit der man die Events weiterleiten kann. Dürfte in den meisten Fällen allerdings nicht nötig sein, also probier es ruhig erstmal ohne. Brechis Code sollte ja irgendwo auch die WinMain (ebenfalls über das EntryPoint Feld referenziert) ausführen (welche allerdings einen anderen ![]() |
AW: DLL Injection von Memory in anderen Prozess
Alles klar mit den Informationen kann man arbeiten :-D
Werde mich mal die Woche hier dran machen und schauen, ob ich es zu laufen bekomme. Danke nochmal. |
AW: DLL Injection von Memory in anderen Prozess
Hallo,
die Frage ist zwar einbiszchen offtopic, aber als jemand, der noch nie DLL Injection verwendet hat, was kann man eigentlich mit DLL Injection machen, was man so nicht machen kann? Sprich für was ist eigentlich DLL Injection? Vielleicht kann jemand paar Beispiele aufzählen. Lg, jus |
AW: DLL Injection von Memory in anderen Prozess
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:02 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 by Thomas Breitkreuz