1 #include<stdio.h>
2 #include<Windows.h>
3 #include<TlHelp32.h>
4
5
6 //typedef unsigned long DWORD;
7 //typedef __nullterminated CONST CHAR *LPCSTR, *PCSTR;
8 //typedef void *HANDLE;
9
10 DWORD getProcessHandle(LPCTSTR lpProcessName)//根据进程名查找进程PID
11 {
12 DWORD dwRet=0;
13 HANDLE hSnapShot=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);/*CreateToolhelp32Snapshot函数为指定的进程、
14 进程使用的堆[HEAP]、模块[MODULE]、
15 线程[THREAD])建立一个快照[snapshot]。*/
16 if(hSnapShot==INVALID_HANDLE_VALUE)
17 {
18 //句柄无效
19 printf("\n获得PID=%s的进程快照失败%d",lpProcessName,GetLastError());
20 return dwRet;
21 }
22
23 //快照抓取成功
24 PROCESSENTRY32 pe32;//声明进程入口对象
25 pe32.dwSize=sizeof(PROCESSENTRY32 );//填充进程入口大小
26 Process32First(hSnapShot,&pe32);//遍历进程列表
27 do
28 {
29 if(!lstrcmp(pe32.szExeFile,lpProcessName))
30 {
31 dwRet=pe32.th32ProcessID;
32 break;
33 }
34 }
35 while(Process32Next(hSnapShot,&pe32));
36 CloseHandle(hSnapShot);
37 return dwRet;
38
39 }
40
41
42 void EnableDebugPriv()
43 {
44 HANDLE hToken; // 进程访问令牌的句柄
45 LUID luid; // 用于存储调试权对应的局local unique identifier
46 TOKEN_PRIVILEGES tkp; // 要设置的权限
47 OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken);
48 // 获取访问令牌
49 LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid); // 获得调试权的luid
50 tkp.PrivilegeCount = 1; // 设置调试权
51 tkp.Privileges[0].Luid = luid;
52 tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
53 AdjustTokenPrivileges(hToken, FALSE, &tkp, sizeof tkp, NULL, NULL); // 使进程拥有调试权
54 CloseHandle(hToken);
55 }
56
57 int main(int argc,char *argv[])
58 {
59 DWORD dwpid=getProcessHandle("calc.exe");
60 LPCSTR lpDllName="D:\\WorkProject\\C++\\20160314\\DLLImport\\Debug\\dllDemo.dll";
61 EnableDebugPriv();//权限提升
62 HANDLE hProcess=OpenProcess(PROCESS_VM_OPERATION|PROCESS_VM_WRITE,FALSE,dwpid);//获得要注入进程的句柄
63
64 if(hProcess==NULL)
65 {
66 printf("\n获取进程句柄错误%d",GetLastError());
67 return -1;
68 }
69
70 DWORD dwSize=strlen(lpDllName)+1;
71 DWORD dwHasWrite;
72 LPVOID lpRemoteBuf=VirtualAllocEx(hProcess,NULL,dwSize,MEM_COMMIT,PAGE_READWRITE);//在远程空间分配地址
73 if(WriteProcessMemory(hProcess,lpRemoteBuf,lpDllName,dwSize,&dwHasWrite))//写入内存函数执行成功返回非零
74 {
75 if(dwHasWrite!=dwSize)
76 {
77 //写入内存不完整,释放内存
78 VirtualFreeEx(hProcess,lpRemoteBuf,dwSize,MEM_COMMIT);
79 CloseHandle(hProcess);
80 return -1;
81 }
82 }
83 else
84 {
85 printf("\n写入远程进程内存空间出错%d",GetLastError());
86 CloseHandle(hProcess);
87 return -1;
88 }
89 //写入成功
90 DWORD dwNewThreadId;
91 LPVOID lpLoadDll=LoadLibraryA;
92 //将LoadLIbraryA作为线程函数,参数为Dll,创建新线程
93 HANDLE hNewRemoteThread=CreateRemoteThread(hProcess,NULL,0,(LPTHREAD_START_ROUTINE)lpLoadDll,lpRemoteBuf,0,&dwNewThreadId);
94 //HANDLE hNewRemoteThread=
95 if(hNewRemoteThread==NULL)
96 {
97 printf("\n建立远程线程失败%d",GetLastError());
98 CloseHandle(hProcess);
99 return -1;
100 }
101 //等待对象句柄返回
102 WaitForSingleObject(hNewRemoteThread,INFINITE);
103
104 CloseHandle(hNewRemoteThread);
105
106
107 //准备卸载之前注入的Dll
108 DWORD dwHandle,dwID;
109 LPVOID pFunc = GetModuleHandleA;//获得在远程线程中被注入的Dll的句柄
110 HANDLE hThread = CreateRemoteThread(hProcess,NULL,0,(LPTHREAD_START_ROUTINE)pFunc,lpRemoteBuf,0,&dwID);
111 WaitForSingleObject(hThread,INFINITE);
112 GetExitCodeThread(hThread,&dwHandle);//线程的结束码即为Dll模块儿的句柄
113 CloseHandle(hThread);
114 pFunc = FreeLibrary;
115 hThread = CreateRemoteThread(hThread,NULL,0,(LPTHREAD_START_ROUTINE)pFunc,(LPVOID)dwHandle,0,&dwID); //将FreeLibraryA注入到远程线程中去卸载Dll
116 WaitForSingleObject(hThread,INFINITE);
117 CloseHandle(hThread);
118 CloseHandle(hProcess);
119 return 0;
120 }