لقد أمضيت فترة ما بعد الظهيرة في MSDN وكتبت هذا المثال.
لقد كتبت testdll.dll ، والتي تحتوي فقط على وظيفة السجل ، والتي يتم استخدامها لإخراج المعلومات في Test.txt.
بيئة الاختبار: WindowsServer2003+Delphi7.0
البرنامج بسيط للغاية ، لذلك لا يحتاج الخبراء إلى قراءته.
TestDll.dll رمز المصدر للاختبار (سيتم حقنه في prjzzhost.exe):
رمز البرنامجLibraryTestdll ؛
يستخدم
sysutils ،
نظام،
النوافذ ،
الطبقات
الإجراء (S: PCHAR) ؛ stdcall ؛
var
F: TextFile ؛
يبدأ
issignfile (f ، 'test.txt') ؛
iffilexists ('test.txt') thenappend (f)
ElsereWrite (F) ؛
Writeeln (f ، s) ؛
Closefile (F) ؛
نهاية؛
ProseasureDllentryPoint (dwreason: dword) ؛
يبدأ
casedwreasonof
dll_process_attach:
log ('dllprocessattach') ؛
dll_process_detach:
log ('dllProcessDetach') ؛
dll_thread_attach:
log ('dllthreadattach') ؛
dll_thread_detach:
log ('dllthreaddetach') ؛
نهاية؛
نهاية؛
صادرات
سجل؛
يبدأ
dllproc: =@dllentrypoint ؛
dllentrypoint (dll_process_attach) ؛
نهاية.
عملية المضيف التي تم حقنها prjzzhost.exe (لا تفعل شيئًا ، إنها بريئة للغاية :) ، لن أعطي الكود هنا لأنه بسيط للغاية ، هاها.
أخيرًا ، أهم شيء هو:
رمز المصدر للمشروع 1.exe:
رمز البرنامجUnitunit1 ؛
واجهة
يستخدم
Windows ، الرسائل ، sysutils ، المتغيرات ، الفئات ، الرسومات ، عناصر التحكم ، النماذج ،
مربعات الحوار ، stdctrls ، tlhelp32 ؛
يكتب
tlog = الإجراء (s: pchar) ؛ stdcall ؛
tservicemain = الإجراء (argc: integer ؛ varargv: pchar) ؛ stdcall ؛
edllloaderror = class (استثناء) ؛
tform1 = فئة (tform)
Button3: Tbutton ؛
الإجراءات button3click (المرسل: tooject) ؛
خاص
{privatedEclarations}
عام
{publicdeclarations}
نهاية؛
var
Form1: Tform1 ؛
تطبيق
{$ r*.dfm}
{تسجيل العمليات}
الإجراءات grocessid (constafilename: string ؛ constPathMatch: boolean ؛ varprocessid: dword) ؛
var
lppe: tprocessentry32 ؛
Sshandle: Thandle ؛
Proforgroc ، Foundok: Boolean ؛
يبدأ
ProcessID: = 0 ؛
{إنشاء لقطة نظام}
Sshandle: = CreateToolHelp32Snapshot (Th32CS_SnapProcess ، 0) ؛
{احصل على العملية الأولى في اللقطة}
{تأكد من ضبط حجم الهيكل ، وإلا سيتم إرجاع خطأ}
lppe.dwsize: = sizeof (tprocessentry32) ؛
profitaproc: = process32first (sshandle ، lppe) ؛
بينما FoundaProcdo
يبدأ
{اجعل المباراة}
Ifpathmatchthen
Foundok: = Ansistricomp (lppe.szexefile ، pCare (afiLename)) = 0
آخر
Foundok: = AnsistriComp (pCHAR (extractFilename (lppe.szexefile)) ، pchar (extractFilename (afilename))) = 0 ؛
iffoundokthen
يبدأ
ProcessId: = lppe.th32Processid ؛
استراحة؛
نهاية؛
{غير موجود ، تابع إلى العملية التالية}
insproc: = process32next (sshandle ، lppe) ؛
نهاية؛
CloseHandle (sshandle) ؛
نهاية؛
{تعيين الأذونات}
PORMONEDENTABLEDDEBUGPRIVILEGE (constenabled: Boolean): Boolean ؛
var
HTK: Thandle ؛ {Open Token Handle}
rtntemp: dword ؛ {القيمة التي تم إرجاعها عند ضبط الأذونات}
tokenpri: token_privileges ؛
كونست
se_debug = 'sedebugprivilege' ؛ {Query Value}
يبدأ
النتيجة: = خطأ ؛
{احصل على مقبض الرمز المميز ، تعيين أذونات}
if (OpenProcessToken (getCurrentProcess () ، token_adjust_privileges ، htk)) ثم
يبدأ
tokenpri.privileGeCount: = 1 ؛
{احصل على قيمة luid}
lookuprivilegevalue (nil ، se_debug ، tokenpri.privileges [0] .luid) ؛
Ifenabledthen
tokenpri.privileges [0] .attributes: = se_privilege_enabled
آخر
tokenpri.privileges [0] .attributes: = 0 ؛
rtntemp: = 0 ؛
{اضبط أذونات جديدة}
تعديل ttokenprivileges (htk ، false ، tokenpri ، sizeof (tokenpri) ، nil ، rtntemp) ؛
النتيجة: = getLasterror = error_success ؛
CloseHandle (HTK) ؛
نهاية؛
نهاية؛
{وظيفة التصحيح}
storeureOutputText (varch: pCare) ؛
var
FileHandle: TextFile ؛
يبدأ
ignfile (fileHandle ، 'zztest.txt') ؛
إلحاق (fileHandle) ؛
Writeln (fileHandle ، ch) ؛
Flush (fileHandle) ؛
CloseFile (fileHandle) ؛
نهاية؛
{حقن العملية عن بُعد}
functionInjectTO (consthost ، الضيف: سلسلة ؛ contpid: dword = 0): dword ؛
var
{مقبض العملية المحقونة ، معرف العملية}
Hremoteprocess: Thandle ؛
dwremoteprocessid: dword ؛
{حجم المحتوى المكتوب على العملية البعيدة}
memsize: dword ؛
{العنوان بعد الكتابة على العملية عن بُعد}
pszlibfileremote: مؤشر ؛
Ireturncode: منطقية ؛
Tempvar: Dword ؛
{أشير إلى عنوان الدالة loadlibraryw}
pfnstartaddr: tfnthroadstartroutine ؛
{DLL PULL PATH ، يجب كتابتها إلى ذاكرة العملية عن بُعد}
pszlibafilename: pwidechar ؛
يبدأ
النتائج: = 0 ؛
{تعيين الأذونات}
EnupplyDebugprivilege (صواب) ؛
{تخصيص حجم الذاكرة لمسار ملف DLL المحقن ، لأنه widechar ، يجب مضاعفه بمقدار 2}
getMem (pszlibafilename ، طول (ضيف)*2+1) ؛
StringTowIdechar (ضيف ، pszlibafilename ، طول (ضيف)*2+1) ؛
{الحصول على معرف العملية}
ifpid> 0then
dwremoteprocessid: = pid
آخر
GetMyProcessid (مضيف ، خطأ ، dwremoteprocessid) ؛
{احصل على مقبض العملية عن بُعد ، احصل على إذن الكتابة}
HremoteProcess: = OpenProcess (Process_Create_Thread+{السماح بإنشاء مؤشرات الترابط عن بُعد}
process_vm_operation+{السماح بعمليات VM عن بُعد}
process_vm_write ، {السماح للكتابة عن بُعد}
كاذبة ، dwremoteprocessid) ؛
{استخدم الدالة VirtualAllocex لتخصيص مساحة في العملية البعيدة ، واكتب مسار DLL في WriteProcessMemory}
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
يبدأ
pfnstartaddr: = getProcaddress (getModuleHandle ('kernel32') ، 'loadlibraryw') ؛
tempvar: = 0 ؛
{ابدأ DLL في العملية البعيدة}
النتيجة: = createremotethread (hremoteprocess ، nil ، 0 ، pfnstartaddr ، pszlibfileremote ، 0 ، tempvar) ؛
نهاية؛
{مساحة الذاكرة الحرة}
Freemem (pszlibafilename) ؛
نهاية؛
{امتحان}
الإجراءات 1.button3click (المرسل: tobject) ؛
يبدأ
حقن ('prjzzhost.exe' ، extractFilePath (paramstr (0))+'TestDll.dll') ؛
نهاية؛
نهاية.
لا ينظر الكود في أعقاب تحميل DLL.