mirror of
https://github.com/boykopovar/AnyPS5.git
synced 2026-10-27 00:28:14 +00:00
116 lines
3.7 KiB
C++
116 lines
3.7 KiB
C++
#include <codegen/x86/X64InstructionRewriter.hpp>
|
|
#include <iostream>
|
|
#include <stdexcept>
|
|
|
|
static void Require(bool ok) {
|
|
if (!ok)
|
|
throw std::runtime_error("Invalid rewrite boundary accepted");
|
|
}
|
|
|
|
static void RequireTruncatedBranchRejected(bool ok) {
|
|
if (!ok)
|
|
throw std::runtime_error(
|
|
"Length-changing rewrite accepted a section with a truncated relative branch");
|
|
}
|
|
|
|
int main() {
|
|
try {
|
|
const Codegen::X64InstructionRewriter rewriter;
|
|
|
|
for (const auto& code : {
|
|
std::vector<std::uint8_t>{
|
|
0xB8, 0x90, 0x90, 0x90, 0x90, 0xC3},
|
|
std::vector<std::uint8_t>{
|
|
0x48, 0x8B, 0x05, 0x90, 0x90, 0x90, 0x90, 0xC3},
|
|
std::vector<std::uint8_t>{
|
|
0xE8, 0x90, 0x90, 0x90, 0x90, 0xC3}
|
|
}) {
|
|
const auto original = code;
|
|
|
|
for (std::size_t offset = 1;
|
|
offset + 1 < code.size();
|
|
++offset) {
|
|
bool rejected = false;
|
|
|
|
try {
|
|
(void)rewriter.Rewrite(code, {offset, {0x90}});
|
|
} catch (const std::exception&) {
|
|
rejected = true;
|
|
}
|
|
|
|
Require(rejected && code == original);
|
|
}
|
|
|
|
const auto result = rewriter.Rewrite(code, {0, {0x90}});
|
|
|
|
Require(result.Bytes == std::vector<std::uint8_t>{
|
|
0x90, 0xC3});
|
|
}
|
|
|
|
const auto result = rewriter.Rewrite(
|
|
{0x90, 0x90, 0xC3},
|
|
{1, {0x90, 0x90}});
|
|
|
|
Require(result.Bytes == std::vector<std::uint8_t>{
|
|
0x90, 0x90, 0x90, 0xC3});
|
|
|
|
for (const auto& code : {
|
|
std::vector<std::uint8_t>{
|
|
0x66, 0xEB, 0x01, 0x90, 0xC3},
|
|
std::vector<std::uint8_t>{
|
|
0x90, 0x66, 0xEB, 0xFC, 0xC3}
|
|
}) {
|
|
bool rejected = false;
|
|
|
|
try {
|
|
const auto offset =
|
|
code[0] == 0x66 ? std::size_t{3} : std::size_t{0};
|
|
|
|
(void)rewriter.Rewrite(code, {offset, {0x66, 0x90}});
|
|
} catch (const std::exception&) {
|
|
rejected = true;
|
|
}
|
|
|
|
RequireTruncatedBranchRejected(rejected);
|
|
}
|
|
|
|
const auto unaffected = rewriter.Rewrite(
|
|
{0x66, 0xEB, 0x00, 0x90, 0x90, 0xC3},
|
|
{4, {0x66, 0x90}});
|
|
|
|
Require(unaffected.Bytes == std::vector<std::uint8_t>{
|
|
0x66, 0xEB, 0x00, 0x90, 0x66, 0x90, 0xC3});
|
|
|
|
std::vector<std::uint8_t> forwardWraparound(0x10004, 0x90);
|
|
forwardWraparound[0xFFFA] = 0x66;
|
|
forwardWraparound[0xFFFB] = 0xEB;
|
|
forwardWraparound[0xFFFC] = 0x03;
|
|
|
|
bool forwardWraparoundRejected = false;
|
|
try {
|
|
(void)rewriter.Rewrite(forwardWraparound, {10, {0x66, 0x90}});
|
|
} catch (const std::exception&) {
|
|
forwardWraparoundRejected = true;
|
|
}
|
|
RequireTruncatedBranchRejected(forwardWraparoundRejected);
|
|
|
|
std::vector<std::uint8_t> backwardWraparound(0x10004, 0x90);
|
|
backwardWraparound[0] = 0x66;
|
|
backwardWraparound[1] = 0xEB;
|
|
backwardWraparound[2] = 0xFC;
|
|
|
|
bool backwardWraparoundRejected = false;
|
|
try {
|
|
(void)rewriter.Rewrite(backwardWraparound, {0xFFFE, {0x66, 0x90}});
|
|
} catch (const std::exception&) {
|
|
backwardWraparoundRejected = true;
|
|
}
|
|
RequireTruncatedBranchRejected(backwardWraparoundRejected);
|
|
|
|
std::cout << "21 rewrite boundary cases passed\n";
|
|
} catch (const std::exception& error) {
|
|
std::cerr << error.what() << '\n';
|
|
return 1;
|
|
}
|
|
}
|