Skip to content

Commit 3a05ef6

Browse files
authored
Merge pull request #52 from otavepto/dev
support older bind variants + auto unload on success or timeout
2 parents d40d306 + ed5b745 commit 3a05ef6

File tree

3 files changed

+600
-412
lines changed

3 files changed

+600
-412
lines changed
Lines changed: 77 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,77 @@
1-
#include "pe_helpers/pe_helpers.hpp"
2-
#include "extra_protection/stubdrm.hpp"
3-
4-
BOOL APIENTRY DllMain(
5-
HMODULE hModule,
6-
DWORD reason,
7-
LPVOID lpReserved)
8-
{
9-
switch (reason)
10-
{
11-
case DLL_PROCESS_ATTACH:
12-
stubdrm::patch();
13-
break;
14-
case DLL_THREAD_ATTACH:
15-
case DLL_THREAD_DETACH:
16-
break;
17-
case DLL_PROCESS_DETACH:
18-
stubdrm::restore();
19-
break;
20-
}
21-
return TRUE;
22-
}
1+
#include "extra_protection/stubdrm.hpp"
2+
3+
#define WIN32_LEAN_AND_MEAN
4+
#include <Windows.h>
5+
6+
#include <condition_variable>
7+
#include <mutex>
8+
#include <chrono>
9+
#include <thread>
10+
11+
12+
static std::mutex dll_unload_mtx{};
13+
static std::condition_variable dll_unload_cv{};
14+
static bool unload_dll = false;
15+
16+
static HMODULE my_hModule = nullptr;
17+
static HANDLE unload_thread_handle = INVALID_HANDLE_VALUE;
18+
19+
20+
static void send_unload_signal()
21+
{
22+
{
23+
std::lock_guard lock(dll_unload_mtx);
24+
unload_dll = true;
25+
}
26+
dll_unload_cv.notify_one();
27+
}
28+
29+
DWORD WINAPI self_unload(LPVOID lpParameter)
30+
{
31+
constexpr const auto UNLOAD_TIMEOUT =
32+
#ifdef _DEBUG
33+
std::chrono::minutes(5)
34+
#else
35+
std::chrono::seconds(5)
36+
#endif
37+
;
38+
39+
{
40+
std::unique_lock lock(dll_unload_mtx);
41+
dll_unload_cv.wait_for(lock, UNLOAD_TIMEOUT, [](){ return unload_dll; });
42+
}
43+
unload_thread_handle = INVALID_HANDLE_VALUE;
44+
FreeLibraryAndExitThread(my_hModule, 0);
45+
}
46+
47+
BOOL APIENTRY DllMain(
48+
HMODULE hModule,
49+
DWORD reason,
50+
LPVOID lpReserved)
51+
{
52+
switch (reason)
53+
{
54+
case DLL_PROCESS_ATTACH:
55+
if (!stubdrm::patch()) {
56+
// https://learn.microsoft.com/en-us/windows/win32/dlls/dllmain
57+
// "The system immediately calls your entry-point function with DLL_PROCESS_DETACH and unloads the DLL"
58+
unload_dll = true;
59+
return FALSE;
60+
}
61+
my_hModule = hModule;
62+
stubdrm::set_cleanup_cb(send_unload_signal);
63+
unload_thread_handle = CreateThread(nullptr, 0, self_unload, nullptr, 0, nullptr);
64+
break;
65+
66+
case DLL_PROCESS_DETACH:
67+
if (!unload_dll) { // not unloaded yet, just an early exit, or thread timed out
68+
stubdrm::restore();
69+
if (unload_thread_handle != INVALID_HANDLE_VALUE && unload_thread_handle != NULL) {
70+
TerminateThread(unload_thread_handle, 0);
71+
}
72+
}
73+
break;
74+
}
75+
76+
return TRUE;
77+
}
Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
1-
#pragma once
2-
3-
#include <string>
4-
#include <vector>
5-
6-
namespace stubdrm
7-
{
8-
bool patch();
9-
10-
bool restore();
11-
}
1+
#pragma once
2+
3+
namespace stubdrm
4+
{
5+
bool patch();
6+
bool restore();
7+
8+
void set_cleanup_cb(void (*fn)());
9+
}

0 commit comments

Comments
 (0)