dll注入与代码注入
学习《逆向工程核心原理》,在x64下dll注入与代码注入。
dll注入主要用到CreateRemoteThread,
代码注入类似,主要用到VirtualAllocEx,WriteProcessMemory,在需注入的进程中开辟空间,写入代码,变量。
1 #include "pch.h"
2 #include <windows.h>
3 #include <tchar.h>
4 #include <tlhelp32.h>
5 #include <stdio.h>
6 #include <shlobj.h>
7 extern void checkAdmin();
8
9 //遍历输出进程pid
10 int TraversalProcess() {
11 HANDLE hProceessnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
12 if (hProceessnap == INVALID_HANDLE_VALUE)
13 {
14 printf_s("创建进行快照失败\n");
15 return -1;
16 }
17 else
18 {
19 PROCESSENTRY32 pe32;
20 pe32.dwSize = sizeof(pe32);
21 BOOL hProcess = Process32First(hProceessnap, &pe32);
22 while (hProcess)
23 {
24 /*WCHAR * ProcessName =(WCHAR *)L"ProcessID.exe";
25 if (!wcscmp(pe32.szExeFile, ProcessName))
26 {*/
27 printf("进程名:%-10ls ----------------进程ID:%6d\n", pe32.szExeFile, pe32.th32ProcessID);
28 /* break;
29 }*/
30 hProcess = Process32Next(hProceessnap, &pe32);
31 }
32 }
33 CloseHandle(hProceessnap);
34 }
35
36 //设置权限
37 BOOL SetPrivilege(LPCTSTR lpszPrivilege, BOOL bEnablePrivilege)
38 {
39 TOKEN_PRIVILEGES tp;
40 HANDLE hToken;
41 LUID luid;
42
43 if (!OpenProcessToken(GetCurrentProcess(),
44 TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
45 &hToken))
46 {
47 _tprintf(L"OpenProcessToken error: %u\n", GetLastError());
48 return FALSE;
49 }
50
51 if (!LookupPrivilegeValue(NULL, // lookup privilege on local system
52 lpszPrivilege, // privilege to lookup
53 &luid)) // receives LUID of privilege
54 {
55 _tprintf(L"LookupPrivilegeValue error: %u\n", GetLastError());
56 return FALSE;
57 }
58
59 tp.PrivilegeCount = 1;
60 tp.Privileges[0].Luid = luid;
61 if (bEnablePrivilege)
62 tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
63 else
64 tp.Privileges[0].Attributes = 0;
65
66 // Enable the privilege or disable all privileges.
67 if (!AdjustTokenPrivileges(hToken,
68 FALSE,
69 &tp,
70 sizeof(TOKEN_PRIVILEGES),
71 (PTOKEN_PRIVILEGES)NULL,
72 (PDWORD)NULL))
73 {
74 _tprintf(L"AdjustTokenPrivileges error: %u\n", GetLastError());
75 return FALSE;
76 }
77
78 if (GetLastError() == ERROR_NOT_ALL_ASSIGNED)
79 {
80 _tprintf(L"The token does not have the specified privilege. \n");
81 return FALSE;
82 }
83
84 return TRUE;
85 }
86
87 //dll注入
88 BOOL InjectDll(DWORD dwPID, LPCTSTR szDllPath)
89 {
90 HANDLE hProcess = NULL, hThread = NULL;
91 HMODULE hMod = NULL;
92 LPVOID pRemoteBuf = NULL;
93 DWORD dwBufSize = (DWORD)(_tcslen(szDllPath) + 1) * sizeof(TCHAR);
94 LPTHREAD_START_ROUTINE pThreadProc;
95
96 // #1. 使用dwPID请求对象进程(notepad.exe)的HANDLE。
97 if (!(hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID)))
98 {
99 _tprintf(L"OpenProcess(%d) failed!!! [%d]\n", dwPID, GetLastError());
100 return FALSE;
101 }
102
103 // #2. 在目标进程(notepad.exe)内存中分配与szDllName大小相同的内存。
104 pRemoteBuf = VirtualAllocEx(hProcess, NULL, dwBufSize, MEM_COMMIT, PAGE_READWRITE);
105
106 // #3. 在分配的内存中使用dll路径
107 WriteProcessMemory(hProcess, pRemoteBuf, (LPVOID)szDllPath, dwBufSize, NULL);
108
109 // #4. 请求到LoadLibraryA() API地址。
110 hMod = GetModuleHandle(L"kernel32.dll");
111 pThreadProc = (LPTHREAD_START_ROUTINE)GetProcAddress(hMod, "LoadLibraryW");
112
113 // #5. 在notepad.exe进程中运行线程
114 hThread = CreateRemoteThread(hProcess, NULL, 0, pThreadProc, pRemoteBuf, 0, NULL);
115 //通过CreateRemoteThread,调用pThreadProc,即LoadLibraryW,参数为在需注入进程中开辟的内存(存储了dll路径)
116
117 WaitForSingleObject(hThread, INFINITE);
118
119 CloseHandle(hThread);
120 CloseHandle(hProcess);
121
122 return TRUE;
123 }
124 //卸载dll
125 BOOL EjectDll(DWORD dwPID, LPCTSTR szDllName)
126 {
127 BOOL bMore = FALSE, bFound = FALSE;
128 HANDLE hSnapshot, hProcess, hThread;
129 HMODULE hModule = NULL;
130 MODULEENTRY32 me = { sizeof(me) };
131 LPTHREAD_START_ROUTINE pThreadProc;
132 // dwPID = notepad 进程 ID
133 // 使用TH32CS_SNAPMODULE参数获得载入notepad程序的DLL名称
134 hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwPID);
135
136 bMore = Module32First(hSnapshot, &me);
137 for (; bMore; bMore = Module32Next(hSnapshot, &me))
138 {
139 if (!_tcsicmp((LPCTSTR)me.szModule, szDllName) ||
140 !_tcsicmp((LPCTSTR)me.szExePath, szDllName))
141 {
142 bFound = TRUE;
143 break;
144 }
145 }
146
147 if (!bFound)
148 {
149 CloseHandle(hSnapshot);
150 return FALSE;
151 }
152
153 if (!(hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID)))
154 {
155 _tprintf(L"OpenProcess(%d) failed!!! [%d]\n", dwPID, GetLastError());
156 return FALSE;
157 }
158
159 hModule = GetModuleHandle(L"kernel32.dll");
160 pThreadProc = (LPTHREAD_START_ROUTINE)GetProcAddress(hModule, "FreeLibrary");
161 hThread = CreateRemoteThread(hProcess, NULL, 0,
162 pThreadProc, me.modBaseAddr,
163 0, NULL);
164 WaitForSingleObject(hThread, INFINITE);
165
166 CloseHandle(hThread);
167 CloseHandle(hProcess);
168 CloseHandle(hSnapshot);
169
170 return TRUE;
171 }
172
173
174 //代码注入所需结构体
175 typedef struct _THREAD_PARAM
176 {
177 FARPROC pFunc[2]; // LoadLibraryA(), GetProcAddress()
178 char szBuf[4][128]; // "user32.dll", "MessageBoxA", "www.reversecore.com", "ReverseCore"
179 } THREAD_PARAM, *PTHREAD_PARAM;
180
181 typedef HMODULE(WINAPI *PFLOADLIBRARYA)
182 (
183 LPCSTR lpLibFileName
184 );
185
186 typedef FARPROC(WINAPI *PFGETPROCADDRESS)
187 (
188 HMODULE hModule,
189 LPCSTR lpProcName
190 );
191
192 typedef int (WINAPI *PFMESSAGEBOXA)
193 (
194 HWND hWnd,
195 LPCSTR lpText,
196 LPCSTR lpCaption,
197 UINT uType
198 );
199
200 //需注入的代码
201 DWORD WINAPI ThreadProc(LPVOID lParam)
202 {
203 PTHREAD_PARAM pParam = (PTHREAD_PARAM)lParam;
204 HMODULE hMod = NULL;
205 FARPROC pFunc = NULL;
206 //调用 LoadLibrary() 加载 "user32.dll"
207 hMod = ((PFLOADLIBRARYA)pParam->pFunc[0])(pParam->szBuf[0]); // "user32.dll"
208 if (!hMod)
209 return 1;
210
211 //调用 GetProcAddress() 获取"MessageBoxA"
212 pFunc = (FARPROC)((PFGETPROCADDRESS)pParam->pFunc[1])(hMod, pParam->szBuf[1]); // "MessageBoxA"
213 if (!pFunc)
214 return 1;
215
216 // 调用MessageBoxA()
217 ((PFMESSAGEBOXA)pFunc)(NULL, pParam->szBuf[2], pParam->szBuf[3], MB_OK);
218 return 0;
219 }
220
221 //实现代码注入
222 BOOL InjectCode(DWORD dwPID)
223 {
224 HMODULE hMod = NULL;
225 THREAD_PARAM param = { 0, };
226 HANDLE hProcess = NULL;
227 HANDLE hThread = NULL;
228 LPVOID pRemoteBuf[2] = { 0, };
229 DWORD dwSize = 0;
230
231 hMod = GetModuleHandleA("kernel32.dll");
232
233 // set THREAD_PARAM
234 param.pFunc[0] = GetProcAddress(hMod, "LoadLibraryA");
235 param.pFunc[1] = GetProcAddress(hMod, "GetProcAddress");
236 strcpy_s(param.szBuf[0], "user32.dll");
237 strcpy_s(param.szBuf[1], "MessageBoxA");
238 strcpy_s(param.szBuf[2], "这是code inject");
239 strcpy_s(param.szBuf[3], "好开心!");
240
241 // Open Process
242 if (!(hProcess = OpenProcess(PROCESS_ALL_ACCESS, // dwDesiredAccess
243 FALSE, // bInheritHandle
244 dwPID))) // dwProcessId
245 {
246 printf("OpenProcess() fail : err_code = %d\n", GetLastError());
247 return FALSE;
248 }
249
250 // Allocation for THREAD_PARAM 写入代码注入所需的data
251 dwSize = sizeof(THREAD_PARAM);
252 if (!(pRemoteBuf[0] = VirtualAllocEx(hProcess, // hProcess
253 NULL, // lpAddress
254 dwSize, // dwSize
255 MEM_COMMIT, // flAllocationType
256 PAGE_READWRITE))) // flProtect
257 {
258 printf("VirtualAllocEx() fail : err_code = %d\n", GetLastError());
259 return FALSE;
260 }
261 SIZE_T sz = 0;
262 if (!WriteProcessMemory(hProcess, // hProcess
263 pRemoteBuf[0], // lpBaseAddress
264 (LPVOID)¶m, // lpBuffer
265 dwSize, // nSize
266 &sz)) // [out] lpNumberOfBytesWritten
267 {
268 printf("写入大小:%d\n", sz);
269 printf("THREAD_PARAM WriteProcessMemory() fail : err_code = %d\n", GetLastError());
270 return FALSE;
271 }
272
273 // Allocation for ThreadProc() 写入代码
274 dwSize = abs((int)((DWORD)InjectCode - (DWORD)ThreadProc));
275
276 printf("dwSize:%d\n", dwSize);
277 //dwSize = 1024;
278 if (!(pRemoteBuf[1] = VirtualAllocEx(hProcess, // hProcess
279 NULL, // lpAddress
280 dwSize, // dwSize
281 MEM_COMMIT, // flAllocationType
282 PAGE_EXECUTE_READWRITE))) // flProtect
283 {
284 printf("VirtualAllocEx() fail : err_code = %d\n", GetLastError());
285 return FALSE;
286 }
287 sz = 0;
288 if (!WriteProcessMemory(hProcess, // hProcess
289 pRemoteBuf[1], // lpBaseAddress
290 (LPVOID)ThreadProc, // lpBuffer
291 dwSize, // nSize
292 &sz)) // [out] lpNumberOfBytesWritten
293 {
294 printf("写入大小:%d\n", sz);
295 printf("ThreadProc() WriteProcessMemory() fail : err_code = %d\n", GetLastError());
296 return FALSE;
297 }
298 printf("ThreadProc()写入大小:%d\n", sz);
299 if (!(hThread = CreateRemoteThread(hProcess, // hProcess
300 NULL, // lpThreadAttributes
301 0, // dwStackSize
302 (LPTHREAD_START_ROUTINE)pRemoteBuf[1], // dwStackSize
303 pRemoteBuf[0], // lpParameter
304 0, // dwCreationFlags
305 NULL))) // lpThreadId
306 {
307 printf("CreateRemoteThread() fail : err_code = %d\n", GetLastError());
308 return FALSE;
309 }
310
311 WaitForSingleObject(hThread, INFINITE);
312 CloseHandle(hThread);
313 CloseHandle(hProcess);
314 printf("code inject end\n");
315 return TRUE;
316 }
317
318
319 int _tmain(int argc, TCHAR *argv[])
320 {
321 /*if (argc != 3)
322 {
323 _tprintf(L"USAGE : %s <pid> <dll_path>\n", argv[0]);
324 return 1;
325 }*/
326 // change privilege
327 // 判断当前进程是否以管理员身份运行
328 checkAdmin();
329 /*if (!SetPrivilege(SE_DEBUG_NAME, TRUE))
330 return 1;*/
331 //TraversalProcess();
332 TCHAR pid[10];
333 TCHAR path[MAX_PATH];
334 system("tasklist");
335 printf("ok\n");
336 printf("输入要注入的进程pid:\n");
337 scanf_s("%ls", pid, 10);
338 printf("请选择功能:1.dll注入 2.代码注入\n");
339 int flag = 0;
340 scanf_s("%d", &flag, 1);
341 if (flag == 1) {
342 printf("输入要注入的dll路径:");
343 scanf_s("%ls", path,MAX_PATH);
344 // inject dll
345 if (InjectDll((DWORD)_tstol(pid), path))
346 _tprintf(L"InjectDll(\"%s\") success!!!\n", path);
347 else
348 _tprintf(L"InjectDll(\"%s\") failed!!!\n", path);
349 printf("输入q 卸载dll\n");
350 while (getchar() != 'q');
351 TCHAR *p = _tcsrchr(path, '\\');
352 if(EjectDll((DWORD)_tstol(pid), p+1))
353 printf("卸载dll成功!\n");
354 else
355 {
356 printf("卸载失败!\n");
357 }
358
359 system("pause");
360 return 0;
361 }
362 else if (flag == 2)
363 {
364 InjectCode((DWORD)_tstol(pid));
365 system("pause");
366 return 0;
367 }
368 else
369 {
370 system("pause");
371 return 0;
372 }
373 }
判断当前运行时的权限,以管理员身份运行。
1 BOOL IsAdmin(HANDLE hProcess)
2 {
3 HANDLE hToken = NULL;
4 OpenProcessToken(hProcess, TOKEN_QUERY, &hToken);
5
6 TOKEN_ELEVATION_TYPE tokenType = TokenElevationTypeDefault; // 用于接收令牌类型
7
8 DWORD dwRetSize = 0; // 用于接收函数输出信息的字节数
9
10 // 2. 查询进程令牌中的权限提升值.( 这个值会记录当前的令牌是何种类型( 细节在17_权限管理_令牌的获取.cpp ) )
11 GetTokenInformation(hToken,
12 TokenElevationType,// 获取令牌的当前提升等级
13 &tokenType,
14 sizeof(tokenType),
15 &dwRetSize // 所需缓冲区的字节数
16 );
17
18
19 // 根据令牌的类型来输出相应的信息
20 if (TokenElevationTypeFull == tokenType) {
21 // 3. 如果令牌是TokenElevationTypeFull , 则拥有至高无上的能力,可以给令牌添加任何特权
22 printf("管理员账户,并拥有全部的权限,可以给令牌添加任何特权\n");
23 return TRUE;
24 }
25 // 4. 如果是其他的, 则需要以管理员身份重新运行本进程. 这样就能以第三步的方法解决剩下的问题.
26 else if (TokenElevationTypeDefault == tokenType) {
27 printf("默认用户, 可能是一个普通用户, 可能是关闭UAC时登录的管理员用户\n");
28
29 // 调用系统函数IsUserAnAdmin, 进一步确定是普通用户还是管理员用户
30 return IsUserAnAdmin();
31 }
32 else if (TokenElevationTypeLimited == tokenType) {
33
34 // 判断受限制的用户是管理员
35 // 如果是管理员, 则这个令牌中会保存有管理员的SID
36
37 // 1. 获取系统内键管理员用户的SID
38 SID adminSid;
39 DWORD dwSize = sizeof(adminSid);
40 CreateWellKnownSid(WinBuiltinAdministratorsSid, // 获取SID的类型,这里是系统内键管理员
41 NULL, // 传NULL,获取本地计算机的管理员
42 &adminSid,// 函数输出的管理员SID
43 &dwSize // 输入结构的大小,也作为输出
44 );
45
46 // 获取本令牌的连接令牌(受限制的令牌都会有一个连接的令牌,受限制的令牌正式由主令牌所创建的. )
47 TOKEN_LINKED_TOKEN linkToken;
48 GetTokenInformation(hToken,
49 TokenLinkedToken, // 获取连接的令牌句柄
50 &linkToken,
51 sizeof(linkToken),
52 &dwSize
53 );
54
55 // 在连接的令牌中查找是否具有管理员的SID
56 BOOL bIsContain = FALSE; // 用于保存是否包含.
57 CheckTokenMembership(linkToken.LinkedToken, // 在这个令牌中检查
58 &adminSid, // 检查令牌中是否包含此SID
59 &bIsContain); // 输出TRUE则包含,反之不包含
60
61
62
63 if (bIsContain) {
64 printf("权限被阉割的受限制管理员账户, 部分权限被移处理\n");
65 }
66
67
68 return bIsContain; // 不是以管理员权限运行
69 }
70
71 return FALSE;
72 }
73
74 void checkAdmin() {
75 if (!IsAdmin(GetCurrentProcess())) {
76
77 // 以管理员身份运行本进程
78 // 1 获取本进程的文件路径.
79 TCHAR path[MAX_PATH] = { 0 }; // 需要初始化
80 DWORD dwPathSize = MAX_PATH;
81 QueryFullProcessImageName(GetCurrentProcess(), 0,
82 path,
83 &dwPathSize);
84
85 // 2 调用创建进程的API运行本进程.
86 ShellExecute(NULL, // 窗口句柄,没有则填NULL
87 _T("runas"), // 以管理员身份运行的重要参数
88 path, // 所有运行的程序的路径(这里是本进程)
89 NULL, // 命令行参数
90 NULL, // 新进程的工作目录的路径
91 SW_SHOW // 创建后的显示标志(最小化,最大化, 显示,隐藏等)
92 );
93
94 // 退出本进程
95 ExitProcess(0);
96 }
97 }
dll注入与代码注入的更多相关文章
- 代码注入——c++代码注入
代码注入之——c++代码注入 0x00 代码注入和DLL注入的区别 DLL注入后DLL会通过线程常驻在某个process中,而代码注入完成之后立即消失. 代码注入体积小,不占内存 0x01 通过c ...
- 注入攻击-SQL注入和代码注入
注入攻击 OWASP将注入攻击和跨站脚本攻击(XSS)列入网络应用程序十大常见安全风险.实际上,它们会一起出现,因为 XSS 攻击依赖于注入攻击的成功.虽然这是最明显的组合关系,但是注入攻击带来的不仅 ...
- C++代码注入
一.C++代码注入原则: 在注入代码中不允许使用API. 在注入代码中不允许使用全局变量. 在注入代码中不允许使用字符串(编译时也被当做全局变量). 在注入代码中不允许使用函数嵌套. 二.注入代码编写 ...
- 通过注入DLL修改API代码实现钩取(一)
通过注入DLL修改API代码实现钩取(一) Ox00 大致思路 通过CreateRemoteThread函数开辟新线程,并将DLL注入进去 通过GetProcessAddress函数找到需钩取的API ...
- 转:EasyHook远程代码注入
EasyHook远程代码注入 最近一段时间由于使用MinHook的API挂钩不稳定,经常因为挂钩地址错误而导致宿主进程崩溃.听同事介绍了一款智能强大的挂钩引擎EasyHook.它比微软的detours ...
- 32位汇编第三讲,RadAsm,IDE的配置和使用,以及汇编代码注入方式
32位汇编第三讲,RadAsm,IDE的配置和使用,以及汇编代码注入方式 一丶RadAsm的配置和使用 用了怎么长时间的命令行方式,我们发现了几个问题 1.没有代码提醒功能 2.编写代码很慢,记不住各 ...
- 安全之路 —— 借助DLL进行远程线程注入实现穿墙与隐藏进程
简介 大多数后门或病毒要想初步实现隐藏进程,即不被像任务管理器这样典型的RING3级进程管理器找到过于明显的不明进程,其中比较著名的方法就是通过远程线程注入的方法注入将恶意进程的DLL文 ...
- 详解C#泛型(二) 获取C#中方法的执行时间及其代码注入 详解C#泛型(一) 详解C#委托和事件(二) 详解C#特性和反射(四) 记一次.net core调用SOAP接口遇到的问题 C# WebRequest.Create 锚点“#”字符问题 根据内容来产生一个二维码
详解C#泛型(二) 一.自定义泛型方法(Generic Method),将类型参数用作参数列表或返回值的类型: void MyFunc<T>() //声明具有一个类型参数的泛型方法 { ...
- Windows下的代码注入
木马和病毒的好坏很大程度上取决于它的隐蔽性,木马和病毒本质上也是在执行程序代码,如果采用独立进程的方式需要考虑隐藏进程否则很容易被发现,在编写这类程序的时候可以考虑将代码注入到其他进程中,借用其他进程 ...
随机推荐
- mitmproxy 代理工具介绍:rewrite和map local实现
在接口测试中,会用到抓包工具或者代理工具,常用代理工具包括charles. burpsuite. fiddler.mitmproxy等,ssh -D参数 可实现socks5代理.网络嗅探工具可以使用t ...
- Next.js SSR Tutorials
Next.js SSR Tutorials https://codesandbox.io/s/nextjs-demo-h49zt cli $ npx create-next-app ssr-demo- ...
- vue & this.$copyText
vue & this.$copyText click copy https://www.npmjs.com/package/vue-clipboard2 <p>{{message2 ...
- 1GB === 1000MB & 1GB === 1024MB
1GB === 1000MB & 1GB === 1024MB 字节单位换算 1 Gigabyte = 1000 Megabytes 1 Gibibyte = 1024 Mebibytes 十 ...
- TypeORM Entity
TypeORM Entity Entity Entity is a class that maps to a database table when using SQL database(or col ...
- App Store Connect
App Store Connect https://developer.apple.com/support/app-store-connect/ https://developer.apple.com ...
- css & auto height & overflow: hidden;
css & auto height & overflow: hidden; {overflow: hidden; height: 100%;} is the panacea! {溢出: ...
- Taro 开发踩坑指南 (小程序,H5, RN)
Taro 开发踩坑指南 (小程序,H5, RN) css taro 如何展示多行文本省略号 https://www.cnblogs.com/xgqfrms/p/12569057.html UI 设计稿 ...
- Captain Technology INC浅谈新能源汽车的未来
近日全世界上最大的资管公司贝莱德向位于的英国电动汽车初创公司Arrival投资1.18亿美元,且该公司已有投资者亚马逊和美国第二大汽车制造商福特汽车参投.中国最知名的电动车公司蔚来股价单日大涨22%, ...
- mybites框架遇到的坑之Mapper.xml文件不要随意加注释和ORA-00911
原文链接:https://blog.csdn.net/streetlight8023/article/details/69388495/ 先说解决方法: org.mybatis.spring.MyBa ...