Compare commits

...

5 Commits

Author SHA1 Message Date
Isaac Marovitz
9035879299
Merge c122571951b3ea6660f7872f832e93f474a481b7 into 865319a39cec873370500d26ce775959a4c5e784 2025-04-17 17:17:46 +03:00
Skyth (Asilkan)
865319a39c
Update README.md (#139)
* Update README.md

* Update README.md

Co-authored-by: Hyper <34012267+hyperbx@users.noreply.github.com>

---------

Co-authored-by: Hyper <34012267+hyperbx@users.noreply.github.com>
2025-04-17 11:29:46 +03:00
Isaac Marovitz
c122571951
Whitespace
Signed-off-by: Isaac Marovitz <isaacryu@icloud.com>
2025-03-13 11:01:32 -04:00
Isaac Marovitz
6783869c8a
This langauge sucks
Signed-off-by: Isaac Marovitz <isaacryu@icloud.com>
2025-03-13 10:42:15 -04:00
Isaac Marovitz
9c6c3dbaa6
Search for and print out register save/load locations
Signed-off-by: Isaac Marovitz <isaacryu@icloud.com>
2025-03-13 10:17:10 -04:00
2 changed files with 61 additions and 4 deletions

View File

@ -4,6 +4,8 @@ XenonRecomp is a tool that converts Xbox 360 executables into C++ code, which ca
This project was heavily inspired by [N64: Recompiled](https://github.com/N64Recomp/N64Recomp), a similar tool for N64 executables.
**DISCLAIMER:** This project does not provide a runtime implementation. It only converts the game code to C++, which is not going to function correctly without a runtime backing it. **Making the game work is your responsibility.**
## Implementation Details
### Instructions

View File

@ -1,11 +1,11 @@
#include "fmt/xchar.h"
#include "function.h"
#include <algorithm>
#include <cassert>
#include <iterator>
#include <file.h>
#include <disasm.h>
#include <file.h>
#include <image.h>
#include <xbox.h>
#include <fmt/core.h>
#include "function.h"
#define SWITCH_ABSOLUTE 0
#define SWITCH_COMPUTED 1
@ -21,6 +21,59 @@ struct SwitchTable
uint32_t type{};
};
static const uint8_t RESTGPRLR_14[] = { 0xe9, 0xc1, 0xff, 0x68 };
static const uint8_t SAVEGPRLR_14[] = { 0xf9, 0xc1, 0xff, 0x68 };
static const uint8_t RESTFPR_14[] = { 0xc9, 0xcc, 0xff, 0x70 };
static const uint8_t SAVEFPR_14[] = { 0xd9, 0xcc, 0xff, 0x70 };
static const uint8_t RESTVMX_14[] = { 0x39, 0x60, 0xfe, 0xe0, 0x7d, 0xcb, 0x60, 0xce };
static const uint8_t SAVEVMX_14[] = { 0x39, 0x60, 0xfe, 0xe0, 0x7d, 0xcb, 0x61, 0xce };
static const uint8_t RESTVMX_64[] = { 0x39, 0x60, 0xfc, 0x00, 0x10, 0x0b, 0x60, 0xcb };
static const uint8_t SAVEVMX_64[] = { 0x39, 0x60, 0xfc, 0x00, 0x10, 0x0b, 0x61, 0xcb };
uint32_t BytePatternSearch(uint8_t* data, const uint32_t dataSize, const uint32_t baseAddress, const uint8_t pattern[], const size_t patternSize)
{
auto result = std::search(data, data + dataSize, pattern, pattern + patternSize);
if (result != data + dataSize) {
return baseAddress + std::distance(data, result);
}
return UINT32_MAX;
}
void RegisterFunctionsSearch(Image& image)
{
uint32_t baseAddress = UINT32_MAX;
for (const auto& section : image.sections) {
if (section.name == ".text") {
baseAddress = section.base;
if (baseAddress == UINT32_MAX) {
fmt::println("Could not find \".text\" section.");
return;
}
uint32_t restgprlr_14 = BytePatternSearch(section.data, section.size, baseAddress, RESTGPRLR_14, sizeof(RESTGPRLR_14));
uint32_t savegprlr_14 = BytePatternSearch(section.data, section.size, baseAddress, SAVEGPRLR_14, sizeof(SAVEGPRLR_14));
uint32_t restfpr_14 = BytePatternSearch(section.data, section.size, baseAddress, RESTFPR_14, sizeof(RESTFPR_14));
uint32_t savefpr_14 = BytePatternSearch(section.data, section.size, baseAddress, SAVEFPR_14, sizeof(SAVEFPR_14));
uint32_t restvmx_14 = BytePatternSearch(section.data, section.size, baseAddress, RESTVMX_14, sizeof(RESTVMX_14));
uint32_t savevmx_14 = BytePatternSearch(section.data, section.size, baseAddress, SAVEVMX_14, sizeof(SAVEVMX_14));
uint32_t restvmx_64 = BytePatternSearch(section.data, section.size, baseAddress, RESTVMX_64, sizeof(RESTVMX_64));
uint32_t savevmx_64 = BytePatternSearch(section.data, section.size, baseAddress, SAVEVMX_64, sizeof(SAVEVMX_64));
fmt::println("restgprlr_14_address = 0x{:X}", restgprlr_14);
fmt::println("savegprlr_14_address = 0x{:X}", savegprlr_14);
fmt::println("restfpr_14_address = 0x{:X}", restfpr_14);
fmt::println("savefpr_14_address = 0x{:X}", savefpr_14);
fmt::println("restvmx_14_address = 0x{:X}", restvmx_14);
fmt::println("savevmx_14_address = 0x{:X}", savevmx_14);
fmt::println("restvmx_64_address = 0x{:X}", restvmx_64);
fmt::println("savevmx_64_address = 0x{:X}", savevmx_64);
}
}
}
void ReadTable(Image& image, SwitchTable& table)
{
uint32_t pOffset;
@ -192,6 +245,8 @@ int main(int argc, char** argv)
const auto file = LoadFile(argv[1]);
auto image = Image::ParseImage(file.data(), file.size());
RegisterFunctionsSearch(image);
auto printTable = [&](const SwitchTable& table)
{
println("[[switch]]");