├── README.md
├── client
├── Loader.sln
└── Loader
│ ├── Loader.vcxproj
│ ├── Loader.vcxproj.filters
│ ├── Loader.vcxproj.user
│ ├── headers
│ └── globals.hpp
│ ├── libs
│ └── th32.lib
│ ├── main.cpp
│ ├── main.hpp
│ ├── protection
│ ├── AntiDebug
│ │ ├── AntiDebug.cpp
│ │ └── AntiDebug.hpp
│ ├── ErasePEHeaders.hpp
│ └── LazyImporter.hpp
│ └── utils
│ ├── Helpers
│ ├── io.cpp
│ ├── io.h
│ ├── util.cpp
│ └── util.h
│ ├── advanced-utils
│ ├── advanced_utils.cpp
│ └── advanced_utils.hpp
│ ├── encrypt-decrypt
│ └── xorstr.hpp
│ ├── inject
│ ├── Helpers
│ │ ├── GetProcId.cpp
│ │ └── GetProcId.hpp
│ ├── inject.cpp
│ └── inject.hpp
│ ├── lazy-importer
│ └── lazy_importer.hpp
│ └── webclient
│ ├── webclient.cpp
│ └── webclient.hpp
└── server
├── client
├── .htaccess
├── client.php
├── config.php
└── download.php
├── loader.php
└── pastaware.sql
/README.md:
--------------------------------------------------------------------------------
1 | # CS:GO Loader with XenForo Authorization
2 | - LoadLibraryA Injector
3 | - Basic Anti Debugger
4 | - XenForo Authorization
5 | - HWID Checks
6 |
7 | ## Protection
8 | - AntiDebug
9 | - ErasePEheaders
10 | - String encryptor: xorstr
11 |
12 | ## Client side setup
13 | Compile - Release x86
14 | Settings - headers/globals.hpp
15 |
16 | ## Server side setup
17 | Setup and sync config.php with globals.hpp
18 | Upload the dll in your client folder (yes, it is confusing, there is a folder called "client" on server)
19 | Setup mysql connection in loader.php file
20 | > $sql = mysqli_connect("host", "name", "pass", "database")
21 |
--------------------------------------------------------------------------------
/client/Loader.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 16
4 | VisualStudioVersion = 16.0.30907.101
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Loader", "Loader\Loader.vcxproj", "{FB66BA86-5F04-4D62-8800-BEBF49CD5FBB}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Debug|x64 = Debug|x64
12 | Debug|x86 = Debug|x86
13 | Release|Any CPU = Release|Any CPU
14 | Release|x64 = Release|x64
15 | Release|x86 = Release|x86
16 | EndGlobalSection
17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
18 | {FB66BA86-5F04-4D62-8800-BEBF49CD5FBB}.Debug|Any CPU.ActiveCfg = Debug|Win32
19 | {FB66BA86-5F04-4D62-8800-BEBF49CD5FBB}.Debug|x64.ActiveCfg = Debug|x64
20 | {FB66BA86-5F04-4D62-8800-BEBF49CD5FBB}.Debug|x64.Build.0 = Debug|x64
21 | {FB66BA86-5F04-4D62-8800-BEBF49CD5FBB}.Debug|x86.ActiveCfg = Debug|Win32
22 | {FB66BA86-5F04-4D62-8800-BEBF49CD5FBB}.Debug|x86.Build.0 = Debug|Win32
23 | {FB66BA86-5F04-4D62-8800-BEBF49CD5FBB}.Release|Any CPU.ActiveCfg = Release|Win32
24 | {FB66BA86-5F04-4D62-8800-BEBF49CD5FBB}.Release|x64.ActiveCfg = Release|x64
25 | {FB66BA86-5F04-4D62-8800-BEBF49CD5FBB}.Release|x64.Build.0 = Release|x64
26 | {FB66BA86-5F04-4D62-8800-BEBF49CD5FBB}.Release|x86.ActiveCfg = Release|Win32
27 | {FB66BA86-5F04-4D62-8800-BEBF49CD5FBB}.Release|x86.Build.0 = Release|Win32
28 | EndGlobalSection
29 | GlobalSection(SolutionProperties) = preSolution
30 | HideSolutionNode = FALSE
31 | EndGlobalSection
32 | GlobalSection(ExtensibilityGlobals) = postSolution
33 | SolutionGuid = {F1B350F1-C92F-43AD-8487-62A5CCC7F4F5}
34 | EndGlobalSection
35 | EndGlobal
36 |
--------------------------------------------------------------------------------
/client/Loader/Loader.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 | {fb66ba86-5f04-4d62-8800-bebf49cd5fbb}
25 | Loader
26 | 10.0.18362.0
27 |
28 |
29 |
30 | Application
31 | true
32 | v142
33 | Unicode
34 |
35 |
36 | Application
37 | false
38 | v142
39 | true
40 | MultiByte
41 |
42 |
43 | Application
44 | true
45 | v142
46 | Unicode
47 | true
48 |
49 |
50 | Application
51 | false
52 | v142
53 | true
54 | Unicode
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 | true
76 |
77 |
78 | false
79 | $(ProjectDir)libs;$(LibraryPath)
80 | $(SolutionDir)exe\
81 | $(ProjectDir)\bin\
82 |
83 |
84 | true
85 | $(SolutionDir)exe\
86 | $(ProjectDir)\bin\
87 | $(ProjectDir)\ext;$(ProjectDir)\libs;$(LibraryPath)
88 |
89 |
90 | false
91 | $(SolutionDir)exe\
92 | $(ProjectDir)\bin\
93 | $(ProjectDir)\ext;$(ProjectDir)\libs;$(LibraryPath)
94 |
95 |
96 |
97 | Level3
98 | true
99 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
100 | true
101 |
102 |
103 | Console
104 | true
105 |
106 |
107 |
108 |
109 | Level3
110 | true
111 | true
112 | true
113 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
114 | true
115 | stdcpp17
116 |
117 |
118 | Console
119 | true
120 | true
121 | true
122 | RequireAdministrator
123 |
124 |
125 |
126 |
127 | Level3
128 | true
129 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions)
130 | true
131 | stdcpp17
132 | false
133 | ProgramDatabase
134 |
135 |
136 | Console
137 | true
138 |
139 |
140 |
141 |
142 | Level3
143 | true
144 | true
145 | true
146 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
147 | true
148 | stdcpp17
149 | MultiThreaded
150 |
151 |
152 | Console
153 | true
154 | true
155 | true
156 | %(AdditionalDependencies)
157 |
158 |
159 | RequireAdministrator
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
--------------------------------------------------------------------------------
/client/Loader/Loader.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {df954bfc-5695-43d0-bd44-3b1516eb9d64}
6 |
7 |
8 | {f5107e85-2d23-44f0-a43b-6a8df6e04717}
9 |
10 |
11 | {b19797d4-865f-4edb-875b-65bded6e3f30}
12 |
13 |
14 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
15 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx
16 |
17 |
18 | {d847e87e-f83e-436e-ad1e-42b779109db1}
19 |
20 |
21 | {af10716d-cb69-4e11-b242-850fefce2fcc}
22 |
23 |
24 | {9eb2c2aa-e0f4-4464-9bbf-c0f2c4c49add}
25 |
26 |
27 | {101ef8d2-4efd-4f2e-b711-e5ccef78bda4}
28 |
29 |
30 | {6ce94a2c-d7f3-499e-b034-eccb07a01c09}
31 |
32 |
33 | {1a39fb61-d80c-4c86-a563-ae55f6d1e184}
34 |
35 |
36 | {2000f3db-5577-456f-a050-73394f0c7bf7}
37 |
38 |
39 | {cab881bc-461c-4327-948d-59676ce24949}
40 |
41 |
42 |
43 |
44 | utils\advanced-utils
45 |
46 |
47 | src
48 |
49 |
50 | utils\webclient
51 |
52 |
53 | utils\inject
54 |
55 |
56 | utils\inject\Helpers
57 |
58 |
59 | protection\AntiDebug
60 |
61 |
62 |
63 |
64 | headers
65 |
66 |
67 | utils\advanced-utils
68 |
69 |
70 | src
71 |
72 |
73 | utils\lazy-importer
74 |
75 |
76 | utils\webclient
77 |
78 |
79 | utils\inject
80 |
81 |
82 | utils\inject\Helpers
83 |
84 |
85 | src
86 |
87 |
88 | utils\encrypt-decrypt
89 |
90 |
91 | protection
92 |
93 |
94 | protection
95 |
96 |
97 | protection\AntiDebug
98 |
99 |
100 |
101 |
102 | libs
103 |
104 |
105 |
--------------------------------------------------------------------------------
/client/Loader/Loader.vcxproj.user:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/client/Loader/headers/globals.hpp:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include
3 | #include "../utils/advanced-utils/advanced_utils.hpp"
4 |
5 | using namespace utilities;
6 |
7 | namespace Globals
8 | {
9 | static struct
10 | {
11 | std::string server = xorstr_("mysite.com");
12 | std::string forum_dir = xorstr_("/");
13 | std::string secret_key = xorstr_("1234567890");
14 | } server_side;
15 |
16 | static struct
17 | {
18 | std::string version = xorstr_("1.0");
19 | std::string client_key = xorstr_("0987654321");
20 | std::string cheat = xorstr_("Pastaware");
21 | } client_side;
22 | };
--------------------------------------------------------------------------------
/client/Loader/libs/th32.lib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wiresnchains/csgo-xenforo-loader/97249d3372d992c9c5a4b3c2d3a086ee19bd53a3/client/Loader/libs/th32.lib
--------------------------------------------------------------------------------
/client/Loader/main.cpp:
--------------------------------------------------------------------------------
1 | #include "main.hpp"
2 |
3 | using namespace std;
4 |
5 | static string username;
6 | static string password;
7 | static string stop;
8 |
9 | namespace uLoader
10 | {
11 | bool check_version()
12 | {
13 | string server_version = WebClient::DownloadString(xorstr_("https://") + Globals::server_side.server + xorstr_("/client/client.php?key=") + Globals::client_side.client_key + xorstr_("&check_version=1"));
14 | if (server_version == Globals::client_side.version) {
15 | return true;
16 | }
17 | else {
18 | return false;
19 | }
20 | }
21 | void setup_loader()
22 | {
23 | cout << xorstr_("Welcome to ") + Globals::client_side.cheat + xorstr_("\n");
24 | SetConsoleTitleA(utilities::get_random_string(15).c_str());
25 | }
26 | int checkUser()
27 | {
28 | string output = WebClient::DownloadString(xorstr_("https://") + Globals::server_side.server + xorstr_("/") + Globals::server_side.forum_dir + xorstr_("loader.php?username=") + username + xorstr_("&password=") + password + xorstr_("&hwid=") + utilities::get_hwid());
29 | if (output == xorstr_("success")) {
30 | return 1;
31 | }
32 | else if (output == xorstr_("hwid:fail")) {
33 | return 2;
34 | }
35 | else {
36 | return 0;
37 | }
38 | }
39 | void userPanel()
40 | {
41 | system("CLS");
42 | static string inject;
43 | cout << xorstr_("Welcome to Swiftware, ") + username + xorstr_("\n");
44 | cout << xorstr_("Inject cheat? (y/n): ");
45 | cin >> inject;
46 | if (inject == xorstr_("y")) {
47 | if (helpers::GetProcId(xorstr_("csgo.exe")) == 0) {
48 | MessageBox(NULL, xorstr_("Launch csgo before loading cheat!"), Globals::client_side.cheat.c_str(), MB_ICONINFORMATION | MB_DEFBUTTON2);
49 | ErasePEHeaderFromMemory();
50 | return;
51 | }
52 | else {
53 | cout << xorstr_("Injecting...\n");
54 |
55 | uLoaderInjector::inject_cheat();
56 | ErasePEHeaderFromMemory();
57 | return;
58 | }
59 | }
60 | else {
61 | ErasePEHeaderFromMemory();
62 | return;
63 | }
64 | }
65 | void authPanel()
66 | {
67 | cout << xorstr_("Username: ");
68 | cin >> username;
69 | cout << xorstr_("Password: ");
70 | cin >> password;
71 | }
72 | }
73 |
74 | int main()
75 | {
76 | if (protection::check_security() != protection::debug_results::none)
77 | return 0;
78 |
79 | if (!uLoader::check_version()) {
80 | MessageBox(NULL, xorstr_("Please, download new loader version!"), Globals::client_side.cheat.c_str(), MB_ICONINFORMATION | MB_DEFBUTTON2);
81 | ErasePEHeaderFromMemory();
82 | return 0;
83 | }
84 |
85 | uLoader::setup_loader();
86 | uLoader::authPanel();
87 |
88 | if (uLoader::checkUser() == 1) {
89 | uLoader::userPanel();
90 | }
91 | if (uLoader::checkUser() == 2) {
92 | MessageBox(NULL, xorstr_("HWID Error"), Globals::client_side.cheat.c_str(), MB_ICONERROR | MB_DEFBUTTON2);
93 | ErasePEHeaderFromMemory();
94 | return 0;
95 | }
96 | else {
97 | ErasePEHeaderFromMemory();
98 | return 0;
99 | }
100 | }
--------------------------------------------------------------------------------
/client/Loader/main.hpp:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #define _CRT_SECURE_NO_WARNINGS
3 | #include
4 | #include "headers/globals.hpp"
5 | #include "utils/webclient/webclient.hpp"
6 | #include "utils/encrypt-decrypt/xorstr.hpp"
7 | #include "utils/inject/Helpers/GetProcId.hpp"
8 | #include "utils/inject/inject.hpp"
9 | #include "protection/ErasePEHeaders.hpp"
10 | #include "protection/AntiDebug/AntiDebug.hpp"
11 |
12 | namespace uLoader
13 | {
14 | extern bool check_version();
15 | extern void setup_loader();
16 | extern int checkUser();
17 | extern void userPanel();
18 | extern void authPanel();
19 | }
--------------------------------------------------------------------------------
/client/Loader/protection/AntiDebug/AntiDebug.cpp:
--------------------------------------------------------------------------------
1 | #include "AntiDebug.hpp"
2 |
3 | BOOL IsProcessRunning(DWORD pid)
4 | {
5 | HANDLE process = OpenProcess(SYNCHRONIZE, FALSE, pid);
6 | DWORD ret = WaitForSingleObject(process, 0);
7 | CloseHandle(process);
8 | return ret == WAIT_TIMEOUT;
9 | }
10 |
11 | bool found = true;
12 |
13 | namespace protection {
14 | int check_process()
15 | {
16 | DWORD ida = helpers::GetProcId("ida.exe");
17 | DWORD ida64 = helpers::GetProcId("ida64.exe");
18 | DWORD ida32 = helpers::GetProcId("ida32.exe");
19 | DWORD ollydbg = helpers::GetProcId("ollydbg.exe");
20 | DWORD ollydbg64 = helpers::GetProcId("ollydbg64.exe");
21 | DWORD loaddll = helpers::GetProcId("loaddll.exe");
22 | DWORD httpdebugger = helpers::GetProcId("httpdebugger.exe");
23 | DWORD windowrenamer = helpers::GetProcId("windowrenamer.exe");
24 | DWORD processhacker = helpers::GetProcId("processhacker.exe");
25 | DWORD processhacker2 = helpers::GetProcId("Process Hacker.exe");
26 | DWORD processhacker3 = helpers::GetProcId("ProcessHacker.exe");
27 | DWORD HxD = helpers::GetProcId("HxD.exe");
28 | DWORD parsecd = helpers::GetProcId("parsecd.exe");
29 | DWORD dnSpy = helpers::GetProcId("dnSpy.exe");
30 |
31 | if (IsProcessRunning(ida) || IsProcessRunning(ida64) || IsProcessRunning(ida32) || IsProcessRunning(ollydbg) || IsProcessRunning(ollydbg64)
32 | || IsProcessRunning(loaddll) || IsProcessRunning(httpdebugger) || IsProcessRunning(windowrenamer) || IsProcessRunning(windowrenamer)
33 | || IsProcessRunning(processhacker) || IsProcessRunning(processhacker2) || IsProcessRunning(processhacker3) || IsProcessRunning(HxD)
34 | || IsProcessRunning(parsecd) || IsProcessRunning(dnSpy)) {
35 | return debug_results::being_debugged_peb;
36 | }
37 | else {
38 | return debug_results::none;
39 | }
40 | }
41 |
42 | int __cdecl vm_handler(EXCEPTION_RECORD* p_rec, void* est, unsigned char* p_context, void* disp)
43 | {
44 | found = true;
45 | (*(unsigned long*)(p_context + 0xB8)) += 4;
46 | return ExceptionContinueExecution;
47 | }
48 |
49 | void to_lower(unsigned char* input)
50 | {
51 | char* p = (char*)input;
52 | unsigned long length = strlen(p);
53 | for (unsigned long i = 0; i < length; i++) p[i] = tolower(p[i]);
54 | }
55 |
56 | const wchar_t* get_string(int index) {
57 | std::string value = "";
58 |
59 | switch (index) {
60 | case 0: value = xorstr_("Qt5QWindowIcon"); break;
61 | case 1: value = xorstr_("OLLYDBG"); break;
62 | case 2: value = xorstr_("SunAwtFrame"); break;
63 | case 3: value = xorstr_("ID"); break;
64 | case 4: value = xorstr_("ntdll.dll"); break;
65 | case 5: value = xorstr_("antidbg"); break;
66 | case 6: value = xorstr_("%random_environment_var_name_that_doesnt_exist?[]<>@\\;*!-{}#:/~%"); break;
67 | case 7: value = xorstr_("%random_file_name_that_doesnt_exist?[]<>@\\;*!-{}#:/~%"); break;
68 | }
69 |
70 | return std::wstring(value.begin(), value.end()).c_str();
71 | }
72 |
73 | int memory::being_debugged_peb() {
74 | BOOL found = FALSE;
75 | _asm
76 | {
77 | xor eax, eax; //clear the eax register
78 | mov eax, fs: [0x30] ; //reference start of the process environment block
79 | mov eax, [eax + 0x02]; //beingdebugged is stored in peb + 2
80 | and eax, 0x000000FF; //reference one byte
81 | mov found, eax; //copy value to found
82 | }
83 |
84 | return (found) ? debug_results::being_debugged_peb : debug_results::none;
85 | }
86 |
87 | int memory::remote_debugger_present() {
88 | //declare variables to hold the process handle & bool to check if it was found
89 | HANDLE h_process = INVALID_HANDLE_VALUE;
90 | BOOL found = FALSE;
91 |
92 | //set the process handle to the current process
93 | h_process = GetCurrentProcess();
94 | //check if a remote debugger is present
95 | CheckRemoteDebuggerPresent(h_process, &found);
96 |
97 | //if found is true, we return the right code.
98 | return (found) ? debug_results::remote_debugger_present : debug_results::none;
99 | }
100 |
101 | int memory::check_window_name() {
102 | const wchar_t* names[4] = { get_string(0), get_string(1), get_string(2), get_string(3) };
103 |
104 | for (const wchar_t* name : names) {
105 | if (FindWindow((LPCSTR)name, 0)) { return debug_results::find_window; }
106 | }
107 |
108 | return debug_results::none;
109 | }
110 |
111 | int memory::is_debugger_present() {
112 | //if debugger is found, we return the right code.
113 | return (IsDebuggerPresent()) ? debug_results::debugger_is_present : debug_results::none;
114 | }
115 |
116 | int memory::nt_global_flag_peb() {
117 | //bool to indicate find status
118 | BOOL found = FALSE;
119 | _asm
120 | {
121 | xor eax, eax; //clear the eax register
122 | mov eax, fs: [0x30] ; //reference start of the peb
123 | mov eax, [eax + 0x68]; //peb+0x68 points to NtGlobalFlags
124 | and eax, 0x00000070; //check three flags
125 | mov found, eax; //copy value to found
126 | }
127 |
128 | //if found is true, we return the right code.
129 | return (found) ? debug_results::being_debugged_peb : debug_results::none;
130 | }
131 |
132 | int memory::nt_query_information_process() {
133 | HANDLE h_process = INVALID_HANDLE_VALUE;
134 | DWORD found = FALSE;
135 | DWORD process_debug_port = 0x07; //first method, check msdn for details
136 | DWORD process_debug_flags = 0x1F; //second method, check msdn for details
137 |
138 | //get a handle to ntdll.dll so we can use NtQueryInformationProcess
139 | HMODULE h_ntdll = LoadLibraryW(get_string(4));
140 |
141 | //if we cant get the handle for some reason, we return none
142 | if (h_ntdll == INVALID_HANDLE_VALUE || h_ntdll == NULL) { return debug_results::none; }
143 |
144 | //dynamically acquire the address of NtQueryInformationProcess
145 | _NtQueryInformationProcess NtQueryInformationProcess = NULL;
146 | NtQueryInformationProcess = (_NtQueryInformationProcess)GetProcAddress(h_ntdll, xorstr_("NtQueryInformationProcess"));
147 |
148 | //if we cant get access for some reason, we return none
149 | if (NtQueryInformationProcess == NULL) { return debug_results::none; }
150 |
151 | //method 1: query ProcessDebugPort
152 | h_process = GetCurrentProcess();
153 | NTSTATUS status = NtQueryInformationProcess(h_process, ProcessDebugPort, &found, sizeof(DWORD), NULL);
154 |
155 | //found something
156 | if (!status && found) { return debug_results::nt_query_information_process; }
157 |
158 | //method 2: query ProcessDebugFlags
159 | status = NtQueryInformationProcess(h_process, process_debug_flags, &found, sizeof(DWORD), NULL);
160 |
161 | //the ProcessDebugFlags set found to 1 if no debugger is found, so we check !found.
162 | if (!status && !found) { return debug_results::nt_query_information_process; }
163 |
164 | return debug_results::none;
165 | }
166 |
167 | int memory::nt_set_information_thread() {
168 | DWORD thread_hide_from_debugger = 0x11;
169 |
170 | //get a handle to ntdll.dll so we can use NtQueryInformationProcess
171 | HMODULE h_ntdll = LoadLibraryW(get_string(4));
172 |
173 | //if we cant get the handle for some reason, we return none
174 | if (h_ntdll == INVALID_HANDLE_VALUE || h_ntdll == NULL) { return debug_results::none; }
175 |
176 | //dynamically acquire the address of NtQueryInformationProcess
177 | _NtQueryInformationProcess NtQueryInformationProcess = NULL;
178 | NtQueryInformationProcess = (_NtQueryInformationProcess)GetProcAddress(h_ntdll, xorstr_("NtQueryInformationProcess"));
179 |
180 | //if we cant get access for some reason, we return none
181 | if (NtQueryInformationProcess == NULL) { return debug_results::none; }
182 |
183 | //make call to deattach a debugger :moyai:
184 | (_NtSetInformationThread)(GetCurrentThread(), thread_hide_from_debugger, 0, 0, 0);
185 |
186 | return debug_results::none;
187 | }
188 |
189 | int memory::debug_active_process() {
190 | BOOL found = FALSE;
191 | STARTUPINFOA si = { 0 };
192 | PROCESS_INFORMATION pi = { 0 };
193 | si.cb = sizeof(si);
194 | TCHAR sz_path[MAX_PATH];
195 | DWORD exit_code = 0;
196 |
197 | DWORD proc_id = GetCurrentProcessId();
198 | std::stringstream stream;
199 | stream << proc_id;
200 | std::string args = stream.str();
201 |
202 | const char* cp_id = args.c_str();
203 | CreateMutex(NULL, FALSE, (LPCSTR)get_string(5));
204 | if (GetLastError() != ERROR_SUCCESS)
205 | {
206 | //if we get here, we're in the child process
207 | if (DebugActiveProcess((DWORD)atoi(cp_id)))
208 | {
209 | //no debugger found
210 | return debug_results::none;
211 | }
212 | else
213 | {
214 | //debugger found, exit child with unique code that we can check for
215 | exit(555);
216 | }
217 | }
218 |
219 | //parent process
220 | DWORD pid = GetCurrentProcessId();
221 | GetModuleFileName(NULL, sz_path, MAX_PATH);
222 |
223 | char cmdline[MAX_PATH + 1 + sizeof(int)];
224 | snprintf(cmdline, sizeof(cmdline), xorstr_("%ws %d"), sz_path, pid);
225 |
226 | //start child process
227 | BOOL success = CreateProcessA(
228 | NULL, //path (NULL means use cmdline instead)
229 | cmdline, //command line
230 | NULL, //process handle not inheritable
231 | NULL, //thread handle not inheritable
232 | FALSE, //set handle inheritance to FALSE
233 | 0, //no creation flags
234 | NULL, //use parent's environment block
235 | NULL, //use parent's starting directory
236 | &si, //pointer to STARTUPINFO structure
237 | &pi); //pointer to PROCESS_INFORMATION structure
238 |
239 | //wait until child process exits and get the code
240 | WaitForSingleObject(pi.hProcess, INFINITE);
241 |
242 | //check for our unique exit code
243 | if (GetExitCodeProcess(pi.hProcess, &exit_code) == 555) { found = TRUE; }
244 |
245 | // Close process and thread handles.
246 | CloseHandle(pi.hProcess);
247 | CloseHandle(pi.hThread);
248 | //if found is true, we return the right code.
249 | return (found) ? debug_results::being_debugged_peb : debug_results::none;
250 | }
251 |
252 | int memory::write_buffer() {
253 | //first option
254 |
255 | //vars to store the amount of accesses to the buffer and the granularity for GetWriteWatch()
256 | ULONG_PTR hits;
257 | DWORD granularity;
258 |
259 | PVOID* addresses = static_cast(VirtualAlloc(NULL, 4096 * sizeof(PVOID), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE));
260 | if (addresses == NULL) {
261 | return debug_results::write_buffer;
262 | }
263 |
264 | int* buffer = static_cast(VirtualAlloc(NULL, 4096 * 4096, MEM_RESERVE | MEM_COMMIT | MEM_WRITE_WATCH, PAGE_READWRITE));
265 | if (buffer == NULL) {
266 | VirtualFree(addresses, 0, MEM_RELEASE);
267 | return debug_results::write_buffer;
268 | }
269 |
270 | //read the buffer once
271 | buffer[0] = 1234;
272 |
273 | hits = 4096;
274 | if (GetWriteWatch(0, buffer, 4096, addresses, &hits, &granularity) != 0) { return debug_results::write_buffer; }
275 | else
276 | {
277 | //free the memory again
278 | VirtualFree(addresses, 0, MEM_RELEASE);
279 | VirtualFree(buffer, 0, MEM_RELEASE);
280 |
281 | //we should have 1 hit if everything is fine
282 | return (hits == 1) ? debug_results::none : debug_results::write_buffer;
283 | }
284 |
285 | //second option
286 |
287 | BOOL result = FALSE, error = FALSE;
288 |
289 | addresses = static_cast(VirtualAlloc(NULL, 4096 * sizeof(PVOID), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE));
290 | if (addresses == NULL) { return debug_results::write_buffer; }
291 |
292 | buffer = static_cast(VirtualAlloc(NULL, 4096 * 4096, MEM_RESERVE | MEM_COMMIT | MEM_WRITE_WATCH, PAGE_READWRITE));
293 | if (buffer == NULL) {
294 | VirtualFree(addresses, 0, MEM_RELEASE);
295 | return debug_results::write_buffer;
296 | }
297 |
298 | //make some calls where a buffer *can* be written to, but isn't actually edited because we pass invalid parameters
299 | if (GlobalGetAtomName(INVALID_ATOM, (LPTSTR)buffer, 1) != FALSE || GetEnvironmentVariable((LPSTR)get_string(6), (LPSTR)buffer, 4096 * 4096) != FALSE || GetBinaryType((LPSTR)get_string(7), (LPDWORD)buffer) != FALSE
300 | || HeapQueryInformation(0, (HEAP_INFORMATION_CLASS)69, buffer, 4096, NULL) != FALSE || ReadProcessMemory(INVALID_HANDLE_VALUE, (LPCVOID)0x69696969, buffer, 4096, NULL) != FALSE
301 | || GetThreadContext(INVALID_HANDLE_VALUE, (LPCONTEXT)buffer) != FALSE || GetWriteWatch(0, &memory::write_buffer, 0, NULL, NULL, (PULONG)buffer) == 0) {
302 | result = false;
303 | error = true;
304 | }
305 |
306 | if (error == FALSE)
307 | {
308 | //all calles failed as they're supposed to
309 | hits = 4096;
310 | if (GetWriteWatch(0, buffer, 4096, addresses, &hits, &granularity) != 0)
311 | {
312 | result = FALSE;
313 | }
314 | else
315 | {
316 | //should have zero reads here because GlobalGetAtomName doesn't probe the buffer until other checks have succeeded
317 | //if there's an API hook or debugger in here it'll probably try to probe the buffer, which will be caught here
318 | result = hits != 0;
319 | }
320 | }
321 |
322 | VirtualFree(addresses, 0, MEM_RELEASE);
323 | VirtualFree(buffer, 0, MEM_RELEASE);
324 |
325 | return result;
326 | }
327 |
328 | int exceptions::close_handle_exception() {
329 | //invalid handle
330 | HANDLE h_invalid = (HANDLE)0xDEADBEEF;
331 |
332 | __try
333 | {
334 | CloseHandle(h_invalid);
335 | }
336 | __except (EXCEPTION_EXECUTE_HANDLER)
337 | {
338 | //if we get the exception, we return the right code.
339 | return debug_results::close_handle_exception;
340 | }
341 |
342 | return debug_results::none;
343 | }
344 |
345 | int exceptions::single_step_exception() {
346 | BOOL debugger_present = TRUE;
347 | __try
348 | {
349 | __asm
350 | {
351 | pushfd //save flag register
352 | or dword ptr[esp], 0x100 //set trap flag in EFlags
353 | popfd //restore flag register
354 | nop //does nothing
355 | }
356 | }
357 | __except (EXCEPTION_EXECUTE_HANDLER) { debugger_present = FALSE; }
358 |
359 | //if the exception was raised, return none
360 | //if a debugger handled the exception (no exception for us to handle), return detection
361 | return (debugger_present) ? debug_results::single_step : debug_results::none;
362 | }
363 |
364 | int exceptions::int_3() {
365 | __try
366 | {
367 | _asm
368 | {
369 | int 3; //0xCC / standard software breakpoint
370 | }
371 | }
372 | //exception is handled by our app = debugger did not attempt to intervene
373 | __except (EXCEPTION_EXECUTE_HANDLER) { return debug_results::none; }
374 |
375 | //if we don't get the exception, we return the right code.
376 | return debug_results::int_3_cc;
377 | }
378 |
379 | int exceptions::int_2d() {
380 | BOOL found = false;
381 | __try
382 | {
383 | _asm
384 | {
385 | int 0x2D; //kernel breakpoint
386 | }
387 | }
388 |
389 | __except (EXCEPTION_EXECUTE_HANDLER) { return debug_results::none; }
390 |
391 | __try
392 | {
393 | __asm
394 | {
395 | xor eax, eax; //clear the eax register
396 | int 2dh; //try to get the debugger to bypass the instruction
397 | inc eax; //set the eax register to 1
398 | mov found, eax;
399 | }
400 | }
401 |
402 | __except (EXCEPTION_EXECUTE_HANDLER) { return debug_results::none; }
403 |
404 | //if we don't get the exception, we return the right code.
405 | return debug_results::int_2;
406 | }
407 |
408 | int exceptions::prefix_hop() {
409 | __try
410 | {
411 | _asm
412 | {
413 | __emit 0xF3; //0xF3 0x64 is the prefix rep
414 | __emit 0x64;
415 | __emit 0xCC; //this gets skipped over if being debugged (read exceptions::int_3())
416 | }
417 | }
418 |
419 | __except (EXCEPTION_EXECUTE_HANDLER) { return debug_results::none; }
420 |
421 | //if we don't get the exception, we return the right code.
422 | return debug_results::prefix_hop;
423 | }
424 |
425 | /*int exceptions::debug_string() {
426 | SetLastError(0);
427 | OutputDebugStringA(xorstr_("anti-debugging test."));
428 |
429 | return (GetLastError() != 0) ? debug_results::debug_string : debug_results::none;
430 | }*/
431 |
432 | /*int timing::rdtsc() {
433 | //integers for time values
434 | UINT64 time_a, time_b = 0;
435 | int time_upper_a, time_lower_a = 0;
436 | int time_upper_b, time_lower_b = 0;
437 |
438 | _asm
439 | {
440 | //rdtsc stores result across EDX:EAX
441 | rdtsc;
442 | mov time_upper_a, edx;
443 | mov time_lower_a, eax;
444 |
445 | //junk code -> skip through breakpoint
446 | xor eax, eax;
447 | mov eax, 5;
448 | shr eax, 2;
449 | sub eax, ebx;
450 | cmp eax, ecx
451 |
452 | rdtsc;
453 | mov time_upper_b, edx;
454 | mov time_lower_b, eax;
455 | }
456 |
457 | time_a = time_upper_a;
458 | time_a = (time_a << 32) | time_lower_a;
459 |
460 | time_b = time_upper_b;
461 | time_b = (time_b << 32) | time_lower_b;
462 |
463 | //0x10000 is purely empirical and is based on the computer's clock cycle, could be less if the cpu clocks really fast etc.
464 | //should change depending on the length and complexity of the code between each rdtsc operation (-> asm code inbetween needs longer to execute but takes A LOT longer if its being debugged / someone is stepping through it)
465 | return (time_b - time_a > 0x10000) ? debug_results::rdtsc : debug_results::none;
466 | }
467 |
468 | int timing::query_performance_counter() {
469 | LARGE_INTEGER t1;
470 | LARGE_INTEGER t2;
471 |
472 | QueryPerformanceCounter(&t1);
473 |
474 | //junk code
475 | _asm
476 | {
477 | xor eax, eax;
478 | push eax;
479 | push ecx;
480 | pop eax;
481 | pop ecx;
482 | sub ecx, eax;
483 | shl ecx, 4;
484 | }
485 |
486 | QueryPerformanceCounter(&t2);
487 |
488 | //30 is a random value
489 | return ((t2.QuadPart - t1.QuadPart) > 30) ? debug_results::query_performance_counter : debug_results::none;
490 | }*/
491 |
492 | int timing::get_tick_count() {
493 | DWORD t1;
494 | DWORD t2;
495 |
496 | t1 = GetTickCount64();
497 |
498 | //junk code to keep the cpu busy for a few cycles so that time passes and the return value of GetTickCount() changes (so we can detect if it runs at "normal" speed or is being checked through by a human)
499 | _asm
500 | {
501 | xor eax, eax;
502 | push eax;
503 | push ecx;
504 | pop eax;
505 | pop ecx;
506 | sub ecx, eax;
507 | shl ecx, 4;
508 | }
509 |
510 | t2 = GetTickCount64();
511 |
512 | //30 ms seems ok
513 | return ((t2 - t1) > 30) ? debug_results::query_performance_counter : debug_results::none;
514 | }
515 |
516 | int cpu::hardware_debug_registers() {
517 | CONTEXT ctx = { 0 };
518 | HANDLE h_thread = GetCurrentThread();
519 |
520 | ctx.ContextFlags = CONTEXT_DEBUG_REGISTERS;
521 | if (GetThreadContext(h_thread, &ctx))
522 | {
523 | return ((ctx.Dr0 != 0x00) || (ctx.Dr1 != 0x00) || (ctx.Dr2 != 0x00) || (ctx.Dr3 != 0x00) || (ctx.Dr6 != 0x00) || (ctx.Dr7 != 0x00)) ? debug_results::hardware_debug_registers : debug_results::none;
524 | }
525 |
526 | return debug_results::none;
527 | }
528 |
529 | int cpu::mov_ss() {
530 | BOOL found = FALSE;
531 |
532 | _asm
533 | {
534 | push ss;
535 | pop ss;
536 | pushfd;
537 | test byte ptr[esp + 1], 1;
538 | jne fnd;
539 | jmp end;
540 | fnd:
541 | mov found, 1;
542 | end:
543 | nop;
544 | }
545 |
546 | return (found) ? debug_results::mov_ss : debug_results::none;
547 | }
548 |
549 | int virtualization::check_cpuid() {
550 | bool found = false;
551 | __asm {
552 | xor eax, eax
553 | mov eax, 0x40000000
554 | cpuid
555 | cmp ecx, 0x4D566572
556 | jne nop_instr
557 | cmp edx, 0x65726177
558 | jne nop_instr
559 | mov found, 0x1
560 | nop_instr:
561 | nop
562 | }
563 |
564 | return (found) ? debug_results::check_cpuid : debug_results::none;
565 | }
566 |
567 | int virtualization::check_registry() {
568 | HKEY h_key = 0;
569 | if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, xorstr_("HARDWARE\\ACPI\\DSDT\\VBOX__"), 0, KEY_READ, &h_key) == ERROR_SUCCESS) { return debug_results::check_registry; }
570 |
571 | return debug_results::none;
572 | }
573 |
574 | debug_results check_security() {
575 | if (memory::being_debugged_peb() != debug_results::none) {
576 | return debug_results::being_debugged_peb;
577 | }
578 | if (memory::remote_debugger_present() != debug_results::none) {
579 | return debug_results::remote_debugger_present;
580 | }
581 | if (memory::check_window_name() != debug_results::none) {
582 | return debug_results::find_window;
583 | }
584 | if (memory::is_debugger_present() != debug_results::none) {
585 | return debug_results::debugger_is_present;
586 | }
587 | if (memory::nt_global_flag_peb() != debug_results::none) {
588 | return debug_results::being_debugged_peb;
589 | }
590 | if (memory::nt_query_information_process() != debug_results::none) {
591 | return debug_results::nt_query_information_process;
592 | }
593 | if (memory::debug_active_process() != debug_results::none) {
594 | return debug_results::debug_active_process;
595 | }
596 | if (memory::write_buffer() != debug_results::none) {
597 | return debug_results::write_buffer;
598 | }
599 | if (exceptions::close_handle_exception() != debug_results::none) {
600 | return debug_results::close_handle_exception;
601 | }
602 | if (exceptions::single_step_exception() != debug_results::none) {
603 | return debug_results::single_step;
604 | }
605 | if (exceptions::int_3() != debug_results::none) {
606 | return debug_results::int_3_cc;
607 | }
608 | if (exceptions::int_2d() != debug_results::none) {
609 | return debug_results::int_2;
610 | }
611 | if (exceptions::prefix_hop() != debug_results::none) {
612 | return debug_results::prefix_hop;
613 | }
614 | /*if (exceptions::debug_string() != debug_results::none) {
615 | return debug_results::debug_string;
616 | }
617 | /*if (timing::rdtsc() != debug_results::none) {
618 | return debug_results::rdtsc;
619 | }
620 | if (timing::query_performance_counter() != debug_results::none) {
621 | return debug_results::query_performance_counter;
622 | }*/
623 | if (timing::get_tick_count() != debug_results::none) {
624 | return debug_results::get_tick_count;
625 | }
626 | if (cpu::hardware_debug_registers() != debug_results::none) {
627 | return debug_results::hardware_debug_registers;
628 | }
629 | if (cpu::mov_ss() != debug_results::none) {
630 | return debug_results::mov_ss;
631 | }
632 | if (virtualization::check_cpuid() != debug_results::none) {
633 | return debug_results::check_cpuid;
634 | }
635 | if (virtualization::check_registry() != debug_results::none) {
636 | return debug_results::check_registry;
637 | }
638 | if (check_process() != debug_results::none) {
639 | return debug_results::debug_active_process;
640 | }
641 |
642 | return debug_results::none;
643 | }
644 | }
--------------------------------------------------------------------------------
/client/Loader/protection/AntiDebug/AntiDebug.hpp:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #define _CRT_SECURE_NO_WARNINGS
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 | #pragma warning(disable : 4091)
14 | #pragma warning(disable : 6387)
15 | #pragma warning(disable : 4244)
16 | #pragma warning(disable : 6262)
17 | #pragma warning(disable : 4733)
18 | #pragma warning(disable : 4731)
19 | #include "../../utils/inject/Helpers/GetProcId.hpp"
20 | #include "../../utils/encrypt-decrypt/xorstr.hpp"
21 |
22 | namespace protection {
23 | int check_process();
24 | int __cdecl vm_handler(EXCEPTION_RECORD* p_rec, void* est, unsigned char* p_context, void* disp);
25 | void to_lower(unsigned char* input);
26 | const wchar_t* get_string(int index);
27 | typedef NTSTATUS(__stdcall* _NtQueryInformationProcess)(_In_ HANDLE, _In_ unsigned int, _Out_ PVOID, _In_ ULONG, _Out_ PULONG);
28 | typedef NTSTATUS(__stdcall* _NtSetInformationThread)(_In_ HANDLE, _In_ THREAD_INFORMATION_CLASS, _In_ PVOID, _In_ ULONG);
29 |
30 | extern enum debug_results
31 | {
32 | //nothing was caught, value = 0
33 | none = 0x0000,
34 |
35 | //something caught in memory (0x1000 - 0x1009)
36 | being_debugged_peb = 0x1000,
37 | remote_debugger_present = 0x1001,
38 | debugger_is_present = 0x1002,
39 | dbg_global_flag = 0x1003,
40 | nt_query_information_process = 0x0004,
41 | find_window = 0x1005,
42 | output_debug_string = 0x1006,
43 | nt_set_information_thread = 0x1007,
44 | debug_active_process = 0x1008,
45 | write_buffer = 0x1009,
46 |
47 | //something caught in exceptions (0x2000 - 0x2005)
48 | close_handle_exception = 0x2000,
49 | single_step = 0x2001,
50 | int_3_cc = 0x2002,
51 | int_2 = 0x2003,
52 | prefix_hop = 0x2004,
53 | debug_string = 0x2005,
54 |
55 | //something caught with timings (0x3000 - 0x3002)
56 | rdtsc = 0x3000,
57 | query_performance_counter = 0x3001,
58 | get_tick_count = 0x3002,
59 |
60 | //something caught in cpu (0x4000 - 0x4001)
61 | hardware_debug_registers = 0x4000,
62 | mov_ss = 0x4001,
63 |
64 | //virtualization (0x5000 - 0x5003)
65 | check_cpuid = 0x5000,
66 | check_registry = 0x5001,
67 | vm = 0x5002,
68 | };
69 |
70 | namespace memory {
71 | int being_debugged_peb();
72 | int remote_debugger_present();
73 | int check_window_name();
74 | int is_debugger_present();
75 | int nt_global_flag_peb();
76 | int nt_query_information_process();
77 | int nt_set_information_thread();
78 | int debug_active_process();
79 | int write_buffer();
80 | }
81 |
82 | namespace exceptions {
83 | int close_handle_exception();
84 | int single_step_exception();
85 | int int_3();
86 | int int_2d();
87 | int prefix_hop();
88 | int debug_string();
89 | }
90 |
91 | namespace timing {
92 | int rdtsc();
93 | int query_performance_counter();
94 | int get_tick_count();
95 | }
96 |
97 | namespace cpu {
98 | int hardware_debug_registers();
99 | int mov_ss();
100 | }
101 |
102 | namespace virtualization {
103 | int check_cpuid();
104 | int check_registry();
105 | }
106 |
107 | debug_results check_security();
108 | }
--------------------------------------------------------------------------------
/client/Loader/protection/ErasePEHeaders.hpp:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include
3 | #include
4 |
5 | VOID ErasePEHeaderFromMemory()
6 | {
7 | DWORD OldProtect = 0;
8 |
9 | char* pBaseAddr = (char*)GetModuleHandle(NULL);
10 |
11 | VirtualProtect(pBaseAddr, 4096, PAGE_READWRITE, &OldProtect);
12 |
13 | SecureZeroMemory(pBaseAddr, 4096);
14 | }
--------------------------------------------------------------------------------
/client/Loader/protection/LazyImporter.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Justas Masiulis
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | // documentation is available at https://github.com/JustasMasiulis/lazy_importer
18 |
19 | #ifndef LAZY_IMPORTER_HPP
20 | #define LAZY_IMPORTER_HPP
21 |
22 | #define LI_FN(name) \
23 | ::li::detail::lazy_function<::li::detail::khash(#name), decltype(&name)>()
24 |
25 | #define LI_FN_DEF(name) ::li::detail::lazy_function<::li::detail::khash(#name), name>()
26 |
27 | #define LI_MODULE(name) ::li::detail::lazy_module<::li::detail::khash(name)>()
28 |
29 | // NOTE only std::forward is used from this header.
30 | // If there is a need to eliminate this dependency the function itself is very small.
31 | #include
32 | #include
33 | #include
34 |
35 | #ifndef LAZY_IMPORTER_NO_FORCEINLINE
36 | #if defined(_MSC_VER)
37 | #define LAZY_IMPORTER_FORCEINLINE __forceinline
38 | #elif defined(__GNUC__) && __GNUC__ > 3
39 | #define LAZY_IMPORTER_FORCEINLINE inline __attribute__((__always_inline__))
40 | #else
41 | #define LAZY_IMPORTER_FORCEINLINE inline
42 | #endif
43 | #else
44 | #define LAZY_IMPORTER_FORCEINLINE inline
45 | #endif
46 |
47 | #ifdef LAZY_IMPORTER_CASE_INSENSITIVE
48 | #define LAZY_IMPORTER_TOLOWER(c) (c >= 'A' && c <= 'Z' ? (c | (1 << 5)) : c)
49 | #else
50 | #define LAZY_IMPORTER_TOLOWER(c) (c)
51 | #endif
52 |
53 | namespace li {
54 | namespace detail {
55 |
56 | template
57 | struct pair {
58 | First first;
59 | Second second;
60 | };
61 |
62 | namespace win {
63 |
64 | struct LIST_ENTRY_T {
65 | const char* Flink;
66 | const char* Blink;
67 | };
68 |
69 | struct UNICODE_STRING_T {
70 | unsigned short Length;
71 | unsigned short MaximumLength;
72 | wchar_t* Buffer;
73 | };
74 |
75 | struct PEB_LDR_DATA_T {
76 | unsigned long Length;
77 | unsigned long Initialized;
78 | const char* SsHandle;
79 | LIST_ENTRY_T InLoadOrderModuleList;
80 | };
81 |
82 | struct PEB_T {
83 | unsigned char Reserved1[2];
84 | unsigned char BeingDebugged;
85 | unsigned char Reserved2[1];
86 | const char* Reserved3[2];
87 | PEB_LDR_DATA_T* Ldr;
88 | };
89 |
90 | struct LDR_DATA_TABLE_ENTRY_T {
91 | LIST_ENTRY_T InLoadOrderLinks;
92 | LIST_ENTRY_T InMemoryOrderLinks;
93 | LIST_ENTRY_T InInitializationOrderLinks;
94 | const char* DllBase;
95 | const char* EntryPoint;
96 | union {
97 | unsigned long SizeOfImage;
98 | const char* _dummy;
99 | };
100 | UNICODE_STRING_T FullDllName;
101 | UNICODE_STRING_T BaseDllName;
102 |
103 | LAZY_IMPORTER_FORCEINLINE const LDR_DATA_TABLE_ENTRY_T*
104 | load_order_next() const noexcept
105 | {
106 | return reinterpret_cast(
107 | InLoadOrderLinks.Flink);
108 | }
109 | };
110 |
111 | struct IMAGE_DOS_HEADER { // DOS .EXE header
112 | unsigned short e_magic; // Magic number
113 | unsigned short e_cblp; // Bytes on last page of file
114 | unsigned short e_cp; // Pages in file
115 | unsigned short e_crlc; // Relocations
116 | unsigned short e_cparhdr; // Size of header in paragraphs
117 | unsigned short e_minalloc; // Minimum extra paragraphs needed
118 | unsigned short e_maxalloc; // Maximum extra paragraphs needed
119 | unsigned short e_ss; // Initial (relative) SS value
120 | unsigned short e_sp; // Initial SP value
121 | unsigned short e_csum; // Checksum
122 | unsigned short e_ip; // Initial IP value
123 | unsigned short e_cs; // Initial (relative) CS value
124 | unsigned short e_lfarlc; // File address of relocation table
125 | unsigned short e_ovno; // Overlay number
126 | unsigned short e_res[4]; // Reserved words
127 | unsigned short e_oemid; // OEM identifier (for e_oeminfo)
128 | unsigned short e_oeminfo; // OEM information; e_oemid specific
129 | unsigned short e_res2[10]; // Reserved words
130 | long e_lfanew; // File address of new exe header
131 | };
132 |
133 | struct IMAGE_FILE_HEADER {
134 | unsigned short Machine;
135 | unsigned short NumberOfSections;
136 | unsigned long TimeDateStamp;
137 | unsigned long PointerToSymbolTable;
138 | unsigned long NumberOfSymbols;
139 | unsigned short SizeOfOptionalHeader;
140 | unsigned short Characteristics;
141 | };
142 |
143 | struct IMAGE_EXPORT_DIRECTORY {
144 | unsigned long Characteristics;
145 | unsigned long TimeDateStamp;
146 | unsigned short MajorVersion;
147 | unsigned short MinorVersion;
148 | unsigned long Name;
149 | unsigned long Base;
150 | unsigned long NumberOfFunctions;
151 | unsigned long NumberOfNames;
152 | unsigned long AddressOfFunctions; // RVA from base of image
153 | unsigned long AddressOfNames; // RVA from base of image
154 | unsigned long AddressOfNameOrdinals; // RVA from base of image
155 | };
156 |
157 | struct IMAGE_DATA_DIRECTORY {
158 | unsigned long VirtualAddress;
159 | unsigned long Size;
160 | };
161 |
162 | struct IMAGE_OPTIONAL_HEADER64 {
163 | unsigned short Magic;
164 | unsigned char MajorLinkerVersion;
165 | unsigned char MinorLinkerVersion;
166 | unsigned long SizeOfCode;
167 | unsigned long SizeOfInitializedData;
168 | unsigned long SizeOfUninitializedData;
169 | unsigned long AddressOfEntryPoint;
170 | unsigned long BaseOfCode;
171 | unsigned long long ImageBase;
172 | unsigned long SectionAlignment;
173 | unsigned long FileAlignment;
174 | unsigned short MajorOperatingSystemVersion;
175 | unsigned short MinorOperatingSystemVersion;
176 | unsigned short MajorImageVersion;
177 | unsigned short MinorImageVersion;
178 | unsigned short MajorSubsystemVersion;
179 | unsigned short MinorSubsystemVersion;
180 | unsigned long Win32VersionValue;
181 | unsigned long SizeOfImage;
182 | unsigned long SizeOfHeaders;
183 | unsigned long CheckSum;
184 | unsigned short Subsystem;
185 | unsigned short DllCharacteristics;
186 | unsigned long long SizeOfStackReserve;
187 | unsigned long long SizeOfStackCommit;
188 | unsigned long long SizeOfHeapReserve;
189 | unsigned long long SizeOfHeapCommit;
190 | unsigned long LoaderFlags;
191 | unsigned long NumberOfRvaAndSizes;
192 | IMAGE_DATA_DIRECTORY DataDirectory[16];
193 | };
194 |
195 | struct IMAGE_OPTIONAL_HEADER32 {
196 | unsigned short Magic;
197 | unsigned char MajorLinkerVersion;
198 | unsigned char MinorLinkerVersion;
199 | unsigned long SizeOfCode;
200 | unsigned long SizeOfInitializedData;
201 | unsigned long SizeOfUninitializedData;
202 | unsigned long AddressOfEntryPoint;
203 | unsigned long BaseOfCode;
204 | unsigned long BaseOfData;
205 | unsigned long ImageBase;
206 | unsigned long SectionAlignment;
207 | unsigned long FileAlignment;
208 | unsigned short MajorOperatingSystemVersion;
209 | unsigned short MinorOperatingSystemVersion;
210 | unsigned short MajorImageVersion;
211 | unsigned short MinorImageVersion;
212 | unsigned short MajorSubsystemVersion;
213 | unsigned short MinorSubsystemVersion;
214 | unsigned long Win32VersionValue;
215 | unsigned long SizeOfImage;
216 | unsigned long SizeOfHeaders;
217 | unsigned long CheckSum;
218 | unsigned short Subsystem;
219 | unsigned short DllCharacteristics;
220 | unsigned long SizeOfStackReserve;
221 | unsigned long SizeOfStackCommit;
222 | unsigned long SizeOfHeapReserve;
223 | unsigned long SizeOfHeapCommit;
224 | unsigned long LoaderFlags;
225 | unsigned long NumberOfRvaAndSizes;
226 | IMAGE_DATA_DIRECTORY DataDirectory[16];
227 | };
228 |
229 | struct IMAGE_NT_HEADERS {
230 | unsigned long Signature;
231 | IMAGE_FILE_HEADER FileHeader;
232 | #ifdef _WIN64
233 | IMAGE_OPTIONAL_HEADER64 OptionalHeader;
234 | #else
235 | IMAGE_OPTIONAL_HEADER32 OptionalHeader;
236 | #endif
237 | };
238 |
239 | } // namespace win
240 |
241 | // hashing stuff
242 | struct hash_t {
243 | using value_type = unsigned long;
244 | constexpr static value_type offset = 2166136261;
245 | constexpr static value_type prime = 16777619;
246 | constexpr static unsigned long long prime64 = prime;
247 |
248 | LAZY_IMPORTER_FORCEINLINE constexpr static value_type single(value_type value,
249 | char c) noexcept
250 | {
251 | return static_cast(
252 | (value ^ LAZY_IMPORTER_TOLOWER(c)) *
253 | static_cast(prime));
254 | }
255 | };
256 |
257 | template
258 | LAZY_IMPORTER_FORCEINLINE constexpr hash_t::value_type
259 | khash(const CharT * str, hash_t::value_type value = hash_t::offset) noexcept
260 | {
261 | return (*str ? khash(str + 1, hash_t::single(value, *str)) : value);
262 | }
263 |
264 | template
265 | LAZY_IMPORTER_FORCEINLINE hash_t::value_type hash(const CharT * str) noexcept
266 | {
267 | hash_t::value_type value = hash_t::offset;
268 |
269 | for (;;) {
270 | char c = *str++;
271 | if (!c)
272 | return value;
273 | value = hash_t::single(value, c);
274 | }
275 | }
276 |
277 | LAZY_IMPORTER_FORCEINLINE hash_t::value_type hash(
278 | const win::UNICODE_STRING_T& str) noexcept
279 | {
280 | auto first = str.Buffer;
281 | const auto last = first + (str.Length / sizeof(wchar_t));
282 | auto value = hash_t::offset;
283 | for (; first != last; ++first)
284 | value = hash_t::single(value, static_cast(*first));
285 |
286 | return value;
287 | }
288 |
289 | LAZY_IMPORTER_FORCEINLINE pair hash_forwarded(
290 | const char* str) noexcept
291 | {
292 | pair module_and_function{
293 | hash_t::offset, hash_t::offset
294 | };
295 |
296 | for (; *str != '.'; ++str)
297 | hash_t::single(module_and_function.first, *str);
298 |
299 | ++str;
300 |
301 | for (; *str; ++str)
302 | hash_t::single(module_and_function.second, *str);
303 |
304 | return module_and_function;
305 | }
306 |
307 |
308 | // some helper functions
309 | LAZY_IMPORTER_FORCEINLINE const win::PEB_T* peb() noexcept
310 | {
311 | #if defined(_WIN64)
312 | return reinterpret_cast(__readgsqword(0x60));
313 | #elif defined(_WIN32)
314 | return reinterpret_cast(__readfsdword(0x30));
315 | #else
316 | #error Unsupported platform. Open an issue and I'll probably add support.
317 | #endif
318 | }
319 |
320 | LAZY_IMPORTER_FORCEINLINE const win::PEB_LDR_DATA_T* ldr()
321 | {
322 | return reinterpret_cast(peb()->Ldr);
323 | }
324 |
325 | LAZY_IMPORTER_FORCEINLINE const win::IMAGE_NT_HEADERS* nt_headers(
326 | const char* base) noexcept
327 | {
328 | return reinterpret_cast(
329 | base + reinterpret_cast(base)->e_lfanew);
330 | }
331 |
332 | LAZY_IMPORTER_FORCEINLINE const win::IMAGE_EXPORT_DIRECTORY* image_export_dir(
333 | const char* base) noexcept
334 | {
335 | return reinterpret_cast(
336 | base + nt_headers(base)->OptionalHeader.DataDirectory->VirtualAddress);
337 | }
338 |
339 | LAZY_IMPORTER_FORCEINLINE const win::LDR_DATA_TABLE_ENTRY_T* ldr_data_entry() noexcept
340 | {
341 | return reinterpret_cast(
342 | ldr()->InLoadOrderModuleList.Flink);
343 | }
344 |
345 | struct exports_directory {
346 | const char* _base;
347 | const win::IMAGE_EXPORT_DIRECTORY* _ied;
348 | unsigned long _ied_size;
349 |
350 | public:
351 | using size_type = unsigned long;
352 |
353 | LAZY_IMPORTER_FORCEINLINE
354 | exports_directory(const char* base) noexcept : _base(base)
355 | {
356 | const auto ied_data_dir = nt_headers(base)->OptionalHeader.DataDirectory[0];
357 | _ied = reinterpret_cast(
358 | base + ied_data_dir.VirtualAddress);
359 | _ied_size = ied_data_dir.Size;
360 | }
361 |
362 | LAZY_IMPORTER_FORCEINLINE explicit operator bool() const noexcept
363 | {
364 | return reinterpret_cast(_ied) != _base;
365 | }
366 |
367 | LAZY_IMPORTER_FORCEINLINE size_type size() const noexcept
368 | {
369 | return _ied->NumberOfNames;
370 | }
371 |
372 | LAZY_IMPORTER_FORCEINLINE const char* base() const noexcept { return _base; }
373 | LAZY_IMPORTER_FORCEINLINE const win::IMAGE_EXPORT_DIRECTORY* ied() const noexcept
374 | {
375 | return _ied;
376 | }
377 |
378 | LAZY_IMPORTER_FORCEINLINE const char* name(size_type index) const noexcept
379 | {
380 | return reinterpret_cast(
381 | _base + reinterpret_cast(
382 | _base + _ied->AddressOfNames)[index]);
383 | }
384 |
385 | LAZY_IMPORTER_FORCEINLINE const char* address(size_type index) const noexcept
386 | {
387 | const auto* const rva_table =
388 | reinterpret_cast(_base + _ied->AddressOfFunctions);
389 |
390 | const auto* const ord_table = reinterpret_cast(
391 | _base + _ied->AddressOfNameOrdinals);
392 |
393 | return _base + rva_table[ord_table[index]];
394 | }
395 |
396 | LAZY_IMPORTER_FORCEINLINE bool is_forwarded(const char* export_address) const
397 | noexcept
398 | {
399 | const auto ui_ied = reinterpret_cast(_ied);
400 | return (export_address > ui_ied && export_address < ui_ied + _ied_size);
401 | }
402 | };
403 |
404 | struct safe_module_enumerator {
405 | using value_type = const detail::win::LDR_DATA_TABLE_ENTRY_T;
406 | value_type* value;
407 | value_type* const head;
408 |
409 | LAZY_IMPORTER_FORCEINLINE safe_module_enumerator() noexcept
410 | : value(ldr_data_entry()), head(value)
411 | {}
412 |
413 | LAZY_IMPORTER_FORCEINLINE void reset() noexcept { value = head; }
414 |
415 | LAZY_IMPORTER_FORCEINLINE bool next() noexcept
416 | {
417 | value = value->load_order_next();
418 | return value != head && value->DllBase;
419 | }
420 | };
421 |
422 | struct unsafe_module_enumerator {
423 | using value_type = const detail::win::LDR_DATA_TABLE_ENTRY_T*;
424 | value_type value;
425 |
426 | LAZY_IMPORTER_FORCEINLINE unsafe_module_enumerator() noexcept
427 | : value(ldr_data_entry())
428 | {}
429 |
430 | LAZY_IMPORTER_FORCEINLINE void reset() noexcept { value = ldr_data_entry(); }
431 |
432 | LAZY_IMPORTER_FORCEINLINE bool next() noexcept
433 | {
434 | value = value->load_order_next();
435 | return true;
436 | }
437 | };
438 |
439 | // provides the cached functions which use Derive classes methods
440 | template
441 | class lazy_base {
442 | protected:
443 | // This function is needed because every templated function
444 | // with different args has its own static buffer
445 | LAZY_IMPORTER_FORCEINLINE static void*& _cache() noexcept
446 | {
447 | static void* value = nullptr;
448 | return value;
449 | }
450 |
451 | public:
452 | template
453 | LAZY_IMPORTER_FORCEINLINE static T safe() noexcept
454 | {
455 | return Derived::template get();
456 | }
457 |
458 | template
459 | LAZY_IMPORTER_FORCEINLINE static T cached() noexcept
460 | {
461 | auto& cached = _cache();
462 | if (!cached)
463 | cached = Derived::template get();
464 |
465 | return (T)(cached);
466 | }
467 |
468 | template
469 | LAZY_IMPORTER_FORCEINLINE static T safe_cached() noexcept
470 | {
471 | return cached();
472 | }
473 | };
474 |
475 | template
476 | struct lazy_module : lazy_base> {
477 | template
478 | LAZY_IMPORTER_FORCEINLINE static T get() noexcept
479 | {
480 | Enum e;
481 | do {
482 | if (hash(e.value->BaseDllName) == Hash)
483 | return (T)(e.value->DllBase);
484 | } while (e.next());
485 | return {};
486 | }
487 | };
488 |
489 | template
490 | struct lazy_function : lazy_base, T> {
491 | using base_type = lazy_base, T>;
492 |
493 | template
494 | LAZY_IMPORTER_FORCEINLINE decltype(auto) operator()(Args&& ... args) const
495 | {
496 | #ifndef LAZY_IMPORTER_CACHE_OPERATOR_PARENS
497 | return get()(std::forward(args)...);
498 | #else
499 | return this->cached()(std::forward(args)...);
500 | #endif
501 | }
502 |
503 | template
504 | LAZY_IMPORTER_FORCEINLINE static F get() noexcept
505 | {
506 | // for backwards compatability.
507 | // Before 2.0 it was only possible to resolve forwarded exports when
508 | // this macro was enabled
509 | #ifdef LAZY_IMPORTER_RESOLVE_FORWARDED_EXPORTS
510 | return forwarded();
511 | #else
512 | Enum e;
513 | do {
514 | const exports_directory exports(e.value->DllBase);
515 |
516 | if (exports) {
517 | auto export_index = exports.size();
518 | while (export_index--)
519 | if (hash(exports.name(export_index)) == Hash)
520 | return (F)(exports.address(export_index));
521 | }
522 | } while (e.next());
523 | return {};
524 | #endif
525 | }
526 |
527 | template
528 | LAZY_IMPORTER_FORCEINLINE static F forwarded() noexcept
529 | {
530 | detail::win::UNICODE_STRING_T name;
531 | hash_t::value_type module_hash = 0;
532 | auto function_hash = Hash;
533 |
534 | Enum e;
535 | do {
536 | name = e.value->BaseDllName;
537 | name.Length -= 8; // get rid of .dll extension
538 |
539 | if (!module_hash || hash(name) == module_hash) {
540 | const exports_directory exports(e.value->DllBase);
541 |
542 | if (exports) {
543 | auto export_index = exports.size();
544 | while (export_index--)
545 | if (hash(exports.name(export_index)) == function_hash) {
546 | const auto addr = exports.address(export_index);
547 |
548 | if (exports.is_forwarded(addr)) {
549 | auto hashes = hash_forwarded(
550 | reinterpret_cast(addr));
551 |
552 | function_hash = hashes.second;
553 | module_hash = hashes.first;
554 |
555 | e.reset();
556 | break;
557 | }
558 | return (F)(addr);
559 | }
560 | }
561 | }
562 | } while (e.next());
563 | return {};
564 | }
565 |
566 | template
567 | LAZY_IMPORTER_FORCEINLINE static F forwarded_safe() noexcept
568 | {
569 | return forwarded();
570 | }
571 |
572 | template
573 | LAZY_IMPORTER_FORCEINLINE static F forwarded_cached() noexcept
574 | {
575 | auto& value = base_type::_cache();
576 | if (!value)
577 | value = forwarded();
578 | return (F)(value);
579 | }
580 |
581 | template
582 | LAZY_IMPORTER_FORCEINLINE static F forwarded_safe_cached() noexcept
583 | {
584 | return forwarded_cached();
585 | }
586 |
587 | template
588 | LAZY_IMPORTER_FORCEINLINE static F in(Module m) noexcept
589 | {
590 | if (IsSafe && !m)
591 | return {};
592 |
593 | const exports_directory exports((const char*)(m));
594 | if (IsSafe && !exports)
595 | return {};
596 |
597 | for (unsigned long i{};; ++i) {
598 | if (IsSafe && i == exports.size())
599 | break;
600 |
601 | if (hash(exports.name(i)) == Hash)
602 | return (F)(exports.address(i));
603 | }
604 | return {};
605 | }
606 |
607 | template
608 | LAZY_IMPORTER_FORCEINLINE static F in_safe(Module m) noexcept
609 | {
610 | return in(m);
611 | }
612 |
613 | template
614 | LAZY_IMPORTER_FORCEINLINE static F in_cached(Module m) noexcept
615 | {
616 | auto& value = base_type::_cache();
617 | if (!value)
618 | value = in(m);
619 | return (F)(value);
620 | }
621 |
622 | template
623 | LAZY_IMPORTER_FORCEINLINE static F in_safe_cached(Module m) noexcept
624 | {
625 | return in_cached(m);
626 | }
627 |
628 | template
629 | LAZY_IMPORTER_FORCEINLINE static F nt() noexcept
630 | {
631 | return in(ldr_data_entry()->load_order_next()->DllBase);
632 | }
633 |
634 | template
635 | LAZY_IMPORTER_FORCEINLINE static F nt_safe() noexcept
636 | {
637 | return in_safe(ldr_data_entry()->load_order_next()->DllBase);
638 | }
639 |
640 | template
641 | LAZY_IMPORTER_FORCEINLINE static F nt_cached() noexcept
642 | {
643 | return in_cached(ldr_data_entry()->load_order_next()->DllBase);
644 | }
645 |
646 | template
647 | LAZY_IMPORTER_FORCEINLINE static F nt_safe_cached() noexcept
648 | {
649 | return in_safe_cached(ldr_data_entry()->load_order_next()->DllBase);
650 | }
651 | };
652 |
653 | }
654 | } // namespace li::detail
655 |
656 | #endif // include guard
--------------------------------------------------------------------------------
/client/Loader/utils/Helpers/io.cpp:
--------------------------------------------------------------------------------
1 | #include "../include.h"
2 | #include "io.h"
3 |
4 | bool io::read_file(const std::string_view path, std::vector& out) {
5 | std::ifstream file(path.data(), std::ios::binary);
6 | if (!file.good()) {
7 | log_error("{} isnt valid.", path);
8 | return false;
9 | }
10 |
11 | file.unsetf(std::ios::skipws);
12 |
13 | file.seekg(0, std::ios::end);
14 | const size_t size = file.tellg();
15 | file.seekg(0, std::ios::beg);
16 |
17 | out.resize(size);
18 |
19 | file.read(&out[0], size);
20 |
21 | file.close();
22 |
23 | return true;
24 | }
--------------------------------------------------------------------------------
/client/Loader/utils/Helpers/io.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 |
6 | #include "../client/enc.h"
7 |
8 | namespace io {
9 |
10 | template
11 | void log(const std::string_view str, Args... params) {
12 | #ifndef _REL
13 | static auto handle = GetStdHandle(STD_OUTPUT_HANDLE);
14 | SetConsoleTextAttribute(handle, FOREGROUND_GREEN);
15 | fmt::print("[+] ");
16 | SetConsoleTextAttribute(handle, FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_RED);
17 |
18 | std::string msg{ str };
19 | msg.append("\n");
20 |
21 | fmt::print(msg, std::forward(params)...);
22 | #endif
23 | }
24 |
25 | template
26 | void log_error(const std::string_view str, Args... params) {
27 | #ifndef _REL
28 | static auto handle = GetStdHandle(STD_OUTPUT_HANDLE);
29 | SetConsoleTextAttribute(handle, FOREGROUND_RED);
30 | fmt::print("[!] ");
31 | SetConsoleTextAttribute(handle, FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_RED);
32 |
33 | std::string msg{ str };
34 | msg.append("\n");
35 |
36 | fmt::print(msg, std::forward(params)...);
37 | #endif
38 | }
39 |
40 | bool read_file(const std::string_view path, std::vector& out);
41 | }; // namespace io
--------------------------------------------------------------------------------
/client/Loader/utils/Helpers/util.cpp:
--------------------------------------------------------------------------------
1 | #include "../../include.h"
2 | #include "util.h"
3 | #include "io.h"
4 | #include "syscalls.h"
5 |
6 | std::string util::wide_to_multibyte(const std::wstring& str) {
7 | std::string ret;
8 | size_t str_len;
9 |
10 | // check if not empty str
11 | if (str.empty())
12 | return{};
13 |
14 | // count size
15 | str_len = WideCharToMultiByte(CP_UTF8, 0, &str[0], str.size(), 0, 0, 0, 0);
16 |
17 | // setup return value
18 | ret.resize(str_len);
19 |
20 | // final conversion
21 | WideCharToMultiByte(CP_UTF8, 0, &str[0], str.size(), &ret[0], str_len, 0, 0);
22 |
23 | return ret;
24 | }
25 |
26 | std::wstring util::multibyte_to_wide(const std::string& str) {
27 | size_t size;
28 | std::wstring out;
29 |
30 | // get size
31 | size = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), str.size() + 1, 0, 0);
32 |
33 | out.resize(size);
34 |
35 | // finally convert
36 | MultiByteToWideChar(CP_UTF8, 0, str.c_str(), str.size() + 1, &out[0], size);
37 |
38 | return out;
39 | }
40 |
41 | bool util::close_handle(HANDLE handle) {
42 | static auto nt_close = g_syscalls.get("NtClose");
43 |
44 | auto status = nt_close(handle);
45 | if (!NT_SUCCESS(status)) {
46 | io::log_error("failed to close {}, status {:#X}.", handle, (status & 0xFFFFFFFF));
47 | return false;
48 | }
49 |
50 | return true;
51 | }
52 |
53 |
54 | bool pe::get_all_modules(std::unordered_map& modules) {
55 | modules.clear();
56 |
57 | auto peb = util::peb();
58 | if (!peb) return false;
59 |
60 | if (!peb->Ldr->InMemoryOrderModuleList.Flink) return false;
61 |
62 | auto* list = &peb->Ldr->InMemoryOrderModuleList;
63 |
64 | for (auto i = list->Flink; i != list; i = i->Flink) {
65 | auto entry = CONTAINING_RECORD(i, native::LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks);
66 | if (!entry)
67 | continue;
68 |
69 | auto name = util::wide_to_multibyte(entry->BaseDllName.Buffer);
70 | std::transform(name.begin(), name.end(), name.begin(), ::tolower);
71 |
72 | modules[name] = virtual_image(entry->DllBase);
73 | }
74 |
75 | return !modules.empty();
76 | }
--------------------------------------------------------------------------------
/client/Loader/utils/Helpers/util.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "native.h"
4 |
5 | namespace util {
6 | std::string wide_to_multibyte(const std::wstring& str);
7 | std::wstring multibyte_to_wide(const std::string& str);
8 |
9 | __forceinline native::_PEB* peb() {
10 | return reinterpret_cast(__readgsqword(0x60));
11 | }
12 |
13 | bool close_handle(HANDLE handle);
14 |
15 | }; // namespace util
16 |
17 | #include "../injection/pe.h"
--------------------------------------------------------------------------------
/client/Loader/utils/advanced-utils/advanced_utils.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | ADVANCED UTILITIES LIBRARY BY FLOWXRC
3 | MADE FOR SWIFTWARE
4 | */
5 | #include "advanced_utils.hpp"
6 |
7 | namespace utilities
8 | {
9 | BOOL IsProcessRunning(DWORD pid)
10 | {
11 | HANDLE process = OpenProcess(SYNCHRONIZE, FALSE, pid);
12 | DWORD ret = WaitForSingleObject(process, 0);
13 | CloseHandle(process);
14 | return ret == WAIT_TIMEOUT;
15 | }
16 | _forceinline std::string get_random_string(size_t length)
17 | {
18 | const static std::string chrs = xorstr_("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ");
19 |
20 | thread_local static std::mt19937 rg{ std::random_device{}() };
21 | thread_local static std::uniform_int_distribution pick(0, sizeof(chrs) - 2);
22 |
23 | std::string s;
24 |
25 | s.reserve(length);
26 |
27 | while (length--)
28 | s += chrs[pick(rg)];
29 |
30 | return s;
31 | }
32 |
33 | __forceinline std::string get_hwid()
34 | {
35 | std::string m_sResult;
36 |
37 | HANDLE m_hFile = CreateFileW(L"\\\\.\\PhysicalDrive0", 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
38 | if (m_hFile == INVALID_HANDLE_VALUE)
39 | return { };
40 |
41 | std::unique_ptr< std::remove_pointer ::type, void(*)(HANDLE) > m_hDevice
42 | {
43 | m_hFile, [](HANDLE handle)
44 | {
45 | CloseHandle(handle);
46 | }
47 | };
48 |
49 | STORAGE_PROPERTY_QUERY m_PropertyQuery;
50 | m_PropertyQuery.PropertyId = StorageDeviceProperty;
51 | m_PropertyQuery.QueryType = PropertyStandardQuery;
52 |
53 | STORAGE_DESCRIPTOR_HEADER m_DescHeader;
54 | DWORD m_dwBytesReturned = 0;
55 | if (!DeviceIoControl(m_hDevice.get(), IOCTL_STORAGE_QUERY_PROPERTY, &m_PropertyQuery, sizeof(STORAGE_PROPERTY_QUERY),
56 | &m_DescHeader, sizeof(STORAGE_DESCRIPTOR_HEADER), &m_dwBytesReturned, NULL))
57 | return { };
58 |
59 | const DWORD m_dwOutBufferSize = m_DescHeader.Size;
60 | std::unique_ptr< BYTE[] > m_pOutBuffer{ new BYTE[m_dwOutBufferSize] { } };
61 |
62 | if (!DeviceIoControl(m_hDevice.get(), IOCTL_STORAGE_QUERY_PROPERTY, &m_PropertyQuery, sizeof(STORAGE_PROPERTY_QUERY),
63 | m_pOutBuffer.get(), m_dwOutBufferSize, &m_dwBytesReturned, NULL))
64 | return { };
65 |
66 | STORAGE_DEVICE_DESCRIPTOR* m_pDeviceDescriptor = reinterpret_cast(m_pOutBuffer.get());
67 | const DWORD m_dwSerialNumberOffset = m_pDeviceDescriptor->SerialNumberOffset;
68 | if (m_dwSerialNumberOffset == 0)
69 | return { };
70 |
71 | m_sResult = reinterpret_cast(m_pOutBuffer.get() + m_dwSerialNumberOffset);
72 | m_sResult.erase(std::remove_if(m_sResult.begin(), m_sResult.end(), std::isspace), m_sResult.end());
73 |
74 | return m_sResult;
75 | }
76 |
77 | HANDLE GetProcessByName(const char* name)
78 | {
79 | HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
80 |
81 | PROCESSENTRY32 entry;
82 | entry.dwSize = sizeof(entry);
83 | HANDLE process;
84 | ZeroMemory(&process, sizeof(HANDLE));
85 |
86 | do {
87 | if (!strcmp(name, _bstr_t(entry.szExeFile)))
88 | {
89 | process = OpenProcess(PROCESS_ALL_ACCESS, false, entry.th32ProcessID);
90 | CloseHandle(hSnapshot);
91 | }
92 | } while (Process32Next(hSnapshot, &entry));
93 |
94 | return process;
95 | }
96 | }
--------------------------------------------------------------------------------
/client/Loader/utils/advanced-utils/advanced_utils.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | ADVANCED UTILITIES LIBRARY BY FLOWXRC
3 | MADE FOR SWIFTWARE
4 | */
5 | #pragma once
6 | #include
7 | #include
8 | #define VC_EXTRALEAN
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 | #pragma comment(lib, "th32.lib")
16 | #include "../lazy-importer/lazy_importer.hpp"
17 |
18 | namespace utilities
19 | {
20 | extern __forceinline std::string get_random_string(size_t length);
21 | extern __forceinline std::string get_hwid();
22 | extern HANDLE GetProcessByName(const char* name);
23 | BOOL IsProcessRunning(DWORD pid);
24 | }
--------------------------------------------------------------------------------
/client/Loader/utils/encrypt-decrypt/xorstr.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 - 2018 Justas Masiulis
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | #ifndef JM_XORSTR_HPP
18 | #define JM_XORSTR_HPP
19 |
20 | #include
21 | #include
22 | #include
23 | #include
24 |
25 | #define xorstr(str) \
26 | ::jm::make_xorstr( \
27 | []() { return str; }, \
28 | std::make_index_sequence{}, \
29 | std::make_index_sequence<::jm::detail::_buffer_size()>{})
30 | #define xorstr_(str) xorstr(str).crypt_get()
31 |
32 | #ifdef _MSC_VER
33 | #define XORSTR_FORCEINLINE __forceinline
34 | #else
35 | #define XORSTR_FORCEINLINE __attribute__((always_inline))
36 | #endif
37 |
38 | // you can define this macro to get possibly faster code on gcc/clang
39 | // at the expense of constants being put into data section.
40 | #if !defined(XORSTR_ALLOW_DATA)
41 | // MSVC - no volatile
42 | // GCC and clang - volatile everywhere
43 | #if defined(__clang__) || defined(__GNUC__)
44 | #define XORSTR_VOLATILE volatile
45 | #endif
46 |
47 | #endif
48 | #ifndef XORSTR_VOLATILE
49 | #define XORSTR_VOLATILE
50 | #endif
51 |
52 | namespace jm {
53 |
54 | namespace detail {
55 |
56 | template
57 | struct unsigned_;
58 |
59 | template<>
60 | struct unsigned_<1> {
61 | using type = std::uint8_t;
62 | };
63 | template<>
64 | struct unsigned_<2> {
65 | using type = std::uint16_t;
66 | };
67 | template<>
68 | struct unsigned_<4> {
69 | using type = std::uint32_t;
70 | };
71 |
72 | template
73 | struct pack_value_type {
74 | using type = decltype(C);
75 | };
76 |
77 | template
78 | constexpr std::size_t _buffer_size()
79 | {
80 | return ((Size / 16) + (Size % 16 != 0)) * 2;
81 | }
82 |
83 | template
84 | struct tstring_ {
85 | using value_type = typename pack_value_type::type;
86 | constexpr static std::size_t size = sizeof...(Cs);
87 | constexpr static value_type str[size] = { Cs... };
88 |
89 | constexpr static std::size_t buffer_size = _buffer_size();
90 | constexpr static std::size_t buffer_align =
91 | #ifndef JM_XORSTR_DISABLE_AVX_INTRINSICS
92 | ((sizeof(str) > 16) ? 32 : 16);
93 | #else
94 | 16;
95 | #endif
96 | };
97 |
98 | template
99 | struct _ki {
100 | constexpr static std::size_t idx = I;
101 | constexpr static std::uint64_t key = K;
102 | };
103 |
104 | template
105 | constexpr std::uint32_t key4() noexcept
106 | {
107 | std::uint32_t value = Seed;
108 | for (char c : __TIME__)
109 | value = static_cast((value ^ c) * 16777619ull);
110 | return value;
111 | }
112 |
113 | template
114 | constexpr std::uint64_t key8()
115 | {
116 | constexpr auto first_part = key4<2166136261 + S>();
117 | constexpr auto second_part = key4();
118 | return (static_cast(first_part) << 32) | second_part;
119 | }
120 |
121 | // clang and gcc try really hard to place the constants in data
122 | // sections. to counter that there was a need to create an intermediate
123 | // constexpr string and then copy it into a non constexpr container with
124 | // volatile storage so that the constants would be placed directly into
125 | // code.
126 | template
127 | struct string_storage {
128 | std::uint64_t storage[T::buffer_size];
129 |
130 | XORSTR_FORCEINLINE constexpr string_storage() noexcept : storage{ Keys... }
131 | {
132 | using cast_type =
133 | typename unsigned_::type;
134 | constexpr auto value_size = sizeof(typename T::value_type);
135 | // puts the string into 64 bit integer blocks in a constexpr
136 | // fashion
137 | for (std::size_t i = 0; i < T::size; ++i)
138 | storage[i / (8 / value_size)] ^=
139 | (std::uint64_t{ static_cast(T::str[i]) }
140 | << ((i % (8 / value_size)) * 8 * value_size));
141 | }
142 | };
143 |
144 | } // namespace detail
145 |
146 | template
147 | class xor_string {
148 | alignas(T::buffer_align) std::uint64_t _storage[T::buffer_size];
149 |
150 | // _single functions needed because MSVC crashes without them
151 | XORSTR_FORCEINLINE void _crypt_256_single(const std::uint64_t* keys,
152 | std::uint64_t* storage) noexcept
153 |
154 | {
155 | _mm256_store_si256(
156 | reinterpret_cast<__m256i*>(storage),
157 | _mm256_xor_si256(
158 | _mm256_load_si256(reinterpret_cast(storage)),
159 | _mm256_load_si256(reinterpret_cast(keys))));
160 | }
161 |
162 | template
163 | XORSTR_FORCEINLINE void _crypt_256(const std::uint64_t* keys,
164 | std::index_sequence) noexcept
165 | {
166 | (_crypt_256_single(keys + Idxs * 4, _storage + Idxs * 4), ...);
167 | }
168 |
169 | XORSTR_FORCEINLINE void _crypt_128_single(const std::uint64_t* keys,
170 | std::uint64_t* storage) noexcept
171 | {
172 | _mm_store_si128(
173 | reinterpret_cast<__m128i*>(storage),
174 | _mm_xor_si128(_mm_load_si128(reinterpret_cast(storage)),
175 | _mm_load_si128(reinterpret_cast(keys))));
176 | }
177 |
178 | template
179 | XORSTR_FORCEINLINE void _crypt_128(const std::uint64_t* keys,
180 | std::index_sequence) noexcept
181 | {
182 | (_crypt_128_single(keys + Idxs * 2, _storage + Idxs * 2), ...);
183 | }
184 |
185 | // loop generates vectorized code which places constants in data dir
186 | XORSTR_FORCEINLINE constexpr void _copy() noexcept
187 | {
188 | constexpr detail::string_storage storage;
189 | static_cast(std::initializer_list{
190 | (const_cast(_storage))[Keys::idx] =
191 | storage.storage[Keys::idx]... });
192 | }
193 |
194 | public:
195 | using value_type = typename T::value_type;
196 | using size_type = std::size_t;
197 | using pointer = value_type*;
198 | using const_pointer = const pointer;
199 |
200 | XORSTR_FORCEINLINE xor_string() noexcept { _copy(); }
201 |
202 | XORSTR_FORCEINLINE constexpr size_type size() const noexcept
203 | {
204 | return T::size - 1;
205 | }
206 |
207 | XORSTR_FORCEINLINE void crypt() noexcept
208 | {
209 | alignas(T::buffer_align) std::uint64_t keys[T::buffer_size];
210 | static_cast(std::initializer_list{
211 | (const_cast(keys))[Keys::idx] =
212 | Keys::key... });
213 |
214 | _copy();
215 |
216 | #ifndef JM_XORSTR_DISABLE_AVX_INTRINSICS
217 | _crypt_256(keys, std::make_index_sequence{});
218 | if constexpr (T::buffer_size % 4 != 0)
219 | _crypt_128(keys, std::index_sequence{});
220 | #else
221 | _crypt_128(keys, std::make_index_sequence{});
222 | #endif
223 | }
224 |
225 | XORSTR_FORCEINLINE const_pointer get() const noexcept
226 | {
227 | return reinterpret_cast(_storage);
228 | }
229 |
230 | XORSTR_FORCEINLINE const_pointer crypt_get() noexcept
231 | {
232 | crypt();
233 | return reinterpret_cast(_storage);
234 | }
235 | };
236 |
237 | template
238 | XORSTR_FORCEINLINE constexpr auto
239 | make_xorstr(Tstr str_lambda,
240 | std::index_sequence,
241 | std::index_sequence) noexcept
242 | {
243 | return xor_string,
244 | detail::_ki()>...>{};
245 | }
246 |
247 | } // namespace jm
248 |
249 | #endif // include guard
250 |
251 | #define _xor_(s) std::string(xorstr_(s))
--------------------------------------------------------------------------------
/client/Loader/utils/inject/Helpers/GetProcId.cpp:
--------------------------------------------------------------------------------
1 | #include "GetProcId.hpp"
2 |
3 | namespace helpers {
4 | DWORD GetProcId(const char* procName)
5 | {
6 | DWORD procId = 0;
7 | HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
8 |
9 | if (hSnap != INVALID_HANDLE_VALUE)
10 | {
11 | PROCESSENTRY32 procEntry;
12 | procEntry.dwSize = sizeof(procEntry);
13 |
14 | if (Process32First(hSnap, &procEntry))
15 | {
16 | do
17 | {
18 | if (!_stricmp(procEntry.szExeFile, procName))
19 | {
20 | procId = procEntry.th32ProcessID;
21 | break;
22 | }
23 | } while (Process32Next(hSnap, &procEntry));
24 | }
25 | }
26 | CloseHandle(hSnap);
27 | return procId;
28 | }
29 | }
--------------------------------------------------------------------------------
/client/Loader/utils/inject/Helpers/GetProcId.hpp:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include
3 | #include
4 | #define RC_INVOKED
5 | #include
6 | #include
7 |
8 | namespace helpers
9 | {
10 | extern DWORD GetProcId(const char* procName);
11 | }
--------------------------------------------------------------------------------
/client/Loader/utils/inject/inject.cpp:
--------------------------------------------------------------------------------
1 | // for swiftware
2 |
3 | #include "inject.hpp"
4 |
5 | std::string getPath(int csidl) {
6 | char out[MAX_PATH];
7 | if (SHGetSpecialFolderPathA(NULL, out, csidl, 0))
8 | return out;
9 | return NULL;
10 | }
11 |
12 | void HideConsole()
13 | {
14 | ::ShowWindow(::GetConsoleWindow(), SW_HIDE);
15 | }
16 |
17 | namespace uLoaderInjector
18 | {
19 | int inject_cheat()
20 | {
21 | std::string dllPath = getPath(CSIDL_APPDATA);
22 | dllPath += "\\";
23 | dllPath += utilities::get_random_string(16);
24 | dllPath += ".dll";
25 | string link = xorstr_("https://") + Globals::server_side.server + xorstr_("/client/download.php?key=") + Globals::server_side.secret_key;
26 | WebClient::DownloadFile(link.c_str(), dllPath.c_str());
27 | DWORD procId = helpers::GetProcId("csgo.exe");
28 | HANDLE hProcessId = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
29 |
30 | auto h_proc = OpenProcess(PROCESS_ALL_ACCESS, 0, procId);
31 |
32 | if (h_proc && h_proc != INVALID_HANDLE_VALUE)
33 | {
34 | const LPVOID nt_open_file = GetProcAddress(LoadLibraryW(L"ntdll"), "NtOpenFile");
35 | if (nt_open_file)
36 | {
37 | char original_bytes[5];
38 | memcpy(original_bytes, nt_open_file, 5);
39 | WriteProcessMemory(h_proc, nt_open_file, original_bytes, 5, nullptr);
40 | }
41 | auto* loc = VirtualAllocEx(h_proc, nullptr, MAX_PATH, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
42 | WriteProcessMemory(h_proc, loc, dllPath.c_str(), strlen(dllPath.c_str()) + 1, nullptr);
43 | auto* const h_thread = CreateRemoteThread(h_proc, nullptr, 0, reinterpret_cast(LoadLibraryA), loc, 0, nullptr);
44 | if (h_thread) CloseHandle(h_thread);
45 | }
46 | cout << xorstr_("[+] Cheat Loaded. Have Fun!\n");
47 | Sleep(3000);
48 | HideConsole();
49 | while (true)
50 | {
51 | if (!utilities::IsProcessRunning(helpers::GetProcId("csgo.exe"))) {
52 | std::remove(dllPath.c_str());
53 | break;
54 | }
55 | Sleep(500);
56 | }
57 | return 0;
58 | }
59 | }
--------------------------------------------------------------------------------
/client/Loader/utils/inject/inject.hpp:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #define _CRT_SECURE_NO_WARNINGS
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #define RC_INVOKED
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 | #include
17 | #include
18 | #include
19 | #pragma comment(lib, "WinINet.lib")
20 | #pragma comment(lib, "Ws2_32.lib")
21 | #pragma comment(lib, "urlmon.lib")
22 | #include "Helpers/GetProcId.hpp"
23 | #include "../webclient/webclient.hpp"
24 | #include "../encrypt-decrypt/xorstr.hpp"
25 | #include "../../headers/globals.hpp"
26 |
27 | namespace uLoaderInjector {
28 | extern int inject_cheat();
29 | }
--------------------------------------------------------------------------------
/client/Loader/utils/lazy-importer/lazy_importer.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Justas Masiulis
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | // documentation is available at https://github.com/JustasMasiulis/lazy_importer
18 |
19 | #ifndef LAZY_IMPORTER_HPP
20 | #define LAZY_IMPORTER_HPP
21 |
22 | #define li(s) LI_FN(s).get()
23 |
24 | #define LI_FN(name) \
25 | ::li::detail::lazy_function<::li::detail::khash(#name), decltype(&name)>()
26 |
27 | #define LI_FN_DEF(name) ::li::detail::lazy_function<::li::detail::khash(#name), name>()
28 |
29 | #define LI_MODULE(name) ::li::detail::lazy_module<::li::detail::khash(name)>()
30 |
31 | // NOTE only std::forward is used from this header.
32 | // If there is a need to eliminate this dependency the function itself is very small.
33 | #include
34 | #include
35 | #include
36 |
37 | #define JM_XORSTR_DISABLE_AVX_INTRINSICS
38 |
39 | #include "../encrypt-decrypt/xorstr.hpp"
40 |
41 | #define _xor_(s) std::string(xorstr_(s))
42 |
43 | #ifndef LAZY_IMPORTER_NO_FORCEINLINE
44 | #if defined(_MSC_VER)
45 | #define LAZY_IMPORTER_FORCEINLINE __forceinline
46 | #elif defined(__GNUC__) && __GNUC__ > 3
47 | #define LAZY_IMPORTER_FORCEINLINE inline __attribute__((__always_inline__))
48 | #else
49 | #define LAZY_IMPORTER_FORCEINLINE inline
50 | #endif
51 | #else
52 | #define LAZY_IMPORTER_FORCEINLINE inline
53 | #endif
54 |
55 | #ifdef LAZY_IMPORTER_CASE_INSENSITIVE
56 | #define LAZY_IMPORTER_TOLOWER(c) (c >= 'A' && c <= 'Z' ? (c | (1 << 5)) : c)
57 | #else
58 | #define LAZY_IMPORTER_TOLOWER(c) (c)
59 | #endif
60 |
61 | namespace li { namespace detail {
62 |
63 | template
64 | struct pair {
65 | First first;
66 | Second second;
67 | };
68 |
69 | namespace win {
70 |
71 | struct LIST_ENTRY_T {
72 | const char* Flink;
73 | const char* Blink;
74 | };
75 |
76 | struct UNICODE_STRING_T {
77 | unsigned short Length;
78 | unsigned short MaximumLength;
79 | wchar_t* Buffer;
80 | };
81 |
82 | struct PEB_LDR_DATA_T {
83 | unsigned long Length;
84 | unsigned long Initialized;
85 | const char* SsHandle;
86 | LIST_ENTRY_T InLoadOrderModuleList;
87 | };
88 |
89 | struct PEB_T {
90 | unsigned char Reserved1[2];
91 | unsigned char BeingDebugged;
92 | unsigned char Reserved2[1];
93 | const char* Reserved3[2];
94 | PEB_LDR_DATA_T* Ldr;
95 | };
96 |
97 | struct LDR_DATA_TABLE_ENTRY_T {
98 | LIST_ENTRY_T InLoadOrderLinks;
99 | LIST_ENTRY_T InMemoryOrderLinks;
100 | LIST_ENTRY_T InInitializationOrderLinks;
101 | const char* DllBase;
102 | const char* EntryPoint;
103 | union {
104 | unsigned long SizeOfImage;
105 | const char* _dummy;
106 | };
107 | UNICODE_STRING_T FullDllName;
108 | UNICODE_STRING_T BaseDllName;
109 |
110 | LAZY_IMPORTER_FORCEINLINE const LDR_DATA_TABLE_ENTRY_T*
111 | load_order_next() const noexcept
112 | {
113 | return reinterpret_cast(
114 | InLoadOrderLinks.Flink);
115 | }
116 | };
117 |
118 | struct IMAGE_DOS_HEADER { // DOS .EXE header
119 | unsigned short e_magic; // Magic number
120 | unsigned short e_cblp; // BYTEs on last page of file
121 | unsigned short e_cp; // Pages in file
122 | unsigned short e_crlc; // Relocations
123 | unsigned short e_cparhdr; // Size of header in paragraphs
124 | unsigned short e_minalloc; // Minimum extra paragraphs needed
125 | unsigned short e_maxalloc; // Maximum extra paragraphs needed
126 | unsigned short e_ss; // Initial (relative) SS value
127 | unsigned short e_sp; // Initial SP value
128 | unsigned short e_csum; // Checksum
129 | unsigned short e_ip; // Initial IP value
130 | unsigned short e_cs; // Initial (relative) CS value
131 | unsigned short e_lfarlc; // File address of relocation table
132 | unsigned short e_ovno; // Overlay number
133 | unsigned short e_res[4]; // Reserved words
134 | unsigned short e_oemid; // OEM identifier (for e_oeminfo)
135 | unsigned short e_oeminfo; // OEM information; e_oemid specific
136 | unsigned short e_res2[10]; // Reserved words
137 | long e_lfanew; // File address of new exe header
138 | };
139 |
140 | struct IMAGE_FILE_HEADER {
141 | unsigned short Machine;
142 | unsigned short NumberOfSections;
143 | unsigned long TimeDateStamp;
144 | unsigned long PointerToSymbolTable;
145 | unsigned long NumberOfSymbols;
146 | unsigned short SizeOfOptionalHeader;
147 | unsigned short Characteristics;
148 | };
149 |
150 | struct IMAGE_EXPORT_DIRECTORY {
151 | unsigned long Characteristics;
152 | unsigned long TimeDateStamp;
153 | unsigned short MajorVersion;
154 | unsigned short MinorVersion;
155 | unsigned long Name;
156 | unsigned long Base;
157 | unsigned long NumberOfFunctions;
158 | unsigned long NumberOfNames;
159 | unsigned long AddressOfFunctions; // RVA from base of image
160 | unsigned long AddressOfNames; // RVA from base of image
161 | unsigned long AddressOfNameOrdinals; // RVA from base of image
162 | };
163 |
164 | struct IMAGE_DATA_DIRECTORY {
165 | unsigned long VirtualAddress;
166 | unsigned long Size;
167 | };
168 |
169 | struct IMAGE_OPTIONAL_HEADER64 {
170 | unsigned short Magic;
171 | unsigned char MajorLinkerVersion;
172 | unsigned char MinorLinkerVersion;
173 | unsigned long SizeOfCode;
174 | unsigned long SizeOfInitializedData;
175 | unsigned long SizeOfUninitializedData;
176 | unsigned long AddressOfEntryPoint;
177 | unsigned long BaseOfCode;
178 | unsigned long long ImageBase;
179 | unsigned long SectionAlignment;
180 | unsigned long FileAlignment;
181 | unsigned short MajorOperatingSystemVersion;
182 | unsigned short MinorOperatingSystemVersion;
183 | unsigned short MajorImageVersion;
184 | unsigned short MinorImageVersion;
185 | unsigned short MajorSubsystemVersion;
186 | unsigned short MinorSubsystemVersion;
187 | unsigned long Win32VersionValue;
188 | unsigned long SizeOfImage;
189 | unsigned long SizeOfHeaders;
190 | unsigned long CheckSum;
191 | unsigned short Subsystem;
192 | unsigned short DllCharacteristics;
193 | unsigned long long SizeOfStackReserve;
194 | unsigned long long SizeOfStackCommit;
195 | unsigned long long SizeOfHeapReserve;
196 | unsigned long long SizeOfHeapCommit;
197 | unsigned long LoaderFlags;
198 | unsigned long NumberOfRvaAndSizes;
199 | IMAGE_DATA_DIRECTORY DataDirectory[16];
200 | };
201 |
202 | struct IMAGE_OPTIONAL_HEADER32 {
203 | unsigned short Magic;
204 | unsigned char MajorLinkerVersion;
205 | unsigned char MinorLinkerVersion;
206 | unsigned long SizeOfCode;
207 | unsigned long SizeOfInitializedData;
208 | unsigned long SizeOfUninitializedData;
209 | unsigned long AddressOfEntryPoint;
210 | unsigned long BaseOfCode;
211 | unsigned long BaseOfData;
212 | unsigned long ImageBase;
213 | unsigned long SectionAlignment;
214 | unsigned long FileAlignment;
215 | unsigned short MajorOperatingSystemVersion;
216 | unsigned short MinorOperatingSystemVersion;
217 | unsigned short MajorImageVersion;
218 | unsigned short MinorImageVersion;
219 | unsigned short MajorSubsystemVersion;
220 | unsigned short MinorSubsystemVersion;
221 | unsigned long Win32VersionValue;
222 | unsigned long SizeOfImage;
223 | unsigned long SizeOfHeaders;
224 | unsigned long CheckSum;
225 | unsigned short Subsystem;
226 | unsigned short DllCharacteristics;
227 | unsigned long SizeOfStackReserve;
228 | unsigned long SizeOfStackCommit;
229 | unsigned long SizeOfHeapReserve;
230 | unsigned long SizeOfHeapCommit;
231 | unsigned long LoaderFlags;
232 | unsigned long NumberOfRvaAndSizes;
233 | IMAGE_DATA_DIRECTORY DataDirectory[16];
234 | };
235 |
236 | struct IMAGE_NT_HEADERS {
237 | unsigned long Signature;
238 | IMAGE_FILE_HEADER FileHeader;
239 | #ifdef _WIN64
240 | IMAGE_OPTIONAL_HEADER64 OptionalHeader;
241 | #else
242 | IMAGE_OPTIONAL_HEADER32 OptionalHeader;
243 | #endif
244 | };
245 |
246 | } // namespace win
247 |
248 | // hashing stuff
249 | struct hash_t {
250 | using value_type = unsigned long;
251 | constexpr static value_type offset = 2166136261;
252 | constexpr static value_type prime = 16777619;
253 | constexpr static unsigned long long prime64 = prime;
254 |
255 | LAZY_IMPORTER_FORCEINLINE constexpr static value_type single(value_type value,
256 | char c) noexcept
257 | {
258 | return static_cast(
259 | (value ^ LAZY_IMPORTER_TOLOWER(c)) *
260 | static_cast(prime));
261 | }
262 | };
263 |
264 | template
265 | LAZY_IMPORTER_FORCEINLINE constexpr hash_t::value_type
266 | khash(const CharT* str, hash_t::value_type value = hash_t::offset) noexcept
267 | {
268 | return (*str ? khash(str + 1, hash_t::single(value, *str)) : value);
269 | }
270 |
271 | template
272 | LAZY_IMPORTER_FORCEINLINE hash_t::value_type hash(const CharT* str) noexcept
273 | {
274 | hash_t::value_type value = hash_t::offset;
275 |
276 | for(;;) {
277 | char c = *str++;
278 | if(!c)
279 | return value;
280 | value = hash_t::single(value, c);
281 | }
282 | }
283 |
284 | LAZY_IMPORTER_FORCEINLINE hash_t::value_type hash(
285 | const win::UNICODE_STRING_T& str) noexcept
286 | {
287 | auto first = str.Buffer;
288 | const auto last = first + (str.Length / sizeof(wchar_t));
289 | auto value = hash_t::offset;
290 | for(; first != last; ++first)
291 | value = hash_t::single(value, static_cast(*first));
292 |
293 | return value;
294 | }
295 |
296 | LAZY_IMPORTER_FORCEINLINE pair hash_forwarded(
297 | const char* str) noexcept
298 | {
299 | pair module_and_function{
300 | hash_t::offset, hash_t::offset
301 | };
302 |
303 | for(; *str != '.'; ++str)
304 | hash_t::single(module_and_function.first, *str);
305 |
306 | ++str;
307 |
308 | for(; *str; ++str)
309 | hash_t::single(module_and_function.second, *str);
310 |
311 | return module_and_function;
312 | }
313 |
314 |
315 | // some helper functions
316 | LAZY_IMPORTER_FORCEINLINE const win::PEB_T* peb() noexcept
317 | {
318 | #if defined(_WIN64)
319 | return reinterpret_cast(__readgsqword(0x60));
320 | #elif defined(_WIN32)
321 | return reinterpret_cast(__readfsdword(0x30));
322 | #else
323 | #error Unsupported platform. Open an issue and I'll probably add support.
324 | #endif
325 | }
326 |
327 | LAZY_IMPORTER_FORCEINLINE const win::PEB_LDR_DATA_T* ldr()
328 | {
329 | return reinterpret_cast(peb()->Ldr);
330 | }
331 |
332 | LAZY_IMPORTER_FORCEINLINE const win::IMAGE_NT_HEADERS* nt_headers(
333 | const char* base) noexcept
334 | {
335 | return reinterpret_cast(
336 | base + reinterpret_cast(base)->e_lfanew);
337 | }
338 |
339 | LAZY_IMPORTER_FORCEINLINE const win::IMAGE_EXPORT_DIRECTORY* image_export_dir(
340 | const char* base) noexcept
341 | {
342 | return reinterpret_cast(
343 | base + nt_headers(base)->OptionalHeader.DataDirectory->VirtualAddress);
344 | }
345 |
346 | LAZY_IMPORTER_FORCEINLINE const win::LDR_DATA_TABLE_ENTRY_T* ldr_data_entry() noexcept
347 | {
348 | return reinterpret_cast(
349 | ldr()->InLoadOrderModuleList.Flink);
350 | }
351 |
352 | struct exports_directory {
353 | const char* _base;
354 | const win::IMAGE_EXPORT_DIRECTORY* _ied;
355 | unsigned long _ied_size;
356 |
357 | public:
358 | using size_type = unsigned long;
359 |
360 | LAZY_IMPORTER_FORCEINLINE
361 | exports_directory(const char* base) noexcept : _base(base)
362 | {
363 | const auto ied_data_dir = nt_headers(base)->OptionalHeader.DataDirectory[0];
364 | _ied = reinterpret_cast(
365 | base + ied_data_dir.VirtualAddress);
366 | _ied_size = ied_data_dir.Size;
367 | }
368 |
369 | LAZY_IMPORTER_FORCEINLINE explicit operator bool() const noexcept
370 | {
371 | return reinterpret_cast(_ied) != _base;
372 | }
373 |
374 | LAZY_IMPORTER_FORCEINLINE size_type size() const noexcept
375 | {
376 | return _ied->NumberOfNames;
377 | }
378 |
379 | LAZY_IMPORTER_FORCEINLINE const char* base() const noexcept { return _base; }
380 | LAZY_IMPORTER_FORCEINLINE const win::IMAGE_EXPORT_DIRECTORY* ied() const noexcept
381 | {
382 | return _ied;
383 | }
384 |
385 | LAZY_IMPORTER_FORCEINLINE const char* name(size_type index) const noexcept
386 | {
387 | return reinterpret_cast(
388 | _base + reinterpret_cast(
389 | _base + _ied->AddressOfNames)[index]);
390 | }
391 |
392 | LAZY_IMPORTER_FORCEINLINE const char* address(size_type index) const noexcept
393 | {
394 | const auto* const rva_table =
395 | reinterpret_cast(_base + _ied->AddressOfFunctions);
396 |
397 | const auto* const ord_table = reinterpret_cast(
398 | _base + _ied->AddressOfNameOrdinals);
399 |
400 | return _base + rva_table[ord_table[index]];
401 | }
402 |
403 | LAZY_IMPORTER_FORCEINLINE bool is_forwarded(const char* export_address) const
404 | noexcept
405 | {
406 | const auto ui_ied = reinterpret_cast(_ied);
407 | return (export_address > ui_ied && export_address < ui_ied + _ied_size);
408 | }
409 | };
410 |
411 | struct safe_module_enumerator {
412 | using value_type = const detail::win::LDR_DATA_TABLE_ENTRY_T;
413 | value_type* value;
414 | value_type* const head;
415 |
416 | LAZY_IMPORTER_FORCEINLINE safe_module_enumerator() noexcept
417 | : value(ldr_data_entry()), head(value)
418 | {}
419 |
420 | LAZY_IMPORTER_FORCEINLINE void reset() noexcept { value = head; }
421 |
422 | LAZY_IMPORTER_FORCEINLINE bool next() noexcept
423 | {
424 | value = value->load_order_next();
425 | return value != head;
426 | }
427 | };
428 |
429 | struct unsafe_module_enumerator {
430 | using value_type = const detail::win::LDR_DATA_TABLE_ENTRY_T*;
431 | value_type value;
432 |
433 | LAZY_IMPORTER_FORCEINLINE unsafe_module_enumerator() noexcept
434 | : value(ldr_data_entry())
435 | {}
436 |
437 | LAZY_IMPORTER_FORCEINLINE void reset() noexcept { value = ldr_data_entry(); }
438 |
439 | LAZY_IMPORTER_FORCEINLINE bool next() noexcept
440 | {
441 | value = value->load_order_next();
442 | return true;
443 | }
444 | };
445 |
446 | // provides the cached functions which use Derive classes methods
447 | template
448 | class lazy_base {
449 | protected:
450 | // This function is needed because every templated function
451 | // with different args has its own static buffer
452 | LAZY_IMPORTER_FORCEINLINE static void*& _cache() noexcept
453 | {
454 | static void* value = nullptr;
455 | return value;
456 | }
457 |
458 | public:
459 | template
460 | LAZY_IMPORTER_FORCEINLINE static T safe() noexcept
461 | {
462 | return Derived::template get();
463 | }
464 |
465 | template
466 | LAZY_IMPORTER_FORCEINLINE static T cached() noexcept
467 | {
468 | auto& cached = _cache();
469 | if(!cached)
470 | cached = Derived::template get();
471 |
472 | return (T)(cached);
473 | }
474 |
475 | template
476 | LAZY_IMPORTER_FORCEINLINE static T safe_cached() noexcept
477 | {
478 | return cached();
479 | }
480 | };
481 |
482 | template
483 | struct lazy_module : lazy_base> {
484 | template
485 | LAZY_IMPORTER_FORCEINLINE static T get() noexcept
486 | {
487 | Enum e;
488 | do {
489 | if(hash(e.value->BaseDllName) == Hash)
490 | return (T)(e.value->DllBase);
491 | } while(e.next());
492 | return {};
493 | }
494 | };
495 |
496 | template
497 | struct lazy_function : lazy_base, T> {
498 | using base_type = lazy_base, T>;
499 |
500 | template
501 | LAZY_IMPORTER_FORCEINLINE decltype(auto) operator()(Args&&... args) const
502 | {
503 | #ifndef LAZY_IMPORTER_CACHE_OPERATOR_PARENS
504 | return get()(std::forward(args)...);
505 | #else
506 | return this->cached()(std::forward(args)...);
507 | #endif
508 | }
509 |
510 | template
511 | LAZY_IMPORTER_FORCEINLINE static F get() noexcept
512 | {
513 | // for backwards compatability.
514 | // Before 2.0 it was only possible to resolve forwarded exports when
515 | // this macro was enabled
516 | #ifdef LAZY_IMPORTER_RESOLVE_FORWARDED_EXPORTS
517 | return forwarded();
518 | #else
519 | Enum e;
520 | do {
521 | const exports_directory exports(e.value->DllBase);
522 |
523 | if(exports) {
524 | auto export_index = exports.size();
525 | while(export_index--)
526 | if(hash(exports.name(export_index)) == Hash)
527 | return (F)(exports.address(export_index));
528 | }
529 | } while(e.next());
530 | return {};
531 | #endif
532 | }
533 |
534 | template
535 | LAZY_IMPORTER_FORCEINLINE static F forwarded() noexcept
536 | {
537 | detail::win::UNICODE_STRING_T name;
538 | hash_t::value_type module_hash = 0;
539 | auto function_hash = Hash;
540 |
541 | Enum e;
542 | do {
543 | name = e.value->BaseDllName;
544 | name.Length -= 8; // get rid of .dll extension
545 |
546 | if(!module_hash || hash(name) == module_hash) {
547 | const exports_directory exports(e.value->DllBase);
548 |
549 | if(exports) {
550 | auto export_index = exports.size();
551 | while(export_index--)
552 | if(hash(exports.name(export_index)) == function_hash) {
553 | const auto addr = exports.address(export_index);
554 |
555 | if(exports.is_forwarded(addr)) {
556 | auto hashes = hash_forwarded(
557 | reinterpret_cast(addr));
558 |
559 | function_hash = hashes.second;
560 | module_hash = hashes.first;
561 |
562 | e.reset();
563 | break;
564 | }
565 | return (F)(addr);
566 | }
567 | }
568 | }
569 | } while(e.next());
570 | return {};
571 | }
572 |
573 | template
574 | LAZY_IMPORTER_FORCEINLINE static F forwarded_safe() noexcept
575 | {
576 | return forwarded();
577 | }
578 |
579 | template
580 | LAZY_IMPORTER_FORCEINLINE static F forwarded_cached() noexcept
581 | {
582 | auto& value = base_type::_cache();
583 | if(!value)
584 | value = forwarded();
585 | return (F)(value);
586 | }
587 |
588 | template
589 | LAZY_IMPORTER_FORCEINLINE static F forwarded_safe_cached() noexcept
590 | {
591 | return forwarded_cached();
592 | }
593 |
594 | template
595 | LAZY_IMPORTER_FORCEINLINE static F in(Module m) noexcept
596 | {
597 | if(IsSafe && !m)
598 | return {};
599 |
600 | const exports_directory exports((const char*)(m));
601 | if(IsSafe && !exports)
602 | return {};
603 |
604 | for(unsigned long i{};; ++i) {
605 | if(IsSafe && i == exports.size())
606 | break;
607 |
608 | if(hash(exports.name(i)) == Hash)
609 | return (F)(exports.address(i));
610 | }
611 | return {};
612 | }
613 |
614 | template
615 | LAZY_IMPORTER_FORCEINLINE static F in_safe(Module m) noexcept
616 | {
617 | return in(m);
618 | }
619 |
620 | template
621 | LAZY_IMPORTER_FORCEINLINE static F in_cached(Module m) noexcept
622 | {
623 | auto& value = base_type::_cache();
624 | if(!value)
625 | value = in(m);
626 | return (F)(value);
627 | }
628 |
629 | template
630 | LAZY_IMPORTER_FORCEINLINE static F in_safe_cached(Module m) noexcept
631 | {
632 | return in_cached(m);
633 | }
634 |
635 | template
636 | LAZY_IMPORTER_FORCEINLINE static F nt() noexcept
637 | {
638 | return in(ldr_data_entry()->load_order_next()->DllBase);
639 | }
640 |
641 | template
642 | LAZY_IMPORTER_FORCEINLINE static F nt_safe() noexcept
643 | {
644 | return in_safe(ldr_data_entry()->load_order_next()->DllBase);
645 | }
646 |
647 | template
648 | LAZY_IMPORTER_FORCEINLINE static F nt_cached() noexcept
649 | {
650 | return in_cached(ldr_data_entry()->load_order_next()->DllBase);
651 | }
652 |
653 | template
654 | LAZY_IMPORTER_FORCEINLINE static F nt_safe_cached() noexcept
655 | {
656 | return in_safe_cached(ldr_data_entry()->load_order_next()->DllBase);
657 | }
658 | };
659 |
660 | }} // namespace li::detail
661 |
662 | #endif // include guard
663 |
--------------------------------------------------------------------------------
/client/Loader/utils/webclient/webclient.cpp:
--------------------------------------------------------------------------------
1 | #include "webclient.hpp"
2 |
3 | namespace WebClient
4 | {
5 | string replaceAll(string subject, const string& search,
6 | const string& replace) {
7 | size_t pos = 0;
8 | while ((pos = subject.find(search, pos)) != string::npos) {
9 | subject.replace(pos, search.length(), replace);
10 | pos += replace.length();
11 | }
12 | return subject;
13 | }
14 |
15 | string DownloadString(string URL) {
16 | HINTERNET interwebs = InternetOpenA("Mozilla/5.0", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, NULL);
17 | HINTERNET urlFile;
18 | string rtn;
19 | if (interwebs) {
20 | urlFile = InternetOpenUrlA(interwebs, URL.c_str(), NULL, NULL, NULL, NULL);
21 | if (urlFile) {
22 | char buffer[2000];
23 | DWORD bytesRead;
24 | do {
25 | InternetReadFile(urlFile, buffer, 2000, &bytesRead);
26 | rtn.append(buffer, bytesRead);
27 | memset(buffer, 0, 2000);
28 | } while (bytesRead);
29 | InternetCloseHandle(interwebs);
30 | InternetCloseHandle(urlFile);
31 | string p = replaceAll(rtn, "|n", "\r\n");
32 | return p;
33 | }
34 | }
35 | InternetCloseHandle(interwebs);
36 | string p = replaceAll(rtn, "|n", "\r\n");
37 | return p;
38 | }
39 |
40 | void DownloadFile(LPCSTR URL, LPCSTR file_loc) {
41 | URLDownloadToFileA(0, URL, file_loc, 0, 0);
42 | }
43 | }
--------------------------------------------------------------------------------
/client/Loader/utils/webclient/webclient.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | WEBCLIENT LIBRARY BY FLOWXRC
3 | MADE FOR SWIFTWARE
4 | */
5 | #pragma once
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 | #pragma comment(lib, "WinINet.lib")
16 | #pragma comment(lib, "Ws2_32.lib")
17 | #pragma comment(lib, "urlmon.lib")
18 | using namespace std;
19 |
20 | namespace WebClient {
21 | extern string replaceAll(string subject, const string& search, const string& replace);
22 | extern string DownloadString(string URL);
23 | extern void DownloadFile(LPCSTR URL, LPCSTR file_loc);
24 | }
--------------------------------------------------------------------------------
/server/client/.htaccess:
--------------------------------------------------------------------------------
1 |
2 | Order Allow,Deny
3 | Deny from all
4 |
5 |
--------------------------------------------------------------------------------
/server/client/client.php:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/server/client/config.php:
--------------------------------------------------------------------------------
1 | '1.0',
4 | 'secret_key' => 'secret_N4QCMWupcOxZW0XZelam1DGR4RQrwOD2MZguyVf9',
5 | 'client_key' => 'public_NHtCNhEPwTcAxcguJZbs'
6 | ];
7 | ?>
--------------------------------------------------------------------------------
/server/client/download.php:
--------------------------------------------------------------------------------
1 | service('XF:User\Login', $_GET["username"], $ip);
12 | $userValidate = $loginService->validate($_GET["password"], $error);
13 | if($userValidate)
14 | {
15 | $username = $_GET['username'];
16 | $hwid = $_GET['hwid'];
17 | $sql = mysqli_connect("host", "name", "pass", "database");
18 | $query = mysqli_query($sql, "SELECT * FROM hwids WHERE username='$username'");
19 | $count = mysqli_num_rows($query);
20 | $row = mysqli_fetch_assoc($query);
21 | if ($count > 0) {
22 | if ($row['hwid'] == $hwid) {
23 | echo "success";
24 | }
25 | else {
26 | echo "hwid:fail";
27 | }
28 | }
29 | else {
30 | $query = mysqli_query($sql, "INSERT INTO hwids (username, hwid) VALUES ('$username', '$hwid')");
31 | echo "success";
32 | }
33 | }
34 | else {
35 | echo "fail";
36 | }
37 | }
38 | else {
39 | echo "fail";
40 | }
41 | }
42 | ?>
--------------------------------------------------------------------------------
/server/pastaware.sql:
--------------------------------------------------------------------------------
1 | -- phpMyAdmin SQL Dump
2 | -- version 4.9.4
3 | -- https://www.phpmyadmin.net/
4 | --
5 | -- Хост: 127.0.0.1
6 | -- Время создания: Фев 01 2021 г., 18:22
7 | -- Версия сервера: 8.0.13
8 | -- Версия PHP: 5.6.40
9 |
10 | SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
11 | SET AUTOCOMMIT = 0;
12 | START TRANSACTION;
13 | SET time_zone = "+00:00";
14 |
15 |
16 | /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
17 | /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
18 | /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
19 | /*!40101 SET NAMES utf8mb4 */;
20 |
21 | --
22 | -- База данных: `swiftware`
23 | --
24 |
25 | -- --------------------------------------------------------
26 |
27 | --
28 | -- Структура таблицы `hwids`
29 | --
30 |
31 | CREATE TABLE `hwids` (
32 | `id` int(11) NOT NULL,
33 | `username` varchar(255) NOT NULL,
34 | `hwid` varchar(255) NOT NULL
35 | ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
36 |
37 | --
38 | -- Дамп данных таблицы `hwids`
39 | --
40 |
41 | INSERT INTO `hwids` (`id`, `username`, `hwid`) VALUES
42 | (1, 'flowxrc', '150505RB254A1C16NPMJ');
43 |
44 | --
45 | -- Индексы сохранённых таблиц
46 | --
47 |
48 | --
49 | -- Индексы таблицы `hwids`
50 | --
51 | ALTER TABLE `hwids`
52 | ADD PRIMARY KEY (`id`);
53 |
54 | --
55 | -- AUTO_INCREMENT для сохранённых таблиц
56 | --
57 |
58 | --
59 | -- AUTO_INCREMENT для таблицы `hwids`
60 | --
61 | ALTER TABLE `hwids`
62 | MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=2;
63 | COMMIT;
64 |
65 | /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
66 | /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
67 | /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
68 |
--------------------------------------------------------------------------------