DLL注入技术之远线程注入
来源:互联网 发布:南昌大学怎么样知乎 编辑:程序博客网 时间:2024/05/21 17:10
DLL注入技术之远线程注入
DLL注入技术指的是将一个DLL文件强行加载到EXE文件中,并成为EXE文件中的一部分,这样做的目的在于方便我们通过这个DLL读写EXE文件内存数据,(例如 HOOK EXE文件中的API),或以被注入EXE的身份去执行一些操作等等。
远线程注入原理是利用Windows 系统中CreateRemoteThread()这个API,其中第4个参数是准备运行的线程,我们可以将LoadLibrary()填入其中,这样就可以执行远程进程中的LoadLibrary()函数,进而将我们自己准备的DLL加载到远程进程空间中执行。
当然除了CreateRemoteThread()和LoadLibrary()这个两个主要的API还是远远不够的,我们还需要以下表格所示的API:OpenProcess打开远程进程VirtualAllocEx在远程进程中申请空间WriteProcessMemory在远程进程中写入数据WaitForSingleObject等待信号量VirtualFreeEx释放远程进程中申请空间CloseHandle关闭句柄
主要代码如下:
int CRemoteThreadInjectDLL::InjectDll(DWORD dwProcessId, PTCHAR szDllName){ if (szDllName[0] == NULL) return -1; //提高权限相关操作 EnablePrivilege(TRUE); //1. 打开进程 HANDLE hProcess = ::OpenProcess( PROCESS_ALL_ACCESS, //打开进程权限 FALSE, //是否可继承 dwProcessId); //进程ID if (hProcess == INVALID_HANDLE_VALUE) return -1; //2. 在远程进程中申请空间 LPVOID pszDllName = ::VirtualAllocEx(hProcess, //远程进程句柄 NULL, //建议开始地址 4096, //分配空间大小 MEM_COMMIT, //空间初始化全0 PAGE_EXECUTE_READWRITE); //空间权限 if (NULL == pszDllName) { return -1; } //3. 向远程进程中写入数据 BOOL bRet = ::WriteProcessMemory( hProcess, pszDllName, szDllName, MAX_PATH, NULL); if (NULL == bRet) { return -1; } //4. 在远程进程中创建远程线程 m_hInjecthread = ::CreateRemoteThread(hProcess, //远程进程句柄 NULL, //安全属性 0, //栈大小 (LPTHREAD_START_ROUTINE)LoadLibrary, //进程处理函数 pszDllName, //传入参数 NULL, //默认创建后的状态 NULL); //线程ID if (NULL == m_hInjecthread) { DWORD dwErr = GetLastError(); return -1; } //5. 等待线程结束返回 DWORD dw = WaitForSingleObject(m_hInjecthread, -1); //6. 获取线程退出码,即LoadLibrary的返回值,即dll的首地址 DWORD dwExitCode; GetExitCodeThread(m_hInjecthread, &dwExitCode); m_hMod = (HMODULE)dwExitCode; //7. 释放空间 BOOL bReturn = VirtualFreeEx(hProcess, pszDllName, 4096, MEM_DECOMMIT); if (NULL == bReturn) { return -1; } CloseHandle(hProcess); hProcess = NULL; //恢复权限相关操作 EnablePrivilege(FALSE); return 0;}
此外,我们还需要提升进程权限以便于提高注入成功率,所需API如下表所示:
OpenProcessToken得到令牌句柄LookupPrivilegeValue得到权限值AdjustTokenPrivileges提升令牌句柄权限
int CRemoteThreadInjectDLL::EnablePrivilege(bool isStart){ //1. 得到令牌句柄 HANDLE hToken = NULL; //令牌句柄 if (!OpenProcessToken( GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY | TOKEN_READ, &hToken)) { return FALSE; } //2. 得到特权值 LUID luid = {0}; //特权值 if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid)) { return FALSE; } //3. 提升令牌句柄权限 TOKEN_PRIVILEGES tp = {0}; //令牌新权限 tp.PrivilegeCount = 1; tp.Privileges[0].Luid = luid; tp.Privileges[0].Attributes = isStart ? SE_PRIVILEGE_ENABLED : 0; if (!AdjustTokenPrivileges(hToken, FALSE, &tp, 0, NULL, NULL)) { return FALSE; } //4. 关闭令牌句柄 CloseHandle(hToken); return 0;}
当要在指定的进程中加载DLL时,我们就需要过滤指定名称的进程,这时遍历进程ID并进行对比,得到所指定的进程,所需API如表所示:CreateToolhelp32Snapshot 创建进程快照 Process32First 第一个进程快照Process32Next 循环下一个进程快照
DWORD CRemoteThreadInjectDLL::GetProcessId(PTCHAR pszProcessName){ HANDLE hProcess = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if (INVALID_HANDLE_VALUE == hProcess) { return 0; } DWORD dwProcessId = 0; PROCESSENTRY32 process32 = {0}; process32.dwSize = sizeof(PROCESSENTRY32); BOOL bRetProcess = FALSE; bRetProcess = ::Process32First(hProcess, &process32); do { if (_tcscmp(pszProcessName, process32.szExeFile) == 0) { dwProcessId = process32.th32ProcessID; break; } bRetProcess = ::Process32Next(hProcess, &process32); }while (bRetProcess); ::CloseHandle(hProcess); return dwProcessId;}
远线程注入API使用较多,不易实现。但是可以批量注入和卸载,这样对于需要反复调试的注入就非常的方便。
0 0
- DLL注入技术之远线程注入
- DLL注入技术之远线程注入
- DLL注入技术之远线程注入
- Dll注入技术之远程线程注入
- Dll注入技术之远程线程注入
- Dll注入技术之远程线程注入
- Dll注入技术之远程线程注入
- 远线程DLL注入技术
- 远程线程注入技术(1)之DLL的注入
- Dll注入-远线程注入
- 远线程DLL注入
- DLL注入之远程线程注入
- DLL注入技术之APC注入
- DLL注入技术之REG注入
- DLL注入技术之消息钩子注入
- DLL注入技术之ComRes注入
- Dll注入技术之注册表注入
- Dll注入技术之ComRes注入
- 【Android自助餐】Handler消息机制完全解析(三)Handler解析
- DLL注入技术之依赖可信进程注入
- [Ceph003]Ceph集群创建Cephfs文件
- 使用Iterator接口输出集合
- tomcat源码解析(五)--两种配置与异步servlet
- DLL注入技术之远线程注入
- 【Android自助餐】Handler消息机制完全解析(四)Looper解析
- Hdu 5344 MZL's xor (杂)
- 浅谈android网络编程
- java8之lambda总结
- Service解析
- DLL注入技术之消息钩子注入
- 读懂心经
- 【Android自助餐】Handler消息机制完全解析(五)鸟瞰与总结