From a2b6994572dd680f3573ad705b2e39cbe4a4ba91 Mon Sep 17 00:00:00 2001 From: google0101-ryan Date: Mon, 8 Jan 2024 19:03:41 +0000 Subject: [PATCH] deploy: 502501b5afa9ab7c7c844420548e3f748e5a406e --- annotated.html | 29 +- classes.html | 23 +- d5/d16/xex_8cpp_source.html | 736 ++++++++++++++-------------- d8/d71/memory_8cpp_source.html | 453 +++++++++-------- d8/dc6/classXexLoader.html | 8 +- d9/d08/structAllocInfo-members.html | 89 ++++ dc/d18/memory_8h_source.html | 50 +- de/de7/structAllocInfo.html | 134 +++++ df/d0a/main_8cpp_source.html | 41 +- doxygen_crawl.html | 2 + hierarchy.html | 31 +- inherit_graph_0.map | 2 +- inherit_graph_0.md5 | 2 +- inherit_graph_0.png | Bin 2309 -> 1153 bytes inherit_graph_1.map | 2 +- inherit_graph_1.md5 | 2 +- inherit_graph_1.png | Bin 1734 -> 2309 bytes inherit_graph_10.map | 2 +- inherit_graph_10.md5 | 2 +- inherit_graph_10.png | Bin 1241 -> 2056 bytes inherit_graph_11.map | 2 +- inherit_graph_11.md5 | 2 +- inherit_graph_11.png | Bin 1427 -> 1241 bytes inherit_graph_12.map | 2 +- inherit_graph_12.md5 | 2 +- inherit_graph_12.png | Bin 1392 -> 1427 bytes inherit_graph_13.map | 2 +- inherit_graph_13.md5 | 2 +- inherit_graph_13.png | Bin 1539 -> 1392 bytes inherit_graph_14.map | 3 + inherit_graph_14.md5 | 1 + inherit_graph_14.png | Bin 0 -> 1539 bytes inherit_graph_2.map | 4 +- inherit_graph_2.md5 | 2 +- inherit_graph_2.png | Bin 2965 -> 1734 bytes inherit_graph_3.map | 4 +- inherit_graph_3.md5 | 2 +- inherit_graph_3.png | Bin 1775 -> 2965 bytes inherit_graph_4.map | 2 +- inherit_graph_4.md5 | 2 +- inherit_graph_4.png | Bin 1634 -> 1775 bytes inherit_graph_5.map | 2 +- inherit_graph_5.md5 | 2 +- inherit_graph_5.png | Bin 2454 -> 1634 bytes inherit_graph_6.map | 2 +- inherit_graph_6.md5 | 2 +- inherit_graph_6.png | Bin 2653 -> 2454 bytes inherit_graph_7.map | 2 +- inherit_graph_7.md5 | 2 +- inherit_graph_7.png | Bin 2481 -> 2653 bytes inherit_graph_8.map | 2 +- inherit_graph_8.md5 | 2 +- inherit_graph_8.png | Bin 1746 -> 2481 bytes inherit_graph_9.map | 2 +- inherit_graph_9.md5 | 2 +- inherit_graph_9.png | Bin 2056 -> 1746 bytes inherits.html | 33 +- search/all_0.js | 2 +- search/all_1.js | 2 +- search/all_2.js | 3 +- search/all_3.js | 3 +- search/all_4.js | 2 +- search/all_5.js | 2 +- search/all_6.js | 3 +- search/all_7.js | 3 +- search/all_8.js | 2 +- search/all_9.js | 2 +- search/all_a.js | 5 +- search/all_b.js | 7 + search/classes_0.js | 2 +- search/classes_1.js | 2 +- search/classes_2.js | 2 +- search/classes_3.js | 2 +- search/classes_4.js | 2 +- search/classes_5.js | 3 +- search/classes_6.js | 3 +- search/classes_7.js | 2 +- search/classes_8.js | 2 +- search/classes_9.js | 5 +- search/classes_a.js | 7 + search/searchdata.js | 4 +- 81 files changed, 1028 insertions(+), 737 deletions(-) create mode 100644 d9/d08/structAllocInfo-members.html create mode 100644 de/de7/structAllocInfo.html create mode 100644 inherit_graph_14.map create mode 100644 inherit_graph_14.md5 create mode 100644 inherit_graph_14.png create mode 100644 search/all_b.js create mode 100644 search/classes_a.js diff --git a/annotated.html b/annotated.html index 1d88544..73527f2 100644 --- a/annotated.html +++ b/annotated.html @@ -77,20 +77,21 @@
Here are the classes, structs, unions and interfaces with brief descriptions:
- - - - - - - - - - - - - - + + + + + + + + + + + + + + +
 CbasicCompression_t
 CfileFormatInfo_t
 CimportHeader_t
 ClibraryHeader_t
 CmspackMemoryFile_t
 CnormalCompressionBlock_t
 CnormalCompressionHeader_t
 CoptionalHeader_tFollowing the XEX header are xexHeader_t::optional_header_count optional headers, which either contain an offset to a struct, or a value
 CpageDescriptor_t
 Cuint128_t
 CxexExport_t
 CxexHeader_tThe header of a .xex file
 CxexLibrary_t
 CXexLoader
 CAllocInfo
 CbasicCompression_t
 CfileFormatInfo_t
 CimportHeader_t
 ClibraryHeader_t
 CmspackMemoryFile_t
 CnormalCompressionBlock_t
 CnormalCompressionHeader_t
 CoptionalHeader_tFollowing the XEX header are xexHeader_t::optional_header_count optional headers, which either contain an offset to a struct, or a value
 CpageDescriptor_t
 Cuint128_t
 CxexExport_t
 CxexHeader_tThe header of a .xex file
 CxexLibrary_t
 CXexLoader
