会话

会话是登录后的用户环境

在进程管理器中详细信息的空栏中右键,可以打开会话属性:

image-20250227180553270

它用来隔离不同用户的操作环境,会话ID的先后顺序取决于系统启动后哪个用户先登录,会话0一般为系统进程,和用户进程隔离来提高安全性。(但是看起来似乎没什么用)

如果要注入系统进程,直接使用CreateRemoteThread会被拦截下来,所以需要用另外的办法。最简单的就是换一个API:NtCreateThreadEx

定义如下,与CreateRemoteThread差不多

1
2
3
4
5
6
7
8
9
10
11
12
13
typedef DWORD(WINAPI* PFNTCREATETHREADEX)(
PHANDLE ThreadHandle,//创建的线程的线程句柄
ACCESS_MASK DesiredAccess,//线程权限
LPVOID ObjectAttributes,//属性,一般nullptr
HANDLE ProcessHandle,//目标进程句柄
LPTHREAD_START_ROUTINE lpStartAddress,//起始函数
LPVOID lpParameter,//参数
ULONG CreateThreadFlags,//好像和挂起有关,填FALSE即可
SIZE_T ZeroBits,//0即可
SIZE_T StackSize,//0即可
SIZE_T MaximumStackSize,//0即可
LPVOID pUnkown//nullptr即可
);

直接用这个注入就好

注入器代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#include<iostream>
#include<windows.h>
#include<tchar.h>




bool modifiedCreateRemoteThread(HANDLE hProcess, LPTHREAD_START_ROUTINE pThreadProc, LPVOID pRemoteBuf)
{
FARPROC pNtCreateThreadEx = GetProcAddress(GetModuleHandleA("ntdll.dll"), "NtCreateThreadEx");
if (!pNtCreateThreadEx)
{
printf("NtCreateThreadEx not found");
return false;
}
typedef DWORD(WINAPI* PFNTCREATETHREADEX)(
PHANDLE ThreadHandle,
ACCESS_MASK DesiredAccess,
LPVOID ObjectAttributes,
HANDLE ProcessHandle,
LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParameter,
ULONG CreateThreadFlags,
SIZE_T ZeroBits,
SIZE_T StackSize,
SIZE_T MaximumStackSize,
LPVOID pUnkown
);
PFNTCREATETHREADEX crt = reinterpret_cast<PFNTCREATETHREADEX>(pNtCreateThreadEx);
HANDLE hThread;
crt(&hThread, THREAD_ALL_ACCESS, nullptr, hProcess, pThreadProc, pRemoteBuf, FALSE, NULL, NULL, NULL, nullptr);
if (!hThread) {
printf("create thread failed");
return false;
}
WaitForSingleObject(hThread, INFINITE);//等待线程结束
CloseHandle(hThread);
CloseHandle(hProcess);
return true;
}








int inject(DWORD dwPID, LPCTSTR szDllPath) {
HANDLE hProcess = 0;
bool status = false;
if (!(hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID)))//取得对应PID句柄
{
_tprintf(_T("open %d failed\n"), dwPID);
return FALSE;
}
DWORD dwBufSize = (DWORD)(_tcslen(szDllPath) + 1) * sizeof(TCHAR);
LPVOID pBuf = VirtualAllocEx(hProcess, NULL, dwBufSize, MEM_COMMIT, PAGE_READWRITE);//申请内存
if (pBuf == 0) {
_tprintf(_T("memory alloc failed\n"));
return FALSE;
}

WriteProcessMemory(hProcess, pBuf, (LPVOID)szDllPath, dwBufSize, NULL);//写入地址
HMODULE kernel = GetModuleHandle(L"kernel32.dll");
if (kernel == NULL)
return FALSE;
LPTHREAD_START_ROUTINE pThreadProc = (LPTHREAD_START_ROUTINE)GetProcAddress(kernel, "LoadLibraryW");//获取LodaLibrary地址
status = modifiedCreateRemoteThread(hProcess,
pThreadProc,//线程回调函数
pBuf//传参
);

return TRUE;
}



int _tmain(int argc, TCHAR* argv[]) {
if (argc != 3)
{
_tprintf(_T("USAGE: %s pid dll_path\n"), argv[0]);
return 1;
}
if (inject((DWORD)_tstol(argv[1]), argv[2]))
_tprintf(_T("inject %s success!\n"), argv[2]);
else
_tprintf(_T("inject %s failed! \n"), argv[2]);
return 0;
}

image-20250227181313876

可以看到进程查看器中显示已经注入成功