Ich habe einen Nachmittag damit verbracht, MSDN durchzublättern und dieses Beispiel für die Sicherheit geschrieben.
Ich habe eine testdll.dll geschrieben, die nur eine Protokollfunktion hat, die zum Ausgabe von Informationen im Dateitest.txt verwendet wird.
Testumgebung: Windowsserver2003+Delphi7.0
Das Programm ist sehr einfach, daher müssen Experten es nicht lesen.
TestDll.dll Quellcode für Test (er wird in prjzzhost.exe injiziert):
ProgrammcodeLibraryTestDll;
Verwendung
SYSUTILS,
System,
Fenster,
Klassen;
procedurelog (s: pchar); stdcall;
var
F: Textfile;
Beginnen
ordnungszeichen (f, 'test.txt');
IFFILEExists ('test.txt'), dann append (f)
ElSerewrite (F);
writeeln (f, s);
CloseFile (f);
Ende;
verfahrensllEntryPoint (dwresonas: dWord);
Beginnen
CASEDWREASONOF
Dll_process_attach:
Log ('dllProcessattach');
Dll_process_detach:
Log ('dllProcessdetach');
Dll_thread_attach:
Log ('dllhreadattach');
Dll_thread_detach:
Log ('dllhreaddetach');
Ende;
Ende;
Exporte
Protokoll;
Beginnen
DllProc: =@dllentryPoint;
DllentryPoint (dll_process_attach);
Ende.
Der injizierte Host -Prozess prjzzhost.exe (es tut nichts, es ist so unschuldig :), ich werde den Code hier nicht geben, weil er zu einfach ist, haha.
Schließlich ist das Wichtigste:
Quellcode von Project1.exe:
ProgrammcodeUnitUnit1;
Schnittstelle
Verwendung
Fenster, Nachrichten, Systeme, Varianten, Klassen, Grafiken, Steuerelemente, Formulare,
Dialoge, stdctrls, tlhelp32;
Typ
Tlog = procedure (s: pchar); stdcall;
TServicemain = Verfahren (argc: Integer; varargv: pchar); stdcall;
EdllloadError = class (Ausnahme);
Tform1 = Klasse (tform)
Button3: Tbutton;
procedurebutton3click (Absender: tobject);
Privat
{PrivatatedEclarations}
öffentlich
{PublicDeclarations}
Ende;
var
Form1: tform1;
Durchführung
{$ R*.dfm}
{Registrierung von Prozessen}
procedureGetMyProcessid (ConstafileName: String; constPathMatch: boolean; varprocessid: dWord);
var
LPPE: TPROCESSENTRY32;
Sshandle: Thandle;
Foundaproc, Foundok: Boolean;
Beginnen
ProcessID: = 0;
{Erstellen Sie ein System Snapshot}
SSHANDLE: = CreateToolHelp32SnapShot (Th32CS_SnApprocess, 0);
{Holen Sie sich den ersten Prozess im Snapshot}
{Stellen Sie sicher, dass Sie die Größe der Struktur festlegen, ansonsten wird Falsch zurückgegeben}}
LPPE.DWSIZE: = sizeof (tprocessentry32);
FoundAPROC: = process32First (sshandle, lppe);
whilefoundaprocdo
Beginnen
{mach ein Match}
ifpathMatchthen
Foundok: = Ansiktricomp (lppe.szexefile, pchar (afileName)) = 0
anders
Footok: = ansiktricomp (pchar (extractFileName (LPPE.SZEXEFILE)), PCHRE (ExtractFileName (AfileName))) = 0;
iffoundokthen
Beginnen
ProcessID: = lppe.th32Processid;
brechen;
Ende;
{Nicht gefunden, weiter mit dem nächsten Prozess} fortgesetzt}
FoundAPROC: = process32Next (sshandle, lppe);
Ende;
Nahe Handle (Shandle);
Ende;
{Berechtigungen festlegen}
FUNKTIONELADEDDEBUGPRIVILEGE (Verhältnis: boolean): boolean;
var
HTK: Thandle; {Open Token -Handle}
Rtntemp: DWORD; {Wert zurückgegeben, wenn die Berechtigungen angepasst werden}
Tokenpri: token_privileges;
Const
SE_DEBUG = 'SEDEBUGPRIVIREGE'; {Abfragewert}
Beginnen
Ergebnis: = falsch;
{Get Process Token Handle, Setzen Sie Berechtigungen}
if (openProcessToken (getCurrentProcess (), token_adjust_privileges, htk) dann
Beginnen
TokenPri.privilegeCount: = 1;
{Get luid value}
LookupprivileGeValue (nil, se_debug, tokenpri.privileges [0] .luid);
ifenabledthen
Tokenpri.privileges [0] .attributes: = se_privilege_enabled
anders
Tokenpri.privileges [0] .attributes: = 0;
rtntemp: = 0;
{Setzen Sie neue Berechtigungen}
OrdnungsgemäßePrivileges (HTK, False, TokenPri, Sizeof (Tokenpri), Nil, Rtntemp);
Ergebnis: = getLasterror = error_success;
Nahhandle (HTK);
Ende;
Ende;
{Debug -Funktion}
procedureOutputText (varch: pchar);
var
DateiHandle: textfile;
Beginnen
Ordnungsdatei (DateiHandle, 'zzTest.txt');
Append (DateiHandle);
WriteLN (FileHandle, CH);
Flush (FileHandle);
CloseFile (FileHandle);
ENDE;
{Remote -Prozess injizieren}
functionInjectto (CSECTHOST, Gast: String; constpid: dWord = 0): DWORD;
var
{Injiziertes Prozesshandle, Prozess -ID}
HremoteProcess: Thandle;
DWREMOTEPROCESSID: DWORD;
{Größe des in Remote -Prozesses geschriebenen Inhalts}
memrize: dword;
{Adresse nach dem Schreiben in den Remote -Prozess}
pszlibFileremote: Zeiger;
IreturnCode: boolean;
Tempvar: dword;
{Zeigen Sie auf die Adresse der Funktion loadlibraryw}
Pfnstartaddr: tfnThreadStarToutine;
{DLL Full Pfad, muss in den Speicher des Remote -Prozesses geschrieben werden}
pszlibafilename: pwidechar;
Beginnen
Ergebnisse: = 0;
{Berechtigungen festlegen}
EnabledDebugprivilege (true);
{Zuordnen der Speichergröße für den injizierten DLL -Dateipfad, da es sich um Widechar handelt, muss es mit 2} multipliziert werden
GetMem (pszlibafilename, Länge (Gast)*2+1);
StringTowidechar (Gast, pszlibafilename, Länge (Gast)*2+1);
{Process id} abrufen
IfPID> 0Then
DWREMOTEPROCESSID: = PID
anders
GetMyProcessid (Host, Falsch, dwremoteProcessid);
{Remote -Prozesshandle erhalten, eine Schreibberechtigung haben}}
HremoteProcess: = openProcess (process_create_thread+{Erstellen Sie die Remote -Erstellung von Threads}
Process_vm_operation+{erlauben remote vm operations}}
Process_vm_write, {Remote VM Writing} erlauben}
Falsch, dwremoteProcessid);
{Verwenden Sie die Funktion virtualalLocex, um Platz im Remote -Prozess zuzuweisen und den DLL -Pfad in WriteProcessMemory zu schreiben}
memsize: = (1+lstrlenw (pszlibafilename))*sizeof (wchar);
pszlibFileremote: = pwidestring (virtualallocex (hremoteProcess, nil, memsize, mem_commit, page_readwrite));
Tempvar: = 0;
IreturnCode: = WriteProcessMemory (hremoteProcess, pszlibFileremote, pszlibafilename, memsize, tempvar);
ifireturncodethen
Beginnen
pfnstartaddr: = getProcaddress (getModuleHandle ('kernel32'), 'lastlibraryW');
Tempvar: = 0;
{Starten Sie DLL im Remote -Prozess}
Ergebnis: = createRemotethread (hremoteProcess, nil, 0, pfnstartaddr, pszlibFileremote, 0, tempvar);
Ende;
{freier Speicherplatz}
Freemem (pszlibafilename);
Ende;
{prüfen}
proceduretform1.button3click (Absender: tobject);
Beginnen
Injectto ('PrjzzHost.exe', ExtractFilePath (Paramstr (0))+'testDll.dll');
Ende;
Ende.
Der Code berücksichtigt nicht die Folgen des geladenen DLL.