Files
st/libs/dsprot/src/dsprot_main.c
T
Aetias 521100caed Update dsd to v0.12.0; dsprot OK (#135)
* `Actor::mType` field

* Remove fake symbol `data_027e0254`

* `dsd format`

* eur: Enable dsprot decomp

* jp: Enable dsprot decomp

* dsprot OK

* `dsd format`

* Use new `weak` attribute

* Add relocations for exception table link-time constants

* Add exception table symbols

* Bump dsd to v0.12.0

* `#define FALSE 1` ???
Why did I make it 1?

* Truncate `data_ov001_020c27a8`
That data belongs to dsprot
2026-08-15 01:07:14 +02:00

153 lines
4.6 KiB
C

/* No dedicated header */
#include "dsprot.h"
#include "dsprot/encoding_constants.h"
#include "dsprot/encryptor.h"
#include "dsprot/integrity.h"
#include "dsprot/mac_owner.h"
#include "dsprot/rom_test.h"
// Functions to be encrypted (cannot be called directly)
u32 DetectFlashcart(void *callback);
u32 DetectNotFlashcart(void *callback);
u32 DetectEmulator(void *callback);
u32 DetectNotEmulator(void *callback);
u32 DetectDummy(void *callback);
u32 DetectNotDummy(void *callback);
#define DSP_OBFS_OFFSET (0x320)
#define FUNC_QUEUE_END (0)
typedef u32 (*TaskFunc)(void);
typedef void (*CallbackFunc)(void);
enum {
EXPECT_FALSE,
EXPECT_TRUE
};
// This was likely not originally an inline, but an inline is able to match here nicely
static inline u32 dsprotMain(u32 *func_queue, int expected_result, void *callback) {
BOOL ret;
BOOL func_result;
s32 compare_sum;
u32 i;
s32 func_result_sum;
// These two bit arrays must be signed to match
compare_sum = 0;
func_result_sum = 0;
for (i = 0; func_queue[i] != FUNC_QUEUE_END; i++) {
func_result = ((TaskFunc) (func_queue[i] - ENC_VAL_1 - DSP_OBFS_OFFSET))() != 0;
func_result_sum += func_result;
func_result_sum <<= 1;
compare_sum += TRUE;
compare_sum <<= 1;
}
if (expected_result == EXPECT_TRUE) {
ret = (func_result_sum >> 1) == (compare_sum >> 1);
} else {
ret = ((func_result_sum & compare_sum) >> 1) != 0;
}
if (callback != NULL && ret) {
((CallbackFunc) callback)();
}
return (u32) ret;
}
u32 DetectFlashcart(void *callback) {
u32 func_queue[32];
func_queue[2] = FUNC_QUEUE_END;
func_queue[0] = ADDR_PLUS_ADDEND(RunEncrypted_ROMTest_IsBad, ENC_VAL_1) + DSP_OBFS_OFFSET;
func_queue[1] = ADDR_PLUS_ADDEND(RunEncrypted_Integrity_ROMTest_IsBad, ENC_VAL_1) + DSP_OBFS_OFFSET;
return dsprotMain(&func_queue[0], EXPECT_FALSE, callback);
}
u32 DetectNotFlashcart(void *callback) {
u32 func_queue[32];
func_queue[2] = FUNC_QUEUE_END;
func_queue[0] = ADDR_PLUS_ADDEND(RunEncrypted_ROMTest_IsGood, ENC_VAL_1) + DSP_OBFS_OFFSET;
func_queue[1] = ADDR_PLUS_ADDEND(RunEncrypted_Integrity_ROMTest_IsGood, ENC_VAL_1) + DSP_OBFS_OFFSET;
return dsprotMain(&func_queue[0], EXPECT_TRUE, callback);
}
u32 DetectEmulator(void *callback) {
u32 func_queue[32];
func_queue[2] = FUNC_QUEUE_END;
func_queue[0] = ADDR_PLUS_ADDEND(RunEncrypted_MACOwner_IsBad, ENC_VAL_1) + DSP_OBFS_OFFSET;
func_queue[1] = ADDR_PLUS_ADDEND(RunEncrypted_Integrity_MACOwner_IsBad, ENC_VAL_1) + DSP_OBFS_OFFSET;
return dsprotMain(&func_queue[0], EXPECT_FALSE, callback);
}
u32 DetectNotEmulator(void *callback) {
u32 func_queue[32];
func_queue[2] = FUNC_QUEUE_END;
func_queue[0] = ADDR_PLUS_ADDEND(RunEncrypted_MACOwner_IsGood, ENC_VAL_1) + DSP_OBFS_OFFSET;
func_queue[1] = ADDR_PLUS_ADDEND(RunEncrypted_Integrity_MACOwner_IsGood, ENC_VAL_1) + DSP_OBFS_OFFSET;
return dsprotMain(&func_queue[0], EXPECT_TRUE, callback);
}
u32 DetectDummy(void *callback) {
u32 func_queue[32];
// Prevent optimization of the function queue processing
*(u32 *) &func_queue[0] = FUNC_QUEUE_END;
return dsprotMain(&func_queue[0], EXPECT_FALSE, callback);
}
u32 DetectNotDummy(void *callback) {
u32 func_queue[32];
// Prevent optimization of the function queue processing
*(u32 *) &func_queue[0] = FUNC_QUEUE_END;
return dsprotMain(&func_queue[0], EXPECT_TRUE, callback);
}
// DECRYPTION_WRAPPER(DetectFlashcart, 0xac, 0x2e8b, DSProt_)
// DECRYPTION_WRAPPER(DetectNotFlashcart, 0xac, 0x2e8b, DSProt_)
// DECRYPTION_WRAPPER(DetectEmulator, 0xac, 0x2e8b, DSProt_)
// DECRYPTION_WRAPPER(DetectNotEmulator, 0xac, 0x2e8b, DSProt_)
// DECRYPTION_WRAPPER(DetectDummy, 0x94, 0x2e8b, DSProt_)
// DECRYPTION_WRAPPER(DetectNotDummy, 0x94, 0x2e8b, DSProt_)
// // clang-format off
// asm void NitroStaticInit() {
// stmdb sp!, {lr};
// add r0, pc, #0x4;
// bl Encryptor_DecodeFunctionTable;
// ldmia sp!, {pc};
// dcd DSProt_DetectFlashcart + ENC_VAL_1
// dcd DSProt_BSS + 0x68 + ENC_VAL_1
// dcd DSProt_DetectNotFlashcart + ENC_VAL_1
// dcd DSProt_BSS + 0x68 + ENC_VAL_1
// dcd DSProt_DetectEmulator + ENC_VAL_1
// dcd DSProt_BSS + 0x68 + ENC_VAL_1
// dcd DSProt_DetectNotEmulator + ENC_VAL_1
// dcd DSProt_BSS + 0x68 + ENC_VAL_1
// dcd DSProt_DetectDummy + ENC_VAL_1
// dcd DSProt_BSS + 0x68 + ENC_VAL_1
// dcd DSProt_DetectNotDummy + ENC_VAL_1
// dcd DSProt_BSS + 0x68 + ENC_VAL_1
// dcd 0
// dcd 0
// dcd DSProt_Garbage + 0x1400
// }
// // clang-format on