-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy paththread.cpp
More file actions
95 lines (83 loc) · 2.48 KB
/
Copy paththread.cpp
File metadata and controls
95 lines (83 loc) · 2.48 KB
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
92
93
94
95
#include "include/thread.h"
Thread::Thread(int tid) : tid(tid), handle(nullptr) { }
int Thread::get_tid() const
{
return this->tid;
}
HANDLE Thread::get_handle()
{
if (handle != nullptr) {
return handle;
}
if (this->tid == 0) {
printf("[%s] Cannot get handle, TID is 0.\n", __FUNCTION__);
return nullptr;
}
HANDLE h = OpenThread(THREAD_SUSPEND_RESUME | THREAD_QUERY_INFORMATION, FALSE, this->tid);
if (h == NULL) {
DWORD lastError = GetLastError();
printf("[%s] OpenThread failed. Error: %lu (0x%lx).\n", __FUNCTION__, this->tid, lastError, lastError);
return nullptr;
}
handle = h;
return handle;
}
bool Thread::suspend() {
HANDLE h = get_handle();
if (h == nullptr) {
printf("[%s] Cannot suspend, handle is invalid/null (TID: %d).\n", __FUNCTION__, this->tid);
return false;
}
DWORD suspendCount = SuspendThread(h);
if (suspendCount == (DWORD)-1) {
DWORD lastError = GetLastError();
printf("[%s] SuspendThread (Win32) failed for TID %d (Error: %lu / 0x%lx)\n", __FUNCTION__, this->tid, lastError, lastError);
return false;
}
return true;
}
bool Thread::resume() {
HANDLE h = get_handle();
if (h == nullptr) {
printf("[%s] Cannot resume, handle is invalid/null (TID: %d).\n", __FUNCTION__, this->tid);
return false;
}
DWORD suspendCount = ResumeThread(h);
if (suspendCount == (DWORD)-1) {
DWORD lastError = GetLastError();
printf("[%s] ResumeThread (Win32) failed for TID %d (Error: %lu / 0x%lx)\n", __FUNCTION__, this->tid, lastError, lastError);
return false;
}
return true;
}
bool Thread::context(CONTEXT& ctx) {
HANDLE h = get_handle();
ctx.ContextFlags = CONTEXT_ALL;
NTSTATUS status = Sw3NtGetContextThread(h, &ctx);
return NT_SUCCESS(status);
}
bool Thread::set_context(CONTEXT ctx) {
HANDLE h = get_handle();
NTSTATUS status = Sw3NtSetContextThread(h, &ctx);
return NT_SUCCESS(status);
}
Thread::Thread(Thread&& other) noexcept : tid(other.tid) {
handle = std::exchange(other.handle, nullptr);
}
Thread& Thread::operator=(Thread&& other) noexcept {
if (this != &other) {
if (handle != nullptr) {
CloseHandle(handle);
}
tid = other.tid;
handle = std::exchange(other.handle, nullptr);
}
return *this;
}
Thread::~Thread()
{
if (handle != nullptr) {
CloseHandle(handle);
handle = nullptr;
}
}