mirror of
https://github.com/RPCSX/rpcsx.git
synced 2026-01-22 00:20:40 +01:00
orbis/regmgr: decode com ops
This commit is contained in:
parent
7eb01a84ee
commit
733b8bf73f
|
|
@ -137,6 +137,7 @@ public:
|
|||
|
||||
rx::shared_mutex regMgrMtx;
|
||||
kmap<std::uint32_t, std::uint32_t> regMgrInt;
|
||||
kmap<std::uint32_t, rx::StaticCString<2048>> regMgrStr;
|
||||
std::vector<std::tuple<std::uint8_t *, size_t>> dialogs{};
|
||||
|
||||
FwType fwType = FwType::Unknown;
|
||||
|
|
|
|||
|
|
@ -128,6 +128,107 @@ orbis::sys_mtypeprotect(Thread *thread, uintptr_t addr, size_t len,
|
|||
|
||||
return vmem::setTypeAndProtect(thread->tproc, range, type, prot);
|
||||
}
|
||||
|
||||
struct RegMgrComKey {
|
||||
std::uint8_t data[4]{};
|
||||
std::uint8_t table{};
|
||||
std::uint8_t index{};
|
||||
|
||||
[[nodiscard]] static constexpr RegMgrComKey unpack(std::uint64_t key) {
|
||||
RegMgrComKey result;
|
||||
result.data[0] = static_cast<std::uint8_t>(key & 0xff);
|
||||
result.data[1] = static_cast<std::uint8_t>((key >> 8) & 0xff);
|
||||
result.data[2] = static_cast<std::uint8_t>((key >> 16) & 0xff);
|
||||
result.data[3] = static_cast<std::uint8_t>((key >> 24) & 0xff);
|
||||
result.table = static_cast<std::uint8_t>(key >> 32);
|
||||
result.index = static_cast<std::uint8_t>(key >> 40);
|
||||
return result;
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr std::uint64_t pack() const {
|
||||
std::uint64_t result = data[0];
|
||||
result |= static_cast<std::uint64_t>(data[0]) << 0;
|
||||
result |= static_cast<std::uint64_t>(data[1]) << 8;
|
||||
result |= static_cast<std::uint64_t>(data[2]) << 16;
|
||||
result |= static_cast<std::uint64_t>(data[3]) << 24;
|
||||
result |= static_cast<std::uint64_t>(table) << 32;
|
||||
result |= static_cast<std::uint64_t>(index) << 40;
|
||||
result |= static_cast<std::uint64_t>(calcChecksum()) << 48;
|
||||
return result;
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr bool validate(std::uint64_t key) const {
|
||||
return calcChecksum() == static_cast<std::uint16_t>(key >> 48);
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr std::uint16_t calcChecksum() const {
|
||||
return std::uint16_t(data[0]) + data[1] + data[2] + data[3] + table * index;
|
||||
}
|
||||
};
|
||||
|
||||
constexpr std::int32_t regMgrGetRegId(std::uint64_t encoded) {
|
||||
constexpr std::uint8_t kRegMgrScrambSdk[] = {
|
||||
0x6b, 0xe8, 0x98, 0x03, 0x9a, 0x70, 0x23, 0x5a,
|
||||
0x63, 0xee, 0xf5, 0x7b, 0xff, 0xa4, 0x4c, 0x8c,
|
||||
};
|
||||
constexpr std::uint8_t kRegMgrScrambLib[] = {
|
||||
0x14, 0xee, 0xde, 0xe1, 0x80, 0xac, 0xf3, 0x78,
|
||||
0x47, 0x43, 0xdb, 0x40, 0x93, 0xdd, 0xb1, 0x34,
|
||||
};
|
||||
|
||||
auto key = RegMgrComKey::unpack(encoded);
|
||||
auto slot = key.index ^ 0x6b;
|
||||
|
||||
const std::uint8_t *table = kRegMgrScrambSdk;
|
||||
|
||||
switch ((key.table ^ table[0xf - slot])) {
|
||||
case 0x19:
|
||||
table = kRegMgrScrambLib;
|
||||
break;
|
||||
case 0x72:
|
||||
table = kRegMgrScrambSdk;
|
||||
break;
|
||||
|
||||
default:
|
||||
return 0x800d0205;
|
||||
}
|
||||
|
||||
std::uint32_t decodedKey = (key.data[1] ^ table[slot + 0]) * 0x1000000 +
|
||||
(key.data[3] ^ table[slot + 1]) * 0x10000 +
|
||||
(key.data[2] ^ table[slot + 2]) * 0x100 +
|
||||
(key.data[0] ^ table[slot + 3]);
|
||||
|
||||
return decodedKey;
|
||||
}
|
||||
|
||||
struct RegMgrComInt {
|
||||
uint64_t encodedId;
|
||||
uint32_t unk;
|
||||
uint32_t value;
|
||||
};
|
||||
|
||||
static_assert(sizeof(RegMgrComInt) == 0x10);
|
||||
|
||||
struct RegMgrComStr {
|
||||
uint64_t encodedId;
|
||||
uint32_t unk;
|
||||
uint32_t padding;
|
||||
uint64_t len;
|
||||
rx::StaticCString<2048> string;
|
||||
};
|
||||
|
||||
static_assert(sizeof(RegMgrComStr) == 0x818);
|
||||
|
||||
struct RegMgrComBin {
|
||||
uint64_t encodedId;
|
||||
uint32_t unk;
|
||||
uint32_t padding;
|
||||
uint64_t len;
|
||||
std::uint8_t data[2048];
|
||||
};
|
||||
|
||||
static_assert(sizeof(RegMgrComBin) == 0x818);
|
||||
|
||||
orbis::SysResult orbis::sys_regmgr_call(Thread *thread, uint32_t op,
|
||||
uint32_t id, ptr<void> result,
|
||||
ptr<void> value, uint64_t len) {
|
||||
|
|
@ -146,6 +247,7 @@ orbis::SysResult orbis::sys_regmgr_call(Thread *thread, uint32_t op,
|
|||
g_context->regMgrInt[id] = *(std::uint32_t *)value;
|
||||
return {};
|
||||
}
|
||||
|
||||
if (op == 2) {
|
||||
// get int
|
||||
if (len != sizeof(uint32_t)) {
|
||||
|
|
@ -158,10 +260,20 @@ orbis::SysResult orbis::sys_regmgr_call(Thread *thread, uint32_t op,
|
|||
thread->where();
|
||||
// return ErrorCode::NOENT;
|
||||
return uwrite((ptr<uint>)value, 0u);
|
||||
return {};
|
||||
}
|
||||
return uwrite((ptr<uint>)value, intValIt->second);
|
||||
|
||||
return uwrite((ptr<uint>)value, intValIt->second);
|
||||
}
|
||||
|
||||
if (op == 3) {
|
||||
// set string
|
||||
|
||||
rx::StaticCString<2048> string;
|
||||
ORBIS_RET_ON_ERROR(ureadString(
|
||||
string.data(), std::min(string.max_size(), len), ptr<char>(value)));
|
||||
|
||||
ORBIS_LOG_WARNING(__FUNCTION__, op, id, string.data());
|
||||
g_context->regMgrStr[id] = string;
|
||||
return {};
|
||||
}
|
||||
|
||||
|
|
@ -173,63 +285,146 @@ orbis::SysResult orbis::sys_regmgr_call(Thread *thread, uint32_t op,
|
|||
return ErrorCode::INVAL;
|
||||
}
|
||||
|
||||
std::memset(value, 0, len);
|
||||
auto it = g_context->regMgrStr.find(id);
|
||||
if (it == g_context->regMgrStr.end()) {
|
||||
ORBIS_LOG_ERROR("registry string entry not exists", op, id);
|
||||
thread->where();
|
||||
std::memset(value, 0, len);
|
||||
return {};
|
||||
}
|
||||
|
||||
ORBIS_LOG_ERROR(__FUNCTION__, op, id, len);
|
||||
if (it->second.length() > len) {
|
||||
return ErrorCode(-0x800d0606);
|
||||
}
|
||||
|
||||
ORBIS_LOG_WARNING(__FUNCTION__, op, id, len, it->second.data());
|
||||
thread->where();
|
||||
ORBIS_RET_ON_ERROR(
|
||||
uwriteRaw(value, it->second.data(), it->second.length() + 1));
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
if (op == 24) {
|
||||
// com: set int
|
||||
RegMgrComInt _request;
|
||||
ORBIS_RET_ON_ERROR(uread(_request, ptr<RegMgrComInt>(value)));
|
||||
|
||||
auto id = regMgrGetRegId(_request.encodedId);
|
||||
|
||||
if (id < 0) {
|
||||
return ErrorCode(-id);
|
||||
}
|
||||
|
||||
ORBIS_LOG_WARNING(__FUNCTION__, op, id, _request.unk, _request.value);
|
||||
g_context->regMgrInt[id] = _request.value;
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
if (op == 25) {
|
||||
struct nonsys_int {
|
||||
union {
|
||||
uint64_t encoded_id;
|
||||
struct {
|
||||
uint8_t data[4];
|
||||
uint8_t table;
|
||||
uint8_t index;
|
||||
uint16_t checksum;
|
||||
} encoded_id_parts;
|
||||
};
|
||||
uint32_t unk;
|
||||
uint32_t value;
|
||||
};
|
||||
// com: get int
|
||||
RegMgrComInt _request;
|
||||
ORBIS_RET_ON_ERROR(uread(_request, ptr<RegMgrComInt>(value)));
|
||||
|
||||
auto int_value = reinterpret_cast<nonsys_int *>(value);
|
||||
ORBIS_LOG_TODO(
|
||||
__FUNCTION__, int_value->encoded_id,
|
||||
int_value->encoded_id_parts.data[0],
|
||||
int_value->encoded_id_parts.data[1],
|
||||
int_value->encoded_id_parts.data[2],
|
||||
int_value->encoded_id_parts.data[3], int_value->encoded_id_parts.table,
|
||||
int_value->encoded_id_parts.index, int_value->encoded_id_parts.checksum,
|
||||
int_value->unk, int_value->value);
|
||||
auto id = regMgrGetRegId(_request.encodedId);
|
||||
|
||||
// HACK: set default system language and gamepad layout to US/EU region
|
||||
// 0x12356328ECF5617B -> language where is 0 is Japanese, 1 is English
|
||||
// 0x22666251FE7BECFF -> confirm button layout, 0 is Circle, 1 is Cross
|
||||
if (int_value->encoded_id == 0x12356328ECF5617B ||
|
||||
int_value->encoded_id == 0x22666251FE7BECFF) {
|
||||
int_value->value = 1;
|
||||
return {};
|
||||
if (id < 0) {
|
||||
return ErrorCode(-id);
|
||||
}
|
||||
|
||||
if (int_value->encoded_id == 0x1ac46343411b3f40) {
|
||||
int_value->value = 0; // allow debug libraries
|
||||
return {};
|
||||
auto it = g_context->regMgrInt.find(id);
|
||||
if (it == g_context->regMgrInt.end()) {
|
||||
ORBIS_LOG_ERROR("registry int entry not exists", op, id);
|
||||
thread->where();
|
||||
// return ErrorCode::NOENT;
|
||||
_request.value = 0;
|
||||
} else {
|
||||
_request.value = it->second;
|
||||
}
|
||||
|
||||
if (int_value->encoded_id == 0x29b56169422aa3dd) {
|
||||
int_value->value = 2;
|
||||
return {};
|
||||
}
|
||||
|
||||
// 0x503f69bde385a6ac // allow loading from dev machine?
|
||||
// 0x2d946f62aef8f878
|
||||
|
||||
int_value->value = 0;
|
||||
ORBIS_LOG_WARNING(__FUNCTION__, op, id, _request.unk, _request.value);
|
||||
return uwrite((ptr<RegMgrComInt>)value, _request);
|
||||
}
|
||||
|
||||
if (op == 26) {
|
||||
// com: set string
|
||||
RegMgrComStr _request;
|
||||
ORBIS_RET_ON_ERROR(uread(_request, ptr<RegMgrComStr>(value)));
|
||||
|
||||
auto id = regMgrGetRegId(_request.encodedId);
|
||||
|
||||
if (id < 0) {
|
||||
return ErrorCode(-id);
|
||||
}
|
||||
|
||||
if (_request.len > 2048 || _request.string[_request.len - 1] != '\0' ||
|
||||
_request.string.length() + 1 != _request.len) {
|
||||
return ErrorCode(-0x800d0205);
|
||||
}
|
||||
|
||||
ORBIS_LOG_WARNING(__FUNCTION__, op, id, _request.unk,
|
||||
_request.string.data());
|
||||
g_context->regMgrStr[id] = _request.string;
|
||||
return {};
|
||||
}
|
||||
|
||||
if (op == 27) {
|
||||
// com: get string
|
||||
RegMgrComStr _request;
|
||||
ORBIS_RET_ON_ERROR(uread(_request, ptr<RegMgrComStr>(value)));
|
||||
|
||||
auto id = regMgrGetRegId(_request.encodedId);
|
||||
|
||||
if (id < 0) {
|
||||
return ErrorCode(-id);
|
||||
}
|
||||
|
||||
auto it = g_context->regMgrStr.find(id);
|
||||
if (it == g_context->regMgrStr.end()) {
|
||||
ORBIS_LOG_ERROR("registry string entry not exists", op, id);
|
||||
thread->where();
|
||||
_request.string = "";
|
||||
} else {
|
||||
_request.len = it->second.length();
|
||||
_request.string = it->second;
|
||||
}
|
||||
|
||||
ORBIS_LOG_WARNING(__FUNCTION__, op, id, _request.string.data());
|
||||
return uwrite((ptr<RegMgrComStr>)value, _request);
|
||||
}
|
||||
|
||||
if (op == 28) {
|
||||
// com: set bin
|
||||
RegMgrComBin _request;
|
||||
ORBIS_RET_ON_ERROR(uread(_request, ptr<RegMgrComBin>(value)));
|
||||
|
||||
auto id = regMgrGetRegId(_request.encodedId);
|
||||
|
||||
if (id < 0) {
|
||||
return ErrorCode(-id);
|
||||
}
|
||||
|
||||
ORBIS_LOG_TODO(__FUNCTION__, op, id, _request.unk);
|
||||
return {};
|
||||
}
|
||||
|
||||
if (op == 29) {
|
||||
// com: get bin
|
||||
RegMgrComBin _request;
|
||||
ORBIS_RET_ON_ERROR(uread(_request, ptr<RegMgrComBin>(value)));
|
||||
|
||||
auto id = regMgrGetRegId(_request.encodedId);
|
||||
|
||||
if (id < 0) {
|
||||
return ErrorCode(-id);
|
||||
}
|
||||
|
||||
ORBIS_LOG_TODO(__FUNCTION__, op, id, _request.unk);
|
||||
return {};
|
||||
}
|
||||
|
||||
ORBIS_LOG_TODO(__FUNCTION__, op, id);
|
||||
return {};
|
||||
}
|
||||
orbis::SysResult orbis::sys_jitshm_create(Thread *thread /* TODO */) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue