1
+ #include < Windows.h>
2
+ #include < iomanip>
3
+ #include < iostream>
4
+ #include < vector>
5
+
6
+
7
+ namespace {
8
+ struct AddressAndReg {
9
+ DWORD func_rva_start;
10
+ DWORD func_rva_end;
11
+ const std::vector<BYTE> native_code;
12
+ };
13
+
14
+ // 0~26 VanillaDimensions::toSerializedInt
15
+ // 27~39 VanillaDimensions::fromSerializedInt(int)
16
+ std::vector<AddressAndReg> data = {
17
+ {0x082BA6F , 0x082BA9A , {0x89 , 0xC8 } },
18
+ {0x26D1CFB , 0x26D1D1F , {0x89 , 0xC3 } },
19
+ {0x10F0CD7 , 0x10F0D00 , {0x89 , 0xC2 } },
20
+ {0x10FFF2E , 0x10FFF57 , {0x89 , 0xC2 } },
21
+ {0x1107480 , 0x11074A9 , {0x89 , 0xC2 } },
22
+ {0x1108365 , 0x110838E , {0x89 , 0xC2 } },
23
+ {0x121CE22 , 0x121CE4B , {0x89 , 0xC3 } },
24
+ {0x123B4A3 , 0x123B4C6 , {0x89 , 0xC3 } },
25
+ {0x124926F , 0x1249298 , {0x89 , 0xC2 } },
26
+ {0x1262064 , 0x126208D , {0x89 , 0xC2 } },
27
+ {0x1B0D610 , 0x1B0D638 , {0x41 , 0x88 , 0xC9 } },
28
+ {0x1B0D8DB , 0x1B0D8FE , {0x88 , 0xC8 } },
29
+ {0x1D8677C , 0x1D867A4 , {0x41 , 0x88 , 0xC9 } },
30
+ {0x27A6E57 , 0x27A6E82 , {0x89 , 0xC3 } },
31
+ {0x2803614 , 0x280363F , {0x89 , 0xC3 } },
32
+ {0x2803ABD , 0x2803AE9 , {0x89 , 0xDF } },
33
+ {0x280089F , 0x28008C5 , {0x41 , 0x89 , 0xC6 } },
34
+ {0x281BE40 , 0x281BE69 , {0x89 , 0xC3 } },
35
+ {0x281B5B0 , 0x281B5DB , {0x89 , 0xD3 } },
36
+ {0x2B45EA2 , 0x2B45ED0 , {0x41 , 0x89 , 0xC6 } },
37
+ {0x2B48EA0 , 0x2B48EC4 , {0x89 , 0xC7 } },
38
+ {0x2B502EE , 0x2B50311 , {0x88 , 0xD8 } },
39
+ {0x2AA89D3 , 0x2AA89F6 , {0x89 , 0xC3 } },
40
+ {0x31078C2 , 0x31078F0 , {0x41 , 0x89 , 0xC3 } },
41
+ {0x31D6A15 , 0x31D6A39 , {0x89 , 0xCB } },
42
+ {0x31D7A6E , 0x31D7A93 , {0x89 , 0xDF } },
43
+ {0x337435D , 0x3374385 , {0x40 , 0x88 , 0xC7 } },
44
+ {0x27A9901 , 0x27A9931 , {0x41 , 0x89 , 0xC8 } },
45
+ {0x27C09AC , 0x27C09D8 , {0x89 , 0xC8 } },
46
+ {0x0C262E0 , 0x0C26330 , {0x89 , 0x8E , 0x3C , 0x00 , 0x00 , 0x00 }},
47
+ {0x11F1079 , 0x11F10A5 , {0x89 , 0xCB } },
48
+ {0x121C5A7 , 0x121C5D3 , {0x89 , 0xCF } },
49
+ {0x16D27E5 , 0x16D281D , {0x89 , 0xC8 } },
50
+ {0x281B520 , 0x281B582 , {0x89 , 0xC8 } },
51
+ {0x280189D , 0x2801A4C , {0x89 , 0x8E , 0x30 , 0x0B , 0x00 , 0x00 }},
52
+ {0x281BE40 , 0x281BE69 , {0x89 , 0xC3 } },
53
+ {0x2B45771 , 0x2B4579D , {0x89 , 0xC8 } },
54
+ {0x2B490CE , 0x2B490FA , {0x89 , 0xC8 } },
55
+ {0x31DDBA4 , 0x31DDBD0 , {0x89 , 0xC8 } },
56
+ {0x3376088 , 0x33760B7 , {} }
57
+ };
58
+
59
+ bool PatchFunction (HMODULE hModule, DWORD faddress_start, DWORD faddress_end, const std::vector<BYTE>& native_code) {
60
+ LPVOID patchAddress = (LPVOID)((DWORD_PTR)hModule + faddress_start);
61
+
62
+
63
+ // Construct the patch
64
+ std::vector<BYTE> patch;
65
+
66
+ patch.insert (patch.end (), native_code.begin (), native_code.end ());
67
+
68
+
69
+ // jmp faddress_end
70
+ // Calculate the relative offset for the jump
71
+ DWORD_PTR offset = (DWORD_PTR)hModule + faddress_end
72
+ - ((DWORD_PTR)patchAddress + patch.size () + 5 ); // +5 for the size of the jmp instruction
73
+
74
+ patch.push_back (0xE9 ); // jmp opcode
75
+ patch.push_back ((BYTE)(offset & 0xFF ));
76
+ patch.push_back ((BYTE)((offset >> 8 ) & 0xFF ));
77
+ patch.push_back ((BYTE)((offset >> 16 ) & 0xFF ));
78
+ patch.push_back ((BYTE)((offset >> 24 ) & 0xFF ));
79
+
80
+ HANDLE hProcess = OpenProcess (PROCESS_ALL_ACCESS, FALSE , GetCurrentProcessId ());
81
+
82
+ // Write the patch to memory
83
+ DWORD oldProtect;
84
+ if (!VirtualProtect (patchAddress, patch.size (), PAGE_EXECUTE_READWRITE, &oldProtect)) {
85
+ std::cerr << " Failed to change memory protection" << std::endl;
86
+ return false ;
87
+ }
88
+
89
+ SIZE_T bytesWritten;
90
+ if (!WriteProcessMemory (hProcess, patchAddress, patch.data (), patch.size (), &bytesWritten)
91
+ || bytesWritten != patch.size ()) {
92
+ std::cerr << " Failed to write to process memory" << std::endl;
93
+ CloseHandle (hProcess);
94
+ return false ;
95
+ }
96
+
97
+ if (!VirtualProtect (patchAddress, patch.size (), oldProtect, &oldProtect)) {
98
+ std::cerr << " Failed to restore memory protection" << std::endl;
99
+ return false ; // Though the patch is applied, restoring protection failed.
100
+ }
101
+
102
+ return true ;
103
+ }
104
+
105
+ void printHexBytes (const void * address, size_t numBytes) {
106
+ const unsigned char * start = static_cast <const unsigned char *>(address);
107
+
108
+ for (size_t i = 0 ; i < numBytes; ++i) {
109
+ std::cout << std::hex << std::setw (2 ) << std::setfill (' 0' ) << static_cast <int >(start[i]) << " " ;
110
+ // Optionally add a newline after every 16 bytes for better readability
111
+ if ((i + 1 ) % 16 == 0 ) {
112
+ std::cout << std::endl;
113
+ }
114
+ }
115
+ std::cout << std::dec << std::endl; // Reset to decimal output
116
+ }
117
+
118
+ } // namespace
119
+
120
+
121
+ void injectNaticeCode () {
122
+ // Calculate the address in the target process
123
+ HMODULE hModule = GetModuleHandle (L" bedrock_server_mod.exe" );
124
+ if (!hModule) {
125
+ std::cerr << " Failed to get module handle for bedrock_server_mod.exe" << std::endl;
126
+ return ;
127
+ }
128
+ for (auto & item : data) {
129
+ PatchFunction (hModule, item.func_rva_start , item.func_rva_end , item.native_code );
130
+ };
131
+ };
0 commit comments