-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathwinring_wrapper.cpp
More file actions
173 lines (150 loc) · 6.23 KB
/
Copy pathwinring_wrapper.cpp
File metadata and controls
173 lines (150 loc) · 6.23 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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
#include <windows.h>
#include <iostream> // Optional: for debug output during development
#include <string> // For std::string
#include <vector> // For path manipulation buffer
#include <libloaderapi.h> // For GetModuleFileName
// Define function pointer types
typedef BOOL (WINAPI *InitializeOls_t)();
typedef VOID (WINAPI *DeinitializeOls_t)();
typedef DWORD (WINAPI *GetDllStatus_t)();
typedef BYTE (WINAPI *ReadIoPortByte_t)(WORD port);
typedef VOID (WINAPI *WriteIoPortByte_t)(WORD port, BYTE value);
// Global variables
HMODULE hWinRing0 = NULL;
InitializeOls_t InitializeOlsFunc = NULL;
DeinitializeOls_t DeinitializeOlsFunc = NULL;
GetDllStatus_t GetDllStatusFunc = NULL;
ReadIoPortByte_t ReadIoPortByteFunc = NULL;
WriteIoPortByte_t WriteIoPortByteFunc = NULL;
BOOL winRingLoaded = FALSE;
BOOL winRingInitialized = FALSE;
DWORD lastLoadError = 0; // Variable to store LoadLibrary error
// Helper function to get the directory of the current module (the wrapper DLL)
std::wstring GetModuleDirectory(HMODULE hModule) {
std::vector<wchar_t> pathBuf;
DWORD copied = 0;
do {
pathBuf.resize(pathBuf.size() + MAX_PATH);
copied = GetModuleFileNameW(hModule, pathBuf.data(), static_cast<DWORD>(pathBuf.size()));
} while (copied >= pathBuf.size());
pathBuf.resize(copied);
std::wstring path(pathBuf.begin(), pathBuf.end());
// Find the last backslash to get the directory
size_t lastBackslash = path.find_last_of(L"\\/");
if (std::wstring::npos != lastBackslash) {
return path.substr(0, lastBackslash);
}
return L"."; // Return current directory if path is unusual
}
// Exported function to load the WinRing0 DLL and get function pointers
extern "C" __declspec(dllexport) BOOL LoadWinRing0() {
if (winRingLoaded) return TRUE; // Already loaded
lastLoadError = 0; // Reset error code
// Get the directory where this wrapper DLL is located
HMODULE hSelf = NULL;
GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
(LPCWSTR)&LoadWinRing0, &hSelf);
std::wstring wrapperDir = GetModuleDirectory(hSelf);
std::wstring winRingPath = wrapperDir + L"\\WinRing0x64.dll";
// std::wcout << L"Attempting to load WinRing0 from: " << winRingPath << std::endl; // Debug output
// Load WinRing0 using the constructed absolute path
hWinRing0 = LoadLibraryW(winRingPath.c_str()); // Use LoadLibraryW for wide string path
if (hWinRing0 == NULL) {
lastLoadError = GetLastError(); // Store the error code
// Optional: Add logging or error reporting here if needed
// std::wcerr << L"LoadLibrary failed for path " << winRingPath << L" with error: " << lastLoadError << std::endl;
return FALSE;
}
InitializeOlsFunc = (InitializeOls_t)GetProcAddress(hWinRing0, "InitializeOls");
DeinitializeOlsFunc = (DeinitializeOls_t)GetProcAddress(hWinRing0, "DeinitializeOls");
GetDllStatusFunc = (GetDllStatus_t)GetProcAddress(hWinRing0, "GetDllStatus");
ReadIoPortByteFunc = (ReadIoPortByte_t)GetProcAddress(hWinRing0, "ReadIoPortByte");
WriteIoPortByteFunc = (WriteIoPortByte_t)GetProcAddress(hWinRing0, "WriteIoPortByte");
if (!InitializeOlsFunc || !DeinitializeOlsFunc || !GetDllStatusFunc || !ReadIoPortByteFunc || !WriteIoPortByteFunc) {
lastLoadError = GetLastError(); // Store GetProcAddress error (less likely)
FreeLibrary(hWinRing0);
hWinRing0 = NULL;
return FALSE;
}
winRingLoaded = TRUE;
return TRUE;
}
// Exported function to initialize the WinRing0 driver
extern "C" __declspec(dllexport) BOOL InitWinRing0() {
if (!winRingLoaded) return FALSE; // Must load first
if (winRingInitialized) return TRUE; // Already initialized
if (InitializeOlsFunc()) {
winRingInitialized = TRUE;
return TRUE;
} else {
return FALSE;
}
}
// Exported function to deinitialize WinRing0
extern "C" __declspec(dllexport) VOID DeinitWinRing0() {
if (winRingInitialized && DeinitializeOlsFunc) {
DeinitializeOlsFunc();
}
if (hWinRing0) {
FreeLibrary(hWinRing0);
}
hWinRing0 = NULL;
InitializeOlsFunc = NULL;
DeinitializeOlsFunc = NULL;
GetDllStatusFunc = NULL;
ReadIoPortByteFunc = NULL;
WriteIoPortByteFunc = NULL;
winRingLoaded = FALSE;
winRingInitialized = FALSE;
lastLoadError = 0; // Reset error on deinit
}
// Exported function to read from an I/O port
extern "C" __declspec(dllexport) BYTE ReadPort(WORD port) {
if (!winRingInitialized || !ReadIoPortByteFunc) {
return 0; // Or some other error indicator
}
// Add small delay matching _ec_wait() if necessary for stability
// Sleep(1); // Example: 1 millisecond delay
return ReadIoPortByteFunc(port);
}
// Exported function to write to an I/O port
extern "C" __declspec(dllexport) VOID WritePort(WORD port, BYTE value) {
if (!winRingInitialized || !WriteIoPortByteFunc) {
return;
}
// Add small delay matching _ec_wait() if necessary for stability
// Sleep(1); // Example: 1 millisecond delay
WriteIoPortByteFunc(port, value);
}
// Exported function to get WinRing0 status OR the LoadLibrary error
extern "C" __declspec(dllexport) DWORD GetStatus() {
// If loading failed, return the LoadLibrary error code
if (!winRingLoaded && lastLoadError != 0) {
return lastLoadError;
}
// If WinRing0's GetDllStatus function pointer is valid, call it
if (GetDllStatusFunc) {
return GetDllStatusFunc();
}
// Otherwise, return a generic error/unknown status
return 0xFFFFFFFF; // Example error code for status unavailable
}
// DLL entry point (optional, can be used for cleanup if process detaches unexpectedly)
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
// Optional: Attempt cleanup if the DLL is unloaded unexpectedly
// DeinitWinRing0(); // Be cautious with cleanup here, might cause issues if called implicitly
break;
}
return TRUE;
}