Windows编程之《远线程注入技术》
近年来,全球大规模爆发勒索病毒和挖矿病毒,让沉寂许久的黑客技术,又重新回到了人们的视野中。Windows操作系统市场占有率高达90%以上,所以面对勒索病毒、挖矿病毒,Windows用户首当其冲。 为了揭开病毒木马的神秘面纱,更好地服务于信息安全,本书总结并剖析了常见的Windows黑客编程技术,用通俗易懂的语言介绍了用户层下的Windows编程和内核层下的Rootkit编程。
【远线程注入技术】概念
远线程注入技术指是:一个进程在另一个进程中创建线程的技术,是一种病毒木马程序所青睐的注入技术。
常用函数
1、OpenProcess函数(打开现有的本地进程对象)
HANDLE OpenProcess(
DWORD dwDesiredAccess, // 访问进程对象
BOOL bInheritHandle, // 进程创建的进程将继承这个句柄:TRUE
DWORD dwProcessId // 打开的本地进程的PID
);
2、VirutalAlloc函数(指定进程的虚拟地址空间内保留、提交或更改内存的状态)
LPVOID VirtualAlloc(
LPVOID lpAddress, // 过程的句柄
SIZE_T dwSize, // 指定要分配页面所需要起始地址的指针
DWORD flAllocationType, // 内存分配类型
DWORD flProtect // 要分配的页面区域内存保护
);
3、WriteProcessMemory函数(指定的进程中将数据写入内存区域,要写入的整个区域必须可访问,否则操作失败)
BOOL WriteProcessMemory(
HANDLE hProcess, // 要修改的进程内存的句柄
LPVOID lpBaseAddress, // 指向指定进程中写入数据的基地址指针
LPCVOID lpBuffer, // 指向缓冲区的指针,其中包含要写入指定进程的地址空间中的数据
SIZE_T nSize, // 要写入指定进程的字节数
SIZE_T *lpNumberOfBytesWritten // 指向变量的指针,该变量接收传输到指定进程的字节数。
);
4、CreateRemoteThread函数(在另一个进程的虚拟地址空间中创建运行的线程)
HANDLE CreateRemoteThread(
HANDLE hProcess, // 要创建线程的进程的句柄
LPSECURITY_ATTRIBUTES lpThreadAttributes, // 指向SCURITY_ATTRIBUTES结构的指针,
SIZE_T dwStackSize, // 堆栈的初始大小、以字节为单位
LPTHREAD_START_ROUTINE lpStartAddress, // 指向由线程执行类型为LPTHREAD_START_TOUTINE的应用程序定义的函数指针,
LPVOID lpParameter, // 指向要传递给线程函数的变量的指针
DWORD dwCreationFlags, // 控制线程创建的标志
LPDWORD lpThreadId // 指向接收线程标识符的变量的指针
);
【远线程注入技术】实现原理
远线程注入DLL之所以称为远线程,是由于它使用关键函数CreateRemoteThread来在其他进程空间中创建一个线程。那么,它为何能够 使其他进程加载一个DLL,实现DLL注入技术。
【远线程注入源代码】
#include <windows.h>
#include <iostream>
using namespace std;
DWORD threadInject(WCHAR* dllpath, DWORD pid)
{
int t = sizeof(dllpath);
//先激活权限
HANDLE hToken;
LUID newLuid;
TOKEN_PRIVILEGES tr;
tr.PrivilegeCount = 1;
tr.Privileges->Attributes = SE_PRIVILEGE_ENABLED;
OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &hToken);
LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &newLuid);
tr.Privileges->Luid = newLuid;
AdjustTokenPrivileges(hToken, FALSE, &tr, sizeof(tr), 0, 0);
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, NULL, pid);
//获取进程句柄
if (hProcess == 0 || hProcess == INVALID_HANDLE_VALUE)
{
printf("创建远线程失败 ");
CloseHandle(hToken);
return 0;
}
//申请内存存放参数
LPVOID p = VirtualAllocEx(hProcess, 0, 0x1000, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (!p)
{
printf("创建远线程失败 ");
CloseHandle(hProcess);
CloseHandle(hToken);
return 0;
}
//写参数
if (!WriteProcessMemory(hProcess, p, (LPVOID)(dllpath), sizeof(WCHAR)* (wcslen(dllpath)+1), NULL))
{
printf("创建远线程失败 ");
VirtualFreeEx(hProcess, p, 0x1000, MEM_FREE);
CloseHandle(hProcess);
CloseHandle(hToken);
return 0;
}
//创建远程线程并执行LoadLibraryW加载dll
HANDLE cThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)(GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "LoadLibraryW")), p, 0, 0);
if (cThread == 0 || cThread == INVALID_HANDLE_VALUE)
{
printf("创建远线程失败 ");
VirtualFreeEx(hProcess, p, 0x1000, MEM_FREE);
CloseHandle(hProcess);
CloseHandle(hToken);
return 0;
}
//5.等待线程结束返回,释放资源
WaitForSingleObject(cThread, -1);
CloseHandle(cThread);
CloseHandle(hProcess);
CloseHandle(hToken);
printf("创建远线程成功 ");
return 0;
}
int main() {
DWORD pid;
wstring str = L"C:\Users\97905\source\repos\RemoteInjectDll\Debug\RemoteInjectDll.dll";
cout << "输入pid" << endl;
cin >> pid;
//RemoteThreadInject(pid);
threadInject((WCHAR*)str.c_str(), pid);
return 0;
}