+1
include/hv_funcs.h
+1
include/hv_funcs.h
+1
include/xboxkrnl.h
+1
include/xboxkrnl.h
···
6
6
extern void XapiThreadStartup(void (__cdecl *StartRoutine)(void *), void * StartContext);
7
7
extern unsigned int XexGetModuleHandle(PCSTR moduleName, PHANDLE hand);
8
8
extern unsigned int XexGetProcedureAddress(HANDLE hand, DWORD dwOrdinal, PVOID Address);
9
+
extern unsigned int XexLoadImage(LPCSTR szXexName, DWORD dwModuleTypeFlags, DWORD dwMinimumVersion, PHANDLE pHandle);
+41
-2
source/FreeMyXe.c
+41
-2
source/FreeMyXe.c
···
42
42
0x38, 0x80, 0x00, 0x07, 0x7C, 0x21, 0x20, 0x78, 0x7C, 0x35, 0xEB, 0xA6, 0x48, 0x00, 0x11, 0xC2
43
43
};
44
44
45
+
// this doesn't work!
46
+
void ApplyXeBuildPatches(uint8_t *patch_data)
47
+
{
48
+
uint32_t *patches = (uint32_t *)patch_data;
49
+
while (1)
50
+
{
51
+
uint32_t length;
52
+
size_t size;
53
+
int i = 0;
54
+
// get the address - if it's 0xFFFFFFFF we've hit the end
55
+
uint32_t address = patches[0];
56
+
if (address == 0xFFFFFFFF)
57
+
break;
58
+
// get the length and byte size of the patch
59
+
length = patches[1];
60
+
size = length * sizeof(uint32_t);
61
+
patches += 2;
62
+
// print info
63
+
DbgPrint("0x%08x: 0x%x words (0x%x bytes)\n", address, length, size);
64
+
for (i = 0; i < length; i++)
65
+
{
66
+
if (address > 0x40000)
67
+
{
68
+
// this isn't correct - the whole system locks up
69
+
uint64_t val = (*(uint64_t *)(0x80000000 | (address - 4)) & 0xFFFFFFFF00000000) | patches[i];
70
+
WriteHypervisorUInt64_RMCI(address, val);
71
+
}
72
+
else
73
+
{
74
+
WriteHypervisorUInt32(address, patches[i]);
75
+
}
76
+
}
77
+
patches += length;
78
+
}
79
+
}
80
+
45
81
void __cdecl main()
46
82
{
47
83
uint8_t cpu_key[0x10];
···
75
111
wsprintfW(dialog_text_buffer, L"About to start patching HV and kernel...\n\nYour CPU key is:\n%08X%08X%08X%08X\n\ngithub.com/InvoxiPlayGames/FreeMyXe", *(uint32_t *)(cpu_key + 0x0), *(uint32_t *)(cpu_key + 0x4), *(uint32_t *)(cpu_key + 0x8), *(uint32_t *)(cpu_key + 0xC));
76
112
MessageBox(dialog_text_buffer);
77
113
114
+
// launch xell
115
+
//HypervisorExecute(0x800000001c040000, xell2f, sizeof(xell2f));
116
+
78
117
DbgPrint("Writing syscall 0 backdoor...\n");
79
118
// install the syscall 0 backdoor at a spare place in memory
80
119
WriteHypervisor(0x0000B564, freeboot_memcpy_bytecode, sizeof(freeboot_memcpy_bytecode));
···
84
123
DbgPrint("Writing memory protection patches...\n");
85
124
// write the patched memory protection instructions
86
125
WriteHypervisor(0x0000154C, memory_protection_bytecode, sizeof(memory_protection_bytecode));
87
-
// jump to the above shellcode
126
+
// jump to the above shellcode
88
127
WriteHypervisorUInt32(0x000011BC, 0x4800154E);
89
128
HypervisorClearCache(0x0000154C);
90
129
···
150
189
WriteHypervisorUInt64_RMCI(MmGetPhysicalAddress(pdwFunction), valTo);
151
190
HypervisorClearCache(MmGetPhysicalAddress(pdwFunction));
152
191
}
153
-
192
+
154
193
DbgPrint("Done\n");
155
194
156
195
Sleep(500);
+22
source/hv_funcs.c
+22
source/hv_funcs.c
···
144
144
XPhysicalFree(shellcode_buf);
145
145
}
146
146
147
+
void HypervisorExecute(uint64_t address, void *code, size_t length)
148
+
{
149
+
uint64_t hv_target = GetHVTargetAddress(address);
150
+
// allocate a buffer for our write
151
+
uint8_t *payload_buf = (uint8_t *)XPhysicalAlloc(0x40000, MAXULONG_PTR, 0, PAGE_READWRITE);
152
+
uint64_t payload_addr = 0x8000000000000000 | MmGetPhysicalAddress(payload_buf);
153
+
memcpy(payload_buf, code, length);
154
+
{
155
+
// allocate a buffer for our freeboot memcpy
156
+
uint8_t *shellcode_buf = (uint8_t *)XPhysicalAlloc(0x1000, MAXULONG_PTR, 0, PAGE_READWRITE);
157
+
uint64_t shellcode_addr = 0x8000000000000000 | MmGetPhysicalAddress(shellcode_buf);
158
+
memcpy(shellcode_buf, freeboot_memcpy_bytecode, sizeof(freeboot_memcpy_bytecode));
159
+
// patch the freeboot memcpy to always have r4 as hv execute (4) and turn the beq after to a b
160
+
*(uint32_t *)(shellcode_buf + 0x8) = LI(4, 4);
161
+
*(uint16_t *)(shellcode_buf + 0xC) = 0x4800;
162
+
// use the hvxpostoutput backdoor to perform the memcpy
163
+
HvxPostOutputMemcpy(0x72627472, shellcode_addr, address, payload_addr, 0x40000);
164
+
XPhysicalFree(shellcode_buf);
165
+
}
166
+
XPhysicalFree(payload_buf);
167
+
}
168
+
147
169
void WriteHypervisorUInt32_RMCI(uint32_t address, uint32_t value)
148
170
{
149
171
uint64_t hv_target = GetHVTargetAddress(address);