Saya menghabiskan satu sore membalik MSDN dan menulis contoh ini.
Saya menulis testdll.dll, yang hanya memiliki fungsi log, yang digunakan untuk mengeluarkan informasi dalam file test.txt.
Lingkungan Uji: WindowsServer2003+Delphi7.0
Program ini sangat sederhana, jadi para ahli tidak perlu membacanya.
TestDll.dll kode sumber untuk pengujian (akan disuntikkan ke prjzzhost.exe):
Kode Programlibrarytestdll;
penggunaan
Sysutils,
Sistem,
windows,
Kelas;
Prosedurelog (S: PCHAR); stdcall;
var
F: TextFile;
Mulai
assignfile (f, 'test.txt');
IfFileExists ('test.txt') lalu lampai (f)
ElsereWrite (f);
writeeln (f, s);
closeFile (f);
akhir;
ProceduredllEntrypoint (DWREASRE: DWORD);
Mulai
Casedwreasonof
DLL_PROCESS_ATTACH:
Log ('DLLProcessAttach');
DLL_PROCESS_DETACH:
Log ('DLLProcessDetach');
Dll_thread_attach:
Log ('DllThreadattach');
DLL_THREAD_DETACH:
Log ('DllThreadDetach');
akhir;
akhir;
ekspor
Log;
Mulai
DLLPROC: =@DllentryPoint;
Dllentrypoint (DLL_PROCESS_ATTACH);
akhir.
Proses host yang disuntikkan prjzzhost.exe (tidak melakukan apa -apa, itu sangat polos :), saya tidak akan memberikan kode di sini karena terlalu sederhana, haha.
Akhirnya, yang paling penting adalah:
Kode Sumber Project1.exe:
Kode Programunitunit1;
antarmuka
penggunaan
Windows, pesan, sysutils, varian, kelas, grafik, kontrol, formulir,
Dialog, stdctrls, tlhelp32;
jenis
Tlog = prosedur (s: pchar); stdcall;
Tservicemain = prosedur (argc: integer; varargv: pchar); stdcall;
EdllloadError = class (Exception);
Tform1 = class (tform)
Button3: tbutton;
ProsedurButton3Click (pengirim: Tobject);
Pribadi
{PrivatedEclarations}
publik
{PublicDeclarations}
akhir;
var
Form1: tform1;
Pelaksanaan
{$ R*.dfm}
{Pendaftaran proses}
ProsedureGetMyProcessId (ConstAfilename: String; ConstPathmatch: Boolean; VarProcessid: DWORD);
var
LPPE: TPROCESSENTRY32;
Sshandle: Thandle;
Foundaproc, foundok: boolean;
Mulai
ProcessID: = 0;
{Buat snapshot sistem}
Sshandle: = createToolHelp32snapshot (th32cs_snapprocess, 0);
{Dapatkan proses pertama di snapshot}
{Pastikan untuk mengatur ukuran struktur, jika tidak salah akan dikembalikan}
lppe.dwsize: = sizeof (tProcessEntry32);
Foundaproc: = Process32First (sshandle, lppe);
sementaraoundaprocdo
Mulai
{buat pertandingan}
ifpathmatchthen
Foundok: = ansistricomp (lppe.szexefile, pchar (afilename)) = 0
kalau tidak
Foundok: = ansistricomp (pchar (extractFileName (lppe.szexefile)), pchar (extractFileName (afilename))) = 0;
iffoundokthen
Mulai
ProcessID: = LPPE.TH32PROCESSID;
merusak;
akhir;
{Tidak ditemukan, lanjutkan ke proses berikutnya}
Foundaproc: = Process32Next (sshandle, lppe);
akhir;
CloseHandle (sshandle);
akhir;
{Atur izin}
FunctionAnabledDebugPrivilege (Constenabled: Boolean): Boolean;
var
htk: thandle; {buka token handle}
rtntemp: dword; {nilai dikembalikan saat menyesuaikan izin}
TokenPri: Token_Privileges;
const
Se_debug = 'sedebugprivilege'; {nilai kueri}
Mulai
Hasil: = false;
{Dapatkan pegangan token proses, atur izin}
if (OpenProcessToken (getCurrentProcess (), token_adjust_privileges, htk)) lalu
Mulai
Tokenpri.privilegecount: = 1;
{Dapatkan nilai luid}
Lookupprivilegevalue (nil, se_debug, tokenpri.privileges [0] .luid);
ifeNableDthen
Tokenpri.privileges [0] .attributes: = se_privilege_enabled
kalau tidak
Tokenpri.privileges [0] .attributes: = 0;
rtntemp: = 0;
{Atur izin baru}
AdjustTokenPrivileges (htk, false, tokenpri, sizeof (tokenpri), nil, rtntemp);
Hasil: = getlasterror = error_success;
CloseHandle (htk);
akhir;
akhir;
{Fungsi debug}
ProsedurureOutputText (varch: pchar);
var
FileHandle: TextFile;
Mulai
Assignfile (fileHandle, 'zztest.txt');
Tambahkan (FileHandle);
Writeln (FileHandle, ch);
Flush (FileHandle);
CloseFile (FileHandle);
AKHIR;
{Suntikkan proses jarak jauh}
functionInjectto (consthost, tamu: string; constpid: dword = 0): dword;
var
{Pegangan proses yang disuntikkan, ID proses}
Hremoteprocess: Thandle;
dwremoteprocessid: dword;
{Ukuran konten yang ditulis untuk proses jarak jauh}
memsize: dword;
{Alamat setelah menulis ke proses jarak jauh}
pszlibfileremote: pointer;
IRETURNCODE: BOOLEAN;
Tempvar: DWORD;
{Poin ke alamat fungsi loadLibraryw}
pfnstartaddr: tfnthreadstartroutine;
{Dll Path Full, perlu ditulis ke memori proses jarak jauh}
pszlibafilename: pwidechar;
Mulai
Hasil: = 0;
{Atur izin}
EnabledDebugPrivilege (true);
{Aloksi ukuran memori untuk jalur file DLL yang disuntikkan, karena itu adalah Widechar, harus dikalikan dengan 2}
GetMem (pszlibafilename, panjang (tamu)*2+1);
StringTowIdechar (tamu, pszlibafilename, panjang (tamu)*2+1);
{Dapatkan ID Proses}
ifpid> 0then
dwremoteprocessid: = pid
kalau tidak
GetMyProcessId (host, false, dwremoteprocessid);
{Dapatkan pegangan proses jarak jauh, miliki izin tulis}
hremoteprocess: = openprocess (process_create_thread+{Izinkan pembuatan remote utas}
Proses_VM_Operation+{Izinkan Operasi VM Jarak Jauh}
Proses_vm_write, {Izinkan Penulisan VM Jarak Jauh}
False, dwremoteprocessid);
{Gunakan fungsi virtualAllocex untuk mengalokasikan ruang dalam proses jarak jauh, dan tulis jalur dll di 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
Mulai
pfnstartaddr: = getProcaddress (getModuleHandle ('kernel32'), 'loadLibraryw');
Tempvar: = 0;
{Start dll dalam proses jarak jauh}
Hasil: = createremotethread (hremoteprocess, nil, 0, pfnstartaddr, pszlibfileremote, 0, tempvar);
akhir;
{Ruang memori gratis}
Freemem (pszlibafilename);
akhir;
{tes}
ProcedureTform1.Button3Click (pengirim: TOBJEKS);
Mulai
Injectto ('prjzzhost.exe', extractFilePath (paramstr (0))+'testdll.dll');
akhir;
akhir.
Kode tidak mempertimbangkan akibat dari DLL yang dimuat.