#include <stdio.h>
02 | #include <tchar.h> |
03 | #include <windows.h> |
04 | #include <atlbase.h> |
05 |
06 | BOOL EnableDebugPriv( LPCTSTR name) |
07 | { |
08 | HANDLE h; |
09 | TOKEN_PRIVILEGES tp; |
10 | LUID id; |
11 |
12 | // 打开进程令牌环 |
13 | if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &h)) |
14 | return FALSE; |
15 |
16 | // 获得进程本地唯一ID |
17 | if (!LookupPrivilegeValue(NULL, name, &id)) |
18 | return FALSE; |
19 |
20 | tp.PrivilegeCount = 1; |
21 | tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; |
22 | tp.Privileges[0].Luid = id; |
23 |
24 | // 调整权限 |
25 | if (!AdjustTokenPrivileges(h, 0, &tp, sizeof (TOKEN_PRIVILEGES), NULL, NULL)) |
26 | return FALSE; |
27 |
28 | return TRUE; |
29 | } |
30 |
31 | BOOL InjectDll( LPCTSTR dll_full_path, DWORD remote_process_id) |
32 | { |
33 | HANDLE h; |
34 |
35 | if (!EnableDebugPriv(SE_DEBUG_NAME)) |
36 | return FALSE; |
37 |
38 | // 打开远程线程. |
39 | h = OpenProcess(PROCESS_ALL_ACCESS, FALSE, remote_process_id); |
40 | if (!h) |
41 | return FALSE; |
42 |
43 | DWORD size = _tcsclen(dll_full_path) + 1; |
44 |
45 | // 使用VirtualAllocEx函数在远程进程的内存地址空间分配DLL文件名空间 |
46 | LPVOID r = VirtualAllocEx(h, NULL, size, MEM_COMMIT, PAGE_READWRITE); |
47 | if (!r) |
48 | return FALSE; |
49 |
50 | // 使用WriteProcessMemory函数将DLL的路径名写入到远程进程的内存空间 |
51 | if (!WriteProcessMemory(h, r, ( void *)dll_full_path, size, NULL)) |
52 | return FALSE; |
53 |
54 | // 计算LoadLibraryA的入口地址 |
55 | PTHREAD_START_ROUTINE start = |
56 | (PTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(TEXT( "Kernel32" )), "LoadLibraryA" ); |
57 | if (!start) |
58 | return FALSE; |
59 |
60 | // (关于GetModuleHandle函数和GetProcAddress函数) |
61 | // 启动远程线程LoadLibraryA,通过远程线程调用创建新的线程. |
62 | DWORD tid; |
63 | HANDLE t = CreateRemoteThread(h, NULL, 0, start, r, 0, &tid); |
64 | if (!t) |
65 | return FALSE; |
66 |
67 | WaitForSingleObject(t, INFINITE); |
68 |
69 | // 释放资源和句柄 |
70 | VirtualFreeEx(h, r, size, MEM_DECOMMIT); |
71 | CloseHandle(t); |
72 | CloseHandle(h); |
73 |
74 | return TRUE; |
75 | } |
76 |
77 | int main( int argc, char **argv) |
78 | { |
79 | if (argc < 3) |
80 | { |
81 | printf ( "usage: InjectDll.exe <dll_path> <process_id>\n" ); |
82 | return -1; |
83 | } |
84 |
85 | TCHAR dll[MAX_PATH]; |
86 | int id = atoi (argv[2]); |
87 |
88 | USES_CONVERSION; |
89 | _tcscpy(dll, A2T(argv[1])); |
90 |
91 | if (!InjectDll(dll, id)) |
92 | { |
93 | printf ( "inject dll failed!\n" ); |
94 | return -1; |
95 | } |
96 |
97 | return 0; |
98 | } |