diff --git a/classes.html b/classes.html index a03ba43..c9cf71b 100644 --- a/classes.html +++ b/classes.html @@ -75,36 +75,39 @@
Class Index
-
B | F | I | L | M | N | O | P | U | X
+
A | B | F | I | L | M | N | O | P | U | X
diff --git a/d5/d16/xex_8cpp_source.html b/d5/d16/xex_8cpp_source.html index f45f7e7..e24a4a3 100644 --- a/d5/d16/xex_8cpp_source.html +++ b/d5/d16/xex_8cpp_source.html @@ -166,385 +166,389 @@
79 optHeaders.push_back(opt);
80 }
81
-
82 mainXexSize = image_size();
-
83
-
84 // Parse security info, including AES key decryption
-
85 uint8_t* aes_key = (buffer+header.sec_info_offset+336);
-
86 aes_decrypt_buffer(xe_xex2_retail_key, aes_key, 16, session_key, 16);
-
87
-
88 printf("AES key is 0x%02x", session_key[0]);
-
89 for (int i = 0; i < 15; i++)
-
90 {
-
91 printf("%02x", session_key[i+1]);
-
92 }
-
93 printf("\n");
-
94
-
95 for (auto& hdr : optHeaders)
-
96 {
-
97 switch (hdr.id)
-
98 {
-
99 case 0x2ff:
-
100 break;
-
101 case 0x3ff:
-
102 {
-
103 fileInfoOffset = hdr.offset;
-
104 ParseFileInfo(hdr.offset);
-
105 break;
-
106 }
-
107 case 0x10100:
-
108 entryPoint = hdr.value;
-
109 printf("Image entry point is 0x%08x\n", entryPoint);
-
110 break;
-
111 case 0x10201:
-
112 baseAddress = hdr.value;
-
113 mainXexBase = baseAddress;
-
114 printf("Image base is 0x%08x\n", baseAddress);
-
115 break;
-
116 case 0x103FF:
-
117 importBaseAddr = hdr.offset;
-
118 break;
-
119 case 0x20200:
-
120 stackSize = hdr.value;
-
121 printf("Stack size is 0x%08x\n", hdr.value);
-
122 break;
-
123 default:
-
124 printf("Unknown optional header ID: 0x%08x\n", hdr.id);
-
125 }
-
126 }
-
127
-
128 // Decrypt/decompress the file
-
129 printf("%d, %d\n", encryptionFormat, compressionFormat);
-
130 char* outBuffer;
-
131 uint32_t uncompressedSize;
-
132 switch (compressionFormat)
-
133 {
-
134 case 1:
-
135 uncompressedSize = ReadImageBasicCompressed(buffer, len, &outBuffer);
-
136 break;
-
137 case 2:
-
138 uncompressedSize = ReadImageCompressed(buffer, len, &outBuffer);
-
139 break;
-
140 default:
-
141 printf("Unknown compression format %d\n", compressionFormat);
-
142 exit(1);
-
143 }
-
144
-
145 std::ofstream out("out.pe");
-
146 out.write(outBuffer, uncompressedSize);
-
147 out.close();
-
148
-
149 // We've got the PE header inside outBuffer now
-
150 if (*(uint32_t*)outBuffer != 0x00905a4d /*"PE" followed by 0x9000*/)
-
151 {
-
152 printf("Invalid PE magic\n");
-
153 exit(1);
-
154 }
-
155
-
156 printf("Found valid PE header file\n");
-
157
-
158 void* base = Memory::AllocMemory(baseAddress, uncompressedSize);
-
159 memcpy(base, outBuffer, uncompressedSize);
-
160
-
161 // Load exports
-
162 exportBaseAddr = bswap32(*(uint32_t*)&buffer[header.sec_info_offset+0x160]);
-
163 exportTable.magic[0] = Memory::Read32(exportBaseAddr+0x00);
-
164 exportTable.magic[1] = Memory::Read32(exportBaseAddr+0x04);
-
165 exportTable.magic[2] = Memory::Read32(exportBaseAddr+0x08);
-
166 exportTable.modulenumber[0] = Memory::Read32(exportBaseAddr+0x0C);
-
167 exportTable.modulenumber[1] = Memory::Read32(exportBaseAddr+0x10);
-
168 exportTable.version[0] = Memory::Read32(exportBaseAddr+0x14);
-
169 exportTable.version[1] = Memory::Read32(exportBaseAddr+0x18);
-
170 exportTable.version[2] = Memory::Read32(exportBaseAddr+0x1C);
-
171 exportTable.imagebaseaddr = Memory::Read32(exportBaseAddr+0x20);
-
172 exportTable.count = Memory::Read32(exportBaseAddr+0x24);
-
173 exportTable.base = Memory::Read32(exportBaseAddr+0x28);
-
174
-
175 // Now we can patch module calls
-
176 // xam.xex and xboxkrnl.exe are the two most common imports afaict
-
177 importHeader_t importHdr = *(importHeader_t*)&buffer[importBaseAddr];
-
178 importHdr.size = bswap32(importHdr.size);
-
179 importHdr.stringTable.count = bswap32(importHdr.stringTable.count);
-
180 importHdr.stringTable.size = bswap32(importHdr.stringTable.size);
-
181
-
182 std::vector<std::string> importNames;
-
183 for (size_t i = 0, j = 0; i < importHdr.stringTable.size && j < importHdr.stringTable.count; j++)
-
184 {
-
185 const char* string = (const char*)&buffer[importBaseAddr+sizeof(importHeader_t)+i];
-
186 importNames.push_back(std::string(string));
-
187
-
188 i += strlen(string) + 1;
-
189 if ((i % 4) != 0)
-
190 i += 4 - (i % 4);
-
191
-
192 printf("Found import \"%s\"\n", string);
-
193 }
-
194
-
195 uint32_t libraryoffs = importHdr.stringTable.size + 12;
-
196 while (libraryoffs < importHdr.size)
-
197 {
-
198 libraryHeader_t libHdr = *(libraryHeader_t*)&buffer[importBaseAddr + libraryoffs];
-
199
-
200 libHdr.count = bswap16(libHdr.count);
-
201 libHdr.id = bswap32(libHdr.id);
-
202 libHdr.name_index = bswap16(libHdr.name_index);
-
203 libHdr.size = bswap32(libHdr.size);
-
204 libHdr.version_min_value = bswap32(libHdr.version_min_value);
-
205 libHdr.version_value = bswap32(libHdr.version_value);
-
206
-
207 xexLibrary_t lib;
-
208 lib.header = libHdr;
-
209 lib.name = importNames[libHdr.name_index];
-
210
-
211 printf("Parsing imports for \"%s\"\n", lib.name.c_str());
-
212
-
213 ParseLibraryInfo(importBaseAddr+libraryoffs+sizeof(libraryHeader_t), lib, libraries.size(), lib.name);
+
82 if (!mainXexSize)
+
83 mainXexSize = image_size();
+
84
+
85 // Parse security info, including AES key decryption
+
86 uint8_t* aes_key = (buffer+header.sec_info_offset+336);
+
87 aes_decrypt_buffer(xe_xex2_retail_key, aes_key, 16, session_key, 16);
+
88
+
89 printf("AES key is 0x%02x", session_key[0]);
+
90 for (int i = 0; i < 15; i++)
+
91 {
+
92 printf("%02x", session_key[i+1]);
+
93 }
+
94 printf("\n");
+
95
+
96 for (auto& hdr : optHeaders)
+
97 {
+
98 switch (hdr.id)
+
99 {
+
100 case 0x2ff:
+
101 break;
+
102 case 0x3ff:
+
103 {
+
104 fileInfoOffset = hdr.offset;
+
105 ParseFileInfo(hdr.offset);
+
106 break;
+
107 }
+
108 case 0x10100:
+
109 entryPoint = hdr.value;
+
110 printf("Image entry point is 0x%08x\n", entryPoint);
+
111 break;
+
112 case 0x10201:
+
113 baseAddress = hdr.value;
+
114 if (!mainXexBase)
+
115 mainXexBase = baseAddress;
+
116 printf("Image base is 0x%08x\n", baseAddress);
+
117 break;
+
118 case 0x103FF:
+
119 importBaseAddr = hdr.offset;
+
120 break;
+
121 case 0x20200:
+
122 stackSize = hdr.value;
+
123 printf("Stack size is 0x%08x\n", hdr.value);
+
124 break;
+
125 default:
+
126 printf("Unknown optional header ID: 0x%08x\n", hdr.id);
+
127 }
+
128 }
+
129
+
130 // Decrypt/decompress the file
+
131 printf("%d, %d\n", encryptionFormat, compressionFormat);
+
132 char* outBuffer;
+
133 uint32_t uncompressedSize;
+
134 switch (compressionFormat)
+
135 {
+
136 case 1:
+
137 uncompressedSize = ReadImageBasicCompressed(buffer, len, &outBuffer);
+
138 break;
+
139 case 2:
+
140 uncompressedSize = ReadImageCompressed(buffer, len, &outBuffer);
+
141 break;
+
142 default:
+
143 printf("Unknown compression format %d\n", compressionFormat);
+
144 exit(1);
+
145 }
+
146
+
147 std::ofstream out("out.pe");
+
148 out.write(outBuffer, uncompressedSize);
+
149 out.close();
+
150
+
151 // We've got the PE header inside outBuffer now
+
152 if (*(uint32_t*)outBuffer != 0x00905a4d /*"PE" followed by 0x9000*/)
+
153 {
+
154 printf("Invalid PE magic\n");
+
155 }
+
156 else
+
157 printf("Found valid PE header file\n");
+
158
+
159 void* base = Memory::AllocMemory(baseAddress, uncompressedSize);
+
160 memcpy(base, outBuffer, uncompressedSize);
+
161
+
162 // Load exports
+
163 exportBaseAddr = bswap32(*(uint32_t*)&buffer[header.sec_info_offset+0x160]);
+
164 if (exportBaseAddr)
+
165 {
+
166 exportTable.magic[0] = Memory::Read32(exportBaseAddr+0x00);
+
167 exportTable.magic[1] = Memory::Read32(exportBaseAddr+0x04);
+
168 exportTable.magic[2] = Memory::Read32(exportBaseAddr+0x08);
+
169 exportTable.modulenumber[0] = Memory::Read32(exportBaseAddr+0x0C);
+
170 exportTable.modulenumber[1] = Memory::Read32(exportBaseAddr+0x10);
+
171 exportTable.version[0] = Memory::Read32(exportBaseAddr+0x14);
+
172 exportTable.version[1] = Memory::Read32(exportBaseAddr+0x18);
+
173 exportTable.version[2] = Memory::Read32(exportBaseAddr+0x1C);
+
174 exportTable.imagebaseaddr = Memory::Read32(exportBaseAddr+0x20);
+
175 exportTable.count = Memory::Read32(exportBaseAddr+0x24);
+
176 exportTable.base = Memory::Read32(exportBaseAddr+0x28);
+
177 }
+
178
+
179 // Now we can patch module calls
+
180 // xam.xex and xboxkrnl.exe are the two most common imports afaict
+
181 importHeader_t importHdr = *(importHeader_t*)&buffer[importBaseAddr];
+
182 importHdr.size = bswap32(importHdr.size);
+
183 importHdr.stringTable.count = bswap32(importHdr.stringTable.count);
+
184 importHdr.stringTable.size = bswap32(importHdr.stringTable.size);
+
185
+
186 std::vector<std::string> importNames;
+
187 for (size_t i = 0, j = 0; i < importHdr.stringTable.size && j < importHdr.stringTable.count; j++)
+
188 {
+
189 const char* string = (const char*)&buffer[importBaseAddr+sizeof(importHeader_t)+i];
+
190 importNames.push_back(std::string(string));
+
191
+
192 i += strlen(string) + 1;
+
193 if ((i % 4) != 0)
+
194 i += 4 - (i % 4);
+
195
+
196 printf("Found import \"%s\"\n", string);
+
197 }
+
198
+
199 uint32_t libraryoffs = importHdr.stringTable.size + 12;
+
200 while (libraryoffs < importHdr.size)
+
201 {
+
202 libraryHeader_t libHdr = *(libraryHeader_t*)&buffer[importBaseAddr + libraryoffs];
+
203
+
204 libHdr.count = bswap16(libHdr.count);
+
205 libHdr.id = bswap32(libHdr.id);
+
206 libHdr.name_index = bswap16(libHdr.name_index);
+
207 libHdr.size = bswap32(libHdr.size);
+
208 libHdr.version_min_value = bswap32(libHdr.version_min_value);
+
209 libHdr.version_value = bswap32(libHdr.version_value);
+
210
+
211 xexLibrary_t lib;
+
212 lib.header = libHdr;
+
213 lib.name = importNames[libHdr.name_index];
214
-
215 libraries.push_back(lib);
-
216
-
217 libraryoffs += libHdr.size;
-
218 }
-
219
-
220 Kernel::RegisterModuleForName(GetName().c_str(), this);
-
221}
+
215 printf("Parsing imports for \"%s\"\n", lib.name.c_str());
+
216
+
217 ParseLibraryInfo(importBaseAddr+libraryoffs+sizeof(libraryHeader_t), lib, libraries.size(), lib.name);
+
218
+
219 libraries.push_back(lib);
+
220
+
221 libraryoffs += libHdr.size;
+
222 }
+
223
+
224 Kernel::RegisterModuleForName(GetName().c_str(), this);
+
225}
-
222
-
223uint32_t XexLoader::GetEntryPoint() const
-
224{
-
225 return entryPoint;
-
226}
-
227
-
228uint32_t XexLoader::GetStackSize() const
-
229{
-
230 return stackSize;
-
231}
-
232
-
233size_t XexLoader::GetLibraryIndexByName(const char *name) const
-
234{
-
235 for (int i = 0; i < libraries.size(); i++)
-
236 {
-
237 auto& lib = libraries[i];
-
238 if (lib.name == name)
-
239 return i;
-
240 }
-
241 return SIZE_MAX;
-
242}
-
243
-
244uint32_t XexLoader::LookupOrdinal(uint32_t ordinal)
-
245{
-
246 ordinal -= exportTable.base;
-
247 if (ordinal >= exportTable.count)
-
248 {
-
249 printf("ERROR: Imported unknown function 0x%08x\n", ordinal);
-
250 exit(1);
-
251 }
-
252
-
253 uint32_t num = ordinal;
-
254 uint32_t ordinal_offset = Memory::Read32(exportBaseAddr+sizeof(xexExport_t)+(num*4));
-
255 ordinal_offset += exportTable.imagebaseaddr << 16;
-
256 return ordinal_offset;
-
257}
-
258
-
259void XexLoader::ParseFileInfo(uint32_t offset)
-
260{
-
261 fileFormatInfo_t fileInfo = *(fileFormatInfo_t*)&buffer[offset];
-
262 fileInfo.info_size = bswap32(fileInfo.info_size);
-
263 fileInfo.compression_type = bswap16(fileInfo.compression_type);
-
264 fileInfo.encryption_type = bswap16(fileInfo.encryption_type);
-
265
-
266 printf("Found file info optional header: %d bytes, compression of type %d, encryption of type %d\n", fileInfo.info_size, fileInfo.compression_type, fileInfo.encryption_type);
-
267
-
268 compressionFormat = fileInfo.compression_type;
-
269 encryptionFormat = fileInfo.encryption_type;
-
270 info = fileInfo;
-
271}
-
272
-
273void XexLoader::ParseLibraryInfo(uint32_t offset, xexLibrary_t &lib, int index, std::string& name)
-
274{
-
275 for (uint32_t i = 0; i < lib.header.count; i++)
-
276 {
-
277 uint32_t recordAddr = bswap32(*(uint32_t*)&buffer[offset]);
-
278 offset += 4;
-
279
-
280 uint32_t record = Memory::Read32(recordAddr);
-
281
-
282 // Write the following routine to RAM:
-
283 // li r11, mod_func_id
-
284 // sc 2
-
285 // blr
-
286 // nop
-
287 if ((record >> 24) == 1 && name != "xam.xex")
-
288 {
-
289 Memory::Write32(recordAddr+0x00, 0x39600000 | (index << 12) | (record & 0xFFFF));
-
290 Memory::Write32(recordAddr+0x04, 0x44000042);
-
291 Memory::Write32(recordAddr+0x08, 0x4e800020);
-
292 Memory::Write32(recordAddr+0x0C, 0x60000000);
-
293 }
-
294 else if ((record >> 24) == 1 && name == "xam.xex")
-
295 {
-
296 // We instead write a stub to call xam.xex functions since we LLE it
-
297 assert(this != xam); // Should never happen, but just in case
-
298
-
299 // Get exports from xam.xex
-
300 uint32_t addr = xam->LookupOrdinal(record & 0xFFFF);
-
301 Memory::Write32(recordAddr+0x00, 0x3D600000 | addr >> 16);
-
302 Memory::Write32(recordAddr+0x04, 0x616B0000 | (addr & 0xFFFF));
-
303 Memory::Write32(recordAddr+0x08, 0x7D6903A6);
-
304 Memory::Write32(recordAddr+0x0C, 0x4E800420);
-
305 }
-
306 }
-
307}
-
308
-
309int XexLoader::ReadImageBasicCompressed(uint8_t *buffer, size_t xex_len, char** outBuffer)
-
310{
-
311 const uint8_t* p = buffer+header.header_size;
-
312 std::vector<basicCompression_t> blocks((info.info_size - 8) / 8);
-
313 uint32_t uncompressedSize = 0;
-
314 for (size_t i = 0; i < (info.info_size - 8) / 8; i++)
-
315 {
-
316 uint32_t offset = fileInfoOffset + 8 + (i * 8);
-
317 basicCompression_t comp = *(basicCompression_t*)&buffer[offset];
-
318 comp.data_size = bswap32(comp.data_size);
-
319 comp.zero_size = bswap32(comp.zero_size);
-
320 blocks.push_back(comp);
-
321 uncompressedSize += comp.data_size + comp.zero_size;
-
322 }
-
323
-
324 printf("Image is %d bytes uncompressed\n", uncompressedSize);
-
325
-
326 char* out = new char[uncompressedSize];
-
327 *outBuffer = out;
-
328 uint8_t* d = (uint8_t*)out;
+
226
+
227uint32_t XexLoader::GetEntryPoint() const
+
228{
+
229 return entryPoint;
+
230}
+
231
+
232uint32_t XexLoader::GetStackSize() const
+
233{
+
234 return stackSize;
+
235}
+
236
+
237size_t XexLoader::GetLibraryIndexByName(const char *name) const
+
238{
+
239 for (int i = 0; i < libraries.size(); i++)
+
240 {
+
241 auto& lib = libraries[i];
+
242 if (lib.name == name)
+
243 return i;
+
244 }
+
245 return SIZE_MAX;
+
246}
+
247
+
248uint32_t XexLoader::LookupOrdinal(uint32_t ordinal)
+
249{
+
250 ordinal -= exportTable.base;
+
251 if (ordinal >= exportTable.count)
+
252 {
+
253 printf("ERROR: Imported unknown function 0x%08x\n", ordinal);
+
254 exit(1);
+
255 }
+
256
+
257 uint32_t num = ordinal;
+
258 uint32_t ordinal_offset = Memory::Read32(exportBaseAddr+sizeof(xexExport_t)+(num*4));
+
259 ordinal_offset += exportTable.imagebaseaddr << 16;
+
260 return ordinal_offset;
+
261}
+
262
+
263void XexLoader::ParseFileInfo(uint32_t offset)
+
264{
+
265 fileFormatInfo_t fileInfo = *(fileFormatInfo_t*)&buffer[offset];
+
266 fileInfo.info_size = bswap32(fileInfo.info_size);
+
267 fileInfo.compression_type = bswap16(fileInfo.compression_type);
+
268 fileInfo.encryption_type = bswap16(fileInfo.encryption_type);
+
269
+
270 printf("Found file info optional header: %d bytes, compression of type %d, encryption of type %d\n", fileInfo.info_size, fileInfo.compression_type, fileInfo.encryption_type);
+
271
+
272 compressionFormat = fileInfo.compression_type;
+
273 encryptionFormat = fileInfo.encryption_type;
+
274 info = fileInfo;
+
275}
+
276
+
277void XexLoader::ParseLibraryInfo(uint32_t offset, xexLibrary_t &lib, int index, std::string& name)
+
278{
+
279 for (uint32_t i = 0; i < lib.header.count; i++)
+
280 {
+
281 uint32_t recordAddr = bswap32(*(uint32_t*)&buffer[offset]);
+
282 offset += 4;
+
283
+
284 uint32_t record = Memory::Read32(recordAddr);
+
285
+
286 // Write the following routine to RAM:
+
287 // li r11, mod_func_id
+
288 // sc 2
+
289 // blr
+
290 // nop
+
291 if ((record >> 24) == 1 && name != "xam.xex")
+
292 {
+
293 Memory::Write32(recordAddr+0x00, 0x39600000 | (index << 12) | (record & 0xFFFF));
+
294 Memory::Write32(recordAddr+0x04, 0x44000042);
+
295 Memory::Write32(recordAddr+0x08, 0x4e800020);
+
296 Memory::Write32(recordAddr+0x0C, 0x60000000);
+
297 }
+
298 else if ((record >> 24) == 1 && name == "xam.xex")
+
299 {
+
300 // We instead write a stub to call xam.xex functions since we LLE it
+
301 assert(this != xam); // Should never happen, but just in case
+
302
+
303 // Get exports from xam.xex
+
304 uint32_t addr = xam->LookupOrdinal(record & 0xFFFF);
+
305 Memory::Write32(recordAddr+0x00, 0x3D600000 | addr >> 16);
+
306 Memory::Write32(recordAddr+0x04, 0x616B0000 | (addr & 0xFFFF));
+
307 Memory::Write32(recordAddr+0x08, 0x7D6903A6);
+
308 Memory::Write32(recordAddr+0x0C, 0x4E800420);
+
309 }
+
310 }
+
311}
+
312
+
313int XexLoader::ReadImageBasicCompressed(uint8_t *buffer, size_t xex_len, char** outBuffer)
+
314{
+
315 const uint8_t* p = buffer+header.header_size;
+
316 std::vector<basicCompression_t> blocks((info.info_size - 8) / 8);
+
317 uint32_t uncompressedSize = 0;
+
318 for (size_t i = 0; i < (info.info_size - 8) / 8; i++)
+
319 {
+
320 uint32_t offset = fileInfoOffset + 8 + (i * 8);
+
321 basicCompression_t comp = *(basicCompression_t*)&buffer[offset];
+
322 comp.data_size = bswap32(comp.data_size);
+
323 comp.zero_size = bswap32(comp.zero_size);
+
324 blocks.push_back(comp);
+
325 uncompressedSize += comp.data_size + comp.zero_size;
+
326 }
+
327
+
328 printf("Image is %d bytes uncompressed\n", uncompressedSize);
329
-
330 uint32_t rk[4 * (MAXNR + 1)];
-
331 uint8_t ivec[16] = {0};
-
332 int32_t Nr = rijndaelKeySetupDec(rk, session_key, 128);
+
330 char* out = new char[uncompressedSize];
+
331 *outBuffer = out;
+
332 uint8_t* d = (uint8_t*)out;
333
-
334 for (size_t n = 0; n < blocks.size(); n++)
-
335 {
-
336 const uint32_t dataSize = blocks[n].data_size;
-
337 const uint32_t zeroSize = blocks[n].zero_size;
-
338
-
339 const uint8_t* ct = p;
-
340 uint8_t* pt = d;
-
341 for (size_t m = 0; m < dataSize; m += 16, ct += 16, pt += 16)
-
342 {
-
343 rijndaelDecrypt(rk, Nr, ct, pt);
-
344 for (size_t i = 0; i < 16; i++)
-
345 {
-
346 pt[i] ^= ivec[i];
-
347 ivec[i] = ct[i];
-
348 }
-
349 }
-
350
-
351 p += dataSize;
-
352 d += dataSize + zeroSize;
-
353 }
+
334 uint32_t rk[4 * (MAXNR + 1)];
+
335 uint8_t ivec[16] = {0};
+
336 int32_t Nr = rijndaelKeySetupDec(rk, session_key, 128);
+
337
+
338 for (size_t n = 0; n < blocks.size(); n++)
+
339 {
+
340 const uint32_t dataSize = blocks[n].data_size;
+
341 const uint32_t zeroSize = blocks[n].zero_size;
+
342
+
343 const uint8_t* ct = p;
+
344 uint8_t* pt = d;
+
345 for (size_t m = 0; m < dataSize; m += 16, ct += 16, pt += 16)
+
346 {
+
347 rijndaelDecrypt(rk, Nr, ct, pt);
+
348 for (size_t i = 0; i < 16; i++)
+
349 {
+
350 pt[i] ^= ivec[i];
+
351 ivec[i] = ct[i];
+
352 }
+
353 }
354
-
355 return uncompressedSize;
-
356}
-
357
-
358int XexLoader::ReadImageCompressed(uint8_t *buffer, size_t xex_len, char **outBuffer)
-
359{
-
360 const uint32_t exe_length = (uint32_t)(xex_len - header.header_size);
-
361 const uint8_t* exe_buffer = (const uint8_t*)(buffer + header.header_size);
-
362
-
363 uint8_t* compress_buffer = NULL;
-
364 const uint8_t* p = NULL;
-
365 uint8_t* d = NULL;
+
355 p += dataSize;
+
356 d += dataSize + zeroSize;
+
357 }
+
358
+
359 return uncompressedSize;
+
360}
+
361
+
362int XexLoader::ReadImageCompressed(uint8_t *buffer, size_t xex_len, char **outBuffer)
+
363{
+
364 const uint32_t exe_length = (uint32_t)(xex_len - header.header_size);
+
365 const uint8_t* exe_buffer = (const uint8_t*)(buffer + header.header_size);
366
-
367 bool free_input = false;
-
368 const uint8_t* input_buffer = exe_buffer;
-
369 size_t input_size = exe_length;
+
367 uint8_t* compress_buffer = NULL;
+
368 const uint8_t* p = NULL;
+
369 uint8_t* d = NULL;
370
-
371 switch (encryptionFormat)
-
372 {
-
373 case 0:
-
374 break;
-
375 case 1:
-
376 free_input = true;
-
377 input_buffer = (const uint8_t*)calloc(1, exe_length);
-
378 aes_decrypt_buffer(session_key, exe_buffer, exe_length, (uint8_t*)input_buffer, exe_length);
-
379 break;
-
380 }
-
381
-
382 normalCompressionHeader_t hdr = *(normalCompressionHeader_t*)(buffer + fileInfoOffset + sizeof(fileFormatInfo_t));
-
383 hdr.windowSize = bswap32(hdr.windowSize);
-
384 hdr.firstBlock.blockSize = bswap32(hdr.firstBlock.blockSize);
+
371 bool free_input = false;
+
372 const uint8_t* input_buffer = exe_buffer;
+
373 size_t input_size = exe_length;
+
374
+
375 switch (encryptionFormat)
+
376 {
+
377 case 0:
+
378 break;
+
379 case 1:
+
380 free_input = true;
+
381 input_buffer = (const uint8_t*)calloc(1, exe_length);
+
382 aes_decrypt_buffer(session_key, exe_buffer, exe_length, (uint8_t*)input_buffer, exe_length);
+
383 break;
+
384 }
385
-
386 normalCompressionBlock_t curBlock = hdr.firstBlock;
-
387
-
388 compress_buffer = (uint8_t*)calloc(1, exe_length);
+
386 normalCompressionHeader_t hdr = *(normalCompressionHeader_t*)(buffer + fileInfoOffset + sizeof(fileFormatInfo_t));
+
387 hdr.windowSize = bswap32(hdr.windowSize);
+
388 hdr.firstBlock.blockSize = bswap32(hdr.firstBlock.blockSize);
389
-
390 p = input_buffer;
-
391 d = compress_buffer;
-
392
-
393 int result_code = 0;
-
394
-
395 uint32_t blockOffs = sizeof(normalCompressionBlock_t);
-
396 while (curBlock.blockSize)
-
397 {
-
398 const uint8_t* pnext = p + curBlock.blockSize;
-
399 normalCompressionBlock_t next_block = *(normalCompressionBlock_t*)p;
-
400 blockOffs += sizeof(normalCompressionBlock_t);
-
401
-
402 next_block.blockSize = bswap32(next_block.blockSize);
-
403
-
404 p += 4;
-
405 p += 20;
-
406
-
407 while (true)
-
408 {
-
409 const size_t chunk_size = (p[0] << 8) | p[1];
-
410 p += 2;
-
411 if (!chunk_size)
-
412 break;
-
413
-
414 memcpy(d, p, chunk_size);
-
415 p += chunk_size;
-
416 d += chunk_size;
-
417 }
-
418
-
419 p = pnext;
-
420 curBlock = next_block;
-
421 }
+
390 normalCompressionBlock_t curBlock = hdr.firstBlock;
+
391
+
392 compress_buffer = (uint8_t*)calloc(1, exe_length);
+
393
+
394 p = input_buffer;
+
395 d = compress_buffer;
+
396
+
397 int result_code = 0;
+
398
+
399 uint32_t blockOffs = sizeof(normalCompressionBlock_t);
+
400 while (curBlock.blockSize)
+
401 {
+
402 const uint8_t* pnext = p + curBlock.blockSize;
+
403 normalCompressionBlock_t next_block = *(normalCompressionBlock_t*)p;
+
404 blockOffs += sizeof(normalCompressionBlock_t);
+
405
+
406 next_block.blockSize = bswap32(next_block.blockSize);
+
407
+
408 p += 4;
+
409 p += 20;
+
410
+
411 while (true)
+
412 {
+
413 const size_t chunk_size = (p[0] << 8) | p[1];
+
414 p += 2;
+
415 if (!chunk_size)
+
416 break;
+
417
+
418 memcpy(d, p, chunk_size);
+
419 p += chunk_size;
+
420 d += chunk_size;
+
421 }
422
-
423 uint32_t uncompressed_size = image_size();
-
424 char* out = new char[uncompressed_size];
-
425
-
426 (*outBuffer) = out;
-
427
-
428 if (!result_code)
-
429 {
-
430 std::memset(out, 0, uncompressed_size);
+
423 p = pnext;
+
424 curBlock = next_block;
+
425 }
+
426
+
427 uint32_t uncompressed_size = image_size();
+
428 char* out = new char[uncompressed_size];
+
429
+
430 (*outBuffer) = out;
431
-
432 result_code = lzx_decompress(compress_buffer, d - compress_buffer, out, uncompressed_size,
-
433 hdr.windowSize, nullptr, 0);
-
434 }
+
432 if (!result_code)
+
433 {
+
434 std::memset(out, 0, uncompressed_size);
435
-
436 if (compress_buffer)
-
437 free((void*)compress_buffer);
-
438 if (free_input)
-
439 free((void*)input_buffer);
-
440 return uncompressed_size;
-
441}
-
442
-
443uint32_t XexLoader::image_size()
-
444{
-
445 uint32_t pageDescriptorCount = bswap32(*(uint32_t*)&buffer[header.sec_info_offset + 0x180]);
+
436 result_code = lzx_decompress(compress_buffer, d - compress_buffer, out, uncompressed_size,
+
437 hdr.windowSize, nullptr, 0);
+
438 }
+
439
+
440 if (compress_buffer)
+
441 free((void*)compress_buffer);
+
442 if (free_input)
+
443 free((void*)input_buffer);
+
444 return uncompressed_size;
+
445}
446
-
447 uint32_t totalSize = 0;
-
448
-
449 for (int i = 0; i < pageDescriptorCount; i++)
-
450 {
-
451 uint32_t offs = header.sec_info_offset + 0x184 + (i * 0x18);
-
452 pageDescriptor_t page = *(pageDescriptor_t*)&buffer[offs];
-
453 page.value = bswap32(page.value);
-
454
-
455 totalSize += page.value * 4096;
-
456 }
-
457
-
458 return totalSize;
-
459}
+
447uint32_t XexLoader::image_size()
+
448{
+
449 uint32_t pageDescriptorCount = bswap32(*(uint32_t*)&buffer[header.sec_info_offset + 0x180]);
+
450
+
451 uint32_t totalSize = 0;
+
452
+
453 for (int i = 0; i < pageDescriptorCount; i++)
+
454 {
+
455 uint32_t offs = header.sec_info_offset + 0x184 + (i * 0x18);
+
456 pageDescriptor_t page = *(pageDescriptor_t*)&buffer[offs];
+
457 page.value = bswap32(page.value);
+
458
+
459 totalSize += page.value * 4096;
+
460 }
+
461
+
462 return totalSize;
+
463}
Definition xex.h:111
XexLoader(uint8_t *buffer, size_t len, std::string path)
Loads a .xex file from a buffer into memory.
Definition xex.cpp:46
Definition xex.h:39
diff --git a/d8/d71/memory_8cpp_source.html b/d8/d71/memory_8cpp_source.html index 5e7a6c4..4a49de3 100644 --- a/d8/d71/memory_8cpp_source.html +++ b/d8/d71/memory_8cpp_source.html @@ -100,230 +100,255 @@
14
15extern uint32_t mainThreadStackSize;
16
-
17uint8_t** readPages, **writePages;
-
18#define PAGE_SIZE (4*1024)
-
19#define MAX_ADDRESS_SPACE 0xFFFF0000
-
20std::bitset<MAX_ADDRESS_SPACE / PAGE_SIZE> usedPages;
-
21
-
22void Memory::Initialize()
-
23{
-
24 readPages = new uint8_t*[MAX_ADDRESS_SPACE / PAGE_SIZE];
-
25 writePages = new uint8_t*[MAX_ADDRESS_SPACE / PAGE_SIZE];
-
26 usedPages.reset();
-
27}
-
28
-
29void Memory::Dump()
-
30{
-
31 std::ofstream file("mem.dump");
-
32 for (uint32_t i = mainXexBase; i < mainXexBase+mainXexSize; i += 4)
-
33 {
-
34 uint32_t data = bswap32(Read32(i));
-
35 file.write((char*)&data, 4);
-
36 }
-
37 file.close();
-
38
-
39 file.open("stack.dump");
-
40 for (uint32_t i = 0x70000000; i < 0x70000000+mainThreadStackSize; i += 4)
-
41 {
-
42 uint32_t data = bswap32(Read32(i));
-
43 file.write((char*)&data, 4);
-
44 }
-
45 file.close();
-
46}
-
47
-
48void *Memory::AllocMemory(uint32_t baseAddress, uint32_t size)
-
49{
-
50 void* ret = mmap((void*)baseAddress, size, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
-
51
-
52 if (ret == MAP_FAILED)
-
53 {
-
54 printf("Failed to allocate memory: %s\n", strerror(errno));
-
55 exit(1);
-
56 }
-
57
-
58 size = (size + PAGE_SIZE) & ~PAGE_SIZE;
+
17std::vector<AllocInfo> allocInfo;
+
18
+
19uint8_t** readPages, **writePages;
+
20#define PAGE_SIZE (4*1024)
+
21#define MAX_ADDRESS_SPACE 0xFFFF0000
+
22std::bitset<MAX_ADDRESS_SPACE / PAGE_SIZE> usedPages;
+
23
+
24void Memory::Initialize()
+
25{
+
26 readPages = new uint8_t*[MAX_ADDRESS_SPACE / PAGE_SIZE];
+
27 writePages = new uint8_t*[MAX_ADDRESS_SPACE / PAGE_SIZE];
+
28 usedPages.reset();
+
29}
+
30
+
31void Memory::Dump()
+
32{
+
33 std::ofstream file("mem.dump");
+
34 for (uint32_t i = mainXexBase; i < mainXexBase+mainXexSize; i += 4)
+
35 {
+
36 uint32_t data = bswap32(Read32(i));
+
37 file.write((char*)&data, 4);
+
38 }
+
39 file.close();
+
40
+
41 file.open("stack.dump");
+
42 for (uint32_t i = 0x70000000; i < 0x70000000+mainThreadStackSize; i += 4)
+
43 {
+
44 uint32_t data = bswap32(Read32(i));
+
45 file.write((char*)&data, 4);
+
46 }
+
47 file.close();
+
48}
+
49
+
50void *Memory::AllocMemory(uint32_t baseAddress, uint32_t size)
+
51{
+
52 void* ret = mmap((void*)baseAddress, size, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
+
53
+
54 if (ret == MAP_FAILED)
+
55 {
+
56 printf("Failed to allocate memory: %s\n", strerror(errno));
+
57 exit(1);
+
58 }
59
-
60 for (int i = 0; i < size; i += PAGE_SIZE)
-
61 {
-
62 readPages[(baseAddress + i) / PAGE_SIZE] = ((uint8_t*)ret+i);
-
63 writePages[(baseAddress + i) / PAGE_SIZE] = ((uint8_t*)ret+i);
-
64 }
-
65
-
66 return ret;
-
67}
-
68
-
69uint32_t Memory::VirtAllocMemoryRange(uint32_t beginAddr, uint32_t endAddr, uint32_t size)
-
70{
-
71 uint32_t requiredPages = size / PAGE_SIZE;
-
72
-
73 // Find the lowest free range that fits the size
-
74 uint32_t candidate = 0;
-
75 uint32_t freePages = 0;
-
76 for (uint32_t i = beginAddr; i < endAddr; i += PAGE_SIZE)
-
77 {
-
78 if (!candidate && !usedPages[i / PAGE_SIZE])
-
79 {
-
80 candidate = i / PAGE_SIZE;
-
81 freePages = 1;
-
82 }
-
83 else if (!usedPages[i / PAGE_SIZE])
-
84 {
-
85 freePages++;
-
86 if (freePages == requiredPages)
-
87 break;
-
88 }
-
89 else
-
90 {
-
91 candidate = 0;
-
92 }
-
93 }
-
94
-
95 if (candidate == 0)
-
96 {
-
97 printf("ERROR: Failed to allocate virtual memory in range [0x%08x -> 0x%08x]\n", beginAddr, endAddr);
-
98 exit(1);
-
99 }
-
100
-
101 // Mark the pages as used
-
102 for (int i = 0; i < requiredPages; i++)
-
103 usedPages.set(candidate+i, true);
-
104
-
105 return candidate*PAGE_SIZE;
-
106}
-
107
-
108uint8_t *Memory::GetRawPtrForAddr(uint32_t addr)
-
109{
-
110 if (!readPages[addr / PAGE_SIZE])
-
111 {
-
112 printf("Read raw ptr from unmapped addr 0x%08x\n", addr);
-
113 exit(1);
-
114 }
-
115
-
116 return &readPages[addr / PAGE_SIZE][addr % PAGE_SIZE];
-
117}
-
118
-
119uint8_t Memory::Read8(uint32_t addr)
-
120{
-
121 if (!readPages[addr / PAGE_SIZE])
-
122 {
-
123 printf("Read8 from unmapped addr 0x%08x\n", addr);
-
124 exit(1);
-
125 }
-
126
-
127 return readPages[addr / PAGE_SIZE][addr % PAGE_SIZE];
-
128}
-
129
-
130uint16_t Memory::Read16(uint32_t addr, bool slow)
-
131{
-
132 if (!slow)
-
133 {
-
134 if (!readPages[addr / PAGE_SIZE])
-
135 {
-
136 return Read16(addr, true);
-
137 }
-
138
-
139 return bswap16(*(uint16_t*)&readPages[addr / PAGE_SIZE][addr % PAGE_SIZE]);
-
140 }
-
141 else
-
142 {
-
143 switch (addr)
-
144 {
-
145 case 0x10158:
-
146 return 0x2; // Some kind of console type (maybe debug vs retail?). xbdm.xex relies on this while booting
-
147 case 0x1015A:
-
148 return 0; // More xbdm.xex nonsense
-
149 case 0x1015C:
-
150 return 0x4f80; // According to assert messages inside xbdm, this is the console's firmware revision
-
151 case 0x1015E:
-
152 return 0; // Setting this to 0x8000 will cause a bunch of extra stuff to happen inside xbdm
-
153 case 0x10164:
-
154 // If bit 9 is set, then xbdm will enforce in-order execution of I/O (EIEIO)
-
155 return 0;
-
156 default:
-
157 printf("Read16 from unmapped address 0x%08x\n", addr);
-
158 exit(1);
+
60 size = (size + PAGE_SIZE) & ~PAGE_SIZE;
+
61
+
62 for (int i = 0; i < size; i += PAGE_SIZE)
+
63 {
+
64 readPages[(baseAddress + i) / PAGE_SIZE] = ((uint8_t*)ret+i);
+
65 writePages[(baseAddress + i) / PAGE_SIZE] = ((uint8_t*)ret+i);
+
66 }
+
67
+
68 return ret;
+
69}
+
70
+
71uint32_t Memory::VirtAllocMemoryRange(uint32_t beginAddr, uint32_t endAddr, uint32_t size)
+
72{
+
73 uint32_t requiredPages = size / PAGE_SIZE;
+
74
+
75 // Find the lowest free range that fits the size
+
76 uint32_t candidate = 0;
+
77 uint32_t freePages = 0;
+
78 for (uint32_t i = beginAddr; i < endAddr; i += PAGE_SIZE)
+
79 {
+
80 if (!candidate && !usedPages[i / PAGE_SIZE])
+
81 {
+
82 candidate = i / PAGE_SIZE;
+
83 freePages = 1;
+
84 }
+
85 else if (!usedPages[i / PAGE_SIZE])
+
86 {
+
87 freePages++;
+
88 if (freePages == requiredPages)
+
89 break;
+
90 }
+
91 else
+
92 {
+
93 candidate = 0;
+
94 }
+
95 }
+
96
+
97 if (candidate == 0)
+
98 {
+
99 printf("ERROR: Failed to allocate virtual memory in range [0x%08x -> 0x%08x]\n", beginAddr, endAddr);
+
100 exit(1);
+
101 }
+
102
+
103 // Mark the pages as used
+
104 for (int i = 0; i < requiredPages; i++)
+
105 usedPages.set(candidate+i, true);
+
106
+
107 AllocInfo info;
+
108 info.baseAddress = candidate*PAGE_SIZE;
+
109 info.regionSize = requiredPages*PAGE_SIZE;
+
110 allocInfo.push_back(info);
+
111
+
112 return candidate*PAGE_SIZE;
+
113}
+
114
+
115uint8_t *Memory::GetRawPtrForAddr(uint32_t addr)
+
116{
+
117 if (!readPages[addr / PAGE_SIZE])
+
118 {
+
119 printf("Read raw ptr from unmapped addr 0x%08x\n", addr);
+
120 exit(1);
+
121 }
+
122
+
123 return &readPages[addr / PAGE_SIZE][addr % PAGE_SIZE];
+
124}
+
125
+
126bool Memory::GetAllocInfo(uint32_t addr, AllocInfo& outInfo)
+
127{
+
128 for (auto& info : allocInfo)
+
129 {
+
130 if (info.baseAddress <= addr && info.baseAddress+info.regionSize > addr)
+
131 {
+
132 outInfo = info;
+
133 return true;
+
134 }
+
135 }
+
136
+
137 printf("Failed to get allocation info for region 0x%08x\n", addr);
+
138 return false;
+
139}
+
140
+
141uint8_t Memory::Read8(uint32_t addr)
+
142{
+
143 if (!readPages[addr / PAGE_SIZE])
+
144 {
+
145 printf("Read8 from unmapped addr 0x%08x\n", addr);
+
146 exit(1);
+
147 }
+
148
+
149 return readPages[addr / PAGE_SIZE][addr % PAGE_SIZE];
+
150}
+
151
+
152uint16_t Memory::Read16(uint32_t addr, bool slow)
+
153{
+
154 if (!slow)
+
155 {
+
156 if (!readPages[addr / PAGE_SIZE])
+
157 {
+
158 return Read16(addr, true);
159 }
-
160 }
-
161}
-
162
-
163uint32_t Memory::Read32(uint32_t addr, bool slow)
-
164{
-
165 if (!slow)
-
166 {
-
167 if (!readPages[addr / PAGE_SIZE])
-
168 {
-
169 return Read32(addr, true);
-
170 }
-
171
-
172 return bswap32(*(uint32_t*)&readPages[addr / PAGE_SIZE][addr % PAGE_SIZE]);
-
173 }
-
174 else
-
175 {
-
176 switch (addr)
-
177 {
-
178 case 0x10156:
-
179 return 0x2000000; // Setting this to 0x2000000 causes some kind of memory address to be set to 1
+
160
+
161 return bswap16(*(uint16_t*)&readPages[addr / PAGE_SIZE][addr % PAGE_SIZE]);
+
162 }
+
163 else
+
164 {
+
165 switch (addr)
+
166 {
+
167 case 0x10158:
+
168 return 0x2; // Some kind of console type (maybe debug vs retail?). xbdm.xex relies on this while booting
+
169 case 0x1015A:
+
170 return 0; // More xbdm.xex nonsense
+
171 case 0x1015C:
+
172 return 0x4f80; // According to assert messages inside xbdm, this is the console's firmware revision
+
173 case 0x1015E:
+
174 return 0; // Setting this to 0x8000 will cause a bunch of extra stuff to happen inside xbdm
+
175 case 0x10164:
+
176 // If bit 9 is set, then xbdm will enforce in-order execution of I/O (EIEIO)
+
177 return 0;
+
178 case 0x8e03860a: // Some kind of weird page mapped by the OS
+
179 return 0;
180 default:
-
181 printf("Read32 from unmapped address 0x%08x\n", addr);
+
181 printf("Read16 from unmapped address 0x%08x\n", addr);
182 exit(1);
183 }
184 }
185}
186
-
187uint64_t Memory::Read64(uint32_t addr)
+
187uint32_t Memory::Read32(uint32_t addr, bool slow)
188{
-
189 if (!readPages[addr / PAGE_SIZE])
+
189 if (!slow)
190 {
-
191 printf("Read64 from unmapped addr 0x%08x\n", addr);
-
192 exit(1);
-
193 }
-
194
-
195 return bswap64(*(uint64_t*)&readPages[addr / PAGE_SIZE][addr % PAGE_SIZE]);
-
196}
-
197
-
198void Memory::Write8(uint32_t addr, uint8_t data)
-
199{
-
200 if (!writePages[addr / PAGE_SIZE])
-
201 {
-
202 printf("Write8 to unmapped addr 0x%08x\n", addr);
-
203 exit(1);
-
204 }
-
205
-
206 writePages[addr / PAGE_SIZE][addr % PAGE_SIZE] = data;
-
207}
-
208
-
209void Memory::Write16(uint32_t addr, uint16_t data)
-
210{
-
211 if (!writePages[addr / PAGE_SIZE])
-
212 {
-
213 printf("Write16 to unmapped addr 0x%08x\n", addr);
-
214 exit(1);
-
215 }
-
216
-
217 *(uint16_t*)&writePages[addr / PAGE_SIZE][addr % PAGE_SIZE] = bswap16(data);
-
218}
-
219
-
220void Memory::Write32(uint32_t addr, uint32_t data)
-
221{
-
222 if (!writePages[addr / PAGE_SIZE])
-
223 {
-
224 printf("Write32 to unmapped addr 0x%08x\n", addr);
-
225 exit(1);
-
226 }
-
227
-
228 *(uint32_t*)&writePages[addr / PAGE_SIZE][addr % PAGE_SIZE] = bswap32(data);
-
229}
-
230
-
231void Memory::Write64(uint32_t addr, uint64_t data)
-
232{
-
233 if (!writePages[addr / PAGE_SIZE])
-
234 {
-
235 printf("Write64 to unmapped addr 0x%08x\n", addr);
-
236 exit(1);
-
237 }
-
238
-
239 *(uint64_t*)&writePages[addr / PAGE_SIZE][addr % PAGE_SIZE] = bswap64(data);
-
240}
+
191 if (!readPages[addr / PAGE_SIZE])
+
192 {
+
193 return Read32(addr, true);
+
194 }
+
195
+
196 return bswap32(*(uint32_t*)&readPages[addr / PAGE_SIZE][addr % PAGE_SIZE]);
+
197 }
+
198 else
+
199 {
+
200 switch (addr)
+
201 {
+
202 case 0x10156:
+
203 return 0x2000000; // Setting this to 0x2000000 causes some kind of memory address to be set to 1
+
204 default:
+
205 printf("Read32 from unmapped address 0x%08x\n", addr);
+
206 exit(1);
+
207 }
+
208 }
+
209}
+
210
+
211uint64_t Memory::Read64(uint32_t addr)
+
212{
+
213 if (!readPages[addr / PAGE_SIZE])
+
214 {
+
215 printf("Read64 from unmapped addr 0x%08x\n", addr);
+
216 exit(1);
+
217 }
+
218
+
219 return bswap64(*(uint64_t*)&readPages[addr / PAGE_SIZE][addr % PAGE_SIZE]);
+
220}
+
221
+
222void Memory::Write8(uint32_t addr, uint8_t data)
+
223{
+
224 if (!writePages[addr / PAGE_SIZE])
+
225 {
+
226 printf("Write8 to unmapped addr 0x%08x\n", addr);
+
227 exit(1);
+
228 }
+
229
+
230 writePages[addr / PAGE_SIZE][addr % PAGE_SIZE] = data;
+
231}
+
232
+
233void Memory::Write16(uint32_t addr, uint16_t data)
+
234{
+
235 if (!writePages[addr / PAGE_SIZE])
+
236 {
+
237 printf("Write16 to unmapped addr 0x%08x\n", addr);
+
238 exit(1);
+
239 }
+
240
+
241 *(uint16_t*)&writePages[addr / PAGE_SIZE][addr % PAGE_SIZE] = bswap16(data);
+
242}
+
243
+
244void Memory::Write32(uint32_t addr, uint32_t data)
+
245{
+
246 if (!writePages[addr / PAGE_SIZE])
+
247 {
+
248 printf("Write32 to unmapped addr 0x%08x\n", addr);
+
249 exit(1);
+
250 }
+
251
+
252 *(uint32_t*)&writePages[addr / PAGE_SIZE][addr % PAGE_SIZE] = bswap32(data);
+
253}
+
254
+
255void Memory::Write64(uint32_t addr, uint64_t data)
+
256{
+
257 if (!writePages[addr / PAGE_SIZE])
+
258 {
+
259 printf("Write64 to unmapped addr 0x%08x\n", addr);
+
260 exit(1);
+
261 }
+
262
+
263 *(uint64_t*)&writePages[addr / PAGE_SIZE][addr % PAGE_SIZE] = bswap64(data);
+
264}
+
Definition memory.h:6