Часто надо заинжектить dll-ку в какой нибудь процесс.
Мы сделаем удобную утилитку. Перейдя по dll в контекстном меню, будет наш пункт inject to, кликнув по которому, можно легко и быстро внедрить dll в любой процесс. Ну а там кому что по душе .
Итак, добавим ресурс диалога, на нем поместим listbox и начинаем кодить…
#include <stdio.h>#include <string.h>#include <windows.h>#include <tlhelp32.h>#include <shlwapi.h>#include "resource.h"#define HASHSIZE 101volatile unsigned long _data;#define tls(_data) ((struct info*)TlsGetValue ( _data ))struct process_in { char exe [ MAX_PATH ]; unsigned pid;};struct info { char path [ MAX_PATH ]; struct process_in arr [ HASHSIZE ];};unsigned hash ( char * s ) { unsigned hashval; for ( hashval = 0; *s; s++ ) hashval = *s + 31 * hashval; return hashval % HASHSIZE;}/***************************************************************************\* делаем снимок процессов заполняем listbox попутно сохраняем pid'ы\***************************************************************************/int select_prce ( HWND hListBox ) { PROCESSENTRY32 pe32; HANDLE hSnap; unsigned hashval; hSnap = CreateToolhelp32Snapshot ( TH32CS_SNAPPROCESS, 0 ); if ( !hSnap ) return 0; pe32.dwSize = sizeof pe32; Process32First ( hSnap, &pe32 ); while ( Process32Next ( hSnap, &pe32 ) ) { wsprintf ( pe32.szExeFile + lstrlen ( pe32.szExeFile ), " %d", pe32.th32ProcessID ); hashval = hash ( pe32.szExeFile ); tls(_data)->arr [ hashval ].pid = pe32.th32ProcessID; lstrcpy ( tls(_data)->arr [ hashval ].exe, pe32.szExeFile ); SendMessage ( hListBox, LB_ADDSTRING, 0, (LPARAM)pe32.szExeFile ); } CloseHandle ( hSnap ); return 1;}/***************************************************************************\* берем привелегии отладчика чтоб открывались* csrss.exe winlogon.exe нужны привелегии админа системы\***************************************************************************/int set_priv ( void ) { HANDLE hToken; TOKEN_PRIVILEGES tkp; DWORD dwRet; if ( !OpenProcessToken ( GetCurrentProcess ( ), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken )) return 0; if ( !LookupPrivilegeValue ( NULL, "SeDebugPrivilege", &tkp.Privileges[0].Luid )) return 0; tkp.PrivilegeCount = 1; tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; return AdjustTokenPrivileges ( hToken, FALSE, &tkp, 0, NULL, &dwRet );}/***************************************************************************\* инжектим длл ку в процесс выделяем память под строку к длл ке* стартовый адрес LoadLibrary записываем в память строку к длл ке* и запускаем поток в kernel32.dll:LoadLibrary для загрузки нашей длл ки\***************************************************************************/int inject ( unsigned pid ) { unsigned writes; void * addr, * hproc, * proc, *hremth; hproc = OpenProcess ( PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_WRITE, FALSE, pid ); if ( !hproc ) goto error; addr = VirtualAllocEx ( hproc, NULL, lstrlen ( tls(_data)->path ) + 1, MEM_COMMIT | MEM_TOP_DOWN, PAGE_READWRITE ); if ( !addr ) goto error; if ( !WriteProcessMemory ( hproc, addr, tls(_data)->path, lstrlen ( tls(_data)->path ) + 1, &writes )) goto error; proc = GetProcAddress ( GetModuleHandle ( "Kernel32.dll" ), "LoadLibraryA" ); if ( !proc ) goto error; hremth = CreateRemoteThread ( hproc, NULL, 0, proc, addr, 0, NULL ); if ( !hremth ) goto error; goto success;error: if ( addr ) VirtualFreeEx ( hproc, addr, writes, MEM_DECOMMIT | MEM_RELEASE ); if ( hproc ) CloseHandle ( hproc ); return 0;success: WaitForSingleObject ( hremth, INFINITE ); VirtualFreeEx ( hproc, addr, writes, MEM_DECOMMIT | MEM_RELEASE ); CloseHandle ( hproc ); CloseHandle ( hremth ); return 1;}/***************************************************************************\* обычная диалоговая процедура по двойному клику на процессе инжектит длл ку\***************************************************************************/BOOL CALLBACK ShowPrce ( HWND hwnd, UINT msg, WPARAM wParam ,LPARAM lParam ) { switch ( msg ) { case WM_INITDIALOG: if (!set_priv ( )) MessageBox ( hwnd, "set_priv failed", "", 0 ); select_prce ( GetDlgItem ( hwnd, IDC_LIST1 )); return TRUE; case WM_COMMAND: switch (LOWORD(wParam)) { case IDCANCEL: EndDialog ( hwnd, 0 ); return TRUE; } switch (HIWORD(wParam)) { case LBN_DBLCLK: { int i; char buff [ 1024 ]; i = SendMessage ( GetDlgItem ( hwnd, IDC_LIST1 ), LB_GETCURSEL, 0, 0 ); SendMessage ( GetDlgItem ( hwnd, IDC_LIST1 ), LB_GETTEXT, i, (LPARAM)buff ); if ( !inject ( tls(_data)->arr [ hash ( buff ) ].pid )) MessageBox ( hwnd, "failed", "", 0 ); else MessageBox ( hwnd, "success", "", 0 ); } } } return FALSE;}/***************************************************************************\* при запуске получаем в lpCmdLine путь к длл ке и запускаем диалог\***************************************************************************/int __stdcall entry ( void ) { int i; char * lpCmdLine; struct info * inj; i = 0; lpCmdLine = GetCommandLine ( ); lpCmdLine = StrRChr ( lpCmdLine, lpCmdLine + lstrlen ( lpCmdLine ) - 2, '"' ); if ( (*(lpCmdLine - 2) != '"') && (*(lpCmdLine+2) != '"') ) return 0; _data = TlsAlloc ( ); inj = HeapAlloc ( GetProcessHeap ( ), 0, sizeof ( struct info ) ); TlsSetValue ( _data, inj ); lstrcpy ( tls(_data)->path, lpCmdLine + 1 ); tls(_data)->path [ lstrlen ( tls(_data)->path ) - 1 ] = '#include <stdio.h>#include <string.h>#include <windows.h>#include <tlhelp32.h>#include <shlwapi.h>#include "resource.h"#define HASHSIZE 101volatile unsigned long _data;#define tls(_data) ((struct info*)TlsGetValue ( _data ))struct process_in { char exe [ MAX_PATH ]; unsigned pid;};struct info { char path [ MAX_PATH ]; struct process_in arr [ HASHSIZE ];};unsigned hash ( char * s ) { unsigned hashval; for ( hashval = 0; *s; s++ ) hashval = *s + 31 * hashval; return hashval % HASHSIZE;}/***************************************************************************\* делаем снимок процессов заполняем listbox попутно сохраняем pid'ы\***************************************************************************/int select_prce ( HWND hListBox ) { PROCESSENTRY32 pe32; HANDLE hSnap; unsigned hashval; hSnap = CreateToolhelp32Snapshot ( TH32CS_SNAPPROCESS, 0 ); if ( !hSnap ) return 0; pe32.dwSize = sizeof pe32; Process32First ( hSnap, &pe32 ); while ( Process32Next ( hSnap, &pe32 ) ) { wsprintf ( pe32.szExeFile + lstrlen ( pe32.szExeFile ), " %d", pe32.th32ProcessID ); hashval = hash ( pe32.szExeFile ); tls(_data)->arr [ hashval ].pid = pe32.th32ProcessID; lstrcpy ( tls(_data)->arr [ hashval ].exe, pe32.szExeFile ); SendMessage ( hListBox, LB_ADDSTRING, 0, (LPARAM)pe32.szExeFile ); } CloseHandle ( hSnap ); return 1;}/***************************************************************************\* берем привелегии отладчика чтоб открывались* csrss.exe winlogon.exe нужны привелегии админа системы\***************************************************************************/int set_priv ( void ) { HANDLE hToken; TOKEN_PRIVILEGES tkp; DWORD dwRet; if ( !OpenProcessToken ( GetCurrentProcess ( ), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken )) return 0; if ( !LookupPrivilegeValue ( NULL, "SeDebugPrivilege", &tkp.Privileges[0].Luid )) return 0; tkp.PrivilegeCount = 1; tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; return AdjustTokenPrivileges ( hToken, FALSE, &tkp, 0, NULL, &dwRet );}/***************************************************************************\* инжектим длл ку в процесс выделяем память под строку к длл ке* стартовый адрес LoadLibrary записываем в память строку к длл ке* и запускаем поток в kernel32.dll:LoadLibrary для загрузки нашей длл ки\***************************************************************************/int inject ( unsigned pid ) { unsigned writes; void * addr, * hproc, * proc, *hremth; hproc = OpenProcess ( PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_WRITE, FALSE, pid ); if ( !hproc ) goto error; addr = VirtualAllocEx ( hproc, NULL, lstrlen ( tls(_data)->path ) + 1, MEM_COMMIT | MEM_TOP_DOWN, PAGE_READWRITE ); if ( !addr ) goto error; if ( !WriteProcessMemory ( hproc, addr, tls(_data)->path, lstrlen ( tls(_data)->path ) + 1, &writes )) goto error; proc = GetProcAddress ( GetModuleHandle ( "Kernel32.dll" ), "LoadLibraryA" ); if ( !proc ) goto error; hremth = CreateRemoteThread ( hproc, NULL, 0, proc, addr, 0, NULL ); if ( !hremth ) goto error; goto success;error: if ( addr ) VirtualFreeEx ( hproc, addr, writes, MEM_DECOMMIT | MEM_RELEASE ); if ( hproc ) CloseHandle ( hproc ); return 0;success: WaitForSingleObject ( hremth, INFINITE ); VirtualFreeEx ( hproc, addr, writes, MEM_DECOMMIT | MEM_RELEASE ); CloseHandle ( hproc ); CloseHandle ( hremth ); return 1;}/***************************************************************************\* обычная диалоговая процедура по двойному клику на процессе инжектит длл ку\***************************************************************************/BOOL CALLBACK ShowPrce ( HWND hwnd, UINT msg, WPARAM wParam ,LPARAM lParam ) { switch ( msg ) { case WM_INITDIALOG: if (!set_priv ( )) MessageBox ( hwnd, "set_priv failed", "", 0 ); select_prce ( GetDlgItem ( hwnd, IDC_LIST1 )); return TRUE; case WM_COMMAND: switch (LOWORD(wParam)) { case IDCANCEL: EndDialog ( hwnd, 0 ); return TRUE; } switch (HIWORD(wParam)) { case LBN_DBLCLK: { int i; char buff [ 1024 ]; i = SendMessage ( GetDlgItem ( hwnd, IDC_LIST1 ), LB_GETCURSEL, 0, 0 ); SendMessage ( GetDlgItem ( hwnd, IDC_LIST1 ), LB_GETTEXT, i, (LPARAM)buff ); if ( !inject ( tls(_data)->arr [ hash ( buff ) ].pid )) MessageBox ( hwnd, "failed", "", 0 ); else MessageBox ( hwnd, "success", "", 0 ); } } } return FALSE;}/***************************************************************************\* при запуске получаем в lpCmdLine путь к длл ке и запускаем диалог\***************************************************************************/int __stdcall entry ( void ) { int i; char * lpCmdLine; struct info * inj; i = 0; lpCmdLine = GetCommandLine ( ); lpCmdLine = StrRChr ( lpCmdLine, lpCmdLine + lstrlen ( lpCmdLine ) - 2, '"' ); if ( (*(lpCmdLine - 2) != '"') && (*(lpCmdLine+2) != '"') ) return 0; _data = TlsAlloc ( ); inj = HeapAlloc ( GetProcessHeap ( ), 0, sizeof ( struct info ) ); TlsSetValue ( _data, inj ); lstrcpy ( tls(_data)->path, lpCmdLine + 1 ); tls(_data)->path [ lstrlen ( tls(_data)->path ) - 1 ] = '\0'; DialogBox ( GetModuleHandle ( NULL ), MAKEINTRESOURCE ( IDD_DIALOG1 ), NULL, ShowPrce ); HeapFree ( GetProcessHeap ( ), 0, tls(_data) ); TlsFree ( _data ); return 0;}/***************************************************************************\* несколько слов о добавлении нашего пункта в контекстное меню длл ки* открываем реестр ключ HKEY_CLASSES_ROOT\dllfile\shell\ создаем в нем подключ с именем, которое будет отображаться* в контекстном меню например у меня он называется inject to . . . в нем подключ command в параметре по* умолчанию пишем значение "C:\WINDOWS\system32\inject.exe""%1" тоесть бросаем нашу тузлу в системный* каталог и записываем к ней путь на месте "%1" будет при разворачивании путь к нашей длл ке все пользуемся ))\***************************************************************************/'; DialogBox ( GetModuleHandle ( NULL ), MAKEINTRESOURCE ( IDD_DIALOG1 ), NULL, ShowPrce ); HeapFree ( GetProcessHeap ( ), 0, tls(_data) ); TlsFree ( _data ); return 0;}/***************************************************************************\* несколько слов о добавлении нашего пункта в контекстное меню длл ки* открываем реестр ключ HKEY_CLASSES_ROOT\dllfile\shell\ создаем в нем подключ с именем, которое будет отображаться* в контекстном меню например у меня он называется inject to . . . в нем подключ command в параметре по* умолчанию пишем значение "C:\WINDOWS\system32\inject.exe""%1" тоесть бросаем нашу тузлу в системный* каталог и записываем к ней путь на месте "%1" будет при разворачивании путь к нашей длл ке все пользуемся ))\***************************************************************************/