├── .gitignore ├── LICENSE ├── readme.md └── src ├── driver.hpp ├── fs.hpp ├── kernelLoader.sln ├── kernelLoader.vcxproj ├── kernelLoader.vcxproj.filters ├── kernelLoader.vcxproj.user └── main.cpp /.gitignore: -------------------------------------------------------------------------------- 1 | .vs 2 | src/x64 -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Soju06 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # KernelLoader 2 | 3 | KernelLoader is a simple tool to load and debug unsigned kernel. 4 | 5 | ## Usage 6 | 7 | ```bash 8 | Usage: 9 | -l, --load [driver path] [driver name] 10 | Load the driver. 11 | 12 | Options: 13 | -o, --overwrite 14 | If the driver already exists, exit and overwrite it. 15 | -w, --watch 16 | Quickly reload drivers from a prompt when needed. 17 | 18 | -u, --unload [driver name] 19 | Delete the driver. 20 | 21 | Global Options: 22 | -s, --status [driver name] 23 | Print the drivers service status. 24 | -i, --ignore-signatures 25 | Install services to ignore kernel driver signatures. (powered by Wind64) 26 | 27 | -r, --uninstall-ignore-signatures 28 | Remove services that ignore signatures of kernel drivers. (powered by Wind64) 29 | ``` 30 | 31 | ## Examples 32 | 33 | #### Watch Mode 34 | 35 | Here is an example of loading `../EasyShield.sys` with Watch mode and signature ignore. 36 | 37 | If signature ignore is enabled and an anti-cheat is running during Watch mode, a flag may occur. Disable the anti-cheat to debug the driver. 38 | 39 | **To use this feature, the driver must support the `SERVICE_ACCEPT_STOP` control.** 40 | 41 | To support the `SERVICE_ACCEPT_STOP` control, refer to [here](#how-to-support-service_accept_stop-control). 42 | 43 | 44 | ```bash 45 | kernelLoader.exe -l ../EasyShield.sys EasyShield2 -w -i 46 | ``` 47 | 48 | ```bash 49 | [+] EasyShield2 driver loaded successfully. 50 | 51 | [*] Press the 'R' key to reload the driver. 52 | Press the 'S' key to print the service status. 53 | Press the 'Q' key to exit the loop. 54 | Press the 'X' key to delete the driver and exit the loop. 55 | 56 | 21:59:07: 57 | ``` 58 | 59 | If you press the S key, you can check the service status as follows. 60 | 61 | ```bash 62 | [+] EasyShield2 Service Status : 63 | ------------------------------------------------------ 64 | Type : SERVICE_KERNEL_DRIVER 65 | Status : RUNNING 66 | ------------------------------------------------------ 67 | Wait Hint : 0ms 68 | Checkpoint : 0 69 | Controls Accepted : SERVICE_ACCEPT_STOP 70 | ------------------------------------------------------ 71 | Exit Code (Win32) : 0x00000000 72 | Exit Code (Service) : 0x00000000 73 | ------------------------------------------------------ 74 | 75 | 76 | [*] Press the 'R' key to reload the driver. 77 | Press the 'S' key to print the service status. 78 | Press the 'Q' key to exit the loop. 79 | Press the 'X' key to delete the driver and exit the loop. 80 | 81 | 21:59:45: 82 | ``` 83 | 84 | ## How to support `SERVICE_ACCEPT_STOP` control 85 | 86 | You can specify a callback function in `PDRIVER_OBJECT->DriverUnload`. 87 | 88 | ```c 89 | VOID OnUnload(PDRIVER_OBJECT driverObject) { 90 | UNREFERENCED_PARAMETER(driverObject); 91 | DbgPrintEx(0, 0, "[*] Device unloaded.\n"); 92 | } 93 | 94 | NTSTATUS DriverEntry( 95 | PDRIVER_OBJECT driverObject, 96 | PUNICODE_STRING registryPath 97 | ) { 98 | UNREFERENCED_PARAMETER(registryPath); 99 | DbgPrintEx(0, 0, "[*] Device loaded.\n"); 100 | 101 | driverObject->DriverUnload = OnUnload; 102 | 103 | return STATUS_SUCCESS; 104 | } 105 | ``` -------------------------------------------------------------------------------- /src/driver.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | #include "fs.hpp" 6 | 7 | inline bool SCManager(SC_HANDLE* handle) { 8 | *handle = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE); 9 | if (handle) return 1; 10 | cout << "[x] Can't open SC manager. (permissions issue)\n"; 11 | return 0; 12 | } 13 | 14 | inline bool OpenDriver( 15 | wstring serviceName, 16 | DWORD access, 17 | SC_HANDLE* manager, 18 | SC_HANDLE* driver, 19 | int ignoreLevel 20 | ) { 21 | auto _manager = manager; 22 | 23 | if (!manager || !SCManager(manager)) 24 | return 0; 25 | 26 | *driver = OpenService( 27 | *manager, 28 | serviceName.c_str(), 29 | access 30 | ); 31 | 32 | if (!*driver) { 33 | if (ignoreLevel < 1) 34 | cout << "[x] Cannot open service.\n"; 35 | if (!_manager) 36 | CloseServiceHandle(*manager); 37 | return 0; 38 | } 39 | return 1; 40 | } 41 | 42 | inline bool GetStatus( 43 | wstring serviceName, 44 | SERVICE_STATUS* status, 45 | SC_HANDLE* manager = 0 46 | ) { 47 | bool lv = 0; 48 | SC_HANDLE handle, service = 0; 49 | 50 | if (manager) 51 | handle = *manager; 52 | 53 | if (!OpenDriver( 54 | serviceName, 55 | SERVICE_QUERY_STATUS, 56 | &handle, 57 | &service, 58 | 0 59 | )) return 0; 60 | 61 | if (!QueryServiceStatus(service, status)) 62 | cout << "[x] Unable to get status of service.\n"; 63 | else lv = 1; 64 | 65 | if (service) 66 | CloseServiceHandle(service); 67 | 68 | if (!manager) 69 | CloseServiceHandle(handle); 70 | 71 | return lv; 72 | } 73 | 74 | inline bool DeleteDriver( 75 | wstring serviceName, 76 | SC_HANDLE* manager = 0, 77 | int ignoreLevel = 0 78 | ) { 79 | bool lv = 0; 80 | SC_HANDLE handle, service = 0; 81 | 82 | if (manager) 83 | handle = *manager; 84 | 85 | if (!OpenDriver( 86 | serviceName, 87 | SERVICE_STOP | DELETE, 88 | &handle, 89 | &service, 90 | ignoreLevel 91 | )) return 0; 92 | 93 | if (!service) { 94 | if (ignoreLevel < 1) 95 | cout << "[x] Cannot open service.\n"; 96 | goto CLOSE; 97 | } 98 | 99 | SERVICE_STATUS status; 100 | if ( 101 | ControlService(service, SERVICE_CONTROL_STOP, &status) || 102 | status.dwCurrentState == SERVICE_STOPPED 103 | ) 104 | if (!DeleteService(service) && ignoreLevel < 3) 105 | cout << "[x] Cannot delete service.\n"; 106 | else lv = 1; 107 | 108 | else if (ignoreLevel < 2) 109 | cout << "[x] Service cannot be stopped (Probably the driver unload method is not defined).\n"; 110 | 111 | CLOSE: 112 | if (service) 113 | CloseServiceHandle(service); 114 | 115 | if (!manager) 116 | CloseServiceHandle(handle); 117 | 118 | return lv; 119 | } 120 | 121 | inline bool LoadDriver( 122 | wstring driverPath, 123 | wstring serviceName, 124 | wstring displayName, 125 | SC_HANDLE* manager = 0, 126 | bool overwrite = 0 127 | ) { 128 | bool lv = 0; 129 | auto _manager = manager; 130 | SC_HANDLE handle; 131 | 132 | if (manager) 133 | handle = *manager; 134 | else if (!SCManager(&handle)) 135 | return 0; 136 | 137 | CREATE_SERVICE: 138 | SC_HANDLE service = CreateService( 139 | handle, 140 | serviceName.c_str(), 141 | displayName.c_str(), 142 | SERVICE_START | DELETE | SERVICE_STOP, 143 | SERVICE_KERNEL_DRIVER, 144 | SERVICE_DEMAND_START, 145 | SERVICE_ERROR_IGNORE, 146 | driverPath.c_str(), 147 | NULL, 148 | NULL, 149 | NULL, 150 | NULL, 151 | NULL 152 | ); 153 | 154 | if (!service) { 155 | if (overwrite) { 156 | if (DeleteDriver( 157 | serviceName.c_str(), 158 | &handle 159 | )) goto CREATE_SERVICE; 160 | } else 161 | cout << "[x] Unable to create service. (there is already a registered service)\n"; 162 | goto CLOSE; 163 | } 164 | 165 | if (!StartServiceA(service, NULL, NULL)) 166 | cout << "[x] Service cannot be run.\n"; 167 | else lv = 1; 168 | 169 | CLOSE: 170 | if (service) 171 | CloseServiceHandle(service); 172 | if (!_manager) 173 | CloseServiceHandle(handle); 174 | 175 | return lv; 176 | } 177 | 178 | #define FLAG_STR(list, value, flag) \ 179 | if ((value & flag) == flag) \ 180 | list.push_back(#flag); 181 | 182 | inline bool PrintStatus( 183 | wstring serviceName, 184 | SC_HANDLE* manager = 0 185 | ) { 186 | SERVICE_STATUS status; 187 | 188 | if (!GetStatus(serviceName, &status, manager)) 189 | return 0; 190 | 191 | vector types, ctrlacp; 192 | FLAG_STR(types, status.dwServiceType, SERVICE_FILE_SYSTEM_DRIVER); 193 | FLAG_STR(types, status.dwServiceType, SERVICE_KERNEL_DRIVER); 194 | FLAG_STR(types, status.dwServiceType, SERVICE_WIN32_OWN_PROCESS); 195 | FLAG_STR(types, status.dwServiceType, SERVICE_WIN32_SHARE_PROCESS); 196 | FLAG_STR(types, status.dwServiceType, SERVICE_USER_OWN_PROCESS); 197 | FLAG_STR(types, status.dwServiceType, SERVICE_USER_SHARE_PROCESS); 198 | FLAG_STR(types, status.dwServiceType, SERVICE_INTERACTIVE_PROCESS); 199 | 200 | FLAG_STR(ctrlacp, status.dwControlsAccepted, SERVICE_ACCEPT_NETBINDCHANGE); 201 | FLAG_STR(ctrlacp, status.dwControlsAccepted, SERVICE_ACCEPT_PARAMCHANGE); 202 | FLAG_STR(ctrlacp, status.dwControlsAccepted, SERVICE_ACCEPT_PAUSE_CONTINUE); 203 | FLAG_STR(ctrlacp, status.dwControlsAccepted, SERVICE_ACCEPT_PRESHUTDOWN); 204 | FLAG_STR(ctrlacp, status.dwControlsAccepted, SERVICE_ACCEPT_SHUTDOWN); 205 | FLAG_STR(ctrlacp, status.dwControlsAccepted, SERVICE_ACCEPT_STOP); 206 | FLAG_STR(ctrlacp, status.dwControlsAccepted, SERVICE_ACCEPT_HARDWAREPROFILECHANGE); 207 | FLAG_STR(ctrlacp, status.dwControlsAccepted, SERVICE_ACCEPT_POWEREVENT); 208 | FLAG_STR(ctrlacp, status.dwControlsAccepted, SERVICE_ACCEPT_SESSIONCHANGE); 209 | FLAG_STR(ctrlacp, status.dwControlsAccepted, SERVICE_ACCEPT_TIMECHANGE); 210 | FLAG_STR(ctrlacp, status.dwControlsAccepted, SERVICE_ACCEPT_TRIGGEREVENT); 211 | // FLAG_STR(ctrlacp, status.dwControlsAccepted, SERVICE_ACCEPT_USERMODEREBOOT); 212 | 213 | cout << format( 214 | "[+] {} Service Status :\n" 215 | "------------------------------------------------------\n" 216 | " Type : {}\n" 217 | " Status : {}\n" 218 | "------------------------------------------------------\n" 219 | " Wait Hint : {}ms\n" 220 | " Checkpoint : {}\n" 221 | " Controls Accepted : {}\n" 222 | "------------------------------------------------------\n" 223 | " Exit Code (Win32) : {:#010x}\n" 224 | " Exit Code (Service) : {:#010x}\n" 225 | "------------------------------------------------------\n" 226 | "\n", 227 | path(serviceName).string(), 228 | strjoin(types, " | "), 229 | status.dwCurrentState == SERVICE_CONTINUE_PENDING ? "PENDING" : 230 | status.dwCurrentState == SERVICE_PAUSE_PENDING ? "PAUSE PENDING" : 231 | status.dwCurrentState == SERVICE_PAUSED ? "PAUSED" : 232 | status.dwCurrentState == SERVICE_RUNNING ? "RUNNING" : 233 | status.dwCurrentState == SERVICE_START_PENDING ? "START PENDING" : 234 | status.dwCurrentState == SERVICE_STOP_PENDING ? "STOP PENDING" : 235 | status.dwCurrentState == SERVICE_STOPPED ? "STOPPED" : 236 | to_string(status.dwCurrentState), 237 | status.dwWaitHint, 238 | status.dwCheckPoint, 239 | ctrlacp.empty() ?"NONE" : strjoin(ctrlacp, " | "), 240 | status.dwWin32ExitCode, 241 | status.dwServiceSpecificExitCode 242 | ); 243 | 244 | return 1; 245 | } 246 | 247 | inline bool HookDebugLog() { 248 | 249 | } -------------------------------------------------------------------------------- /src/fs.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace std; 8 | using namespace std::filesystem; 9 | 10 | static const char Strings[] = 11 | "0123456789" 12 | "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 13 | "abcdefghijklmnopqrstuvwxyz"; 14 | 15 | inline string randstr(int len) { 16 | char* str = new char[(size_t)len + 1] { 0 }; 17 | 18 | for (int i = 0; i < len; ++i) 19 | str[i] = Strings[rand() % (sizeof(Strings) - 1)]; 20 | 21 | return str; 22 | } 23 | 24 | inline bool tempdir(path& dir, string prefix) { 25 | while (1) { 26 | dir = temp_directory_path() / path(prefix + randstr(8)); 27 | if (!exists(dir)) break; 28 | } 29 | 30 | return create_directories(dir); 31 | } 32 | 33 | inline path curdir() { 34 | wchar_t filepath[MAX_PATH] = { 0 }; 35 | GetModuleFileName(NULL, filepath, MAX_PATH); 36 | return path(filepath).parent_path(); 37 | } 38 | 39 | inline string strjoin(vector strings, string delim) { 40 | if (strings.empty()) 41 | return ""; 42 | 43 | return accumulate(strings.begin() + 1, strings.end(), strings[0], 44 | [&delim](std::string x, std::string y) { 45 | return x + delim + y; 46 | } 47 | ); 48 | } 49 | -------------------------------------------------------------------------------- /src/kernelLoader.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.4.33205.214 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "kernelLoader", "kernelLoader.vcxproj", "{F0651DBE-72D5-4005-A99E-BA7D8C5B5F97}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Debug|x86 = Debug|x86 12 | Release|x64 = Release|x64 13 | Release|x86 = Release|x86 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {F0651DBE-72D5-4005-A99E-BA7D8C5B5F97}.Debug|x64.ActiveCfg = Debug|x64 17 | {F0651DBE-72D5-4005-A99E-BA7D8C5B5F97}.Debug|x64.Build.0 = Debug|x64 18 | {F0651DBE-72D5-4005-A99E-BA7D8C5B5F97}.Debug|x86.ActiveCfg = Debug|Win32 19 | {F0651DBE-72D5-4005-A99E-BA7D8C5B5F97}.Debug|x86.Build.0 = Debug|Win32 20 | {F0651DBE-72D5-4005-A99E-BA7D8C5B5F97}.Release|x64.ActiveCfg = Release|x64 21 | {F0651DBE-72D5-4005-A99E-BA7D8C5B5F97}.Release|x64.Build.0 = Release|x64 22 | {F0651DBE-72D5-4005-A99E-BA7D8C5B5F97}.Release|x86.ActiveCfg = Release|Win32 23 | {F0651DBE-72D5-4005-A99E-BA7D8C5B5F97}.Release|x86.Build.0 = Release|Win32 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {DC46A656-9E34-4352-A43F-3EC0EDEDD9F3} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /src/kernelLoader.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 16.0 23 | Win32Proj 24 | {f0651dbe-72d5-4005-a99e-ba7d8c5b5f97} 25 | kernelLoader 26 | 10.0 27 | 28 | 29 | 30 | Application 31 | true 32 | v143 33 | Unicode 34 | 35 | 36 | Application 37 | false 38 | v143 39 | true 40 | Unicode 41 | 42 | 43 | Application 44 | true 45 | v142 46 | Unicode 47 | 48 | 49 | Application 50 | false 51 | v142 52 | true 53 | Unicode 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | true 75 | 76 | 77 | false 78 | 79 | 80 | true 81 | 82 | 83 | false 84 | 85 | 86 | 87 | Level3 88 | true 89 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 90 | true 91 | 92 | 93 | Console 94 | true 95 | 96 | 97 | 98 | 99 | Level3 100 | true 101 | true 102 | true 103 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 104 | true 105 | 106 | 107 | Console 108 | true 109 | true 110 | true 111 | 112 | 113 | 114 | 115 | Level3 116 | true 117 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions) 118 | true 119 | stdcpp20 120 | 121 | 122 | Console 123 | true 124 | RequireAdministrator 125 | 126 | 127 | 128 | 129 | Level3 130 | true 131 | true 132 | true 133 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 134 | true 135 | stdcpp20 136 | 137 | 138 | Console 139 | true 140 | true 141 | true 142 | RequireAdministrator 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | -------------------------------------------------------------------------------- /src/kernelLoader.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 10 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 11 | 12 | 13 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 14 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | Source Files 23 | 24 | 25 | Source Files 26 | 27 | 28 | -------------------------------------------------------------------------------- /src/kernelLoader.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | \\tsclient\G\Downloads\eft_kernel\kernelLoader\x64\Debug\kernelLoader.exe 5 | \\tsclient\G\Downloads\eft_kernel\kernelLoader 6 | NativeOnly 7 | WindowsRemoteDebugger 8 | 172.28.99.45:4026 9 | -l "C:\Users\soju\Desktop\eft_kernel2.sys" eftk -w 10 | 11 | -------------------------------------------------------------------------------- /src/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #pragma comment(lib, "urlmon.lib") 8 | 9 | #include "driver.hpp" 10 | 11 | using namespace std; 12 | 13 | constexpr auto WIND64_URL = L"https://github.com/katlogic/WindowsD/releases/download/v2.2/wind64.exe"; 14 | constexpr const char* HELP_STR = R"( 15 | Usage: 16 | -l, --load [driver path] [driver name] 17 | Load the driver. 18 | 19 | Options: 20 | -o, --overwrite 21 | If the driver already exists, exit and overwrite it. 22 | -w, --watch 23 | Quickly reload drivers from a prompt when needed. 24 | 25 | -u, --unload [driver name] 26 | Delete the driver. 27 | 28 | Global Options: 29 | -s, --status [driver name] 30 | Print the drivers service status. 31 | -i, --ignore-signatures 32 | Install services to ignore kernel driver signatures. (powered by Wind64) 33 | 34 | -r, --uninstall-ignore-signatures 35 | Remove services that ignore signatures of kernel drivers. (powered by Wind64) 36 | )"; 37 | 38 | int Argc; 39 | const char** Argv; 40 | path RunningDir; 41 | 42 | string NowTime() { 43 | tm t; 44 | stringstream buf; 45 | time_t now_t = time(0); 46 | localtime_s(&t, &now_t); 47 | buf << put_time(&t, "%H:%M:%S"); 48 | return buf.str(); 49 | } 50 | 51 | int FindArgs(const char* flag) { 52 | for (int i = 0; i < Argc; i++) { 53 | auto arg = Argv[i]; 54 | if (strcmp(arg, flag) == 0) 55 | return i; 56 | } 57 | return -1; 58 | } 59 | 60 | const char* GetValue(int flagIndex) { 61 | if (flagIndex < 0 || flagIndex >= Argc) return 0; 62 | return Argv[flagIndex + 1]; 63 | } 64 | 65 | bool UseWind64(const char* cmd = 0) { 66 | auto windP = RunningDir / path("wind64.exe"); 67 | wstring windW = windP.wstring(); 68 | 69 | if (!exists(windP)) { 70 | wcout << format(L"[*] Download Wind64 from {}\n", WIND64_URL); 71 | 72 | 73 | if ( 74 | URLDownloadToFile( 75 | NULL, 76 | WIND64_URL, 77 | windW.c_str(), 78 | BINDF_GETNEWESTVERSION, 79 | NULL 80 | ) != S_OK) { 81 | cout << "[*] Failed to download Wind64.\n"; 82 | return 0; 83 | } 84 | } 85 | 86 | 87 | if (cmd) { 88 | auto status = system(format("{} {}", absolute(windP).string(), cmd).c_str()); 89 | 90 | 91 | if (status != 1) { 92 | cout << format("[*] Failed to execute Wind64. (ExitCode: 0x{:016X})\n", status); 93 | return 0; 94 | } 95 | 96 | Sleep(1000); 97 | } 98 | 99 | return 1; 100 | } 101 | 102 | int main(int argc, const char** argv) { 103 | bool acok = 0; 104 | int argi = 0; 105 | const char *invparm = 0, *misparm = 0; 106 | Argc = argc; Argv = argv; 107 | RunningDir = curdir(); 108 | 109 | cout << "[*] Kernel Loader\n"; 110 | 111 | #define INVPARM(parm) invparm = #parm; goto SHOW_USAGE; 112 | #define MISPARM(parm) misparm = #parm; goto SHOW_USAGE; 113 | 114 | bool ignore_signatures = 115 | FindArgs("-i") != -1 || 116 | FindArgs("--ignore-signatures") != -1; 117 | if ( 118 | argc == 0 || 119 | FindArgs("-?") != -1 || 120 | FindArgs("-h") != -1 121 | ) { 122 | SHOW_USAGE: 123 | if (invparm) cout << format("[-] Parameter {} is invalid.\n", invparm); 124 | if (misparm) cout << format("[-] Parameter {} is missing.\n", misparm); 125 | cout << HELP_STR; 126 | goto EXIT; 127 | } 128 | 129 | if (ignore_signatures) { 130 | // wind64.exe /i 131 | acok = 1; 132 | cout << "[*] Install services to ignore kernel driver signatures.\n"; 133 | if (!UseWind64("/i")) 134 | goto EXIT; 135 | cout << "[+] OK\n"; 136 | } else if ( 137 | // wind64.exe /u 138 | FindArgs("-r") != -1 || 139 | FindArgs("--uninstall-ignore-signatures") != -1 140 | ) { 141 | acok = 1; 142 | cout << "[*] Uninstall services that ignore signatures of kernel drivers.\n"; 143 | if (!UseWind64("/u")) 144 | goto EXIT; 145 | } else if ( 146 | // status 147 | (argi = FindArgs("-s")) != -1 || 148 | (argi = FindArgs("--status")) != -1 149 | ) { 150 | acok = 1; 151 | auto name = GetValue(argi); 152 | 153 | if (!name) { 154 | MISPARM(name); 155 | } 156 | 157 | PrintStatus(path(name)); 158 | } 159 | 160 | if ( 161 | // load 162 | (argi = FindArgs("-l")) != -1 || 163 | (argi = FindArgs("--load")) != -1 164 | ) { 165 | auto 166 | driverPath = GetValue(argi), 167 | name = GetValue(argi + 1); 168 | auto 169 | overwrite = FindArgs("-o") != -1 || 170 | FindArgs("--overwrite") != -1, 171 | watch = FindArgs("-w") != -1 || 172 | FindArgs("--watch") != -1; 173 | 174 | if (!driverPath) { 175 | MISPARM(driverPath); 176 | } 177 | if (!name) { 178 | MISPARM(name); 179 | } 180 | 181 | path 182 | tmpdir, 183 | nameP = name, 184 | driverP = absolute(driverPath), 185 | driver = driverP; 186 | 187 | if (!exists(driver) || is_directory(driver)) { 188 | cout << format("[x] Driver files not found! {}\n", driver.string()); 189 | goto EXIT; 190 | } 191 | 192 | if (watch) { 193 | if (!tempdir(tmpdir, "kernelLoader_")) { 194 | cout << "[x] Unable to create temporary directory.\n"; 195 | goto EXIT; 196 | } 197 | driver = tmpdir / path(driver.filename()); 198 | overwrite = 1; 199 | } 200 | 201 | SC_HANDLE manager; 202 | 203 | if (!SCManager(&manager)) 204 | goto EXIT; 205 | 206 | bool first = 1, remv = 0; 207 | LOAD__: 208 | if (watch) { 209 | if (!first && !DeleteDriver(nameP, &manager, 1)) { 210 | cout << "[x] Cannot delete driver.\n"; 211 | goto LOAD_EXIT; 212 | } 213 | copy( 214 | driverP, 215 | driver, 216 | copy_options::overwrite_existing 217 | ); 218 | system("cls"); 219 | first = 0; 220 | } 221 | 222 | if (LoadDriver( 223 | driver, 224 | nameP, 225 | nameP, 226 | 0, 227 | overwrite 228 | )) 229 | cout << format("[+] {} driver loaded successfully.\n", name); 230 | else 231 | cout << format("[x] Failed to load driver {}\n", name); 232 | 233 | if (watch) { 234 | WATCH_H: 235 | cout << format( 236 | "\n" 237 | "[*] Press the 'R' key to reload the driver.\n" 238 | " Press the 'S' key to print the service status.\n" 239 | " Press the 'Q' key to exit the loop.\n" 240 | " Press the 'X' key to delete the driver and exit the loop.\n" 241 | "\n{}: ", 242 | NowTime() 243 | ); 244 | 245 | int ch = toupper(_getch()); 246 | cout << "\n"; 247 | 248 | if (ch == 'R') 249 | goto LOAD__; 250 | if (ch == 'S') { 251 | system("cls"); 252 | PrintStatus(nameP, &manager); 253 | goto WATCH_H; 254 | } 255 | if (ch == 'Q') { 256 | cout << "[*] Exit!\n"; 257 | goto LOAD_EXIT; 258 | } 259 | if (ch == 'X') { 260 | if (remv = DeleteDriver( 261 | path(name) 262 | )) 263 | cout << "[+] Driver uninstalled successfully.\n"; 264 | 265 | goto LOAD_EXIT; 266 | } 267 | 268 | system("cls"); 269 | cout << "[-] Wrong command key\n"; 270 | goto WATCH_H; 271 | } 272 | 273 | LOAD_EXIT: 274 | CloseServiceHandle(manager); 275 | 276 | if ( 277 | watch && 278 | remv && 279 | exists(driver) && 280 | !is_directory(driver) 281 | ) 282 | remove(driver); 283 | 284 | if (ignore_signatures) { 285 | cout << "[*] Uninstall services that ignore signatures of kernel drivers.\n"; 286 | UseWind64("/u"); 287 | } 288 | 289 | remove_all(tmpdir); 290 | } else if ( 291 | (argi = FindArgs("-u")) != -1 || 292 | (argi = FindArgs("--unload")) != -1 293 | ) { 294 | // unload 295 | auto name = GetValue(argi); 296 | 297 | if (!name) { 298 | MISPARM(name); 299 | } 300 | 301 | if (DeleteDriver( 302 | path(name) 303 | )) 304 | cout << "[+] Driver uninstalled successfully.\n"; 305 | } else if (!acok) 306 | goto SHOW_USAGE; 307 | 308 | EXIT: 309 | return 0; 310 | } 311 | --------------------------------------------------------------------------------