1
+ #include < stdio.h>
2
+ #include < stdlib.h>
3
+ #include < windows.h>
4
+ #include < io.h>
5
+ #include < psapi.h>
6
+ #include < wchar.h>
7
+ #include < string.h>
8
+ #include < TlHelp32.h>
9
+ #pragma comment(lib, "psapi.lib")
10
+
11
+ int * pointer_path;
12
+ int num_ptr;
13
+
14
+ // get the base address of the process main module
15
+ uintptr_t GetProcessBaseAddress (DWORD processId) {
16
+
17
+ uintptr_t baseAddress = 0 ;
18
+ HANDLE processHandle = OpenProcess (PROCESS_ALL_ACCESS, TRUE , processId);
19
+ HMODULE * moduleArray;
20
+ LPBYTE moduleArrayBytes;
21
+ DWORD bytesRequired;
22
+
23
+ if (processHandle) {
24
+ if (EnumProcessModules (processHandle, NULL , 0 , & bytesRequired)) {
25
+ if (bytesRequired) {
26
+ moduleArrayBytes = (LPBYTE) LocalAlloc (LPTR, bytesRequired);
27
+
28
+ if (moduleArrayBytes) {
29
+ int moduleCount;
30
+
31
+ moduleCount = bytesRequired / sizeof (HMODULE);
32
+ moduleArray = (HMODULE * ) moduleArrayBytes;
33
+
34
+ if (EnumProcessModules (processHandle, moduleArray, bytesRequired, & bytesRequired)) {
35
+ baseAddress = (uintptr_t )(moduleArray[0 ]);
36
+ }
37
+
38
+ LocalFree (moduleArrayBytes);
39
+ }
40
+ }
41
+ }
42
+
43
+ CloseHandle (processHandle);
44
+ }
45
+
46
+ return baseAddress;
47
+ }
48
+
49
+ // convert char arr to wchar
50
+ const wchar_t *ToWchar (const char *c) {
51
+ const size_t cSize = strlen (c)+1 ;
52
+ wchar_t * wc = new wchar_t [cSize];
53
+ mbstowcs (wc, c, cSize);
54
+ return wc;
55
+ }
56
+
57
+ // get process ID from executable name
58
+ DWORD GetProcId (WCHAR * name) {
59
+ PROCESSENTRY32 entry;
60
+ entry.dwSize = sizeof (PROCESSENTRY32);
61
+
62
+ HANDLE snapshot = CreateToolhelp32Snapshot (TH32CS_SNAPPROCESS, 0 );
63
+
64
+ if (Process32First (snapshot, & entry) == TRUE ) {
65
+ while (Process32Next (snapshot, & entry) == TRUE ) {
66
+ if (wcscmp (ToWchar (entry.szExeFile ), name) == 0 ) {
67
+ return entry.th32ProcessID ;
68
+ }
69
+ }
70
+ }
71
+
72
+ CloseHandle (snapshot);
73
+ return 0 ;
74
+ }
75
+
76
+ // main (entry point)
77
+ int main (int argc, char * argv[]) {
78
+ FILE * ptr_file;
79
+ char MEE_POINTER_FILE[0x2048 ];
80
+ int LOGIN_STEP_VALUE = -1 ;
81
+
82
+ char * tmp;
83
+ #ifdef _WIN64
84
+ printf_s (" x64 Version can ONLY be used for the 64 Bit Versions of the game.\n " );
85
+ #else
86
+ printf_s (" x86 Version can ONLY be used for the 32 Bit Versions of the game.\n " );
87
+ #endif
88
+
89
+ strncpy_s (MEE_POINTER_FILE, 0x2048 , " mee.ptr" , 0x2048 );
90
+ if (argc > 1 ) {
91
+ for (int i = 0 ; i < argc; i++) {
92
+
93
+ if (strcmp (argv[i], " --help" ) == 0 ) {
94
+ printf_s (" --ptr <mee.ptr file>\n " );
95
+ printf_s (" --lstep <custom login step value>\n " );
96
+ return 0 ;
97
+ }
98
+
99
+ if (strcmp (argv[i], " --ptr" ) == 0 )
100
+ strncpy_s (MEE_POINTER_FILE, 0x2048 , argv[i + 1 ], 0x2048 );
101
+
102
+ if (strcmp (argv[i], " --lstep" ) == 0 )
103
+ LOGIN_STEP_VALUE = strtol (argv[i + 1 ], & tmp, 10 );
104
+
105
+ }
106
+
107
+ printf_s (" MEE.PTR FILE : %s\n LOGIN STEP VALUE: %i\n " , MEE_POINTER_FILE, LOGIN_STEP_VALUE);
108
+ }
109
+
110
+ printf_s (" Loading %s\n " , MEE_POINTER_FILE);
111
+ if ((_access (MEE_POINTER_FILE, 0 )) != -1 ) // If the mee.ptr file exists AND the process has permission to read it..
112
+ {
113
+ // Open the pointer file
114
+ fopen_s ( & ptr_file, MEE_POINTER_FILE, " r" );
115
+
116
+ /*
117
+ This next part just gets the size
118
+ of mee.ptr file
119
+ */
120
+
121
+ // Seek to the end of the file
122
+ fseek (ptr_file, 0 , SEEK_END);
123
+ // Get the current position
124
+ int sz = ftell (ptr_file) + 1 ;
125
+ // Seek to the start of the file
126
+ fseek (ptr_file, 0 , SEEK_SET);
127
+
128
+ /*
129
+ Allocate a buffer the size of mee.ptr
130
+ then read the contents of the mee.ptr file
131
+ into that buffer
132
+ */
133
+
134
+ // Allocate (sz) bytes of memory for the buffer.
135
+ char * file_contents = (char * ) malloc (sz);
136
+ // Set the newly allocated buffer to all 0x00
137
+ memset (file_contents, 0x00 , sz);
138
+ // Read the contents of mee.ptr into the buffer.
139
+ fread (file_contents, sz, 1 , ptr_file);
140
+
141
+ /*
142
+ Create a copy of the pointer path file buffer
143
+ This is so we can scan through and mess with the pointers to it
144
+ Without messing up the our original copy
145
+ */
146
+
147
+ // Allocate (sz) bytes of memory for the buffer
148
+ char * work_buf = (char * ) malloc (sz);
149
+ // Copy contents of previously read file into the new buffer
150
+ memcpy_s (work_buf, sz, file_contents, sz);
151
+
152
+ /*
153
+ * Count the total number of elements
154
+ * From mee.ptr file.
155
+ */
156
+
157
+ // Set the total number of elements in the pointer path to 0
158
+ num_ptr = 0 ;
159
+
160
+ // Pointer to the next element, NULL for now.
161
+ char * next_token1 = NULL ;
162
+
163
+ // Get a pointer to the first occurance of " > "
164
+ char * token = strtok_s (work_buf, " > " , & next_token1);
165
+
166
+ // Repeat this until there is no more " > " left
167
+ while (token != NULL ) {
168
+ // Get the pointer to the next " > ".
169
+ token = strtok_s (NULL , " > " , & next_token1);
170
+ // Add 1 to the total number of elements
171
+ num_ptr++;
172
+ }
173
+
174
+ // Free up memory used for counting the list of elements
175
+ free (work_buf);
176
+
177
+ /*
178
+ * Create a new 2nd copy of the pointer path file buffer
179
+ */
180
+
181
+ // Allocate buffer the size of the mee.ptr file
182
+ work_buf = (char * ) malloc (sz);
183
+ // Copy contents of mee.ptr file into new buffer
184
+ memcpy_s (work_buf, sz, file_contents, sz);
185
+
186
+ /*
187
+ * Allocate the memory required for the interger array
188
+ * Then convert each ASCII Hex Code to an int
189
+ * And store it in the pointer paths array.
190
+ */
191
+
192
+ // Allocate memory buffer the size of the required int array
193
+ pointer_path = (int * ) malloc (num_ptr * sizeof (int ));
194
+
195
+ // Pointer to the next element, NULL for now.
196
+ char * next_token2 = NULL ;
197
+ // Get the pointer to the first element (seperated by " > ")
198
+ char * ptrs = strtok_s (work_buf, " > " , & next_token2);
199
+ // Convert the ascii string to a int value, and put it into the int array
200
+ pointer_path[0 ] = (int ) strtol (ptrs, & tmp, 16 );
201
+
202
+ // Repeat until read all pointers
203
+ for (int i = 1 ; i < num_ptr; i++) {
204
+ // Read the next element (seperated by " > ")
205
+ ptrs = strtok_s (NULL , " > " , & next_token2);
206
+ // Convert the ascii string to a int value, and put it into the int array
207
+ pointer_path[i] = (int ) strtol (ptrs, & tmp, 16 );
208
+ }
209
+
210
+ // Finally close the mee.ptr file
211
+ fclose (ptr_file);
212
+
213
+ // Free up memory used for reading the list of elements
214
+ free (work_buf);
215
+ // Free up memory used for the file contents
216
+ free (file_contents);
217
+
218
+ printf_s (" Loaded %s!\n " , MEE_POINTER_FILE);
219
+ } else // If no mee.ptr file is found ... OR the process dont have permission to read it
220
+ {
221
+ // Set number of elements to a default number
222
+ num_ptr = 8 ;
223
+ // Allocate enough space for an int array of that size
224
+ pointer_path = (int * ) malloc (num_ptr * sizeof (int ));
225
+ #ifdef _WIN64 // This code is only included if the project is built as win64 version
226
+ printf_s (" Failed, using default pointer path (MCEE 1.17.30 UWP x64)\n " );
227
+ // Use a default pointer path.
228
+ pointer_path[0 ] = 0x3607D48 ;
229
+ pointer_path[1 ] = 0x0 ;
230
+ pointer_path[2 ] = 0x50 ;
231
+ pointer_path[3 ] = 0xA8 ;
232
+ pointer_path[4 ] = 0xE8 ;
233
+ pointer_path[5 ] = 0x0 ;
234
+ pointer_path[6 ] = 0x630 ;
235
+ pointer_path[7 ] = 0x10 ;
236
+ #else // if its NOT the win64 version..
237
+ printf_s (" Failed, using default pointer path (MCEE 1.17.30 Win32 x86)\n " );
238
+ // Use a default pointer path.
239
+ pointer_path[0 ] = 0x2CBF0FC ;
240
+ pointer_path[1 ] = 0x0 ;
241
+ pointer_path[2 ] = 0x7C ;
242
+ pointer_path[3 ] = 0x0 ;
243
+ pointer_path[4 ] = 0x68 ;
244
+ pointer_path[5 ] = 0xC ;
245
+ pointer_path[6 ] = 0x2E4 ;
246
+ pointer_path[7 ] = 0x8 ;
247
+ #endif
248
+ }
249
+
250
+ /*
251
+ * Print the currently in use
252
+ * pointer path to the output of the terminal
253
+ */
254
+
255
+ // Print "Pointer Path: "
256
+ printf_s (" \n Pointer Path: " );
257
+ for (int i = 0 ; i < num_ptr; i++) // Repeat for all elements in the path
258
+ {
259
+ // Print the hex encoding of the current element
260
+ printf_s (" %x" , pointer_path[i]);
261
+ if (i != num_ptr - 1 ) // if its not the last element
262
+ {
263
+ // Print " > "
264
+ printf_s (" > " );
265
+ }
266
+ }
267
+ // Print a newline
268
+ printf_s (" \n " );
269
+
270
+ /*
271
+ * This part is the part that actually patches
272
+ * Education edition's memory space
273
+ */
274
+
275
+ // Process ID of minecraft educattion ediion application, (currently 0)
276
+ DWORD proc_id = 0 ;
277
+ printf_s (" \n Please open Minecraft Education Edition\n " );
278
+
279
+ /*
280
+ * Repeatidly check if "Minecraft.Windows.exe" or "Minecraft.Win10.DX11.exe" is open
281
+ */
282
+ while (proc_id == 0 ) {
283
+ proc_id = GetProcId (L" Minecraft.Windows.exe" ); // Try to get the process ID for "Minecraft.Windows"
284
+ if (proc_id == 0 ) // If the process ID is NULL (process not found)
285
+ proc_id = GetProcId (L" Minecraft.Win10.DX11.exe" ); // Try to get the process ID for "Minecrat.Win10.DX11.exe"
286
+ }
287
+ // Print the process ID
288
+ printf_s (" MCEE Process ID: %x\n " , proc_id);
289
+ // Try to open the process.
290
+ HANDLE hProcess = OpenProcess (PROCESS_ALL_ACCESS, TRUE , proc_id);
291
+ // Print the process handle
292
+ printf_s (" MCEE Process Handle: 0x%p\n " , hProcess);
293
+
294
+ if (!hProcess) // If failed to open the process (eg no permission)
295
+ {
296
+ // Display a message box saying to try with admin rights
297
+ MessageBox (NULL , " Cannot open process!\r\n Try \" Run as administrator\" " , " Error!" , MB_OK + MB_ICONERROR);
298
+ } else {
299
+ // Base Address of the minecraft education edition process (NULL for now)
300
+ uintptr_t baseAddress = 0 ;
301
+ while (baseAddress == 0 ) // Repeat until the base address is not NULL.
302
+ // Try to get the base address of the Minecraft Education Edition Process
303
+ baseAddress = GetProcessBaseAddress (proc_id);
304
+
305
+ printf_s (" MCEE Base Addr: 0x%p\n " , (void * ) baseAddress);
306
+ printf_s (" Waiting for game to initalize....\n " );
307
+
308
+ read_ptr_path:
309
+
310
+ // recalculate base address idk why but this seems to be required.
311
+ baseAddress = GetProcessBaseAddress (proc_id);
312
+
313
+ // Read first element
314
+ uintptr_t first_ptr = pointer_path[0 ];
315
+ uintptr_t cur_ptr = baseAddress + first_ptr;
316
+ uintptr_t ptr = 0 ;
317
+ uintptr_t new_ptr = 0 ;
318
+
319
+ // Read first element from the games memory
320
+ ReadProcessMemory (hProcess, (LPCVOID) cur_ptr, & ptr, sizeof (uintptr_t ), 0 );
321
+ if (ptr == 0 )
322
+ goto read_ptr_path;
323
+
324
+ /*
325
+ * Follow all elements
326
+ * in the path, until you reach
327
+ * the pointer to the login step value.
328
+ */
329
+ for (int i = 1 ; i < num_ptr - 1 ; i++) {
330
+ cur_ptr = ptr + pointer_path[i];
331
+ ReadProcessMemory (hProcess, (LPCVOID) cur_ptr, & new_ptr, sizeof (uintptr_t ), 0 );
332
+ if (new_ptr == 0 ) {
333
+ i -= 1 ;
334
+ goto read_ptr_path;
335
+ } else {
336
+ ptr = new_ptr;
337
+
338
+ }
339
+ }
340
+
341
+ // final addition
342
+ ptr += pointer_path[num_ptr - 1 ];
343
+
344
+ // Wait for Welcome Screen.
345
+ int login_step_value = 0 ;
346
+ ReadProcessMemory (hProcess, (LPCVOID) ptr, & login_step_value, sizeof (int ), 0 );
347
+
348
+ if (login_step_value != 0x0 ) {
349
+
350
+ printf_s (" Final Ptr: 0x%p\n " , (void * ) ptr);
351
+
352
+ printf_s (" Current Login Step: %i\n " , login_step_value);
353
+ if (LOGIN_STEP_VALUE != -1 ) {
354
+ printf_s (" Trying login stage %i" , LOGIN_STEP_VALUE);
355
+ WriteProcessMemory (hProcess, (LPVOID) ptr, & LOGIN_STEP_VALUE, sizeof (int ), 0 );
356
+ goto finish;
357
+ }
358
+
359
+ printf_s (" Trying login stage 5...\n " ); // Backwards Comp (0.xx)
360
+ int login_step_value = 5 ;
361
+ WriteProcessMemory (hProcess, (LPVOID) ptr, & login_step_value, sizeof (int ), 0 );
362
+
363
+ Sleep (1 * 200 );
364
+
365
+ printf_s (" Trying login stage 6...\n " ); // Backwards Comp (1.9 and lower)
366
+ login_step_value = 6 ;
367
+ WriteProcessMemory (hProcess, (LPVOID) ptr, & login_step_value, sizeof (int ), 0 );
368
+
369
+ Sleep (1 * 200 );
370
+
371
+ printf_s (" Trying login stage 8...\n " );
372
+ login_step_value = 8 ;
373
+ WriteProcessMemory (hProcess, (LPVOID) ptr, & login_step_value, sizeof (int ), 0 );
374
+
375
+ } else
376
+ goto read_ptr_path;
377
+
378
+ finish:
379
+
380
+ CloseHandle (hProcess);
381
+
382
+ printf_s (" \n Success!\n " );
383
+ return 0 ;
384
+ }
385
+ }
0 commit comments